1 #ifndef hamr_openmp_allocator_h
2 #define hamr_openmp_allocator_h
4 #include "hamr_config.h"
19 template <
typename T,
typename E =
void>
24 class HAMR_EXPORT
openmp_deleter<T, typename std::enable_if<!std::is_arithmetic<T>::value>::type>
37 void operator()(T *ptr);
48 ::openmp_deleter(T *ptr,
size_t n,
int dev) : m_ptr(ptr), m_elem(n), m_dev(dev)
50 #if defined(HAMR_VERBOSE)
53 std::cerr <<
"created openmp_deleter for array of " << n
54 <<
" objects of type " <<
typeid(T).name() <<
sizeof(T)
55 <<
" at " << m_ptr <<
" on device " << m_dev << std::endl;
63 openmp_deleter<T, typename std::enable_if<!std::is_arithmetic<T>::value>::type>
68 #if defined(HAMR_VERBOSE)
71 std::cerr <<
"openmp_deleter deleting array of " << m_elem
72 <<
" objects of type " <<
typeid(T).name() <<
sizeof(T)
73 <<
" at " << m_ptr <<
" on device " << m_dev << std::endl;
78 for (
size_t i = 0; i < m_elem; ++i)
82 omp_target_free(ptr, m_dev);
91 class HAMR_EXPORT
openmp_deleter<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
104 void operator()(T *ptr);
113 template <
typename T>
115 ::openmp_deleter(T *ptr,
size_t n,
int dev) : m_ptr(ptr), m_elem(n), m_dev(dev)
117 #if defined(HAMR_VERBOSE)
120 std::cerr <<
"created openmp_deleter for array of " << n
121 <<
" numbers of type " <<
typeid(T).name() <<
sizeof(T)
122 <<
" at " << m_ptr <<
" on device " << m_dev << std::endl;
128 template <
typename T>
130 openmp_deleter<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
133 assert(ptr == m_ptr);
135 #if defined(HAMR_VERBOSE)
138 std::cerr <<
"openmp_deleter deleting array of " << m_elem
139 <<
" numbers of type " <<
typeid(T).name() <<
sizeof(T)
140 <<
" at " << m_ptr <<
" on device " << m_dev << std::endl;
145 omp_target_free(ptr, m_dev);
153 template <
typename T,
typename E =
void>
157 template <
typename T>
158 struct HAMR_EXPORT
openmp_allocator<T, typename std::enable_if<!std::is_arithmetic<T>::value>::type>
164 static std::shared_ptr<T> allocate(
size_t n);
172 static std::shared_ptr<T> allocate(
size_t n,
const T &val);
179 template <
typename U>
180 static std::shared_ptr<T> allocate(
size_t n,
const U *vals);
184 template <
typename T>
190 int dev = omp_get_default_device();
191 T *ptr = (T*)omp_target_alloc(n*
sizeof(T), dev);
194 #pragma omp target teams HAMR_OPENMP_LOOP is_device_ptr(ptr)
195 for (
size_t i = 0; i < n; ++i)
198 #if defined(HAMR_VERBOSE)
201 std::cerr <<
"openmp_allocator allocating array of " << n
202 <<
" objects of type " <<
typeid(T).name() <<
sizeof(T)
203 <<
" at " << ptr <<
" on device " << dev << std::endl;
208 return std::shared_ptr<T>(ptr, openmp_deleter<T>(ptr, n, dev));
212 template <
typename T>
214 openmp_allocator<T, typename std::enable_if<!std::is_arithmetic<T>::value>::type>
215 ::allocate(
size_t n,
const T &val)
218 int dev = omp_get_default_device();
219 T *ptr = (T*)omp_target_alloc(n*
sizeof(T), dev);
222 #pragma omp target teams HAMR_OPENMP_LOOP is_device_ptr(ptr) map(to: val)
223 for (
size_t i = 0; i < n; ++i)
224 new (&ptr[i]) T(val);
226 #if defined(HAMR_VERBOSE)
229 std::cerr <<
"openmp_allocator allocating array of " << n
230 <<
" objects of type " <<
typeid(T).name() <<
sizeof(T)
231 <<
" at " << ptr <<
" initialized to " << val << std::endl;
236 return std::shared_ptr<T>(ptr, openmp_deleter<T>(ptr, n));
240 template <
typename T>
241 template <
typename U>
243 openmp_allocator<T, typename std::enable_if<!std::is_arithmetic<T>::value>::type>
244 ::allocate(
size_t n,
const U *vals)
247 int dev = omp_get_default_device();
248 T *ptr = (T*)omp_target_alloc(n*
sizeof(T), dev);
251 #pragma omp target teams HAMR_OPENMP_LOOP is_device_ptr(ptr) map(to: vals[0:n])
252 for (
size_t i = 0; i < n; ++i)
253 new (&ptr[i]) T(vals[i]);
255 #if defined(HAMR_VERBOSE)
258 std::cerr <<
"openmp_allocator allocating array of " << n
259 <<
" objects of type " <<
typeid(T).name() <<
sizeof(T)
260 <<
" initialized from array of objects of type "
261 <<
typeid(U).name() <<
sizeof(U) <<
" at " << vals
262 <<
" on device " << dev << std::endl;
267 return std::shared_ptr<T>(ptr, openmp_deleter<T>(ptr, n));
274 template <
typename T>
275 struct HAMR_EXPORT
openmp_allocator<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
281 static std::shared_ptr<T> allocate(
size_t n);
288 static std::shared_ptr<T> allocate(
size_t n,
const T &val);
295 template <
typename U>
296 static std::shared_ptr<T> allocate(
size_t n,
const U *vals);
300 template <
typename T>
305 size_t n_bytes = n*
sizeof(T);
308 int dev = omp_get_default_device();
309 T *ptr = (T*)omp_target_alloc(n_bytes, dev);
312 #if defined(HAMR_INIT_ALLOC)
313 #pragma omp target teams HAMR_OPENMP_LOOP is_device_ptr(ptr)
314 for (
size_t i = 0; i < n; ++i)
318 #if defined(HAMR_VERBOSE)
321 std::cerr <<
"openmp_allocator allocating array of " << n
322 <<
" numbers of type " <<
typeid(T).name() <<
sizeof(T)
323 <<
" at " << ptr <<
" on device " << dev << std::endl;
328 return std::shared_ptr<T>(ptr, openmp_deleter<T>(ptr, n, dev));
332 template <
typename T>
334 openmp_allocator<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
335 ::allocate(
size_t n,
const T &val)
337 size_t n_bytes = n*
sizeof(T);
340 int dev = omp_get_default_device();
341 T *ptr = (T*)omp_target_alloc(n_bytes, dev);
344 #pragma omp target teams HAMR_OPENMP_LOOP is_device_ptr(ptr) map(to: val)
345 for (
size_t i = 0; i < n; ++i)
348 #if defined(HAMR_VERBOSE)
351 std::cerr <<
"openmp_allocator allocating array of " << n
352 <<
" numbers of type " <<
typeid(T).name() <<
sizeof(T)
353 <<
" at " << ptr <<
" initialized to " << val << std::endl;
358 return std::shared_ptr<T>(ptr, openmp_deleter<T>(ptr, n, dev));
362 template <
typename T>
363 template <
typename U>
365 openmp_allocator<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
366 ::allocate(
size_t n,
const U *vals)
368 size_t n_bytes = n*
sizeof(T);
371 int dev = omp_get_default_device();
372 T *ptr = (T*)omp_target_alloc(n_bytes, dev);
375 #pragma omp target teams HAMR_OPENMP_LOOP is_device_ptr(ptr) map(to: vals[0:n])
376 for (
size_t i = 0; i < n; ++i)
379 #if defined(HAMR_VERBOSE)
382 std::cerr <<
"openmp_allocator allocating array of " << n
383 <<
" numbers of type " <<
typeid(T).name() <<
sizeof(T)
384 <<
" at " << ptr <<
" initialized from an array of numbers of type "
385 <<
typeid(U).name() <<
sizeof(U) <<
" at " << vals << std::endl;
390 return std::shared_ptr<T>(ptr, openmp_deleter<T>(ptr, n, dev));