HAMR
The Heterogeneous Accelerator Memory Resource
hamr_hip_malloc_uva_allocator.h
1 #ifndef hamr_hip_malloc_uva_allocator_h
2 #define hamr_hip_malloc_uva_allocator_h
3 
4 #include <iostream>
5 #include <type_traits>
6 #include <memory>
7 #include <typeinfo>
8 #include <cassert>
9 #include <cstring>
10 #include <cstdlib>
11 
12 #include <hip/hip_runtime.h>
13 
14 
15 #include "hamr_config.h"
16 #include "hamr_hip_kernels.h"
17 #include "hamr_env.h"
18 
19 namespace hamr
20 {
21 
22 /// a deleter for arrays allocated with hip_malloc_uva
23 template <typename T, typename E = void>
25 
26 /// a deleter for arrays allocated with hip_malloc_uva, specialized for objects
27 template <typename T>
28 class hip_malloc_uva_deleter<T, typename std::enable_if<!std::is_arithmetic<T>::value>::type>
29 {
30 public:
31  /** constructs the deleter
32  * @param[in] ptr the pointer to the array to delete
33  * @param[in] n the number of elements in the array
34  */
35  hip_malloc_uva_deleter(T *ptr, size_t n);
36 
37  /** deletes the array
38  * @param[in] ptr the pointer to the array to delete. must be the same as
39  * that passed during construction.
40  */
41  void operator()(T *ptr);
42 
43 private:
44  T *m_ptr;
45  size_t m_elem;
46 };
47 
48 // --------------------------------------------------------------------------
49 template <typename T>
51  ::hip_malloc_uva_deleter(T *ptr, size_t n) : m_ptr(ptr), m_elem(n)
52 {
53 #if defined(HAMR_VERBOSE)
54  if (hamr::get_verbose())
55  {
56  std::cerr << "created hip_malloc_uva_deleter for array of " << n
57  << " objects of type " << typeid(T).name() << std::endl;
58  }
59 #endif
60 }
61 
62 // --------------------------------------------------------------------------
63 template <typename T>
64 void
66  ::operator()(T *ptr)
67 {
68 #if !defined(HAMR_ENABLE_OBJECTS)
69  (void) ptr;
70  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
71  " hip_malloc_uva_deleter dealllocate objects failed."
72  " HAMR_ENABLE_OBJECTS is not enabled" << std::endl;
73  abort();
74 #else
75  assert(ptr == m_ptr);
76 
77 #if defined(HAMR_VERBOSE)
78  if (hamr::get_verbose())
79  {
80  std::cerr << "hip_malloc_uva_deleter deleting array of " << m_elem
81  << " objects of type " << typeid(T).name() << sizeof(T)
82  << " at " << m_ptr << std::endl;
83  }
84 #endif
85 
86  // get launch parameters
87  int device_id = -1;
88  dim3 block_grid;
89  int n_blocks = 0;
90  dim3 thread_grid = 0;
91  if (hamr::partition_thread_blocks(device_id, m_elem, 8, block_grid,
92  n_blocks, thread_grid))
93  {
94  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
95  " Failed to determine launch properties." << std::endl;
96  return;
97  }
98 
99  // destruct
100  hipError_t ierr = hipSuccess;
101  hip_kernels::destruct<T><<<block_grid, thread_grid>>>(ptr, m_elem);
102  if ((ierr = hipGetLastError()) != hipSuccess)
103  {
104  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
105  " Failed to launch the destruct kernel. "
106  << hipGetErrorString(ierr) << std::endl;
107  return;
108  }
109 
110  // free the array
111  ierr = hipFree(ptr);
112  (void) ierr;
113 #endif
114 }
115 
116 
117 
118 
119 
120 /// a deleter for arrays allocated with hip_malloc_uva, specialized for numbers
121 template <typename T>
122 class hip_malloc_uva_deleter<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
123 {
124 public:
125  /** constructs the deleter
126  * @param[in] ptr the pointer to the array to delete
127  * @param[in] n the number of elements in the array
128  */
129  hip_malloc_uva_deleter(T *ptr, size_t n);
130 
131  /** deletes the array
132  * @param[in] ptr the pointer to the array to delete. must be the same as
133  * that passed during construction.
134  */
135  void operator()(T *ptr);
136 
137 private:
138  T *m_ptr;
139  size_t m_elem;
140 };
141 
142 // --------------------------------------------------------------------------
143 template <typename T>
145  ::hip_malloc_uva_deleter(T *ptr, size_t n) : m_ptr(ptr), m_elem(n)
146 {
147 #if defined(HAMR_VERBOSE)
148  if (hamr::get_verbose())
149  {
150  std::cerr << "created hip_malloc_uva_deleter for array of " << n
151  << " numbers of type " << typeid(T).name() << sizeof(T)
152  << std::endl;
153  }
154 #endif
155 }
156 
157 // --------------------------------------------------------------------------
158 template <typename T>
159 void
161  ::operator()(T *ptr)
162 {
163  assert(ptr == m_ptr);
164 
165 #if defined(HAMR_VERBOSE)
166  if (hamr::get_verbose())
167  {
168  std::cerr << "hip_malloc_uva_deleter deleting array of " << m_elem
169  << " numbers of type " << typeid(T).name() << sizeof(T)
170  << std::endl;
171  }
172 #endif
173 
174  // free the array
175  hipError_t ierr = hipSuccess;
176  ierr = hipFree(ptr);
177  (void) ierr;
178 }
179 
180 
181 
182 
183 
184 /// a class for allocating arrays with hip_malloc_uva
185 template <typename T, typename E = void>
187 
188 /// a class for allocating arrays with hip_malloc_uva, specialized for objects
189 template <typename T>
190 struct HAMR_EXPORT hip_malloc_uva_allocator<T, typename std::enable_if<!std::is_arithmetic<T>::value>::type>
191 {
192  /** allocate an array of n elements.
193  * @param[in] n the number of elements to allocate
194  * @returns a shared point to the array that holds a deleter for the memory
195  */
196  static std::shared_ptr<T> allocate(size_t n);
197 
198  /** allocate an array of n elements.
199  * @param[in] n the number of elements to allocate
200  * @param[in] val a value to initialize the elements to
201  * @returns a shared point to the array that holds a deleter for the memory
202  */
203  static std::shared_ptr<T> allocate(size_t n, const T &val);
204 
205  /** allocate an array of n elements.
206  * @param[in] n the number of elements to allocate
207  * @param[in] vals an array of values to initialize the elements with
208  * @param[in] hipVals a flag that is set to true if vals is accessible from codes running in CUDA
209  * @returns a shared point to the array that holds a deleter for the memory
210  */
211  template <typename U>
212  static std::shared_ptr<T> allocate(size_t n, const U *vals, bool hipVals = false);
213 };
214 
215 // --------------------------------------------------------------------------
216 template <typename T>
217 std::shared_ptr<T>
219  ::allocate(size_t n_elem)
220 {
221 #if !defined(HAMR_ENABLE_OBJECTS)
222  (void) n_elem;
223  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
224  " hip_malloc_uva_allocator allocate objects failed."
225  " HAMR_ENABLE_OBJECTS is not enabled" << std::endl;
226  abort();
227  return nullptr;
228 #else
229  size_t n_bytes = n_elem*sizeof(T);
230 
231  // allocate
232  T *ptr = nullptr;
233  hipError_t ierr = hipSuccess;
234  if ((ierr = hipMallocManaged(&ptr, n_bytes)) != hipSuccess)
235  {
236  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
237  " Failed to hipMallocManaged " << n_elem << " of "
238  << typeid(T).name() << sizeof(T) << " total " << n_bytes << "bytes. "
239  << hipGetErrorString(ierr) << std::endl;
240  return nullptr;
241  }
242 
243  // get launch parameters
244  int device_id = -1;
245  dim3 block_grid;
246  int n_blocks = 0;
247  dim3 thread_grid = 0;
248  if (hamr::partition_thread_blocks(device_id, n_elem, 8, block_grid,
249  n_blocks, thread_grid))
250  {
251  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
252  " Failed to determine launch properties. "
253  << hipGetErrorString(ierr) << std::endl;
254  return nullptr;
255  }
256 
257  // construct
258  hip_kernels::construct<T><<<block_grid, thread_grid>>>(ptr, n_elem);
259  if ((ierr = hipGetLastError()) != hipSuccess)
260  {
261  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
262  " Failed to launch the construct kernel. "
263  << hipGetErrorString(ierr) << std::endl;
264  return nullptr;
265  }
266 
267 #if defined(HAMR_VERBOSE)
268  if (hamr::get_verbose())
269  {
270  std::cerr << "hip_malloc_uva_allocator allocating array of " << n_elem
271  << " objects of type " << typeid(T).name() << sizeof(T)
272  << " at " << ptr << std::endl;
273  }
274 #endif
275 
276  // package
277  return std::shared_ptr<T>(ptr, hip_malloc_uva_deleter<T>(ptr, n_elem));
278 #endif
279 }
280 
281 // --------------------------------------------------------------------------
282 template <typename T>
283 std::shared_ptr<T>
284 hip_malloc_uva_allocator<T, typename std::enable_if<!std::is_arithmetic<T>::value>::type>
285  ::allocate(size_t n_elem, const T &val)
286 {
287 #if !defined(HAMR_ENABLE_OBJECTS)
288  (void) n_elem;
289  (void) val;
290  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
291  " hip_malloc_uva_allocator allocate objects failed."
292  " HAMR_ENABLE_OBJECTS is not enabled" << std::endl;
293  abort();
294  return nullptr;
295 #else
296  // allocate
297  T *ptr = nullptr;
298  size_t n_bytes = n_elem*sizeof(T);
299 
300  hipError_t ierr = hipSuccess;
301  if ((ierr = hipMallocManaged(&ptr, n_bytes)) != hipSuccess)
302  {
303  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
304  " Failed to hipMallocManaged " << n_elem << " of "
305  << typeid(T).name() << " total " << n_bytes << "bytes. "
306  << hipGetErrorString(ierr) << std::endl;
307  return nullptr;
308  }
309 
310  // get launch parameters
311  int device_id = -1;
312  dim3 block_grid;
313  int n_blocks = 0;
314  dim3 thread_grid = 0;
315  if (hamr::partition_thread_blocks(device_id, n_elem, 8, block_grid,
316  n_blocks, thread_grid))
317  {
318  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
319  " Failed to determine launch properties. "
320  << hipGetErrorString(ierr) << std::endl;
321  return nullptr;
322  }
323 
324  // construct
325  hip_kernels::construct<T><<<block_grid, thread_grid>>>(ptr, n_elem, val);
326  if ((ierr = hipGetLastError()) != hipSuccess)
327  {
328  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
329  " Failed to launch the construct kernel. "
330  << hipGetErrorString(ierr) << std::endl;
331  return nullptr;
332  }
333 
334 #if defined(HAMR_VERBOSE)
335  if (hamr::get_verbose())
336  {
337  std::cerr << "hip_malloc_uva_allocator allocating array of " << n_elem
338  << " objects of type " << typeid(T).name() << sizeof(T)
339  << " at " << ptr << " initialized to " << val
340  << std::endl;
341  }
342 #endif
343 
344  // package
345  return std::shared_ptr<T>(ptr, hip_malloc_uva_deleter<T>(ptr, n_elem));
346 #endif
347 }
348 
349 // --------------------------------------------------------------------------
350 template <typename T>
351 template <typename U>
352 std::shared_ptr<T>
353 hip_malloc_uva_allocator<T, typename std::enable_if<!std::is_arithmetic<T>::value>::type>
354  ::allocate(size_t n_elem, const U *vals, bool hipVals)
355 {
356 #if !defined(HAMR_ENABLE_OBJECTS)
357  (void) n_elem;
358  (void) vals;
359  (void) hipVals;
360  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
361  " hip_malloc_uva_allocator allocate objects failed."
362  " HAMR_ENABLE_OBJECTS is not enabled" << std::endl;
363  abort();
364  return nullptr;
365 #else
366  // allocate
367  T *ptr = nullptr;
368  size_t n_bytes = n_elem*sizeof(T);
369 
370  hipError_t ierr = hipSuccess;
371  if ((ierr = hipMallocManaged(&ptr, n_bytes)) != hipSuccess)
372  {
373  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
374  " Failed to hipMallocManaged " << n_elem << " of "
375  << typeid(T).name() << " total " << n_bytes << "bytes. "
376  << hipGetErrorString(ierr) << std::endl;
377  return nullptr;
378  }
379 
380  // move the existing array to the GPU
381  U *tmp = nullptr;
382  if (!hipVals)
383  {
384  size_t n_bytes_vals = n_elem*sizeof(U);
385  if ((ierr = hipMalloc(&tmp, n_bytes_vals)) != hipSuccess)
386  {
387  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
388  " Failed to hipMalloc " << n_elem << " of "
389  << typeid(U).name() << sizeof(U) << " total " << n_bytes_vals
390  << " bytes. " << hipGetErrorString(ierr) << std::endl;
391  return nullptr;
392  }
393 
394  if ((ierr = hipMemcpy(tmp, vals, n_bytes_vals, hipMemcpyHostToDevice)) != hipSuccess)
395  {
396  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
397  " Failed to hipMemcpy array of " << n_elem
398  << " of " << typeid(T).name() << " total " << n_bytes_vals
399  << " bytes. " << hipGetErrorString(ierr) << std::endl;
400  return nullptr;
401  }
402 
403  vals = tmp;
404  }
405 
406  // get launch parameters
407  int device_id = -1;
408  dim3 block_grid;
409  int n_blocks = 0;
410  dim3 thread_grid = 0;
411  if (hamr::partition_thread_blocks(device_id, n_elem, 8, block_grid,
412  n_blocks, thread_grid))
413  {
414  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
415  " Failed to determine launch properties. "
416  << hipGetErrorString(ierr) << std::endl;
417  return nullptr;
418  }
419 
420  // construct
421  hip_kernels::construct<T><<<block_grid, thread_grid>>>(ptr, n_elem, vals);
422  if ((ierr = hipGetLastError()) != hipSuccess)
423  {
424  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
425  " Failed to launch the construct kernel. "
426  << hipGetErrorString(ierr) << std::endl;
427  return nullptr;
428  }
429 
430  // free up temporary buffers
431  if (!hipVals)
432  {
433  ierr = hipFree(tmp);
434  (void) ierr;
435  }
436 
437 #if defined(HAMR_VERBOSE)
438  if (hamr::get_verbose())
439  {
440  std::cerr << "hip_malloc_uva_allocator allocating array of " << n_elem
441  << " objects of type " << typeid(T).name() << sizeof(T)
442  << " at " << ptr << " initialized from " << (hipVals ? "CUDA" : "host")
443  << " array of objects of type " << typeid(U).name() << sizeof(U)
444  << " at " << vals << std::endl;
445  }
446 #endif
447 
448  // package
449  return std::shared_ptr<T>(ptr, hip_malloc_uva_deleter<T>(ptr, n_elem));
450 #endif
451 }
452 
453 
454 
455 
456 /// a class for allocating arrays with hip_malloc_uva, specialized for numbers
457 template <typename T>
458 struct HAMR_EXPORT hip_malloc_uva_allocator<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
459 {
460  /** allocate an array of n elements.
461  * @param[in] n the number of elements to allocate
462  * @returns a shared point to the array that holds a deleter for the memory
463  */
464  static std::shared_ptr<T> allocate(size_t n);
465 
466  /** allocate an array of n elements.
467  * @param[in] n the number of elements to allocate
468  * @param[in] val a value to initialize the elements to
469  * @returns a shared point to the array that holds a deleter for the memory
470  */
471  static std::shared_ptr<T> allocate(size_t n, const T &val);
472 
473  /** allocate an array of n elements.
474  * @param[in] n the number of elements to allocate
475  * @param[in] vals an array of values to initialize the elements with
476  * @param[in] hipVals a flag set to true if vals is accessible from codes running in CUDA
477  * @returns a shared point to the array that holds a deleter for the memory
478  */
479  template <typename U>
480  static std::shared_ptr<T> allocate(size_t n, const U *vals, bool hipVals = false);
481 };
482 
483 // --------------------------------------------------------------------------
484 template <typename T>
485 std::shared_ptr<T>
487  ::allocate(size_t n_elem)
488 {
489  size_t n_bytes = n_elem*sizeof(T);
490 
491  // allocate
492  T *ptr = nullptr;
493  hipError_t ierr = hipSuccess;
494  if ((ierr = hipMallocManaged(&ptr, n_bytes)) != hipSuccess)
495  {
496  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
497  " Failed to hipMalloc " << n_elem << " of "
498  << typeid(T).name() << " total " << n_bytes << "bytes. "
499  << hipGetErrorString(ierr) << std::endl;
500  return nullptr;
501  }
502 
503  // construct
504 #if defined(HAMR_INIT_ALLOC)
505  hipMemset(ptr, 0, n_bytes);
506 #endif
507 
508 #if defined(HAMR_VERBOSE)
509  if (hamr::get_verbose())
510  {
511  std::cerr << "hip_malloc_uva_allocator allocating array of " << n_elem
512  << " numbers of type " << typeid(T).name() << sizeof(T)
513  << " at " << ptr << std::endl;
514  }
515 #endif
516 
517  // package
518  return std::shared_ptr<T>(ptr, hip_malloc_uva_deleter<T>(ptr, n_elem));
519 }
520 
521 // --------------------------------------------------------------------------
522 template <typename T>
523 std::shared_ptr<T>
524 hip_malloc_uva_allocator<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
525  ::allocate(size_t n_elem, const T &val)
526 {
527  size_t n_bytes = n_elem*sizeof(T);
528 
529  // allocate
530  T *ptr = nullptr;
531  hipError_t ierr = hipSuccess;
532  if ((ierr = hipMallocManaged(&ptr, n_bytes)) != hipSuccess)
533  {
534  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
535  " Failed to hipMallocManaged " << n_elem << " of "
536  << typeid(T).name() << " total " << n_bytes << "bytes. "
537  << hipGetErrorString(ierr) << std::endl;
538  return nullptr;
539  }
540 
541  // get launch parameters
542  int device_id = -1;
543  dim3 block_grid;
544  int n_blocks = 0;
545  dim3 thread_grid = 0;
546  if (hamr::partition_thread_blocks(device_id, n_elem, 8, block_grid,
547  n_blocks, thread_grid))
548  {
549  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
550  " Failed to determine launch properties. "
551  << hipGetErrorString(ierr) << std::endl;
552  return nullptr;
553  }
554 
555  // construct
556  hip_kernels::fill<T><<<block_grid, thread_grid>>>(ptr, n_elem, val);
557  if ((ierr = hipGetLastError()) != hipSuccess)
558  {
559  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
560  " Failed to launch the construct kernel. "
561  << hipGetErrorString(ierr) << std::endl;
562  return nullptr;
563  }
564 
565 #if defined(HAMR_VERBOSE)
566  if (hamr::get_verbose())
567  {
568  std::cerr << "hip_malloc_uva_allocator allocating array of " << n_elem
569  << " objects of type " << typeid(T).name() << sizeof(T)
570  << " at " << ptr << " initialized to " << val << std::endl;
571  }
572 #endif
573 
574  // package
575  return std::shared_ptr<T>(ptr, hip_malloc_uva_deleter<T>(ptr, n_elem));
576 }
577 
578 // --------------------------------------------------------------------------
579 template <typename T>
580 template <typename U>
581 std::shared_ptr<T>
582 hip_malloc_uva_allocator<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
583  ::allocate(size_t n_elem, const U *vals, bool hipVals)
584 {
585  size_t n_bytes = n_elem*sizeof(T);
586 
587  // allocate
588  T *ptr = nullptr;
589  hipError_t ierr = hipSuccess;
590  if ((ierr = hipMallocManaged(&ptr, n_bytes)) != hipSuccess)
591  {
592  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
593  " Failed to hipMallocManaged " << n_elem << " of "
594  << typeid(T).name() << " total " << n_bytes << "bytes. "
595  << hipGetErrorString(ierr) << std::endl;
596  return nullptr;
597  }
598 
599  // move the existing array to the GPU
600  U *tmp = nullptr;
601  if (!hipVals)
602  {
603  size_t n_bytes_vals = n_elem*sizeof(U);
604  if ((ierr = hipMalloc(&tmp, n_bytes_vals)) != hipSuccess)
605  {
606  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
607  " Failed to hipMalloc " << n_elem << " of "
608  << typeid(T).name() << " total " << n_bytes_vals << "bytes. "
609  << hipGetErrorString(ierr) << std::endl;
610  return nullptr;
611  }
612 
613  if ((ierr = hipMemcpy(tmp, vals, n_bytes_vals, hipMemcpyHostToDevice)) != hipSuccess)
614  {
615  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
616  " Failed to hipMemcpy array of " << n_elem
617  << " of " << typeid(T).name() << " total " << n_bytes_vals << "bytes. "
618  << hipGetErrorString(ierr) << std::endl;
619  return nullptr;
620  }
621 
622  vals = tmp;
623  }
624 
625  // get launch parameters
626  int device_id = -1;
627  dim3 block_grid;
628  int n_blocks = 0;
629  dim3 thread_grid = 0;
630  if (hamr::partition_thread_blocks(device_id, n_elem, 8, block_grid, n_blocks, thread_grid))
631  {
632  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
633  " Failed to determine launch properties. "
634  << hipGetErrorString(ierr) << std::endl;
635  return nullptr;
636  }
637 
638  // construct
639  hip_kernels::fill<T><<<block_grid, thread_grid>>>(ptr, n_elem, vals);
640  if ((ierr = hipGetLastError()) != hipSuccess)
641  {
642  std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] ERROR:"
643  " Failed to launch the construct kernel. "
644  << hipGetErrorString(ierr) << std::endl;
645  return nullptr;
646  }
647 
648  // free up temporary buffers
649  if (!hipVals)
650  {
651  ierr = hipFree(tmp);
652  (void) ierr;
653  }
654 
655 #if defined(HAMR_VERBOSE)
656  if (hamr::get_verbose())
657  {
658  std::cerr << "hip_malloc_uva_allocator allocating array of " << n_elem
659  << " objects of type " << typeid(T).name() << sizeof(T)
660  << " at " << ptr << " initialized from " << (hipVals ? "CUDA" : "host")
661  << " array " << vals << " objects of type " << typeid(U).name() << sizeof(T)
662  << std::endl;
663  }
664 #endif
665 
666 
667  // package
668  return std::shared_ptr<T>(ptr, hip_malloc_uva_deleter<T>(ptr, n_elem));
669 }
670 
671 }
672 
673 #endif
hamr::hip_malloc_uva_allocator
a class for allocating arrays with hip_malloc_uva
Definition: hamr_hip_malloc_uva_allocator.h:186
hamr::hip_malloc_uva_deleter
a deleter for arrays allocated with hip_malloc_uva
Definition: hamr_hip_malloc_uva_allocator.h:24
hamr::partition_thread_blocks
HAMR_EXPORT int partition_thread_blocks(int device_id, size_t array_size, int warps_per_block, dim3 &block_grid, int &n_blocks, dim3 &thread_grid)
hamr::get_verbose
constexpr HAMR_EXPORT int get_verbose()
returns the value of the HAMR_VERBOSE environment variable
Definition: hamr_env.h:14
hamr
heterogeneous accelerator memory resource
Definition: hamr_buffer.h:13