Skip to content

Commit f797c1c

Browse files
authoredNov 26, 2024
Refactoring the new Async mode additions (apt-sim#321)
The goal of this PR is to adapt the new Asynchronous AdePT components to the way the library is structured. This involves keeping a clear separation between AdePT and the integration layer. Main changes: - Remove `AdePTConfiguration` from the integration layer. This is an utility class which holds the AdePT configuration for a run, it is part of AdePT and independent from the integration layer. However the new `AdePTConfiguration::CreateAdePTInstance` is compiled as part of `AdePTG4Integration`. In practice, this isn't a change from the previous implementation, where the integration layer has the responsability of initializing `AdePTConfiguration`, and also of passing the values in `AdePTConfiguration` to `AdePTTransport`. This will be changed in this PR, by introducing a new `AdePTTransport` constructor which takes an `AdePTConfiguration` instance as an argument. Now the integration layer is only responsible of initializing `AdePTConfiguration`. - `AdePTConfiguration` will now also store the number of threads, which is used to compute the number of tracks and step slots allocated to each thread in synchronous mode. By doing this, we will also remove the need to store the number of slots per thread as `static inline` variables in `AdePTTransport`. This was done because in Geant4 we can only get the correct number of threads from the master, as the workers will report 1, thus we can only compute the space per thread from the master. However this is a G4-specific requirement that is not related to AdePT, so now, instead of doing that, we store the number of threads as a `static inline` variable in `AdePTTrackingManager`, on the integration side, which each thread then passes on to `AdePTConfiguration`. - Remove the `AdePTTransportFactory` method in favour of using the `AdePTTransport` constructor. This method is currently implemented as a free function that is part of the integration layer. It is called from `AdePTConfiguration::CreateAdePTInstance`. In principle, it wouldn't be an issue to keep one factory per transport backed, per integration layer, however at least for the synchronous backend there seems to be little reason to use a factory method instead the `AdePTTransport` constructor. In order to - Implement a constructor in `AdePTTransport` which takes an `AdePTConfiguration` instance as an argument. In the current implementation, the integration layer is supposed to initialize `AdePTConfiguration` and also to pass those values on to `AdePTTransport`. With this change, the integration layer only needs to initialize the configuration. - Move the instantiation of `ShowerGPU` back to to `AdePTTrackingManager.cu`. We need to instantiate `ShowerGPU` in a `.cu` file so that this function is compiled by `nvcc`. This is a necessary evil, and needs to be done in the integration layer since AdePT is a header-only library. This function has currently been moved to `AdePTTransport.cu`, which lives on the integration layer. As with the `AdePTConfiguration` change, in practice the integration layer is still responsible of doing this instantiation, it just lives on a different file. Since `AdePTTransport.cu` is not actually related to `AdePTTransport`, and it is `AdePTTrackingManager` that calls this function, I believe it is less misleading to keep this in `AdePTTrackingManager.cu`. - Remove the functionality to keep tracks returned by AdePT on host. There are two main reasons for this: - This functionality is meant to keep loopers returned from AdePT on host, however it doesn't distinguish between loopers and particles that simply stepped outside of the GPU region. This may be implemented in the future in a similar manner, by having a special ID for loopers if needed. - However in the future we may need to keep unique IDs for GPU tracks, in order to be able to identify them on host, so we can't use the ID field for this. - Remove the call to the user stepping action from the tracking manager. - `G4SteppingManager::Stepping` already calls the stepping action
1 parent 955e892 commit f797c1c

10 files changed

+38
-92
lines changed
 

‎CMakeLists.txt

+1-3
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,11 @@ endif()
164164
#----------------------------------------------------------------------------#
165165
set(ADEPT_G4_INTEGRATION_SRCS
166166
src/AdePTTrackingManager.cc
167+
src/AdePTTrackingManager.cu
167168
src/AdePTPhysics.cc
168169
src/HepEMPhysics.cc
169170
src/AdePTGeant4Integration.cpp
170171
src/AdePTConfigurationMessenger.cc
171-
src/AdePTConfiguration.cc
172172
)
173173

174174
add_library(CopCore INTERFACE)
@@ -180,8 +180,6 @@ target_include_directories(CopCore
180180

181181
add_library(AdePT_G4_integration SHARED
182182
${ADEPT_G4_INTEGRATION_SRCS}
183-
src/AdePTTransport.cc
184-
src/AdePTTransport.cu
185183
)
186184
target_include_directories(AdePT_G4_integration
187185
PUBLIC

‎include/AdePT/core/AdePTConfiguration.hh

+5-4
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ std::shared_ptr<AdePTTransportInterface> AdePTTransportFactory(unsigned int nThr
2525
///
2626
class AdePTConfiguration {
2727
public:
28-
AdePTConfiguration();
29-
~AdePTConfiguration();
28+
AdePTConfiguration() : fAdePTConfigurationMessenger{new AdePTConfigurationMessenger(this)} {}
29+
~AdePTConfiguration() {}
30+
void SetNumThreads(int numThreads) { fNumThreads = numThreads; }
3031
void SetTrackInAllRegions(bool trackInAllRegions) { fTrackInAllRegions = trackInAllRegions; }
3132
void AddGPURegionName(std::string name) { fGPURegionNames.push_back(name); }
3233
void SetAdePTActivation(bool activateAdePT) { fAdePTActivated = activateAdePT; }
@@ -42,6 +43,7 @@ public:
4243

4344
bool GetTrackInAllRegions() { return fTrackInAllRegions; }
4445
bool IsAdePTActivated() { return fAdePTActivated; }
46+
int GetNumThreads() { return fNumThreads; };
4547
int GetVerbosity() { return fVerbosity; };
4648
int GetTransportBufferThreshold() { return fTransportBufferThreshold; }
4749
int GetCUDAStackLimit() { return fCUDAStackLimit; }
@@ -50,14 +52,13 @@ public:
5052
double GetMillionsOfHitSlots() { return fMillionsOfHitSlots; }
5153
std::vector<std::string> *GetGPURegionNames() { return &fGPURegionNames; }
5254

53-
std::shared_ptr<AdePTTransportInterface> CreateAdePTInstance(unsigned int nThread);
54-
5555
// Temporary
5656
std::string GetVecGeomGDML() { return fVecGeomGDML; }
5757

5858
private:
5959
bool fTrackInAllRegions{false};
6060
bool fAdePTActivated{true};
61+
int fNumThreads;
6162
int fVerbosity{0};
6263
int fTransportBufferThreshold{200};
6364
int fCUDAStackLimit{0};

‎include/AdePT/core/AdePTTransport.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "CommonStruct.h"
2020
#include <AdePT/core/AdePTScoringTemplate.cuh>
2121
#include <AdePT/core/HostScoringStruct.cuh>
22+
#include <AdePT/core/AdePTConfiguration.hh>
2223

2324
class G4Region;
2425
struct GPUstate;
@@ -32,7 +33,7 @@ class AdePTTransport : public AdePTTransportInterface {
3233
using TrackBuffer = adeptint::TrackBuffer;
3334
using VolAuxArray = adeptint::VolAuxArray;
3435

35-
AdePTTransport() = default;
36+
AdePTTransport(AdePTConfiguration &configuration);
3637

3738
~AdePTTransport() { delete fScoring; }
3839

@@ -76,8 +77,8 @@ class AdePTTransport : public AdePTTransportInterface {
7677

7778
private:
7879
static inline G4HepEmState *fg4hepem_state{nullptr}; ///< The HepEm state singleton
79-
static inline int fCapacity{1024 * 1024}; ///< Track container capacity on GPU
80-
static inline int fHitBufferCapacity{1024 * 1024}; ///< Capacity of hit buffers
80+
int fCapacity{1024 * 1024}; ///< Track container capacity on GPU
81+
int fHitBufferCapacity{1024 * 1024}; ///< Capacity of hit buffers
8182
int fNthreads{0}; ///< Number of cpu threads
8283
int fMaxBatch{0}; ///< Max batch size for allocating GPU memory
8384
int fNumVolumes{0}; ///< Total number of active logical volumes

‎include/AdePT/core/AdePTTransport.icc

+16
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@ void ShowerGPU(IntegrationLayer &integration, int event, TrackBuffer &buffer, GP
3838

3939
} // namespace adept_impl
4040

41+
template <typename IntegrationLayer>
42+
AdePTTransport<IntegrationLayer>::AdePTTransport(AdePTConfiguration &configuration)
43+
{
44+
fDebugLevel = 0;
45+
fBufferThreshold = configuration.GetTransportBufferThreshold();
46+
fMaxBatch = 2 * configuration.GetTransportBufferThreshold();
47+
fTrackInAllRegions = configuration.GetTrackInAllRegions();
48+
fGPURegionNames = configuration.GetGPURegionNames();
49+
fCUDAStackLimit = configuration.GetCUDAStackLimit();
50+
fCapacity = 1024 * 1024 * configuration.GetMillionsOfTrackSlots() / configuration.GetNumThreads();
51+
fHitBufferCapacity = 1024 * 1024 * configuration.GetMillionsOfHitSlots() / configuration.GetNumThreads();
52+
53+
printf( "AdePT Allocated track capacity: %d tracks\n", fCapacity);
54+
printf( "AdePT Allocated step buffer capacity: %d tracks\n", fHitBufferCapacity);
55+
}
56+
4157
template <typename IntegrationLayer>
4258
bool AdePTTransport<IntegrationLayer>::InitializeField(double bz)
4359
{

‎include/AdePT/integration/AdePTTrackingManager.hh

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "globals.hh"
1111
#include <AdePT/core/AdePTTransportInterface.hh>
12+
#include <AdePT/core/AdePTTransport.h>
1213
#include "AdePT/copcore/SystemOfUnits.h"
1314
#include <AdePT/integration/AdePTGeant4Integration.hh>
1415
#include <AdePT/core/AdePTConfiguration.hh>
@@ -49,9 +50,9 @@ private:
4950
/// @brief Steps a track using the Generic G4TrackingManager until it enters a GPU region or stops
5051
void StepInHostRegion(G4Track *aTrack);
5152

53+
static inline int fNumThreads{0};
5254
std::set<G4Region const *> fGPURegions{};
5355
int fVerbosity{0};
54-
5556
std::shared_ptr<AdePTTransportInterface> fAdeptTransport;
5657
AdePTConfiguration *fAdePTConfiguration;
5758
unsigned int fTrackCounter{0};

‎src/AdePTConfiguration.cc

-29
This file was deleted.

‎src/AdePTGeant4Integration.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,6 @@ void AdePTGeant4Integration::ReturnTrack(adeptint::TrackData const &track, unsig
513513
G4Track *secondary = new G4Track(dynamique, track.globalTime, posi);
514514
secondary->SetLocalTime(track.localTime);
515515
secondary->SetProperTime(track.properTime);
516-
secondary->SetTrackID(kAdePTTrackID);
517516
secondary->SetParentID(track.parentID);
518517

519518
G4EventManager::GetEventManager()->GetStackManager()->PushOneTrack(secondary);

‎src/AdePTTrackingManager.cc

+10-12
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,25 @@ AdePTTrackingManager::~AdePTTrackingManager()
2828

2929
void AdePTTrackingManager::InitializeAdePT()
3030
{
31-
const auto num_threads = G4RunManager::GetRunManager()->GetNumberOfThreads();
32-
3331
// Check if this is a sequential run
3432
G4RunManager::RMType rmType = G4RunManager::GetRunManager()->GetRunManagerType();
3533
bool sequential = (rmType == G4RunManager::sequentialRM);
3634

3735
// One thread initializes common elements
3836
auto tid = G4Threading::G4GetThreadId();
3937
if (tid < 0) {
38+
// Only the master thread knows the actual number of threads, the worker threads will return "1"
39+
// This value is stored here by the master in a static variable, and used by each thread to pass the
40+
// correct number to their AdePTConfiguration instance
41+
fNumThreads = G4RunManager::GetRunManager()->GetNumberOfThreads();
42+
fAdePTConfiguration->SetNumThreads(fNumThreads);
43+
4044
// Load the VecGeom world in memory
4145
AdePTGeant4Integration::CreateVecGeomWorld(fAdePTConfiguration->GetVecGeomGDML());
4246

4347
// Create an instance of an AdePT transport engine. This can either be one engine per thread or a shared engine for
4448
// all threads.
45-
fAdeptTransport = fAdePTConfiguration->CreateAdePTInstance(num_threads);
49+
fAdeptTransport = std::make_shared<AdePTTransport<AdePTGeant4Integration>>(*fAdePTConfiguration);
4650

4751
// Initialize common data:
4852
// G4HepEM, Upload VecGeom geometry to GPU, Geometry check, Create volume auxiliary data
@@ -54,7 +58,8 @@ void AdePTTrackingManager::InitializeAdePT()
5458
} else {
5559
// Create an instance of an AdePT transport engine. This can either be one engine per thread or a shared engine for
5660
// all threads.
57-
fAdeptTransport = fAdePTConfiguration->CreateAdePTInstance(num_threads);
61+
fAdePTConfiguration->SetNumThreads(fNumThreads);
62+
fAdeptTransport = std::make_shared<AdePTTransport<AdePTGeant4Integration>>(*fAdePTConfiguration);
5863
// Initialize per-thread data
5964
fAdeptTransport->Initialize();
6065
}
@@ -190,10 +195,8 @@ void AdePTTrackingManager::ProcessTrack(G4Track *aTrack)
190195
// Check if the particle is in a GPU region
191196
const bool isGPURegion = trackInAllRegions || fGPURegions.find(region) != fGPURegions.end();
192197

193-
if (isGPURegion &&
194-
aTrack->GetTrackID() != AdePTGeant4Integration::kAdePTTrackID /*track didn't come back from AdePT*/) {
198+
if (isGPURegion) {
195199
// If the track is in a GPU region, hand it over to AdePT
196-
197200
auto particlePosition = aTrack->GetPosition();
198201
auto particleDirection = aTrack->GetMomentumDirection();
199202
G4double energy = aTrack->GetKineticEnergy();
@@ -240,16 +243,11 @@ void AdePTTrackingManager::StepInHostRegion(G4Track *aTrack)
240243
G4TrackingManager *trackManager = eventManager->GetTrackingManager();
241244
G4SteppingManager *steppingManager = trackManager->GetSteppingManager();
242245
G4Region const *previousRegion = aTrack->GetVolume()->GetLogicalVolume()->GetRegion();
243-
G4UserSteppingAction *steppingAction = steppingManager->GetUserAction();
244-
const bool stayOnHost = aTrack->GetParentID() == AdePTGeant4Integration::kAdePTTrackID;
245246

246247
// Track the particle Step-by-Step while it is alive and outside of a GPU region
247248
while ((aTrack->GetTrackStatus() == fAlive || aTrack->GetTrackStatus() == fStopButAlive)) {
248249
aTrack->IncrementCurrentStepNumber();
249250
steppingManager->Stepping();
250-
if (steppingAction) steppingAction->UserSteppingAction(aTrack->GetStep());
251-
252-
if (stayOnHost) continue;
253251

254252
if (aTrack->GetTrackStatus() != fStopAndKill) {
255253
// Switch the touchable to update the volume, which is checked in the
File renamed without changes.

‎src/AdePTTransport.cc

-39
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.