Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-11-24 00:02:23

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