From 002aeae5cf2b93193392ad0846010e3e663a2617 Mon Sep 17 00:00:00 2001 From: raiqarasool Date: Thu, 22 Aug 2024 09:17:22 -0400 Subject: [PATCH 1/4] Replaced JPerfUtils with JBenchUtils (class format), set event number and caller name based seed inside constructor (Fixes #315) --- .../EventGroupExample/GroupedEventProcessor.h | 5 +- .../ADCSampleFactory.h | 1 - .../InteractiveStreamingExample.cc | 5 +- .../JTestRootEventSource.cc | 9 +- .../StreamingExample/AHitAnomalyDetector.h | 5 +- src/examples/StreamingExample/AHitBHitFuser.h | 8 +- src/examples/StreamingExample/ZmqMain.cc | 15 +-- src/libraries/JANA/CMakeLists.txt | 2 + src/libraries/JANA/Utils/JBenchUtils.cc | 91 +++++++++++++++++++ src/libraries/JANA/Utils/JBenchUtils.h | 33 +++++++ src/plugins/JTest/JTestDisentangler.h | 9 +- src/plugins/JTest/JTestParser.h | 18 ++-- src/plugins/JTest/JTestPlotter.h | 7 +- src/plugins/JTest/JTestTracker.h | 9 +- src/programs/unit_tests/Engine/ScaleTests.h | 12 ++- .../unit_tests/Topology/TopologyTests.cc | 4 +- 16 files changed, 191 insertions(+), 42 deletions(-) create mode 100644 src/libraries/JANA/Utils/JBenchUtils.cc create mode 100644 src/libraries/JANA/Utils/JBenchUtils.h diff --git a/src/examples/EventGroupExample/GroupedEventProcessor.h b/src/examples/EventGroupExample/GroupedEventProcessor.h index 795fac81d..3fe9151d5 100644 --- a/src/examples/EventGroupExample/GroupedEventProcessor.h +++ b/src/examples/EventGroupExample/GroupedEventProcessor.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include "TridasEvent.h" @@ -26,8 +26,9 @@ class GroupedEventProcessor : public JEventProcessor { void Process(const std::shared_ptr& event) override { + std::unique_ptr bench_utils = std::make_unique(event->GetEventNumber(), NAME_OF_THIS); // In parallel, perform a random amount of (slow) computation - consume_cpu_ms(100, 1.0); + bench_utils->consume_cpu_ms(100, 1.0); auto tridas_event = event->GetSingle(); tridas_event->should_keep = true; diff --git a/src/examples/InteractiveStreamingExample/ADCSampleFactory.h b/src/examples/InteractiveStreamingExample/ADCSampleFactory.h index ae263f117..2d1a100ad 100644 --- a/src/examples/InteractiveStreamingExample/ADCSampleFactory.h +++ b/src/examples/InteractiveStreamingExample/ADCSampleFactory.h @@ -7,7 +7,6 @@ #define _ADCSampleFactory_h_ #include -#include #include "ADCSample.h" #include "INDRAMessage.h" diff --git a/src/examples/InteractiveStreamingExample/InteractiveStreamingExample.cc b/src/examples/InteractiveStreamingExample/InteractiveStreamingExample.cc index 01ac9ec92..b9b5be586 100644 --- a/src/examples/InteractiveStreamingExample/InteractiveStreamingExample.cc +++ b/src/examples/InteractiveStreamingExample/InteractiveStreamingExample.cc @@ -6,6 +6,8 @@ #include #include #include +#include + #include "RootProcessor.h" #include "MonitoringProcessor.h" @@ -19,6 +21,7 @@ void dummy_publisher_loop(JApplication* app) { size_t delay_ms = 1; auto logger = app->GetService()->get_logger("dummy_publisher_loop"); + std::unique_ptr bench_utils = std::make_unique(7, "InteractiveStreamingExample.cc:dummy_publisher_loop"); std::this_thread::yield(); //std::this_thread::sleep_for(std::chrono::milliseconds(10)); // Wait for JANA to fire up so we don't lose data @@ -51,7 +54,7 @@ void dummy_publisher_loop(JApplication* app) { //LOG_DEBUG(logger) << "Send: " << message << " (" << message.get_buffer_size() << " bytes)" << LOG_END; std::cout << "dummy_producer_loop: Sending '" << message << "' (" << message.get_buffer_size() << " bytes)" << std::endl; transport.send(message); - consume_cpu_ms(delay_ms, 0, false); + bench_utils->consume_cpu_ms(delay_ms, 0, false); std::this_thread::yield(); } diff --git a/src/examples/RootDatamodelExample/JTestRootEventSource.cc b/src/examples/RootDatamodelExample/JTestRootEventSource.cc index 02760b6f5..7e01a4108 100644 --- a/src/examples/RootDatamodelExample/JTestRootEventSource.cc +++ b/src/examples/RootDatamodelExample/JTestRootEventSource.cc @@ -13,7 +13,7 @@ #include #include -#include +#include JTestRootEventSource::JTestRootEventSource() { SetTypeName(NAME_OF_THIS); // Provide JANA with class name @@ -24,13 +24,14 @@ JEventSource::Result JTestRootEventSource::Emit(JEvent& event) { /// Generate an event by inserting objects into "event". /// (n.b. a normal event source would read these from a file or stream) - // Spin the CPU a bit to limit the rate - consume_cpu_ms(5); - // Configure event and run numbers static size_t current_event_number = 1; event.SetEventNumber(current_event_number++); event.SetRunNumber(222); + + std::unique_ptr bench_utils = std::make_unique(event.GetEventNumber(), NAME_OF_THIS); + // Spin the CPU a bit to limit the rate + bench_utils->consume_cpu_ms(5); // Generate hit objects. We use random numbers to give some variation // and make things look a little more realistic diff --git a/src/examples/StreamingExample/AHitAnomalyDetector.h b/src/examples/StreamingExample/AHitAnomalyDetector.h index b925f4e9b..c3309623e 100644 --- a/src/examples/StreamingExample/AHitAnomalyDetector.h +++ b/src/examples/StreamingExample/AHitAnomalyDetector.h @@ -8,7 +8,7 @@ #include #include -#include +#include #include "AHit.h" class AHitAnomalyDetector : public JEventProcessor { @@ -33,7 +33,8 @@ class AHitAnomalyDetector : public JEventProcessor { } ss << "}" << std::endl; std::cout << ss.str(); - consume_cpu_ms(m_delay_ms); + std::unique_ptr bench_utils = std::make_unique(event.GetEventNumber(), NAME_OF_THIS); + bench_utils->consume_cpu_ms(m_delay_ms); } void Finish() override { std::cout << "Anomaly detection: Done!" << std::endl; diff --git a/src/examples/StreamingExample/AHitBHitFuser.h b/src/examples/StreamingExample/AHitBHitFuser.h index 5f3e09951..6fa7efdb9 100644 --- a/src/examples/StreamingExample/AHitBHitFuser.h +++ b/src/examples/StreamingExample/AHitBHitFuser.h @@ -8,7 +8,7 @@ #include #include -#include +#include #include "AHit.h" /// AHitBHitFuser @@ -39,7 +39,9 @@ class AHitBHitFuser : public JEventProcessor { } ss << "}" << std::endl; std::cout << ss.str(); - consume_cpu_ms(m_delay_ms); + + std::unique_ptr bench_utils = std::make_unique(event.GetEventNumber(), NAME_OF_THIS); + bench_utils->consume_cpu_ms(m_delay_ms); auto raw_hits = event.Get("raw_hits"); @@ -52,7 +54,7 @@ class AHitBHitFuser : public JEventProcessor { calibrated_hit->V += 7; std::cout << serializer.serialize(*calibrated_hit) << std::endl; } - consume_cpu_ms(m_delay_ms); + bench_utils->consume_cpu_ms(m_delay_ms); } void Finish() override { std::cout << "Done!" << std::endl; diff --git a/src/examples/StreamingExample/ZmqMain.cc b/src/examples/StreamingExample/ZmqMain.cc index d363e129a..ab196cc4a 100644 --- a/src/examples/StreamingExample/ZmqMain.cc +++ b/src/examples/StreamingExample/ZmqMain.cc @@ -7,9 +7,11 @@ #include #include #include +#include #include #include + #include "ReadoutMessageAuto.h" #include "ZmqTransport.h" #include "AHitParser.h" @@ -18,7 +20,8 @@ void dummy_publisher_loop() { - consume_cpu_ms(3000, 0, false); + std::unique_ptr bench_utils = std::make_unique(6, "ZmqMain.cc:dummy_publisher_loop"); + bench_utils->consume_cpu_ms(3000, 0, false); auto transport = ZmqTransport("tcp://127.0.0.1:5555", true); transport.initialize(); @@ -30,14 +33,14 @@ void dummy_publisher_loop() { message.event_number = counter; message.payload_size = 4; - message.payload[0] = randfloat(0,1); - message.payload[1] = randfloat(-100,100); - message.payload[2] = randfloat(-100,100); - message.payload[3] = randfloat(-100,100); + message.payload[0] = bench_utils->randfloat(0,1); + message.payload[1] = bench_utils->randfloat(-100,100); + message.payload[2] = bench_utils->randfloat(-100,100); + message.payload[3] = bench_utils->randfloat(-100,100); transport.send(message); std::cout << "Send: " << message << "(" << message.get_buffer_capacity() << " bytes)" << std::endl; - consume_cpu_ms(1000, 0, false); + bench_utils->consume_cpu_ms(1000, 0, false); } // Send end-of-stream message so that JANA knows to shut down diff --git a/src/libraries/JANA/CMakeLists.txt b/src/libraries/JANA/CMakeLists.txt index e7c59008a..9e4229b16 100644 --- a/src/libraries/JANA/CMakeLists.txt +++ b/src/libraries/JANA/CMakeLists.txt @@ -85,6 +85,8 @@ set(JANA2_SOURCES Utils/JProcessorMapping.cc Utils/JPerfUtils.cc Utils/JPerfUtils.h + Utils/JBenchUtils.cc + Utils/JBenchUtils.h Utils/JStringification.cc Utils/JStringification.h Utils/JAutoActivator.cc diff --git a/src/libraries/JANA/Utils/JBenchUtils.cc b/src/libraries/JANA/Utils/JBenchUtils.cc new file mode 100644 index 000000000..64a6ea3d4 --- /dev/null +++ b/src/libraries/JANA/Utils/JBenchUtils.cc @@ -0,0 +1,91 @@ + +// Copyright 2020, Jefferson Science Associates, LLC. +// Subject to the terms in the LICENSE file found in the top-level directory. + + +#include "JBenchUtils.h" + + +JBenchUtils::JBenchUtils(size_t event_number, std::string caller_name) +{ + std::hash hasher; + long seed = event_number ^ hasher(caller_name); + m_generator = std::mt19937(seed); +} + + +size_t JBenchUtils::rand_size(size_t avg, double spread) { + auto delta = static_cast(avg*spread); + std::uniform_int_distribution distribution(avg-delta, avg+delta); + return distribution(m_generator); +} + + +int JBenchUtils::randint(int min, int max) { + std::uniform_int_distribution distribution(min, max); + return distribution(m_generator); +} + +double JBenchUtils::randdouble(double min, double max) { + std::uniform_real_distribution dist(min, max); + return dist(m_generator); +} + +float JBenchUtils::randfloat(float min, float max) { + std::uniform_real_distribution dist(min, max); + return dist(m_generator); +} + +uint64_t JBenchUtils::consume_cpu_ms(uint64_t millisecs, double spread, bool fix_flops) { + + uint64_t sampled = rand_size(millisecs, spread); + uint64_t result = 0; + + if (fix_flops) { + // Perform a fixed amount of work in a variable time + const uint64_t appx_iters_per_millisec = 14000; + sampled *= appx_iters_per_millisec; + + for (uint64_t i=0; i& buffer) { + + auto length = buffer.size(); + uint64_t sum = 0; + for (unsigned i=0; i& buffer, uint64_t bytes, double spread) { + + uint64_t sampled = rand_size(bytes, spread); + for (unsigned i=0; i +#include +#include +#include +#include +#include +#include + + +class JBenchUtils { + + std::mt19937 m_generator; + +public: + + JBenchUtils(size_t event_number, std::string caller_name); + + size_t rand_size(size_t avg, double spread); + int randint(int min, int max); + double randdouble(double min=0.0, double max=1000.0); + float randfloat(float min=0.0, float max=1000.0); + + uint64_t consume_cpu_ms(uint64_t millisecs, double spread=0.0, bool fix_flops=true); + uint64_t read_memory(const std::vector& buffer); + uint64_t write_memory(std::vector& buffer, uint64_t bytes, double spread=0.0); + +}; diff --git a/src/plugins/JTest/JTestDisentangler.h b/src/plugins/JTest/JTestDisentangler.h index 2cc08a8b4..8b2a1e501 100644 --- a/src/plugins/JTest/JTestDisentangler.h +++ b/src/plugins/JTest/JTestDisentangler.h @@ -7,7 +7,7 @@ #include #include -#include +#include #include "JTestDataObjects.h" #include "JTestCalibrationService.h" @@ -38,19 +38,20 @@ class JTestDisentangler : public JFactoryT { void Process(const std::shared_ptr &aEvent) override { + std::unique_ptr bench_utils = std::make_unique(aEvent->GetEventNumber(), NAME_OF_THIS); // Read (large) entangled event data auto eed = aEvent->GetSingle(); - read_memory(*eed->buffer); + bench_utils->read_memory(*eed->buffer); // Read calibration data m_calibration_service->getCalibration(); // Do a little bit of computation - consume_cpu_ms(m_cputime_ms, m_cputime_spread); + bench_utils->consume_cpu_ms(m_cputime_ms, m_cputime_spread); // Write (large) event data auto ed = new JTestEventData; - write_memory(ed->buffer, m_write_bytes, m_write_spread); + bench_utils->write_memory(ed->buffer, m_write_bytes, m_write_spread); Insert(ed); } }; diff --git a/src/plugins/JTest/JTestParser.h b/src/plugins/JTest/JTestParser.h index 83e2a7951..8175196ef 100644 --- a/src/plugins/JTest/JTestParser.h +++ b/src/plugins/JTest/JTestParser.h @@ -7,11 +7,13 @@ #include #include + #include #include #include -#include +#include + #include "JTestDataObjects.h" @@ -50,23 +52,27 @@ class JTestParser : public JEventSource { Result Emit(JEvent& event) override { - if ((m_events_generated % 40) == 0) { + const auto prev_m_events_generated = m_events_generated; + m_events_generated++; + event.SetEventNumber(m_events_generated); + + std::unique_ptr bench_utils = std::make_unique(m_events_generated, typeid(*this).name()); + + if ((prev_m_events_generated % 40) == 0) { // "Read" new entangled event every 40 events m_latest_entangled_buffer = std::shared_ptr>(new std::vector); - write_memory(*m_latest_entangled_buffer, m_write_bytes, m_write_spread); + bench_utils->write_memory(*m_latest_entangled_buffer, m_write_bytes, m_write_spread); } // Spin the CPU - consume_cpu_ms(m_cputime_ms, m_cputime_spread); + bench_utils->consume_cpu_ms(m_cputime_ms, m_cputime_spread); // Emit a shared pointer to the entangled event buffer auto eec = new JTestEntangledEventData; eec->buffer = m_latest_entangled_buffer; event.Insert(eec); - m_events_generated++; - event.SetEventNumber(m_events_generated); event.SetRunNumber(1); return Result::Success; } diff --git a/src/plugins/JTest/JTestPlotter.h b/src/plugins/JTest/JTestPlotter.h index 0c643f925..d53c591fc 100644 --- a/src/plugins/JTest/JTestPlotter.h +++ b/src/plugins/JTest/JTestPlotter.h @@ -35,9 +35,10 @@ class JTestPlotter : public JEventProcessor { void Process(const std::shared_ptr& event) override { + std::unique_ptr bench_utils = std::make_unique(event->GetEventNumber(), typeid(*this).name()); // Read the track data auto td = event->GetSingle(); - read_memory(td->buffer); + bench_utils->read_memory(td->buffer); // Read the extra data objects inserted by JTestTracker event->Get(); @@ -46,11 +47,11 @@ class JTestPlotter : public JEventProcessor { std::lock_guard lock(m_mutex); // Consume CPU - consume_cpu_ms(m_cputime_ms, m_cputime_spread); + bench_utils->consume_cpu_ms(m_cputime_ms, m_cputime_spread); // Write the histogram data auto hd = new JTestHistogramData; - write_memory(hd->buffer, m_write_bytes, m_write_spread); + bench_utils->write_memory(hd->buffer, m_write_bytes, m_write_spread); event->Insert(hd); } diff --git a/src/plugins/JTest/JTestTracker.h b/src/plugins/JTest/JTestTracker.h index 1f99dc6c9..2b03a0914 100644 --- a/src/plugins/JTest/JTestTracker.h +++ b/src/plugins/JTest/JTestTracker.h @@ -8,7 +8,7 @@ #include #include -#include +#include #include "JTestDataObjects.h" class JTestTracker : public JFactoryT { @@ -36,16 +36,17 @@ class JTestTracker : public JFactoryT { void Process(const std::shared_ptr &aEvent) override { + std::unique_ptr bench_utils = std::make_unique(aEvent->GetEventNumber(), typeid(*this).name()); // Read (large) event data auto ed = aEvent->GetSingle(); - read_memory(ed->buffer); + bench_utils->read_memory(ed->buffer); // Do lots of computation - consume_cpu_ms(m_cputime_ms, m_cputime_spread); + bench_utils->consume_cpu_ms(m_cputime_ms, m_cputime_spread); // Write (small) track data auto td = new JTestTrackData; - write_memory(td->buffer, m_write_bytes, m_write_spread); + bench_utils->write_memory(td->buffer, m_write_bytes, m_write_spread); Insert(td); // Insert some additional objects diff --git a/src/programs/unit_tests/Engine/ScaleTests.h b/src/programs/unit_tests/Engine/ScaleTests.h index 7e7e0aaaf..96a08098e 100644 --- a/src/programs/unit_tests/Engine/ScaleTests.h +++ b/src/programs/unit_tests/Engine/ScaleTests.h @@ -5,7 +5,7 @@ #ifndef JANA2_SCALETESTS_H #define JANA2_SCALETESTS_H -#include +#include #include #include @@ -16,8 +16,9 @@ struct DummySource : public JEventSource { SetCallbackStyle(CallbackStyle::ExpertMode); } - Result Emit(JEvent&) override { - consume_cpu_ms(20); + Result Emit(JEvent& event) override { + std::unique_ptr bench_utils = std::make_unique(event.GetEventNumber(), NAME_OF_THIS); + bench_utils->consume_cpu_ms(20); std::this_thread::sleep_for(std::chrono::nanoseconds(1)); return Result::Success; } @@ -28,8 +29,9 @@ struct DummyProcessor : public JEventProcessor { DummyProcessor() { SetCallbackStyle(CallbackStyle::ExpertMode); } - void Process(const JEvent&) override { - consume_cpu_ms(100); + void Process(const JEvent& event) override { + std::unique_ptr bench_utils = std::make_unique(event.GetEventNumber(), NAME_OF_THIS); + bench_utils->consume_cpu_ms(100); std::this_thread::sleep_for(std::chrono::nanoseconds(1)); } }; diff --git a/src/programs/unit_tests/Topology/TopologyTests.cc b/src/programs/unit_tests/Topology/TopologyTests.cc index f66f08ef6..46dd6d3bb 100644 --- a/src/programs/unit_tests/Topology/TopologyTests.cc +++ b/src/programs/unit_tests/Topology/TopologyTests.cc @@ -8,6 +8,7 @@ #include #include "TestTopologyComponents.h" +#include #include #include @@ -161,9 +162,10 @@ TEST_CASE("JTopology: Basic functionality") { step(emit_rand_ints); bool work_left = true; + std::unique_ptr bench_utils = std::make_unique(5, "TopologyTests"); while (work_left) { // Pick a random arrow - JArrow* arrow = arrows[randint(0, 3)]; + JArrow* arrow = arrows[bench_utils->randint(0, 3)]; auto name = arrow->get_name(); JArrowMetrics metrics; From c23544ff208e94b49a1fd4ee4d874cdd5425f8de Mon Sep 17 00:00:00 2001 From: raiqarasool Date: Mon, 9 Sep 2024 10:14:53 -0400 Subject: [PATCH 2/4] JBenchUtils Seed setting moved from constructor to separate function --- .../EventGroupExample/GroupedEventProcessor.h | 6 +++--- .../InteractiveStreamingExample.cc | 5 +++-- .../RootDatamodelExample/JTestRootEventSource.cc | 4 ++-- .../RootDatamodelExample/JTestRootEventSource.h | 1 + .../StreamingExample/AHitAnomalyDetector.h | 5 +++-- src/examples/StreamingExample/AHitBHitFuser.h | 7 ++++--- src/examples/StreamingExample/ZmqMain.cc | 15 ++++++++------- src/libraries/JANA/Utils/JBenchUtils.cc | 2 +- src/libraries/JANA/Utils/JBenchUtils.h | 4 +++- src/plugins/JTest/JTestDisentangler.h | 9 +++++---- src/plugins/JTest/JTestParser.h | 7 ++++--- src/plugins/JTest/JTestPlotter.h | 9 +++++---- src/plugins/JTest/JTestTracker.h | 9 +++++---- src/programs/unit_tests/Engine/ScaleTests.h | 14 ++++++++++---- src/programs/unit_tests/Topology/TopologyTests.cc | 5 +++-- 15 files changed, 60 insertions(+), 42 deletions(-) diff --git a/src/examples/EventGroupExample/GroupedEventProcessor.h b/src/examples/EventGroupExample/GroupedEventProcessor.h index 3fe9151d5..5fc94098f 100644 --- a/src/examples/EventGroupExample/GroupedEventProcessor.h +++ b/src/examples/EventGroupExample/GroupedEventProcessor.h @@ -17,7 +17,7 @@ /// GroupedEventProcessor demonstrates basic usage of JEventGroups class GroupedEventProcessor : public JEventProcessor { - + JBenchUtils m_bench_utils = JBenchUtils(); public: GroupedEventProcessor() { SetTypeName(NAME_OF_THIS); @@ -26,9 +26,9 @@ class GroupedEventProcessor : public JEventProcessor { void Process(const std::shared_ptr& event) override { - std::unique_ptr bench_utils = std::make_unique(event->GetEventNumber(), NAME_OF_THIS); + m_bench_utils.set_seed(event->GetEventNumber(), NAME_OF_THIS); // In parallel, perform a random amount of (slow) computation - bench_utils->consume_cpu_ms(100, 1.0); + m_bench_utils.consume_cpu_ms(100, 1.0); auto tridas_event = event->GetSingle(); tridas_event->should_keep = true; diff --git a/src/examples/InteractiveStreamingExample/InteractiveStreamingExample.cc b/src/examples/InteractiveStreamingExample/InteractiveStreamingExample.cc index b9b5be586..a7fe0acb0 100644 --- a/src/examples/InteractiveStreamingExample/InteractiveStreamingExample.cc +++ b/src/examples/InteractiveStreamingExample/InteractiveStreamingExample.cc @@ -19,9 +19,10 @@ void dummy_publisher_loop(JApplication* app) { + JBenchUtils bench_utils = JBenchUtils(); size_t delay_ms = 1; auto logger = app->GetService()->get_logger("dummy_publisher_loop"); - std::unique_ptr bench_utils = std::make_unique(7, "InteractiveStreamingExample.cc:dummy_publisher_loop"); + bench_utils.set_seed(7, "InteractiveStreamingExample.cc:dummy_publisher_loop"); std::this_thread::yield(); //std::this_thread::sleep_for(std::chrono::milliseconds(10)); // Wait for JANA to fire up so we don't lose data @@ -54,7 +55,7 @@ void dummy_publisher_loop(JApplication* app) { //LOG_DEBUG(logger) << "Send: " << message << " (" << message.get_buffer_size() << " bytes)" << LOG_END; std::cout << "dummy_producer_loop: Sending '" << message << "' (" << message.get_buffer_size() << " bytes)" << std::endl; transport.send(message); - bench_utils->consume_cpu_ms(delay_ms, 0, false); + bench_utils.consume_cpu_ms(delay_ms, 0, false); std::this_thread::yield(); } diff --git a/src/examples/RootDatamodelExample/JTestRootEventSource.cc b/src/examples/RootDatamodelExample/JTestRootEventSource.cc index 7e01a4108..f8c73ff47 100644 --- a/src/examples/RootDatamodelExample/JTestRootEventSource.cc +++ b/src/examples/RootDatamodelExample/JTestRootEventSource.cc @@ -29,9 +29,9 @@ JEventSource::Result JTestRootEventSource::Emit(JEvent& event) { event.SetEventNumber(current_event_number++); event.SetRunNumber(222); - std::unique_ptr bench_utils = std::make_unique(event.GetEventNumber(), NAME_OF_THIS); + m_bench_utils.set_seed(event.GetEventNumber(), NAME_OF_THIS); // Spin the CPU a bit to limit the rate - bench_utils->consume_cpu_ms(5); + m_bench_utils.consume_cpu_ms(5); // Generate hit objects. We use random numbers to give some variation // and make things look a little more realistic diff --git a/src/examples/RootDatamodelExample/JTestRootEventSource.h b/src/examples/RootDatamodelExample/JTestRootEventSource.h index fba3dd6a9..9f2b46778 100644 --- a/src/examples/RootDatamodelExample/JTestRootEventSource.h +++ b/src/examples/RootDatamodelExample/JTestRootEventSource.h @@ -11,6 +11,7 @@ class JTestRootEventSource : public JEventSource { + JBenchUtils m_bench_utils = JBenchUtils(); public: JTestRootEventSource(); virtual ~JTestRootEventSource() = default; diff --git a/src/examples/StreamingExample/AHitAnomalyDetector.h b/src/examples/StreamingExample/AHitAnomalyDetector.h index c3309623e..582c44d67 100644 --- a/src/examples/StreamingExample/AHitAnomalyDetector.h +++ b/src/examples/StreamingExample/AHitAnomalyDetector.h @@ -33,14 +33,15 @@ class AHitAnomalyDetector : public JEventProcessor { } ss << "}" << std::endl; std::cout << ss.str(); - std::unique_ptr bench_utils = std::make_unique(event.GetEventNumber(), NAME_OF_THIS); - bench_utils->consume_cpu_ms(m_delay_ms); + m_bench_utils.set_seed(event.GetEventNumber(), NAME_OF_THIS); + m_bench_utils.consume_cpu_ms(m_delay_ms); } void Finish() override { std::cout << "Anomaly detection: Done!" << std::endl; } private: size_t m_delay_ms; + JBenchUtils m_bench_utils = JBenchUtils(); }; diff --git a/src/examples/StreamingExample/AHitBHitFuser.h b/src/examples/StreamingExample/AHitBHitFuser.h index 6fa7efdb9..91b30f014 100644 --- a/src/examples/StreamingExample/AHitBHitFuser.h +++ b/src/examples/StreamingExample/AHitBHitFuser.h @@ -40,8 +40,8 @@ class AHitBHitFuser : public JEventProcessor { ss << "}" << std::endl; std::cout << ss.str(); - std::unique_ptr bench_utils = std::make_unique(event.GetEventNumber(), NAME_OF_THIS); - bench_utils->consume_cpu_ms(m_delay_ms); + m_bench_utils.set_seed(event.GetEventNumber(), NAME_OF_THIS); + m_bench_utils.consume_cpu_ms(m_delay_ms); auto raw_hits = event.Get("raw_hits"); @@ -54,13 +54,14 @@ class AHitBHitFuser : public JEventProcessor { calibrated_hit->V += 7; std::cout << serializer.serialize(*calibrated_hit) << std::endl; } - bench_utils->consume_cpu_ms(m_delay_ms); + m_bench_utils.consume_cpu_ms(m_delay_ms); } void Finish() override { std::cout << "Done!" << std::endl; } private: size_t m_delay_ms; + JBenchUtils m_bench_utils = JBenchUtils(); }; diff --git a/src/examples/StreamingExample/ZmqMain.cc b/src/examples/StreamingExample/ZmqMain.cc index ab196cc4a..b08d1dfe4 100644 --- a/src/examples/StreamingExample/ZmqMain.cc +++ b/src/examples/StreamingExample/ZmqMain.cc @@ -20,8 +20,9 @@ void dummy_publisher_loop() { - std::unique_ptr bench_utils = std::make_unique(6, "ZmqMain.cc:dummy_publisher_loop"); - bench_utils->consume_cpu_ms(3000, 0, false); + JBenchUtils bench_utils = JBenchUtils(); + bench_utils.set_seed(6, "ZmqMain.cc:dummy_publisher_loop"); + bench_utils.consume_cpu_ms(3000, 0, false); auto transport = ZmqTransport("tcp://127.0.0.1:5555", true); transport.initialize(); @@ -33,14 +34,14 @@ void dummy_publisher_loop() { message.event_number = counter; message.payload_size = 4; - message.payload[0] = bench_utils->randfloat(0,1); - message.payload[1] = bench_utils->randfloat(-100,100); - message.payload[2] = bench_utils->randfloat(-100,100); - message.payload[3] = bench_utils->randfloat(-100,100); + message.payload[0] = bench_utils.randfloat(0,1); + message.payload[1] = bench_utils.randfloat(-100,100); + message.payload[2] = bench_utils.randfloat(-100,100); + message.payload[3] = bench_utils.randfloat(-100,100); transport.send(message); std::cout << "Send: " << message << "(" << message.get_buffer_capacity() << " bytes)" << std::endl; - bench_utils->consume_cpu_ms(1000, 0, false); + bench_utils.consume_cpu_ms(1000, 0, false); } // Send end-of-stream message so that JANA knows to shut down diff --git a/src/libraries/JANA/Utils/JBenchUtils.cc b/src/libraries/JANA/Utils/JBenchUtils.cc index 64a6ea3d4..e05e0f612 100644 --- a/src/libraries/JANA/Utils/JBenchUtils.cc +++ b/src/libraries/JANA/Utils/JBenchUtils.cc @@ -6,7 +6,7 @@ #include "JBenchUtils.h" -JBenchUtils::JBenchUtils(size_t event_number, std::string caller_name) +void JBenchUtils::set_seed(size_t event_number, std::string caller_name) { std::hash hasher; long seed = event_number ^ hasher(caller_name); diff --git a/src/libraries/JANA/Utils/JBenchUtils.h b/src/libraries/JANA/Utils/JBenchUtils.h index f60fa80c9..3e55aa14e 100644 --- a/src/libraries/JANA/Utils/JBenchUtils.h +++ b/src/libraries/JANA/Utils/JBenchUtils.h @@ -19,7 +19,9 @@ class JBenchUtils { public: - JBenchUtils(size_t event_number, std::string caller_name); + JBenchUtils(){} + + void set_seed(size_t event_number, std::string caller_name); size_t rand_size(size_t avg, double spread); int randint(int min, int max); diff --git a/src/plugins/JTest/JTestDisentangler.h b/src/plugins/JTest/JTestDisentangler.h index 8b2a1e501..155245cea 100644 --- a/src/plugins/JTest/JTestDisentangler.h +++ b/src/plugins/JTest/JTestDisentangler.h @@ -19,6 +19,7 @@ class JTestDisentangler : public JFactoryT { size_t m_write_bytes = 500000; double m_cputime_spread = 0.25; double m_write_spread = 0.25; + JBenchUtils m_bench_utils = JBenchUtils(); std::shared_ptr m_calibration_service; @@ -38,20 +39,20 @@ class JTestDisentangler : public JFactoryT { void Process(const std::shared_ptr &aEvent) override { - std::unique_ptr bench_utils = std::make_unique(aEvent->GetEventNumber(), NAME_OF_THIS); + m_bench_utils.set_seed(aEvent->GetEventNumber(), NAME_OF_THIS); // Read (large) entangled event data auto eed = aEvent->GetSingle(); - bench_utils->read_memory(*eed->buffer); + m_bench_utils.read_memory(*eed->buffer); // Read calibration data m_calibration_service->getCalibration(); // Do a little bit of computation - bench_utils->consume_cpu_ms(m_cputime_ms, m_cputime_spread); + m_bench_utils.consume_cpu_ms(m_cputime_ms, m_cputime_spread); // Write (large) event data auto ed = new JTestEventData; - bench_utils->write_memory(ed->buffer, m_write_bytes, m_write_spread); + m_bench_utils.write_memory(ed->buffer, m_write_bytes, m_write_spread); Insert(ed); } }; diff --git a/src/plugins/JTest/JTestParser.h b/src/plugins/JTest/JTestParser.h index 8175196ef..51bf6bd43 100644 --- a/src/plugins/JTest/JTestParser.h +++ b/src/plugins/JTest/JTestParser.h @@ -24,6 +24,7 @@ class JTestParser : public JEventSource { size_t m_write_bytes = 2000000; double m_cputime_spread = 0.25; double m_write_spread = 0.25; + JBenchUtils m_bench_utils = JBenchUtils(); std::shared_ptr> m_latest_entangled_buffer; size_t m_events_generated = 0; @@ -56,16 +57,16 @@ class JTestParser : public JEventSource { m_events_generated++; event.SetEventNumber(m_events_generated); - std::unique_ptr bench_utils = std::make_unique(m_events_generated, typeid(*this).name()); + m_bench_utils.set_seed(m_events_generated, typeid(*this).name()); if ((prev_m_events_generated % 40) == 0) { // "Read" new entangled event every 40 events m_latest_entangled_buffer = std::shared_ptr>(new std::vector); - bench_utils->write_memory(*m_latest_entangled_buffer, m_write_bytes, m_write_spread); + m_bench_utils.write_memory(*m_latest_entangled_buffer, m_write_bytes, m_write_spread); } // Spin the CPU - bench_utils->consume_cpu_ms(m_cputime_ms, m_cputime_spread); + m_bench_utils.consume_cpu_ms(m_cputime_ms, m_cputime_spread); // Emit a shared pointer to the entangled event buffer auto eec = new JTestEntangledEventData; diff --git a/src/plugins/JTest/JTestPlotter.h b/src/plugins/JTest/JTestPlotter.h index d53c591fc..c01949d99 100644 --- a/src/plugins/JTest/JTestPlotter.h +++ b/src/plugins/JTest/JTestPlotter.h @@ -16,6 +16,7 @@ class JTestPlotter : public JEventProcessor { size_t m_write_bytes = 1000; double m_cputime_spread = 0.25; double m_write_spread = 0.25; + JBenchUtils m_bench_utils = JBenchUtils(); std::mutex m_mutex; public: @@ -35,10 +36,10 @@ class JTestPlotter : public JEventProcessor { void Process(const std::shared_ptr& event) override { - std::unique_ptr bench_utils = std::make_unique(event->GetEventNumber(), typeid(*this).name()); + m_bench_utils.set_seed(event->GetEventNumber(), typeid(*this).name()); // Read the track data auto td = event->GetSingle(); - bench_utils->read_memory(td->buffer); + m_bench_utils.read_memory(td->buffer); // Read the extra data objects inserted by JTestTracker event->Get(); @@ -47,11 +48,11 @@ class JTestPlotter : public JEventProcessor { std::lock_guard lock(m_mutex); // Consume CPU - bench_utils->consume_cpu_ms(m_cputime_ms, m_cputime_spread); + m_bench_utils.consume_cpu_ms(m_cputime_ms, m_cputime_spread); // Write the histogram data auto hd = new JTestHistogramData; - bench_utils->write_memory(hd->buffer, m_write_bytes, m_write_spread); + m_bench_utils.write_memory(hd->buffer, m_write_bytes, m_write_spread); event->Insert(hd); } diff --git a/src/plugins/JTest/JTestTracker.h b/src/plugins/JTest/JTestTracker.h index 2b03a0914..3438d8fdb 100644 --- a/src/plugins/JTest/JTestTracker.h +++ b/src/plugins/JTest/JTestTracker.h @@ -17,6 +17,7 @@ class JTestTracker : public JFactoryT { size_t m_write_bytes = 1000; double m_cputime_spread = 0.25; double m_write_spread = 0.25; + JBenchUtils m_bench_utils = JBenchUtils(); public: @@ -36,17 +37,17 @@ class JTestTracker : public JFactoryT { void Process(const std::shared_ptr &aEvent) override { - std::unique_ptr bench_utils = std::make_unique(aEvent->GetEventNumber(), typeid(*this).name()); + m_bench_utils.set_seed(aEvent->GetEventNumber(), typeid(*this).name()); // Read (large) event data auto ed = aEvent->GetSingle(); - bench_utils->read_memory(ed->buffer); + m_bench_utils.read_memory(ed->buffer); // Do lots of computation - bench_utils->consume_cpu_ms(m_cputime_ms, m_cputime_spread); + m_bench_utils.consume_cpu_ms(m_cputime_ms, m_cputime_spread); // Write (small) track data auto td = new JTestTrackData; - bench_utils->write_memory(td->buffer, m_write_bytes, m_write_spread); + m_bench_utils.write_memory(td->buffer, m_write_bytes, m_write_spread); Insert(td); // Insert some additional objects diff --git a/src/programs/unit_tests/Engine/ScaleTests.h b/src/programs/unit_tests/Engine/ScaleTests.h index 96a08098e..6369f5376 100644 --- a/src/programs/unit_tests/Engine/ScaleTests.h +++ b/src/programs/unit_tests/Engine/ScaleTests.h @@ -17,11 +17,14 @@ struct DummySource : public JEventSource { } Result Emit(JEvent& event) override { - std::unique_ptr bench_utils = std::make_unique(event.GetEventNumber(), NAME_OF_THIS); - bench_utils->consume_cpu_ms(20); + m_bench_utils.set_seed(event.GetEventNumber(), NAME_OF_THIS); + m_bench_utils.consume_cpu_ms(20); std::this_thread::sleep_for(std::chrono::nanoseconds(1)); return Result::Success; } + + private: + JBenchUtils m_bench_utils = JBenchUtils(); }; struct DummyProcessor : public JEventProcessor { @@ -30,10 +33,13 @@ struct DummyProcessor : public JEventProcessor { SetCallbackStyle(CallbackStyle::ExpertMode); } void Process(const JEvent& event) override { - std::unique_ptr bench_utils = std::make_unique(event.GetEventNumber(), NAME_OF_THIS); - bench_utils->consume_cpu_ms(100); + m_bench_utils.set_seed(event.GetEventNumber(), NAME_OF_THIS); + m_bench_utils.consume_cpu_ms(100); std::this_thread::sleep_for(std::chrono::nanoseconds(1)); } + + private: + JBenchUtils m_bench_utils = JBenchUtils(); }; } // namespace scaletest #endif //JANA2_SCALETESTS_H diff --git a/src/programs/unit_tests/Topology/TopologyTests.cc b/src/programs/unit_tests/Topology/TopologyTests.cc index 46dd6d3bb..5535cda4d 100644 --- a/src/programs/unit_tests/Topology/TopologyTests.cc +++ b/src/programs/unit_tests/Topology/TopologyTests.cc @@ -162,10 +162,11 @@ TEST_CASE("JTopology: Basic functionality") { step(emit_rand_ints); bool work_left = true; - std::unique_ptr bench_utils = std::make_unique(5, "TopologyTests"); + JBenchUtils bench_utils = JBenchUtils(); + bench_utils.set_seed(5, "TopologyTests"); while (work_left) { // Pick a random arrow - JArrow* arrow = arrows[bench_utils->randint(0, 3)]; + JArrow* arrow = arrows[bench_utils.randint(0, 3)]; auto name = arrow->get_name(); JArrowMetrics metrics; From cfb8195f4744bd299c241e33e147ca5174362468 Mon Sep 17 00:00:00 2001 From: raiqarasool Date: Mon, 9 Sep 2024 10:35:07 -0400 Subject: [PATCH 3/4] JBenchUtils header files added --- src/examples/RootDatamodelExample/JTestRootEventSource.cc | 1 - src/examples/RootDatamodelExample/JTestRootEventSource.h | 2 ++ src/plugins/JTest/JTestPlotter.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/examples/RootDatamodelExample/JTestRootEventSource.cc b/src/examples/RootDatamodelExample/JTestRootEventSource.cc index f8c73ff47..8d8807e5b 100644 --- a/src/examples/RootDatamodelExample/JTestRootEventSource.cc +++ b/src/examples/RootDatamodelExample/JTestRootEventSource.cc @@ -13,7 +13,6 @@ #include #include -#include JTestRootEventSource::JTestRootEventSource() { SetTypeName(NAME_OF_THIS); // Provide JANA with class name diff --git a/src/examples/RootDatamodelExample/JTestRootEventSource.h b/src/examples/RootDatamodelExample/JTestRootEventSource.h index 9f2b46778..b3b2ee913 100644 --- a/src/examples/RootDatamodelExample/JTestRootEventSource.h +++ b/src/examples/RootDatamodelExample/JTestRootEventSource.h @@ -8,6 +8,8 @@ #include #include +#include + class JTestRootEventSource : public JEventSource { diff --git a/src/plugins/JTest/JTestPlotter.h b/src/plugins/JTest/JTestPlotter.h index c01949d99..a37928b9d 100644 --- a/src/plugins/JTest/JTestPlotter.h +++ b/src/plugins/JTest/JTestPlotter.h @@ -7,6 +7,7 @@ #include #include +#include #include "JTestTracker.h" #include From 61ef6f3f96555a6ede2928cf7c24329302ea8d3d Mon Sep 17 00:00:00 2001 From: Nathan Brei Date: Wed, 11 Sep 2024 12:55:31 -0400 Subject: [PATCH 4/4] Remove JPerfUtils --- src/libraries/JANA/CMakeLists.txt | 3 - src/libraries/JANA/Utils/JPerfUtils.cc | 99 ------------------- src/libraries/JANA/Utils/JPerfUtils.h | 25 ----- .../unit_tests/Topology/TopologyTests.cc | 1 - 4 files changed, 128 deletions(-) delete mode 100644 src/libraries/JANA/Utils/JPerfUtils.cc delete mode 100644 src/libraries/JANA/Utils/JPerfUtils.h diff --git a/src/libraries/JANA/CMakeLists.txt b/src/libraries/JANA/CMakeLists.txt index c800b3578..1ca7a8800 100644 --- a/src/libraries/JANA/CMakeLists.txt +++ b/src/libraries/JANA/CMakeLists.txt @@ -31,10 +31,7 @@ set(JANA2_SOURCES Utils/JCpuInfo.cc Utils/JProcessorMapping.cc - Utils/JPerfUtils.cc - Utils/JPerfUtils.h Utils/JBenchUtils.cc - Utils/JBenchUtils.h Utils/JStringification.cc Utils/JAutoActivator.cc Utils/JTablePrinter.cc diff --git a/src/libraries/JANA/Utils/JPerfUtils.cc b/src/libraries/JANA/Utils/JPerfUtils.cc deleted file mode 100644 index 864c53068..000000000 --- a/src/libraries/JANA/Utils/JPerfUtils.cc +++ /dev/null @@ -1,99 +0,0 @@ - -// Copyright 2020, Jefferson Science Associates, LLC. -// Subject to the terms in the LICENSE file found in the top-level directory. - - -#include -#include - -#include "JPerfUtils.h" - - -thread_local std::mt19937* generator = nullptr; - -uint64_t consume_cpu_ms(uint64_t millisecs, double spread, bool fix_flops) { - - uint64_t sampled = rand_size(millisecs, spread); - uint64_t result = 0; - - if (fix_flops) { - // Perform a fixed amount of work in a variable time - const uint64_t appx_iters_per_millisec = 14000; - sampled *= appx_iters_per_millisec; - - for (uint64_t i=0; i& buffer) { - - auto length = buffer.size(); - uint64_t sum = 0; - for (unsigned i=0; i& buffer, uint64_t bytes, double spread) { - - uint64_t sampled = rand_size(bytes, spread); - for (unsigned i=0; i hasher; - long now = std::chrono::steady_clock::now().time_since_epoch().count(); - long seed = now + hasher(std::this_thread::get_id()); - generator = new std::mt19937(seed); - } -} - -size_t rand_size(size_t avg, double spread) { - auto delta = static_cast(avg*spread); - init_generator(); - std::uniform_int_distribution distribution(avg-delta, avg+delta); - return distribution(*generator); -} - - -int randint(int min, int max) { - init_generator(); - std::uniform_int_distribution distribution(min, max); - return distribution(*generator); -} - -double randdouble(double min, double max) { - init_generator(); - std::uniform_real_distribution dist(min, max); - return dist(*generator); -} - -float randfloat(float min, float max) { - init_generator(); - std::uniform_real_distribution dist(min, max); - return dist(*generator); -} - - - diff --git a/src/libraries/JANA/Utils/JPerfUtils.h b/src/libraries/JANA/Utils/JPerfUtils.h deleted file mode 100644 index 08813d4a6..000000000 --- a/src/libraries/JANA/Utils/JPerfUtils.h +++ /dev/null @@ -1,25 +0,0 @@ - -// Copyright 2020, Jefferson Science Associates, LLC. -// Subject to the terms in the LICENSE file found in the top-level directory. - -#pragma once - -#include -#include - -extern thread_local std::mt19937* generator; - - -uint64_t consume_cpu_ms(uint64_t millisecs, double spread=0.0, bool fix_flops=true); - -uint64_t read_memory(const std::vector& buffer); - -uint64_t write_memory(std::vector& buffer, uint64_t bytes, double spread=0.0); - -size_t rand_size(size_t avg, double spread); - -int randint(int min, int max); - -double randdouble(double min=0.0, double max=1000.0); - -float randfloat(float min=0.0, float max=1000.0); diff --git a/src/programs/unit_tests/Topology/TopologyTests.cc b/src/programs/unit_tests/Topology/TopologyTests.cc index 5535cda4d..d13e89c48 100644 --- a/src/programs/unit_tests/Topology/TopologyTests.cc +++ b/src/programs/unit_tests/Topology/TopologyTests.cc @@ -9,7 +9,6 @@ #include "TestTopologyComponents.h" #include -#include #include