Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RHistBufferedFill.hxx
Go to the documentation of this file.
1 /// \file ROOT/RHistBufferedFill.h
2 /// \ingroup Hist ROOT7
3 /// \author Axel Naumann <axel@cern.ch>
4 /// \date 2015-07-03
5 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6 /// is welcome!
7 
8 /*************************************************************************
9  * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers. *
10  * All rights reserved. *
11  * *
12  * For the licensing terms see $ROOTSYS/LICENSE. *
13  * For the list of contributors see $ROOTSYS/README/CREDITS. *
14  *************************************************************************/
15 
16 #ifndef ROOT7_RHistBufferedFill
17 #define ROOT7_RHistBufferedFill
18 
19 #include "ROOT/RSpan.hxx"
20 
21 namespace ROOT {
22 namespace Experimental {
23 
24 namespace Internal {
25 template <class DERIVED, class HIST, int SIZE>
26 class RHistBufferedFillBase {
27 public:
28  using CoordArray_t = typename HIST::CoordArray_t;
29  using Weight_t = typename HIST::Weight_t;
30 
31 private:
32  size_t fCursor = 0;
33  std::array<CoordArray_t, SIZE> fXBuf;
34  std::array<Weight_t, SIZE> fWBuf;
35 
36 public:
37  RHistBufferedFillBase() {}
38  ~RHistBufferedFillBase() { toDerived().Flush(); }
39 
40  DERIVED &toDerived() { return *static_cast<DERIVED *>(this); }
41  const DERIVED &toDerived() const { return *static_cast<const DERIVED *>(this); }
42 
43  std::span<const CoordArray_t> GetCoords() const
44  {
45  return std::span<const CoordArray_t>(fXBuf.begin(), fXBuf.begin() + fCursor);
46  }
47  std::span<const Weight_t> GetWeights() const
48  {
49  return std::span<const Weight_t>(fWBuf.begin(), fWBuf.begin() + fCursor);
50  }
51 
52  void Fill(const CoordArray_t &x, Weight_t weight = 1.)
53  {
54  fXBuf[fCursor] = x;
55  fWBuf[fCursor++] = weight;
56  if (fCursor == SIZE) {
57  Flush();
58  }
59  }
60 
61  void Flush() {
62  toDerived().FlushImpl();
63  fCursor = 0;
64  }
65 };
66 
67 } // namespace Internal
68 
69 /** \class RHistBufferedFill
70  Buffers calls to Fill().
71 
72  Once the buffer is full, on destruction of when calling Flush(), it sends the
73  buffers off as an ideally vectorizable FillN() operation. It also serves as a
74  multi-threaded way of filling the same histogram, reducing the locking
75  frequency.
76 
77  The HIST template can be either a RHist instance, a RHistImpl instance, or
78  a RHistLockedFill instance.
79  **/
80 
81 template <class HIST, int SIZE = 1024>
82 class RHistBufferedFill: public Internal::RHistBufferedFillBase<RHistBufferedFill<HIST, SIZE>, HIST, SIZE> {
83 public:
84  using Hist_t = HIST;
85  using CoordArray_t = typename HIST::CoordArray_t;
86  using Weight_t = typename HIST::Weight_t;
87 
88 private:
89  HIST &fHist;
90  size_t fCursor = 0;
91  std::array<CoordArray_t, SIZE> fXBuf;
92  std::array<Weight_t, SIZE> fWBuf;
93 
94  friend class Internal::RHistBufferedFillBase<RHistBufferedFill<HIST, SIZE>, HIST, SIZE>;
95  void FlushImpl() { fHist.FillN(this->GetCoords(), this->GetWeights()); }
96 
97 public:
98  RHistBufferedFill(Hist_t &hist): fHist{hist} {}
99 
100  void FillN(const std::span<const CoordArray_t> xN, const std::span<const Weight_t> weightN)
101  {
102  fHist.FillN(xN, weightN);
103  }
104 
105  void FillN(const std::span<const CoordArray_t> xN) { fHist.FillN(xN); }
106 
107  HIST &GetHist()
108  {
109  this->Flush(); // synchronize!
110  return fHist;
111  }
112  operator HIST &() { return GetHist(); }
113 
114  static constexpr int GetNDim() { return HIST::GetNDim(); }
115 };
116 } // namespace Experimental
117 } // namespace ROOT
118 
119 #endif