Caffe2 - C++ API
A deep learning, cross platform ML framework
ideep_context.h
1 #pragma once
2 
3 #include <cstdlib>
4 #include <ctime>
5 #include <random>
6 
7 #include <caffe2/core/context.h>
8 
9 namespace caffe2 {
10 
11 class IDEEPContext final : public BaseContext {
12  public:
13  typedef std::mt19937 rand_gen_type;
14  IDEEPContext() : random_seed_(RandomNumberSeed()) {}
15  explicit IDEEPContext(const DeviceOption& option)
16  : random_seed_(
17  option.has_random_seed() ? option.random_seed()
18  : RandomNumberSeed()) {
19  CAFFE_ENFORCE_EQ(option.device_type(), PROTO_IDEEP);
20  }
21  explicit IDEEPContext(const at::Device& device)
22  : IDEEPContext(DeviceToOption(device)) {}
23 
24  ~IDEEPContext() noexcept override {}
25 
26  inline void SwitchToDevice(int /*stream_id*/) {}
27  using BaseContext::SwitchToDevice;
28 
29  inline void WaitEvent(const Event& ev) {
30  ev.Wait(IDEEP, this);
31  }
32 
33  inline void Record(Event* ev, const char* err_msg = nullptr) const {
34  CAFFE_ENFORCE(ev, "Event must not be null.");
35  ev->Record(IDEEP, this, err_msg);
36  }
37 
38 
39  inline void FinishDeviceComputation() {}
40 
41  inline rand_gen_type& RandGenerator() {
42  if (!random_generator_.get()) {
43  random_generator_.reset(new rand_gen_type(random_seed_));
44  }
45  return *random_generator_.get();
46  }
47 
48  inline static at::DataPtr New(size_t nbytes) {
49  return GetAllocator(CPU)->allocate(nbytes);
50  }
51 
52  void CopyBytesSameDevice(size_t nbytes, const void* src, void* dst) override {
53  if (nbytes == 0) {
54  return;
55  }
56  CAFFE_ENFORCE(src);
57  CAFFE_ENFORCE(dst);
58  memcpy(dst, src, nbytes);
59  }
60 
61  void CopyBytesFromCPU(size_t nbytes, const void* src, void* dst) override {
62  CopyBytesSameDevice(nbytes, src, dst);
63  }
64 
65  void CopyBytesToCPU(size_t nbytes, const void* src, void* dst) override {
66  CopyBytesSameDevice(nbytes, src, dst);
67  }
68 
69  bool SupportsNonFundamentalTypes() const override {
70  // IDEEP meta copy is OK
71  return true;
72  }
73 
74  // Two copy functions that deals with cross-device copies.
75  template <class SrcContext, class DstContext>
76  inline void CopyBytes(size_t nbytes, const void* src, void* dst);
77 
78  template <typename T, class SrcContext, class DstContext>
79  inline void Copy(size_t n, const T* src, T* dst) {
80  if (std::is_fundamental<T>::value) {
81  CopyBytes<SrcContext, DstContext>(
82  n * sizeof(T),
83  static_cast<const void*>(src),
84  static_cast<void*>(dst));
85  } else {
86  for (size_t i = 0; i < n; ++i) {
87  dst[i] = src[i];
88  }
89  }
90  }
91 
92  template <class SrcContext, class DstContext>
93  inline void
94  CopyItems(const TypeMeta& meta, size_t n, const void* src, void* dst) {
95  if (meta.copy()) {
96  meta.copy()(src, dst, n);
97  } else {
98  CopyBytes<SrcContext, DstContext>(n * meta.itemsize(), src, dst);
99  }
100  }
101 
102  static bool HasAsyncPartDefault() {
103  return false;
104  }
105 
106  static bool SupportsAsyncScheduling() {
107  return false;
108  }
109 
110  static bool IsStreamFree(const DeviceOption& /* unused */, int /* unused */) {
111  return true;
112  }
113 
114  at::Device device() const override {
115  return at::Device(IDEEP);
116  }
117 
118  DeviceType device_type() const override {
119  return IDEEP;
120  }
121 
122  static constexpr DeviceType GetDeviceType() {
123  return IDEEP;
124  }
125 
126  protected:
127  // TODO(jiayq): instead of hard-coding a generator, make it more flexible.
128  int random_seed_{1701};
129  std::unique_ptr<rand_gen_type> random_generator_;
130 };
131 
132 template <>
133 inline void IDEEPContext::CopyBytes<IDEEPContext, IDEEPContext>(
134  size_t nbytes,
135  const void* src,
136  void* dst) {
137  if (nbytes == 0) {
138  return;
139  }
140  CAFFE_ENFORCE(src);
141  CAFFE_ENFORCE(dst);
142  memcpy(dst, src, nbytes);
143 }
144 
145 template <>
146 inline void IDEEPContext::CopyBytes<CPUContext, IDEEPContext>(
147  size_t nbytes,
148  const void* src,
149  void* dst) {
150  if (nbytes == 0) {
151  return;
152  }
153  CAFFE_ENFORCE(src);
154  CAFFE_ENFORCE(dst);
155  memcpy(dst, src, nbytes);
156 }
157 
158 template <>
159 inline void IDEEPContext::CopyBytes<IDEEPContext, CPUContext>(
160  size_t nbytes,
161  const void* src,
162  void* dst) {
163  if (nbytes == 0) {
164  return;
165  }
166  CAFFE_ENFORCE(src);
167  CAFFE_ENFORCE(dst);
168  memcpy(dst, src, nbytes);
169 }
170 
171 } // 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
uint32_t RandomNumberSeed()
A function to generate a random number seed that is unique in a best-effort basis, using an ever-incrementing seed and the current time.
Definition: context.cc:10
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
TypeMeta is a thin class that allows us to store the type of a container such as a blob...
Definition: typeid.h:324