Back to home page

Project CMSSW displayed by LXR

 
 

    


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  // ALPAKA_ACC_GPU_CUDA_ENABLED
0021 
0022 #ifdef ALPAKA_ACC_GPU_HIP_ENABLED
0023 #include "FWCore/ServiceRegistry/interface/Service.h"
0024 #include "HeterogeneousCore/ROCmServices/interface/ROCmInterface.h"
0025 #endif  // ALPAKA_ACC_GPU_HIP_ENABLED
0026 
0027 namespace {
0028 
0029   // 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".
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 }  // namespace
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     // rely on the CUDAService to initialise the CUDA devices
0103     edm::Service<CUDAInterface> cuda;
0104 #endif  // ALPAKA_ACC_GPU_CUDA_ENABLED
0105 #ifdef ALPAKA_ACC_GPU_HIP_ENABLED
0106     // rely on the ROCmService to initialise the ROCm devices
0107     edm::Service<ROCmInterface> rocm;
0108 #endif  // ALPAKA_ACC_GPU_HIP_ENABLED
0109 
0110     // TODO from Andrea Bocci:
0111     //   - extract and print more information about the platform and devices
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  // ALPAKA_ACC_GPU_CUDA_ENABLED
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  // ALPAKA_ACC_GPU_HIP_ENABLED
0132 
0133     // enumerate all devices on this platform
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     // initialise the queue and event caches
0155     cms::alpakatools::getQueueCache<Queue>().clear();
0156     cms::alpakatools::getEventCache<Event>().clear();
0157 
0158     // initialise the caching memory allocators
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     // clean up the caching memory allocators
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     // clean up the queue and event caches
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 }  // namespace ALPAKA_ACCELERATOR_NAMESPACE