Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:03:51

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