platform.h revision 122cdce33e3e0a01a7f82645617317530aa571fb
1/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7    http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14==============================================================================*/
15
16// Defines types and declares functions for identifying and extracting
17// information about the types of platforms and supporting libraries for which
18// StreamExecutor implementations exist.
19#ifndef TENSORFLOW_STREAM_EXECUTOR_PLATFORM_H_
20#define TENSORFLOW_STREAM_EXECUTOR_PLATFORM_H_
21
22#include <map>
23#include "tensorflow/stream_executor/platform/port.h"
24
25#include "tensorflow/stream_executor/device_options.h"
26#include "tensorflow/stream_executor/lib/status.h"
27#include "tensorflow/stream_executor/lib/statusor.h"
28#include "tensorflow/stream_executor/platform/port.h"
29#include "tensorflow/stream_executor/plugin.h"
30#include "tensorflow/stream_executor/trace_listener.h"
31
32namespace perftools {
33namespace gputools {
34
35class StreamExecutor;
36
37// Describes the platform for a StreamExecutor instantiation to act upon.
38//
39// Implementors: if you add a value here be sure to update PlatformKindString
40// and CheckPlatformKindIsValid.
41enum class PlatformKind {
42  kInvalid,
43  kCuda,
44  kOpenCL,
45  kHost,
46  kMock,
47  kSize,
48};
49
50// Returns true if kind represents a valid platform capable of enqueuing items
51// on a stream, but not necessarily on an accelerator device.
52// Returns false for kMock and any invalid PlatformKind values.
53bool PlatformIsRunnable(PlatformKind kind);
54
55// Returns true if kind represents a valid platform capable of running kernels
56// on an accelerator device. Returns false for kHost*, kMock and any invalid
57// PlatformKind values.
58bool PlatformIsRunnableOnDevice(PlatformKind kind);
59
60// Returns a printable description of a PlatformKind.
61string PlatformKindString(PlatformKind kind);
62
63// Returns the PlatformKind corresponding to the input string; returns kInvalid
64// in the case of no match.
65PlatformKind PlatformKindFromString(string platform_string);
66
67// Checks that kind takes on a valid value.
68void CheckPlatformKindIsValid(PlatformKind kind);
69
70// StreamExecutorConfig encapsulates the set of options for constructing a
71// StreamExecutor for a given platform.
72struct StreamExecutorConfig {
73  // Sets members to defaults: -1 for ordinal (must be changed), and default
74  // PluginConfig and DeviceOptions.
75  StreamExecutorConfig();
76
77  // Simple ordinal-setting constructor.
78  explicit StreamExecutorConfig(int ordinal);
79
80  // The ordinal of the device to be managed by the returned StreamExecutor.
81  int ordinal;
82
83  // The PluginConfig for the returned StreamExecutor.
84  PluginConfig plugin_config;
85
86  // The DeviceOptions for the returned StreamExecutor.
87  DeviceOptions device_options;
88};
89
90// Abstract base class for a platform registered with the MultiPlatformManager.
91class Platform {
92 public:
93  virtual ~Platform();
94
95  // A platform ID is a unique identifier for each registered platform type -
96  // each platform is required to expose an ID to ensure unique registration and
97  // as a target against which plugins can register.
98  //
99  // The macro below is provided to help generate a [process-unique] identifer.
100  using Id = void*;
101
102// Helper macro to define a plugin ID. To be used only inside plugin
103// implementation files. Works by "reserving" an address/value (guaranteed to be
104// unique) inside a process space.
105#define PLATFORM_DEFINE_ID(ID_VAR_NAME) \
106  namespace {                           \
107  int plugin_id_value;                  \
108  }                                     \
109  const perftools::gputools::Platform::Id ID_VAR_NAME = &plugin_id_value;
110
111  // Returns a key uniquely identifying this platform.
112  virtual Id id() const = 0;
113
114  // Returns the number of devices accessible on this platform.
115  //
116  // Note that, though these devices are visible, if there is only one userspace
117  // context allowed for the device at a time and another process is using this
118  // device, a call to ExecutorForDevice may return an error status.
119  virtual int VisibleDeviceCount() const = 0;
120
121  // Name of this platform.
122  virtual const string& Name() const = 0;
123
124  // Returns a device with the given ordinal on this platform with a default
125  // plugin configuration or, if none can be found with the given ordinal or
126  // there is an error in opening a context to communicate with the device, an
127  // error status is returned.
128  //
129  // Ownership of the executor is NOT transferred to the caller --
130  // the Platform owns the executors in a singleton-like fashion.
131  virtual port::StatusOr<StreamExecutor*> ExecutorForDevice(int ordinal) = 0;
132
133  // Returns a device or error, as above, with the specified plugins.
134  //
135  // Ownership of the executor is NOT transferred to the caller.
136  virtual port::StatusOr<StreamExecutor*> ExecutorForDeviceWithPluginConfig(
137      int ordinal, const PluginConfig& plugin_config) = 0;
138
139  // Returns a device constructed with the options specified in "config".
140  // Ownership of the executor is NOT transferred to the caller.
141  virtual port::StatusOr<StreamExecutor*> GetExecutor(
142      const StreamExecutorConfig& config) = 0;
143
144  // Returns a device constructed with the options specified in "config" without
145  // looking in or storing to the Platform's executor cache.
146  // Ownership IS transferred to the caller.
147  virtual port::StatusOr<std::unique_ptr<StreamExecutor>> GetUncachedExecutor(
148      const StreamExecutorConfig& config) = 0;
149
150  // Warning: this is a dangerous API and should be used with caution.
151  //
152  // Forces the platform to delete executor instances, releasing their
153  // associated device contexts. There must be no held instances of the executor
154  // and there must be no outstanding activity on the devices for this platform.
155  //
156  // This is only useful on platforms which bind a device to a single process
157  // that has obtained the device context. May return UNIMPLEMENTED on platforms
158  // that have no reason to destroy device contexts.
159  virtual port::Status ForceExecutorShutdown();
160
161  // Registers a TraceListener to listen to all StreamExecutors for this
162  // platform.
163  // Takes ownership of listener.
164  virtual void RegisterTraceListener(
165      std::unique_ptr<TraceListener> listener) = 0;
166
167  // Removes the specified TraceListener from all StreamExecutors.
168  virtual void UnregisterTraceListener(TraceListener* listener) = 0;
169
170  // Map of executor-to-executor coordinate and boolean, indicating if the first
171  // executor can access the second's memory.
172  using PeerAccessMap = std::map<std::pair<int, int>, bool>;
173
174  // Returns a matrix indicating which executors can access which other
175  // executors' memory.
176  virtual std::unique_ptr<PeerAccessMap> GetPeerAccessMap();
177
178  // Attempts to enable all peer-to-peer access links described by the result of
179  // GetPeerAccessMap(). Note that calling this routine will force the creation
180  // of a default-argument (see StreamExecutorConfig) StreamExecutor object for
181  // each device ordinal in the system, should any not yet exist.
182  virtual port::Status EnablePeerAccess();
183
184 protected:
185  // SE_DISALLOW_COPY_AND_ASSIGN declares a constructor, which suppresses the
186  // presence of the default constructor. This statement re-enables it, which
187  // simplifies subclassing.
188  Platform() = default;
189
190 private:
191  SE_DISALLOW_COPY_AND_ASSIGN(Platform);
192};
193
194}  // namespace gputools
195}  // namespace perftools
196
197#endif  // TENSORFLOW_STREAM_EXECUTOR_PLATFORM_H_
198