Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:44

0001 /// \file ROOT/RHistConcurrentFill.hxx
0002 /// \ingroup HistV7
0003 /// \author Axel Naumann <axel@cern.ch>
0004 /// \date 2015-07-03
0005 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
0006 /// is welcome!
0007 
0008 /*************************************************************************
0009  * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers.               *
0010  * All rights reserved.                                                  *
0011  *                                                                       *
0012  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0013  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0014  *************************************************************************/
0015 
0016 #ifndef ROOT7_RHistConcurrentFill
0017 #define ROOT7_RHistConcurrentFill
0018 
0019 #include "ROOT/RSpan.hxx"
0020 #include "ROOT/RHistBufferedFill.hxx"
0021 
0022 #include <mutex>
0023 
0024 namespace ROOT {
0025 namespace Experimental {
0026 
0027 template <class HIST, int SIZE>
0028 class RHistConcurrentFillManager;
0029 
0030 /**
0031  \class RHistConcurrentFiller
0032  Buffers a thread's Fill calls and submits them to the
0033  RHistConcurrentFillManager. Enables multi-threaded filling.
0034  **/
0035 
0036 template <class HIST, int SIZE>
0037 class RHistConcurrentFiller: public Internal::RHistBufferedFillBase<RHistConcurrentFiller<HIST, SIZE>, HIST, SIZE> {
0038    RHistConcurrentFillManager<HIST, SIZE> &fManager;
0039 
0040 public:
0041    using CoordArray_t = typename HIST::CoordArray_t;
0042    using Weight_t = typename HIST::Weight_t;
0043 
0044    RHistConcurrentFiller(RHistConcurrentFillManager<HIST, SIZE> &manager): fManager(manager) {}
0045 
0046    /// Thread-specific HIST::Fill().
0047    using Internal::RHistBufferedFillBase<RHistConcurrentFiller<HIST, SIZE>, HIST, SIZE>::Fill;
0048 
0049    /// Thread-specific HIST::FillN().
0050    void FillN(const std::span<const CoordArray_t> xN, const std::span<const Weight_t> weightN)
0051    {
0052       fManager.FillN(xN, weightN);
0053    }
0054 
0055    /// Thread-specific HIST::FillN().
0056    void FillN(const std::span<const CoordArray_t> xN) { fManager.FillN(xN); }
0057 
0058    static constexpr int GetNDim() { return HIST::GetNDim(); }
0059 
0060 private:
0061    friend class Internal::RHistBufferedFillBase<RHistConcurrentFiller<HIST, SIZE>, HIST, SIZE>;
0062    void FlushImpl() { fManager.FillN(this->GetCoords(), this->GetWeights()); }
0063 };
0064 
0065 /**
0066  \class RHistConcurrentFillManager
0067  Manages the synchronization of calls to FillN().
0068 
0069  The HIST template can be a RHist instance. This class hands out
0070  RHistConcurrentFiller objects that can concurrently fill the histogram. They
0071  buffer calls to Fill() until the buffer is full, and then swap the buffer
0072  with that of the RHistConcurrentFillManager. The manager than fills the
0073  histogram.
0074  **/
0075 
0076 template <class HIST, int SIZE = 1024>
0077 class RHistConcurrentFillManager {
0078    friend class RHistConcurrentFiller<HIST, SIZE>;
0079 
0080 public:
0081    using Hist_t = HIST;
0082    using CoordArray_t = typename HIST::CoordArray_t;
0083    using Weight_t = typename HIST::Weight_t;
0084 
0085 private:
0086    HIST &fHist;
0087    std::mutex fFillMutex; // should become a spin lock
0088 
0089 public:
0090    RHistConcurrentFillManager(HIST &hist): fHist(hist) {}
0091 
0092    RHistConcurrentFiller<HIST, SIZE> MakeFiller() { return RHistConcurrentFiller<HIST, SIZE>{*this}; }
0093 
0094    /// Thread-specific HIST::FillN().
0095    void FillN(const std::span<const CoordArray_t> xN, const std::span<const Weight_t> weightN)
0096    {
0097       std::lock_guard<std::mutex> lockGuard(fFillMutex);
0098       fHist.FillN(xN, weightN);
0099    }
0100 
0101    /// Thread-specific HIST::FillN().
0102    void FillN(const std::span<const CoordArray_t> xN)
0103    {
0104       std::lock_guard<std::mutex> lockGuard(fFillMutex);
0105       fHist.FillN(xN);
0106    }
0107 };
0108 
0109 } // namespace Experimental
0110 } // namespace ROOT
0111 
0112 #endif