Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions include/AdePT/core/AsyncAdePTTransport.hh
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

class G4Region;
class G4VPhysicalVolume;
class G4HepEmConfig;
struct G4HepEmState;
namespace AsyncAdePT {
struct TrackBuffer;
Expand Down Expand Up @@ -73,16 +74,14 @@ private:
///< Needed to stall the GPU, in case the nPartInFlight * fHitBufferSafetyFactor > available HitSlots
double fHitBufferSafetyFactor{1.5};

void Initialize(G4HepEmTrackingManagerSpecialized *hepEmTM, AdePTGeant4Integration &g4Integration,
const std::vector<float> &uniformFieldValues);
void Initialize(G4HepEmConfig *hepEmConfig);
void InitBVH();
bool InitializeGeometry(const vecgeom::cxx::VPlacedVolume *world);
bool InitializePhysics(G4HepEmConfig *hepEmConfig);
void InitWDTOnDevice(const adeptint::WDTHostPacked &src, adeptint::WDTDeviceBuffers &dev, unsigned short maxIter);

public:
AsyncAdePTTransport(AdePTConfiguration &configuration, G4HepEmTrackingManagerSpecialized *hepEmTM,
AdePTGeant4Integration &g4Integration, const std::vector<float> &uniformFieldValues);
AsyncAdePTTransport(AdePTConfiguration &configuration, G4HepEmConfig *hepEmConfig);
AsyncAdePTTransport(const AsyncAdePTTransport &other) = delete;
~AsyncAdePTTransport();

Expand All @@ -94,6 +93,9 @@ public:
bool GetCallUserActions() const { return fReturnFirstAndLastStep; }
std::vector<std::string> const *GetGPURegionNames() { return fGPURegionNames; }
std::vector<std::string> const *GetCPURegionNames() { return fCPURegionNames; }
G4HepEmState *GetHepEmState() const { return fg4hepem_state.get(); }
void CompleteInitialization(adeptint::VolAuxData *auxData, const adeptint::WDTHostPacked &wdtPacked,
const std::vector<float> &uniformFieldValues);
/// Block until transport of the given event is done.
void Flush(int threadId, int eventId, AdePTGeant4Integration &g4Integration);
void ProcessGPUSteps(int threadId, int eventId, AdePTGeant4Integration &g4Integration);
Expand Down
38 changes: 19 additions & 19 deletions include/AdePT/core/AsyncAdePTTransport.icc
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,7 @@ std::ostream &operator<<(std::ostream &stream, TrackDataWithIDs const &track)

// These definitions live in a header-included .icc file, so they must remain
// inline to avoid multiple definitions across translation units.
inline AsyncAdePTTransport::AsyncAdePTTransport(AdePTConfiguration &configuration,
G4HepEmTrackingManagerSpecialized *hepEmTM,
AdePTGeant4Integration &g4Integration,
const std::vector<float> &uniformFieldValues)
inline AsyncAdePTTransport::AsyncAdePTTransport(AdePTConfiguration &configuration, G4HepEmConfig *hepEmConfig)
: fAdePTSeed{configuration.GetAdePTSeed()}, fNThread{(ushort)configuration.GetNumThreads()},
fTrackCapacity{(uint)(1024 * 1024 * configuration.GetMillionsOfTrackSlots())},
fLeakCapacity{(uint)(1024 * 1024 * configuration.GetMillionsOfLeakSlots())},
Expand All @@ -97,7 +94,7 @@ inline AsyncAdePTTransport::AsyncAdePTTransport(AdePTConfiguration &configuratio
std::atomic_init(&eventState, EventState::LeakedTracksRetrieved);
}

AsyncAdePTTransport::Initialize(hepEmTM, g4Integration, uniformFieldValues);
AsyncAdePTTransport::Initialize(hepEmConfig);
}

inline AsyncAdePTTransport::~AsyncAdePTTransport()
Expand Down Expand Up @@ -185,12 +182,10 @@ inline bool AsyncAdePTTransport::InitializePhysics(G4HepEmConfig *hepEmConfig)
return true;
}

