Skip to content

Commit 33611d4

Browse files
committed
temp saving progress - now woring with meson 1.10
1 parent b729976 commit 33611d4

23 files changed

Lines changed: 670 additions & 502 deletions

actions/run/gRunAction.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ GRunAction::GRunAction(std::shared_ptr<GOptions> gopt, std::shared_ptr<gdynamicd
1212
GBase(gopt, GRUNACTION_LOGGER),
1313
goptions(gopt),
1414
digitization_routines_map(digi_map) {
15-
auto desc = "GRunAction " + std::to_string(G4Threading::G4GetThreadId());
15+
auto desc= std::to_string(G4Threading::G4GetThreadId());
1616

1717
log->debug(CONSTRUCTOR, FUNCTION_NAME, desc);
1818
}
@@ -28,6 +28,7 @@ G4Run* GRunAction::GenerateRun() {
2828

2929
// invoked at the beginning of BeamOn (before physics tables are computed)
3030
void GRunAction::BeginOfRunAction(const G4Run* aRun) {
31+
3132
int thread_id = G4Threading::G4GetThreadId();
3233
int run = aRun->GetRunID();
3334
int neventsThisRun = aRun->GetNumberOfEventToBeProcessed();
@@ -54,8 +55,8 @@ void GRunAction::BeginOfRunAction(const G4Run* aRun) {
5455

5556
// invoked at the very end of the run processing
5657
void GRunAction::EndOfRunAction(const G4Run* aRun) {
57-
// const GRun* theRun = static_cast<const GRun*>(aRun);
5858

59+
// const GRun* theRun = static_cast<const GRun*>(aRun);
5960
int thread_id = G4Threading::G4GetThreadId();
6061
int run = aRun->GetRunID();
6162
std::string what_am_i = IsMaster() ? "Master" : "Worker";

examples/basic/b1/b1.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
experiment: examples
22
runno: 1
3-
n: 5
3+
n: 50
44
nthreads: 12
55

66
gparticle:

examples/basic/b1/geometry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def build_geometry(configuration):
5252
gvolume.material = 'G4_BONE_COMPACT_ICRU'
5353
gvolume.color = 'lightgray'
5454
gvolume.set_position(0, -10, 70)
55-
gvolume.digitization = 'flux' # temp assigning flux for testing digitization routines
55+
gvolume.digitization = 'dosimeter' # collects edep, dose
5656
gvolume.set_identifier('box', 2)
5757
gvolume.opacity = 0.1
5858
gvolume.publish(configuration)

gdata/event/gEventDataCollection.h

Lines changed: 72 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -18,80 +18,83 @@
1818
constexpr const char* GEVENTDATA_LOGGER = "gevent_data";
1919

2020
namespace gevent_data {
21-
inline GOptions defineOptions() {
22-
auto goptions = GOptions(GEVENTDATA_LOGGER);
23-
goptions += geventheader::defineOptions();
24-
goptions += gtrue_data::defineOptions();
25-
goptions += gdigi_data::defineOptions();
26-
goptions += gtouchable::defineOptions();
27-
return goptions;
28-
}
21+
inline auto defineOptions() -> GOptions {
22+
auto goptions = GOptions(GEVENTDATA_LOGGER);
23+
goptions += geventheader::defineOptions();
24+
goptions += gtrue_data::defineOptions();
25+
goptions += gdigi_data::defineOptions();
26+
goptions += gtouchable::defineOptions();
27+
return goptions;
2928
}
29+
} // namespace gevent_data
3030

3131

32-
class GEventDataCollection : public GBase<GEventDataCollection> {
32+
class GEventDataCollection : public GBase<GEventDataCollection>
33+
{
3334
public:
34-
/**
35-
* \brief Constructs a GEventDataCollection.
36-
*
37-
* \param header Pointer to the event header.
38-
* \param logger Pointer to a GLogger instance (using the 'gdata' name).
39-
*/
40-
41-
GEventDataCollection(const std::shared_ptr<GOptions>& gopts, std::unique_ptr<GEventHeader> header)
42-
: GBase(gopts, GDATAEVENTHEADER_LOGGER), gevent_header(std::move(header)) { }
43-
44-
/**
45-
* \brief Adds true hit information data for a detector.
46-
* \param sdName The sensitive detector name.
47-
* \param data Pointer to GTrueInfoData.
48-
*/
49-
void addDetectorTrueInfoData(const std::string& sdName, std::unique_ptr<GTrueInfoData> data);
50-
51-
/**
52-
* \brief Adds digitized hit data for a detector.
53-
* \param sdName The sensitive detector name.
54-
* \param data Pointer to GDigitizedData.
55-
*/
56-
void addDetectorDigitizedData(const std::string& sdName, std::unique_ptr<GDigitizedData> data);
57-
58-
/**
59-
* \brief Gets the event header.
60-
* \return Pointer to the event header.
61-
*/
62-
[[nodiscard]] inline const std::unique_ptr<GEventHeader>& getHeader() const { return gevent_header; }
63-
64-
/**
65-
* \brief Gets the map of data collections.
66-
* \return Pointer to the map from detector names to GDataCollection.
67-
*/
68-
[[nodiscard]] inline const std::map<std::string, std::unique_ptr<GDataCollection>>& getDataCollectionMap() const { return gdataCollectionMap; }
69-
70-
/**
71-
* \brief Gets the event number.
72-
* \return The event number.
73-
*/
74-
[[nodiscard]] inline int getEventNumber() const { return gevent_header->getG4LocalEvn(); }
75-
76-
// returning shared here as GEventDataCollection may be used by multiple streams and also collected in a runData vector
77-
static std::shared_ptr<GEventDataCollection> create(const std::shared_ptr<GOptions>& gopts) {
78-
auto header = GEventHeader::create(gopts);
79-
auto edc = std::make_shared<GEventDataCollection>(gopts, std::move(header));
80-
81-
auto digi_data = GDigitizedData::create(gopts);
82-
auto true_data = GTrueInfoData::create(gopts);
83-
84-
edc->addDetectorDigitizedData("ctof", std::move(digi_data));
85-
edc->addDetectorTrueInfoData("ctof", std::move(true_data));
86-
87-
return edc;
88-
}
35+
/**
36+
* \brief Constructs a GEventDataCollection.
37+
*
38+
* \param gopts Pointer to GOptions
39+
* \param header Pointer to the event header.
40+
*/
41+
42+
GEventDataCollection(const std::shared_ptr<GOptions>& gopts, std::unique_ptr<GEventHeader> header)
43+
: GBase(gopts, GDATAEVENTHEADER_LOGGER), gevent_header(std::move(header)) {
44+
}
45+
46+
/**
47+
* \brief Adds true hit information data for a detector.
48+
* \param sdName The sensitive detector name.
49+
* \param data Pointer to GTrueInfoData.
50+
*/
51+
void addDetectorTrueInfoData(const std::string& sdName, std::unique_ptr<GTrueInfoData> data);
52+
53+
/**
54+
* \brief Adds digitized hit data for a detector.
55+
* \param sdName The sensitive detector name.
56+
* \param data Pointer to GDigitizedData.
57+
*/
58+
void addDetectorDigitizedData(const std::string& sdName, std::unique_ptr<GDigitizedData> data);
59+
60+
/**
61+
* \brief Gets the event header.
62+
* \return Pointer to the event header.
63+
*/
64+
[[nodiscard]] auto getHeader() const -> const std::unique_ptr<GEventHeader>& { return gevent_header; }
65+
66+
/**
67+
* \brief Gets the map of data collections.
68+
* \return Pointer to the map from detector names to GDataCollection.
69+
*/
70+
[[nodiscard]] auto getDataCollectionMap() const -> const std::map<std::string, std::unique_ptr<GDataCollection>>& {
71+
return gdataCollectionMap;
72+
}
73+
74+
/**
75+
* \brief Gets the event number.
76+
* \return The event number.
77+
*/
78+
[[nodiscard]] auto getEventNumber() const -> int { return gevent_header->getG4LocalEvn(); }
79+
80+
// returning shared here as GEventDataCollection may be used by multiple streams and also collected in a runData vector
81+
static auto create(const std::shared_ptr<GOptions>& gopts) -> std::shared_ptr<GEventDataCollection> {
82+
auto header = GEventHeader::create(gopts);
83+
auto edc = std::make_shared<GEventDataCollection>(gopts, std::move(header));
84+
85+
auto digi_data = GDigitizedData::create(gopts);
86+
auto true_data = GTrueInfoData::create(gopts);
87+
88+
edc->addDetectorDigitizedData("ctof", std::move(digi_data));
89+
edc->addDetectorTrueInfoData("ctof", std::move(true_data));
90+
91+
return edc;
92+
}
8993

9094
private:
91-
std::unique_ptr<GEventHeader> gevent_header;
92-
std::map<std::string, std::unique_ptr<GDataCollection>> gdataCollectionMap; // keyed by the sensitive detector name.
93-
94-
/// Static thread-safe event counter - used for testing only
95-
static std::atomic<int> globalEventDataCollectionCounter;
95+
std::unique_ptr<GEventHeader> gevent_header;
96+
std::map<std::string, std::unique_ptr<GDataCollection>> gdataCollectionMap; // keyed by the sensitive detector name.
9697

98+
/// Static thread-safe event counter - used for testing only
99+
static std::atomic<int> globalEventDataCollectionCounter;
97100
};

gdata/examples/event_example.cc

Lines changed: 68 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
*/
2424

2525
// gdata
26-
#include "event/gEventDataCollection.h"
26+
#include "run/gRunDataCollection.h"
27+
2728

2829
// gemc
2930
#include "glogger.h"
@@ -32,76 +33,81 @@
3233
auto run_simulation_in_threads(int nevents,
3334
int nthreads,
3435
const std::shared_ptr<GOptions>& gopt,
35-
const std::shared_ptr<GLogger>& log) -> std::vector<std::shared_ptr<GEventDataCollection>> {
36-
std::mutex collectorMtx;
37-
std::vector<std::shared_ptr<GEventDataCollection>> collected;
38-
39-
// thread-safe integer counter starts at 1.
40-
// fetch_add returns the old value *and* bumps.
41-
// zero contention: each thread fetches the next free event number.
42-
std::atomic<int> next{1};
43-
44-
// pool of jthreads. jthread joins in its destructor so we don’t need an
45-
// explicit loop at the end.
46-
// each element represents one worker thread running your event-processing lambda.
47-
// std::vector<std::jthread> pool; use this when C++20 is widely available
48-
std::vector<jthread_alias> pool; // was std::vector<std::jthread>
49-
50-
pool.reserve(nthreads);
51-
52-
for (int tid = 0; tid < nthreads; ++tid) {
53-
// The capture [&, tid] gives the thread references to variables like next, nevents, runDataMtx, etc.
54-
pool.emplace_back([&, tid] // capture tid *by value*
55-
{
56-
// start the thread with a lambda
57-
log->info(0, "worker ", tid, " started");
58-
59-
int localCount = 0; // events built by *this* worker
60-
thread_local std::vector<std::shared_ptr<GEventDataCollection>> localRunData;
61-
62-
while (true) {
63-
// repeatedly asks the shared atomic counter for “the next unclaimed event
64-
// number,” processes that event, stores the result, and goes back for more.
65-
// memory_order_relaxed: we only need *atomicity*, no ordering
66-
int evn = next.fetch_add(1, std::memory_order_relaxed); // atomically returns the current value and increments it by 1.
67-
if (evn > nevents) break; // exit the while loop
68-
69-
auto event_data_collection = GEventDataCollection::create(gopt);
70-
localRunData.emplace_back(event_data_collection);
71-
72-
++localCount; // tally for this worker
73-
}
74-
75-
// braces to lock the mutex when it's constructed and unlocks when it is destroyed
76-
{
77-
std::scoped_lock lk(collectorMtx);
78-
for (auto& evt : localRunData) { collected.emplace_back(evt); }
79-
localRunData.clear();
80-
}
81-
82-
log->info(0, "worker ", tid, " processed ", localCount, " events");
83-
}); // jthread constructor launches the thread immediately
84-
} // pool’s destructor blocks until every jthread has joined
85-
return collected;
36+
const std::shared_ptr<GLogger>& log) -> std::vector<std::shared_ptr<
37+
GEventDataCollection>> {
38+
std::mutex collectorMtx;
39+
std::vector<std::shared_ptr<GEventDataCollection>> collected;
40+
41+
// thread-safe integer event counter starts at 1.
42+
// fetch_add returns the old value *and* bumps.
43+
// zero contention: each thread fetches the next free event number.
44+
std::atomic<int> next{1};
45+
46+
// pool of jthreads. jthread joins in its destructor so we don’t need an
47+
// explicit loop at the end.
48+
// each element represents one worker thread running your event-processing lambda.
49+
// std::vector<std::jthread> pool; use this when C++20 is widely available
50+
std::vector<jthread_alias> pool; // was std::vector<std::jthread>
51+
52+
pool.reserve(nthreads);
53+
54+
for (int tid = 0; tid < nthreads; ++tid) {
55+
// The capture [&, tid] gives the thread references to variables like next, nevents, runDataMtx, etc.
56+
pool.emplace_back([&, tid] // capture tid *by value*
57+
{
58+
// start the thread with a lambda
59+
log->info(0, "worker ", tid, " started");
60+
61+
int localCount = 0; // events built by *this* worker
62+
thread_local std::vector<std::shared_ptr<GEventDataCollection>> localRunData;
63+
64+
while (true) {
65+
// repeatedly asks the shared atomic counter for “the next unclaimed event
66+
// number,” processes that event, stores the result, and goes back for more.
67+
// memory_order_relaxed: we only need *atomicity*, no ordering
68+
int evn = next.fetch_add(1, std::memory_order_relaxed);
69+
// atomically returns the current value and increments it by 1.
70+
if (evn > nevents) { break ;} // exit the while loop
71+
72+
73+
auto event_data_collection = GEventDataCollection::create(gopt);
74+
localRunData.emplace_back(event_data_collection);
75+
76+
++localCount; // tally for this worker
77+
}
78+
79+
// braces to lock the mutex when it's constructed and unlocks when it is destroyed
80+
{
81+
std::scoped_lock lk(collectorMtx);
82+
for (auto& evt : localRunData) { collected.emplace_back(evt); }
83+
localRunData.clear();
84+
}
85+
86+
log->info(0, "worker ", tid, " processed ", localCount, " events");
87+
}); // jthread constructor launches the thread immediately
88+
} // pool’s destructor blocks until every jthread has joined
89+
return collected;
8690
}
8791

8892

8993
// emulation of a run of events, collecting data in separate threads
9094

9195
int main(int argc, char* argv[]) {
92-
// Create GOptions using gevent_data::defineOptions, which aggregates options from all gdata and gtouchable.
93-
auto gopts = std::make_shared<GOptions>(argc, argv, gevent_data::defineOptions());
96+
// Create GOptions using gevent_data::defineOptions, which aggregates options from all gdata and gtouchable.
97+
auto gopts = std::make_shared<GOptions>(argc, argv, gevent_data::defineOptions());
9498

95-
// Create loggers: one for gdata and one for gtouchable.
96-
auto log = std::make_shared<GLogger>(gopts, SFUNCTION_NAME, GEVENTDATA_LOGGER);
99+
// Create loggers: one for gdata and one for gtouchable.
100+
auto log = std::make_shared<GLogger>(gopts, SFUNCTION_NAME, GEVENTDATA_LOGGER);
97101

98-
constexpr int nevents = 10;
99-
constexpr int nthreads = 8;
102+
constexpr int nevents = 10;
103+
constexpr int nthreads = 8;
100104

101-
auto runData = run_simulation_in_threads(nevents, nthreads, gopts, log);
105+
auto runData = run_simulation_in_threads(nevents, nthreads, gopts, log);
102106

103-
// For demonstration, we'll simply print the event numbers.
104-
for (size_t i = 0; i < runData.size(); i++) { log->info("event n. ", i + 1, " collected with local event number: ", runData[i]->getEventNumber()); }
107+
// For demonstration, we'll simply print the event numbers.
108+
for (size_t i = 0; i < runData.size(); i++) {
109+
log->info("event n. ", i + 1, " collected with local event number: ", runData[i]->getEventNumber());
110+
}
105111

106-
return EXIT_SUCCESS;
112+
return EXIT_SUCCESS;
107113
}

0 commit comments

Comments
 (0)