CMS 3D CMS Logo

getDeviceCachingAllocator.h
Go to the documentation of this file.
1 #ifndef HeterogeneousCore_AlpakaInterface_interface_getDeviceCachingAllocator_h
2 #define HeterogeneousCore_AlpakaInterface_interface_getDeviceCachingAllocator_h
3 
4 #include <cassert>
5 #include <memory>
6 
7 #include <alpaka/alpaka.hpp>
8 
13 
14 namespace cms::alpakatools {
15 
16  namespace detail {
17 
18  template <typename TDev,
19  typename TQueue,
20  typename = std::enable_if_t<alpaka::isDevice<TDev> and alpaka::isQueue<TQueue>>>
22  using Allocator = CachingAllocator<TDev, TQueue>;
23  auto const& devices = cms::alpakatools::devices<alpaka::Platform<TDev>>();
24  ssize_t const size = devices.size();
25 
26  // allocate the storage for the objects
27  auto ptr = std::allocator<Allocator>().allocate(size);
28 
29  // construct the objects in the storage
30  ptrdiff_t index = 0;
31  try {
32  for (; index < size; ++index) {
33 #if __cplusplus >= 202002L
34  std::construct_at(
35 #else
36  std::allocator<Allocator>().construct(
37 #endif
38  ptr + index,
39  devices[index],
45  true, // reuseSameQueueAllocations
46  false); // debug
47  }
48  } catch (...) {
49  --index;
50  // destroy any object that had been succesfully constructed
51  while (index >= 0) {
52  std::destroy_at(ptr + index);
53  --index;
54  }
55  // deallocate the storage
56  std::allocator<Allocator>().deallocate(ptr, size);
57  // rethrow the exception
58  throw;
59  }
60 
61  // use a custom deleter to destroy all objects and deallocate the memory
62  auto deleter = [size](Allocator* ptr) {
63  for (size_t i = size; i > 0; --i) {
64  std::destroy_at(ptr + i - 1);
65  }
66  std::allocator<Allocator>().deallocate(ptr, size);
67  };
68 
69  return std::unique_ptr<Allocator[], decltype(deleter)>(ptr, deleter);
70  }
71 
72  } // namespace detail
73 
74  template <typename TDev,
75  typename TQueue,
76  typename = std::enable_if_t<alpaka::isDevice<TDev> and alpaka::isQueue<TQueue>>>
78  // initialise all allocators, one per device
79  CMS_THREAD_SAFE static auto allocators = detail::allocate_device_allocators<TDev, TQueue>();
80 
81  size_t const index = alpaka::getNativeHandle(device);
82  assert(index < cms::alpakatools::devices<alpaka::Platform<TDev>>().size());
83 
84  // the public interface is thread safe
85  return allocators[index];
86  }
87 
88 } // namespace cms::alpakatools
89 
90 #endif // HeterogeneousCore_AlpakaInterface_interface_getDeviceCachingAllocator_h
CachingAllocator< TDev, TQueue > & getDeviceCachingAllocator(TDev const &device)
constexpr unsigned int minBin
constexpr unsigned int maxBin
assert(be >=bs)
constexpr double maxCachedFraction
#define CMS_THREAD_SAFE
constexpr size_t maxCachedBytes
constexpr unsigned int binGrowth
std::vector< alpaka::Dev< TPlatform > > const & devices()
Definition: devices.h:22
std::unique_ptr< GeometricDet > construct(DDCompactView const &cpv, std::vector< int > const &detidShifts)