21#include <unordered_map>
45 std::unordered_map<KeyType, Entry>
entries;
46 std::unordered_map<KeyType, UndoRecord>
undo;
63 size_t spilled,
bool overflowed,
bool memoryLimited)
81 const auto sample =
static_cast<float>(double(emitted) / scale);
95 const float shortfall = granted ?
static_cast<float>(double(emitted) / double(granted)) :
cfg.
marginUp;
100 const float util = granted ?
float(
double(emitted) /
double(granted)) : 1.f;
120 std::lock_guard lock{mImpl->mutex};
121 mImpl->entries.clear();
123 mImpl->transactionActive =
false;
128 std::lock_guard lock{mImpl->mutex};
129 if (mImpl->transactionActive) {
130 throw std::logic_error{
"CapacityEstimator transaction already active"};
132 assert(mImpl->undo.empty());
133 mImpl->transactionActive =
true;
138 std::lock_guard lock{mImpl->mutex};
140 mImpl->transactionActive =
false;
145 std::lock_guard lock{mImpl->mutex};
146 if (!mImpl->transactionActive) {
149 for (
const auto& [
key, record] : mImpl->undo) {
150 if (record.existed) {
151 const auto current = mImpl->entries.find(
key);
152 assert(current != mImpl->entries.end());
153 current->second = record.previous;
155 mImpl->entries.erase(
key);
159 mImpl->transactionActive =
false;
167 std::lock_guard lock{mImpl->mutex};
168 const auto it = mImpl->entries.find(
key);
169 if (it == mImpl->entries.end() || it->second.statistics.samples == 0) {
170 return mImpl->cfg.floorSlots;
172 const auto&
e = it->second;
173 const double raw = double(
e.ratio) * scale * double(
e.margin);
174 if (!std::isfinite(
raw) ||
raw < 0.) {
175 return mImpl->cfg.floorSlots;
181 const size_t ceiling = std::max(mImpl->cfg.floorSlots,
static_cast<size_t>(
double(
e.statistics.maxEmitted) *
double(mImpl->cfg.marginMax)));
182 if (
raw >=
static_cast<double>(ceiling)) {
185 return std::max(mImpl->cfg.floorSlots,
static_cast<size_t>(std::ceil(
raw)));
190 std::lock_guard lock{mImpl->mutex};
191 const auto it = mImpl->entries.find(
key);
192 if (it == mImpl->entries.end() || it->second.statistics.maxEmitted == 0) {
193 return mImpl->cfg.floorSlots;
195 const auto&
e = it->second;
196 const double raw = double(
e.statistics.maxEmitted) * double(
e.margin);
197 if (!std::isfinite(
raw) ||
raw >=
static_cast<double>(std::numeric_limits<size_t>::max())) {
198 return std::numeric_limits<size_t>::max();
200 return std::max(mImpl->cfg.floorSlots,
static_cast<size_t>(std::ceil(
raw)));
208 std::lock_guard lock{mImpl->mutex};
209 const auto it = mImpl->entries.find(
key);
210 if (it == mImpl->entries.end() || it->second.statistics.samples == 0) {
213 const double raw = double(it->second.ratio) * scale;
214 return std::isfinite(
raw) &&
raw > 0. ?
raw : 0.;
219 std::lock_guard lock{mImpl->mutex};
220 const auto it = mImpl->entries.find(
key);
221 if (it == mImpl->entries.end()) {
224 return it->second.statistics;
232 std::lock_guard lock{mImpl->mutex};
233 mImpl->observe(
key, scale, capacityUsed, capacityUsed, emitted,
234 overflowed && emitted > capacityUsed ? emitted - capacityUsed : 0,
235 overflowed, memoryLimited);
239 size_t emitted,
size_t spilled,
bool overflowed,
bool memoryLimited)
244 std::lock_guard lock{mImpl->mutex};
245 mImpl->observe(
key, scale, requested, granted, emitted, spilled, overflowed, memoryLimited);
250 std::lock_guard lock{mImpl->mutex};
251 std::vector<KeyType>
keys;
252 keys.reserve(mImpl->entries.size());
253 for (
const auto& [
key, _] : mImpl->entries) {
257 const auto da = decodeKey(a);
258 const auto db = decodeKey(b);
259 return std::tie(da.site, da.iteration, da.variant, da.slot) <
260 std::tie(db.site, db.iteration, db.variant, db.slot);
265 LOGP(info,
"Printing CapacityEstimators:");
267 const auto&
value = mImpl->entries.at(
key);
270 LOGP(info,
"\tSite:{} | iter:{} | var:({},{}) | slot:{} | ratio:{} | margin:{} | maxEmitted:{} | samples:{} | low:{} | requested:{} | granted:{} | emitted:{} | spilled:{} | overflows:{}",
SlabSiteNames[decoded.site], decoded.iteration,
getVariantHigh(decoded.variant),
getVariantLow(decoded.variant), decoded.slot,
value.ratio,
value.margin,
statistics.
maxEmitted,
statistics.
samples,
statistics.
nLowStreak,
statistics.
requested,
statistics.
granted,
statistics.
emitted,
statistics.
spilled,
statistics.
overflowEvents);
Cross-timeframe output-size prediction.
std::vector< std::string > keys
o2::raw::RawFileWriter * raw
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char e
configStandalone Reconstruction rec_tpc float
void commitTransaction() noexcept
static constexpr int getVariantHigh(int variant) noexcept
void rollbackTransaction() noexcept
Statistics statistics(uint64_t key) const
size_t capacity(uint64_t key, double scale) const
size_t peakCapacity(uint64_t key) const
static constexpr int getVariantLow(int variant) noexcept
double expected(uint64_t key, double scale) const
void update(uint64_t key, double scale, size_t emitted, size_t capacityUsed, bool overflowed, bool memoryLimited)
static constexpr Decoded decodeKey(KeyType key) noexcept
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * value
GLboolean GLboolean GLboolean GLboolean a
uint32_t trackClusterIndicesSize noexcept
constexpr const char *const SlabSiteNames[SlabSite::NSlabSite]
float marginOverflowSlack
std::unordered_map< KeyType, Entry > entries
void observe(KeyType key, double scale, size_t requested, size_t granted, size_t emitted, size_t spilled, bool overflowed, bool memoryLimited)
std::unordered_map< KeyType, UndoRecord > undo
void checkpointBeforeUpdate(KeyType key)