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/multi_platform_manager.h"
17f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
18f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/stream_executor/lib/error.h"
19a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlower#include "tensorflow/stream_executor/lib/initialize.h"
20f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/stream_executor/lib/str_util.h"
21f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/stream_executor/lib/stringprintf.h"
22f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
23f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurnamespace perftools {
24f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurnamespace gputools {
25f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
26f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur/* static */ port::Status MultiPlatformManager::RegisterPlatform(
27f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    std::unique_ptr<Platform> platform) {
28f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  CHECK(platform != nullptr);
29f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  string key = port::Lowercase(platform->Name());
30e4a4e922ed4be890f4273a7a276768dfefe80a4cPeter Hawkins  mutex_lock lock(GetPlatformsMutex());
31f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  if (GetPlatformMap()->find(key) != GetPlatformMap()->end()) {
32f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    return port::Status(port::error::INTERNAL,
33f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur                        "platform is already registered with name: \"" +
34f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur                            platform->Name() + "\"");
35f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
36f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  GetPlatformByIdMap()->insert(std::make_pair(platform->id(), platform.get()));
37f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Release ownership/uniqueness to prevent destruction on program exit.
38f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // This avoids Platforms "cleaning up" on program exit, because otherwise,
39f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // there are _very_ tricky races between StreamExecutor and underlying
40f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // platforms (CUDA, OpenCL) during exit. Since these are fixed-size and 1x per
41f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // program, these are deemed acceptable.
42f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  (*GetPlatformMap())[key] = platform.release();
43f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return port::Status::OK();
44f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
45f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
46f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur/* static */ port::StatusOr<Platform*> MultiPlatformManager::PlatformWithName(
47f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    const string& target) {
48982549ea3423df4270ff154e5c764beb43d472daRasmus Munk Larsen  tf_shared_lock lock(GetPlatformsMutex());
49f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  auto it = GetPlatformMap()->find(port::Lowercase(target));
50f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
51f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  if (it == GetPlatformMap()->end()) {
52f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    return port::Status(
53f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        port::error::NOT_FOUND,
54f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        "could not find registered platform with name: \"" + target + "\"");
55f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
56f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
57f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return it->second;
58f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
59f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
60f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur/* static */ port::StatusOr<Platform*> MultiPlatformManager::PlatformWithId(
61f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    const Platform::Id& id) {
62982549ea3423df4270ff154e5c764beb43d472daRasmus Munk Larsen  tf_shared_lock lock(GetPlatformsMutex());
63f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  auto it = GetPlatformByIdMap()->find(id);
64f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  if (it == GetPlatformByIdMap()->end()) {
65f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    return port::Status(
66f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        port::error::NOT_FOUND,
67f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        port::Printf("could not find registered platform with id: 0x%p", id));
68f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
69f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
70f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return it->second;
71f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
72f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
73f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur/* static */ void MultiPlatformManager::ClearPlatformRegistry() {
74e4a4e922ed4be890f4273a7a276768dfefe80a4cPeter Hawkins  mutex_lock lock(GetPlatformsMutex());
75f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  GetPlatformMap()->clear();
76f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  GetPlatformByIdMap()->clear();
77f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
78f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
79f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}  // namespace gputools
80f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}  // namespace perftools
81a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlower
82a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlowerREGISTER_MODULE_INITIALIZER(
83a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlower    multi_platform_manager,
84a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlower    {
85a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlower        // Nothing -- this is just a module initializer
86a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlower        // definition to reference for sequencing
87a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlower        // purposes from Platform subclasses that register
88a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlower        // themselves with the MultiPlatformManager.
89a7b60a8206554270c1d066fd66242b1d90574a14A. Unique TensorFlower    });
90