Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-08-15 01:07:42

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