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],
40  config,
41  true, // reuseSameQueueAllocations
42  debug);
43  }
44  } catch (...) {
45  --index;
46  // destroy any object that had been succesfully constructed
47  while (index >= 0) {
48  std::destroy_at(ptr + index);
49  --index;
50  }
51  // deallocate the storage
52  std::allocator<Allocator>().deallocate(ptr, size);
53  // rethrow the exception
54  throw;
55  }
56 
57  // use a custom deleter to destroy all objects and deallocate the memory
58  auto deleter = [size](Allocator* allocators) {
59  for (size_t i = size; i > 0; --i) {
60  std::destroy_at(allocators + i - 1);
61  }
62  std::allocator<Allocator>().deallocate(allocators, size);
63  };
64 
65  return std::unique_ptr<Allocator[], decltype(deleter)>(ptr, deleter);
66  }
67 
68  } // namespace detail
69 
70  template <typename TDev,
71  typename TQueue,
72  typename = std::enable_if_t<alpaka::isDevice<TDev> and alpaka::isQueue<TQueue>>>
75  bool debug = false) {
76  // initialise all allocators, one per device
77  CMS_THREAD_SAFE static auto allocators = detail::allocate_device_allocators<TDev, TQueue>(config, debug);
78 
79  size_t const index = alpaka::getNativeHandle(device);
80  assert(index < cms::alpakatools::devices<alpaka::Platform<TDev>>().size());
81 
82  // the public interface is thread safe
83  return allocators[index];
84  }
85 
86 } // namespace cms::alpakatools
87 
88 #endif // HeterogeneousCore_AlpakaInterface_interface_getDeviceCachingAllocator_h
def config(tmpl, pkg_help)
Definition: cms.py:19
Definition: config.py:1
assert(be >=bs)
#define CMS_THREAD_SAFE
auto allocate_device_allocators(AllocatorConfig const &config, bool debug)
#define debug
Definition: HDRShower.cc:19
std::vector< alpaka::Dev< TPlatform > > const & devices()
Definition: devices.h:22
CachingAllocator< TDev, TQueue > & getDeviceCachingAllocator(TDev const &device, AllocatorConfig const &config=AllocatorConfig{}, bool debug=false)
std::unique_ptr< GeometricDet > construct(DDCompactView const &cpv, std::vector< int > const &detidShifts)