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 #ifndef TENSORFLOW_CORE_COMMON_RUNTIME_DEVICE_DEVICE_ID_H_
17 #define TENSORFLOW_CORE_COMMON_RUNTIME_DEVICE_DEVICE_ID_H_
18 
19 #include "tensorflow/core/lib/gtl/int_type.h"
20 
21 namespace tensorflow {
22 
23 // There are three types of device ids:
24 // - *physical* device id: this is the integer index of a device in the
25 //   physical machine, it can be filtered (for e.g. using environment variable
26 //   CUDA_VISIBLE_DEVICES when using CUDA). Note that this id is not visible to
27 //   Tensorflow, but result after filtering is visible to TF and is called
28 //   platform device id as below.
29 //   For CUDA, see
30 //   http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#env-vars
31 //   for more details.
32 // - *platform* device id (also called *visible* device id in
33 //   third_party/tensorflow/core/protobuf/config.proto): this is the id that is
34 //   visible to Tensorflow after filtering (for e.g. by CUDA_VISIBLE_DEVICES).
35 //   For CUDA, this id is generated by the CUDA GPU driver. It starts from 0
36 //   and is used for CUDA API calls like cuDeviceGet().
37 // - TF device id (also called *virtual* device id in
38 //   third_party/tensorflow/core/protobuf/config.proto): this is the id that
39 //   Tensorflow generates and exposes to its users. It is the id in the <id>
40 //   field of the device name "/device:GPU:<id>", and is also the identifier of
41 //   a BaseGPUDevice. Note that the configuration allows us to create multiple
42 //   BaseGPUDevice per GPU hardware in order to use multi CUDA streams on the
43 //   hardware, so the mapping between TF GPU id and platform GPU id is not a 1:1
44 //   mapping, see the example below.
45 //
46 // For example, assuming that in the machine we have GPU device with index 0, 1,
47 // 2 and 3 (physical GPU id). Setting "CUDA_VISIBLE_DEVICES=1,2,3" will create
48 // the following mapping between platform GPU id and physical GPU id:
49 //
50 //        platform GPU id ->  physical GPU id
51 //                 0  ->  1
52 //                 1  ->  2
53 //                 2  ->  3
54 //
55 // Note that physical GPU id 0 is invisible to TF so there is no mapping entry
56 // for it.
57 //
58 // Assuming we configure the Session to create one BaseGPUDevice per GPU
59 // hardware, then setting GPUOptions::visible_device_list to "2,0" will create
60 // the following mapping between TF device id and platform device id:
61 //
62 //                  TF GPU id  ->  platform GPU ID
63 //      0 (i.e. /device:GPU:0) ->  2
64 //      1 (i.e. /device:GPU:1) ->  0
65 //
66 // Note that platform device id 1 is filtered out by
67 // GPUOptions::visible_device_list, so it won't be used by the TF process.
68 //
69 // On the other hand, if we configure it to create 2 BaseGPUDevice per GPU
70 // hardware, then setting GPUOptions::visible_device_list to "2,0" will create
71 // the following mapping between TF device id and platform device id:
72 //
73 //                  TF GPU id  ->  platform GPU ID
74 //      0 (i.e. /device:GPU:0) ->  2
75 //      1 (i.e. /device:GPU:1) ->  2
76 //      2 (i.e. /device:GPU:2) ->  0
77 //      3 (i.e. /device:GPU:3) ->  0
78 //
79 // We create strong-typed integer classes for both TF device id and platform
80 // device id to minimize programming errors and improve code readability. Except
81 // for the StreamExecutor interface (as we don't change its API), whenever we
82 // need a TF device id (or platform device id) we should use TfDeviceId (or
83 // PlatformDeviceId) instead of a raw integer.
84 TF_LIB_GTL_DEFINE_INT_TYPE(TfDeviceId, int32);
85 TF_LIB_GTL_DEFINE_INT_TYPE(PlatformDeviceId, int32);
86 
87 }  // namespace tensorflow
88 
89 #endif  // TENSORFLOW_CORE_COMMON_RUNTIME_DEVICE_DEVICE_ID_H_
90