Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 08:07:19

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2017 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Plugins/FpeMonitoring/FpeMonitor.hpp"
0012 #include "ActsExamples/Framework/IAlgorithm.hpp"
0013 #include "ActsExamples/Framework/IContextDecorator.hpp"
0014 #include "ActsExamples/Framework/IReader.hpp"
0015 #include "ActsExamples/Framework/IWriter.hpp"
0016 #include "ActsExamples/Framework/SequenceElement.hpp"
0017 #include "ActsExamples/Utilities/tbbWrap.hpp"
0018 #include <Acts/Utilities/Logger.hpp>
0019 
0020 #include <cstddef>
0021 #include <memory>
0022 #include <optional>
0023 #include <stdexcept>
0024 #include <string>
0025 #include <typeinfo>
0026 #include <unordered_map>
0027 #include <utility>
0028 #include <vector>
0029 
0030 #include <tbb/enumerable_thread_specific.h>
0031 
0032 namespace ActsExamples {
0033 class DataHandleBase;
0034 class IAlgorithm;
0035 class IContextDecorator;
0036 class IReader;
0037 class IWriter;
0038 class SequenceElement;
0039 
0040 using IterationCallback = void (*)();
0041 
0042 /// Custom exception class so FPE failures can be caught
0043 class FpeFailure : public std::runtime_error {
0044   using std::runtime_error::runtime_error;
0045 };
0046 
0047 class SequenceConfigurationException : public std::runtime_error {
0048  public:
0049   SequenceConfigurationException()
0050       : std::runtime_error{"Sequence configuration error"} {}
0051 };
0052 
0053 /// A simple algorithm sequencer for event processing.
0054 ///
0055 /// This is the backbone of the framework. It reads events from file,
0056 /// runs the configured algorithms for each event, and writes selected data
0057 /// back to a file.
0058 class Sequencer {
0059  public:
0060   struct FpeMask {
0061     std::string file;
0062     std::pair<std::size_t, std::size_t> lines;
0063     Acts::FpeType type;
0064     std::size_t count;
0065   };
0066 
0067   struct Config {
0068     /// number of events to skip at the beginning
0069     std::size_t skip = 0;
0070     /// number of events to process, std::numeric_limits<std::size_t>::max() to
0071     /// process all available events
0072     std::optional<std::size_t> events = std::nullopt;
0073     /// logging level
0074     Acts::Logging::Level logLevel = Acts::Logging::INFO;
0075     /// number of parallel threads to run, negative for automatic
0076     /// determination
0077     int numThreads = -1;
0078     /// output directory for timing information, empty for working directory
0079     std::string outputDir;
0080     /// output name of the timing file
0081     std::string outputTimingFile = "timing.csv";
0082     /// Callback that is invoked in the event loop.
0083     /// @warning This function can be called from multiple threads and should therefore be thread-safe
0084     IterationCallback iterationCallback = []() {};
0085     /// Run data flow consistency checks
0086     /// Defaults to false right now until all components are migrated
0087     bool runDataFlowChecks = true;
0088 
0089     bool trackFpes = true;
0090     std::vector<FpeMask> fpeMasks{};
0091     bool failOnFirstFpe = false;
0092     std::size_t fpeStackTraceLength = 8;
0093   };
0094 
0095   Sequencer(const Config &cfg);
0096 
0097   /// Add a context decorator to the set of context decorators.
0098   ///
0099   /// @throws std::invalid_argument if the decorator is NULL.
0100   void addContextDecorator(std::shared_ptr<IContextDecorator> decorator);
0101 
0102   /// Add a reader to the set of readers.
0103   ///
0104   /// @throws std::invalid_argument if the reader is NULL.
0105   void addReader(std::shared_ptr<IReader> reader);
0106 
0107   /// Append an algorithm to the sequence of algorithms.
0108   ///
0109   /// @throws std::invalid_argument if the algorithm is NULL.
0110   void addAlgorithm(std::shared_ptr<IAlgorithm> algorithm);
0111 
0112   /// Append a sequence element to the sequence
0113   ///
0114   /// @throws std::invalid_argument if the element is NULL.
0115   void addElement(const std::shared_ptr<SequenceElement> &element);
0116 
0117   /// Add a writer to the set of writers.
0118   ///
0119   /// @throws std::invalid_argument if the writer is NULL.
0120   void addWriter(std::shared_ptr<IWriter> writer);
0121 
0122   /// Add an alias to the whiteboard.
0123   void addWhiteboardAlias(const std::string &aliasName,
0124                           const std::string &objectName);
0125 
0126   Acts::FpeMonitor::Result fpeResult() const;
0127 
0128   /// Run the event loop.
0129   ///
0130   /// @return status code compatible with the `main()` return code
0131   /// @returns EXIT_SUCCESS when everying worked without problems
0132   /// @returns EXIT_FAILURE if something went wrong
0133   ///
0134   /// @note If the number of events to process is undefined, the sequencer
0135   /// will process events until the first reader signals the end-of-file. If
0136   /// given, it sets an upper bound.
0137   ///
0138   /// This function is intended to be run as the last thing in the tool
0139   /// main function and its return value can be used directly as the program
0140   /// return value, i.e.
0141   ///
0142   ///     int main(int argc, char* argv[])
0143   ///     {
0144   ///         Sequencer::Config cfg;
0145   ///         ... // configure the sequencer
0146   ///         Sequencer seq;
0147   ///         ... // set up the algorithms
0148   ///         return seq.run();
0149   ///     }
0150   ///
0151   /// This will run the start-of-run hook for all configured services, run all
0152   /// configured readers, algorithms, and writers for each event, then invoke
0153   /// the end-of-run hook for all configured writers.
0154   int run();
0155 
0156   /// Get const access to the config
0157   const Config &config() const { return m_cfg; }
0158 
0159  private:
0160   /// List of all configured algorithm names.
0161   std::vector<std::string> listAlgorithmNames() const;
0162   /// Determine range of (requested) events;
0163   /// [std::numeric_limits<std::size_t>::max(),
0164   /// std::numeric_limits<std::size_t>::max()) for error.
0165   std::pair<std::size_t, std::size_t> determineEventsRange() const;
0166 
0167   std::pair<std::string, std::size_t> fpeMaskCount(
0168       const boost::stacktrace::stacktrace &st, Acts::FpeType type) const;
0169 
0170   void fpeReport() const;
0171 
0172   struct SequenceElementWithFpeResult {
0173     std::shared_ptr<SequenceElement> sequenceElement;
0174     tbb::enumerable_thread_specific<Acts::FpeMonitor::Result> fpeResult{};
0175   };
0176 
0177   Config m_cfg;
0178   tbbWrap::task_arena m_taskArena;
0179   std::vector<std::shared_ptr<IContextDecorator>> m_decorators;
0180   std::vector<std::shared_ptr<IReader>> m_readers;
0181   std::vector<SequenceElementWithFpeResult> m_sequenceElements;
0182   std::unique_ptr<const Acts::Logger> m_logger;
0183 
0184   std::unordered_map<std::string, std::string> m_whiteboardObjectAliases;
0185 
0186   std::unordered_map<std::string, const DataHandleBase *> m_whiteBoardState;
0187 
0188   std::atomic<std::size_t> m_nUnmaskedFpe = 0;
0189 
0190   const Acts::Logger &logger() const { return *m_logger; }
0191 };
0192 
0193 std::ostream &operator<<(std::ostream &os,
0194                          const ActsExamples::Sequencer::FpeMask &m);
0195 
0196 }  // namespace ActsExamples