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