Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RF] Consistent treatment of empty datasets with new CPU backend #14817

Merged
merged 2 commits into from
Feb 26, 2024
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
16 changes: 13 additions & 3 deletions roofit/batchcompute/src/RooBatchCompute.cu
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,19 @@ void fillBatches(Batches &batches, RestrictArr output, size_t nEvents, std::size
batches._output = output;
}

void fillArrays(Batch *arrays, const VarVector &vars, double *buffer, double *bufferDevice)
void fillArrays(Batch *arrays, const VarVector &vars, double *buffer, double *bufferDevice, std::size_t nEvents)
{
for (int i = 0; i < vars.size(); i++) {
const std::span<const double> &span = vars[i];
if (span.size() == 1) {
if (!span.empty() && span.size() < nEvents) {
// In the scalar case, the value is not on the GPU yet, so we have to
// copy the value to the GPU buffer.
buffer[i] = span[0];
arrays[i].set(bufferDevice + i, false);
} else {
// In the vector input cases, they are already on the GPU, so we can
// fill be buffer with some dummy value and set the input span
// directly.
buffer[i] = 0.0;
arrays[i].set(span.data(), true);
}
Expand Down Expand Up @@ -132,7 +137,7 @@ public:
auto extraArgsDevice = reinterpret_cast<double *>(scalarBufferDevice + vars.size());

fillBatches(*batches, output, nEvents, vars.size(), extraArgs.size());
fillArrays(arrays, vars, scalarBuffer, scalarBufferDevice);
fillArrays(arrays, vars, scalarBuffer, scalarBufferDevice, nEvents);
batches->_arrays = arraysDevice;

if (!extraArgs.empty()) {
Expand Down Expand Up @@ -255,6 +260,8 @@ __global__ void nllSumKernel(const double *__restrict__ probas, const double *__

double RooBatchComputeClass::reduceSum(RooBatchCompute::Config const &cfg, InputArr input, size_t n)
{
if (n == 0)
return 0.0;
const int gridSize = getGridSize(n);
cudaStream_t stream = *cfg.cudaStream();
CudaInterface::DeviceArray<double> devOut(2 * gridSize);
Expand All @@ -270,6 +277,9 @@ ReduceNLLOutput RooBatchComputeClass::reduceNLL(RooBatchCompute::Config const &c
std::span<const double> weights, std::span<const double> offsetProbas)
{
ReduceNLLOutput out;
if (probas.empty()) {
return out;
}
const int gridSize = getGridSize(probas.size());
CudaInterface::DeviceArray<double> devOut(2 * gridSize);
cudaStream_t stream = *cfg.cudaStream();
Expand Down
18 changes: 8 additions & 10 deletions roofit/batchcompute/src/RooBatchCompute.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,19 @@ void fillBatches(Batches &batches, RestrictArr output, size_t nEvents, std::size
batches._output = output;
}

void fillArrays(std::vector<Batch> &arrays, const VarVector &vars, double *buffer)
void fillArrays(std::vector<Batch> &arrays, const VarVector &vars, double *buffer, std::size_t nEvents)
{

arrays.resize(vars.size());
for (size_t i = 0; i < vars.size(); i++) {
const std::span<const double> &span = vars[i];
if (span.empty()) {
std::stringstream ss;
ss << "The span number " << i << " passed to Batches::Batches() is empty!";
throw std::runtime_error(ss.str());
} else if (span.size() > 1) {
arrays[i].set(span.data(), true);
} else {
if (!span.empty() && span.size() < nEvents) {
// In the scalar case, copy the value to each element of vector input
// buffer.
std::fill_n(&buffer[i * bufferSize], bufferSize, span.data()[0]);
arrays[i].set(&buffer[i * bufferSize], false);
} else {
arrays[i].set(span.data(), true);
}
}
}
Expand Down Expand Up @@ -131,7 +129,7 @@ class RooBatchComputeClass : public RooBatchComputeInterface {
Batches batches;
std::vector<Batch> arrays;
fillBatches(batches, output, nEventsPerThread, vars.size(), extraArgs);
fillArrays(arrays, vars, buffer.data());
fillArrays(arrays, vars, buffer.data(), nEvents);
batches._arrays = arrays.data();
batches.advance(batches.getNEvents() * idx);

Expand Down Expand Up @@ -163,7 +161,7 @@ class RooBatchComputeClass : public RooBatchComputeInterface {
Batches batches;
std::vector<Batch> arrays;
fillBatches(batches, output, nEvents, vars.size(), extraArgs);
fillArrays(arrays, vars, buffer.data());
fillArrays(arrays, vars, buffer.data(), nEvents);
batches._arrays = arrays.data();

std::size_t events = batches.getNEvents();
Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/inc/RooAddModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class RooAddModel : public RooResolutionModel {
RooListProxy _coefList ; ///< List of coefficients
mutable RooArgList* _snormList{nullptr}; ///<! List of supplemental normalization factors

bool _haveLastCoef = false; ///< Flag indicating if last PDFs coefficient was supplied in the ctor
bool _haveLastCoef = false; ///< Flag indicating if last PDFs coefficient was supplied in the constructor
bool _allExtendable = false; ///< Flag indicating if all PDF components are extendable

mutable Int_t _coefErrCount ; ///<! Coefficient error counter
Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/inc/RooAddPdf.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class RooAddPdf : public RooAbsPdf {
RooListProxy _coefList ; ///< List of coefficients
mutable RooArgList* _snormList{nullptr}; ///<! List of supplemental normalization factors

bool _haveLastCoef = false; ///< Flag indicating if last PDFs coefficient was supplied in the ctor
bool _haveLastCoef = false; ///< Flag indicating if last PDFs coefficient was supplied in the constructor
bool _allExtendable = false; ///< Flag indicating if all PDF components are extendable
bool _recursive = false; ///< Flag indicating is fractions are treated recursively

Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/inc/RooCompositeDataStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class RooCompositeDataStore : public RooAbsDataStore {
// Ctors from DataStore
RooCompositeDataStore(RooStringView name, RooStringView title, const RooArgSet& vars, RooCategory& indexCat, std::map<std::string,RooAbsDataStore*> const& inputData) ;

// Empty ctor
// Empty constructor.
RooAbsDataStore* clone(const char* newname=nullptr) const override { return new RooCompositeDataStore(*this,newname) ; }
RooAbsDataStore* clone(const RooArgSet& vars, const char* newname=nullptr) const override { return new RooCompositeDataStore(*this,vars,newname) ; }

Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/inc/RooCustomizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class RooCustomizer {
RooArgSet _internalCloneBranchList; ///< List of branches of internal clone
RooArgSet* _cloneBranchList = nullptr; ///< Pointer to list of cloned branches used

// Cloned leafs are owned by the user supplied list in the ctor
// Cloned leaves are owned by the user supplied list in the constructor
RooArgSet* _cloneNodeListAll = nullptr; ///< List of all cloned nodes
RooArgSet* _cloneNodeListOwned = nullptr;///< List of owned cloned nodes
} ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ getDataSpans(RooAbsData const &data, std::string const &rangeName, RooSimultaneo
bool takeGlobalObservablesFromData, std::stack<std::vector<double>> &buffers);

std::map<RooFit::Detail::DataKey, std::size_t>
determineOutputSizes(RooAbsArg const &topNode,
std::function<std::size_t(RooFit::Detail::DataKey)> const &inputSizeFunc);
determineOutputSizes(RooAbsArg const &topNode, std::function<int(RooFit::Detail::DataKey)> const &inputSizeFunc);

} // namespace BatchModeDataHelpers
} // namespace Detail
Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/inc/RooLinkedListElem.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace RooLinkedListImplDetails {

class RooLinkedListElem {
public:
// Initial element ctor
// Initial element constructor
RooLinkedListElem() = default;

void init(TObject* arg, RooLinkedListElem* after=nullptr) {
Expand Down
8 changes: 4 additions & 4 deletions roofit/roofitcore/inc/RooMinimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class RooDataSet;

class RooMinimizer : public TObject {
public:
/// Config argument to RooMinimizer ctor
/// Config argument to RooMinimizer constructor.
struct Config {

Config() {}
Expand All @@ -55,16 +55,16 @@ class RooMinimizer : public TObject {
int offsetting = -1; // RooAbsMinimizerFcn config
const char *logf = nullptr; // RooAbsMinimizerFcn config

// RooAbsMinimizerFcn config that can only be set in ctor, 0 means no parallelization (default),
// RooAbsMinimizerFcn config that can only be set in constructor, 0 means no parallelization (default),
// -1 is parallelization with the number of workers controlled by RooFit::MultiProcess which
// defaults to the number of available processors, n means parallelization with n CPU's
int parallelize = 0;

// Experimental: RooAbsMinimizerFcn config that can only be set in ctor
// Experimental: RooAbsMinimizerFcn config that can only be set in constructor
// argument is ignored when parallelize is 0
bool enableParallelGradient = true;

// Experimental: RooAbsMinimizerFcn config that can only be set in ctor
// Experimental: RooAbsMinimizerFcn config that can only be set in constructor
// argument is ignored when parallelize is 0
bool enableParallelDescent = false;

Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/inc/RooMsgService.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ class RooMsgService : public TObject {

Int_t _errorCount ;

// Private ctor -- singleton class
// Private constructor -- singleton class
RooMsgService() ;
RooMsgService(const RooMsgService&) ;

Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/inc/RooNumConvPdf.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class RooNumConvPdf : public RooAbsPdf {
protected:

// WVE Store all properties of RooNumConvolution here so that can be take
// along in the copy ctor.
// along in the copy constructor.

RooNumConvolution& conv() const { if (!_init) initialize() ; return *_conv ; }

Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/inc/RooTreeDataStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class RooTreeDataStore : public RooAbsDataStore {
RooTreeDataStore() ;
RooTreeDataStore(TTree* t, const RooArgSet& vars, const char* wgtVarName=nullptr) ;

// Empty ctor
// Empty constructor
RooTreeDataStore(RooStringView name, RooStringView title, const RooArgSet& vars, const char* wgtVarName=nullptr) ;
RooAbsDataStore* clone(const char* newname=nullptr) const override { return new RooTreeDataStore(*this,newname) ; }
RooAbsDataStore* clone(const RooArgSet& vars, const char* newname=nullptr) const override { return new RooTreeDataStore(*this,vars,newname) ; }
Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/inc/RooVectorDataStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class RooVectorDataStore : public RooAbsDataStore {

RooVectorDataStore() ;

// Empty ctor
// Empty constructor
RooVectorDataStore(RooStringView name, RooStringView title, const RooArgSet& vars, const char* wgtVarName=nullptr) ;

RooAbsDataStore* clone(const char* newname=nullptr) const override { return new RooVectorDataStore(*this,newname) ; }
Expand Down
23 changes: 13 additions & 10 deletions roofit/roofitcore/src/BatchModeDataHelpers.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,6 @@ getSingleDataSpans(RooAbsData const &data, std::string_view rangeName, std::stri

std::size_t nEvents = static_cast<size_t>(data.numEntries());

// We also want to support empty datasets: in this case the
// RooFitDriver::Dataset is not filled with anything.
if (nEvents == 0) {
return dataSpans;
}

auto weight = data.getWeightBatch(0, nEvents, /*sumW2=*/false);
auto weightSumW2 = data.getWeightBatch(0, nEvents, /*sumW2=*/true);

Expand Down Expand Up @@ -274,16 +268,18 @@ RooFit::Detail::BatchModeDataHelpers::getDataSpans(RooAbsData const &data, std::
/// \param[in] topNode The top node of the computation graph.
/// \param[in] inputSizeFunc A function to get the input sizes.
std::map<RooFit::Detail::DataKey, std::size_t> RooFit::Detail::BatchModeDataHelpers::determineOutputSizes(
RooAbsArg const &topNode, std::function<std::size_t(RooFit::Detail::DataKey)> const &inputSizeFunc)
RooAbsArg const &topNode, std::function<int(RooFit::Detail::DataKey)> const &inputSizeFunc)
{
std::map<RooFit::Detail::DataKey, std::size_t> output;

RooArgSet serverSet;
RooHelpers::getSortedComputationGraph(topNode, serverSet);

for (RooAbsArg *arg : serverSet) {
std::size_t inputSize = inputSizeFunc(arg);
if (inputSize > 0) {
int inputSize = inputSizeFunc(arg);
// The size == -1 encodes that the input doesn't come from an array
// input.
if (inputSize != -1) {
output[arg] = inputSize;
}
}
Expand All @@ -296,7 +292,14 @@ std::map<RooFit::Detail::DataKey, std::size_t> RooFit::Detail::BatchModeDataHelp
if (!arg->isReducerNode()) {
for (RooAbsArg *server : arg->servers()) {
if (server->isValueServer(*arg)) {
size = std::max(output.at(server), size);
std::size_t inputSize = output.at(server);
if (inputSize != 1) {
// If the input if from an external array, the output will
// adopt its size and we can stop the checking of other
// servers.
size = inputSize;
break;
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions roofit/roofitcore/src/RooAbsArg.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ std::size_t RooAbsArg::getParametersSizeEstimate(const RooArgSet* nset) const
/// ourself as top node that don't match any of the names the args in the
/// supplied argset. Returns `true` only if something went wrong.
/// The complement of this function is getObservables().
/// \param[in] observables Set of leafs to ignore because they are observables and not parameters.
/// \param[in] observables Set of leaves to ignore because they are observables and not parameters.
/// \param[out] outputSet Output set.
/// \param[in] stripDisconnected Allow pdf to strip parameters from list before adding it.

Expand Down Expand Up @@ -745,7 +745,7 @@ RooFit::OwningPtr<RooArgSet> RooAbsArg::getObservables(const RooArgSet* dataList
/// The complement of this function is getParameters().
/// \param[in] dataList Set of leaf nodes to match.
/// \param[out] outputSet Output set.
/// \param[in] valueOnly If this parameter is true, we only match leafs that
/// \param[in] valueOnly If this parameter is true, we only match leaves that
/// depend on the value of any arg in `dataList`.

bool RooAbsArg::getObservables(const RooAbsCollection* dataList, RooArgSet& outputSet, bool valueOnly) const
Expand Down
Loading
Loading