CMS 3D CMS Logo

AlpakaService.cc
Go to the documentation of this file.
1 #include <boost/core/demangle.hpp>
2 
3 #include <alpaka/alpaka.hpp>
4 
16 
17 #ifdef ALPAKA_ACC_GPU_CUDA_ENABLED
20 #endif // ALPAKA_ACC_GPU_CUDA_ENABLED
21 
22 #ifdef ALPAKA_ACC_GPU_HIP_ENABLED
25 #endif // ALPAKA_ACC_GPU_HIP_ENABLED
26 
27 namespace {
28 
29  // Note: we cannot use "uint64_t" with the ParameterSet-related functions, because the template specialisations expect "unsigned long long", while "uint64_t" expands to "unsigned long".
30 
31  edm::ParameterSetDescription createAllocatorConfig(
34  desc.addUntracked<uint32_t>("binGrowth", alloc.binGrowth)
35  ->setComment("Bin growth factor (bin_growth in cub::CachingDeviceAllocator)");
36  desc.addUntracked<uint32_t>("minBin", alloc.minBin)
37  ->setComment(
38  "Smallest bin, corresponds to binGrowth^minBin bytes (min_bin in cub::CachingDeviceAllocator).\n8 "
39  "corresponds to 256 bytes.");
40  desc.addUntracked<uint32_t>("maxBin", alloc.maxBin)
41  ->setComment(
42  "Largest bin, corresponds to binGrowth^maxBin bytes (max_bin in cub::CachingDeviceAllocator).\n30 "
43  "corresponds do 1 GiB.\nNote that unlike in cub, allocations larger than binGrowth^maxBin are set to "
44  "fail.");
45  desc.addUntracked<unsigned long long>("maxCachedBytes", alloc.maxCachedBytes)
46  ->setComment("Total storage for the allocator; 0 means no limit.");
47  desc.addUntracked<double>("maxCachedFraction", alloc.maxCachedFraction)
48  ->setComment(
49  "Fraction of total device memory taken for the allocator; 0 means no limit.\nIf both maxCachedBytes and "
50  "maxCachedFraction are non-zero, the smallest resulting value is used.");
51  desc.addUntracked<bool>("fillAllocations", alloc.fillAllocations)
52  ->setComment("Fill all newly allocated or re-used memory blocks with fillAllocationValue.");
53  desc.addUntracked<uint32_t>("fillAllocationValue", alloc.fillAllocationValue)
54  ->setComment("Byte value used to fill all newly allocated or re-used memory blocks");
55  desc.addUntracked<bool>("fillReallocations", alloc.fillReallocations)
56  ->setComment(
57  "Fill only the re-used memory blocks with fillReallocationValue.\nIf both fillAllocations and "
58  "fillReallocations are true, fillAllocationValue is used for newly allocated blocks and "
59  "fillReallocationValue is used for re-allocated blocks.");
60  desc.addUntracked<uint32_t>("fillReallocationValue", alloc.fillReallocationValue)
61  ->setComment("Byte value used to fill all re-used memory blocks");
62  desc.addUntracked<bool>("fillDeallocations", alloc.fillDeallocations)
63  ->setComment("Fill memory blocks with fillDeallocationValue before freeing or caching them for re-use");
64  desc.addUntracked<uint32_t>("fillDeallocationValue", alloc.fillDeallocationValue)
65  ->setComment("Byte value used to fill all deallocated or cached memory blocks");
66  desc.addUntracked<bool>("fillCaches", alloc.fillCaches)
67  ->setComment(
68  "Fill memory blocks with fillCacheValue before caching them for re-use.\nIf both fillDeallocations and "
69  "fillCaches are true, fillDeallocationValue is used for blocks about to be freed and fillCacheValue is "
70  "used for blocks about to be cached.");
71  desc.addUntracked<uint32_t>("fillCacheValue", alloc.fillCacheValue)
72  ->setComment("Byte value used to fill all cached memory blocks");
73  return desc;
74  }
75 
76  cms::alpakatools::AllocatorConfig parseAllocatorConfig(edm::ParameterSet const& config) {
78  alloc.binGrowth = config.getUntrackedParameter<uint32_t>("binGrowth");
79  alloc.minBin = config.getUntrackedParameter<uint32_t>("minBin");
80  alloc.maxBin = config.getUntrackedParameter<uint32_t>("maxBin");
81  alloc.maxCachedBytes = config.getUntrackedParameter<unsigned long long>("maxCachedBytes");
82  alloc.maxCachedFraction = config.getUntrackedParameter<double>("maxCachedFraction");
83  alloc.fillAllocations = config.getUntrackedParameter<bool>("fillAllocations");
84  alloc.fillAllocationValue = static_cast<uint8_t>(config.getUntrackedParameter<uint32_t>("fillAllocationValue"));
85  alloc.fillReallocations = config.getUntrackedParameter<bool>("fillReallocations");
86  alloc.fillReallocationValue = static_cast<uint8_t>(config.getUntrackedParameter<uint32_t>("fillReallocationValue"));
87  alloc.fillDeallocations = config.getUntrackedParameter<bool>("fillDeallocations");
88  alloc.fillDeallocationValue = static_cast<uint8_t>(config.getUntrackedParameter<uint32_t>("fillDeallocationValue"));
89  alloc.fillCaches = config.getUntrackedParameter<bool>("fillCaches");
90  alloc.fillCacheValue = static_cast<uint8_t>(config.getUntrackedParameter<uint32_t>("fillCacheValue"));
91  return alloc;
92  }
93 
94 } // namespace
95 
97 
99  : enabled_(config.getUntrackedParameter<bool>("enabled")),
100  verbose_(config.getUntrackedParameter<bool>("verbose")) {
101 #ifdef ALPAKA_ACC_GPU_CUDA_ENABLED
102  // rely on the CUDAService to initialise the CUDA devices
104 #endif // ALPAKA_ACC_GPU_CUDA_ENABLED
105 #ifdef ALPAKA_ACC_GPU_HIP_ENABLED
106  // rely on the ROCmService to initialise the ROCm devices
108 #endif // ALPAKA_ACC_GPU_HIP_ENABLED
109 
110  // TODO from Andrea Bocci:
111  // - extract and print more information about the platform and devices
112 
113  if (not enabled_) {
114  edm::LogInfo("AlpakaService") << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << " disabled by configuration";
115  return;
116  }
117 
118 #ifdef ALPAKA_ACC_GPU_CUDA_ENABLED
119  if (not cuda or not cuda->enabled()) {
120  enabled_ = false;
121  edm::LogInfo("AlpakaService") << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << " disabled by CUDAService";
122  return;
123  }
124 #endif // ALPAKA_ACC_GPU_CUDA_ENABLED
125 #ifdef ALPAKA_ACC_GPU_HIP_ENABLED
126  if (not rocm or not rocm->enabled()) {
127  enabled_ = false;
128  edm::LogInfo("AlpakaService") << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << " disabled by ROCmService";
129  return;
130  }
131 #endif // ALPAKA_ACC_GPU_HIP_ENABLED
132 
133  // enumerate all devices on this platform
134  auto const& devices = cms::alpakatools::devices<Platform>();
135  if (devices.empty()) {
136  const std::string platform = boost::core::demangle(typeid(Platform).name());
137  edm::LogWarning("AlpakaService") << "Could not find any devices on platform " << platform << ".\n"
138  << "Disabling " << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << ".";
139  enabled_ = false;
140  return;
141  }
142 
143  {
144  const char* suffix[] = {"s.", ":", "s:"};
145  const auto n = devices.size();
146  edm::LogInfo out("AlpakaService");
147  out << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << " succesfully initialised.\n";
148  out << "Found " << n << " device" << suffix[n < 2 ? n : 2];
149  for (auto const& device : devices) {
150  out << "\n - " << alpaka::getName(device);
151  }
152  }
153 
154  // initialise the queue and event caches
155  cms::alpakatools::getQueueCache<Queue>().clear();
156  cms::alpakatools::getEventCache<Event>().clear();
157 
158  // initialise the caching memory allocators
159  cms::alpakatools::AllocatorConfig hostAllocatorConfig =
160  parseAllocatorConfig(config.getUntrackedParameter<edm::ParameterSet>("hostAllocator"));
161  cms::alpakatools::getHostCachingAllocator<Queue>(hostAllocatorConfig, verbose_);
162  cms::alpakatools::AllocatorConfig deviceAllocatorConfig =
163  parseAllocatorConfig(config.getUntrackedParameter<edm::ParameterSet>("deviceAllocator"));
164  for (auto const& device : devices)
165  cms::alpakatools::getDeviceCachingAllocator<Device, Queue>(device, deviceAllocatorConfig, verbose_);
166  }
167 
169  // clean up the caching memory allocators
170  cms::alpakatools::getHostCachingAllocator<Queue>().freeAllCached();
171  for (auto const& device : cms::alpakatools::devices<Platform>())
172  cms::alpakatools::getDeviceCachingAllocator<Device, Queue>(device).freeAllCached();
173 
174  // clean up the queue and event caches
175  cms::alpakatools::getQueueCache<Queue>().clear();
176  cms::alpakatools::getEventCache<Event>().clear();
177  }
178 
181  desc.addUntracked<bool>("enabled", true);
182  desc.addUntracked<bool>("verbose", false);
183  desc.addUntracked<edm::ParameterSetDescription>("hostAllocator", createAllocatorConfig())
184  ->setComment("Configuration for the host's CachingAllocator");
185  desc.addUntracked<edm::ParameterSetDescription>("deviceAllocator", createAllocatorConfig())
186  ->setComment("Configuration for the devices' CachingAllocator");
187 
188  descriptions.add(ALPAKA_TYPE_ALIAS_NAME(AlpakaService), desc);
189  }
190 
191 } // namespace ALPAKA_ACCELERATOR_NAMESPACE
AlpakaService(edm::ParameterSet const &config, edm::ActivityRegistry &)
Definition: config.py:1
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
Log< level::Info, false > LogInfo
void add(std::string const &label, ParameterSetDescription const &psetDescription)
std::vector< alpaka::Dev< TPlatform > > const & devices()
Definition: devices.h:22
std::string getName(const G4String &)
Definition: ForwardName.cc:3
void clear(EGIsoObj &c)
Definition: egamma.h:82
Log< level::Warning, false > LogWarning
TPlatform const & platform()
Definition: devices.h:14