Logo ROOT  
Reference Guide
BatchData.cxx
Go to the documentation of this file.
1// Author: Stephan Hageboeck, CERN 12 Apr 2019
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-2019, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17#include "BatchData.h"
18
19#include <ostream>
20#include <iomanip>
21
22namespace BatchHelpers {
23
24///////////////////////////////////////////////////////////////////////////
25/// Return the status of the batch starting at `begin`.
26/// \param[in] begin Start of the batch.
27/// \param[in] normSet Optional normSet pointer to distinguish differently normalised computations.
28/// \param[in] ownerTag Optional owner tag. This avoids reusing batch memory for e.g. getVal() and getLogVal().
29/// \return One state of the Status_t enum.
30BatchData::Status_t BatchData::status(std::size_t begin, const RooArgSet* const normSet, Tag_t ownerTag) const {
31 if (_foreignData)
32 return begin < _foreignData->size() ? kReadyAndConstant : kNoBatch;
33 else if (_ownedBatches.empty())
34 return kNoBatch;
35
36 auto item = _ownedBatches.find(std::make_tuple(begin, normSet, ownerTag));
37 if (item != _ownedBatches.end()) {
38 return item->second.status;
39 } else if ( (item = findEnclosingBatch(begin, normSet, ownerTag)) != _ownedBatches.end() ){
40 // We didn't find a batch that starts with `begin`, but `begin` might be
41 // inside of an existing batch. This search is slower.
42 return item->second.status;
43 }
44
45 return kNoBatch;
46}
47
48
49///////////////////////////////////////////////////////////////////////////
50/// Set the status of a batch with the given properties.
51///
52/// The status of foreign read-only data will never change.
53/// \param[in] begin Begin index of the batch.
54/// \param[in] size Size of the batch for checking that enough data is available.
55/// \param[in] normSet Optional normSet pointer to destinguish differently normalised computations.
56/// \param[in] ownerTag Optional owner tag. This avoids reusing batch memory for e.g. getVal() and getLogVal().
57/// \return True if status successfully set, false if no such batch / not writable.
58bool BatchData::setStatus(std::size_t begin, std::size_t size, Status_t stat,
59 const RooArgSet* const normSet, Tag_t ownerTag) {
60 if (_foreignData)
61 return false;
62
63 auto item = _ownedBatches.find(std::make_tuple(begin, normSet, ownerTag));
64 if (item == _ownedBatches.end() || size != item->second.data.size())
65 return false;
66
67 item->second.status = stat;
68 return true;
69}
70
71
72///////////////////////////////////////////////////////////////////////////
73/// Retrieve an existing batch.
74///
75/// \param[in] begin Begin index of the batch.
76/// \param[in] size Requested size. Batch may come out smaller than this.
77/// \param[in] normSet Optional normSet pointer to distinguish differently normalised computations.
78/// \param[in] ownerTag Optional owner tag. This avoids reusing batch memory for e.g. getVal() and getLogVal().
79/// \return Non-mutable contiguous batch data.
80RooSpan<const double> BatchData::getBatch(std::size_t begin, std::size_t maxSize,
81 const RooArgSet* const normSet, Tag_t ownerTag) const {
82 if (_foreignData) {
83 if (begin >= _foreignData->size())
84 return {};
85
86 const double* dataBegin = &*(_foreignData->begin()+begin);
87 maxSize = std::min(maxSize, _foreignData->size() - begin);
88 return RooSpan<const double>(dataBegin, maxSize);
89 }
90
91 if (_ownedBatches.empty())
92 return {};
93
94 const auto item = _ownedBatches.find(std::make_tuple(begin, normSet, ownerTag));
95 if (item == _ownedBatches.end()) {
96 // If requesting a batch inside another, a slower search algorithm must be used
97 return createSpanInsideExistingBatch(begin, maxSize, normSet, ownerTag);
98 }
99
100 const auto& batch = item->second;
101 maxSize = std::min(maxSize, batch.data.size() - (begin-batch.begin));
102
103 return RooSpan<const double>(batch.data.data(), maxSize);
104}
105
106
107////////////////////////////////////////////////////////////////////////////////
108/// Make a batch and return a span pointing to the pdf-local memory.
109/// The batch status is switched to `kWriting`, but the batch is not initialised.
110/// If a batch at this start point exists, the storage will be resized to fit the required
111/// size.
112///
113/// \param[in] begin Begin of the batch.
114/// \param[in] batchSize Size of the batch.
115/// \param[in] normSet Optional normSet pointer to distinguish differently normalised computations.
116/// \param[in] ownerTag Optional owner tag. This avoids reusing batch memory for e.g. getVal() and getLogVal().
117/// \return An uninitialised RooSpan starting at event `begin`.
118RooSpan<double> BatchData::makeWritableBatchUnInit(std::size_t begin, std::size_t batchSize,
119 const RooArgSet* const normSet, Tag_t ownerTag) {
120 auto item = _ownedBatches.find(std::make_tuple(begin, normSet, ownerTag));
121 if (item == _ownedBatches.end()) {
122 auto inserted = _ownedBatches.emplace(std::piecewise_construct,
123 std::forward_as_tuple(begin, normSet, ownerTag),
124 std::forward_as_tuple(Batch{begin, std::vector<double>(batchSize), kWriting}));
125 return RooSpan<double>(inserted.first->second.data);
126 }
127
128 Batch& batch = item->second;
129 batch.status = kWriting;
130 if (batch.data.size() != batchSize) {
131 batch.data.resize(batchSize);
132 }
133
134 return RooSpan<double>(batch.data);
135}
136
137
138////////////////////////////////////////////////////////////////////////////////
139/// Make a batch and return a span pointing to the pdf-local memory.
140/// Calls makeWritableBatchUnInit() and initialises the memory.
141///
142/// \param[in] begin Begin of the batch.
143/// \param[in] batchSize End of the batch (not included)
144/// \param[in] value Value to initialise with (defaults to 0.).
145/// \param[in] normSet Optional normSet pointer to distinguish differently normalised computations.
146/// \param[in] ownerTag Optional owner tag. This avoids reusing batch memory for e.g. getVal() and getLogVal().
147/// \return An initialised RooSpan starting at event `begin`.
148RooSpan<double> BatchData::makeWritableBatchInit(std::size_t begin, std::size_t batchSize, double value,
149 const RooArgSet* const normSet, Tag_t ownerTag) {
150 auto batch = makeWritableBatchUnInit(begin, batchSize, normSet, ownerTag);
151 for (auto& elm : batch) {
152 elm = value;
153 }
154
155 return batch;
156}
157
158////////////////////////////////////////////////////////////////////////////////
159/// Attach a foreign storage. Batches coming from this storage will be read only.
160void BatchData::attachForeignStorage(const std::vector<double>& vec) {
161 clear();
162
163 _foreignData = &vec;
164 _ownedBatches.clear();
165}
166
167
168////////////////////////////////////////////////////////////////////////////////
169/// Print to given output stream.
170void BatchData::print(std::ostream& os, const std::string& indent) const {
171 os << indent << "Batch data access";
172 if (_ownedBatches.empty() && !_foreignData) {
173 os << " not initialised." << std::endl;
174 return;
175 }
176
177 using std::setw;
178
179 os << " with " << (_foreignData ? "(foreign)" : "(owned)") << " data:";
180 os << "\n" << indent << std::right << std::setw(8) << "Batch #" << std::setw(8) << "Start"
181 << std::setw(7) << "Status";
182
183 unsigned int i=0;
184 for (auto item : _ownedBatches) {
185 auto key = item.first;
186 const Batch& batch = item.second;
187
188 os << "\n" << indent
189 << std::setw(8) << i << std::setw(8) << std::get<0>(key) << std::setw(8) << std::get<2>(key)
190 << std::setw(7) << batch.status << ": {";
191 for (unsigned int j=0; j < 5 && j < batch.data.size(); ++j) {
192 os << batch.data[j] << ", ";
193 }
194 os << "...}";
195 }
196 os << std::resetiosflags(std::ios::adjustfield) << std::endl;
197}
198
199////////////////////////////////////////////////////////////////////////////////
200/// Find the batch that contains the event with number `evt`.
201/// \param[in] evt Index of the event to find.
202/// \param[in] normSet Optional normalisation set defining what this batch was normalised to.
203/// \param[in] ownerTag Optional owner tag to prevent sharing of memory between e.g. getVal() and getLogVal().
204BatchData::Map_t::const_iterator BatchData::findEnclosingBatch(std::size_t evt,
205 const RooArgSet* const normSet, Tag_t ownerTag) const {
206 for (auto it = _ownedBatches.cbegin(); it != _ownedBatches.cend(); ++it) {
207 if (normSet == std::get<1>(it->first)
208 && ownerTag == std::get<2>(it->first)
209 && it->second.inBatch(evt))
210 return it;
211 }
212
213 return _ownedBatches.end();
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// Create a span pointing to existing batch memory.
218/// \param[in] begin Index of the event to find.
219/// \param[in] batchSize Requested size of the span. May come out smaller if no more data exists.
220/// \param[in] normSet Optional normalisation set defining what this batch was normalised to.
221/// \param[in] ownerTag Optional owner tag to prevent sharing of memory between e.g. getVal() and getLogVal().
222/// \return RooSpan pointing inside an existing batch or an empty span if no such batch.
224 const RooArgSet* const normSet, Tag_t ownerTag) const {
225 for (auto it = _ownedBatches.cbegin(); it != _ownedBatches.cend(); ++it) {
226 if (normSet == std::get<1>(it->first)
227 && ownerTag == std::get<2>(it->first)
228 && it->second.inBatch(begin))
229 return it->second.makeSpan(begin, batchSize);
230 }
231
232 return {};
233}
234
235}
static void indent(ostringstream &buf, int indent_level)
bool setStatus(std::size_t begin, std::size_t size, Status_t stat, const RooArgSet *const normSet=nullptr, Tag_t ownerTag=kUnspecified)
Set the status of a batch with the given properties.
Definition: BatchData.cxx:58
RooSpan< const double > getBatch(std::size_t begin, std::size_t maxSize, const RooArgSet *const normSet=nullptr, Tag_t ownerTag=kUnspecified) const
Retrieve an existing batch.
Definition: BatchData.cxx:80
RooSpan< double > makeWritableBatchUnInit(std::size_t begin, std::size_t batchSize, const RooArgSet *const normSet=nullptr, Tag_t ownerTag=kUnspecified)
Make a batch and return a span pointing to the pdf-local memory.
Definition: BatchData.cxx:118
void clear()
Discard all storage.
Definition: BatchData.h:45
void print(std::ostream &os, const std::string &indent) const
Print to given output stream.
Definition: BatchData.cxx:170
Status_t
Status of the batch.
Definition: BatchData.h:34
RooSpan< const double > createSpanInsideExistingBatch(std::size_t begin, std::size_t batchSize, const RooArgSet *const normSet, Tag_t ownerTag) const
Create a span pointing to existing batch memory.
Definition: BatchData.cxx:223
const std::vector< double > * _foreignData
Definition: BatchData.h:111
Map_t::const_iterator findEnclosingBatch(std::size_t evt, const RooArgSet *const normSet, Tag_t ownerTag) const
Find the batch that contains the event with number evt.
Definition: BatchData.cxx:204
Status_t status(std::size_t begin, const RooArgSet *const normSet=nullptr, Tag_t ownerTag=kUnspecified) const
Return the status of the batch starting at begin.
Definition: BatchData.cxx:30
RooSpan< double > makeWritableBatchInit(std::size_t begin, std::size_t batchSize, double value, const RooArgSet *const normSet=nullptr, Tag_t ownerTag=kUnspecified)
Make a batch and return a span pointing to the pdf-local memory.
Definition: BatchData.cxx:148
void attachForeignStorage(const std::vector< double > &vec)
Attach a foreign storage. Batches coming from this storage will be read only.
Definition: BatchData.cxx:160
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
A simple container to hold a batch of data values.
Definition: RooSpan.h:32
std::vector< double > data
Definition: BatchData.h:82