Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions README/ReleaseNotes/v642/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ The following people have contributed to this new version:
Note that `all=ON` enables several of these options, so building with `-Dall=ON` now requires all of their dependencies to be installed, or the unwanted ones to be disabled explicitly.
Build options that are enabled by default, such as `pyroot`, `opengl`, `xml`, `sqlite`, `davix`, `curl`, `tmva-cpu` or `tpython` are not affected: they are still disabled automatically when their dependencies are missing.
* The option `fail-on-missing=OFF` will no longer be honored for CMake ROOT build options that have easy-to-install dependencies (e.g. via homebrew or apt-get), such as those required by options `cfitsio`, `civetweb`, `fftw3`, `imt`, `mathmore`, `nlohmann_json`, `tmva-cpu`, `unuran`, `vdt` or `xrootd`. Before, associated `builtin_option` was automatically turned ON (or the opt-in feature turned to OFF), now, user has to install system package or manually set `builtin_option` to `ON` or opt-in feature to `OFF`.
* The legacy evaluation backend of RooFit and the related `RooFit::BatchMode()` command argument are deprecated and will be removed in ROOT 6.44. See the RooFit section below for details.
* The method `RooRealVar::removeRange()` and the corresponding method in `RooErrorVar` that were deprecated in ROOT 6.40 are now removed.
* The overloads of `RooAbsReal::createChi2()` and `RooAbsReal::chi2FitTo()` that take unbinned **RooDataSet** data objects were deprecated in ROOT 6.40 and are now removed.
* The **RooStats::HybridPlot** class and the related **HybridResult::GetPlot** method were deprecated in ROOT 6.40 and are now removed.
Expand Down Expand Up @@ -144,6 +145,26 @@ the cut instead of being selected based on `sqrt(abs(x))`.

* The `RooMinimizer::Strategy` enum has been removed. It named the Minuit strategies that are usually referred to just by integers, but caused confusion because it didn't include the unnamed "Strategy 3". Since people usually set the strategy with integer values anyway, it was decided that the simplest solution to avoid the confusion was simply to remove the `RooMinimizer::Strategy` enum

### Deprecation of the legacy evaluation backend

The `legacy` evaluation backend for likelihood and chi-square fits is deprecated and will be removed in ROOT 6.44.
It was superseded by the vectorized `cpu` backend, which is the default since ROOT 6.32.
After the removal of the constant term optimization (see below), the legacy backend also has no performance-relevant feature left that would justify its continued maintenance.

Selecting the legacy backend with `RooFit::EvalBackend("legacy")` now prints a deprecation warning whenever a likelihood or chi-square object is created with it, and the `RooFit::EvalBackend::Legacy()` factory function is marked as deprecated, resulting in compiler warnings.

The **RooFit::BatchMode()** command argument, which was superseded by `RooFit::EvalBackend()` in ROOT 6.28, is deprecated at the same time and will also be removed in ROOT 6.44.
Note that the C++ declarations of `RooFit::BatchMode()` had been unintentionally absent since ROOT 6.30; they are restored in this release, marked as deprecated, to give downstream code a proper migration window.

The removal in ROOT 6.44 will also include:

* the implementation classes of the legacy test statistics: **RooNLLVar**, **RooChi2Var**, **RooAbsOptTestStatistic** and **RooAbsTestStatistic** (their headers are not part of the public interface anymore since ROOT 6.32, but they are still installed),
* the old multiprocessing mechanism of the legacy backend, consisting of the **RooRealMPFE** class and the underlying **BidirMMapPipe**,
* the `nll::name[pdf,data]` and `chi2::name[pdf,data]` expressions in the `RooWorkspace::factory()` language, which instantiate the removed classes directly.

Users are strongly encouraged to switch to the default `cpu` evaluation backend, i.e., to simply not pass any `EvalBackend()` or `BatchMode()` command argument.
If the default backend does not work for a given use case, **please report it by opening an issue on the ROOT GitHub repository**.

### Removal of the constant term optimization for legacy test statistic classes

The **RooFit::Optimize()** option (constant term optimization) was deprecated in ROOT 6.40, and its functionality is now removed.
Expand Down
2 changes: 1 addition & 1 deletion roofit/histfactory/test/testHistFactory.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ TEST_P(HFFixtureEval, Evaluation)
const double systEps = 1e-6;

