Home | History | Annotate | Download | only in stream_executor
      1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
      2 
      3 Licensed under the Apache License, Version 2.0 (the "License");
      4 you may not use this file except in compliance with the License.
      5 You may obtain a copy of the License at
      6 
      7     http://www.apache.org/licenses/LICENSE-2.0
      8 
      9 Unless required by applicable law or agreed to in writing, software
     10 distributed under the License is distributed on an "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 See the License for the specific language governing permissions and
     13 limitations 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 
     24 #include "tensorflow/stream_executor/device_options.h"
     25 #include "tensorflow/stream_executor/lib/status.h"
     26 #include "tensorflow/stream_executor/lib/status_macros.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 
     32 namespace perftools {
     33 namespace gputools {
     34 
     35 class 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.
     41 enum 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.
     53 bool 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.
     58 bool PlatformIsRunnableOnDevice(PlatformKind kind);
     59 
     60 // Returns a printable description of a PlatformKind.
     61 string PlatformKindString(PlatformKind kind);
     62 
     63 // Returns the PlatformKind corresponding to the input string; returns kInvalid
     64 // in the case of no match.
     65 PlatformKind PlatformKindFromString(string platform_string);
     66 
     67 // Checks that kind takes on a valid value.
     68 void CheckPlatformKindIsValid(PlatformKind kind);
     69 
     70 // StreamExecutorConfig encapsulates the set of options for constructing a
     71 // StreamExecutor for a given platform.
     72 struct 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.
     91 class 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] identifier.
    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