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