forked from acts-project/acts
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSequencer.hpp
More file actions
198 lines (166 loc) · 6.84 KB
/
Sequencer.hpp
File metadata and controls
198 lines (166 loc) · 6.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
#pragma once
#include "Acts/Utilities/Logger.hpp"
#include "ActsExamples/Framework/DataHandle.hpp"
#include "ActsExamples/Framework/IAlgorithm.hpp"
#include "ActsExamples/Framework/IContextDecorator.hpp"
#include "ActsExamples/Framework/IReader.hpp"
#include "ActsExamples/Framework/IWriter.hpp"
#include "ActsExamples/Framework/SequenceElement.hpp"
#include "ActsExamples/Framework/WhiteBoard.hpp"
#include "ActsExamples/Utilities/tbbWrap.hpp"
#include "ActsPlugins/FpeMonitoring/FpeMonitor.hpp"
#include <cstddef>
#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
#include <tbb/enumerable_thread_specific.h>
namespace ActsExamples {
using IterationCallback = void (*)();
/// Custom exception class so FPE failures can be caught
class FpeFailure : public std::runtime_error {
using std::runtime_error::runtime_error;
};
class SequenceConfigurationException : public std::runtime_error {
public:
explicit SequenceConfigurationException(const std::string &message)
: std::runtime_error{"Sequence configuration error: " + message} {}
};
/// A simple algorithm sequencer for event processing.
///
/// This is the backbone of the framework. It reads events from file,
/// runs the configured algorithms for each event, and writes selected data
/// back to a file.
class Sequencer {
public:
struct FpeMask {
std::string file;
std::pair<std::size_t, std::size_t> lines;
ActsPlugins::FpeType type{};
std::size_t count = 0;
};
struct Config {
/// number of events to skip at the beginning
std::size_t skip = 0;
/// number of events to process, std::numeric_limits<std::size_t>::max() to
/// process all available events
std::optional<std::size_t> events = std::nullopt;
/// logging level
Acts::Logging::Level logLevel = Acts::Logging::INFO;
/// number of parallel threads to run, negative for automatic
/// determination
int numThreads = -1;
/// output directory for timing information, empty for working directory
std::string outputDir;
/// output name of the timing file
std::string outputTimingFile = "timing.csv";
/// Callback that is invoked in the event loop.
/// @warning This function can be called from multiple threads and should therefore be thread-safe
IterationCallback iterationCallback = []() {};
/// If true, FPEs are tracked.
bool trackFpes = true;
/// If true, FPEs are masked and reported.
std::vector<FpeMask> fpeMasks{};
/// If true, the first FPE encountered makes Sequencer::run() fail.
bool failOnFirstFpe = false;
/// If false, unmasked FPEs are reported but do not make Sequencer::run()
/// fail.
bool failOnUnmaskedFpe = true;
/// The number of stack frames to include in the FPE report.
std::size_t fpeStackTraceLength = 8;
};
explicit Sequencer(const Config &cfg);
/// Add a context decorator to the set of context decorators.
///
/// @throws std::invalid_argument if the decorator is NULL.
void addContextDecorator(std::shared_ptr<IContextDecorator> decorator);
/// Add a reader to the set of readers.
///
/// @throws std::invalid_argument if the reader is NULL.
void addReader(std::shared_ptr<IReader> reader);
/// Append an algorithm to the sequence of algorithms.
///
/// @throws std::invalid_argument if the algorithm is NULL.
void addAlgorithm(std::shared_ptr<IAlgorithm> algorithm);
/// Append a sequence element to the sequence
///
/// @throws std::invalid_argument if the element is NULL.
void addElement(const std::shared_ptr<SequenceElement> &element);
/// Add a writer to the set of writers.
///
/// @throws std::invalid_argument if the writer is NULL.
void addWriter(std::shared_ptr<IWriter> writer);
/// Add an alias to the whiteboard.
void addWhiteboardAlias(const std::string &aliasName,
const std::string &objectName);
ActsPlugins::FpeMonitor::Result fpeResult() const;
/// Run the event loop.
///
/// @return status code compatible with the `main()` return code
/// @returns EXIT_SUCCESS when everying worked without problems
/// @returns EXIT_FAILURE if something went wrong
///
/// @note If the number of events to process is undefined, the sequencer
/// will process events until the first reader signals the end-of-file. If
/// given, it sets an upper bound.
///
/// This function is intended to be run as the last thing in the tool
/// main function and its return value can be used directly as the program
/// return value, i.e.
///
/// int main(int argc, char* argv[])
/// {
/// Sequencer::Config cfg;
/// ... // configure the sequencer
/// Sequencer seq;
/// ... // set up the algorithms
/// return seq.run();
/// }
///
/// This will run the start-of-run hook for all configured services, run all
/// configured readers, algorithms, and writers for each event, then invoke
/// the end-of-run hook for all configured writers.
int run();
/// Get const access to the config
const Config &config() const { return m_cfg; }
private:
/// List of all configured algorithm names.
std::vector<std::string> listAlgorithmNames() const;
/// Determine range of (requested) events;
/// [std::numeric_limits<std::size_t>::max(),
/// std::numeric_limits<std::size_t>::max()) for error.
std::pair<std::size_t, std::size_t> determineEventsRange() const;
std::pair<std::string, std::size_t> fpeMaskCount(
const boost::stacktrace::stacktrace &st, ActsPlugins::FpeType type) const;
void fpeReport() const;
struct SequenceElementWithFpeResult {
std::shared_ptr<SequenceElement> sequenceElement;
std::unique_ptr<
tbb::enumerable_thread_specific<ActsPlugins::FpeMonitor::Result>>
fpeResult = std::make_unique<
tbb::enumerable_thread_specific<ActsPlugins::FpeMonitor::Result>>();
};
Config m_cfg;
tbbWrap::task_arena m_taskArena;
std::vector<std::shared_ptr<IContextDecorator>> m_decorators;
std::vector<std::shared_ptr<IReader>> m_readers;
std::vector<std::shared_ptr<IWriter>> m_writers;
std::vector<SequenceElementWithFpeResult> m_sequenceElements;
std::unique_ptr<const Acts::Logger> m_logger;
WhiteBoard::AliasMapType m_whiteboardObjectAliases;
DataHandleBase::StateMapType m_whiteBoardState;
std::atomic<std::size_t> m_nSkippedEvents = 0;
std::atomic<std::size_t> m_nUnmaskedFpe = 0;
const Acts::Logger &logger() const { return *m_logger; }
};
std::ostream &operator<<(std::ostream &os, const Sequencer::FpeMask &m);
} // namespace ActsExamples