Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:22:34

0001 /// \file ROOT/RHistBufferedFill.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_RHistBufferedFill
0017 #define ROOT7_RHistBufferedFill
0018 
0019 #include "ROOT/RSpan.hxx"
0020 #include <array>
0021 #include <cstddef>
0022 
0023 namespace ROOT {
0024 namespace Experimental {
0025 
0026 namespace Internal {
0027 template <class DERIVED, class HIST, int SIZE>
0028 class RHistBufferedFillBase {
0029 public:
0030    using CoordArray_t = typename HIST::CoordArray_t;
0031    using Weight_t = typename HIST::Weight_t;
0032 
0033 private:
0034    size_t fCursor = 0;
0035    std::array<CoordArray_t, SIZE> fXBuf;
0036    std::array<Weight_t, SIZE> fWBuf;
0037 
0038 public:
0039    RHistBufferedFillBase() {}
0040    ~RHistBufferedFillBase() { toDerived().Flush(); }
0041 
0042    DERIVED &toDerived() { return *static_cast<DERIVED *>(this); }
0043    const DERIVED &toDerived() const { return *static_cast<const DERIVED *>(this); }
0044 
0045    std::span<const CoordArray_t> GetCoords() const
0046    {
0047       return std::span<const CoordArray_t>(fXBuf.begin(), fXBuf.begin() + fCursor);
0048    }
0049    std::span<const Weight_t> GetWeights() const
0050    {
0051       return std::span<const Weight_t>(fWBuf.begin(), fWBuf.begin() + fCursor);
0052    }
0053 
0054    void Fill(const CoordArray_t &x, Weight_t weight = 1.)
0055    {
0056       fXBuf[fCursor] = x;
0057       fWBuf[fCursor++] = weight;
0058       if (fCursor == SIZE) {
0059          Flush();
0060       }
0061    }
0062 
0063    void Flush() {
0064       toDerived().FlushImpl();
0065       fCursor = 0;
0066    }
0067 };
0068 
0069 } // namespace Internal
0070 
0071 /** \class RHistBufferedFill
0072  Buffers calls to Fill().
0073 
0074  Once the buffer is full, on destruction of when calling Flush(), it sends the
0075  buffers off as an ideally vectorizable FillN() operation. It also serves as a
0076  multi-threaded way of filling the same histogram, reducing the locking
0077  frequency.
0078 
0079  The HIST template can be either a RHist instance, a RHistImpl instance, or
0080  a RHistLockedFill instance.
0081  **/
0082 
0083 template <class HIST, int SIZE = 1024>
0084 class RHistBufferedFill: public Internal::RHistBufferedFillBase<RHistBufferedFill<HIST, SIZE>, HIST, SIZE> {
0085 public:
0086    using Hist_t = HIST;
0087    using CoordArray_t = typename HIST::CoordArray_t;
0088    using Weight_t = typename HIST::Weight_t;
0089 
0090 private:
0091    HIST &fHist;
0092 
0093    friend class Internal::RHistBufferedFillBase<RHistBufferedFill<HIST, SIZE>, HIST, SIZE>;
0094    void FlushImpl() { fHist.FillN(this->GetCoords(), this->GetWeights()); }
0095 
0096 public:
0097    RHistBufferedFill(Hist_t &hist): fHist{hist} {}
0098 
0099    void FillN(const std::span<const CoordArray_t> xN, const std::span<const Weight_t> weightN)
0100    {
0101       fHist.FillN(xN, weightN);
0102    }
0103 
0104    void FillN(const std::span<const CoordArray_t> xN) { fHist.FillN(xN); }
0105 
0106    HIST &GetHist()
0107    {
0108       this->Flush(); // synchronize!
0109       return fHist;
0110    }
0111    operator HIST &() { return GetHist(); }
0112 
0113    static constexpr int GetNDim() { return HIST::GetNDim(); }
0114 };
0115 } // namespace Experimental
0116 } // namespace ROOT
0117 
0118 #endif