Skip to content
Snippets Groups Projects
Commit bad94e42 authored by Steven Andrew Farrell's avatar Steven Andrew Farrell
Browse files

Adding G4ThreadInitTool implementation.

Relocating this tool from G4HiveEx (named G4InitTool) to G4AtlasTools
with some minor changes, including improved method of assigning G4
thread ID and replacing some usages of 'auto'.
parent 787cd632
No related merge requests found
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
// Main header include
#include "G4ThreadInitTool.h"
// Geant4 includes
#include "G4WorkerRunManager.hh"
#include "G4UImanager.hh"
#include "G4MTRunManager.hh"
#include "G4WorkerThread.hh"
#include "G4UserWorkerThreadInitialization.hh"
#include "G4RunManager.hh"
#include "G4VUserActionInitialization.hh"
#include "G4UserWorkerInitialization.hh"
#include "G4AutoDelete.hh"
// System includes
#include <unistd.h>
#include <sys/syscall.h>
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
G4ThreadInitTool::G4ThreadInitTool(const std::string& type,
const std::string& name,
const IInterface* parent)
: base_class(type, name, parent),
m_nInitThreads(0)
{}
//-----------------------------------------------------------------------------
// Worker thread initialization.
// This code is modeled after G4MTRunManagerKernel::StartThread.
//-----------------------------------------------------------------------------
void G4ThreadInitTool::initThread()
{
ATH_MSG_INFO("==> tbb thread started with id: 0x" <<
std::hex << pthread_self() << std::dec);
// Define the G4 worker thread context and setup its cleanup mechanism.
auto wThreadContext = new G4WorkerThread;
G4AutoDelete::Register(wThreadContext);
// Assign the thread ID
static std::atomic_uint tid(0);
wThreadContext->SetThreadId( tid++ );
G4Threading::G4SetThreadId( wThreadContext->GetThreadId() );
// Setup thread-local geometry and physics
wThreadContext->BuildGeometryAndPhysicsVector();
// Retrieve the master thread run manager
G4MTRunManager* masterRM = G4MTRunManager::GetMasterRunManager();
// Worker thread initialization object
const G4UserWorkerThreadInitialization* workerInitializer =
masterRM->GetUserWorkerThreadInitialization();
// Random number setup.
// TODO: revisit this once MT AthRNGSvc is available.
const CLHEP::HepRandomEngine* masterEngine = masterRM->getMasterRandomEngine();
workerInitializer->SetupRNGEngine(masterEngine);
// Create the thread-local worker run manager (G4AtlasWorkerRunManager)
ATH_MSG_INFO("Creating worker RM");
G4WorkerRunManager* wrm = workerInitializer->CreateWorkerRunManager();
wrm->SetWorkerThread(wThreadContext);
// Share detector from master with worker.
ATH_MSG_INFO("Assigning detector construction");
const G4VUserDetectorConstruction* detector =
masterRM->GetUserDetectorConstruction();
// I don't want to const-cast here, but this is what they do in G4's
// StartThread function, so there is likely no alternative.
wrm->G4RunManager::SetUserInitialization
(const_cast<G4VUserDetectorConstruction*>(detector));
// Share physics list from master with worker.
const G4VUserPhysicsList* physicslist = masterRM->GetUserPhysicsList();
wrm->SetUserInitialization(const_cast<G4VUserPhysicsList*>(physicslist));
// Build thread-local user actions - NOT CURRENTLY USED.
if(masterRM->GetUserActionInitialization()) {
masterRM->GetNonConstUserActionInitialization()->Build();
}
// Start user worker initialization
if(masterRM->GetUserWorkerInitialization()) {
masterRM->GetUserWorkerInitialization()->WorkerStart();
}
// Initialize the worker run manager
ATH_MSG_INFO("Initializing worker RM");
wrm->Initialize();
// Copy the UI commands to the worker
std::vector<G4String> cmds = masterRM->GetCommandStack();
ATH_MSG_INFO (cmds.size() << " commands in UI stack");
G4UImanager* uimgr = G4UImanager::GetUIpointer();
for(const auto& it : cmds) {
ATH_MSG_INFO ("Adding command to worker: " << it);
uimgr->ApplyCommand(it);
}
// Atomic increment number of initialized threads
m_nInitThreads++;
ATH_MSG_INFO("==> tbb thread end of initThread with id: 0x" <<
std::hex << pthread_self() << std::dec);
}
//-----------------------------------------------------------------------------
// Worker thread termination
//-----------------------------------------------------------------------------
void G4ThreadInitTool::terminateThread()
{
// Atomic decrement number of initialized threads
m_nInitThreads--;
}
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef G4ATLASTOOLS_G4THREADINITTOOL_H
#define G4ATLASTOOLS_G4THREADINITTOOL_H
#include "AthenaBaseComps/AthAlgTool.h"
#include "GaudiKernel/IThreadInitTool.h"
#include <string>
#include <atomic>
/// @class G4ThreadInitTool
/// @brief A tool which sets up the worker-thread-local workspace for Geant4.
///
/// @author Steve Farrell <Steven.Farrell@cern.ch>
///
class G4ThreadInitTool : virtual public extends1<AthAlgTool, IThreadInitTool>
{
public:
/// Standard tool constructor
G4ThreadInitTool(const std::string&, const std::string&, const IInterface*);
/// Set up the Geant4 workspace for this worker thread
virtual void initThread() override final;
/// Tear down the Geant4 workspace for this worker thread
virtual void terminateThread() override final;
/// Counter used for barrier mechanism in thread initialization.
/// This number needs to be correctly reported to properly ensure
/// scheduling of thread-initialization tasks on every thread.
virtual unsigned int nInit() const override final {
return m_nInitThreads;
}
private:
/// Counter of threads that have been initialized
std::atomic_uint m_nInitThreads;
}; // class G4ThreadInitTool
#endif // G4ATLASTOOLS_G4THREADINITTOOL_H
......@@ -14,6 +14,7 @@
#include "../FastSimulationMasterTool.h"
#include "G4AtlasTools/GlobalFieldManagerTool.h"
#include "G4AtlasTools/DetectorFieldManagerTool.h"
#include "../G4ThreadInitTool.h"
DECLARE_TOOL_FACTORY( PhysicsListToolBase )
DECLARE_TOOL_FACTORY( DetectorGeometryBase )
......@@ -29,3 +30,4 @@ DECLARE_TOOL_FACTORY( FastSimulationMasterTool )
DECLARE_TOOL_FACTORY( AddPhysicsDecayTool )
DECLARE_TOOL_FACTORY( GlobalFieldManagerTool )
DECLARE_TOOL_FACTORY( DetectorFieldManagerTool )
DECLARE_TOOL_FACTORY( G4ThreadInitTool )
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment