1122cdce33e3e0a01a7f82645617317530aa571fbA. Unique TensorFlower/* Copyright 2015 The TensorFlow Authors. All Rights Reserved. 29c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur 39c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurLicensed under the Apache License, Version 2.0 (the "License"); 49c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudluryou may not use this file except in compliance with the License. 59c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurYou may obtain a copy of the License at 69c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur 79c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur http://www.apache.org/licenses/LICENSE-2.0 89c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur 99c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurUnless required by applicable law or agreed to in writing, software 109c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlurdistributed under the License is distributed on an "AS IS" BASIS, 119c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 129c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurSee the License for the specific language governing permissions and 139c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlurlimitations under the License. 149c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur==============================================================================*/ 159c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur 16f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/stream_executor/cuda/cuda_platform.h" 17f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 18f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/stream_executor/cuda/cuda_driver.h" 19ddd4aaf5286de24ba70402ee0ec8b836d3aed8c7Vijay Vasudevan#include "tensorflow/stream_executor/cuda/cuda_gpu_executor.h" 20ddd4aaf5286de24ba70402ee0ec8b836d3aed8c7Vijay Vasudevan#include "tensorflow/stream_executor/cuda/cuda_platform_id.h" 21f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/stream_executor/lib/error.h" 22f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/stream_executor/lib/initialize.h" 23f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/stream_executor/lib/ptr_util.h" 24f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/stream_executor/lib/status.h" 25f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/stream_executor/lib/stringprintf.h" 26f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 27f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurnamespace perftools { 28f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurnamespace gputools { 29f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurnamespace cuda { 30109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlowernamespace { 31109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower 32109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower// Synchronize with spinlocks. 33109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlowerconst char kScheduleSpinString[] = "spin"; 34109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower// Synchronize with spinlocks that also call CPU yield instructions. 35109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlowerconst char kScheduleYieldString[] = "yield"; 36109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower// Synchronize with a "synchronization primitive" (e.g. mutex). 37109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlowerconst char kScheduleBlockingSyncString[] = "blocking_sync"; 38109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower 39109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlowerconst DeviceOptions GetDeviceOptionsFromEnv() { 40109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower const char* gpu_schedule_string = 41109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower std::getenv("TF_CUDA_PLATFORM_GPU_DEVICE_SCHEDULE"); 42109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower 43109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower if (gpu_schedule_string == nullptr) { 44109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower return perftools::gputools::DeviceOptions::Default(); 45109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower } 46109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower 47109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower unsigned device_flags = 0; 489b3233d25e0dd7078667712f128657f3fbb7dbd4A. Unique TensorFlower if (strcmp(kScheduleSpinString, gpu_schedule_string) == 0) { 49109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower device_flags = perftools::gputools::DeviceOptions::kScheduleSpin; 509b3233d25e0dd7078667712f128657f3fbb7dbd4A. Unique TensorFlower } else if (strcmp(kScheduleYieldString, gpu_schedule_string) == 0) { 51109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower device_flags = perftools::gputools::DeviceOptions::kScheduleYield; 529b3233d25e0dd7078667712f128657f3fbb7dbd4A. Unique TensorFlower } else if (strcmp(kScheduleBlockingSyncString, gpu_schedule_string) == 0) { 53109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower device_flags = perftools::gputools::DeviceOptions::kScheduleBlockingSync; 54109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower } else { 55109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower LOG(QFATAL) << "Unknown option for environment variable " 56109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower "TF_CUDA_PLATFORM_GPU_DEVICE_SCHEDULE " 57109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower << gpu_schedule_string << " should be one of {" 58109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower << kScheduleBlockingSyncString << ", " << kScheduleSpinString 59109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower << ", " << kScheduleYieldString << "}"; 60109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower } 61109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower 62109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower return perftools::gputools::DeviceOptions(device_flags); 63109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower} 64109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower 65109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower} // namespace 66f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 67f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurCudaPlatform::CudaPlatform() 68f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur : name_("CUDA"), min_numa_node_(0), limit_numa_node_(0) {} 69f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 70f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurCudaPlatform::~CudaPlatform() {} 71f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 72f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// Due to legacy issues in user code, we can't currently call InpectNumaNodes 73f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// at module initialization time, because non-GPU programs still include this 74f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// plugin via various methods, so instead, it has to be init-on-reference. 75f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid CudaPlatform::InspectNumaNodes() { 76f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur // To get NUMA node information, we need to create all executors, so we can 77f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur // examine their device descriptions to see their bus assignments. 78f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur static bool initialized = false; 79f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur static mutex numa_mutex(LINKER_INITIALIZED); 80f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur mutex_lock lock(numa_mutex); 81f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur if (initialized) { 82f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur return; 83f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur } 84f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 85f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur StreamExecutorConfig config; 86f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur for (int i = 0; i < VisibleDeviceCount(); i++) { 87f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur config.ordinal = i; 88f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur StreamExecutor* exec = GetExecutor(config).ValueOrDie(); 89f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur if (i == 0) { 90f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur // NUMA nodes may not start at 0, so set the minimum node based on the 91f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur // first executor we see. 92f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur min_numa_node_ = exec->GetDeviceDescription().numa_node(); 93f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur limit_numa_node_ = min_numa_node_ + 1; 94f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur } else { 95f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur min_numa_node_ = 96f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur std::min(min_numa_node_, exec->GetDeviceDescription().numa_node()); 97f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur limit_numa_node_ = std::max(limit_numa_node_, 98f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur exec->GetDeviceDescription().numa_node() + 1); 99f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur } 100f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur } 101f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur initialized = true; 102f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} 103f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 104f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurint CudaPlatform::BusCount() { 105f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur InspectNumaNodes(); 106f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur return limit_numa_node_ - min_numa_node_; 107f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} 108f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 109f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurint CudaPlatform::DeviceToBus(int device_ordinal) { 110f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur StreamExecutorConfig config; 111f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur config.ordinal = device_ordinal; 112f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur StreamExecutor* exec = GetExecutor(config).ValueOrDie(); 113f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur return exec->GetDeviceDescription().numa_node() - min_numa_node_; 114f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} 115f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 116f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurport::StatusOr<StreamExecutor*> CudaPlatform::FirstExecutorForBus( 117f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur int bus_ordinal) { 118f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur InspectNumaNodes(); 119f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur CHECK_LT(bus_ordinal, BusCount()) << "bus ordinal out of available range"; 120f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur for (int i = 0; i < VisibleDeviceCount(); i++) { 121f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur if (DeviceToBus(i) == bus_ordinal) { 122f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur StreamExecutorConfig config; 123f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur config.ordinal = i; 124f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur return GetExecutor(config).ValueOrDie(); 125f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur } 126f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur } 127f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 128f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur return port::Status{ 129f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur port::error::NOT_FOUND, 130f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur port::Printf("Executor for bus %d not found.", bus_ordinal)}; 131f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} 132f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 133f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurPlatform::Id CudaPlatform::id() const { return kCudaPlatformId; } 134f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 135f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurint CudaPlatform::VisibleDeviceCount() const { 136f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur // Throw away the result - it logs internally, and this [containing] function 137f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur // isn't in the path of user control. It's safe to call this > 1x. 138f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur if (!cuda::CUDADriver::Init().ok()) { 139f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur return -1; 140f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur } 141f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 142f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur return CUDADriver::GetDeviceCount(); 143f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} 144f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 145f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurconst string& CudaPlatform::Name() const { return name_; } 146f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 147f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurport::StatusOr<StreamExecutor*> CudaPlatform::ExecutorForDevice(int ordinal) { 148f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur StreamExecutorConfig config; 149f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur config.ordinal = ordinal; 150f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur config.plugin_config = PluginConfig(); 151109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower config.device_options = GetDeviceOptionsFromEnv(); 152f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur return GetExecutor(config); 153f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} 154f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 155f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurport::StatusOr<StreamExecutor*> CudaPlatform::ExecutorForDeviceWithPluginConfig( 156f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur int device_ordinal, const PluginConfig& plugin_config) { 157f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur StreamExecutorConfig config; 158f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur config.ordinal = device_ordinal; 159f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur config.plugin_config = plugin_config; 160109133639706026d2bd944dd0a0c8fcae0d4fac6A. Unique TensorFlower config.device_options = GetDeviceOptionsFromEnv(); 161f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur return GetExecutor(config); 162f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} 163f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 164f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurport::StatusOr<StreamExecutor*> CudaPlatform::GetExecutor( 165f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur const StreamExecutorConfig& config) { 166122750a879f508342b53ee2eaecfde1656981280Peter Hawkins return executor_cache_.GetOrCreate( 167122750a879f508342b53ee2eaecfde1656981280Peter Hawkins config, [&]() { return GetUncachedExecutor(config); }); 168f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} 169f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 170f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurport::StatusOr<std::unique_ptr<StreamExecutor>> 171f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurCudaPlatform::GetUncachedExecutor(const StreamExecutorConfig& config) { 172ddd4aaf5286de24ba70402ee0ec8b836d3aed8c7Vijay Vasudevan auto executor = port::MakeUnique<StreamExecutor>( 173c31294351628addffc1cd89687fad0e81bac5a55A. Unique TensorFlower this, port::MakeUnique<CUDAExecutor>(config.plugin_config)); 174f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur auto init_status = executor->Init(config.ordinal, config.device_options); 175f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur if (!init_status.ok()) { 176f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur return port::Status{ 177f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur port::error::INTERNAL, 178f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur port::Printf( 179f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur "failed initializing StreamExecutor for CUDA device ordinal %d: %s", 180f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur config.ordinal, init_status.ToString().c_str())}; 181f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur } 182f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 183f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur return std::move(executor); 184f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} 185f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 186f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid CudaPlatform::RegisterTraceListener( 187f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur std::unique_ptr<TraceListener> listener) { 188f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur LOG(FATAL) << "not yet implemented: register CUDA trace listener"; 189f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} 190f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 191f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid CudaPlatform::UnregisterTraceListener(TraceListener* listener) { 192f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur LOG(FATAL) << "not yet implemented: unregister CUDA trace listener"; 193f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} 194f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 195f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} // namespace cuda 196f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 197f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurstatic void InitializeCudaPlatform() { 198f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur // Disabling leak checking, MultiPlatformManager does not destroy its 199f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur // registered platforms. 200191825e63f341a4e7777b85254f616e541000d5cA. Unique TensorFlower 201f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur std::unique_ptr<cuda::CudaPlatform> platform(new cuda::CudaPlatform); 202f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur SE_CHECK_OK(MultiPlatformManager::RegisterPlatform(std::move(platform))); 203f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} 204f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 205f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} // namespace gputools 206f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} // namespace perftools 207f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 208f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurREGISTER_MODULE_INITIALIZER(cuda_platform, 209f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur perftools::gputools::InitializeCudaPlatform()); 210a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlower 211a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlowerDECLARE_MODULE_INITIALIZER(multi_platform_manager); 212a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlower// Note that module initialization sequencing is not supported in the 213a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlower// open-source project, so this will be a no-op there. 214a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlowerREGISTER_MODULE_INITIALIZER_SEQUENCE(cuda_platform, multi_platform_manager); 215