Caffe2 - C++ API
A deep learning, cross platform ML framework
context_base.h
1 #pragma once
2 
3 #include <array>
4 #include <cstdlib>
5 #include <ctime>
6 #include <memory>
7 #include <unordered_map>
8 
9 #include <ATen/core/ATenGeneral.h>
10 #include <c10/core/Allocator.h>
11 #include <c10/util/typeid.h>
12 #include <c10/util/Exception.h>
13 #include <c10/util/Registry.h>
14 #include <c10/core/CopyBytes.h>
15 
16 namespace caffe2 {
17 class Event;
18 
19 } // namespace caffe2
20 namespace at {
21 
22 class BaseContext;
23 
33  public:
34  virtual ~BaseContext() noexcept {}
35 
36  virtual Device device() const = 0;
37 
38  /* Sorry for the naming, will get rid of this in future diff */
39  virtual DeviceType device_type() const = 0;
40 
41  virtual void SwitchToDevice(int /*stream_id*/) = 0;
42 
43  inline void SwitchToDevice() {
44  SwitchToDevice(0);
45  }
46 
47  virtual void WaitEvent(const caffe2::Event& ev) = 0;
48 
49  virtual void Record(caffe2::Event* ev, const char* err_msg = nullptr)
50  const = 0;
51 
52  virtual void FinishDeviceComputation() = 0;
53 
54  // This used to be arbitrary cross-device copy, but it turns out everyone
55  // did direct CPU-X copy, so we just make three functions for it (to avoid
56  // double dispatch). This will get obsoleted by C10. where copies
57  // will be proper operators (and get to rely on multiple dispatch there.)
58  virtual void CopyBytesSameDevice(
59  size_t nbytes,
60  const void* src,
61  void* dst) = 0;
62 
63  virtual void CopyBytesFromCPU(size_t nbytes, const void* src, void* dst) = 0;
64 
65  virtual void CopyBytesToCPU(size_t nbytes, const void* src, void* dst) = 0;
66 
67  template <typename T>
68  inline void CopySameDevice(size_t n, const T* src, T* dst) {
69  static_assert(
70  std::is_fundamental<T>::value,
71  "CopySameDevice requires fundamental types");
72  CopyBytesSameDevice(
73  n * sizeof(T), static_cast<const void*>(src), static_cast<void*>(dst));
74  }
75 
76  template <typename T>
77  inline void CopyFromCPU(size_t n, const T* src, T* dst) {
78  static_assert(
79  std::is_fundamental<T>::value,
80  "CopyFromCPU requires fundamental types");
81  CopyBytesFromCPU(
82  n * sizeof(T), static_cast<const void*>(src), static_cast<void*>(dst));
83  }
84 
85  template <typename T>
86  inline void CopyToCPU(size_t n, const T* src, T* dst) {
87  static_assert(
88  std::is_fundamental<T>::value, "CopyToCPU requires fundamental types");
89  CopyBytesToCPU(
90  n * sizeof(T), static_cast<const void*>(src), static_cast<void*>(dst));
91  }
92 
93  virtual bool SupportsNonFundamentalTypes() const {
94  return false;
95  }
96 
97  inline void EnforceMetaCopyOK() {
98  AT_ASSERTM(
99  SupportsNonFundamentalTypes(), "Context requires fundamental types");
100  }
101 
102  void CopyItemsSameDevice(
103  const caffe2::TypeMeta& meta,
104  size_t n,
105  const void* src,
106  void* dst) {
107  if (meta.copy()) {
108  EnforceMetaCopyOK();
109  meta.copy()(src, dst, n);
110  } else {
111  CopyBytesSameDevice(n * meta.itemsize(), src, dst);
112  }
113  }
114 
115  void CopyItemsFromCPU(
116  const caffe2::TypeMeta& meta,
117  size_t n,
118  const void* src,
119  void* dst) {
120  if (meta.copy()) {
121  EnforceMetaCopyOK();
122  meta.copy()(src, dst, n);
123  } else {
124  CopyBytesFromCPU(n * meta.itemsize(), src, dst);
125  }
126  }
127 
128  void CopyItemsToCPU(
129  const caffe2::TypeMeta& meta,
130  size_t n,
131  const void* src,
132  void* dst) {
133  if (meta.copy()) {
134  EnforceMetaCopyOK();
135  meta.copy()(src, dst, n);
136  } else {
137  CopyBytesToCPU(n * meta.itemsize(), src, dst);
138  }
139  }
140 };
141 
142 // Context constructor registry
143 C10_DECLARE_TYPED_REGISTRY(
144  ContextRegistry,
145  at::DeviceType,
147  std::unique_ptr,
148  at::Device);
149 
150 #define REGISTER_CONTEXT(type, ...) \
151  C10_REGISTER_TYPED_CLASS(ContextRegistry, type, __VA_ARGS__)
152 
153 inline std::unique_ptr<at::BaseContext> CreateContext(
154  const at::Device& device) {
155  return at::ContextRegistry()->Create(device.type(), device);
156 }
157 
158 } // namespace at
159 
160 namespace caffe2 {
161 
162 using at::BaseContext;
163 using at::CreateContext;
164 } // namespace caffe2
constexpr size_t itemsize() const noexcept
Returns the size of the item.
Definition: typeid.h:365
Virtual interface for the Context class in Caffe2.
Definition: context_base.h:32
Represents a a compute device on which a tensor is located.
Definition: Device.h:30
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Definition: blob.h:13
constexpr Copy * copy() const noexcept
Returns the typed copy function pointer for individual iterms.
Definition: typeid.h:380
Flush-To-Zero and Denormals-Are-Zero mode.
TypeMeta is a thin class that allows us to store the type of a container such as a blob...
Definition: typeid.h:324
DeviceType type() const noexcept
Returns the type of device this is.
Definition: Device.h:65