@@ -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