Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:33:38

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