26#include <RConfigure.h>
47#error "RF_ARCH should always be defined"
66 for (std::size_t i = 0; i < vars.size(); i++) {
67 arrays[i]._array = vars[i].data();
68 arrays[i]._isVector = vars[i].empty() || vars[i].size() >= nEvents;
74 for (std::size_t i = 0; i <
batches.nBatches; i++) {
88 std::vector<Batch>
arrays(vars.size());
95 std::size_t events = count;
118std::size_t
numChunks(std::size_t nEvents)
131 static std::mutex mutex;
136 static auto &
executors = *
new std::map<int, std::unique_ptr<ROOT::TThreadExecutor>>;
137 std::lock_guard<std::mutex> lock{mutex};
140 executor = std::make_unique<ROOT::TThreadExecutor>(nThreads);
156 const unsigned int nTasks = executor.
GetPoolSize() >
static_cast<unsigned int>(nThreads) ? nThreads : 0;
205 std::transform(out.begin(), out.end(), out.begin(), [](
unsigned char c) { return std::tolower(c); });
236 const std::size_t nEvents = output.size();
247 const std::size_t nExtra =
extraArgs.size();
254 computeRange(computeFn, output.data(), nEvents, vars, {extraCopies.data() + iChunk * nExtra, nExtra},
258 for (std::size_t k = 0; k < nExtra; ++k) {
283 if (std::isinf(
prob)) {
287 if (std::isnan(
prob)) {
292 return {std::log(
prob), 0.0};
304 const std::size_t begin = chunkBegin(iChunk);
306 ROOT::Math::KahanSum<double, 4u>::Accumulate(input + begin, input + begin + chunkSize(iChunk, n));
325struct NLLPartialResult {
331void reduceNLLRange(std::span<const double> probas, std::span<const double> weights,
332 std::span<const double>
offsetProbas, std::size_t begin, std::size_t end, NLLPartialResult &
result)
334 for (std::size_t i = begin; i < end; ++i) {
336 if (0. == weights[i])
356 std::span<const double> weights, std::span<const double>
offsetProbas)
358 const std::size_t
n = weights.size();
366 const std::size_t begin = chunkBegin(iChunk);
367 reduceNLLRange(probas, weights, offsetProbas, begin, begin + chunkSize(iChunk, n), partials[iChunk]);
374 result.counters.nInfiniteValues +=
partial.counters.nInfiniteValues;
375 result.counters.nNonPositiveValues +=
partial.counters.nNonPositiveValues;
390 if (
result.badness != 0.) {
401class ScalarBufferContainer {
403 ScalarBufferContainer() {}
404 ScalarBufferContainer(std::size_t
size)
407 throw std::runtime_error(
"ScalarBufferContainer can only be of size 1");
410 double const *hostReadPtr()
const {
return &
_val; }
411 double const *deviceReadPtr()
const {
return &
_val; }
413 double *hostWritePtr() {
return &
_val; }
414 double *deviceWritePtr() {
return &
_val; }
416 void assignFromHost(std::span<const double>
input) {
_val =
input[0]; }
417 void assignFromDevice(std::span<const double>) {
throw std::bad_function_call(); }
423class CPUBufferContainer {
427 double const *hostReadPtr()
const {
return _vec.data(); }
428 double const *deviceReadPtr()
const
430 throw std::bad_function_call();
434 double *hostWritePtr() {
return _vec.data(); }
435 double *deviceWritePtr()
437 throw std::bad_function_call();
441 void assignFromHost(std::span<const double>
input) {
_vec.assign(
input.begin(),
input.end()); }
442 void assignFromDevice(std::span<const double>) {
throw std::bad_function_call(); }
448template <
class Container>
449class BufferImpl :
public AbsBuffer {
451 using Queue = std::queue<std::unique_ptr<Container>>;
453 BufferImpl(std::size_t
size, Queue &queue) :
_queue{queue}
456 _vec = std::make_unique<Container>(
size);
465 double const *hostReadPtr()
const override {
return _vec->hostReadPtr(); }
466 double const *deviceReadPtr()
const override {
return _vec->deviceReadPtr(); }
468 double *hostWritePtr()
override {
return _vec->hostWritePtr(); }
469 double *deviceWritePtr()
override {
return _vec->deviceWritePtr(); }
471 void assignFromHost(std::span<const double>
input)
override {
_vec->assignFromHost(
input); }
472 void assignFromDevice(std::span<const double>
input)
override {
_vec->assignFromDevice(
input); }
477 std::unique_ptr<Container>
_vec;
484struct BufferQueuesMaps {
489class BufferManager :
public AbsBufferManager {
492 BufferManager() :
_queuesMaps{std::make_unique<BufferQueuesMaps>()} {}
494 std::unique_ptr<AbsBuffer> makeScalarBuffer()
override
496 return std::make_unique<ScalarBuffer>(1,
_queuesMaps->scalarBufferQueuesMap[1]);
498 std::unique_ptr<AbsBuffer> makeCpuBuffer(std::size_t
size)
override
502 std::unique_ptr<AbsBuffer> makeGpuBuffer(std::size_t)
override {
throw std::bad_function_call(); }
503 std::unique_ptr<AbsBuffer> makePinnedBuffer(std::size_t, CudaInterface::CudaStream * =
nullptr)
override
505 throw std::bad_function_call();
514std::unique_ptr<AbsBufferManager> RooBatchComputeClass::createBufferManager()
const
516 return std::make_unique<BufferManager>();
#define _R_QUOTEVAL_(string)
std::vector< double > _vec
std::map< std::size_t, CPUBuffer::Queue > cpuBufferQueuesMap
std::map< std::size_t, ScalarBuffer::Queue > scalarBufferQueuesMap
std::unique_ptr< BufferQueuesMaps > _queuesMaps
ROOT::Math::KahanSum< double > nllSum
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
static unsigned int total
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
The Kahan summation is a compensated summation algorithm, which significantly reduces numerical error...
static KahanSum< T, N > Accumulate(Iterator begin, Iterator end, T initialValue=T{})
Iterate over a range and return an instance of a KahanSum.
const_iterator begin() const
const_iterator end() const
A pseudo container class which is a generator of indices.
This class provides a simple interface to execute the same task multiple times in parallel threads,...
unsigned GetPoolSize() const
Returns the number of worker threads in the task arena.
void Foreach(F func, unsigned nTimes, unsigned nChunks=0)
Execute a function without arguments several times in parallel, dividing the execution in nChunks.
const double *__restrict _array
Minimal configuration struct to steer the evaluation of a single node with the RooBatchCompute librar...
This class overrides some RooBatchComputeInterface functions, for the purpose of providing a CPU spec...
std::string architectureName() const override
void compute(Config const &, Computer computer, std::span< double > output, VarSpan vars, ArgSpan extraArgs) override
Compute multiple values using optimized functions.
const std::vector< void(*)(Batches &)> _computeFunctions
double reduceSum(Config const &, InputArr input, size_t n) override
void deleteCudaStream(CudaInterface::CudaStream *) const override
std::unique_ptr< AbsBufferManager > createBufferManager() const override
CudaInterface::CudaStream * newCudaStream() const override
void synchronizeCudaStream(CudaInterface::CudaStream *) const override
Wait until all work that was enqueued on the stream has completed.
Architecture architecture() const override
ReduceNLLOutput reduceNLL(Config const &, std::span< const double > probas, std::span< const double > weights, std::span< const double > offsetProbas) override
The interface which should be implemented to provide optimised computation functions for implementati...
std::vector< void(*)(Batches &)> getFunctions()
static RooBatchComputeClass computeObj
Static object to trigger the constructor which overwrites the dispatch pointer.
Namespace for dispatching RooFit computations to various backends.
std::span< double > ArgSpan
R__EXTERN RooBatchComputeInterface * dispatchCPU
This dispatch pointer points to an implementation of the compute library, provided one has been loade...
constexpr std::size_t bufferSize
const double *__restrict InputArr
std::span< const std::span< const double > > VarSpan
void probas(TString dataset, TString fin="TMVA.root", Bool_t useTMVAStyle=kTRUE)
std::size_t nInfiniteValues
std::size_t nNonPositiveValues
static double packFloatIntoNaN(float payload)
Pack float into mantissa of a NaN.
static float unpackNaN(double val)
If val is NaN and a this NaN has been tagged as containing a payload, unpack the float from the manti...