File indexing completed on 2026-07-07 08:47:25
0001
0002 #include "JANA/Utils/JEventLevel.h"
0003 #include <catch.hpp>
0004
0005 #include <JANA/JApplication.h>
0006 #include <JANA/JFactoryGenerator.h>
0007 #include <JANA/CLI/JBenchmarker.h>
0008 #include <JANA/JEventUnfolder.h>
0009 #include <JANA/JEventProcessor.h>
0010 #include <JANA/JEventSource.h>
0011 #include <JANA/Utils/JBenchUtils.h>
0012
0013
0014 namespace jana::perftest::unfold {
0015
0016 struct Data { size_t x; };
0017
0018 struct BSrc : public JEventSource {
0019
0020 Output<Data> data_out {this};
0021 Parameter<int> latency_us {this, "latency_us", 0};
0022
0023 BSrc() {
0024 SetPrefix("bsrc");
0025 SetLevel(JEventLevel::Block);
0026 SetCallbackStyle(CallbackStyle::ExpertMode);
0027 data_out.SetShortName("1");
0028 }
0029 JEventSource::Result Emit(JEvent& block) override {
0030 data_out().push_back(new Data {block.GetEventNumber()*3 });
0031 JBenchUtils::consume_cpu_us(*latency_us);
0032 return Result::Success;
0033 };
0034 };
0035
0036 struct BFac : public JFactory {
0037 Input<Data> data_in {this};
0038 Output<Data> data_out {this};
0039 Parameter<int> latency_us {this, "latency_us", 0};
0040
0041 BFac() {
0042 SetPrefix("bfac");
0043 SetLevel(JEventLevel::Block);
0044 data_in.SetDatabundleName("1");
0045 data_out.SetShortName("2");
0046 }
0047 void Process(const JEvent&) override {
0048 auto x = data_in().at(0)->x + 7;
0049 data_out().push_back(new Data {x});
0050 JBenchUtils::consume_cpu_us(*latency_us);
0051 };
0052 };
0053
0054 struct Unf : public JEventUnfolder {
0055 Input<Data> parent_data_in {this};
0056 Output<Data> child_data_out {this};
0057 Parameter<int> latency_us {this, "latency_us", 0};
0058
0059 Unf() {
0060 SetPrefix("unf");
0061 SetParentLevel(JEventLevel::Block);
0062 SetChildLevel(JEventLevel::PhysicsEvent);
0063 SetCallbackStyle(CallbackStyle::ExpertMode);
0064 parent_data_in.SetDatabundleName("2");
0065 child_data_out.SetShortName("3");
0066 }
0067 JEventUnfolder::Result Unfold(const JEvent&, JEvent&, int child_nr) override {
0068 auto x = parent_data_in().at(0)->x * 10 + child_nr;
0069 child_data_out().push_back(new Data{x});
0070 JBenchUtils::consume_cpu_us(*latency_us);
0071
0072 if (child_nr == 9) {
0073 return Result::NextChildNextParent;
0074 }
0075 return Result::NextChildKeepParent;
0076 };
0077 };
0078
0079 struct PEFac : public JFactory {
0080 Input<Data> data_in {this};
0081 Output<Data> data_out {this};
0082 Parameter<int> latency_us {this, "latency_us", 0};
0083 PEFac() {
0084 SetPrefix("pefac");
0085 SetLevel(JEventLevel::PhysicsEvent);
0086 data_in.SetDatabundleName("3");
0087 data_out.SetShortName("4");
0088 }
0089 void Process(const JEvent&) override {
0090 auto x = data_in().at(0)->x * 10;
0091 data_out().push_back(new Data {x});
0092 JBenchUtils::consume_cpu_us(*latency_us);
0093 };
0094 };
0095
0096 struct PEProc : public JEventProcessor {
0097 Input<Data> data_in {this};
0098 Parameter<int> latency_us {this, "latency_us", 0};
0099 PEProc() {
0100 SetPrefix("peproc");
0101 SetLevel(JEventLevel::PhysicsEvent);
0102 SetCallbackStyle(CallbackStyle::ExpertMode);
0103 data_in.SetDatabundleName("4");
0104 }
0105 void ProcessSequential(const JEvent&) override {
0106 (void) (data_in().at(0)->x);
0107 JBenchUtils::consume_cpu_us(*latency_us);
0108 };
0109 };
0110
0111
0112 TEST_CASE("UnfoldTopology_Mini") {
0113
0114 LOG << "Running UnfoldTopology_Mini";
0115
0116 JApplication app;
0117 app.SetParameterValue("bsrc:latency_us", 0);
0118 app.SetParameterValue("bfac:latency_us", 0);
0119 app.SetParameterValue("unf:latency_us", 0);
0120 app.SetParameterValue("pefac:latency_us", 0);
0121 app.SetParameterValue("peproc:latency_us", 0);
0122 app.SetParameterValue("benchmark:resultsdir", "docs/perf_tests");
0123 app.SetParameterValue("benchmark:rates_filename", "unfold_mini.dat");
0124 app.SetParameterValue("benchmark:use_log_scale", true);
0125 app.SetParameterValue("benchmark:minthreads", "1");
0126 app.SetParameterValue("benchmark:maxthreads", "32");
0127
0128 app.Add(new BSrc);
0129 app.Add(new Unf);
0130 app.Add(new PEProc);
0131 app.Add(new JFactoryGeneratorT<BFac>);
0132 app.Add(new JFactoryGeneratorT<PEFac>);
0133
0134 JBenchmarker benchmarker(&app);
0135 benchmarker.RunUntilFinished();
0136 }
0137
0138 TEST_CASE("UnfoldTopology_Small") {
0139 LOG << "Running UnfoldTopology_Small";
0140
0141 JApplication app;
0142 app.SetParameterValue("bsrc:latency_us", 0);
0143 app.SetParameterValue("bfac:latency_us", 1'000'000 / 500);
0144 app.SetParameterValue("unf:latency_us", 0);
0145 app.SetParameterValue("pefac:latency_us", 1'000'000 / 5000);
0146 app.SetParameterValue("peproc:latency_us", 0);
0147 app.SetParameterValue("benchmark:resultsdir", "docs/perf_tests");
0148 app.SetParameterValue("benchmark:rates_filename", "unfold_small.dat");
0149 app.SetParameterValue("benchmark:use_log_scale", true);
0150 app.SetParameterValue("benchmark:minthreads", "1");
0151 app.SetParameterValue("benchmark:maxthreads", "32");
0152
0153 app.Add(new BSrc);
0154 app.Add(new Unf);
0155 app.Add(new PEProc);
0156 app.Add(new JFactoryGeneratorT<BFac>);
0157 app.Add(new JFactoryGeneratorT<PEFac>);
0158
0159 JBenchmarker benchmarker(&app);
0160 benchmarker.RunUntilFinished();
0161 }
0162
0163 TEST_CASE("UnfoldTopology_Small_Saturation") {
0164 LOG << "Running UnfoldTopology_Small_Saturation";
0165
0166 JApplication app;
0167 app.SetParameterValue("bsrc:latency_us", 1'000'000 / 2'000); // 2 kHz
0168 app.SetParameterValue("bfac:latency_us", 1'000'000 / 500); // 500 Hz
0169 app.SetParameterValue("unf:latency_us", 1'000'000 / 20'000);
0170 app.SetParameterValue("pefac:latency_us", 1'000'000 / 5000);
0171 app.SetParameterValue("peproc:latency_us", 1'000'000 / 20'000); // 20 kHz
0172 app.SetParameterValue("benchmark:resultsdir", "docs/perf_tests");
0173 app.SetParameterValue("benchmark:rates_filename", "unfold_small_saturation.dat");
0174 app.SetParameterValue("benchmark:use_log_scale", false);
0175 app.SetParameterValue("benchmark:minthreads", "1");
0176 app.SetParameterValue("benchmark:maxthreads", "16");
0177
0178 app.Add(new BSrc);
0179 app.Add(new Unf);
0180 app.Add(new PEProc);
0181 app.Add(new JFactoryGeneratorT<BFac>);
0182 app.Add(new JFactoryGeneratorT<PEFac>);
0183
0184 JBenchmarker benchmarker(&app);
0185 benchmarker.RunUntilFinished();
0186 }
0187
0188 TEST_CASE("UnfoldTopology_Medium") {
0189 LOG << "Running UnfoldTopology_Medium";
0190
0191 JApplication app;
0192 app.SetParameterValue("bsrc:latency_us", 0); // Infinity Hz
0193 app.SetParameterValue("bfac:latency_us", 1'000'000 / 10); // 10 Hz
0194 app.SetParameterValue("unf:latency_us", 0); // Infinity Hz
0195 app.SetParameterValue("pefac:latency_us", 1'000'000 / 100); // 100 Hz
0196 app.SetParameterValue("peproc:latency_us", 0); // Infinity Hz
0197 app.SetParameterValue("benchmark:resultsdir", "docs/perf_tests");
0198 app.SetParameterValue("benchmark:rates_filename", "unfold_medium.dat");
0199 app.SetParameterValue("benchmark:use_log_scale", true);
0200 app.SetParameterValue("benchmark:minthreads", "1");
0201 app.SetParameterValue("benchmark:maxthreads", "32");
0202
0203 app.Add(new BSrc);
0204 app.Add(new Unf);
0205 app.Add(new PEProc);
0206 app.Add(new JFactoryGeneratorT<BFac>);
0207 app.Add(new JFactoryGeneratorT<PEFac>);
0208
0209 JBenchmarker benchmarker(&app);
0210 benchmarker.RunUntilFinished();
0211 }
0212
0213 TEST_CASE("UnfoldTopology_Medium_Saturation") {
0214 LOG << "Running UnfoldTopology_Medium";
0215
0216 JApplication app;
0217 app.SetParameterValue("bsrc:latency_us", 1'000'000 / 40); // 40 Hz
0218 app.SetParameterValue("bfac:latency_us", 1'000'000 / 10); // 10 Hz
0219 app.SetParameterValue("unf:latency_us", 1'000'000 / 400); // 400 Hz
0220 app.SetParameterValue("pefac:latency_us", 1'000'000 / 100); // 100 Hz
0221 app.SetParameterValue("peproc:latency_us", 1'000'000 / 400); // 400 Hz
0222 app.SetParameterValue("benchmark:resultsdir", "docs/perf_tests");
0223 app.SetParameterValue("benchmark:rates_filename", "unfold_medium_saturation.dat");
0224 app.SetParameterValue("benchmark:use_log_scale", false);
0225 app.SetParameterValue("benchmark:minthreads", "1");
0226 app.SetParameterValue("benchmark:maxthreads", "16");
0227
0228 app.Add(new BSrc);
0229 app.Add(new Unf);
0230 app.Add(new PEProc);
0231 app.Add(new JFactoryGeneratorT<BFac>);
0232 app.Add(new JFactoryGeneratorT<PEFac>);
0233
0234 JBenchmarker benchmarker(&app);
0235 benchmarker.RunUntilFinished();
0236 }
0237
0238 TEST_CASE("UnfoldTopology_Large") {
0239 LOG << "Running UnfoldTopology_Large";
0240
0241 JApplication app;
0242 app.SetParameterValue("bsrc:latency_us", 0); // Infinity Hz
0243 app.SetParameterValue("bfac:latency_us", 1'000'000*2); // 0.5 Hz
0244 app.SetParameterValue("unf:latency_us", 0); // Infinity Hz
0245 app.SetParameterValue("pefac:latency_us", 1'000'000 / 5); // 5 Hz
0246 app.SetParameterValue("peproc:latency_us", 0); // Infinity Hz
0247 app.SetParameterValue("benchmark:resultsdir", "docs/perf_tests");
0248 app.SetParameterValue("benchmark:rates_filename", "unfold_large.dat");
0249 app.SetParameterValue("benchmark:use_log_scale", true);
0250 app.SetParameterValue("benchmark:minthreads", "1");
0251 app.SetParameterValue("benchmark:maxthreads", "32");
0252
0253 app.Add(new BSrc);
0254 app.Add(new Unf);
0255 app.Add(new PEProc);
0256 app.Add(new JFactoryGeneratorT<BFac>);
0257 app.Add(new JFactoryGeneratorT<PEFac>);
0258
0259 JBenchmarker benchmarker(&app);
0260 benchmarker.RunUntilFinished();
0261 }
0262
0263
0264 TEST_CASE("UnfoldTopology_Large_Saturation") {
0265 LOG << "Running UnfoldTopology_Large_Saturation";
0266
0267 JApplication app;
0268 app.SetParameterValue("bsrc:latency_us", 1'000'000 / 2); // 2 Hz
0269 app.SetParameterValue("bfac:latency_us", 1'000'000*2); // 0.5 Hz
0270 app.SetParameterValue("unf:latency_us", 1'000'000 / 20); // 20 Hz
0271 app.SetParameterValue("pefac:latency_us", 1'000'000 / 5); // 5 Hz
0272 app.SetParameterValue("peproc:latency_us", 1'000'000 / 20); // 20 Hz
0273 app.SetParameterValue("benchmark:resultsdir", "docs/perf_tests");
0274 app.SetParameterValue("benchmark:rates_filename", "unfold_large_saturation.dat");
0275 app.SetParameterValue("benchmark:use_log_scale", false);
0276 app.SetParameterValue("benchmark:minthreads", "1");
0277 app.SetParameterValue("benchmark:maxthreads", "16");
0278
0279 app.Add(new BSrc);
0280 app.Add(new Unf);
0281 app.Add(new PEProc);
0282 app.Add(new JFactoryGeneratorT<BFac>);
0283 app.Add(new JFactoryGeneratorT<PEFac>);
0284
0285 JBenchmarker benchmarker(&app);
0286 benchmarker.RunUntilFinished();
0287 }
0288
0289
0290 }
0291
0292
0293