-
Notifications
You must be signed in to change notification settings - Fork 1.4k
[hist] Implement initial RHistConcurrentFiller
#20555
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| /// \file | ||
| /// \warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes. | ||
| /// Feedback is welcome! | ||
|
|
||
| #ifndef ROOT_RHistConcurrentFiller | ||
| #define ROOT_RHistConcurrentFiller | ||
|
|
||
| #include "RHist.hxx" | ||
| #include "RHistEngine.hxx" | ||
| #include "RHistFillContext.hxx" | ||
| #include "RWeight.hxx" | ||
|
|
||
| #include <exception> | ||
| #include <memory> | ||
| #include <mutex> | ||
| #include <stdexcept> | ||
| #include <vector> | ||
|
|
||
| namespace ROOT { | ||
| namespace Experimental { | ||
|
|
||
| /** | ||
| A histogram filler to concurrently fill an RHist. | ||
|
|
||
| \code | ||
| auto hist = std::make_shared<ROOT::Experimental::RHist<int>>(10, std::make_pair(5, 15)); | ||
| { | ||
| ROOT::Experimental::RHistConcurrentFiller filler(hist); | ||
| auto context = filler.CreateFillContext(); | ||
| context.Fill(8.5); | ||
| } | ||
| // hist->GetBinContent(ROOT::Experimental::RBinIndex(3)) will return 1 | ||
| \endcode | ||
|
|
||
| \warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes. | ||
| Feedback is welcome! | ||
| */ | ||
| template <typename BinContentType> | ||
| class RHistConcurrentFiller final { | ||
| /// A pointer to the filled histogram | ||
| std::shared_ptr<RHist<BinContentType>> fHist; | ||
|
|
||
| /// Mutex to protect access to the list of fill contexts (not for filling itself!) | ||
| std::mutex fMutex; | ||
| /// The list of fill contexts, for checks during destruction | ||
| std::vector<std::weak_ptr<RHistFillContext<BinContentType>>> fFillContexts; | ||
|
|
||
| public: | ||
| /// Create a filler object. | ||
| /// | ||
| /// \param[in] hist a pointer to the histogram | ||
| explicit RHistConcurrentFiller(std::shared_ptr<RHist<BinContentType>> hist) : fHist(hist) | ||
| { | ||
| if (!hist) { | ||
| throw std::invalid_argument("hist must not be nullptr"); | ||
| } | ||
| } | ||
|
|
||
| RHistConcurrentFiller(const RHistConcurrentFiller<BinContentType> &) = delete; | ||
| RHistConcurrentFiller(RHistConcurrentFiller<BinContentType> &&) = delete; | ||
| RHistConcurrentFiller<BinContentType> &operator=(const RHistConcurrentFiller<BinContentType> &) = delete; | ||
| RHistConcurrentFiller<BinContentType> &operator=(RHistConcurrentFiller<BinContentType> &&) = delete; | ||
|
|
||
| ~RHistConcurrentFiller() | ||
| { | ||
| for (const auto &context : fFillContexts) { | ||
| if (!context.expired()) { | ||
| // According to C++ Core Guideline C.36 "A destructor must not fail" and (C.37) "If a destructor tries to | ||
| // exit with an exception, it’s a bad design error and the program had better terminate". | ||
| std::terminate(); // GCOVR_EXCL_LINE | ||
| } | ||
| } | ||
| } | ||
|
|
||
| const std::shared_ptr<RHist<BinContentType>> &GetHist() const { return fHist; } | ||
|
|
||
| /// Create a new context for concurrent filling. | ||
| std::shared_ptr<RHistFillContext<BinContentType>> CreateFillContext() | ||
| { | ||
| // Cannot use std::make_shared because the constructor of RHistFillContext is private. Also it would mean that the | ||
| // (direct) memory of all contexts stays around until the vector of weak_ptr's is cleared. | ||
| std::shared_ptr<RHistFillContext<BinContentType>> context(new RHistFillContext<BinContentType>(*fHist)); | ||
|
|
||
| { | ||
| std::lock_guard g(fMutex); | ||
| fFillContexts.push_back(context); | ||
| } | ||
|
|
||
| return context; | ||
| } | ||
| }; | ||
|
|
||
| } // namespace Experimental | ||
| } // namespace ROOT | ||
|
|
||
| #endif | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| /// \file | ||
| /// \warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes. | ||
| /// Feedback is welcome! | ||
|
|
||
| #ifndef ROOT_RHistFillContext | ||
| #define ROOT_RHistFillContext | ||
|
|
||
| #include "RHist.hxx" | ||
| #include "RHistEngine.hxx" | ||
| #include "RHistStats.hxx" | ||
|
|
||
| namespace ROOT { | ||
| namespace Experimental { | ||
|
|
||
| // forward declaration for friend declaration | ||
| template <typename BinContentType> | ||
| class RHistConcurrentFiller; | ||
|
|
||
| /** | ||
| A context to concurrently fill an RHist. | ||
|
|
||
| \sa RHistConcurrentFiller | ||
|
|
||
| \warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes. | ||
| Feedback is welcome! | ||
| */ | ||
| template <typename BinContentType> | ||
| class RHistFillContext final { | ||
| friend class RHistConcurrentFiller<BinContentType>; | ||
|
|
||
| private: | ||
| /// A pointer to the filled histogram | ||
| RHist<BinContentType> *fHist = nullptr; | ||
|
|
||
| /// Local histogram statistics | ||
| RHistStats fStats; | ||
|
|
||
| /// \sa RHistConcurrentFiller::CreateFillContent() | ||
| explicit RHistFillContext(RHist<BinContentType> &hist) : fHist(&hist), fStats(hist.GetNDimensions()) {} | ||
| RHistFillContext(const RHistFillContext<BinContentType> &) = delete; | ||
| RHistFillContext(RHistFillContext<BinContentType> &&) = default; | ||
| RHistFillContext<BinContentType> &operator=(const RHistFillContext<BinContentType> &) = delete; | ||
| RHistFillContext<BinContentType> &operator=(RHistFillContext<BinContentType> &&) = default; | ||
|
|
||
| public: | ||
| ~RHistFillContext() { Flush(); } | ||
|
|
||
| /// Fill an entry into the histogram. | ||
| /// | ||
| /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently | ||
| /// discarded. | ||
| /// | ||
| /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be | ||
| /// converted for the axis type at run-time. | ||
| /// | ||
| /// \param[in] args the arguments for each axis | ||
| /// \sa RHist::Fill(const std::tuple<A...> &args) | ||
| template <typename... A> | ||
| void Fill(const std::tuple<A...> &args) | ||
| { | ||
| fHist->fEngine.FillAtomic(args); | ||
| fStats.Fill(args); | ||
| } | ||
|
|
||
| /// Fill an entry into the histogram with a weight. | ||
| /// | ||
| /// This overload is not available for integral bin content types (see \ref RHistEngine::SupportsWeightedFilling). | ||
| /// | ||
| /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently | ||
| /// discarded. | ||
| /// | ||
| /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be | ||
| /// converted for the axis type at run-time. | ||
| /// | ||
| /// \param[in] args the arguments for each axis | ||
| /// \param[in] weight the weight for this entry | ||
| /// \sa RHist::Fill(const std::tuple<A...> &args, RWeight weight) | ||
| template <typename... A> | ||
| void Fill(const std::tuple<A...> &args, RWeight weight) | ||
| { | ||
| fHist->fEngine.FillAtomic(args, weight); | ||
| fStats.Fill(args, weight); | ||
| } | ||
|
|
||
| /// Fill an entry into the histogram. | ||
| /// | ||
| /// For weighted filling, pass an RWeight as the last argument. This is not available for integral bin content types | ||
| /// (see \ref RHistEngine::SupportsWeightedFilling). | ||
| /// | ||
| /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently | ||
| /// discarded. | ||
| /// | ||
| /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be | ||
| /// converted for the axis type at run-time. | ||
| /// | ||
| /// \param[in] args the arguments for each axis | ||
| /// \sa RHist::Fill(const A &...args) | ||
| template <typename... A> | ||
| void Fill(const A &...args) | ||
| { | ||
| fHist->fEngine.FillAtomic(args...); | ||
| fStats.Fill(args...); | ||
| } | ||
|
|
||
| /// Flush locally accumulated entries to the histogram. | ||
| void Flush() | ||
| { | ||
| fHist->fStats.AddAtomic(fStats); | ||
| fStats.Clear(); | ||
| } | ||
| }; | ||
|
|
||
| } // namespace Experimental | ||
| } // namespace ROOT | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.