Skip to content

Commit

Permalink
Merge pull request #374 from JeffersonLab/nbrei_modernize_jtest
Browse files Browse the repository at this point in the history
Modernize JTest
  • Loading branch information
nathanwbrei authored Oct 17, 2024
2 parents ecb73f7 + 085f245 commit 073d8a4
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 130 deletions.
32 changes: 16 additions & 16 deletions docs/howto/other-howtos.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,22 +89,22 @@ The `JTest` plugin lets you test JANA's performance for different workloads. It

| Name | Type | Default | Description |
|:-----|:-----|:------------|:--------|
jtest:parser_ms | int | 0 | Time spent during parsing
jtest:parser_spread | int | 0.25 | Spread of time spent during parsing
jtest:parser_bytes | int | 2000000 | Bytes written during parsing
jtest:parser_bytes_spread | double | 0.25 | Spread of bytes written during parsing
jtest:disentangler_ms | int | 20 | Time spent during disentangling
jtest:disentangler_spread | double | 0.25 | Spread of time spent during disentangling
jtest:disentangler_bytes | int | 500000 | Bytes written during disentangling
jtest:disentangler_bytes_spread | double | 0.25 | Spread of bytes written during disentangling
jtest:tracker_ms | int | 200 | Time spent during tracking
jtest:tracker_spread | double | 0.25 | Spread of time spent during tracking
jtest:tracker_bytes | int | 1000 | Bytes written during tracking
jtest:tracker_bytes_spread | double | 0.25 | Spread of bytes written during tracking
jtest:plotter_ms | int | 0 | Time spent during plotting
jtest:plotter_spread | double | 0.25 | Spread of time spent during plotting
jtest:plotter_bytes | int | 1000 | Bytes written during plotting
jtest:plotter_bytes_spread | double | 0.25 | Spread of bytes written during plotting
jtest:parser:cputime_ms | int | 0 | Time spent during parsing
jtest:parser:cputime_spread | int | 0.25 | Spread of time spent during parsing
jtest:parser:bytes | int | 2000000 | Bytes written during parsing
jtest:parser:bytes_spread | double | 0.25 | Spread of bytes written during parsing
jtest:disentangler:cputime_ms | int | 20 | Time spent during disentangling
jtest:disentangler:cputime_spread | double | 0.25 | Spread of time spent during disentangling
jtest:disentangler:bytes | int | 500000 | Bytes written during disentangling
jtest:disentangler:bytes_spread | double | 0.25 | Spread of bytes written during disentangling
jtest:tracker:cputime_ms | int | 200 | Time spent during tracking
jtest:tracker:cputime_spread | double | 0.25 | Spread of time spent during tracking
jtest:tracker:bytes | int | 1000 | Bytes written during tracking
jtest:tracker:bytes_spread | double | 0.25 | Spread of bytes written during tracking
jtest:plotter:cputime_ms | int | 0 | Time spent during plotting
jtest:plotter:cputime_spread | double | 0.25 | Spread of time spent during plotting
jtest:plotter:bytes | int | 1000 | Bytes written during plotting
jtest:plotter:bytes_spread | double | 0.25 | Spread of bytes written during plotting



