Iguana 1.2.0
Implementation Guardian of Analysis Algorithms
Loading...
Searching...
No Matches
TestMultithreading.h
1#pragma once
2// multithreaded test of an iguana algorithm
3
4#include <iguana/algorithms/AlgorithmSequence.h>
5#ifdef USE_HIPO_MULTITHREADED_CHAIN
6#include "Fuzzing.h"
7#include <cassert>
8#include <hipo4/chain.h>
9#endif
10
11inline int TestMultithreading(
12 std::string const algo_name,
13 std::vector<std::string> const prerequisite_algos,
14 std::vector<std::string> const bank_names,
15 std::string const data_file,
16 int data_tag,
17 int const num_events,
18 int const num_threads,
19 bool const vary_run,
20 std::string const log_level)
21{
22
23#ifdef USE_HIPO_MULTITHREADED_CHAIN
24
25 iguana::Logger log("test");
26 log.SetLevel(log_level);
27
28 // check arguments
29 if(algo_name.empty() || bank_names.empty()) {
30 log.Error("need algorithm name and banks");
31 return 1;
32 }
33 if(data_file.empty()) {
34 log.Error("need a data file for command 'multithreading'");
35 return 1;
36 }
37
38 // set the concurrency model
39 iguana::GlobalConcurrencyModel = "memoize";
40
41 // find the 'RUN::config' bank, if any
42 std::optional<hipo::banklist::size_type> run_config_bank_idx{};
43 if(vary_run) {
44 for(hipo::banklist::size_type idx = 0; idx < bank_names.size(); idx++) {
45 if(bank_names.at(idx) == "RUN::config") {
46 run_config_bank_idx = idx;
47 break;
48 }
49 }
50 }
51
52 // start the HIPO chain
53 hipo::chain ch(num_threads, false, false);
54 ch.set_tags({data_tag});
55 ch.add(data_file);
56 auto banks = ch.getBanks(bank_names);
57
58 // define the algorithm
60 for(auto const& prerequisite_algo : prerequisite_algos)
61 seq.Add(prerequisite_algo);
62 seq.Add(algo_name);
63 seq.PrintSequence();
64 seq.SetLogLevel(algo_name, log_level);
65 seq.iguana::Algorithm::SetLogLevel(log_level);
66
67 // start the algorithm
68 seq.Start(banks);
69
70 // setup run number variation
71 Fuzzing fuzz;
72 if(vary_run) {
73 seq.GetLog()->Warn("==================================================================================================");
74 seq.GetLog()->Warn("RUN NUMBER VARIATION IS ENABLED, DO NOT ATTEMPT TO CROSS CHECK RESULTS WITH SINGLE-THREADED TESTS!");
75 seq.GetLog()->Warn("==================================================================================================");
76 }
77
78 // define the event processor
79 auto processor = [&seq,
80 &vary_run,
81 &run_config_bank_idx,
82 &fuzz](auto& banks, int file_idx, long event_idx) {
83 // occasionally vary the run number; so far, algorithms with data-dependent configuration
84 // parameters have dependence on run number, so this variation aims to improve thread
85 // sanitizer test coverage
86 if(vary_run && run_config_bank_idx.has_value()) {
87 auto random_run = fuzz.RunNumRandom();
88 if(random_run.has_value()) {
89 seq.GetLog()->Trace("RANDOMLY VARIED RUN NUMBER TO BE {}", random_run.value());
90 banks[run_config_bank_idx.value()].putInt("run", 0, random_run.value());
91 }
92 }
93 // run the iguana algorithm
94 seq.Run(banks);
95 };
96
97 // process events
98 double percentage = num_events == 0 ? 100 : static_cast<double>(num_events) / ch.total_events() * 100;
99 auto frac = std::clamp(percentage, 0.0, 100.0) / 100.0;
100 if(num_events != 0)
101 assert((num_events == std::lround(ch.total_events() * frac)));
102 ch.process(banks, processor, percentage);
103
104 // stop the algorithm
105 seq.Stop();
106 return 0;
107
108#else
109 throw std::runtime_error("called command `multithreading` but HIPO version does not support it");
110#endif
111}
fuzzing tests
Definition Fuzzing.h:8
std::optional< int > RunNumRandom()
Definition Fuzzing.h:22
Algorithm: An algorithm that can run a sequence of algorithms
void Add(std::string const &algo_class_name, std::string const &algo_instance_name="")
void PrintSequence(Logger::Level level=Logger::info) const
void SetLogLevel(std::string const &algo_instance_name, std::string const &lev)
Set an algorithm log level.
virtual bool Run(hipo::banklist &banks) const final
Run Function: Process an event's hipo::banklist
virtual void Stop() final
Stop Function: Finalize this algorithm after all events are processed.
virtual void Start(hipo::banklist &banks) final
Start Function: Initialize this algorithm before any events are processed, with the intent to process...
Simple logger service.
Definition Logger.h:19
std::unique_ptr< Logger > & GetLog()