inline void AsyncAdePTTransport::Initialize(G4HepEmTrackingManagerSpecialized *hepEmTM,
AdePTGeant4Integration &g4Integration,
const std::vector<float> &uniformFieldValues)
inline void AsyncAdePTTransport::Initialize(G4HepEmConfig *hepEmConfig)
{
const auto numVolumes = vecgeom::GeoManager::Instance().GetRegisteredVolumesCount();
if (numVolumes == 0) throw std::runtime_error("AsyncAdePTTransport::Initialize: Number of geometry volumes is zero.");
if (vecgeom::GeoManager::Instance().GetRegisteredVolumesCount() == 0)
throw std::runtime_error("AsyncAdePTTransport::Initialize: Number of geometry volumes is zero.");

G4cout << "=== AsyncAdePTTransport: initializing geometry and physics\n";
// Initialize geometry on device
Expand All @@ -202,24 +197,29 @@ inline void AsyncAdePTTransport::Initialize(G4HepEmTrackingManagerSpecialized *h
throw std::runtime_error("AsyncAdePTTransport::Initialize: Cannot initialize geometry on GPU");

// Initialize G4HepEm
if (!InitializePhysics(hepEmTM->GetConfig()))
if (!InitializePhysics(hepEmConfig))
throw std::runtime_error("AsyncAdePTTransport::Initialize cannot initialize physics on GPU");
}

// Check VecGeom geometry matches Geant4. Initialize auxiliary per-LV data. Initialize scoring map.
g4Integration.CheckGeometry(fg4hepem_state.get());
adeptint::VolAuxData *auxData = new adeptint::VolAuxData[vecgeom::GeoManager::Instance().GetRegisteredVolumesCount()];
adeptint::WDTHostRaw wdtRaw;
g4Integration.InitVolAuxData(auxData, fg4hepem_state.get(), hepEmTM, fTrackInAllRegions, fGPURegionNames, wdtRaw);
inline void AsyncAdePTTransport::CompleteInitialization(adeptint::VolAuxData *auxData,
const adeptint::WDTHostPacked &wdtPacked,
const std::vector<float> &uniformFieldValues)
{
// This is the second half of the split initialization. A non-zero volume count was already
// required in Initialize() before geometry upload, and it remains a hard precondition here
// before uploading any geometry-derived metadata to the device.
const auto numVolumes = vecgeom::GeoManager::Instance().GetRegisteredVolumesCount();
if (numVolumes == 0)
throw std::runtime_error("AsyncAdePTTransport::CompleteInitialization: Number of geometry volumes is zero.");

// Initialize volume auxiliary data on device
auto &volAuxArray = adeptint::VolAuxArray::GetInstance();
volAuxArray.fNumVolumes = numVolumes;
volAuxArray.fAuxData = auxData;
AsyncAdePT::InitVolAuxArray(volAuxArray);

// Pack host-side WDT
adeptint::WDTHostPacked wdtPacked = adeptint::PackWDT(wdtRaw);
fHasWDTRegions = !wdtPacked.regions.empty(); // set the flag whether WDT regions are enabled
// The Geant4 side has already packed the host-side WDT metadata before handing it to transport.
fHasWDTRegions = !wdtPacked.regions.empty(); // set the flag whether WDT regions are enabled

// Upload WDT to device
adeptint::WDTDeviceBuffers wdtDev;
Expand Down
3 changes: 3 additions & 0 deletions include/AdePT/integration/AdePTTrackingManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ private:
const vecgeom::NavigationState GetVecGeomFromG4State(const G4Track &aG4Track,
const G4NavigationHistory *aG4NavigationHistory = nullptr);

/// @brief Perform the one-time shared AdePT transport initialization on the first Geant4 worker.
void InitializeSharedAdePTTransport();

std::unique_ptr<G4HepEmTrackingManagerSpecialized> fHepEmTrackingManager;
AdePTGeant4Integration fGeant4Integration;
static inline int fNumThreads{0};
Expand Down
53 changes: 35 additions & 18 deletions src/AdePTTrackingManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "G4Gamma.hh"
#include "G4Positron.hh"

#include <VecGeom/management/GeoManager.h>

#include <algorithm>

#ifdef ENABLE_POWER_METER
Expand All @@ -26,11 +28,10 @@ namespace {
using AdePTTransport = AdePTTrackingManager::AdePTTransport;
}

std::shared_ptr<AdePTTransport> InstantiateAdePT(AdePTConfiguration &conf, G4HepEmTrackingManagerSpecialized *hepEmTM,
AdePTGeant4Integration &g4Integration,
const std::vector<float> &uniformFieldValues)
std::shared_ptr<AdePTTransport> GetSharedAdePTTransport(AdePTConfiguration &conf,
G4HepEmTrackingManagerSpecialized *hepEmTM)
{
static std::shared_ptr<AdePTTransport> AdePT{new AdePTTransport(conf, hepEmTM, g4Integration, uniformFieldValues)};
static std::shared_ptr<AdePTTransport> AdePT{new AdePTTransport(conf, hepEmTM->GetConfig())};
return AdePT;
}

Expand All @@ -55,6 +56,32 @@ AdePTTrackingManager::~AdePTTrackingManager()
#endif
}

void AdePTTrackingManager::InitializeSharedAdePTTransport()
{
#ifdef ADEPT_USE_EXT_BFIELD
std::cout << "Reading in covfie file for magnetic field: " << fAdePTConfiguration->GetCovfieBfieldFile() << std::endl;
if (fAdePTConfiguration->GetCovfieBfieldFile() == "") std::cout << "No magnetic field file provided!" << std::endl;
#endif
const auto uniformFieldValues = fGeant4Integration.GetUniformField();

// Create the shared AdePT transport engine on the first worker thread.
fAdeptTransport = GetSharedAdePTTransport(*fAdePTConfiguration, fHepEmTrackingManager.get());

// Check VecGeom geometry matches Geant4 before deriving any geometry metadata for transport.
fGeant4Integration.CheckGeometry(fAdeptTransport->GetHepEmState());

// Initialize auxiliary per-LV data and collect the raw WDT metadata on the Geant4 side.
auto *auxData = new adeptint::VolAuxData[vecgeom::GeoManager::Instance().GetRegisteredVolumesCount()];
adeptint::WDTHostRaw wdtRaw;
fGeant4Integration.InitVolAuxData(auxData, fAdeptTransport->GetHepEmState(), fHepEmTrackingManager.get(),
fAdePTConfiguration->GetTrackInAllRegions(),
fAdePTConfiguration->GetGPURegionNames(), wdtRaw);
adeptint::WDTHostPacked wdtPacked = adeptint::PackWDT(wdtRaw);

// Finish the shared transport initialization by uploading the prepared metadata to the device.
fAdeptTransport->CompleteInitialization(auxData, wdtPacked, uniformFieldValues);
}

void AdePTTrackingManager::InitializeAdePT()
{
auto tid = G4Threading::G4GetThreadId();
Expand Down Expand Up @@ -106,17 +133,7 @@ void AdePTTrackingManager::InitializeAdePT()
#endif
}

#ifdef ADEPT_USE_EXT_BFIELD
std::cout << "Reading in covfie file for magnetic field: " << fAdePTConfiguration->GetCovfieBfieldFile()
<< std::endl;
if (fAdePTConfiguration->GetCovfieBfieldFile() == "") std::cout << "No magnetic field file provided!" << std::endl;
#endif
const auto uniformFieldValues = fGeant4Integration.GetUniformField();

// Create an instance of an AdePT transport engine. This can either be one engine per thread or a shared engine for
// all threads.
fAdeptTransport =
InstantiateAdePT(*fAdePTConfiguration, fHepEmTrackingManager.get(), fGeant4Integration, uniformFieldValues);
InitializeSharedAdePTTransport();

// common init done, can notify other workers to proceed their initialization
{
Expand All @@ -136,9 +153,9 @@ void AdePTTrackingManager::InitializeAdePT()
// Now the fNumThreads is known and all workers can initialize
fAdePTConfiguration->SetNumThreads(fNumThreads);

// AdePTTransport was already initialized by the first G4 worker. The other workers get its pointer here
fAdeptTransport = InstantiateAdePT(*fAdePTConfiguration, fHepEmTrackingManager.get(), fGeant4Integration,
fGeant4Integration.GetUniformField());
// The shared AdePT transport was already created and initialized by the first worker.
// The remaining workers only retrieve the shared pointer here.
fAdeptTransport = GetSharedAdePTTransport(*fAdePTConfiguration, fHepEmTrackingManager.get());

// Initialize the GPU region list
if (!fAdePTConfiguration->GetTrackInAllRegions()) {
Expand Down
Loading