Viskores  1.0
DeviceAdapterMemoryManager.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_cont_internal_DeviceAdapterMemoryManager_h
19 #define viskores_cont_internal_DeviceAdapterMemoryManager_h
20 
22 
23 #include <viskores/Flags.h>
24 #include <viskores/Types.h>
25 
27 
28 #include <cstring>
29 #include <memory>
30 #include <vector>
31 
32 namespace viskores
33 {
34 
36 
37 namespace cont
38 {
39 namespace internal
40 {
41 
42 struct TransferredBuffer;
43 
44 namespace detail
45 {
46 
47 struct BufferInfoInternals;
48 
49 } // namespace detail
50 
51 class VISKORES_CONT_EXPORT BufferInfo
52 {
53 public:
57  VISKORES_CONT void* GetPointer() const;
58 
62 
69 
70  VISKORES_CONT BufferInfo();
71  VISKORES_CONT ~BufferInfo();
72 
73  VISKORES_CONT BufferInfo(const BufferInfo& src);
74  VISKORES_CONT BufferInfo(BufferInfo&& src);
75 
76  VISKORES_CONT BufferInfo& operator=(const BufferInfo& src);
77  VISKORES_CONT BufferInfo& operator=(BufferInfo&& src);
78 
83  VISKORES_CONT BufferInfo(const BufferInfo& src, viskores::cont::DeviceAdapterId device);
84  VISKORES_CONT BufferInfo(BufferInfo&& src, viskores::cont::DeviceAdapterId device);
85 
88  using Deleter = void(void* container);
89 
92  using Reallocater = void(void*& memory,
93  void*& container,
95  viskores::BufferSizeType newSize);
96 
102  void* memory,
103  void* container,
105  Deleter deleter,
106  Reallocater reallocater);
107 
110  VISKORES_CONT void Reallocate(viskores::BufferSizeType newSize);
111 
118  VISKORES_CONT TransferredBuffer TransferOwnership();
119 
120 private:
121  detail::BufferInfoInternals* Internals;
123 };
124 
125 
135 struct TransferredBuffer
136 {
137  void* Memory;
138  void* Container;
139  BufferInfo::Deleter* Delete;
140  BufferInfo::Reallocater* Reallocate;
142 };
143 
146 VISKORES_CONT_EXPORT VISKORES_CONT viskores::cont::internal::BufferInfo AllocateOnHost(
148 
154 class VISKORES_CONT_EXPORT DeviceAdapterMemoryManagerBase
155 {
156 public:
157  VISKORES_CONT virtual ~DeviceAdapterMemoryManagerBase();
158 
161  VISKORES_CONT virtual viskores::cont::internal::BufferInfo Allocate(
162  viskores::BufferSizeType size) const = 0;
163 
166  VISKORES_CONT void Reallocate(viskores::cont::internal::BufferInfo& buffer,
167  viskores::BufferSizeType newSize) const;
168 
170  VISKORES_CONT BufferInfo
171  ManageArray(void* memory,
172  void* container,
174  viskores::cont::internal::BufferInfo::Deleter deleter,
175  viskores::cont::internal::BufferInfo::Reallocater reallocater) const;
176 
178  VISKORES_CONT virtual viskores::cont::DeviceAdapterId GetDevice() const = 0;
179 
182  VISKORES_CONT virtual viskores::cont::internal::BufferInfo CopyHostToDevice(
183  const viskores::cont::internal::BufferInfo& src) const = 0;
184 
187  VISKORES_CONT virtual void CopyHostToDevice(
188  const viskores::cont::internal::BufferInfo& src,
189  const viskores::cont::internal::BufferInfo& dest) const = 0;
190 
193  VISKORES_CONT virtual viskores::cont::internal::BufferInfo CopyDeviceToHost(
194  const viskores::cont::internal::BufferInfo& src) const = 0;
195 
198  VISKORES_CONT virtual void CopyDeviceToHost(
199  const viskores::cont::internal::BufferInfo& src,
200  const viskores::cont::internal::BufferInfo& dest) const = 0;
201 
204  VISKORES_CONT virtual viskores::cont::internal::BufferInfo CopyDeviceToDevice(
205  const viskores::cont::internal::BufferInfo& src) const = 0;
206 
209  VISKORES_CONT virtual void CopyDeviceToDevice(
210  const viskores::cont::internal::BufferInfo& src,
211  const viskores::cont::internal::BufferInfo& dest) const = 0;
212 
213 
222  VISKORES_CONT virtual void* AllocateRawPointer(viskores::BufferSizeType size) const;
223 
230  VISKORES_CONT virtual void CopyDeviceToDeviceRawPointer(const void* src,
231  void* dest,
232  viskores::BufferSizeType size) const;
233 
242  VISKORES_CONT virtual void DeleteRawPointer(void*) const = 0;
243 };
244 
251 template <typename DeviceAdapterTag>
252 class DeviceAdapterMemoryManager;
253 
254 VISKORES_CONT_EXPORT VISKORES_CONT void HostDeleter(void*);
255 VISKORES_CONT_EXPORT VISKORES_CONT void* HostAllocate(viskores::BufferSizeType);
256 VISKORES_CONT_EXPORT VISKORES_CONT void HostReallocate(void*&,
257  void*&,
260 
261 
262 VISKORES_CONT_EXPORT VISKORES_CONT void InvalidRealloc(void*&,
263  void*&,
266 
267 // Deletes a container object by casting it to a pointer of a given type (the template argument)
268 // and then using delete[] on the object.
269 template <typename T>
270 VISKORES_CONT inline void SimpleArrayDeleter(void* container_)
271 {
272  T* container = reinterpret_cast<T*>(container_);
273  delete[] container;
274 }
275 
276 // Reallocates a standard C array. Note that the allocation method is different than the default
277 // host allocation of viskores::cont::internal::BufferInfo and may be less efficient.
278 template <typename T>
279 VISKORES_CONT inline void SimpleArrayReallocater(void*& memory,
280  void*& container,
281  viskores::BufferSizeType oldSize,
282  viskores::BufferSizeType newSize)
283 {
284  VISKORES_ASSERT(memory == container);
285  VISKORES_ASSERT(static_cast<std::size_t>(newSize) % sizeof(T) == 0);
286 
287  // If the new size is not much smaller than the old size, just reuse the buffer (and waste a
288  // little memory).
289  if ((newSize > ((3 * oldSize) / 4)) && (newSize <= oldSize))
290  {
291  return;
292  }
293 
294  void* newBuffer = new T[static_cast<std::size_t>(newSize) / sizeof(T)];
295  std::memcpy(newBuffer, memory, static_cast<std::size_t>(newSize < oldSize ? newSize : oldSize));
296 
297  if (memory != nullptr)
298  {
299  SimpleArrayDeleter<T>(memory);
300  }
301 
302  memory = container = newBuffer;
303 }
304 
305 // Deletes a container object by casting it to a pointer of a given type (the template argument)
306 // and then using delete on the object.
307 template <typename T>
308 VISKORES_CONT inline void CastDeleter(void* container_)
309 {
310  T* container = reinterpret_cast<T*>(container_);
311  delete container;
312 }
313 
314 template <typename T, typename Allocator>
315 VISKORES_CONT inline void StdVectorDeleter(void* container)
316 {
317  CastDeleter<std::vector<T, Allocator>>(container);
318 }
319 
320 template <typename T, typename Allocator>
321 VISKORES_CONT inline void StdVectorReallocater(void*& memory,
322  void*& container,
323  viskores::BufferSizeType oldSize,
324  viskores::BufferSizeType newSize)
325 {
326  using vector_type = std::vector<T, Allocator>;
327  vector_type* vector = reinterpret_cast<vector_type*>(container);
328  VISKORES_ASSERT(vector->empty() || (memory == vector->data()));
329  VISKORES_ASSERT(oldSize == static_cast<viskores::BufferSizeType>(vector->size() * sizeof(T)));
330 
331  vector->resize(static_cast<std::size_t>(newSize));
332  memory = vector->data();
333 }
334 }
335 }
336 } // namespace viskores::cont::internal
337 
338 #endif //viskores_cont_internal_DeviceAdapterMemoryManager_h
Types.h
DeviceAdapterTag.h
viskores::Int64
signed long long Int64
Base type to use for 64-bit signed integer numbers.
Definition: Types.h:212
VISKORES_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
VISKORES_ASSERT
#define VISKORES_ASSERT(condition)
Definition: Assert.h:51
viskores::BufferSizeType
viskores::Int64 BufferSizeType
Definition: DeviceAdapterMemoryManager.h:35
viskores::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:66
Flags.h
viskores_cont_export.h