const MakeModelMode makeModelMode = std::get<0>(GetParam());
const bool useBatchMode = std::get<2>(GetParam()) != RooFit::EvalBackend::Legacy();
const bool useBatchMode = std::get<2>(GetParam()) != RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy);

RooHelpers::HijackMessageStream evalMessages(RooFit::INFO, RooFit::FastEvaluations);

Expand Down
2 changes: 1 addition & 1 deletion roofit/roofit/test/vectorisedPDFs/VectorisedPDFTests.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ std::unique_ptr<RooFitResult> PDFTest::runScalarFit(RooAbsPdf *pdf)
}

MyTimer singleTimer("Fitting scalar mode " + _name);
std::unique_ptr<RooFitResult> result{pdf->fitTo(*_dataFit, RooFit::EvalBackend::Legacy(), RooFit::SumW2Error(false),
std::unique_ptr<RooFitResult> result{pdf->fitTo(*_dataFit, RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy), RooFit::SumW2Error(false),
RooFit::PrintLevel(_printLevel), RooFit::Save(),
_multiProcess > 0 ? RooFit::NumCPU(_multiProcess) : RooCmdArg())};
std::cout << singleTimer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace TestStatistics {
class RooUnbinnedL : public RooAbsL {
public:
RooUnbinnedL(RooAbsPdf *pdf, RooAbsData *data, RooAbsL::Extended extended = RooAbsL::Extended::Auto,
RooFit::EvalBackend evalBackend = RooFit::EvalBackend::Legacy());
RooFit::EvalBackend evalBackend = RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy));
RooUnbinnedL(const RooUnbinnedL &other);
~RooUnbinnedL() override;
bool setApplyWeightSquared(bool flag);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class NLLFactory {
RooArgSet _externalConstraints;
RooArgSet _globalObservables;
std::string _globalObservablesTag;
RooFit::EvalBackend _evalBackend = RooFit::EvalBackend::Legacy();
RooFit::EvalBackend _evalBackend = RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy);
};

/// Delegating function to build a likelihood without additional arguments.
Expand Down
20 changes: 13 additions & 7 deletions roofit/roofitcore/inc/RooGlobalFunc.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,15 @@ RooCmdArg Parallelize(int nWorkers) ;
RooCmdArg ModularL(bool flag=false) ;
RooCmdArg TimingAnalysis(bool timingAnalysis) ;

//RooCmdArg BatchMode(std::string const& batchMode="cpu");
//// The const char * overload is necessary, otherwise the compiler will cast a
//// C-Style string to a bool and choose the BatchMode(bool) overload if one
//// calls for example BatchMode("off").
//inline RooCmdArg BatchMode(const char * batchMode) { return BatchMode(std::string(batchMode)); }
//inline RooCmdArg BatchMode(bool batchModeOn) { return BatchMode(batchModeOn ? "cpu" : "off"); }
RooCmdArg BatchMode(std::string const &batchMode = "cpu")
R__DEPRECATED(6, 44, "Use EvalBackend() instead of BatchMode().");
// The const char * overload is necessary, otherwise the compiler will cast a
// C-Style string to a bool and choose the BatchMode(bool) overload if one
// calls for example BatchMode("off").
RooCmdArg BatchMode(const char *batchMode)
R__DEPRECATED(6, 44, "Use EvalBackend() instead of BatchMode().");
RooCmdArg BatchMode(bool batchModeOn)
R__DEPRECATED(6, 44, "Use EvalBackend() instead of BatchMode().");

RooCmdArg IntegrateBins(double precision);

