VTK-m  2.2
DeviceAdapterMemoryManager.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_cont_internal_DeviceAdapterMemoryManager_h
11 #define vtk_m_cont_internal_DeviceAdapterMemoryManager_h
12 
14 
15 #include <vtkm/Flags.h>
16 #include <vtkm/Types.h>
17 
19 
20 #include <cstring>
21 #include <memory>
22 #include <vector>
23 
24 namespace vtkm
25 {
26 
28 
29 namespace cont
30 {
31 namespace internal
32 {
33 
34 struct TransferredBuffer;
35 
36 namespace detail
37 {
38 
39 struct BufferInfoInternals;
40 
41 } // namespace detail
42 
43 class VTKM_CONT_EXPORT BufferInfo
44 {
45 public:
49  VTKM_CONT void* GetPointer() const;
50 
53  VTKM_CONT vtkm::BufferSizeType GetSize() const;
54 
60  VTKM_CONT vtkm::cont::DeviceAdapterId GetDevice() const;
61 
62  VTKM_CONT BufferInfo();
63  VTKM_CONT ~BufferInfo();
64 
65  VTKM_CONT BufferInfo(const BufferInfo& src);
66  VTKM_CONT BufferInfo(BufferInfo&& src);
67 
68  VTKM_CONT BufferInfo& operator=(const BufferInfo& src);
69  VTKM_CONT BufferInfo& operator=(BufferInfo&& src);
70 
75  VTKM_CONT BufferInfo(const BufferInfo& src, vtkm::cont::DeviceAdapterId device);
76  VTKM_CONT BufferInfo(BufferInfo&& src, vtkm::cont::DeviceAdapterId device);
77 
80  using Deleter = void(void* container);
81 
84  using Reallocater = void(void*& memory,
85  void*& container,
86  vtkm::BufferSizeType oldSize,
87  vtkm::BufferSizeType newSize);
88 
93  VTKM_CONT BufferInfo(vtkm::cont::DeviceAdapterId device,
94  void* memory,
95  void* container,
97  Deleter deleter,
98  Reallocater reallocater);
99 
102  VTKM_CONT void Reallocate(vtkm::BufferSizeType newSize);
103 
110  VTKM_CONT TransferredBuffer TransferOwnership();
111 
112 private:
113  detail::BufferInfoInternals* Internals;
115 };
116 
117 
127 struct TransferredBuffer
128 {
129  void* Memory;
130  void* Container;
131  BufferInfo::Deleter* Delete;
132  BufferInfo::Reallocater* Reallocate;
134 };
135 
138 VTKM_CONT_EXPORT VTKM_CONT vtkm::cont::internal::BufferInfo AllocateOnHost(
139  vtkm::BufferSizeType size);
140 
146 class VTKM_CONT_EXPORT DeviceAdapterMemoryManagerBase
147 {
148 public:
149  VTKM_CONT virtual ~DeviceAdapterMemoryManagerBase();
150 
153  VTKM_CONT virtual vtkm::cont::internal::BufferInfo Allocate(vtkm::BufferSizeType size) const = 0;
154 
157  VTKM_CONT void Reallocate(vtkm::cont::internal::BufferInfo& buffer,
158  vtkm::BufferSizeType newSize) const;
159 
161  VTKM_CONT BufferInfo ManageArray(void* memory,
162  void* container,
164  vtkm::cont::internal::BufferInfo::Deleter deleter,
165  vtkm::cont::internal::BufferInfo::Reallocater reallocater) const;
166 
168  VTKM_CONT virtual vtkm::cont::DeviceAdapterId GetDevice() const = 0;
169 
172  VTKM_CONT virtual vtkm::cont::internal::BufferInfo CopyHostToDevice(
173  const vtkm::cont::internal::BufferInfo& src) const = 0;
174 
177  VTKM_CONT virtual void CopyHostToDevice(const vtkm::cont::internal::BufferInfo& src,
178  const vtkm::cont::internal::BufferInfo& dest) const = 0;
179 
182  VTKM_CONT virtual vtkm::cont::internal::BufferInfo CopyDeviceToHost(
183  const vtkm::cont::internal::BufferInfo& src) const = 0;
184 
187  VTKM_CONT virtual void CopyDeviceToHost(const vtkm::cont::internal::BufferInfo& src,
188  const vtkm::cont::internal::BufferInfo& dest) const = 0;
189 
192  VTKM_CONT virtual vtkm::cont::internal::BufferInfo CopyDeviceToDevice(
193  const vtkm::cont::internal::BufferInfo& src) const = 0;
194 
197  VTKM_CONT virtual void CopyDeviceToDevice(const vtkm::cont::internal::BufferInfo& src,
198  const vtkm::cont::internal::BufferInfo& dest) const = 0;
199 
200 
209  VTKM_CONT virtual void* AllocateRawPointer(vtkm::BufferSizeType size) const;
210 
217  VTKM_CONT virtual void CopyDeviceToDeviceRawPointer(const void* src,
218  void* dest,
219  vtkm::BufferSizeType size) const;
220 
229  VTKM_CONT virtual void DeleteRawPointer(void*) const = 0;
230 };
231 
238 template <typename DeviceAdapterTag>
239 class DeviceAdapterMemoryManager;
240 
241 VTKM_CONT_EXPORT VTKM_CONT void HostDeleter(void*);
243 VTKM_CONT_EXPORT VTKM_CONT void HostReallocate(void*&,
244  void*&,
247 
248 
249 VTKM_CONT_EXPORT VTKM_CONT void InvalidRealloc(void*&,
250  void*&,
253 
254 // Deletes a container object by casting it to a pointer of a given type (the template argument)
255 // and then using delete[] on the object.
256 template <typename T>
257 VTKM_CONT inline void SimpleArrayDeleter(void* container_)
258 {
259  T* container = reinterpret_cast<T*>(container_);
260  delete[] container;
261 }
262 
263 // Reallocates a standard C array. Note that the allocation method is different than the default
264 // host allocation of vtkm::cont::internal::BufferInfo and may be less efficient.
265 template <typename T>
266 VTKM_CONT inline void SimpleArrayReallocater(void*& memory,
267  void*& container,
268  vtkm::BufferSizeType oldSize,
269  vtkm::BufferSizeType newSize)
270 {
271  VTKM_ASSERT(memory == container);
272  VTKM_ASSERT(static_cast<std::size_t>(newSize) % sizeof(T) == 0);
273 
274  // If the new size is not much smaller than the old size, just reuse the buffer (and waste a
275  // little memory).
276  if ((newSize > ((3 * oldSize) / 4)) && (newSize <= oldSize))
277  {
278  return;
279  }
280 
281  void* newBuffer = new T[static_cast<std::size_t>(newSize) / sizeof(T)];
282  std::memcpy(newBuffer, memory, static_cast<std::size_t>(newSize < oldSize ? newSize : oldSize));
283 
284  if (memory != nullptr)
285  {
286  SimpleArrayDeleter<T>(memory);
287  }
288 
289  memory = container = newBuffer;
290 }
291 
292 // Deletes a container object by casting it to a pointer of a given type (the template argument)
293 // and then using delete on the object.
294 template <typename T>
295 VTKM_CONT inline void CastDeleter(void* container_)
296 {
297  T* container = reinterpret_cast<T*>(container_);
298  delete container;
299 }
300 
301 template <typename T, typename Allocator>
302 VTKM_CONT inline void StdVectorDeleter(void* container)
303 {
304  CastDeleter<std::vector<T, Allocator>>(container);
305 }
306 
307 template <typename T, typename Allocator>
308 VTKM_CONT inline void StdVectorReallocater(void*& memory,
309  void*& container,
310  vtkm::BufferSizeType oldSize,
311  vtkm::BufferSizeType newSize)
312 {
313  using vector_type = std::vector<T, Allocator>;
314  vector_type* vector = reinterpret_cast<vector_type*>(container);
315  VTKM_ASSERT(vector->empty() || (memory == vector->data()));
316  VTKM_ASSERT(oldSize == static_cast<vtkm::BufferSizeType>(vector->size() * sizeof(T)));
317 
318  vector->resize(static_cast<std::size_t>(newSize));
319  memory = vector->data();
320 }
321 }
322 }
323 } // namespace vtkm::cont::internal
324 
325 #endif //vtk_m_cont_internal_DeviceAdapterMemoryManager_h
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
Types.h
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
DeviceAdapterTag.h
vtkm::BufferSizeType
vtkm::Int64 BufferSizeType
Definition: DeviceAdapterMemoryManager.h:27
VTKM_CONT_EXPORT
#define VTKM_CONT_EXPORT
Definition: vtkm_cont_export.h:44
vtkm_cont_export.h
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::Int64
signed long long Int64
Base type to use for 64-bit signed integer numbers.
Definition: Types.h:204
vtkm::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:58
Flags.h