ROOT   Reference Guide
RunContext.cxx
Go to the documentation of this file.
1// Author: Stephan Hageboeck, CERN Jul 2020
2
3/*****************************************************************************
4 * RooFit
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2020, Regents of the University of California *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
15 *****************************************************************************/
16
17/**
18 * \struct RooBatchCompute::RunContext
19 *
20 * This struct enables passing computation data around between elements of a computation graph.
21 *
22 * ### Separating data and computation graph
23 * The RunContext stores read-only spans to data that has already been computed.
24 * This can be data of the observables (which is constant during a fit)
25 * or intermediate computation results from evaluating PDFs or formulae for every point in a dataset.
26 * The latter may change as fit parameters change.
27 *
28 * Instead of storing information about these data *inside* nodes of the computation graph (requiring a change
29 * of their state, possibly violating const-correctness), this information is stored in RunContext::spans using
30 * the pointer of the element that produced those results as a key. In this way, one or multiple RunContext
31 * instances can be passed around when computations are running, leaving the objects of the computation graph
32 * invariant.
33 *
34 * ### Memory ownership model
35 * The RunContext can provide memory for temporary data, that is, data that can vanish after a fit converges. Using
36 * RunContext::makeBatch(), a suitable amount of memory is allocated to store computation results.
37 * When intermediate data are cleared, this memory is *not freed*. In this way, temporary data can be invalidated
38 * when fit parameters change, but the memory is only allocated once per fit.
39 *
40 * When a RunContext goes out of scope, the memory is freed. That means that in between fit cycles, a RunContext should
41 * be cleared using clear(), or single results should be invalidated by removing these from RunContext::spans.
42 * The RunContext object should be destroyed only *after* a fit completes.
43 */
44
45
46#include "RunContext.h"
47#include "RooBatchCompute.h"
48
49#include <limits>
50#include <iostream>
51
52class RooAbsArg;
53
54namespace RooBatchCompute {
55
56/// Check if there is a span of data corresponding to the object passed as owner.
58 const auto item = spans.find(owner);
59 if (item != spans.end())
60 return item->second;
61
62 return {};
63}
64
65
66/// Check if there is a writable span of data corresponding to the object passed as owner.
67/// The span can be used both for reading and writing.
69 auto item = ownedMemory.find(owner);
70 if (item != ownedMemory.end()) {
71 assert(spans.count(owner) > 0); // If we can write, the span must also be registered for reading
72 return RooSpan<double>(item->second);
73 }
74
75 return {};
76}
77
78
79/// Create a writable batch. If the RunContext already owns memory for the object
80/// owner, just resize the memory. If it doesn't exist yet, allocate it.
81/// \warning The memory will be uninitialised, so every entry **must** be overwritten.
82/// On first use, all values are initialised to NaN to help detect such errors.
83///
84/// A read-only reference to the memory will be stored in spans.
85/// \param owner RooFit object whose value should be written into the memory.
86/// \param size Requested size of the span.
87/// \return A writeable RooSpan of the requested size, whose memory is owned by
88/// the RunContext.
90 auto item = ownedMemory.find(owner);
91 if (item == ownedMemory.end() || item->second.size() != size) {
92 std::vector<double>& data = ownedMemory[owner];
93 data.resize(size, std::numeric_limits<double>::quiet_NaN());
94#ifndef NDEBUG
95 data.assign(size, std::numeric_limits<double>::quiet_NaN());
96#endif
97 spans[owner] = RooSpan<const double>(data);
98 return {data};
99 }
100
101 spans[owner] = RooSpan<const double>(item->second);
102 return {item->second};
103}
104
106 spans.clear();
107 rangeName = nullptr;
108}
109
110}
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:74
A simple container to hold a batch of data values.
Definition: RooSpan.h:34
Namespace for dispatching RooFit computations to various backends.
RooSpan< double > makeBatch(const RooAbsArg *owner, std::size_t size)
Create a writable batch.
Definition: RunContext.cxx:89
void clear()
Clear all computation results without freeing memory.
Definition: RunContext.cxx:105
std::map< const RooAbsArg *, std::vector< double > > ownedMemory
Memory owned by this struct. It is associated to nodes in the computation graph using their pointers.
Definition: RunContext.h:56
RooSpan< const double > getBatch(const RooArgProxy &proxy) const
std::map< const RooAbsArg *, RooSpan< const double > > spans
Once an object has computed its value(s), the span pointing to the results is registered here.
Definition: RunContext.h:52
RooSpan< double > getWritableBatch(const RooAbsArg *owner)
Check if there is a writable span of data corresponding to the object passed as owner.
Definition: RunContext.cxx:68