Expand All @@ -263,7 +266,10 @@ class EvalBackend : public RooCmdArg {

EvalBackend(std::string const &name);

static EvalBackend Legacy();
static EvalBackend Legacy()
R__DEPRECATED(6, 44, "The legacy evaluation backend will be removed in ROOT 6.44. "
"Use the default \"cpu\" evaluation backend, i.e. simply don't pass any EvalBackend() "
"command argument.");
static EvalBackend Cpu();
static EvalBackend Cuda();
static EvalBackend Codegen();
Expand Down
17 changes: 17 additions & 0 deletions roofit/roofitcore/src/FitHelpers.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@ namespace {

constexpr int extendedFitDefault = 2;

#ifdef ROOFIT_LEGACY_EVAL_BACKEND
/// Print a deprecation warning when the legacy evaluation backend is selected for a fit.
void printLegacyEvalBackendWarning(RooAbsReal const &topLevelArg)
{
oocoutW(&topLevelArg, InputArguments)
<< "The legacy evaluation backend is deprecated and will be removed in ROOT 6.44.\n"
"Please use the default \"cpu\" evaluation backend instead, i.e., don't pass RooFit::EvalBackend(\"legacy\")\n"
"or RooFit::BatchMode(\"off\") anymore. If the default backend does not work for your use case, please\n"
"report it by opening an issue on the ROOT GitHub repository."
<< std::endl;
}
#endif

////////////////////////////////////////////////////////////////////////////////
/// Use the asymptotically correct approach to estimate errors in the presence of weights.
/// This is slower but more accurate than `SumW2Error`. See also https://arxiv.org/abs/1911.01303).
Expand Down Expand Up @@ -924,6 +937,8 @@ std::unique_ptr<RooAbsReal> createNLL(RooAbsPdf &pdf, RooAbsData &data, const Ro
std::unique_ptr<RooAbsReal> nll;

#ifdef ROOFIT_LEGACY_EVAL_BACKEND
printLegacyEvalBackendWarning(pdf);

bool verbose = pc.getInt("verbose");

int numcpu = pc.getInt("numcpu");
Expand Down Expand Up @@ -1140,6 +1155,8 @@ std::unique_ptr<RooAbsReal> createChi2(RooAbsReal &real, RooDataHist &data, cons
}

#ifdef ROOFIT_LEGACY_EVAL_BACKEND
printLegacyEvalBackendWarning(real);

RooAbsTestStatistic::Configuration cfg;

RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors);
Expand Down
4 changes: 3 additions & 1 deletion roofit/roofitcore/src/RooAbsPdf.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,9 @@ double RooAbsPdf::extendedTerm(RooAbsData const& data, bool weightSquared, bool
* This backend re-uses code from the **cpu** backend, but compiled in CUDA kernels.
* Hence, the results are expected to be identical, modulo some numerical differences that can arise from the different order in which the GPU is summing the log probabilities.
* This backend can drastically speed up the fit if all RooAbsArg object in the model support it.
* <tr><td> **legacy** <td> The original likelihood evaluation method.
* <tr><td> **legacy** <td> \deprecated The original likelihood evaluation method.
* It is deprecated and will be removed in ROOT 6.44, together with the deprecated BatchMode() command argument
* (where the legacy backend corresponded to `BatchMode("off")`).
* Evaluates the PDF for each single data entry at a time before summing the negative log probabilities.
* It supports multi-threading, but you might need more than 20 threads to maybe see about 10% performance gain over the default cpu-backend (that runs currently only on a single thread).
* <tr><td> **codegen** <td> **Experimental** - Generates and compiles minimal C++ code for the NLL on-the-fly and wraps it in the returned RooAbsReal.
Expand Down
30 changes: 25 additions & 5 deletions roofit/roofitcore/src/RooGlobalFunc.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -476,21 +476,41 @@ RooCmdArg TimingAnalysis(bool flag)
{
return RooCmdArg("TimingAnalysis", flag, 0, 0, 0, nullptr, nullptr, nullptr);
}
RooCmdArg BatchMode(std::string const &batchMode)
namespace {

RooCmdArg batchModeImpl(std::string const &batchMode)
{
oocoutW(nullptr, InputArguments)
<< "The BatchMode() command argument is deprecated. Please use EvalBackend() instead." << std::endl;
<< "The BatchMode() command argument is deprecated and will be removed in ROOT 6.44, together with the legacy\n"
"evaluation backend that corresponds to BatchMode(\"off\"). Please use EvalBackend() instead, or simply pass\n"
"no command argument to get the default \"cpu\" evaluation backend."
<< std::endl;
std::string lower = batchMode;
std::transform(lower.begin(), lower.end(), lower.begin(), [](unsigned char c) { return std::tolower(c); });
if (lower == "off") {
return EvalBackend::Legacy();
return EvalBackend(EvalBackend::Value::Legacy);
} else if (lower == "cpu") {
return EvalBackend::Cpu();
return EvalBackend(EvalBackend::Value::Cpu);
} else if (lower == "cuda") {
return EvalBackend::Cuda();
return EvalBackend(EvalBackend::Value::Cuda);
}
throw std::runtime_error("Only supported string values for BatchMode() are \"off\", \"cpu\", or \"cuda\".");
}

} // namespace

RooCmdArg BatchMode(std::string const &batchMode)
{
return batchModeImpl(batchMode);
}
RooCmdArg BatchMode(const char *batchMode)
{
return batchModeImpl(batchMode);
}
RooCmdArg BatchMode(bool batchModeOn)
{
return batchModeImpl(batchModeOn ? "cpu" : "off");
}
/// Integrate the PDF over bins. Improves accuracy for binned fits. Switch off using `0.` as argument. \see
/// RooAbsPdf::fitTo().
RooCmdArg IntegrateBins(double precision)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ TEST_P(LikelihoodGradientJobTest, GaussianND)
std::unique_ptr<RooArgSet> values;
RooAbsPdf *pdf;
std::unique_ptr<RooDataSet> data;
std::tie(nll, pdf, data, values) = generate_ND_gaussian_pdf_nll(w, N, 1000, RooFit::EvalBackend::Legacy());
std::tie(nll, pdf, data, values) = generate_ND_gaussian_pdf_nll(w, N, 1000, RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy));

RooArgSet savedValues;
values->snapshot(savedValues);
Expand Down Expand Up @@ -632,7 +632,7 @@ TEST_P(LikelihoodGradientJobErrorTest, ErrorHandling)
} else {
data = std::unique_ptr<RooDataSet>{pdf->generate(*w.var("m"), 10000)};
}
std::unique_ptr<RooAbsReal> nll{pdf->createNLL(*data, RooFit::EvalBackend::Legacy())};
std::unique_ptr<RooAbsReal> nll{pdf->createNLL(*data, RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy))};

