Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef HeterogeneousCore_AlpakaCore_interface_QueueCache_h
0002 #define HeterogeneousCore_AlpakaCore_interface_QueueCache_h
0003 
0004 #include <memory>
0005 #include <vector>
0006 
0007 #include <alpaka/alpaka.hpp>
0008 
0009 #include "FWCore/Utilities/interface/ReusableObjectHolder.h"
0010 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0011 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
0012 #include "HeterogeneousCore/AlpakaInterface/interface/devices.h"
0013 #include "HeterogeneousCore/AlpakaInterface/interface/AlpakaServiceFwd.h"
0014 
0015 namespace cms::alpakatools {
0016 
0017   template <typename Queue>
0018   class QueueCache {
0019 #ifdef ALPAKA_ACC_GPU_CUDA_ENABLED
0020     friend class alpaka_cuda_async::AlpakaService;
0021 #endif
0022 #ifdef ALPAKA_ACC_GPU_HIP_ENABLED
0023     friend class alpaka_rocm_async::AlpakaService;
0024 #endif
0025 #ifdef ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED
0026     friend class alpaka_serial_sync::AlpakaService;
0027 #endif
0028 #ifdef ALPAKA_ACC_CPU_B_TBB_T_SEQ_ENABLED
0029     friend class alpaka_tbb_async::AlpakaService;
0030 #endif
0031 
0032     using Device = alpaka::Dev<Queue>;
0033     using Platform = alpaka::Platform<Device>;
0034 
0035   public:
0036     // QueueCache should be constructed by the first call to
0037     // getQueueCache() only if we have any devices present
0038     QueueCache() : cache_(devices<Platform>().size()) {}
0039 
0040     // Gets a (cached) queue for the current device. The queue
0041     // will be returned to the cache by the shared_ptr destructor.
0042     // This function is thread safe
0043     std::shared_ptr<Queue> get(Device const& dev) {
0044       return cache_[alpaka::getNativeHandle(dev)].makeOrGet([dev]() { return std::make_unique<Queue>(dev); });
0045     }
0046 
0047   private:
0048     // not thread safe, intended to be called only from AlpakaService
0049     void clear() {
0050       // Reset the contents of the caches, but leave an
0051       // edm::ReusableObjectHolder alive for each device. This is needed
0052       // mostly for the unit tests, where the function-static
0053       // QueueCache lives through multiple tests (and go through
0054       // multiple shutdowns of the framework).
0055       cache_.clear();
0056       cache_.resize(devices<Platform>().size());
0057     }
0058 
0059     std::vector<edm::ReusableObjectHolder<Queue>> cache_;
0060   };
0061 
0062   // Gets the global instance of a QueueCache
0063   // This function is thread safe
0064   template <typename Queue>
0065   QueueCache<Queue>& getQueueCache() {
0066     // the public interface is thread safe
0067     CMS_THREAD_SAFE static QueueCache<Queue> cache;
0068     return cache;
0069   }
0070 
0071 }  // namespace cms::alpakatools
0072 
0073 #endif  // HeterogeneousCore_AlpakaCore_interface_QueueCache_h