Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-12 03:12:11

0001 #ifndef DataFormats_Common_interface_DeviceProduct_h
0002 #define DataFormats_Common_interface_DeviceProduct_h
0003 
0004 #include <cassert>
0005 #include <memory>
0006 
0007 #include "DataFormats/Common/interface/Uninitialized.h"
0008 
0009 namespace edm {
0010   class DeviceProductBase {
0011   public:
0012     DeviceProductBase() = default;
0013     ~DeviceProductBase() = default;
0014 
0015     // TODO: in principle this function is an implementation detail
0016     template <typename M>
0017     M const& metadata() const {
0018       // TODO: I believe the assertion could be removed safely after
0019       // the data dependence and scheduling systems would guarantee
0020       // that the an EDModule in a given execution space can access
0021       // only to the EDProducts in a memory space compatible with the
0022       // execution space.
0023       //
0024       // On the other hand, with Alpaka (likely with others) the
0025       // getSynchronized() does additional checks so the added cost is
0026       // probably not that much?
0027       assert(typeid(M) == *metadataType_);
0028       return *static_cast<M const*>(metadata_.get());
0029     }
0030 
0031   protected:
0032     template <typename M>
0033     explicit DeviceProductBase(std::shared_ptr<M> metadata)
0034         : metadata_(std::move(metadata)), metadataType_(&typeid(M)) {}
0035 
0036   private:
0037     std::shared_ptr<void const> metadata_;
0038     std::type_info const* metadataType_;
0039   };
0040 
0041   /**
0042    * A wrapper for Event Data product in device memory accompanied
0043    * with some device-specific metadata. Not intended to be used directly by
0044    * developers (except in ROOT dictionary declarations in
0045    * classes_def.xml similar to edm::Wrapper).
0046    */
0047   template <typename T>
0048   class DeviceProduct : public DeviceProductBase {
0049   public:
0050     DeviceProduct()
0051       requires(requires { T(); })
0052     = default;
0053 
0054     explicit DeviceProduct(edm::Uninitialized)
0055       requires(requires { T(edm::kUninitialized); })
0056         : data_{edm::kUninitialized} {}
0057 
0058     template <typename M, typename... Args>
0059     explicit DeviceProduct(std::shared_ptr<M> metadata, Args&&... args)
0060         : DeviceProductBase(std::move(metadata)), data_(std::forward<Args>(args)...) {}
0061 
0062     DeviceProduct(const DeviceProduct&) = delete;
0063     DeviceProduct& operator=(const DeviceProduct&) = delete;
0064     DeviceProduct(DeviceProduct&&) = default;
0065     DeviceProduct& operator=(DeviceProduct&&) = default;
0066 
0067     /**
0068      * Get the actual data product after the metadata object has
0069      * synchronized the access. The synchronization details depend on
0070      * the metadata type, which the caller must know. All the
0071      * arguments are passed to M::synchronize() function.
0072      */
0073     template <typename M, typename... Args>
0074     T const& getSynchronized(Args&&... args) const {
0075       auto const& md = metadata<M>();
0076       md.synchronize(std::forward<Args>(args)...);
0077       return data_;
0078     }
0079 
0080   private:
0081     T data_;  //!
0082   };
0083 }  // namespace edm
0084 #endif