Skip to content

Commit a826643

Browse files
sawenzelclaude
andcommitted
Set the number of Geant4 threads before TGeant4 is created
This sizes TGeo for the requested number of transport threads. - TGeant4's constructor sets gGeoManager->SetMaxThreads from Geant4's thread count, before /run/numberOfThreads ran. - The count is now passed in G4FORCENUMBEROFTHREADS before TGeant4 is created. https://its.cern.ch/jira/browse/O2-7305 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 3bd40a3 commit a826643

1 file changed

Lines changed: 7 additions & 5 deletions

File tree

‎Detectors/gconfig/g4Config.C‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ void Config()
167167
}
168168
/// avoid the use of G4BACKTRACE (it seems to inferfere with process logic in o2-sim)
169169
setenv("G4BACKTRACE", "none", 1);
170+
if (mtMode) {
171+
// one transport thread per requested worker; set before TGeant4 exists, since its constructor sizes TGeo for the threads
172+
const char* nthreads = getenv("ALICE_NSIMWORKERS");
173+
setenv("G4FORCENUMBEROFTHREADS", nthreads ? nthreads : "1", 1);
174+
}
170175
/// Create the G4 VMC
171176
TGeant4* geant4 = new TGeant4("TGeant4", "The Geant4 Monte Carlo", runConfiguration);
172177
std::cout << "Geant4 has been created." << std::endl;
@@ -184,9 +189,7 @@ void Config()
184189
if (g4Params.navmode == o2::conf::EG4Nav::kVecGeom) {
185190
LOG(fatal) << "G4.navmode=kVecGeom is not yet supported in multithreaded mode (--isMT)";
186191
}
187-
// one transport thread per requested worker, each taking one sub-event at a time
188-
const char* nthreads = getenv("ALICE_NSIMWORKERS");
189-
geant4->ProcessGeantCommand(Form("/run/numberOfThreads %s", nthreads ? nthreads : "1"));
192+
// each thread takes one sub-event at a time
190193
geant4->ProcessGeantCommand("/run/eventModulo 1");
191194
// a thread without more work ends its own event loop after the current (empty) event
192195
o2::base::MTWorkerHooks::instance().stopWorker = []() { G4RunManager::GetRunManager()->AbortRun(true); };
@@ -196,8 +199,7 @@ void Config()
196199
o2::base::MTWorkerHooks::instance().beginTrack = &o2::simsetup::invalidateFieldCache;
197200
// the primary generator exists only on the worker threads, so its commands are applied there
198201
o2::base::MTWorkerHooks::instance().beginRunOnWorker = []() { G4UImanager::GetUIpointer()->ApplyCommand(kSkipUnknownParticles); };
199-
// the media energy cuts are set after the initialisation run has built all couples, so Geant4 would not apply them;
200-
// marking the region cuts as modified makes the first run recompute the couples and rebuild the physics tables
202+
// the media energy cuts come after the initialisation run built the couples, so the first run must rebuild them
201203
o2::base::MTWorkerHooks::instance().beforeTransport = []() {
202204
for (auto region : *G4RegionStore::GetInstance()) {
203205
if (auto cuts = region->GetProductionCuts()) {

0 commit comments

Comments
 (0)