getPropagatedError() method taking too long to run

Dear experts,

We are working on a TopEFT analysis. Currently we use RooFit library to extract information out of a RooWorkspace for the purpose of plotting the postfit results. We have observed a severe bottleneck in our framework when calling RooAbsReal::getPropagatedError().

Our workspace is constructed in a way that the signal process consists multiple sub-processes. We initialize multiple compound objects, with each object being a product of the normalization(RooRealVar) and the corresponding PDF(RooPDF) of a sub-process. There are O(50k) such objects being created in total. Interestingly, we notice that the call time of getPropagatedError() method on those compound objects increases for all such objects the more we introduce, even though there should be no explicit dependence between those sub-processes.

On a side note, our RooWorkspace is rather quite large, with O(100k) objects in it. This has been problematic as we’ve frequently ran into segfaults when trying to access certain parts of the workspace, however, we aren’t sure if this coming from just the size of the workspace or if its just related to the way the workspace was constructed.

We would like to know whether or not we should expect such a long runtime as well as if there are more efficient ways of extracting information out of a RooWorkspace, e.g. is constructing compound Roo objects really inefficient if certain considerations aren’t made? Are there options to help speed up the computation?

Best,
Furong

Hi,
Which ROOT version are you using ? We are improving the performances of Roofit, and in case of large number of objects we have been improved the internal RooFit collection classes.
We should probably look also in detail at getPropagatedErrors(), the long time could be due to the cloning of the model happening internally in the function. @jonas could have more to say on this.
Best regards,

Lorenzo

Hi, thanks for pointing this out!

Apparently, getPropagatedError() is cloning the full model, which should absolutely not be necessary.

Even with all the optimizations we have applied in the last months, model cloning is still very expensive for large models with many channels and should be avoided.

I have opened a PR to avoid that model cloning. Hopefully we can get it into the next ROOT release!

It would be great if you could follow the status of that PR and try out the ROOT master when it’s merged, and possibly give feedback.

About your performance problems in general: maybe there are also more places where you can avoid deep copying the models.

I hope this is helpful!
Jonas