From 002aeae5cf2b93193392ad0846010e3e663a2617 Mon Sep 17 00:00:00 2001 From: raiqarasool Date: Thu, 22 Aug 2024 09:17:22 -0400 Subject: [PATCH 1/6] 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/6] 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/6] 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/6] 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 From dc64be5447f8fd42e389b423cccb6286651cf67d Mon Sep 17 00:00:00 2001 From: raiqarasool Date: Wed, 11 Sep 2024 13:36:31 -0400 Subject: [PATCH 5/6] Modified JANA1to2 main page for links --- docs/jana1to2/transition-guide-jana1-to-jana2.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/jana1to2/transition-guide-jana1-to-jana2.md b/docs/jana1to2/transition-guide-jana1-to-jana2.md index 991b513aa..e411a4a91 100644 --- a/docs/jana1to2/transition-guide-jana1-to-jana2.md +++ b/docs/jana1to2/transition-guide-jana1-to-jana2.md @@ -1,16 +1,14 @@ # Transition Guides for JANA1 to JANA2 -Welcome to the transition guides for JANA1 to JANA2! This page provides an overview of the changes and directs you to detailed documentation to help you navigate the updates effectively. +Welcome to the transition guides for JANA1 to JANA2! This page provides an overview of the changes and directs you to detailed documentation to help you navigate the updates effectively. As JANA transitions from version 1 (JANA1) to version 2 (JANA2), several important changes have been made. To assist you in adapting to these changes, we have created two comprehensive guides: -## Overview +## 1. **Developers Transition Guide:** +This guide focuses on key syntax and structural changes between JANA1 and JANA2. It is intended for developers who need to understand and update their codebase according to the new standards. + - [Developers Transition Guide: Key Syntax Changes](jana1to2/developers-transition-guide.md) -As JANA transitions from version 1 (JANA1) to version 2 (JANA2), several important changes have been made. To assist you in adapting to these changes, we have created two comprehensive guides: - -1. **Developers Transition Guide:** This guide focuses on key syntax and structural changes between JANA1 and JANA2. It is intended for developers who need to understand and update their codebase according to the new standards. - - [Developers Transition Guide: Key Syntax Changes](developers-transition-guide.md) - -2. **Parameter Changes Guide:** This guide details the changes in parameters between JANA1 and JANA2. It provides user-focused information on how these changes impact configurations and usage. - - [Parameter Changes Guide](parameter-changes-guide.md) +## 2. **Parameter Changes Guide:** +This guide details the changes in parameters between JANA1 and JANA2. It provides user-focused information on how these changes impact configurations and usage. + - [Parameter Changes Guide](jana1to2/parameter-changes-guide.md) These resources are designed to help you understand the modifications and adapt your workflow accordingly. For additional assistance or if you have any questions, contact [rasool@jlab.org](mailto:rasool@jlab.org). \ No newline at end of file From aa8e392c9f5d451a8eb6dfcccc8fa62b05053c64 Mon Sep 17 00:00:00 2001 From: raiqarasool Date: Wed, 11 Sep 2024 13:38:20 -0400 Subject: [PATCH 6/6] Modified JANA1to2 main page for headings --- docs/jana1to2/transition-guide-jana1-to-jana2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/jana1to2/transition-guide-jana1-to-jana2.md b/docs/jana1to2/transition-guide-jana1-to-jana2.md index e411a4a91..489cee2f0 100644 --- a/docs/jana1to2/transition-guide-jana1-to-jana2.md +++ b/docs/jana1to2/transition-guide-jana1-to-jana2.md @@ -2,11 +2,11 @@ Welcome to the transition guides for JANA1 to JANA2! This page provides an overview of the changes and directs you to detailed documentation to help you navigate the updates effectively. As JANA transitions from version 1 (JANA1) to version 2 (JANA2), several important changes have been made. To assist you in adapting to these changes, we have created two comprehensive guides: -## 1. **Developers Transition Guide:** +## Developers Transition Guide This guide focuses on key syntax and structural changes between JANA1 and JANA2. It is intended for developers who need to understand and update their codebase according to the new standards. - [Developers Transition Guide: Key Syntax Changes](jana1to2/developers-transition-guide.md) -## 2. **Parameter Changes Guide:** +## Parameter Changes Guide This guide details the changes in parameters between JANA1 and JANA2. It provides user-focused information on how these changes impact configurations and usage. - [Parameter Changes Guide](jana1to2/parameter-changes-guide.md)