ATLAS Offline Software
Loading...
Searching...
No Matches
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),
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 // Start user worker run
100 if(masterRM->GetUserWorkerInitialization()) {
101 masterRM->GetUserWorkerInitialization()->WorkerRunStart();
102 }
103
104 // Copy the UI commands to the worker
105 std::vector<G4String> cmds = masterRM->GetCommandStack();
106 ATH_MSG_INFO (cmds.size() << " commands in UI stack");
107 G4UImanager* uimgr = G4UImanager::GetUIpointer();
108 for(const auto& it : cmds) {
109 ATH_MSG_INFO ("Adding command to worker: " << it);
110 uimgr->ApplyCommand(it);
111 }
112
113 // Atomic increment number of initialized threads
115
116 ATH_MSG_INFO("==> tbb thread end of initThread with id: 0x" <<
117 std::hex << pthread_self() << std::dec);
118}
119
120//-----------------------------------------------------------------------------
121// Worker thread termination
122//-----------------------------------------------------------------------------
124{
125 ATH_MSG_DEBUG("terminateThread ==> tbb thread 0x" <<
126 std::hex << pthread_self() << std::dec);
127
128 // Geant4 worker finalization
129 auto runMgr = G4RunManager::GetRunManager();
130 ATH_MSG_DEBUG("G4RunManager ptr" << runMgr);
131 if(runMgr) {
132 runMgr->RunTermination();
133 ATH_MSG_INFO("terminateThread ==> safely called G4AtlasWorkerRunManager::RunTermination for tbb thread 0x" <<
134 std::hex << pthread_self() << std::dec);
135 // Atomic decrement number of initialized threads
137 }
138 else {
139 ATH_MSG_WARNING("skipping attempt to call terminateThread for tbb thread 0x" <<
140 std::hex << pthread_self() << std::dec <<
141 " without having first called initThread.");
142 // Not decrementing m_nInitThreads as initThread was not called in this case.
143 }
144}
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
virtual void terminateThread() override final
Tear down the Geant4 workspace for this worker thread.
std::atomic_uint m_nInitThreads
Counter of threads that have been initialized.
G4ThreadInitTool(const std::string &, const std::string &, const IInterface *)
Standard tool constructor.
virtual void initThread() override final
Set up the Geant4 workspace for this worker thread.