ie_blob.h
Go to the documentation of this file.
1 // Copyright (C) 2018-2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 
5 /**
6  * @brief A header file for Blob and generic TBlob<>
7  *
8  * @file ie_blob.h
9  */
10 #pragma once
11 
12 #include <cstring>
13 #include <functional>
14 #include <map>
15 #include <memory>
16 #include <numeric>
17 #include <string>
18 #include <type_traits>
19 #include <utility>
20 #include <vector>
21 
22 #include "ie_allocator.hpp"
23 #include "ie_common.h"
24 #include "ie_layouts.h"
25 #include "ie_locked_memory.hpp"
26 #include "ie_precision.hpp"
28 #include "details/ie_exception.hpp"
30 
31 namespace InferenceEngine {
32 
33 /**
34  * @brief This class represents a universal container in the Inference Engine
35  *
36  * @note Each Blob implementation must be derived from this Blob class directly or indirectly
37  */
38 class INFERENCE_ENGINE_API_CLASS(Blob) {
39 public:
40  /**
41  * @brief A smart pointer containing Blob object
42  */
43  using Ptr = std::shared_ptr<Blob>;
44 
45  /**
46  * @brief A smart pointer to the const Blob object
47  */
48  using CPtr = std::shared_ptr<const Blob>;
49 
50  /**
51  * @brief Creates a TBlob<> object from a Data node
52  *
53  * @param data A reference to a smart pointer of the Data node
54  * @return Smart pointer to TBlob<> with the relevant C type to the precision of the data node
55  */
56  static Ptr CreateFromData(const DataPtr& data);
57 
58  /**
59  * @brief Blob virtual destructor
60  */
61  virtual ~Blob();
62 
63  /**
64  * @brief Checks if the Blob object can be cast to the type T*
65  *
66  * @tparam T Type to be checked. Must represent a class derived from the Blob
67  * @return true if this object can be dynamically cast to the type T*. Otherwise, false
68  */
69  template <typename T,
70  typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
71  typename std::enable_if<std::is_base_of<Blob, T>::value, int>::type = 0>
72  bool is() noexcept {
73  return dynamic_cast<T*>(this) != nullptr;
74  }
75 
76  /**
77  * @brief Checks if the Blob object can be cast to the type const T*
78  *
79  * @tparam T Type to be checked. Must represent a class derived from the Blob
80  * @return true if this object can be dynamically cast to the type const T*. Otherwise, false
81  */
82  template <typename T,
83  typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
84  typename std::enable_if<std::is_base_of<Blob, T>::value, int>::type = 0>
85  bool is() const noexcept {
86  return dynamic_cast<const T*>(this) != nullptr;
87  }
88 
89  /**
90  * @brief Casts this Blob object to the type T*.
91  *
92  * Use InferenceEngine::as() to operate with shared Blob objects instead of raw pointers
93  *
94  * @tparam T Type to cast to. Must represent a class derived from the Blob
95  * @return Raw pointer to the object of the type T or nullptr on error
96  */
97  template <typename T,
98  typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
99  typename std::enable_if<std::is_base_of<Blob, T>::value, int>::type = 0>
100  T* as() noexcept {
101  return dynamic_cast<T*>(this);
102  }
103 
104  /**
105  * @brief Casts this Blob object to the type const T*.
106  *
107  * Use InferenceEngine::as() to operate with shared Blob objects instead of raw pointers
108  *
109  * @tparam T Type to cast to. Must represent a class derived from the Blob
110  * @return Raw pointer to the object of the type const T or nullptr on error
111  */
112  template <typename T,
113  typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
114  typename std::enable_if<std::is_base_of<Blob, T>::value, int>::type = 0>
115  const T* as() const noexcept {
116  return dynamic_cast<const T*>(this);
117  }
118 
119  /**
120  * @brief Constructor. Creates an empty Blob object with the specified precision.
121  *
122  * @param tensorDesc Defines the layout and dims of the blob
123  */
124  explicit Blob(const TensorDesc& tensorDesc): tensorDesc(tensorDesc) {}
125 
126  /**
127  * @brief Returns the tensor description
128  * @return A const reference to a tensor descriptor
129  */
130  virtual const TensorDesc& getTensorDesc() const noexcept {
131  return tensorDesc;
132  }
133 
134  /**
135  * @brief Returns the tensor description
136  * @return A reference to a tensor descriptor
137  */
138  virtual TensorDesc& getTensorDesc() noexcept {
139  return tensorDesc;
140  }
141 
142  /**
143  * @brief By default, returns the total number of elements (a product of all the dims or 1 for scalar)
144  *
145  * Return value and its interpretation heavily depend on the blob type
146  *
147  * @return The total number of elements
148  */
149  virtual size_t size() const noexcept {
150  if (tensorDesc.getLayout() == Layout::SCALAR) return 1;
151  return product(tensorDesc.getDims());
152  }
153 
154  /**
155  * @brief Returns the size of the current Blob in bytes.
156  * @return Blob's size in bytes
157  */
158  virtual size_t byteSize() const noexcept {
159  return size() * element_size();
160  }
161 
162  /**
163  * @deprecated Cast to MemoryBlob and use its API instead.
164  * Blob class can represent compound blob, which do not refer to the only solid memory.
165  *
166  * @brief Provides the number of bytes per element.
167  *
168  * The overall Blob capacity is size() * element_size(). Abstract method.
169  *
170  * @return Returns the number of bytes per element
171  */
172  virtual size_t element_size() const noexcept = 0;
173 
174  /**
175  * @brief Allocates memory to store the data.
176  *
177  * Abstract method.
178  */
179  virtual void allocate() noexcept = 0;
180 
181  /**
182  * @brief Releases previously allocated data.
183  *
184  * Abstract method.
185  *
186  * @return `True` if deallocation happens successfully, `false` otherwise.
187  */
188  virtual bool deallocate() noexcept = 0;
189 
190  /**
191  * @deprecated Cast to MemoryBlob and use new wlock/rwlock API instead.
192  * Blob class can represent compound blob, which do not refer to the only solid memory.
193  * @brief Gets access to the allocated memory.
194  *
195  * Abstract method.
196  *
197  * @return A LockedMemory object
198  */
199  virtual LockedMemory<void> buffer() noexcept = 0;
200 
201  /**
202  * @deprecated Cast to MemoryBlob and use new MemoryBlob::rmap() function instead.
203  * Blob class can represent compound blob, which do not refer to the only solid memory.
204  * @brief Gets read-only access to the allocated memory.
205  *
206  * Abstract method.
207  *
208  * @return A LockedMemory object
209  */
210  virtual LockedMemory<const void> cbuffer() const noexcept = 0;
211 
212  /**
213  * @brief Creates a blob describing given ROI object based on the current blob with memory sharing.
214  *
215  * Note: default implementation throws "not implemented" exception.
216  *
217  * @param roi A ROI object inside of the current blob.
218  *
219  * @return A shared pointer to the newly created ROI blob.
220  */
221  virtual Blob::Ptr createROI(const ROI& roi) const;
222 
223 protected:
224  /**
225  * @brief The tensor descriptor of the given blob.
226  */
227  TensorDesc tensorDesc;
228 
229  /**
230  * @deprecated Cast to MemoryBlob and use its API instead.
231  * @brief Multiplies the dimension vector values.
232  *
233  * @param dims Reference to a vector with dimension values of type size_t
234  * @return Result of multiplication
235  */
236  static size_t product(const SizeVector& dims) noexcept {
237  if (dims.empty()) return 0;
238  return std::accumulate(std::begin(dims), std::end(dims), (size_t)1, std::multiplies<size_t>());
239  }
240 
241  /**
242  * @brief Gets an allocator for allocator-based blobs
243  *
244  * @return The allocator for allocator-based blobs or nullptr if there is none
245  */
246  virtual const std::shared_ptr<IAllocator>& getAllocator() const noexcept = 0;
247 
248  /**
249  * @brief Gets a handle to allocated memory
250  *
251  * @return The handle to allocated memory for allocator-based blobs or nullptr if there is none
252  */
253  virtual void* getHandle() const noexcept = 0;
254 
255  /// private
256  template <typename>
257  friend class TBlobProxy;
258 };
259 
260 /**
261  * @brief Helper cast function to work with shared Blob objects
262  * @param blob A blob to cast
263  * @return shared_ptr to the type T. Returned shared_ptr shares ownership of the object with the
264  * input Blob::Ptr
265  */
266 template <typename T,
267  typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
268  typename std::enable_if<std::is_base_of<Blob, T>::value, int>::type = 0>
269 std::shared_ptr<T> as(const Blob::Ptr& blob) noexcept {
270  return std::dynamic_pointer_cast<T>(blob);
271 }
272 
273 /**
274  * @brief Helper cast function to work with shared Blob objects
275  * @param blob A blob to cast
276  * @return shared_ptr to the type const T. Returned shared_ptr shares ownership of the object with
277  * the input Blob::Ptr
278  */
279 template <typename T,
280  typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
281  typename std::enable_if<std::is_base_of<Blob, T>::value, int>::type = 0>
282 std::shared_ptr<const T> as(const Blob::CPtr& blob) noexcept {
283  return std::dynamic_pointer_cast<const T>(blob);
284 }
285 
286 /**
287  * @brief This class implements a container object that represents a tensor in memory (host and
288  * remote/accelerated)
289  *
290  * @note Any Blob implementation that represents a concept of a tensor in memory (for example,
291  * TBlob) must be a subclass of MemoryBlob instead of Blob
292  */
293 class INFERENCE_ENGINE_API_CLASS(MemoryBlob): public Blob {
294 public:
295  /**
296  * @brief A smart pointer to the MemoryBlob object
297  */
298  using Ptr = std::shared_ptr<MemoryBlob>;
299 
300  /**
301  * @brief A smart pointer to the const MemoryBlob object
302  */
303  using CPtr = std::shared_ptr<const MemoryBlob>;
304 
305  /**
306  * @brief MemoryBlob virtual destructor
307  */
308  virtual ~MemoryBlob();
309 
310  /**
311  * @brief Constructor. Creates an empty MemoryBlob object with the specified precision.
312  *
313  * @param tensorDesc Defines the layout and dims of the blob
314  */
315  explicit MemoryBlob(const TensorDesc& tensorDesc): Blob(tensorDesc) {}
316 
317  /**
318  * @brief Returns the tensor description
319  */
320  const TensorDesc& getTensorDesc() const noexcept override {
321  return tensorDesc;
322  }
323 
324  /**
325  * @brief Returns the tensor description
326  */
327  TensorDesc& getTensorDesc() noexcept override {
328  return tensorDesc;
329  }
330 
331  /**
332  * @brief Returns the total number of elements, which is a product of all the dimensions
333  * @return The total number of elements
334  */
335  size_t size() const noexcept override {
336  if (tensorDesc.getLayout() == Layout::SCALAR) return 1;
337  return product(tensorDesc.getDims());
338  }
339 
340  /**
341  * @brief Returns the size of the current Blob in bytes calculated as `size() * element_size()`.
342  * @return Blob's size in bytes
343  */
344  size_t byteSize() const noexcept override {
345  return size() * element_size();
346  }
347 
348  /**
349  * @brief Provides the number of bytes per element.
350  * Abstract method.
351  * @return The number of bytes per element.
352  */
353  size_t element_size() const noexcept override = 0;
354 
355  /**
356  * @brief Allocates memory to store the data.
357  *
358  * Abstract method.
359  */
360  void allocate() noexcept override = 0;
361 
362  /**
363  * @brief Releases previously allocated data.
364  *
365  * Abstract method.
366  * @return `True` if deallocation happens successfully, `false` otherwise.
367  */
368  bool deallocate() noexcept override = 0;
369 
370  /**
371  * @deprecated Use wmap() or rwmap() API instead.
372  * @brief Gets access to the allocated memory.
373  *
374  * Abstract method.
375  *
376  * @return A LockedMemory object
377  */
378  LockedMemory<void> buffer() noexcept override = 0;
379 
380  /**
381  * @deprecated Use rmap() function instead.
382  * @brief Gets read-only access to the allocated memory.
383  *
384  * Abstract method.
385  *
386  * @return A LockedMemory object
387  */
388  LockedMemory<const void> cbuffer() const noexcept override = 0;
389 
390  /**
391  * @brief Gets read/write access to the memory in virtual space of the process.
392  * The function returns object which retains mapped memory.
393  * The memory been addressed in the MemoryBlob in general case can be allocated on remote device.
394  * This function maps remote memory to the memory in the virtual process space and after destruction
395  * of the LockedMemory will upload changed content to the accelerator.
396  *
397  * To avoid extra copy of data, you can use rmap() and wmap() functions.
398  *
399  * In case of memory originally allocated on the host, this function returns LockedMemory which will
400  * transparently refer to original memory address. No extra copy will happen
401  *
402  * In general case, pointer received from that LockedMemory becomes invalid just after
403  * destruction of LockedMemory instance. Keep Locked memory alive while you need to address memory
404  * in the process on the host.
405  *
406  * Abstract method.
407  *
408  * @return A LockedMemory object
409  */
410  virtual LockedMemory<void> rwmap()noexcept = 0;
411 
412  /**
413  * @brief Gets read only access to the memory in virtual space of the process.
414  * The function returns object which retains mapped memory.
415  *
416  * The memory been addressed in the MemoryBlob in general case can be allocated on remote device.
417  * This function copies remote memory to the memory in the virtual process space and after
418  * destruction of the LockedMemory it will not upload host memory back, because it is expected that
419  * content is not changed.
420  *
421  * To have an ability change content, you can use rwmap() and wmap() functions.
422  *
423  * In case of memory originally allocated on the host, this function returns LockedMemory which will
424  * transparently refer to original memory address. No extra copy will happen
425  *
426  * In general case, pointer received from that LockedMemory becomes invalid just after destruction
427  * of LockedMemory instance. Keep Locked memory alive while you need to address memory in the
428  * process on the host.
429  *
430  * Abstract method.
431  *
432  * @return A LockedMemory object
433  */
434  virtual LockedMemory<const void> rmap()const noexcept = 0;
435 
436  /**
437  * @brief Gets "write only direction" access to the memory in virtual space of the process.
438  * The function returns object which retains memory to be uploaded on device.
439  *
440  * The memory been addressed in the MemoryBlob in general case can be allocated on remote device.
441  * This function does not copy of the content from the device to the memory in the virtual process
442  * space, the content of the memory just after calling of this function is not specified. After
443  * destruction of the LockedMemory, content will be upload host memory.
444  * In the same time there is no abilities to restrict reading from the memory, you need to care of
445  * reading from memory got by wmap(), it might have sense in some cases like filling of content and
446  * before uploading to device
447  *
448  * To access data stored in the blob, you can use rwmap() and rmap() functions.
449  *
450  * In case of memory originally allocated on the host, this function returns LockedMemory which will
451  * transparently refer to original memory address. No extra copy will happen
452  *
453  * In general case, pointer received from that LockedMemory becomes invalid just after destruction
454  * of LockedMemory instance. Keep Locked memory alive while you need to address memory in the
455  * process on the host.
456  *
457  * Abstract method.
458  *
459  * @return A LockedMemory object
460  */
461  virtual LockedMemory<void> wmap()noexcept = 0;
462 
463 protected:
464  /**
465  * @brief Gets the allocator for allocator-based blobs.
466  *
467  * @return The allocator for allocator-based blobs or if there is none then a nullptr.
468  */
469  const std::shared_ptr<IAllocator>& getAllocator() const noexcept override = 0;
470 
471  /**
472  * @brief Gets the handle to allocated memory.
473  *
474  * @return The handle to allocated memory for allocator-based blobs or if there is none then a nullptr.
475  */
476  void* getHandle() const noexcept override = 0;
477 
478  /// private
479  template <typename>
480  friend class TBlobProxy;
481 };
482 
483 /**
484  * @brief This is a convenient type for working with a map containing pairs(string, pointer to a Blob instance).
485  */
486 using BlobMap = std::map<std::string, Blob::Ptr>;
487 
488 /**
489  * @brief Represents real host memory allocated for a Tensor/Blob per C type.
490  */
491 template <typename T, typename = std::enable_if<std::is_pod<T>::value>>
492 class TBlob : public MemoryBlob {
493  template <typename, typename>
494  friend class TBlob;
495 
496 public:
497  /**
498  * @brief Smart Pointer to this TBlob object.
499  */
500  using Ptr = std::shared_ptr<TBlob<T>>;
501 
502  /**
503  * @brief Creates a TBlob object with the specified dimensions and layout but does not allocate the memory.
504  *
505  * Use the allocate() method to allocate memory.
506  *
507  * @param tensorDesc Tensor description
508  */
509  explicit TBlob(const TensorDesc& tensorDesc): MemoryBlob(tensorDesc) {}
510 
511  /**
512  * @brief The constructor creates a TBlob object with the specified dimensions and layout
513  * on the pre-allocated memory.
514  *
515  * The allocate() call is not required.
516  *
517  * @param tensorDesc Tensor description
518  * @param ptr Pointer to the pre-allocated memory
519  * @param data_size Length of the pre-allocated array. If not set, size is assumed equal
520  * to the dot product of dims.
521  */
522  TBlob(const TensorDesc& tensorDesc, T* ptr, size_t data_size = 0): MemoryBlob(tensorDesc) {
523  if (data_size == 0) {
524  data_size = size();
525  }
526 
527  if (data_size != 0 && ptr == nullptr) {
528  THROW_IE_EXCEPTION << "Using Blob on external nullptr memory";
529  }
530 
531  _allocator = details::make_pre_allocator(ptr, data_size);
532  // blob on attached memory is always allocated, so we are not forcing the user to call allocate()
533  allocate();
534  }
535 
536  /**
537  * @brief Creates a TBlob object with the specified dimensions, layout and custom memory allocator but does not
538  * allocate the memory.
539  *
540  * @param tensorDesc Tensor description
541  * @param alloc An allocator
542  */
543  TBlob(const TensorDesc& tensorDesc, const std::shared_ptr<IAllocator>& alloc)
544  : MemoryBlob(tensorDesc), _allocator(alloc) {
545  if (_allocator == nullptr) THROW_IE_EXCEPTION << "TBlob allocator was not initialized.";
546  }
547 
548  /**
549  * @brief The copy constructor data is reallocated and copied from the source to the target blob.
550  *
551  * @param blob Source blob
552  */
553  TBlob(const TBlob<T>& blob): MemoryBlob(blob.getTensorDesc()) {
554  copyFrom(blob);
555  }
556 
557  /**
558  * @brief A move constructor.
559  *
560  * @param blob rvalue to make a move from
561  */
562  TBlob(TBlob<T>&& blob): MemoryBlob(blob.getTensorDesc()) {
563  moveFrom(blob);
564  }
565 
566  /**
567  * @brief Copy operator for the TBlob object.
568  *
569  * @param blob object reference to copy from
570  * @return Newly copied object
571  */
572  TBlob& operator=(const TBlob& blob) {
573  copyFrom(blob);
574  return *this;
575  }
576 
577  /**
578  *@brief Virtual destructor.
579  */
580 
581 #if defined(__clang__) && !defined(__SYCL_COMPILER_VERSION)
582  virtual ~TBlob();
583 #else
584  virtual ~TBlob() {
585  free();
586  }
587 #endif // __clang__ && !__SYCL_COMPILER_VERSION
588 
589  /**
590  * @brief Gets the size of the given type.
591  *
592  * @return Size of the type
593  */
594  size_t element_size() const noexcept override {
595  return sizeof(T);
596  }
597 
598  /**
599  * @brief Creates an new empty rvalue LockedMemory object.
600  *
601  * @return rvalue for the empty locked object of type T
602  */
603  virtual LockedMemory<T> data() noexcept {
604  return std::move(lockme<T>());
605  }
606 
607  /**
608  * @brief Creates a new empty rvalue read-only LockedMemory object.
609  *
610  * @return rvalue for the empty locked const object of type T.
611  */
612  virtual LockedMemory<const T> readOnly() const noexcept {
613  return std::move(lockme<const T>());
614  }
615 
616  /**
617  * @brief Allocates or reallocates memory
618  */
619  void allocate() noexcept override {
620  const auto allocator = getAllocator();
621  const auto rawHandle = allocator->alloc(size() * sizeof(T));
622 
623  if (rawHandle == nullptr) {
624  return;
625  }
626 
627  _handle.reset(
628  rawHandle,
629  [allocator](void* rawHandle) {
630  allocator->free(rawHandle);
631  });
632  }
633 
634  /**
635  * @brief Frees all allocated data
636  */
637  bool deallocate() noexcept override {
638  return free();
639  }
640 
641  /**
642  * @brief Creates a new LockedMemory instance holding void pointer.
643  *
644  * @return LockedMemory instance holding void pointer
645  */
646  LockedMemory<void> buffer() noexcept override {
647  return std::move(lockme<void>());
648  }
649 
650  /**
651  * @brief Creates a new LockedMemory instance holding constant void pointer.
652  *
653  * @return LockedMemory instance holding constant void pointer
654  */
655  LockedMemory<const void> cbuffer() const noexcept override {
656  return std::move(lockme<const void>());
657  }
658 
659  LockedMemory<void> rwmap()noexcept override {
660  return std::move(lockme<void>());
661  }
662 
663  LockedMemory<const void> rmap() const noexcept override {
664  return std::move(lockme<const void>());
665  }
666  LockedMemory<void> wmap()noexcept override {
667  return std::move(lockme<void>());
668  }
669 
670  Blob::Ptr createROI(const ROI& roi) const override {
671  return Blob::Ptr(new TBlob<T>(*this, roi));
672  }
673 
674  /**
675  * @brief Gets BlobIterator for the data.
676  *
677  * Enables a ranged loop support for the TBlob object.
678  *
679  * @return BlobIterator object of type T
680  */
681  details::BlobIterator<T> begin() {
682  return details::BlobIterator<T>(data());
683  }
684 
685  /**
686  * @brief Gets BlobIterator for the end of data.
687  *
688  * Enables a ranged loop support for the TBlob object.
689  *
690  * @return BlobIterator object of type T representing end of the data
691  */
692  details::BlobIterator<T> end() {
693  return details::BlobIterator<T>(data(), size());
694  }
695 
696  /**
697  * @brief Gets a const BlobIterator for the read-only data.
698  *
699  * Enables a ranged loop support for the TBlob object.
700  *
701  * @return BlobIterator object of type const T
702  */
703  details::BlobIterator<const T> begin() const {
704  return details::BlobIterator<const T>(readOnly());
705  }
706 
707  /**
708  * @brief Gets a const BlobIterator for the end of read-only data.
709  *
710  * Enables a ranged loop support for the TBlob object.
711  *
712  * @return BlobIterator object of type const T representing end of data
713  */
714  details::BlobIterator<const T> end() const {
715  return details::BlobIterator<const T>(readOnly(), size());
716  }
717 
718 protected:
719  /**
720  * @brief Local instance of IAllocator to manipulate memory.
721  */
722  mutable std::shared_ptr<IAllocator> _allocator;
723 
724  /**
725  * @brief A handle for the stored memory returned from _allocator.alloc().
726  */
727  std::shared_ptr<void> _handle;
728 
729  /**
730  * @brief Copies dimensions and data from the TBlob object.
731  *
732  * @param blob object reference to copy from
733  */
734  void copyFrom(const TBlob<T>& blob) {
735  tensorDesc = blob.tensorDesc;
736  this->allocate();
737  auto memptr = data();
738  memcpy(memptr, blob.readOnly(), byteSize());
739  }
740 
741  /**
742  * @brief Swaps memory handlers between the current blob and the given one.
743  *
744  * @tparam U Type of the blob to move from
745  * @param blob TBlob instance to move from
746  */
747  template <class U>
748  void moveFrom(TBlob<U>& blob) {
749  tensorDesc = blob.tensorDesc;
750  this->_allocator = std::move(blob._allocator);
751  std::swap(this->_handle, blob._handle);
752  }
753 
754  /**
755  * @brief Frees handler and cleans up the stored data.
756  */
757  virtual bool free() {
758  bool bCanRelease = _handle != nullptr;
759  _handle.reset();
760  return bCanRelease;
761  }
762 
763  /**
764  * @brief Creates a LockedMemory instance.
765  *
766  * @tparam S Type of the LockedMemory to be created
767  * @return A created instance of LockedMemory
768  */
769  template <class S>
771  return LockedMemory<S>(_allocator.get(), getHandle(), 0);
772  }
773 
774  /**
775  * @brief Gets an allocator or creates a default one.
776  *
777  * @return IAllocator instance
778  */
779  const std::shared_ptr<IAllocator>& getAllocator() const noexcept override {
780  // in case when constructor without allocator was used
781  if (!_allocator) {
782  _allocator = shared_from_irelease(CreateDefaultAllocator());
783  }
784 
785  return _allocator;
786  }
787 
788  /**
789  * @brief Returns handle to the stored data.
790  */
791  void* getHandle() const noexcept override {
792  return _handle.get();
793  }
794 
795  /**
796  * @brief Creates a blob from the existing blob with a given ROI
797  * @param origBlob An original blob
798  * @param roi A ROI object
799  */
800  TBlob(const TBlob& origBlob, const ROI& roi) :
801  MemoryBlob(make_roi_desc(origBlob.getTensorDesc(), roi, true)),
802  _allocator(origBlob._allocator) {
803  IE_ASSERT(origBlob._handle != nullptr)
804  << "Original Blob must be allocated before ROI creation";
805 
806  _handle = origBlob._handle;
807  }
808 };
809 
810 #if defined(__clang__) && !defined(__SYCL_COMPILER_VERSION)
811 extern template class INFERENCE_ENGINE_API_CLASS(InferenceEngine::TBlob<float>);
812 extern template class INFERENCE_ENGINE_API_CLASS(InferenceEngine::TBlob<double>);
813 extern template class INFERENCE_ENGINE_API_CLASS(InferenceEngine::TBlob<int8_t>);
814 extern template class INFERENCE_ENGINE_API_CLASS(InferenceEngine::TBlob<uint8_t>);
815 extern template class INFERENCE_ENGINE_API_CLASS(InferenceEngine::TBlob<int16_t>);
816 extern template class INFERENCE_ENGINE_API_CLASS(InferenceEngine::TBlob<uint16_t>);
817 extern template class INFERENCE_ENGINE_API_CLASS(InferenceEngine::TBlob<int32_t>);
818 extern template class INFERENCE_ENGINE_API_CLASS(InferenceEngine::TBlob<uint32_t>);
819 extern template class INFERENCE_ENGINE_API_CLASS(InferenceEngine::TBlob<long>);
820 extern template class INFERENCE_ENGINE_API_CLASS(InferenceEngine::TBlob<long long>);
821 extern template class INFERENCE_ENGINE_API_CLASS(InferenceEngine::TBlob<unsigned long>);
822 extern template class INFERENCE_ENGINE_API_CLASS(InferenceEngine::TBlob<unsigned long long>);
823 #endif // __clang__ && !__SYCL_COMPILER_VERSION
824 
825 /**
826  * @brief Creates a blob with the given tensor descriptor.
827  *
828  * @tparam Type Type of the shared pointer to be created
829  * @param tensorDesc Tensor descriptor for Blob creation
830  * @return A shared pointer to the newly created blob of the given type
831  */
832 template <typename Type>
834  if (!tensorDesc.getPrecision().hasStorageType<Type>())
835  THROW_IE_EXCEPTION << "Cannot make shared blob! "
836  << "The blob type cannot be used to store objects of current precision";
837  return std::make_shared<InferenceEngine::TBlob<Type>>(tensorDesc);
838 }
839 
840 /**
841  * @brief Creates a blob with the given tensor descriptor from the pointer to the pre-allocated memory.
842  *
843  * @tparam Type Type of the shared pointer to be created
844  * @param tensorDesc TensorDesc for Blob creation
845  * @param ptr Pointer to the pre-allocated memory
846  * @param size Length of the pre-allocated array
847  * @return A shared pointer to the newly created blob of the given type
848  */
849 template <typename Type>
850 inline typename InferenceEngine::TBlob<Type>::Ptr make_shared_blob(const TensorDesc& tensorDesc, Type* ptr,
851  size_t size = 0) {
852  if (!tensorDesc.getPrecision().hasStorageType<Type>())
853  THROW_IE_EXCEPTION << "Cannot make shared blob! "
854  << "The blob type cannot be used to store objects of current precision";
855  return std::make_shared<InferenceEngine::TBlob<Type>>(tensorDesc, ptr, size);
856 }
857 
858 /**
859  * @brief Creates a blob with the given tensor descriptor and allocator.
860  *
861  * @tparam Type Type of the shared pointer to be created
862  * @param tensorDesc Tensor descriptor for Blob creation
863  * @param alloc Shared pointer to IAllocator to use in the blob
864  * @return A shared pointer to the newly created blob of the given type
865  */
866 template <typename Type>
868  const TensorDesc& tensorDesc, const std::shared_ptr<InferenceEngine::IAllocator>& alloc) {
869  if (!tensorDesc.getPrecision().hasStorageType<Type>())
870  THROW_IE_EXCEPTION << "Cannot make shared blob! "
871  << "The blob type cannot be used to store objects of current precision";
872  return std::make_shared<InferenceEngine::TBlob<Type>>(tensorDesc, alloc);
873 }
874 
875 /**
876  * @brief Creates a copy of given TBlob instance.
877  *
878  * @tparam TypeTo Type of the shared pointer to be created
879  * @param arg given pointer to blob
880  * @return A shared pointer to the newly created blob of the given type
881  */
882 template <typename TypeTo>
884  return std::make_shared<InferenceEngine::TBlob<TypeTo>>(arg);
885 }
886 
887 /**
888  * @brief Creates a Blob object of the specified type
889  *
890  * @param args Constructor arguments for the Blob object
891  * @return A shared pointer to the newly created Blob object
892  */
893 template <typename T, typename... Args, typename std::enable_if<std::is_base_of<Blob, T>::value, int>::type = 0>
894 std::shared_ptr<T> make_shared_blob(Args&&... args) {
895  return std::make_shared<T>(std::forward<Args>(args)...);
896 }
897 
898 /**
899  * @brief Creates a blob describing given ROI object based on the given blob with pre-allocated memory.
900  *
901  * @param inputBlob original blob with pre-allocated memory.
902  * @param roi A ROI object inside of the original blob.
903  * @return A shared pointer to the newly created blob.
904  */
905 INFERENCE_ENGINE_API_CPP(Blob::Ptr) make_shared_blob(const Blob::Ptr& inputBlob, const ROI& roi);
906 
907 } // namespace InferenceEngine
This class represents a universal container in the Inference Engine.
Definition: ie_blob.h:38
std::shared_ptr< const Blob > CPtr
A smart pointer to the const Blob object.
Definition: ie_blob.h:48
virtual size_t size() const noexcept
By default, returns the total number of elements (a product of all the dims or 1 for scalar)
Definition: ie_blob.h:149
virtual size_t byteSize() const noexcept
Returns the size of the current Blob in bytes.
Definition: ie_blob.h:158
bool is() const noexcept
Checks if the Blob object can be cast to the type const T*.
Definition: ie_blob.h:85
virtual ~Blob()
Blob virtual destructor.
bool is() noexcept
Checks if the Blob object can be cast to the type T*.
Definition: ie_blob.h:72
const T * as() const noexcept
Casts this Blob object to the type const T*.
Definition: ie_blob.h:115
virtual TensorDesc & getTensorDesc() noexcept
Returns the tensor description.
Definition: ie_blob.h:138
std::shared_ptr< Blob > Ptr
A smart pointer containing Blob object.
Definition: ie_blob.h:43
T * as() noexcept
Casts this Blob object to the type T*.
Definition: ie_blob.h:100
virtual const std::shared_ptr< IAllocator > & getAllocator() const noexcept=0
Gets an allocator for allocator-based blobs.
virtual const TensorDesc & getTensorDesc() const noexcept
Returns the tensor description.
Definition: ie_blob.h:130
Blob(const TensorDesc &tensorDesc)
Constructor. Creates an empty Blob object with the specified precision.
Definition: ie_blob.h:124
static Ptr CreateFromData(const DataPtr &data)
Creates a TBlob<> object from a Data node.
virtual size_t element_size() const noexcept=0
Provides the number of bytes per element.
Allocator concept to be used for memory management and is used as part of the Blob.
Definition: ie_allocator.hpp:29
This class is for read-only segments.
Definition: ie_locked_memory.hpp:319
This class is for <void*> data and allows casting to any pointers.
Definition: ie_locked_memory.hpp:219
This class represents locked memory for read/write memory.
Definition: ie_locked_memory.hpp:111
This class implements a container object that represents a tensor in memory (host and remote/accelera...
Definition: ie_blob.h:293
const TensorDesc & getTensorDesc() const noexcept override
Returns the tensor description.
Definition: ie_blob.h:320
size_t element_size() const noexcept override=0
Provides the number of bytes per element. Abstract method.
size_t size() const noexcept override
Returns the total number of elements, which is a product of all the dimensions.
Definition: ie_blob.h:335
virtual ~MemoryBlob()
MemoryBlob virtual destructor.
MemoryBlob(const TensorDesc &tensorDesc)
Constructor. Creates an empty MemoryBlob object with the specified precision.
Definition: ie_blob.h:315
size_t byteSize() const noexcept override
Returns the size of the current Blob in bytes calculated as size() * element_size().
Definition: ie_blob.h:344
TensorDesc & getTensorDesc() noexcept override
Returns the tensor description.
Definition: ie_blob.h:327
bool hasStorageType(const char *typeName=nullptr) const noexcept
checks whether given storage class T can be used to store objects of current precision
Definition: ie_precision.hpp:99
Represents real host memory allocated for a Tensor/Blob per C type.
Definition: ie_blob.h:492
details::BlobIterator< T > end()
Gets BlobIterator for the end of data.
Definition: ie_blob.h:692
TBlob & operator=(const TBlob &blob)
Copy operator for the TBlob object.
Definition: ie_blob.h:572
virtual bool free()
Frees handler and cleans up the stored data.
Definition: ie_blob.h:757
std::shared_ptr< void > _handle
A handle for the stored memory returned from _allocator.alloc().
Definition: ie_blob.h:727
details::BlobIterator< const T > end() const
Gets a const BlobIterator for the end of read-only data.
Definition: ie_blob.h:714
TBlob(TBlob< T > &&blob)
A move constructor.
Definition: ie_blob.h:562
LockedMemory< void > buffer() noexcept override
Creates a new LockedMemory instance holding void pointer.
Definition: ie_blob.h:646
TBlob(const TensorDesc &tensorDesc, const std::shared_ptr< IAllocator > &alloc)
Creates a TBlob object with the specified dimensions, layout and custom memory allocator but does not...
Definition: ie_blob.h:543
std::shared_ptr< IAllocator > _allocator
Local instance of IAllocator to manipulate memory.
Definition: ie_blob.h:722
Blob::Ptr createROI(const ROI &roi) const override
Creates a blob describing given ROI object based on the current blob with memory sharing.
Definition: ie_blob.h:670
void allocate() noexcept override
Allocates or reallocates memory.
Definition: ie_blob.h:619
details::BlobIterator< T > begin()
Gets BlobIterator for the data.
Definition: ie_blob.h:681
virtual LockedMemory< const T > readOnly() const noexcept
Creates a new empty rvalue read-only LockedMemory object.
Definition: ie_blob.h:612
LockedMemory< void > rwmap() noexcept override
Gets read/write access to the memory in virtual space of the process. The function returns object whi...
Definition: ie_blob.h:659
TBlob(const TensorDesc &tensorDesc)
Creates a TBlob object with the specified dimensions and layout but does not allocate the memory.
Definition: ie_blob.h:509
LockedMemory< const void > rmap() const noexcept override
Gets read only access to the memory in virtual space of the process. The function returns object whic...
Definition: ie_blob.h:663
void moveFrom(TBlob< U > &blob)
Swaps memory handlers between the current blob and the given one.
Definition: ie_blob.h:748
TBlob(const TensorDesc &tensorDesc, T *ptr, size_t data_size=0)
The constructor creates a TBlob object with the specified dimensions and layout on the pre-allocated ...
Definition: ie_blob.h:522
TBlob(const TBlob &origBlob, const ROI &roi)
Creates a blob from the existing blob with a given ROI.
Definition: ie_blob.h:800
LockedMemory< const void > cbuffer() const noexcept override
Creates a new LockedMemory instance holding constant void pointer.
Definition: ie_blob.h:655
void * getHandle() const noexcept override
Returns handle to the stored data.
Definition: ie_blob.h:791
void copyFrom(const TBlob< T > &blob)
Copies dimensions and data from the TBlob object.
Definition: ie_blob.h:734
bool deallocate() noexcept override
Frees all allocated data.
Definition: ie_blob.h:637
virtual ~TBlob()
Virtual destructor.
Definition: ie_blob.h:584
LockedMemory< void > wmap() noexcept override
Gets "write only direction" access to the memory in virtual space of the process. The function return...
Definition: ie_blob.h:666
virtual LockedMemory< T > data() noexcept
Creates an new empty rvalue LockedMemory object.
Definition: ie_blob.h:603
details::BlobIterator< const T > begin() const
Gets a const BlobIterator for the read-only data.
Definition: ie_blob.h:703
std::shared_ptr< TBlob< T > > Ptr
Smart Pointer to this TBlob object.
Definition: ie_blob.h:500
TBlob(const TBlob< T > &blob)
The copy constructor data is reallocated and copied from the source to the target blob.
Definition: ie_blob.h:553
size_t element_size() const noexcept override
Gets the size of the given type.
Definition: ie_blob.h:594
LockedMemory< S > lockme() const
Creates a LockedMemory instance.
Definition: ie_blob.h:770
const std::shared_ptr< IAllocator > & getAllocator() const noexcept override
Gets an allocator or creates a default one.
Definition: ie_blob.h:779
This class defines Tensor description.
Definition: ie_layouts.h:158
const Precision & getPrecision() const
Returns the memory precision.
Definition: ie_layouts.h:247
A header file that provides Allocator interface.
A header file for the BlobIterator class.
This is a header file with common inference engine definitions.
A header file for the main Inference Engine exception.
#define THROW_IE_EXCEPTION
A macro used to throw general exception with a description.
Definition: ie_exception.hpp:25
#define IE_ASSERT(EXPRESSION)
Uses assert() function if NDEBUG is not defined, InferenceEngine exception otherwise.
Definition: ie_exception.hpp:54
A header file for data layouts and conversion between them.
A header file for generic LockedMemory<> and different variations of locks.
The header file defines utility PreAllocator class.
A header file that provides class for describing precision of data.
Inference Engine C++ API.
Definition: cldnn_config.hpp:15
InferenceEngine::TBlob< Type >::Ptr make_shared_blob(const TensorDesc &tensorDesc)
Creates a blob with the given tensor descriptor.
Definition: ie_blob.h:833
std::shared_ptr< T > as(const Blob::Ptr &blob) noexcept
Helper cast function to work with shared Blob objects.
Definition: ie_blob.h:269
InferenceEngine::IAllocator * CreateDefaultAllocator() noexcept
Creates the default implementation of the Inference Engine allocator per plugin.
std::shared_ptr< Data > DataPtr
Smart pointer to Data.
Definition: ie_common.h:37
std::vector< size_t > SizeVector
Represents tensor size.
Definition: ie_common.h:27
std::map< std::string, Blob::Ptr > BlobMap
This is a convenient type for working with a map containing pairs(string, pointer to a Blob instance)...
Definition: ie_blob.h:486
TensorDesc make_roi_desc(const TensorDesc &origDesc, const ROI &roi, bool useOrigMemDesc)
Creates a TensorDesc object for ROI.
This structure describes ROI data for image-like tensors.
Definition: ie_layouts.h:329