// if m0 were constant (i.e. setConstant(true)), the fit would converge without errors, because m0 outside of the
// physical area of the Argus distribution is what causes the errors in the line search phase of the fit
Expand Down Expand Up @@ -693,7 +693,7 @@ TEST_P(LikelihoodGradientJobErrorTest, FitSimpleLinear)
} else {
data = std::unique_ptr<RooDataSet>{pdf.generate(x, 1000)};
}
std::unique_ptr<RooAbsReal> nll(pdf.createNLL(*data, RooFit::EvalBackend::Legacy()));
std::unique_ptr<RooAbsReal> nll(pdf.createNLL(*data, RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy)));

RooArgSet normSet{x};
ASSERT_FALSE(std::isnan(pdf.getVal(normSet)));
Expand Down Expand Up @@ -841,7 +841,7 @@ TEST_P(LikelihoodGradientJobBinnedErrorTest, TriggerMuLEZero)
values->snapshot(savedValues);

// legacy RooFit fit
std::unique_ptr<RooAbsReal> nll(w.pdf("model")->createNLL(h_data, RooFit::EvalBackend::Legacy()));
std::unique_ptr<RooAbsReal> nll(w.pdf("model")->createNLL(h_data, RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy)));

double nll0BeforeFit = nll->getVal();

Expand Down Expand Up @@ -933,7 +933,7 @@ TEST(MinuitFcnGrad, DISABLED_CompareToRooMinimizerFcn)

std::unique_ptr<RooAbsReal> nll_vanilla{pdf->createNLL(*data, RooFit::Constrain(*nuisance_parameters),
RooFit::GlobalObservables(*global_observables),
RooFit::EvalBackend::Legacy()
RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy)
/*, RooFit::Offset(true)*/)};

double vanilla_val = nll_vanilla->getVal();
Expand Down
6 changes: 3 additions & 3 deletions roofit/roofitcore/test/TestStatistics/testLikelihoodJob.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ TEST_F(LikelihoodJobTest, UnbinnedGaussianND)
using namespace RooFit;
unsigned int N = 4;

std::tie(nll, pdf, data, values) = generate_ND_gaussian_pdf_nll(w, N, 1000, EvalBackend::Legacy());
std::tie(nll, pdf, data, values) = generate_ND_gaussian_pdf_nll(w, N, 1000, EvalBackend(EvalBackend::Value::Legacy));
likelihood = TestStatistics::buildLikelihood(pdf, data.get());
// dummy offsets (normally they are shared with other objects):
SharedOffset offset;
Expand Down Expand Up @@ -487,7 +487,7 @@ TEST_F(LikelihoodJobSimBinnedConstrainedTest, ConstrainedAndOffset)
// RooAbsTestStatistic.
nll = std::unique_ptr<RooAbsReal>{pdf->createNLL(*data, Constrain(*w.var("alpha_bkg_A")),
GlobalObservables(*w.var("alpha_bkg_obs_B")), Offset("initial"),
EvalBackend::Legacy())};
EvalBackend(EvalBackend::Value::Legacy))};

