Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooFitDriver.cxx
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 * Authors:
4 * Jonas Rembser, CERN 2021
5 * Emmanouil Michalainas, CERN 2021
6 *
7 * Copyright (c) 2021, CERN
8 *
9 * Redistribution and use in source and binary forms,
10 * with or without modification, are permitted according to the terms
11 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
12 */
13
14/**
15\file RooFitDriver.cxx
16\class RooFitDriver
17\ingroup Roofitcore
18
19This class can evaluate a RooAbsReal object in other ways than recursive graph
20traversal. Currently, it is being used for evaluating a RooAbsReal object and
21supplying the value to the minimizer, during a fit. The class scans the
22dependencies and schedules the computations in a secure and efficient way. The
23computations take place in the RooBatchCompute library and can be carried off
24by either the CPU or a CUDA-supporting GPU. The RooFitDriver class takes care
25of data transfers. An instance of this class is created every time
26RooAbsPdf::fitTo() is called and gets destroyed when the fitting ends.
27**/
28
29#include "RooFitDriver.h"
30
31#include <RooAbsCategory.h>
32#include <RooAbsData.h>
33#include <RooAbsReal.h>
34#include <RooRealVar.h>
35#include <RooBatchCompute.h>
36#include <RooHelpers.h>
37#include <RooMsgService.h>
41#include "RooFit/CUDAHelpers.h"
42#include <RooSimultaneous.h>
43
44#include <TList.h>
45
46#include <iomanip>
47#include <numeric>
48#include <thread>
49
50namespace ROOT {
51namespace Experimental {
52
53namespace {
54
55void logArchitectureInfo(RooFit::BatchModeOption batchMode)
56{
57 // We have to exit early if the message stream is not active. Otherwise it's
58 // possible that this function skips logging because it thinks it has
59 // already logged, but actually it didn't.
60 if (!RooMsgService::instance().isActive(static_cast<RooAbsArg *>(nullptr), RooFit::Fitting, RooFit::INFO)) {
61 return;
62 }
63
64 // Don't repeat logging architecture info if the batchMode option didn't change
65 {
66 // Second element of pair tracks whether this function has already been called
67 static std::pair<RooFit::BatchModeOption, bool> lastBatchMode;
68 if (lastBatchMode.second && lastBatchMode.first == batchMode)
69 return;
70 lastBatchMode = {batchMode, true};
71 }
72
73 auto log = [](std::string_view message) {
74 oocxcoutI(static_cast<RooAbsArg *>(nullptr), Fitting) << message << std::endl;
75 };
76
78 throw std::runtime_error(std::string("In: ") + __func__ + "(), " + __FILE__ + ":" + __LINE__ +
79 ": Cuda implementation of the computing library is not available\n");
80 }
82 log("using generic CPU library compiled with no vectorizations");
83 } else {
84 log(std::string("using CPU computation library compiled with -m") +
85 RooBatchCompute::dispatchCPU->architectureName());
86 }
87 if (batchMode == RooFit::BatchModeOption::Cuda) {
88 log("using CUDA computation library");
89 }
90}
91
92} // namespace
93
94/// A struct used by the RooFitDriver to store information on the RooAbsArgs in
95/// the computation graph.
96struct NodeInfo {
97 /// Check the servers of a node that has been computed and release it's resources
98 /// if they are no longer needed.
100 {
101 if (--remClients == 0) {
102 delete buffer;
103 buffer = nullptr;
104 }
105 }
106
107 bool isScalar() const { return outputSize == 1; }
108
109 bool computeInGPU() const { return (absArg->isReducerNode() || !isScalar()) && absArg->canComputeBatchWithCuda(); }
110
111 RooAbsArg *absArg = nullptr;
112
114 std::size_t iNode = 0;
115 cudaEvent_t *event = nullptr;
116 cudaStream_t *stream = nullptr;
117 int remClients = 0;
118 int remServers = 0;
120 bool fromDataset = false;
121 bool isVariable = false;
122 bool isDirty = true;
123 bool isCategory = false;
124 bool hasLogged = false;
125 std::size_t outputSize = 1;
126 std::size_t lastSetValCount = std::numeric_limits<std::size_t>::max();
127 double scalarBuffer = 0.0;
128 std::vector<NodeInfo *> serverInfos;
129 std::vector<NodeInfo *> clientInfos;
130
132 {
133 if (event)
135 if (stream)
137 }
138};
139
140/// Construct a new RooFitDriver. The constructor analyzes and saves metadata about the graph,
141/// useful for the evaluation of it that will be done later. In case the CUDA mode is selected,
142/// there's also some CUDA-related initialization.
143///
144/// \param[in] absReal The RooAbsReal object that sits on top of the
145/// computation graph that we want to evaluate.
146/// \param[in] batchMode The computation mode, accepted values are
147/// `RooBatchCompute::Cpu` and `RooBatchCompute::Cuda`.
149 : _topNode{const_cast<RooAbsReal &>(absReal)}, _batchMode{batchMode}
150{
151 // Initialize RooBatchCompute
153
154 // Some checks and logging of used architectures
155 logArchitectureInfo(_batchMode);
156
157 RooArgSet serverSet;
159
160 _dataMapCPU.resize(serverSet.size());
161 _dataMapCUDA.resize(serverSet.size());
162
163 std::map<RooFit::Detail::DataKey, NodeInfo *> nodeInfos;
164
165 // Fill the ordered nodes list and initialize the node info structs.
166 _nodes.resize(serverSet.size());
167 std::size_t iNode = 0;
168 for (RooAbsArg *arg : serverSet) {
169
170 auto &nodeInfo = _nodes[iNode];
171 nodeInfo.absArg = arg;
172 nodeInfo.iNode = iNode;
173 nodeInfos[arg] = &nodeInfo;
174
175 if (dynamic_cast<RooRealVar const *>(arg)) {
176 nodeInfo.isVariable = true;
177 } else {
178 arg->setDataToken(iNode);
179 }
180 if (dynamic_cast<RooAbsCategory const *>(arg)) {
181 nodeInfo.isCategory = true;
182 }
183
184 ++iNode;
185 }
186
187 for (NodeInfo &info : _nodes) {
188 info.serverInfos.reserve(info.absArg->servers().size());
189 for (RooAbsArg *server : info.absArg->servers()) {
190 if (server->isValueServer(*info.absArg)) {
191 auto *serverInfo = nodeInfos.at(server);
192 info.serverInfos.emplace_back(serverInfo);
193 serverInfo->clientInfos.emplace_back(&info);
194 }
195 }
196 }
197
199
201 // create events and streams for every node
202 for (auto &info : _nodes) {
205 }
206 }
207}
208
209/// If there are servers with the same name that got de-duplicated in the
210/// `_nodes` list, we need to set their data tokens too. We find such nodes by
211/// visiting the servers of every known node.
213{
214 for (NodeInfo &info : _nodes) {
215 std::size_t iValueServer = 0;
216 for (RooAbsArg *server : info.absArg->servers()) {
217 if (server->isValueServer(*info.absArg)) {
218 auto *knownServer = info.serverInfos[iValueServer]->absArg;
219 if (knownServer->hasDataToken()) {
220 server->setDataToken(knownServer->dataToken());
221 }
222 ++iValueServer;
223 }
224 }
225 }
226}
227
228void RooFitDriver::setData(RooAbsData const &data, std::string const &rangeName, RooSimultaneous const *simPdf,
229 bool skipZeroWeights, bool takeGlobalObservablesFromData)
230{
231 std::stack<std::vector<double>>{}.swap(_vectorBuffers);
232 setData(RooFit::BatchModeDataHelpers::getDataSpans(data, rangeName, simPdf, skipZeroWeights,
233 takeGlobalObservablesFromData, _vectorBuffers));
234}
235
237{
238 // Iterate over the given data spans and add them to the data map. Check if
239 // they are used in the computation graph. If yes, add the span to the data
240 // map and set the node info accordingly.
241 std::size_t totalSize = 0;
242 std::size_t iNode = 0;
243 for (auto &info : _nodes) {
244 if (info.buffer) {
245 delete info.buffer;
246 info.buffer = nullptr;
247 }
248 auto found = dataSpans.find(info.absArg->namePtr());
249 if (found != dataSpans.end()) {
250 info.absArg->setDataToken(iNode);
251 _dataMapCPU.set(info.absArg, found->second);
252 info.outputSize = found->second.size();
253 info.fromDataset = true;
254 info.isDirty = false;
255 totalSize += info.outputSize;
256 } else {
257 info.outputSize = 1;
258 info.fromDataset = false;
259 info.isDirty = true;
260 }
261 ++iNode;
262 }
263
266
267 for (auto &info : _nodes) {
268 // In principle we don't need dirty flag propagation because the driver
269 // takes care of deciding which node needs to be re-evaluated. However,
270 // disabling it also for scalar mode results in very long fitting times
271 // for specific models (test 14 in stressRooFit), which still needs to be
272 // understood. TODO.
273 if (!info.isScalar()) {
274 setOperMode(info.absArg, RooAbsArg::ADirty);
275 }
276 }
277
278 // Extra steps for initializing in cuda mode
280 return;
281
282 // copy observable data to the GPU
283 // TODO: use separate buffers here
284 _cudaMemDataset = static_cast<double *>(RooBatchCompute::dispatchCUDA->cudaMalloc(totalSize * sizeof(double)));
285 size_t idx = 0;
286 for (auto &info : _nodes) {
287 if (!info.fromDataset)
288 continue;
289 std::size_t size = info.outputSize;
290 if (size == 1) {
291 // Scalar observables from the data don't need to be copied to the GPU
292 _dataMapCUDA.set(info.absArg, _dataMapCPU.at(info.absArg));
293 } else {
294 _dataMapCUDA.set(info.absArg, {_cudaMemDataset + idx, size});
296 size * sizeof(double));
297 idx += size;
298 }
299 }
300
301 markGPUNodes();
302}
303
304RooFitDriver::~RooFitDriver()
305{
306 for (auto &info : _nodes) {
307 info.absArg->resetDataToken();
308 }
309
310 if (_batchMode == RooFit::BatchModeOption::Cuda) {
311 RooBatchCompute::dispatchCUDA->cudaFree(_cudaMemDataset);
312 }
313}
314
315std::vector<double> RooFitDriver::getValues()
316{
317 getVal();
318 // We copy the data to the output vector
319 auto dataSpan = _dataMapCPU.at(&topNode());
320 std::vector<double> out;
321 out.reserve(dataSpan.size());
322 for (auto const &x : dataSpan) {
323 out.push_back(x);
324 }
325 return out;
326}
327
328void RooFitDriver::computeCPUNode(const RooAbsArg *node, NodeInfo &info)
329{
330 using namespace Detail;
331
332 auto nodeAbsReal = static_cast<RooAbsReal const *>(node);
333
334 const std::size_t nOut = info.outputSize;
335
336 double *buffer = nullptr;
337 if (nOut == 1) {
338 buffer = &info.scalarBuffer;
339 if (_batchMode == RooFit::BatchModeOption::Cuda) {
340 _dataMapCUDA.set(node, {buffer, nOut});
341 }
342 } else {
343 if (!info.hasLogged && _batchMode == RooFit::BatchModeOption::Cuda) {
344 RooAbsArg const &arg = *info.absArg;
345 oocoutI(&arg, FastEvaluations) << "The argument " << arg.ClassName() << "::" << arg.GetName()
346 << " could not be evaluated on the GPU because the class doesn't support it. "
347 "Consider requesting or implementing it to benefit from a speed up."
348 << std::endl;
349 info.hasLogged = true;
350 }
351 if (!info.buffer) {
352 info.buffer = info.copyAfterEvaluation ? _bufferManager.makePinnedBuffer(nOut, info.stream)
353 : _bufferManager.makeCpuBuffer(nOut);
354 }
355 buffer = info.buffer->cpuWritePtr();
356 }
357 _dataMapCPU.set(node, {buffer, nOut});
358 nodeAbsReal->computeBatch(nullptr, buffer, nOut, _dataMapCPU);
359 if (info.copyAfterEvaluation) {
360 _dataMapCUDA.set(node, {info.buffer->gpuReadPtr(), nOut});
361 if (info.event) {
363 }
364 }
365}
366
367/// Process a variable in the computation graph. This is a separate non-inlined
368/// function such that we can see in performance profiles how long this takes.
369void RooFitDriver::processVariable(NodeInfo &nodeInfo)
370{
371 RooAbsArg *node = nodeInfo.absArg;
372 auto *var = static_cast<RooRealVar const *>(node);
373 if (nodeInfo.lastSetValCount != var->valueResetCounter()) {
374 nodeInfo.lastSetValCount = var->valueResetCounter();
375 for (NodeInfo *clientInfo : nodeInfo.clientInfos) {
376 clientInfo->isDirty = true;
377 }
378 computeCPUNode(node, nodeInfo);
379 nodeInfo.isDirty = false;
380 }
381}
382
383/// Flags all the clients of a given node dirty. This is a separate non-inlined
384/// function such that we can see in performance profiles how long this takes.
385void RooFitDriver::setClientsDirty(NodeInfo &nodeInfo)
386{
387 for (NodeInfo *clientInfo : nodeInfo.clientInfos) {
388 clientInfo->isDirty = true;
389 }
390}
391
392/// Returns the value of the top node in the computation graph
393double RooFitDriver::getVal()
394{
395 ++_getValInvocations;
396
397 if (_batchMode == RooFit::BatchModeOption::Cuda) {
398 return getValHeterogeneous();
399 }
400
401 for (auto &nodeInfo : _nodes) {
402 if (!nodeInfo.fromDataset) {
403 if (nodeInfo.isVariable) {
404 processVariable(nodeInfo);
405 } else {
406 if (nodeInfo.isDirty) {
407 setClientsDirty(nodeInfo);
408 computeCPUNode(nodeInfo.absArg, nodeInfo);
409 nodeInfo.isDirty = false;
410 }
411 }
412 }
413 }
414
415 // return the final value
416 return _dataMapCPU.at(&topNode())[0];
417}
418
419/// Returns the value of the top node in the computation graph
420double RooFitDriver::getValHeterogeneous()
421{
422 for (auto &info : _nodes) {
423 info.remClients = info.clientInfos.size();
424 info.remServers = info.serverInfos.size();
425 if (info.buffer)
426 delete info.buffer;
427 info.buffer = nullptr;
428 }
429
430 // find initial GPU nodes and assign them to GPU
431 for (auto &info : _nodes) {
432 if (info.remServers == 0 && info.computeInGPU()) {
433 assignToGPU(info);
434 }
435 }
436
437 NodeInfo const &topNodeInfo = _nodes.back();
438 while (topNodeInfo.remServers != -2) {
439 // find finished GPU nodes
440 for (auto &info : _nodes) {
441 if (info.remServers == -1 && !RooBatchCompute::dispatchCUDA->streamIsActive(info.stream)) {
442 info.remServers = -2;
443 // Decrement number of remaining servers for clients and start GPU computations
444 for (auto *infoClient : info.clientInfos) {
445 --infoClient->remServers;
446 if (infoClient->computeInGPU() && infoClient->remServers == 0) {
447 assignToGPU(*infoClient);
448 }
449 }
450 for (auto *serverInfo : info.serverInfos) {
451 serverInfo->decrementRemainingClients();
452 }
453 }
454 }
455
456 // find next CPU node
457 auto it = _nodes.begin();
458 for (; it != _nodes.end(); it++) {
459 if (it->remServers == 0 && !it->computeInGPU())
460 break;
461 }
462
463 // if no CPU node available sleep for a while to save CPU usage
464 if (it == _nodes.end()) {
465 std::this_thread::sleep_for(std::chrono::milliseconds(1));
466 continue;
467 }
468
469 // compute next CPU node
470 NodeInfo &info = *it;
471 RooAbsArg const *node = info.absArg;
472 info.remServers = -2; // so that it doesn't get picked again
473
474 if (!info.fromDataset) {
475 computeCPUNode(node, info);
476 }
477
478 // Assign the clients that are computed on the GPU
479 for (auto *infoClient : info.clientInfos) {
480 if (--infoClient->remServers == 0 && infoClient->computeInGPU()) {
481 assignToGPU(*infoClient);
482 }
483 }
484 for (auto *serverInfo : info.serverInfos) {
485 serverInfo->decrementRemainingClients();
486 }
487 }
488
489 // return the final value
490 return _dataMapCPU.at(&topNode())[0];
491}
492
493/// Assign a node to be computed in the GPU. Scan it's clients and also assign them
494/// in case they only depend on GPU nodes.
495void RooFitDriver::assignToGPU(NodeInfo &info)
496{
497 using namespace Detail;
498
499 auto node = static_cast<RooAbsReal const *>(info.absArg);
500
501 info.remServers = -1;
502 // wait for every server to finish
503 for (auto *infoServer : info.serverInfos) {
504 if (infoServer->event)
506 }
507
508 const std::size_t nOut = info.outputSize;
509
510 double *buffer = nullptr;
511 if (nOut == 1) {
512 buffer = &info.scalarBuffer;
513 _dataMapCPU.set(node, {buffer, nOut});
514 } else {
515 info.buffer = info.copyAfterEvaluation ? _bufferManager.makePinnedBuffer(nOut, info.stream)
516 : _bufferManager.makeGpuBuffer(nOut);
517 buffer = info.buffer->gpuWritePtr();
518 }
519 _dataMapCUDA.set(node, {buffer, nOut});
520 node->computeBatch(info.stream, buffer, nOut, _dataMapCUDA);
522 if (info.copyAfterEvaluation) {
523 _dataMapCPU.set(node, {info.buffer->cpuReadPtr(), nOut});
524 }
525}
526
527/// Decides which nodes are assigned to the GPU in a CUDA fit.
528void RooFitDriver::markGPUNodes()
529{
530 for (auto &info : _nodes) {
531 info.copyAfterEvaluation = false;
532 // scalar nodes don't need copying
533 if (!info.isScalar()) {
534 for (auto *clientInfo : info.clientInfos) {
535 if (info.computeInGPU() != clientInfo->computeInGPU()) {
536 info.copyAfterEvaluation = true;
537 break;
538 }
539 }
540 }
541 }
542}
543
544void RooFitDriver::determineOutputSizes()
545{
546 for (auto &argInfo : _nodes) {
547 for (auto *serverInfo : argInfo.serverInfos) {
548 if (!argInfo.absArg->isReducerNode()) {
549 argInfo.outputSize = std::max(serverInfo->outputSize, argInfo.outputSize);
550 }
551 }
552 }
553}
554
555/// Temporarily change the operation mode of a RooAbsArg until the
556/// RooFitDriver gets deleted.
557void RooFitDriver::setOperMode(RooAbsArg *arg, RooAbsArg::OperMode opMode)
558{
559 if (opMode != arg->operMode()) {
560 _changeOperModeRAIIs.emplace(arg, opMode);
561 }
562}
563
564RooAbsReal &RooFitDriver::topNode() const
565{
566 return _topNode;
567}
568
569void RooFitDriver::print(std::ostream &os) const
570{
571 std::cout << "--- RooFit BatchMode evaluation ---\n";
572
573 std::vector<int> widths{9, 37, 20, 9, 10, 20};
574
575 auto printElement = [&](int iCol, auto const &t) {
576 const char separator = ' ';
577 os << separator << std::left << std::setw(widths[iCol]) << std::setfill(separator) << t;
578 os << "|";
579 };
580
581 auto printHorizontalRow = [&]() {
582 int n = 0;
583 for (int w : widths) {
584 n += w + 2;
585 }
586 for (int i = 0; i < n; i++) {
587 os << '-';
588 }
589 os << "|\n";
590 };
591
592 printHorizontalRow();
593
594 os << "|";
595 printElement(0, "Index");
596 printElement(1, "Name");
597 printElement(2, "Class");
598 printElement(3, "Size");
599 printElement(4, "From Data");
600 printElement(5, "1st value");
601 std::cout << "\n";
602
603 printHorizontalRow();
604
605 for (std::size_t iNode = 0; iNode < _nodes.size(); ++iNode) {
606 auto &nodeInfo = _nodes[iNode];
607 RooAbsArg *node = nodeInfo.absArg;
608
609 auto span = _dataMapCPU.at(node);
610
611 os << "|";
612 printElement(0, iNode);
613 printElement(1, node->GetName());
614 printElement(2, node->ClassName());
615 printElement(3, nodeInfo.outputSize);
616 printElement(4, nodeInfo.fromDataset);
617 printElement(5, span[0]);
618
619 std::cout << "\n";
620 }
621
622 printHorizontalRow();
623}
624
625RooArgSet RooFitDriver::getParameters() const
626{
627 RooArgSet parameters;
628 for (auto &nodeInfo : _nodes) {
629 if (!nodeInfo.fromDataset && nodeInfo.isVariable) {
630 parameters.add(*nodeInfo.absArg);
631 }
632 }
633 // Just like in RooAbsArg::getParameters(), we sort the parameters alphabetically.
634 parameters.sort();
635 return parameters;
636}
637
638RooAbsRealWrapper::RooAbsRealWrapper(std::unique_ptr<RooFitDriver> driver, std::string const &rangeName,
639 RooSimultaneous const *simPdf, bool takeGlobalObservablesFromData)
640 : RooAbsReal{"RooFitDriverWrapper", "RooFitDriverWrapper"},
641 _driver{std::move(driver)},
642 _topNode("topNode", "top node", this, _driver->topNode()),
643 _rangeName{rangeName},
644 _simPdf{simPdf},
645 _takeGlobalObservablesFromData{takeGlobalObservablesFromData}
646{
647}
648
650 : RooAbsReal{other, name},
651 _driver{other._driver},
652 _topNode("topNode", this, other._topNode),
653 _data{other._data},
654 _rangeName{other._rangeName},
655 _simPdf{other._simPdf},
656 _takeGlobalObservablesFromData{other._takeGlobalObservablesFromData}
657{
658}
659
660bool RooAbsRealWrapper::getParameters(const RooArgSet *observables, RooArgSet &outputSet,
661 bool /*stripDisconnected*/) const
662{
663 outputSet.add(_driver->getParameters());
664 if (observables) {
665 outputSet.remove(*observables);
666 }
667 // If we take the global observables as data, we have to return these as
668 // parameters instead of the parameters in the model. Otherwise, the
669 // constant parameters in the fit result that are global observables will
670 // not have the right values.
672 outputSet.replace(*_data->getGlobalObservables());
673 }
674 return false;
675}
676
678{
679 _data = &data;
680 _driver->setData(*_data, _rangeName, _simPdf, /*skipZeroWeights=*/true, _takeGlobalObservablesFromData);
681 return true;
682}
683
684} // namespace Experimental
685} // namespace ROOT
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define oocoutI(o, a)
#define oocxcoutI(o, a)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
char name[80]
Definition TGX11.cxx:110
virtual double const * gpuReadPtr() const =0
virtual double const * cpuReadPtr() const =0
RooAbsRealWrapper(std::unique_ptr< RooFitDriver > driver, std::string const &rangeName, RooSimultaneous const *simPdf, bool takeGlobalObservablesFromData)
std::shared_ptr< RooFitDriver > _driver
bool setData(RooAbsData &data, bool cloneData) override
bool getParameters(const RooArgSet *observables, RooArgSet &outputSet, bool stripDisconnected) const override
Fills a list with leaf nodes in the arg tree starting with ourself as top node that don't match any o...
std::map< RooFit::Detail::DataKey, RooSpan< const double > > DataSpansMap
RooFitDriver(const RooAbsReal &absReal, RooFit::BatchModeOption batchMode=RooFit::BatchModeOption::Cpu)
Construct a new RooFitDriver.
const RooFit::BatchModeOption _batchMode
void setOperMode(RooAbsArg *arg, RooAbsArg::OperMode opMode)
Temporarily change the operation mode of a RooAbsArg until the RooFitDriver gets deleted.
void syncDataTokens()
If there are servers with the same name that got de-duplicated in the _nodes list,...
RooFit::Detail::DataMap _dataMapCPU
RooFit::Detail::DataMap _dataMapCUDA
void setData(RooAbsData const &data, std::string const &rangeName="", RooSimultaneous const *simPdf=nullptr, bool skipZeroWeights=false, bool takeGlobalObservablesFromData=true)
std::vector< NodeInfo > _nodes
std::stack< std::vector< double > > _vectorBuffers
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition RooAbsArg.h:74
virtual bool canComputeBatchWithCuda() const
Definition RooAbsArg.h:573
virtual bool isReducerNode() const
Definition RooAbsArg.h:574
OperMode operMode() const
Query the operation mode of this node.
Definition RooAbsArg.h:481
A space to attach TBranches.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
virtual bool replace(const RooAbsArg &var1, const RooAbsArg &var2)
Replace var1 with var2 and return true for success.
void sort(bool reverse=false)
Sort collection using std::sort and name comparison.
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:59
RooArgSet const * getGlobalObservables() const
Returns snapshot of global observables stored in this data.
Definition RooAbsData.h:301
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition RooAbsReal.h:62
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
virtual void cudaEventRecord(cudaEvent_t *, cudaStream_t *)
virtual cudaEvent_t * newCudaEvent(bool)
virtual void cudaStreamWaitEvent(cudaStream_t *, cudaEvent_t *)
virtual bool streamIsActive(cudaStream_t *)
virtual void deleteCudaStream(cudaStream_t *)
virtual void deleteCudaEvent(cudaEvent_t *)
virtual void memcpyToCUDA(void *, const void *, size_t, cudaStream_t *=nullptr)
void set(RooAbsArg const *arg, RooSpan< const double > const &span)
Definition DataMap.h:88
RooSpan< const double > at(RooAbsArg const *arg, RooAbsArg const *caller=nullptr)
Definition DataMap.cxx:21
auto resize(std::size_t n)
Definition DataMap.h:86
static RooMsgService & instance()
Return reference to singleton instance.
RooRealVar represents a variable that can be changed from the outside.
Definition RooRealVar.h:40
RooSimultaneous facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:207
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
R__EXTERN RooBatchComputeInterface * dispatchCUDA
R__EXTERN RooBatchComputeInterface * dispatchCPU
This dispatch pointer points to an implementation of the compute library, provided one has been loade...
void init()
Inspect hardware capabilities, and load the optimal library for RooFit computations.
std::map< RooFit::Detail::DataKey, RooSpan< const double > > getDataSpans(RooAbsData const &data, std::string const &rangeName, RooSimultaneous const *simPdf, bool skipZeroWeights, bool takeGlobalObservablesFromData, std::stack< std::vector< double > > &buffers)
Extract all content from a RooFit datasets as a map of spans.
BatchModeOption
For setting the batch mode flag with the BatchMode() command argument to RooAbsPdf::fitTo()
void getSortedComputationGraph(RooAbsReal const &func, RooArgSet &out)
Get the topologically-sorted list of all nodes in the computation graph.
A struct used by the RooFitDriver to store information on the RooAbsArgs in the computation graph.
std::vector< NodeInfo * > serverInfos
std::vector< NodeInfo * > clientInfos
void decrementRemainingClients()
Check the servers of a node that has been computed and release it's resources if they are no longer n...