Caffe2 - C++ API
A deep learning, cross platform ML framework
blob.h
1 #pragma once
2 
3 #include <cstddef>
4 #include <sstream>
5 #include <type_traits>
6 #include <typeinfo>
7 #include <vector>
8 
9 #include <c10/util/intrusive_ptr.h>
10 #include <c10/util/typeid.h>
11 #include <c10/macros/Macros.h>
12 
13 namespace caffe2 {
14 
15 class Tensor;
16 
24 class CAFFE2_API Blob final : public c10::intrusive_ptr_target {
25  public:
29  Blob() noexcept : meta_(), pointer_(nullptr), has_ownership_(false) {}
30  ~Blob() {
31  Reset();
32  }
33 
34  Blob(Blob&& other) noexcept : Blob() {
35  swap(other);
36  }
37 
38  Blob& operator=(Blob&& other) noexcept {
39  Blob(std::move(other)).swap(*this);
40  return *this;
41  }
42 
46  template <class T>
47  bool IsType() const noexcept {
48  return meta_.Match<T>();
49  }
50 
54  const TypeMeta& meta() const noexcept {
55  return meta_;
56  }
57 
61  const char* TypeName() const noexcept {
62  return meta_.name();
63  }
64 
69  // TODO(jerryzh): add a Get(DeviceType) function?
70  template <class T>
71  const T& Get() const {
72  AT_ASSERTM(
73  IsType<T>(),
74  "wrong type for the Blob instance. Blob contains ",
75  meta_.name(),
76  " while caller expects ",
77  TypeMeta::TypeName<T>());
78  // TODO: after we add Get<Tensor>(DeviceType)
79  // and changed all the callsites, we can add
80  // a static assert here to enforce T != Tensor
81  return *static_cast<const T*>(pointer_);
82  }
83 
84  const void* GetRaw() const noexcept {
85  return pointer_;
86  }
87  void* GetRaw() noexcept {
88  return pointer_;
89  }
90 
99  template <class T>
101  static_assert(
102  std::is_default_constructible<T>::value,
103  "GetMutable can't be called with non-default-constructible types. "
104  "Try using specialized methods");
105  if (IsType<T>()) {
106  return static_cast<T*>(pointer_);
107  } else {
108  // TODO Re-enable logging
109  // VLOG(1) << "Create new mutable object " << TypeMeta::TypeName<T>();
110  return Reset<T>(new T());
111  }
112  }
113 
114  template <class T>
115  T* GetMutableOrNull() {
116  if (IsType<T>()) {
117  return static_cast<T*>(pointer_);
118  } else {
119  return nullptr;
120  }
121  }
122 
131  template <class T>
132  T* Reset(T* allocated) {
133  free_();
134  meta_ = TypeMeta::Make<T>();
135  pointer_ = static_cast<void*>(allocated);
136  has_ownership_ = true;
137  return allocated;
138  }
139 
150  template <class T>
151  typename std::remove_const<T>::type* ShareExternal(
152  typename std::remove_const<T>::type* allocated) {
153  return static_cast<T*>(ShareExternal(
154  static_cast<void*>(allocated),
155  TypeMeta::Make<typename std::remove_const<T>::type>()));
156  }
157 
158  // TODO Remove ShareExternal() and have Blob always own its content
159  void* ShareExternal(void* allocated, const TypeMeta& meta) {
160  free_();
161  meta_ = meta;
162  pointer_ = static_cast<void*>(allocated);
163  has_ownership_ = false;
164  return allocated;
165  }
166 
170  void Reset() {
171  free_();
172  pointer_ = nullptr;
173  meta_ = TypeMeta();
174  has_ownership_ = false;
175  }
176 
180  void swap(Blob& rhs) {
181  using std::swap;
182  swap(meta_, rhs.meta_);
183  swap(pointer_, rhs.pointer_);
184  swap(has_ownership_, rhs.has_ownership_);
185  }
186 
187  private:
188  void free_() {
189  if (has_ownership_) {
190  AT_ASSERTM(pointer_ != nullptr, "Can't have ownership of nullptr");
191  (*meta_.deleteFn())(pointer_);
192  }
193  }
194 
195  TypeMeta meta_;
196  void* pointer_ = nullptr;
197  bool has_ownership_ = false;
198 
199  C10_DISABLE_COPY_AND_ASSIGN(Blob);
200 };
201 
202 inline void swap(Blob& lhs, Blob& rhs) {
203  lhs.swap(rhs);
204 }
205 
206 inline std::ostream& operator<<(std::ostream& out, const Blob& v) {
207  return out << "Blob[" << v.TypeName() << "]";
208 }
209 
210 } // namespace caffe2
Blob is a general container that hosts a typed pointer.
Definition: blob.h:24
bool IsType() const noexcept
Checks if the content stored in the blob is of type T.
Definition: blob.h:47
std::remove_const< T >::type * ShareExternal(typename std::remove_const< T >::type *allocated)
Sets the underlying object to the allocated one, but does not take over the ownership of the passed i...
Definition: blob.h:151
Blob() noexcept
Initializes an empty Blob.
Definition: blob.h:29
void Reset()
Resets the Blob to an empty one.
Definition: blob.h:170
static TypeMeta Make()
Returns a TypeMeta object that corresponds to the typename T.
Definition: typeid.h:427
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Definition: blob.h:13
void swap(Blob &rhs)
Swaps the underlying storage of two blobs.
Definition: blob.h:180
const TypeMeta & meta() const noexcept
Returns the meta info of the blob.
Definition: blob.h:54
T * Reset(T *allocated)
Sets the underlying object to the allocated one.
Definition: blob.h:132
intrusive_ptr<T> is an alternative to shared_ptr<T> that has better performance because it does the r...
Definition: intrusive_ptr.h:35
T * GetMutable()
Gets a mutable pointer to the stored object.
Definition: blob.h:100
const char * TypeName() const noexcept
Returns a printable typename of the blob.
Definition: blob.h:61
TypeMeta is a thin class that allows us to store the type of a container such as a blob...
Definition: typeid.h:324
const T & Get() const
Gets the const reference of the stored object.
Definition: blob.h:71