Caffe2 - C++ API
A deep learning, cross platform ML framework
tensor_options_cuda.cpp
1 #include <gtest/gtest.h>
2 
3 #include <ATen/Context.h>
4 #include <ATen/DeviceGuard.h>
5 #include <ATen/Functions.h>
6 #include <c10/core/ScalarType.h>
7 #include <c10/core/TensorOptions.h>
8 
9 #include <torch/cuda.h>
10 
11 // NB: This file is compiled even in CPU build (for some reason), so
12 // make sure you don't include any CUDA only headers.
13 
14 using namespace at;
15 
16 // TODO: This might be generally helpful aliases elsewhere.
17 at::Device CPUDevice() {
18  return at::Device(at::kCPU);
19 }
20 at::Device CUDADevice(DeviceIndex index) {
21  return at::Device(at::kCUDA, index);
22 }
23 
24 // A macro so we don't lose location information when an assertion fails.
25 #define REQUIRE_OPTIONS(device_, index_, type_, layout_) \
26  ASSERT_EQ(options.device().type(), Device((device_), (index_)).type()); \
27  ASSERT_TRUE( \
28  options.device().index() == Device((device_), (index_)).index()); \
29  ASSERT_EQ(typeMetaToScalarType(options.dtype()), (type_)); \
30  ASSERT_TRUE(options.layout() == (layout_))
31 
32 #define REQUIRE_TENSOR_OPTIONS(device_, index_, type_, layout_) \
33  ASSERT_EQ(tensor.device().type(), Device((device_), (index_)).type()); \
34  ASSERT_EQ(tensor.device().index(), Device((device_), (index_)).index()); \
35  ASSERT_EQ(tensor.scalar_type(), (type_)); \
36  ASSERT_TRUE(tensor.type().layout() == (layout_))
37 
38 TEST(TensorOptionsTest, ConstructsWellFromCUDATypes_CUDA) {
39  auto options = CUDA(kFloat).options();
40  REQUIRE_OPTIONS(kCUDA, -1, kFloat, kStrided);
41 
42  options = CUDA(kInt).options();
43  REQUIRE_OPTIONS(kCUDA, -1, kInt, kStrided);
44 
45  options = getNonVariableType(Backend::SparseCUDA, kFloat).options();
46  REQUIRE_OPTIONS(kCUDA, -1, kFloat, kSparse);
47 
48  options = getNonVariableType(Backend::SparseCUDA, kByte).options();
49  REQUIRE_OPTIONS(kCUDA, -1, kByte, kSparse);
50 
51  options = CUDA(kFloat).options(/*device=*/5);
52  REQUIRE_OPTIONS(kCUDA, 5, kFloat, kStrided);
53 
54  options =
55  getNonVariableType(Backend::SparseCUDA, kFloat).options(/*device=*/5);
56  REQUIRE_OPTIONS(kCUDA, 5, kFloat, kSparse);
57 }
58 
59 TEST(TensorOptionsTest, ConstructsWellFromCUDATensors_MultiCUDA) {
60  auto options = empty(5, device(kCUDA).dtype(kDouble)).options();
61  REQUIRE_OPTIONS(kCUDA, 0, kDouble, kStrided);
62 
63  options = empty(5, getNonVariableType(Backend::SparseCUDA, kByte)).options();
64  REQUIRE_OPTIONS(kCUDA, 0, kByte, kSparse);
65 
66  if (torch::cuda::device_count() > 1) {
67  Tensor tensor;
68  {
69  DeviceGuard guard(CUDADevice(1));
70  tensor = empty(5, device(kCUDA));
71  }
72  options = tensor.options();
73  REQUIRE_OPTIONS(kCUDA, 1, kFloat, kStrided);
74 
75  {
76  DeviceGuard guard(CUDADevice(1));
77  tensor = empty(5, device(kCUDA).layout(kSparse));
78  }
79  options = tensor.options();
80  REQUIRE_OPTIONS(kCUDA, 1, kFloat, kSparse);
81  }
82 }
TensorOptions options() const
Returns the TensorOptions corresponding to this Tensor.
Definition: TensorMethods.h:42
Represents a a compute device on which a tensor is located.
Definition: Device.h:30
int16_t DeviceIndex
An index representing a specific device; e.g., the 1 in GPU 1.
Definition: Device.h:18
RAII guard that sets a certain default device in its constructor, and changes it back to the device t...
Definition: DeviceGuard.h:19
Flush-To-Zero and Denormals-Are-Zero mode.