File indexing completed on 2023-02-02 16:37:49
0001 #ifndef HeterogeneousCore_AlpakaCore_interface_ProducerBase_h
0002 #define HeterogeneousCore_AlpakaCore_interface_ProducerBase_h
0003
0004 #include "DataFormats/Common/interface/DeviceProduct.h"
0005 #include "FWCore/Framework/interface/FrameworkfwdMostUsed.h"
0006 #include "FWCore/Framework/interface/moduleAbilities.h"
0007 #include "FWCore/Utilities/interface/EDPutToken.h"
0008 #include "FWCore/Utilities/interface/Transition.h"
0009 #include "HeterogeneousCore/AlpakaCore/interface/alpaka/EDMetadataAcquireSentry.h"
0010 #include "HeterogeneousCore/AlpakaCore/interface/EventCache.h"
0011 #include "HeterogeneousCore/AlpakaCore/interface/QueueCache.h"
0012 #include "HeterogeneousCore/AlpakaCore/interface/module_backend_config.h"
0013 #include "HeterogeneousCore/AlpakaInterface/interface/TransferToHost.h"
0014
0015 #include <memory>
0016 #include <tuple>
0017
0018 namespace ALPAKA_ACCELERATOR_NAMESPACE {
0019 template <typename Producer, edm::Transition Tr>
0020 class ProducerBaseAdaptor;
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 template <template <typename...> class BaseT, typename... Args>
0039 class ProducerBase : public BaseT<Args..., edm::Transformer> {
0040 static_assert(not edm::CheckAbility<edm::module::Abilities::kTransformer>::kHasIt,
0041 "ALPAKA_ACCELERATOR_NAMESPACE::ProducerBase can not be used with Transformer ability (as it is "
0042 "used internally)");
0043 using Base = BaseT<Args..., edm::Transformer>;
0044
0045 public:
0046 template <edm::Transition Tr = edm::Transition::Event>
0047 [[nodiscard]] auto produces() noexcept {
0048 return ProducerBaseAdaptor<ProducerBase, Tr>(*this);
0049 }
0050
0051 template <edm::Transition Tr = edm::Transition::Event>
0052 [[nodiscard]] auto produces(std::string instanceName) noexcept {
0053 return ProducerBaseAdaptor<ProducerBase, Tr>(*this, std::move(instanceName));
0054 }
0055
0056 static void prevalidate(edm::ConfigurationDescriptions& descriptions) {
0057 Base::prevalidate(descriptions);
0058 cms::alpakatools::module_backend_config(descriptions);
0059 }
0060
0061 private:
0062 template <typename TProducer, edm::Transition Tr>
0063 friend class ProducerBaseAdaptor;
0064
0065
0066
0067
0068
0069 template <typename TProduct, edm::Transition Tr>
0070 edm::EDPutTokenT<TProduct> produces(std::string instanceName) {
0071 return Base::template produces<TProduct, Tr>(std::move(instanceName));
0072 }
0073
0074
0075
0076
0077
0078 template <typename TProduct, typename TToken, edm::Transition Tr>
0079 edm::EDPutTokenT<TToken> deviceProduces(std::string instanceName) {
0080 edm::EDPutTokenT<TToken> token = Base::template produces<TToken, Tr>(std::move(instanceName));
0081
0082 #ifndef ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED
0083
0084
0085
0086
0087
0088 this->registerTransformAsync(
0089 token,
0090 [](TToken const& deviceProduct, edm::WaitingTaskWithArenaHolder holder) {
0091 auto const& device = alpaka::getDev(deviceProduct.template metadata<EDMetadata>().queue());
0092 detail::EDMetadataAcquireSentry sentry(device, std::move(holder));
0093 auto metadataPtr = sentry.metadata();
0094 constexpr bool tryReuseQueue = true;
0095 TProduct const& productOnDevice =
0096 deviceProduct.template getSynchronized<EDMetadata>(*metadataPtr, tryReuseQueue);
0097
0098 using TransferT = cms::alpakatools::TransferToHost<TProduct>;
0099 using HostType = typename TransferT::HostDataType;
0100 HostType productOnHost = TransferT::transferAsync(metadataPtr->queue(), productOnDevice);
0101
0102
0103
0104 using TplType = std::tuple<HostType, std::shared_ptr<EDMetadata>>;
0105
0106 return std::make_shared<TplType>(std::move(productOnHost), sentry.finish());
0107 },
0108 [](auto tplPtr) { return std::move(std::get<0>(*tplPtr)); });
0109 #endif
0110 return token;
0111 }
0112 };
0113
0114
0115 template <typename TProducer, edm::Transition Tr>
0116 class ProducerBaseAdaptor {
0117 public:
0118
0119 template <typename Type>
0120 edm::EDPutTokenT<Type> produces() {
0121 return producer_.template produces<Type, Tr>(label_);
0122 }
0123
0124
0125 template <typename TProduct, typename TToken>
0126 edm::EDPutTokenT<TToken> deviceProduces() {
0127 return producer_.template deviceProduces<TProduct, TToken, Tr>(label_);
0128 }
0129
0130 private:
0131
0132 friend TProducer;
0133
0134 ProducerBaseAdaptor(TProducer& producer, std::string label) : producer_(producer), label_(std::move(label)) {}
0135 explicit ProducerBaseAdaptor(TProducer& producer) : producer_(producer) {}
0136
0137 TProducer& producer_;
0138 std::string const label_;
0139 };
0140 }
0141
0142 #endif