@@ -409,26 +409,6 @@ double RooProdPdf::calculate(const RooProdPdf::CacheElem& cache, bool /*verbose*
409409 }
410410}
411411
412- // //////////////////////////////////////////////////////////////////////////////
413- // / Evaluate product of PDFs in batch mode.
414- void RooProdPdf::doEvalImpl (RooAbsArg const *caller, const RooProdPdf::CacheElem &cache, RooFit::EvalContext &ctx) const
415- {
416- if (cache._isRearranged ) {
417- auto numerator = ctx.at (cache._rearrangedNum .get ());
418- auto denominator = ctx.at (cache._rearrangedDen .get ());
419- RooBatchCompute::compute (ctx.config (caller), RooBatchCompute::Ratio, ctx.output (), {numerator, denominator});
420- } else {
421- std::vector<std::span<const double >> factors;
422- factors.reserve (cache._partList .size ());
423- for (const RooAbsArg *i : cache._partList ) {
424- auto span = ctx.at (i);
425- factors.push_back (span);
426- }
427- std::array<double , 1 > special{static_cast <double >(factors.size ())};
428- RooBatchCompute::compute (ctx.config (caller), RooBatchCompute::ProdPdf, ctx.output (), factors, special);
429- }
430- }
431-
432412namespace {
433413
434414template <class T >
@@ -2185,44 +2165,85 @@ RooProdPdf::compileForNormSet(RooArgSet const &normSet, RooFit::Detail::CompileC
21852165 return fixedProdPdf;
21862166}
21872167
2188- namespace RooFit {
2189- namespace Detail {
2168+ namespace RooFit ::Detail {
21902169
21912170RooFixedProdPdf::RooFixedProdPdf (std::unique_ptr<RooProdPdf> &&prodPdf, RooArgSet const &normSet)
21922171 : RooAbsPdf(prodPdf->GetName (), prodPdf->GetTitle()),
21932172 _normSet{normSet},
21942173 _servers (" !servers" , " List of servers" , this ),
21952174 _prodPdf{std::move (prodPdf)}
21962175{
2197- initialize ();
2176+ auto cache = _prodPdf->createCacheElem (&_normSet, nullptr );
2177+ _isRearranged = cache->_isRearranged ;
2178+
2179+ // The actual servers for a given normalization set depend on whether the
2180+ // cache is rearranged or not. See RooProdPdf::calculate to see
2181+ // which args in the cache are used directly.
2182+ if (_isRearranged) {
2183+ _servers.add (*cache->_rearrangedNum );
2184+ _servers.add (*cache->_rearrangedDen );
2185+ addOwnedComponents (std::move (cache->_rearrangedNum ));
2186+ addOwnedComponents (std::move (cache->_rearrangedDen ));
2187+ return ;
2188+ }
2189+ // We don't want to carry the full cache object around, so we let it go out
2190+ // of scope and transfer the ownership of the args that we actually need.
2191+ cache->_ownedList .releaseOwnership ();
2192+ std::vector<std::unique_ptr<RooAbsArg>> owned;
2193+ for (RooAbsArg *arg : cache->_ownedList ) {
2194+ owned.emplace_back (arg);
2195+ }
2196+ for (RooAbsArg *arg : cache->_partList ) {
2197+ _servers.add (*arg);
2198+ auto found = std::find_if (owned.begin (), owned.end (), [&](auto const &ptr) { return arg == ptr.get (); });
2199+ if (found != owned.end ()) {
2200+ addOwnedComponents (std::move (owned[std::distance (owned.begin (), found)]));
2201+ }
2202+ }
21982203}
21992204
22002205RooFixedProdPdf::RooFixedProdPdf (const RooFixedProdPdf &other, const char *name)
22012206 : RooAbsPdf(other, name),
22022207 _normSet{other._normSet },
2203- _servers (" !servers" , " List of servers" , this ),
2204- _prodPdf{static_cast <RooProdPdf *>(other._prodPdf ->Clone ())}
2208+ // _servers("!servers", "List of servers", this),
2209+ _servers (" !servers" , this , other._servers),
2210+ _prodPdf{static_cast <RooProdPdf *>(other._prodPdf ->Clone ())},
2211+ _isRearranged{other._isRearranged }
2212+ {
2213+ }
2214+
2215+ // //////////////////////////////////////////////////////////////////////////////
2216+ // / Evaluate product of PDFs in batch mode.
2217+
2218+ void RooFixedProdPdf::doEval (RooFit::EvalContext &ctx) const
22052219{
2206- initialize ();
2220+ if (_isRearranged) {
2221+ auto numerator = ctx.at (rearrangedNum ());
2222+ auto denominator = ctx.at (rearrangedDen ());
2223+ RooBatchCompute::compute (ctx.config (this ), RooBatchCompute::Ratio, ctx.output (), {numerator, denominator});
2224+ return ;
2225+ }
2226+ std::vector<std::span<const double >> factors;
2227+ factors.reserve (partList ()->size ());
2228+ for (const RooAbsArg *arg : *partList ()) {
2229+ auto span = ctx.at (arg);
2230+ factors.push_back (span);
2231+ }
2232+ std::array<double , 1 > special{static_cast <double >(factors.size ())};
2233+ RooBatchCompute::compute (ctx.config (this ), RooBatchCompute::ProdPdf, ctx.output (), factors, special);
22072234}
22082235
2209- void RooFixedProdPdf::initialize ()
2236+ double RooFixedProdPdf::evaluate () const
22102237{
2211- _cache = _prodPdf->createCacheElem (&_normSet, nullptr );
2212- auto &cache = *_cache;
2238+ if (_isRearranged) {
2239+ return rearrangedNum ()->getVal () / rearrangedDen ()->getVal ();
2240+ }
2241+ double value = 1.0 ;
22132242
2214- // The actual servers for a given normalization set depend on whether the
2215- // cache is rearranged or not. See RooProdPdf::calculateBatch to see
2216- // which args in the cache are used directly.
2217- if (cache._isRearranged ) {
2218- _servers.add (*cache._rearrangedNum );
2219- _servers.add (*cache._rearrangedDen );
2220- } else {
2221- for (std::size_t i = 0 ; i < cache._partList .size (); ++i) {
2222- _servers.add (cache._partList [i]);
2223- }
2243+ for (auto *arg : static_range_cast<RooAbsReal *>(*partList ())) {
2244+ value *= arg->getVal ();
22242245 }
2246+ return value;
22252247}
22262248
2227- } // namespace Detail
2228- } // namespace RooFit
2249+ } // namespace RooFit::Detail
0 commit comments