Expand Down
22 changes: 18 additions & 4 deletions src/libraries/JANA/Components/JHasInputs.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ struct JHasInputs {
Input(JHasInputs* owner) {
owner->RegisterInput(this);
this->type_name = JTypeInfo::demangle<T>();
this->names.push_back("");
// For non-PODIO inputs, these are technically tags for now, not names
this->levels.push_back(JEventLevel::None);
}

Input(JHasInputs* owner, const InputOptions& options) {
Expand All @@ -96,30 +99,33 @@ struct JHasInputs {
}

const std::vector<const T*>& operator()() { return m_data; }
const std::vector<const T*>& operator*() { return m_data; }
const std::vector<const T*>* operator->() { return &m_data; }


private:
friend class JComponentT;

void GetCollection(const JEvent& event) {
auto& level = this->levels[0];
m_data.clear();
if (level == event.GetLevel() || level == JEventLevel::None) {
m_data = event.Get<T>(this->names[0], !this->is_optional);
event.Get<T>(m_data, this->names[0], !this->is_optional);
}
else {
if (this->is_optional && !event.HasParent(level)) return;
m_data = event.GetParent(level).template Get<T>(this->names[0], !this->is_optional);
event.GetParent(level).template Get<T>(m_data, this->names[0], !this->is_optional);
}
}
void PrefetchCollection(const JEvent& event) {
auto& level = this->levels[0];
auto& name = this->names[0];
if (level == event.GetLevel() || level == JEventLevel::None) {
event.Get<T>(name, !this->is_optional);
event.GetFactory<T>(name, !this->is_optional)->Create(event.shared_from_this());
}
else {
if (this->is_optional && !event.HasParent(level)) return;
event.GetParent(level).template Get<T>(name, !this->is_optional);
event.GetParent(level).template GetFactory<T>(name, !this->is_optional)->Create(event.shared_from_this());
}
}
};
Expand All @@ -135,6 +141,8 @@ struct JHasInputs {
PodioInput(JHasInputs* owner) {
owner->RegisterInput(this);
this->type_name = JTypeInfo::demangle<PodioT>();
this->names.push_back(this->type_name);
this->levels.push_back(JEventLevel::None);
}

PodioInput(JHasInputs* owner, const InputOptions& options) {
Expand All @@ -146,6 +154,12 @@ struct JHasInputs {
const typename PodioT::collection_type* operator()() {
return m_data;
}
const typename PodioT::collection_type& operator*() {
return *m_data;
}
const typename PodioT::collection_type* operator->() {
return m_data;
}

void GetCollection(const JEvent& event) {
auto& level = this->levels[0];
Expand Down
17 changes: 11 additions & 6 deletions src/libraries/JANA/JEventSource.cc
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
#include <JANA/JEventSource.h>

void JEventSource::DoInit() {
if (m_status == Status::Uninitialized) {
CallWithJExceptionWrapper("JEventSource::Init", [&](){ Init();});
m_status = Status::Initialized;
LOG_INFO(GetLogger()) << "Initialized JEventSource '" << GetTypeName() << "' ('" << GetResourceName() << "')" << LOG_END;
std::lock_guard<std::mutex> lock(m_mutex);
if (m_status != Status::Uninitialized) {
throw JException("Attempted to initialize a JEventSource that is already initialized!");
}
else {
throw JException("Attempted to initialize a JEventSource that is not uninitialized!");
for (auto* parameter : m_parameters) {
parameter->Configure(*(m_app->GetJParameterManager()), m_prefix);
}
for (auto* service : m_services) {
service->Fetch(m_app);
}
CallWithJExceptionWrapper("JEventSource::Init", [&](){ Init(); });
m_status = Status::Initialized;
LOG_INFO(GetLogger()) << "Initialized JEventSource '" << GetTypeName() << "' ('" << GetResourceName() << "')" << LOG_END;
}

void JEventSource::DoInitialize() {
Expand Down
15 changes: 5 additions & 10 deletions src/libraries/JANA/JEventUnfolder.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,23 +61,18 @@ class JEventUnfolder : public jana::components::JComponent,

void DoInit() {
std::lock_guard<std::mutex> lock(m_mutex);
if (m_status != Status::Uninitialized) {
throw JException("JEventUnfolder: Attempting to initialize twice or from an invalid state");
}
// TODO: Obtain overrides of collection names from param manager

for (auto* parameter : m_parameters) {
parameter->Configure(*(m_app->GetJParameterManager()), m_prefix);
}
for (auto* service : m_services) {
service->Fetch(m_app);
}
if (m_status == Status::Uninitialized) {
CallWithJExceptionWrapper("JEventUnfolder::Init", [&](){
Init();
});
m_status = Status::Initialized;
}
else {
throw JException("JEventUnfolder: Attempting to initialize twice or from an invalid state");
}
CallWithJExceptionWrapper("JEventUnfolder::Init", [&](){Init();});
m_status = Status::Initialized;
}

void DoPreprocess(const JEvent& parent) {
Expand Down
16 changes: 11 additions & 5 deletions src/libraries/JANA/JFactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ void JFactory::Create(const std::shared_ptr<const JEvent>& event) {
}

if (mStatus == Status::Uninitialized) {
CallWithJExceptionWrapper("JFactory::Init", [&](){ Init(); });
mStatus = Status::Unprocessed;
DoInit();
}

auto src = event->GetJEventSource();
Expand Down Expand Up @@ -66,10 +65,17 @@ void JFactory::Create(const std::shared_ptr<const JEvent>& event) {
}

void JFactory::DoInit() {
if (mStatus == Status::Uninitialized) {
CallWithJExceptionWrapper("JFactory::Init", [&](){ Init(); });
mStatus = Status::Unprocessed;
if (mStatus != Status::Uninitialized) {
throw JException("Attempted to initialize a JFactory that has already been initialized!");
}
for (auto* parameter : m_parameters) {
parameter->Configure(*(m_app->GetJParameterManager()), m_prefix);
}
for (auto* service : m_services) {
service->Fetch(m_app);
}
CallWithJExceptionWrapper("JFactory::Init", [&](){ Init(); });
mStatus = Status::Unprocessed;
}

void JFactory::Summarize(JComponentSummary& summary) const {
Expand Down
15 changes: 10 additions & 5 deletions src/libraries/JANA/JMultifactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,17 @@ JFactorySet* JMultifactory::GetHelpers() {
void JMultifactory::DoInit() {

std::lock_guard<std::mutex> lock(m_mutex);
if (m_status == Status::Uninitialized) {
CallWithJExceptionWrapper("JMultifactory::Init", [&](){
Init();
});
m_status = Status::Initialized;
if (m_status != Status::Uninitialized) {
throw JException("Attempted to initialzie a JMultifactory that has already been initialized!");
}
CallWithJExceptionWrapper("JMultifactory::Init", [&](){ Init(); });
for (auto* parameter : m_parameters) {
parameter->Configure(*(m_app->GetJParameterManager()), m_prefix);
}
for (auto* service : m_services) {
service->Fetch(m_app);
}
m_status = Status::Initialized;
}

void JMultifactory::Summarize(JComponentSummary& summary) const {
Expand Down
7 changes: 6 additions & 1 deletion src/plugins/JTest/JTestCalibrationService.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@
#ifndef JANA2_JTESTCALIBRATIONSERVICE_H
#define JANA2_JTESTCALIBRATIONSERVICE_H

#include <JANA/JService.h>

struct JTestCalibrationService: JService {

Parameter<double> m_calibration_value{this, "calibration_value", 7.0, "Dummy calibration value"};

double getCalibration() {
return 7.0;
return *m_calibration_value;
}

};
Expand Down
6 changes: 6 additions & 0 deletions src/plugins/JTest/JTestDataObjects.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,10 @@ struct JTestHistogramData : public JObject {
JOBJECT_PUBLIC(JTestHistogramData)
};

struct JTestTrackAuxilliaryData : public JObject {
int something = 1;
float something2 = 2;
JOBJECT_PUBLIC(JTestTrackAuxilliaryData)
};

#endif //JANA2_JTESTEVENTCONTEXTS_H
33 changes: 14 additions & 19 deletions src/plugins/JTest/JTestDisentangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,39 @@

class JTestDisentangler : public JFactoryT<JTestEventData> {

size_t m_cputime_ms = 20;
size_t m_write_bytes = 500000;
double m_cputime_spread = 0.25;
double m_write_spread = 0.25;
JBenchUtils m_bench_utils = JBenchUtils();
Parameter<size_t> m_cputime_ms {this, "cputime_ms", 20, "Time spent during disentangling" };
Parameter<size_t> m_write_bytes {this, "bytes", 500000, "Bytes written during disentangling"};
Parameter<double> m_cputime_spread {this, "cputime_spread", 0.25, "Spread of time spent during disentangling"};
Parameter<double> m_write_spread {this, "bytes_spread", 0.25, "Spread of bytes written during disentangling"};

std::shared_ptr<JTestCalibrationService> m_calibration_service;
Service<JTestCalibrationService> m_calibration_service {this};

public:
JBenchUtils m_bench_utils;

void Init() override {
auto app = GetApplication();
assert (app != nullptr);
app->SetDefaultParameter("jtest:disentangler_ms", m_cputime_ms, "Time spent during disentangling");
app->SetDefaultParameter("jtest:disentangler_spread", m_cputime_spread, "Spread of time spent during disentangling");
app->SetDefaultParameter("jtest:disentangler_bytes", m_write_bytes, "Bytes written during disentangling");
app->SetDefaultParameter("jtest:disentangler_bytes_spread", m_write_spread, "Spread of bytes written during disentangling");
public:

// Retrieve calibration service from JApp
m_calibration_service = app->GetService<JTestCalibrationService>();
JTestDisentangler() {
SetPrefix("jtest:disentangler");
SetTypeName(NAME_OF_THIS);
}

void Process(const std::shared_ptr<const JEvent> &aEvent) override {

m_bench_utils.set_seed(aEvent->GetEventNumber(), NAME_OF_THIS);

// Read (large) entangled event data
auto eed = aEvent->GetSingle<JTestEntangledEventData>();
m_bench_utils.read_memory(*eed->buffer);

// Read calibration data
m_calibration_service->getCalibration();
auto calib = m_calibration_service->getCalibration();

// Do a little bit of computation
m_bench_utils.consume_cpu_ms(m_cputime_ms, m_cputime_spread);
m_bench_utils.consume_cpu_ms(*m_cputime_ms + calib, *m_cputime_spread);

// Write (large) event data
auto ed = new JTestEventData;
m_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);
}
};
Expand Down
23 changes: 8 additions & 15 deletions src/plugins/JTest/JTestParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@

#include <JANA/Utils/JBenchUtils.h>


#include "JTestDataObjects.h"


class JTestParser : public JEventSource {

size_t m_cputime_ms = 0;
size_t m_write_bytes = 2000000;
double m_cputime_spread = 0.25;
double m_write_spread = 0.25;
Parameter<size_t> m_cputime_ms {this, "cputime_ms", 0, "Time spent during parsing" };
Parameter<size_t> m_write_bytes {this, "bytes", 2000000, "Bytes written during parsing"};
Parameter<double> m_cputime_spread {this, "cputime_spread", 0.25, "Spread of time spent during parsing"};
Parameter<double> m_write_spread {this, "bytes_spread", 0.25, "Spread of bytes written during parsing"};

JBenchUtils m_bench_utils = JBenchUtils();
std::shared_ptr<std::vector<char>> m_latest_entangled_buffer;

Expand All @@ -32,6 +32,7 @@ class JTestParser : public JEventSource {
public:

JTestParser() {
SetPrefix("jtest:parser");
SetTypeName(NAME_OF_THIS);
SetCallbackStyle(CallbackStyle::ExpertMode);
}
Expand All @@ -40,14 +41,6 @@ class JTestParser : public JEventSource {
return "JTest Fake Event Source";
}

void Init() override {
auto app = GetApplication();
app->SetDefaultParameter("jtest:parser_ms", m_cputime_ms, "Time spent during parsing");
app->SetDefaultParameter("jtest:parser_spread", m_cputime_spread, "Spread of time spent during parsing");
app->SetDefaultParameter("jtest:parser_bytes", m_write_bytes, "Bytes written during parsing");
app->SetDefaultParameter("jtest:parser_bytes_spread", m_write_spread, "Spread of bytes written during parsing");
}

void Open() override {
}

Expand All @@ -62,11 +55,11 @@ class JTestParser : public JEventSource {
if ((prev_m_events_generated % 40) == 0) {
// "Read" new entangled event every 40 events
m_latest_entangled_buffer = std::shared_ptr<std::vector<char>>(new std::vector<char>);
m_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
m_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;
Expand Down
Loading

0 comments on commit 073d8a4

Please sign in to comment.