Skip to content

[v640][RF] Backport RooFit bugfix and performance improvement#22030

Merged
guitargeek merged 4 commits intoroot-project:v6-40-00-patchesfrom
guitargeek:bp_1
Apr 24, 2026
Merged

[v640][RF] Backport RooFit bugfix and performance improvement#22030
guitargeek merged 4 commits intoroot-project:v6-40-00-patchesfrom
guitargeek:bp_1

Conversation

@guitargeek
Copy link
Copy Markdown
Contributor

Backport RooFit bugfix and performance improvement to the 6.40 release branch.

Use RooDataHist interfaces that take index input arguments, which is
safer because they don't rely on the cached last index in the
RooDataHist.

Addresses one bullet point in
root-project#6557:

"Correct interface of RooAbsData and derived classes to use e.g.
std::size_t for indexing events. int doesn't make sense."

As a followup, we could consider to deprecate the interfaces that use
the last cached "current" index.

(cherry picked from commit 5754e62)
For models with a single POI and no nuisance parameters,
`BayesianCalculator::GetInterval()` used `ComputeIntervalUsingRooFit()`,
which built the CDF via `RooAbsPdf::createCdf()` On a computation graph
that contains the NLL. The `createCdf()` relies on cloning the integrand
subtree and substituting the POI with a prime variable, but the POI
dependency inside the NLL compiled for the new vectorizing CPU
evaluation backend is not propagated through the clone. The CDF and
therefore the calculated interval is then wrong. Users worked around
this by calling `SetScanOfPosterior(N)` instead (see root-project#17567).

Fortunately, there was already a code path for the n-dimensional
parameter case present that doesn't use `createCdf()`, but the ROOT Math
integrator classes directly. This commit commit suggests to also do this
for the 1D POI-only case to avoid the issue with using the compiled NLL
in `createCdf()` and simplifying the code by only providing one code
path for interval caluclation with integration.

Add a gtest regression test that reproduces the issue scenario and
checks the default-path upper limit matches the explicit scan reference.

Closes root-project#17567.

(cherry picked from commit 1eb9fb6)
When a likelihood is evaluated with the new `"cpu"` backend, the
`RooFit::Evaluator` fully manages dependency tracking and re-evaluation
of the computation graph. In this case, RooFit’s built-in dirty flag
propagation in RooAbsArg becomes redundant and introduces significant
overhead for large models.

This patch disables regular dirty state propagation for all
non-fundamental nodes in the Evaluator's computation graph by setting
their OperMode to `RooAbsArg::ADirty`. Fundamental nodes (e.g.
RooRealVar, RooCategory) are excluded because they are often shared with
other computation graphs outside the Evaluator (usually the original pdf
in the RooWorkspace).

To set the OperMode of *all* RooAbsArgs to `ADirty` during minimization,
while avoiding side effects outside the minimization scope, the dirty
flag propagation for the fundamental nodes is only disabled temporarily
in the RooMinimizer.

This commit drastically speeds up fits with AD in particular (up to 2 x
for large models), because with fast gradients, the dirty flag
propagation that determines which part of the compute graph needs to be
recomputed becomes the bottleneck. It was also redundant with a faster
"dirty state" bookkeeping mechanism in the `RooFit::Evaluator` class
itself.

At this point, there is no performance regression anymore when disabling
recursive dirty flag propagation for all evaluated nodes, so the old
comment in the code about test 14 in stressRooFit being slow doesn't
apply anymore.

(cherry picked from commit fa97774)
Several places needed to record a set of operation-mode changes and
restore them later as a group, so it's better to have the
ChangeOperModeRAII act on groups of RooAbsArg to not have to create one
RAII object per arg.

(cherry picked from commit d42a27c)
@guitargeek guitargeek requested a review from bellenot as a code owner April 23, 2026 14:34
@github-actions
Copy link
Copy Markdown

Test Results

    22 files      22 suites   3d 12h 4m 8s ⏱️
 3 846 tests  3 844 ✅  1 💤 1 ❌
75 944 runs  75 925 ✅ 18 💤 1 ❌

For more details on these failures, see this check.

Results for commit 8837e4e.

@guitargeek guitargeek added this to the 6.40.00 milestone Apr 24, 2026
@guitargeek guitargeek merged commit 98a75ad into root-project:v6-40-00-patches Apr 24, 2026
27 of 30 checks passed
@guitargeek guitargeek deleted the bp_1 branch April 24, 2026 11:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant