File indexing completed on 2024-07-02 00:53:48
0001 #include <boost/core/demangle.hpp>
0002
0003 #include <alpaka/alpaka.hpp>
0004
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0008 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0009 #include "HeterogeneousCore/AlpakaCore/interface/EventCache.h"
0010 #include "HeterogeneousCore/AlpakaCore/interface/QueueCache.h"
0011 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
0012 #include "HeterogeneousCore/AlpakaInterface/interface/devices.h"
0013 #include "HeterogeneousCore/AlpakaInterface/interface/getDeviceCachingAllocator.h"
0014 #include "HeterogeneousCore/AlpakaInterface/interface/getHostCachingAllocator.h"
0015 #include "HeterogeneousCore/AlpakaServices/interface/alpaka/AlpakaService.h"
0016
0017 #ifdef ALPAKA_ACC_GPU_CUDA_ENABLED
0018 #include "FWCore/ServiceRegistry/interface/Service.h"
0019 #include "HeterogeneousCore/CUDAServices/interface/CUDAInterface.h"
0020 #endif
0021
0022 #ifdef ALPAKA_ACC_GPU_HIP_ENABLED
0023 #include "FWCore/ServiceRegistry/interface/Service.h"
0024 #include "HeterogeneousCore/ROCmServices/interface/ROCmInterface.h"
0025 #endif
0026
0027 namespace {
0028
0029
0030
0031 edm::ParameterSetDescription createAllocatorConfig(
0032 cms::alpakatools::AllocatorConfig const& alloc = cms::alpakatools::AllocatorConfig{}) {
0033 edm::ParameterSetDescription desc;
0034 desc.addUntracked<uint32_t>("binGrowth", alloc.binGrowth)
0035 ->setComment("Bin growth factor (bin_growth in cub::CachingDeviceAllocator)");
0036 desc.addUntracked<uint32_t>("minBin", alloc.minBin)
0037 ->setComment(
0038 "Smallest bin, corresponds to binGrowth^minBin bytes (min_bin in cub::CachingDeviceAllocator).\n8 "
0039 "corresponds to 256 bytes.");
0040 desc.addUntracked<uint32_t>("maxBin", alloc.maxBin)
0041 ->setComment(
0042 "Largest bin, corresponds to binGrowth^maxBin bytes (max_bin in cub::CachingDeviceAllocator).\n30 "
0043 "corresponds do 1 GiB.\nNote that unlike in cub, allocations larger than binGrowth^maxBin are set to "
0044 "fail.");
0045 desc.addUntracked<unsigned long long>("maxCachedBytes", alloc.maxCachedBytes)
0046 ->setComment("Total storage for the allocator; 0 means no limit.");
0047 desc.addUntracked<double>("maxCachedFraction", alloc.maxCachedFraction)
0048 ->setComment(
0049 "Fraction of total device memory taken for the allocator; 0 means no limit.\nIf both maxCachedBytes and "
0050 "maxCachedFraction are non-zero, the smallest resulting value is used.");
0051 desc.addUntracked<bool>("fillAllocations", alloc.fillAllocations)
0052 ->setComment("Fill all newly allocated or re-used memory blocks with fillAllocationValue.");
0053 desc.addUntracked<uint32_t>("fillAllocationValue", alloc.fillAllocationValue)
0054 ->setComment("Byte value used to fill all newly allocated or re-used memory blocks");
0055 desc.addUntracked<bool>("fillReallocations", alloc.fillReallocations)
0056 ->setComment(
0057 "Fill only the re-used memory blocks with fillReallocationValue.\nIf both fillAllocations and "
0058 "fillReallocations are true, fillAllocationValue is used for newly allocated blocks and "
0059 "fillReallocationValue is used for re-allocated blocks.");
0060 desc.addUntracked<uint32_t>("fillReallocationValue", alloc.fillReallocationValue)
0061 ->setComment("Byte value used to fill all re-used memory blocks");
0062 desc.addUntracked<bool>("fillDeallocations", alloc.fillDeallocations)
0063 ->setComment("Fill memory blocks with fillDeallocationValue before freeing or caching them for re-use");
0064 desc.addUntracked<uint32_t>("fillDeallocationValue", alloc.fillDeallocationValue)
0065 ->setComment("Byte value used to fill all deallocated or cached memory blocks");
0066 desc.addUntracked<bool>("fillCaches", alloc.fillCaches)
0067 ->setComment(
0068 "Fill memory blocks with fillCacheValue before caching them for re-use.\nIf both fillDeallocations and "
0069 "fillCaches are true, fillDeallocationValue is used for blocks about to be freed and fillCacheValue is "
0070 "used for blocks about to be cached.");
0071 desc.addUntracked<uint32_t>("fillCacheValue", alloc.fillCacheValue)
0072 ->setComment("Byte value used to fill all cached memory blocks");
0073 return desc;
0074 }
0075
0076 cms::alpakatools::AllocatorConfig parseAllocatorConfig(edm::ParameterSet const& config) {
0077 cms::alpakatools::AllocatorConfig alloc;
0078 alloc.binGrowth = config.getUntrackedParameter<uint32_t>("binGrowth");
0079 alloc.minBin = config.getUntrackedParameter<uint32_t>("minBin");
0080 alloc.maxBin = config.getUntrackedParameter<uint32_t>("maxBin");
0081 alloc.maxCachedBytes = config.getUntrackedParameter<unsigned long long>("maxCachedBytes");
0082 alloc.maxCachedFraction = config.getUntrackedParameter<double>("maxCachedFraction");
0083 alloc.fillAllocations = config.getUntrackedParameter<bool>("fillAllocations");
0084 alloc.fillAllocationValue = static_cast<uint8_t>(config.getUntrackedParameter<uint32_t>("fillAllocationValue"));
0085 alloc.fillReallocations = config.getUntrackedParameter<bool>("fillReallocations");
0086 alloc.fillReallocationValue = static_cast<uint8_t>(config.getUntrackedParameter<uint32_t>("fillReallocationValue"));
0087 alloc.fillDeallocations = config.getUntrackedParameter<bool>("fillDeallocations");
0088 alloc.fillDeallocationValue = static_cast<uint8_t>(config.getUntrackedParameter<uint32_t>("fillDeallocationValue"));
0089 alloc.fillCaches = config.getUntrackedParameter<bool>("fillCaches");
0090 alloc.fillCacheValue = static_cast<uint8_t>(config.getUntrackedParameter<uint32_t>("fillCacheValue"));
0091 return alloc;
0092 }
0093
0094 }
0095
0096 namespace ALPAKA_ACCELERATOR_NAMESPACE {
0097
0098 AlpakaService::AlpakaService(edm::ParameterSet const& config, edm::ActivityRegistry&)
0099 : enabled_(config.getUntrackedParameter<bool>("enabled")),
0100 verbose_(config.getUntrackedParameter<bool>("verbose")) {
0101 #ifdef ALPAKA_ACC_GPU_CUDA_ENABLED
0102
0103 edm::Service<CUDAInterface> cuda;
0104 #endif
0105 #ifdef ALPAKA_ACC_GPU_HIP_ENABLED
0106
0107 edm::Service<ROCmInterface> rocm;
0108 #endif
0109
0110
0111
0112
0113 if (not enabled_) {
0114 edm::LogInfo("AlpakaService") << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << " disabled by configuration";
0115 return;
0116 }
0117
0118 #ifdef ALPAKA_ACC_GPU_CUDA_ENABLED
0119 if (not cuda or not cuda->enabled()) {
0120 enabled_ = false;
0121 edm::LogInfo("AlpakaService") << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << " disabled by CUDAService";
0122 return;
0123 }
0124 #endif
0125 #ifdef ALPAKA_ACC_GPU_HIP_ENABLED
0126 if (not rocm or not rocm->enabled()) {
0127 enabled_ = false;
0128 edm::LogInfo("AlpakaService") << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << " disabled by ROCmService";
0129 return;
0130 }
0131 #endif
0132
0133
0134 auto const& devices = cms::alpakatools::devices<Platform>();
0135 if (devices.empty()) {
0136 const std::string platform = boost::core::demangle(typeid(Platform).name());
0137 edm::LogWarning("AlpakaService") << "Could not find any devices on platform " << platform << ".\n"
0138 << "Disabling " << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << ".";
0139 enabled_ = false;
0140 return;
0141 }
0142
0143 {
0144 const char* suffix[] = {"s.", ":", "s:"};
0145 const auto n = devices.size();
0146 edm::LogInfo out("AlpakaService");
0147 out << ALPAKA_TYPE_ALIAS_NAME(AlpakaService) << " succesfully initialised.\n";
0148 out << "Found " << n << " device" << suffix[n < 2 ? n : 2];
0149 for (auto const& device : devices) {
0150 out << "\n - " << alpaka::getName(device);
0151 }
0152 }
0153
0154
0155 cms::alpakatools::getQueueCache<Queue>().clear();
0156 cms::alpakatools::getEventCache<Event>().clear();
0157
0158
0159 cms::alpakatools::AllocatorConfig hostAllocatorConfig =
0160 parseAllocatorConfig(config.getUntrackedParameter<edm::ParameterSet>("hostAllocator"));
0161 cms::alpakatools::getHostCachingAllocator<Queue>(hostAllocatorConfig, verbose_);
0162 cms::alpakatools::AllocatorConfig deviceAllocatorConfig =
0163 parseAllocatorConfig(config.getUntrackedParameter<edm::ParameterSet>("deviceAllocator"));
0164 for (auto const& device : devices)
0165 cms::alpakatools::getDeviceCachingAllocator<Device, Queue>(device, deviceAllocatorConfig, verbose_);
0166 }
0167
0168 AlpakaService::~AlpakaService() {
0169
0170 cms::alpakatools::getHostCachingAllocator<Queue>().freeAllCached();
0171 for (auto const& device : cms::alpakatools::devices<Platform>())
0172 cms::alpakatools::getDeviceCachingAllocator<Device, Queue>(device).freeAllCached();
0173
0174
0175 cms::alpakatools::getQueueCache<Queue>().clear();
0176 cms::alpakatools::getEventCache<Event>().clear();
0177 }
0178
0179 void AlpakaService::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0180 edm::ParameterSetDescription desc;
0181 desc.addUntracked<bool>("enabled", true);
0182 desc.addUntracked<bool>("verbose", false);
0183 desc.addUntracked<edm::ParameterSetDescription>("hostAllocator", createAllocatorConfig())
0184 ->setComment("Configuration for the host's CachingAllocator");
0185 desc.addUntracked<edm::ParameterSetDescription>("deviceAllocator", createAllocatorConfig())
0186 ->setComment("Configuration for the devices' CachingAllocator");
0187
0188 descriptions.add(ALPAKA_TYPE_ALIAS_NAME(AlpakaService), desc);
0189 }
0190
0191 }