Caffe2 - C++ API
A deep learning, cross platform ML framework
Device.cpp
1 #include <c10/core/Device.h>
2 #include <c10/macros/Macros.h>
3 #include <c10/util/Exception.h>
4 
5 #include <algorithm>
6 #include <array>
7 #include <exception>
8 #include <ostream>
9 #include <string>
10 #include <tuple>
11 #include <vector>
12 
13 namespace c10 {
14 namespace {
15 DeviceType parse_type(const std::string& device_string) {
16  static const std::array<std::pair<std::string, DeviceType>, 9> types = {{
17  {"cpu", DeviceType::CPU},
18  {"cuda", DeviceType::CUDA},
19  {"mkldnn", DeviceType::MKLDNN},
20  {"opengl", DeviceType::OPENGL},
21  {"opencl", DeviceType::OPENCL},
22  {"ideep", DeviceType::IDEEP},
23  {"hip", DeviceType::HIP},
24  {"msnpu", DeviceType::MSNPU},
25  {"xla", DeviceType::XLA},
26  }};
27  auto device = std::find_if(
28  types.begin(),
29  types.end(),
30  [device_string](const std::pair<std::string, DeviceType>& p) {
31  return p.first == device_string;
32  });
33  if (device != types.end()) {
34  return device->second;
35  }
36  AT_ERROR(
37  "Expected one of cpu, cuda, mkldnn, opengl, opencl, ideep, hip, msnpu device type at start of device string: ", device_string);
38 }
39 } // namespace
40 
41 void Device::validate() {
42  AT_CHECK(index_ == -1 || index_ >= 0,
43  "Device index must be -1 or non-negative, got ", index_);
44  AT_CHECK(!is_cpu() || index_ <= 0,
45  "CPU device index must be -1 or zero, got ", index_);
46 }
47 
48 // `std::regex` is still in a very incomplete state in GCC 4.8.x,
49 // so we have to do our own parsing, like peasants.
50 // https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions
51 //
52 // Replace with the following code once we shed our GCC skin:
53 //
54 // static const std::regex regex(
55 // "(cuda|cpu)|(cuda|cpu):([0-9]+)|([0-9]+)",
56 // std::regex_constants::basic);
57 // std::smatch match;
58 // const bool ok = std::regex_match(device_string, match, regex);
59 // AT_CHECK(ok, "Invalid device string: '", device_string, "'");
60 // if (match[1].matched) {
61 // type_ = parse_type_from_string(match[1].str());
62 // } else {
63 // if (match[2].matched) {
64 // type_ = parse_type_from_string(match[1].str());
65 // } else {
66 // type_ = Type::CUDA;
67 // }
68 // AT_ASSERT(match[3].matched);
69 // index_ = std::stoi(match[3].str());
70 // }
71 Device::Device(const std::string& device_string) : Device(Type::CPU) {
72  AT_CHECK(!device_string.empty(), "Device string must not be empty");
73  int index = device_string.find(":");
74  if (index == std::string::npos) {
75  type_ = parse_type(device_string);
76  } else {
77  std::string s;
78  s = device_string.substr(0, index);
79  AT_CHECK(!s.empty(), "Device string must not be empty");
80  type_ = parse_type(s);
81 
82  std::string device_index = device_string.substr(index + 1);
83  try {
84  index_ = c10::stoi(device_index);
85  } catch (const std::exception &) {
86  AT_ERROR("Could not parse device index '", device_index,
87  "' in device string '", device_string, "'");
88  }
89  AT_CHECK(index_ >= 0,
90  "Device index must be non-negative, got ", index_);
91  }
92  validate();
93 }
94 
95 std::ostream& operator<<(std::ostream& stream, const Device& device) {
96  stream << device.type();
97  if (device.has_index()) {
98  stream << ":" << device.index();
99  }
100  return stream;
101 }
102 
103 } // namespace c10
bool has_index() const noexcept
Returns true if the device has a non-default index.
Definition: Device.h:75
TensorOptions device_index(int16_t device_index)
Convenience function that returns a TensorOptions object with the device set to CUDA and the device_i...
TensorOptions device(Device device)
Convenience function that returns a TensorOptions object with the device set to the given one...
Represents a a compute device on which a tensor is located.
Definition: Device.h:30
bool is_cpu() const noexcept
Return true if the device is of CPU type.
Definition: Device.h:85
To register your own kernel for an operator, do in one (!) cpp file: C10_REGISTER_KERNEL(OperatorHand...
Definition: alias_info.h:7
Device(DeviceType type, DeviceIndex index=-1)
Constructs a new Device from a DeviceType and an optional device index.
Definition: Device.h:35
DeviceIndex index() const noexcept
Returns the optional index.
Definition: Device.h:70
DeviceType type() const noexcept
Returns the type of device this is.
Definition: Device.h:65