// --------

Expand Down Expand Up @@ -567,7 +567,7 @@ TEST_P(LikelihoodJobSplitStrategies, DISABLED_SimBinnedConstrainedAndOffset)
// RooAbsTestStatistic.
nll = std::unique_ptr<RooAbsReal>{pdf->createNLL(*data, Constrain(*w.var("alpha_bkg_A")),
GlobalObservables(*w.var("alpha_bkg_obs_B")), Offset("initial"),
EvalBackend::Legacy())};
EvalBackend(EvalBackend::Value::Legacy))};

// --------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ TEST_F(LikelihoodSerialTest, UnbinnedGaussianND)
{
unsigned int N = 4;

std::tie(nll, pdf, data, values) = generate_ND_gaussian_pdf_nll(w, N, 1000, RooFit::EvalBackend::Legacy());
std::tie(nll, pdf, data, values) = generate_ND_gaussian_pdf_nll(w, N, 1000, RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy));
likelihood = RFTS::buildLikelihood(pdf, data.get());
// dummy offsets (normally they are shared with other objects):
SharedOffset offset;
Expand Down Expand Up @@ -409,7 +409,7 @@ TEST_F(LikelihoodSerialSimBinnedConstrainedTest, ConstrainedAndOffset)
// RooAbsTestStatistic.
nll = std::unique_ptr<RooAbsReal>{pdf->createNLL(*data, Constrain(*w.var("alpha_bkg_A")),
GlobalObservables(*w.var("alpha_bkg_obs_B")), Offset("initial"),
EvalBackend::Legacy())};
EvalBackend(EvalBackend::Value::Legacy))};

// --------

Expand Down
4 changes: 2 additions & 2 deletions roofit/roofitcore/test/TestStatistics/testRooRealL.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ TEST_P(RooRealL, setVal)
// the multiprocess test statistics classes were designed to give values
// that are bit-by-bit identical with the old test statistics based on
// RooAbsTestStatistic.
std::unique_ptr<RooAbsReal> nll{pdf->createNLL(*data, RooFit::EvalBackend::Legacy())};
std::unique_ptr<RooAbsReal> nll{pdf->createNLL(*data, RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy))};

RooFit::TestStatistics::RooRealL nll_new("nll_new", "new style NLL",
std::make_unique<RooFit::TestStatistics::RooUnbinnedL>(pdf, data.get()));
Expand Down Expand Up @@ -270,7 +270,7 @@ TEST_P(RealLVsMPFE, getVal)
// the multiprocess test statistics classes were designed to give values
// that are bit-by-bit identical with the old test statistics based on
// RooAbsTestStatistic.
std::unique_ptr<RooAbsReal> nll_mpfe{pdf->createNLL(*data, RooFit::EvalBackend::Legacy())};
std::unique_ptr<RooAbsReal> nll_mpfe{pdf->createNLL(*data, RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy))};

auto mpfe_result = nll_mpfe->getVal();

Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/test/gtest_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#endif

#ifdef ROOFIT_LEGACY_EVAL_BACKEND
#define ROOFIT_EVAL_BACKEND_LEGACY RooFit::EvalBackend::Legacy(),
#define ROOFIT_EVAL_BACKEND_LEGACY RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy),
#else
#define ROOFIT_EVAL_BACKEND_LEGACY
#endif
Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/test/stressRooFit.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ int main(int argc, const char *argv[])
int dryRun = false;
bool doDump = false;
bool doTreeStore = false;
auto backend = RooFit::EvalBackend::Legacy();
auto backend = RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy);

// string refFileName = "http://root.cern.ch/files/stressRooFit_v534_ref.root" ;
string refFileName = "stressRooFit_ref.root";
Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/test/testGlobalObservables.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ bool isNotIdentical(RooFitResult const &res1, RooFitResult const &res2)
// we track the global observables separately.
class GlobsTest : public testing::TestWithParam<std::tuple<RooFit::EvalBackend>> {
public:
GlobsTest() : _evalBackend{RooFit::EvalBackend::Legacy()} {}
GlobsTest() : _evalBackend{RooFit::EvalBackend(RooFit::EvalBackend::Value::Legacy)} {}

void SetUp() override
{
Expand Down
Loading
Loading