VTK-m  2.0
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 
13 #include <vtkm/cont/vtkm_cont_export.h>
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 
27 using BufferSizeType = vtkm::Int64;
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 
207 template <typename DeviceAdapterTag>
208 class DeviceAdapterMemoryManager;
209 
210 VTKM_CONT_EXPORT VTKM_CONT void InvalidRealloc(void*&,
211  void*&,
214 
215 // Deletes a container object by casting it to a pointer of a given type (the template argument)
216 // and then using delete[] on the object.
217 template <typename T>
218 VTKM_CONT inline void SimpleArrayDeleter(void* container_)
219 {
220  T* container = reinterpret_cast<T*>(container_);
221  delete[] container;
222 }
223 
224 // Reallocates a standard C array. Note that the allocation method is different than the default
225 // host allocation of vtkm::cont::internal::BufferInfo and may be less efficient.
226 template <typename T>
227 VTKM_CONT inline void SimpleArrayReallocater(void*& memory,
228  void*& container,
229  vtkm::BufferSizeType oldSize,
230  vtkm::BufferSizeType newSize)
231 {
232  VTKM_ASSERT(memory == container);
233  VTKM_ASSERT(static_cast<std::size_t>(newSize) % sizeof(T) == 0);
234 
235  // If the new size is not much smaller than the old size, just reuse the buffer (and waste a
236  // little memory).
237  if ((newSize > ((3 * oldSize) / 4)) && (newSize <= oldSize))
238  {
239  return;
240  }
241 
242  void* newBuffer = new T[static_cast<std::size_t>(newSize) / sizeof(T)];
243  std::memcpy(newBuffer, memory, static_cast<std::size_t>(newSize < oldSize ? newSize : oldSize));
244 
245  if (memory != nullptr)
246  {
247  SimpleArrayDeleter<T>(memory);
248  }
249 
250  memory = container = newBuffer;
251 }
252 
253 // Deletes a container object by casting it to a pointer of a given type (the template argument)
254 // and then using delete on the object.
255 template <typename T>
256 VTKM_CONT inline void CastDeleter(void* container_)
257 {
258  T* container = reinterpret_cast<T*>(container_);
259  delete container;
260 }
261 
262 template <typename T, typename Allocator>
263 VTKM_CONT inline void StdVectorDeleter(void* container)
264 {
265  CastDeleter<std::vector<T, Allocator>>(container);
266 }
267 
268 template <typename T, typename Allocator>
269 VTKM_CONT inline void StdVectorReallocater(void*& memory,
270  void*& container,
271  vtkm::BufferSizeType oldSize,
272  vtkm::BufferSizeType newSize)
273 {
274  using vector_type = std::vector<T, Allocator>;
275  vector_type* vector = reinterpret_cast<vector_type*>(container);
276  VTKM_ASSERT(vector->empty() || (memory == vector->data()));
277  VTKM_ASSERT(oldSize == static_cast<vtkm::BufferSizeType>(vector->size() * sizeof(T)));
278 
279  vector->resize(static_cast<std::size_t>(newSize));
280  memory = vector->data();
281 }
282 }
283 }
284 } // namespace vtkm::cont::internal
285 
286 #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
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::cont::DeviceAdapterId
Definition: DeviceAdapterTag.h:52
vtkm::worklet::splatkernels::vector_type
vtkm::Vec3f_64 vector_type
Definition: KernelBase.h:24
Flags.h