-
Notifications
You must be signed in to change notification settings - Fork 421
Add codegen implementations of CMSHist classes #1191
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,10 +5,13 @@ | |
| #if ROOT_VERSION_CODE >= ROOT_VERSION(6, 36, 0) | ||
|
|
||
| #include "../interface/AsymPow.h" | ||
| #include "../interface/CMSHistErrorPropagator.h" | ||
| #include "../interface/CMSHistFunc.h" | ||
| #include "../interface/CMSHistSum.h" | ||
| #include "../interface/CombineMathFuncs.h" | ||
| #include "../interface/ProcessNormalization.h" | ||
| #include "../interface/VerticalInterpHistPdf.h" | ||
| #include "../interface/VerticalInterpPdf.h" | ||
| #include "../interface/CombineMathFuncs.h" | ||
|
|
||
| #include <RooUniformBinning.h> | ||
|
|
||
|
|
@@ -257,4 +260,68 @@ std::string RooFit::Experimental::codegenIntegralImpl(VerticalInterpPdf& arg, | |
| arg.quadraticAlgo()); | ||
| } | ||
|
|
||
| void RooFit::Experimental::codegenImpl(CMSHistFunc& arg, CodegenContext& ctx) { | ||
| arg.evaluate(); // trigger cache() creation | ||
| std::vector<double> const& edges = arg.cache().GetBinEdges(); | ||
|
|
||
| // I don't know if these values are actually constant and we can take them | ||
| // here to hardcode into the generated code... | ||
| auto const& values = arg.cache().GetValues(); | ||
|
|
||
| ctx.addResult(&arg, | ||
| ctx.buildCall("RooFit::Detail::MathFuncs::cmsHistFunc", | ||
| arg.getXVar(), | ||
| edges.size() - 1, | ||
| edges, | ||
| values | ||
| )); | ||
| } | ||
|
|
||
| void RooFit::Experimental::codegenImpl(CMSHistErrorPropagator& arg, CodegenContext& ctx) { | ||
| ctx.addResult(&arg, | ||
| ctx.buildCall("RooFit::Detail::MathFuncs::cmsHistErrorPropagator", | ||
| arg.getXVar(), | ||
| arg.coefList().size(), | ||
| arg.coefList(), | ||
| arg.funcList())); | ||
| } | ||
|
|
||
| std::string RooFit::Experimental::codegenIntegralImpl(CMSHistErrorPropagator& arg, | ||
| int code, | ||
| const char* rangeName, | ||
| CodegenContext& ctx) { | ||
| return "2.0"; // TODO: dummy for now | ||
| } | ||
|
Comment on lines
+289
to
+294
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Placeholder integral implementation returns hardcoded value. The Would you like me to open an issue to track implementing the proper integral codegen for |
||
|
|
||
| void RooFit::Experimental::codegenImpl(CMSHistSum& arg, CodegenContext& ctx) { | ||
| arg.evaluate(); | ||
| std::vector<double> const& edges = arg.cache().GetBinEdges(); | ||
| std::size_t nBins = edges.size() - 1; | ||
| RooArgList const& coefs = arg.coefList(); | ||
| std::size_t nSamples = coefs.size(); | ||
| std::vector<double> values(nBins * nSamples); | ||
| for (std::size_t iSamples = 0; iSamples < nSamples; ++iSamples) { | ||
| std::vector<double> sampleValues = arg.getFuncValList(iSamples); | ||
| for (std::size_t iBin = 0; iBin < nBins; ++iBin) | ||
| values[iBin + iSamples * nBins] = sampleValues[iBin]; | ||
| } | ||
|
|
||
| ctx.addResult(&arg, | ||
| ctx.buildCall("RooFit::Detail::MathFuncs::cmsHistSum", | ||
| arg.getXVar(), | ||
| nBins, | ||
| nSamples, | ||
| coefs, | ||
| edges, | ||
| values | ||
| )); | ||
| } | ||
|
Comment on lines
+296
to
+318
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Search for staging_ usage in the codebase
rg -n 'staging_' --type cc --type hRepository: cms-analysis/HiggsAnalysis-CombinedLimit Length of output: 224 🏁 Script executed: # Look for the CMSHistSum class definition and getFuncValList method
rg -n 'class CMSHistSum\|getFuncValList' --type cc --type h -A 3Repository: cms-analysis/HiggsAnalysis-CombinedLimit Length of output: 224 🏁 Script executed: # Search for mutex, lock, or synchronization primitives in CMSHistSum files
rg -n 'mutex|lock|synchron|thread' src/CMSHistSum.cc interface/CMSHistSum.h --type cc --type hRepository: cms-analysis/HiggsAnalysis-CombinedLimit Length of output: 224 🏁 Script executed: # Check the codegenImpl function and CodegenContext for threading info
rg -n 'codegenImpl|CodegenContext' src/CombineCodegenImpl.cxx --type cc -B 2 -A 5Repository: cms-analysis/HiggsAnalysis-CombinedLimit Length of output: 224 🌐 Web query:
💡 Result: Short answer: not safely — RooFit's code generation and some related operations (workspace I/O, codegen/JIT, shared caches) are not thread‑safe for concurrent use; protect them with a mutex or run them in separate processes. Evidence: forum threads and RooFit source show codegen/IO usage is serialized in practice and users report segfaults when calling import/codegen from multiple threads. [1][2]. Recommendation: serialize codegen/workspace import (std::mutex) or fork worker processes. [3] Sources:
Ensure codegen executes in a single-threaded context; RooFit's code generation is not thread-safe. The |
||
|
|
||
| std::string RooFit::Experimental::codegenIntegralImpl(CMSHistSum& arg, | ||
| int code, | ||
| const char* rangeName, | ||
| CodegenContext& ctx) { | ||
| return "3.0"; // TODO: dummy for now | ||
| } | ||
|
Comment on lines
+320
to
+325
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Placeholder integral implementation returns hardcoded value. Similarly, Would you like me to open an issue to track implementing the proper integral codegen for |
||
|
|
||
| #endif // ROOT_VERSION_CODE >= ROOT_VERSION(6,36,0) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing bounds check on
fnIdxparameter.The function does not validate that
fnIdxis within valid range before accessingcompcache_[fnIdx],vtype_[fnIdx],binerrors_[fnIdx], andscaledbinmods_[fnIdx]. This could lead to out-of-bounds access if called with an invalid index.Consider adding bounds validation:
std::vector<double> CMSHistSum::getFuncValList(std::size_t fnIdx) { + if (fnIdx >= static_cast<std::size_t>(n_procs_)) { + throw std::out_of_range("fnIdx exceeds number of processes"); + } staging_ = compcache_[fnIdx];📝 Committable suggestion