ATLAS Offline Software
G4ThreadInitTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Main header include
6 #include "G4ThreadInitTool.h"
8 
9 // Geant4 includes
10 #include "G4WorkerRunManager.hh"
11 #include "G4UImanager.hh"
12 #include "G4MTRunManager.hh"
13 #include "G4WorkerThread.hh"
14 #include "G4UserWorkerThreadInitialization.hh"
15 #include "G4RunManager.hh"
16 #include "G4VUserActionInitialization.hh"
17 #include "G4UserWorkerInitialization.hh"
18 #include "G4AutoDelete.hh"
19 
20 // System includes
21 #include <unistd.h>
22 #include <sys/syscall.h>
23 
24 //-----------------------------------------------------------------------------
25 // Constructor
26 //-----------------------------------------------------------------------------
28  const std::string& name,
29  const IInterface* parent)
30  : base_class(type, name, parent),
31  m_nInitThreads(0)
32 {}
33 
34 //-----------------------------------------------------------------------------
35 // Worker thread initialization.
36 // This code is modeled after G4MTRunManagerKernel::StartThread.
37 //-----------------------------------------------------------------------------
39 {
40  ATH_MSG_INFO("==> tbb thread started with id: 0x" <<
41  std::hex << pthread_self() << std::dec);
42 
43  // Define the G4 worker thread context and setup its cleanup mechanism.
44  auto wThreadContext = new G4WorkerThread;
45  G4AutoDelete::Register(wThreadContext);
46 
47  // Assign the thread ID
48  static std::atomic_uint tid(0);
49  wThreadContext->SetThreadId( tid++ );
50  G4Threading::G4SetThreadId( wThreadContext->GetThreadId() );
51 
52  // Setup thread-local geometry and physics
53  wThreadContext->BuildGeometryAndPhysicsVector();
54 
55  // Retrieve the master thread run manager
56  G4MTRunManager* masterRM = G4MTRunManager::GetMasterRunManager();
57  // Worker thread initialization object
58  const G4UserWorkerThreadInitialization* workerInitializer =
59  masterRM->GetUserWorkerThreadInitialization();
60 
61  // Random number setup.
62  // TODO: revisit this once MT AthRNGSvc is available.
63  const CLHEP::HepRandomEngine* masterEngine = masterRM->getMasterRandomEngine();
64  workerInitializer->SetupRNGEngine(masterEngine);
65 
66  // Create the thread-local worker run manager (G4AtlasWorkerRunManager)
67  ATH_MSG_INFO("Creating worker RM");
68  G4WorkerRunManager* wrm = workerInitializer->CreateWorkerRunManager();
69  wrm->SetWorkerThread(wThreadContext);
70 
71  // Share detector from master with worker.
72  ATH_MSG_INFO("Assigning detector construction");
73  // I don't want to const-cast here, but this is what they do in G4's
74  // StartThread function, so there is likely no alternative.
75  // Should not be a problem for threading.
76  G4VUserDetectorConstruction* detector ATLAS_THREAD_SAFE =
77  const_cast<G4VUserDetectorConstruction*> (masterRM->GetUserDetectorConstruction());
78  wrm->G4RunManager::SetUserInitialization (detector);
79  // Share physics list from master with worker.
80  // Should not be a problem for threading.
81  G4VUserPhysicsList* physicslist ATLAS_THREAD_SAFE =
82  const_cast<G4VUserPhysicsList*>(masterRM->GetUserPhysicsList());
83  wrm->SetUserInitialization(physicslist);
84 
85  // Build thread-local user actions - NOT CURRENTLY USED.
86  if(masterRM->GetUserActionInitialization()) {
87  masterRM->GetNonConstUserActionInitialization()->Build();
88  }
89 
90  // Start user worker initialization
91  if(masterRM->GetUserWorkerInitialization()) {
92  masterRM->GetUserWorkerInitialization()->WorkerStart();
93  }
94 
95  // Initialize the worker run manager
96  ATH_MSG_INFO("Initializing worker RM");
97  wrm->Initialize();
98 
99  // Copy the UI commands to the worker
100  std::vector<G4String> cmds = masterRM->GetCommandStack();
101  ATH_MSG_INFO (cmds.size() << " commands in UI stack");
102  G4UImanager* uimgr = G4UImanager::GetUIpointer();
103  for(const auto& it : cmds) {
104  ATH_MSG_INFO ("Adding command to worker: " << it);
105  uimgr->ApplyCommand(it);
106  }
107 
108  // Atomic increment number of initialized threads
109  m_nInitThreads++;
110 
111  ATH_MSG_INFO("==> tbb thread end of initThread with id: 0x" <<
112  std::hex << pthread_self() << std::dec);
113 }
114 
115 //-----------------------------------------------------------------------------
116 // Worker thread termination
117 //-----------------------------------------------------------------------------
119 {
120  ATH_MSG_DEBUG("terminateThread ==> tbb thread 0x" <<
121  std::hex << pthread_self() << std::dec);
122 
123  // Geant4 worker finalization
124  auto runMgr = G4RunManager::GetRunManager();
125  ATH_MSG_DEBUG("G4RunManager ptr" << runMgr);
126  if(runMgr) {
127  runMgr->RunTermination();
128  ATH_MSG_INFO("terminateThread ==> safely called G4AtlasWorkerRunManager::RunTermination for tbb thread 0x" <<
129  std::hex << pthread_self() << std::dec);
130  // Atomic decrement number of initialized threads
131  m_nInitThreads--;
132  }
133  else {
134  ATH_MSG_WARNING("skipping attempt to call terminateThread for tbb thread 0x" <<
135  std::hex << pthread_self() << std::dec <<
136  " without having first called initThread.");
137  // Not decrementing m_nInitThreads as initThread was not called in this case.
138  }
139 }
G4ThreadInitTool::m_nInitThreads
std::atomic_uint m_nInitThreads
Counter of threads that have been initialized.
Definition: G4ThreadInitTool.h:43
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
TRTCalib_cfilter.detector
detector
Definition: TRTCalib_cfilter.py:241
skel.it
it
Definition: skel.GENtoEVGEN.py:396
G4ThreadInitTool.h
G4ThreadInitTool::terminateThread
virtual void terminateThread() override final
Tear down the Geant4 workspace for this worker thread.
Definition: G4ThreadInitTool.cxx:118
Herwig7_QED_EvtGen_Common.cmds
string cmds
Definition: Herwig7_QED_EvtGen_Common.py:11
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
G4ThreadInitTool::initThread
virtual void initThread() override final
Set up the Geant4 workspace for this worker thread.
Definition: G4ThreadInitTool.cxx:38
test_pyathena.parent
parent
Definition: test_pyathena.py:15
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
G4ThreadInitTool::G4ThreadInitTool
G4ThreadInitTool(const std::string &, const std::string &, const IInterface *)
Standard tool constructor.
Definition: G4ThreadInitTool.cxx:27
checker_macros.h
Define macros for attributes used to control the static checker.