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 
14 
15 namespace cms::alpakatools {
16 
17  namespace detail {
18 
19  template <typename TDev,
20  typename TQueue,
21  typename = std::enable_if_t<alpaka::isDevice<TDev> and alpaka::isQueue<TQueue>>>
23  using Allocator = CachingAllocator<TDev, TQueue>;
24  auto const& devices = cms::alpakatools::devices<alpaka::Pltf<TDev>>();
25  ssize_t const size = devices.size();
26 
27  // allocate the storage for the objects
28  auto ptr = std::allocator<Allocator>().allocate(size);
29 
30  // construct the objects in the storage
31  ptrdiff_t index = 0;
32  try {
33  for (; index < size; ++index) {
34 #if __cplusplus >= 202002L
35  std::construct_at(
36 #else
37  std::allocator<Allocator>().construct(
38 #endif
39  ptr + index,
40  devices[index],
46  true, // reuseSameQueueAllocations
47  false); // debug
48  }
49  } catch (...) {
50  --index;
51  // destroy any object that had been succesfully constructed
52  while (index >= 0) {
53  std::destroy_at(ptr + index);
54  --index;
55  }
56  // deallocate the storage
57  std::allocator<Allocator>().deallocate(ptr, size);
58  // rethrow the exception
59  throw;
60  }
61 
62  // use a custom deleter to destroy all objects and deallocate the memory
63  auto deleter = [size](Allocator* ptr) {
64  for (size_t i = size; i > 0; --i) {
65  std::destroy_at(ptr + i - 1);
66  }
67  std::allocator<Allocator>().deallocate(ptr, size);
68  };
69 
70  return std::unique_ptr<Allocator[], decltype(deleter)>(ptr, deleter);
71  }
72 
73  } // namespace detail
74 
75  template <typename TDev,
76  typename TQueue,
77  typename = std::enable_if_t<alpaka::isDevice<TDev> and alpaka::isQueue<TQueue>>>
79  // initialise all allocators, one per device
80  CMS_THREAD_SAFE static auto allocators = detail::allocate_device_allocators<TDev, TQueue>();
81 
82  size_t const index = alpaka::getNativeHandle(device);
83  assert(index < cms::alpakatools::devices<alpaka::Pltf<TDev>>().size());
84 
85  // the public interface is thread safe
86  return allocators[index];
87  }
88 
89 } // namespace cms::alpakatools
90 
91 #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:35
std::unique_ptr< GeometricDet > construct(DDCompactView const &cpv, std::vector< int > const &detidShifts)