Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:15:39

0001 #ifndef HeterogeneousCore_AlpakaCore_interface_alpaka_Record_h
0002 #define HeterogeneousCore_AlpakaCore_interface_alpaka_Record_h
0003 
0004 #include "FWCore/Framework/interface/ESHandle.h"
0005 #include "FWCore/Framework/interface/ESTransientHandle.h"
0006 #include "FWCore/Utilities/interface/ESGetToken.h"
0007 #include "HeterogeneousCore/AlpakaCore/interface/QueueCache.h"
0008 #include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESGetToken.h"
0009 #include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESDeviceProduct.h"
0010 #include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESDeviceProductType.h"
0011 
0012 namespace ALPAKA_ACCELERATOR_NAMESPACE {
0013   class ESProducer;
0014 
0015   namespace device {
0016     /**
0017    * The device::Record class template mimics the EventSetup Record
0018    * classes, and provides access to ESProducts in the host memory
0019    * space, and in the device memory space defined by the backend
0020    * (i.e. ALPAKA_ACCELERATOR_NAMESPACE), that exist in the TRecord
0021    * Record. The device::Record also gives access to the Queue object
0022    * the ESProducer should use to queue all the device operations.
0023    *
0024    * Access to device memory space products is synchronized properly.
0025    *
0026    * Note that not full interface of EventSetup Record is replicated
0027    * here. If something important is missing, that can be added.
0028    */
0029     template <typename TRecord>
0030     class Record {
0031     public:
0032       // TODO: support for multiple devices will be added later
0033       Record(TRecord const& record, Device const& device)
0034           : record_(record), queue_(cms::alpakatools::getQueueCache<Queue>().get(device)) {}
0035 
0036       // Alpaka operations do not accept a temporary as an argument
0037       // TODO: Returning non-const reference here is BAD
0038       Queue& queue() const { return *queue_; }
0039 
0040       // getHandle()
0041 
0042       template <typename TProduct, typename TDepRecord>
0043       edm::ESHandle<TProduct> getHandle(edm::ESGetToken<TProduct, TDepRecord> const& iToken) const {
0044         return record_.getHandle(iToken);
0045       }
0046 
0047       template <typename TProduct, typename TDepRecord>
0048       edm::ESHandle<TProduct> getHandle(device::ESGetToken<TProduct, TDepRecord> const& iToken) const {
0049         auto handle = record_.getHandle(iToken.underlyingToken());
0050         if constexpr (detail::useESProductDirectly<TProduct>) {
0051           return handle;
0052         } else {
0053           if (not handle) {
0054             return edm::ESHandle<TProduct>(handle.whyFailedFactory());
0055           }
0056           return edm::ESHandle<TProduct>(&handle->get(alpaka::getDev(*queue_)), handle.description());
0057         }
0058       }
0059 
0060       // getTransientHandle()
0061 
0062       template <typename TProduct, typename TDepRecord>
0063       edm::ESTransientHandle<TProduct> getTransientHandle(edm::ESGetToken<TProduct, TDepRecord> const& iToken) const {
0064         return record_.getTransientHandle(iToken);
0065       }
0066 
0067       template <typename TProduct, typename TDepRecord>
0068       edm::ESTransientHandle<TProduct> getTransientHandle(device::ESGetToken<TProduct, TDepRecord> const& iToken) const {
0069         auto handle = record_.getTransientHandle(iToken.underlyingToken());
0070         if constexpr (detail::useESProductDirectly<TProduct>) {
0071           return handle;
0072         } else {
0073           if (not handle) {
0074             return edm::ESTransientHandle<TProduct>();
0075           }
0076           if (handle.failedToGet()) {
0077             return edm::ESTransientHandle<TProduct>(handle.whyFailedFactory());
0078           }
0079           return edm::ESTransientHandle<TProduct>(&handle->get(alpaka::getDev(*queue_)), handle.description());
0080         }
0081       }
0082 
0083       // get()
0084 
0085       template <typename TProduct, typename TDepRecord>
0086       TProduct const& get(edm::ESGetToken<TProduct, TDepRecord> const& iToken) const {
0087         return record_.get(iToken);
0088       }
0089 
0090       template <typename TProduct, typename TDepRecord>
0091       TProduct const& get(device::ESGetToken<TProduct, TDepRecord> const& iToken) const {
0092         auto const& product = record_.get(iToken.underlyingToken());
0093         if constexpr (detail::useESProductDirectly<TProduct>) {
0094           return product;
0095         } else {
0096           return product.get(alpaka::getDev(*queue_));
0097         }
0098       }
0099 
0100     private:
0101       friend ESProducer;
0102 
0103       std::shared_ptr<Queue> queuePtr() const { return queue_; }
0104 
0105       TRecord const& record_;
0106       std::shared_ptr<Queue> queue_;
0107     };
0108   }  // namespace device
0109 }  // namespace ALPAKA_ACCELERATOR_NAMESPACE
0110 
0111 #endif