File indexing completed on 2023-02-02 16:37:49
0001 #ifndef HeterogeneousCore_AlpakaCore_interface_alpaka_ESProducer_h
0002 #define HeterogeneousCore_AlpakaCore_interface_alpaka_ESProducer_h
0003
0004 #include "FWCore/Framework/interface/ESProducer.h"
0005 #include "FWCore/Framework/interface/produce_helpers.h"
0006 #include "HeterogeneousCore/AlpakaCore/interface/module_backend_config.h"
0007 #include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESDeviceProduct.h"
0008 #include "HeterogeneousCore/AlpakaCore/interface/alpaka/Record.h"
0009 #include "HeterogeneousCore/AlpakaInterface/interface/devices.h"
0010
0011 #include <functional>
0012
0013 namespace ALPAKA_ACCELERATOR_NAMESPACE {
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 class ESProducer : public edm::ESProducer {
0025 using Base = edm::ESProducer;
0026
0027 public:
0028 static void prevalidate(edm::ConfigurationDescriptions& descriptions) {
0029 Base::prevalidate(descriptions);
0030 cms::alpakatools::module_backend_config(descriptions);
0031 }
0032
0033 protected:
0034 template <typename T>
0035 auto setWhatProduced(T* iThis, edm::es::Label const& label = {}) {
0036 return setWhatProduced(iThis, &T::produce, label);
0037 }
0038
0039 template <typename T, typename TReturn, typename TRecord>
0040 auto setWhatProduced(T* iThis, TReturn (T ::*iMethod)(TRecord const&), edm::es::Label const& label = {}) {
0041 return Base::setWhatProduced(iThis, iMethod, label);
0042 }
0043
0044 template <typename T, typename TReturn, typename TRecord>
0045 auto setWhatProduced(T* iThis,
0046 TReturn (T ::*iMethod)(device::Record<TRecord> const&),
0047 edm::es::Label const& label = {}) {
0048 using TProduct = typename edm::eventsetup::produce::smart_pointer_traits<TReturn>::type;
0049 using ProductType = ESDeviceProduct<TProduct>;
0050 using ReturnType = detail::ESDeviceProductWithStorage<TProduct, TReturn>;
0051 return Base::setWhatProduced(
0052 [iThis, iMethod](TRecord const& record) -> std::unique_ptr<ProductType> {
0053
0054 auto const& devices = cms::alpakatools::devices<Platform>();
0055 std::vector<std::shared_ptr<Queue>> queues;
0056 queues.reserve(devices.size());
0057 auto ret = std::make_unique<ReturnType>(devices.size());
0058 bool allnull = true;
0059 bool anynull = false;
0060 for (auto const& dev : devices) {
0061 device::Record<TRecord> const deviceRecord(record, dev);
0062 auto prod = std::invoke(iMethod, iThis, deviceRecord);
0063 if (prod) {
0064 allnull = false;
0065 ret->insert(dev, std::move(prod));
0066 } else {
0067 anynull = true;
0068 }
0069 queues.push_back(deviceRecord.queuePtr());
0070 }
0071
0072 for (auto& queuePtr : queues) {
0073 alpaka::wait(*queuePtr);
0074 }
0075 if (allnull) {
0076 return nullptr;
0077 } else if (anynull) {
0078
0079
0080
0081
0082
0083
0084
0085
0086 ESProducer::throwSomeNullException();
0087 }
0088 return ret;
0089 },
0090 label);
0091 }
0092
0093 private:
0094 static void throwSomeNullException();
0095 };
0096 }
0097
0098 #endif