Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The surface model uses BVH-accelerated Locate and Safety. No solids on GPU #304

Merged
merged 3 commits into from
Sep 3, 2024
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
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,18 @@ endif()
if(ADEPT_USE_SURF)
if(VecGeom_SURF_FOUND)
if (ADEPT_USE_SURF_SINGLE)
message(STATUS "${Green}Surface model in VecGeom uses single precision${ColorReset}")
message(STATUS "${Green}Using the surface model in VecGeom in single precision${ColorReset}")
add_compile_definitions(ADEPT_USE_SURF_SINGLE)
else()
message(STATUS "${Green}Surface model in VecGeom uses double precision${ColorReset}")
message(STATUS "${Green}Using the surface model in VecGeom in double precision${ColorReset}")
endif()
add_compile_definitions(ADEPT_USE_SURF)
else()
message(STATUS "${Magenta}No VecGeom surface support. Forcing ADEPT_USE_SURF to OFF${ColorReset}")
set(ADEPT_USE_SURF OFF CACHE BOOL "Disable using the surface model" FORCE)
endif()
else()
message(STATUS "${Green}Using the solid model in VecGeom${ColorReset}")
endif()

# Find Geant4, optional for now
Expand Down
16 changes: 12 additions & 4 deletions include/AdePT/core/AdePTTransport.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ __global__ void InitTracks(adeptint::TrackData *trackinfo, int ntracks, int star
};
assert(trackmgr != nullptr && "Unsupported pdg type");

Track &track = trackmgr->NextTrack();
track.parentID = trackinfo[i].parentID;
Track &track = trackmgr->NextTrack();
track.parentID = trackinfo[i].parentID;

track.rngState.SetSeed(1234567 * event + startTrack + i);
track.eKin = trackinfo[i].eKin;
Expand All @@ -134,12 +134,20 @@ __global__ void InitTracks(adeptint::TrackData *trackinfo, int ntracks, int star
track.navState.Clear();
// We locate the pushed point because we run the risk that the
// point is not located in the GPU region
#ifndef ADEPT_USE_SURF
AdePTNavigator::LocatePointIn(world, track.pos + tolerance * track.dir, track.navState, true);
#else
AdePTNavigator::LocatePointIn(vecgeom::NavigationState::WorldId(), track.pos + tolerance * track.dir,
track.navState, true);
#endif
// The track must be on boundary at this point
track.navState.SetBoundaryState(true);
// nextState is initialized as needed.
auto volume = track.navState.Top();
int lvolID = volume->GetLogicalVolume()->id();
#ifndef ADEPT_USE_SURF
int lvolID = track.navState.Top()->GetLogicalVolume()->id();
#else
int lvolID = track.navState.GetLogicalId();
#endif
assert(auxDataArray[lvolID].fGPUregion);
}
}
Expand Down
15 changes: 11 additions & 4 deletions include/AdePT/core/AdePTTransport.icc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ void AdePTTransport<IntegrationLayer>::AddTrack(int pdg, int parent_id, double e
template <typename IntegrationLayer>
bool AdePTTransport<IntegrationLayer>::InitializeGeometry(const vecgeom::cxx::VPlacedVolume *world)
{
auto &cudaManager = vecgeom::cxx::CudaManager::Instance();
bool success = true;
#ifdef ADEPT_USE_SURF
#ifdef ADEPT_USE_SURF_SINGLE
using BrepHelper = vgbrep::BrepHelper<float>;
Expand All @@ -77,14 +79,17 @@ bool AdePTTransport<IntegrationLayer>::InitializeGeometry(const vecgeom::cxx::VP
if (!BrepHelper::Instance().Convert()) return 1;
BrepHelper::Instance().PrintSurfData();
std::cout << "== Conversion to surface model done in " << timer.Stop() << " [s]\n";
#endif
// Upload geometry to GPU.
auto &cudaManager = vecgeom::cxx::CudaManager::Instance();
// Upload only navigation table to the GPU
cudaManager.SynchronizeNavigationTable();
#else
// Upload solid geometry to GPU.
cudaManager.LoadGeometry(world);
auto world_dev = cudaManager.Synchronize();
success = world_dev != nullptr;
#endif
// Initialize BVH
InitBVH();
return (world_dev != nullptr);
return success;
}

template <typename IntegrationLayer>
Expand Down Expand Up @@ -168,7 +173,9 @@ template <typename IntegrationLayer>
void AdePTTransport<IntegrationLayer>::InitBVH()
{
vecgeom::BVHManager::Init();
#ifndef ADEPT_USE_SURF
vecgeom::BVHManager::DeviceInit();
#endif
}

template <typename IntegrationLayer>
Expand Down
17 changes: 12 additions & 5 deletions include/AdePT/kernels/electrons.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,14 @@ static __device__ __forceinline__ void TransportElectrons(adept::TrackManager<Tr
double localTime = currentTrack.localTime;
double properTime = currentTrack.properTime;
auto navState = currentTrack.navState;
const auto volume = navState.Top();
adeptint::TrackData trackdata;
// the MCC vector is indexed by the logical volume id
const int lvolID = volume->GetLogicalVolume()->id();
#ifndef ADEPT_USE_SURF
const int lvolID = navState.Top()->GetLogicalVolume()->id();
#else
const int lvolID = navState.GetLogicalId();
#endif

VolAuxData const &auxData = auxDataArray[lvolID];

auto survive = [&](bool leak = false) {
Expand Down Expand Up @@ -301,14 +305,17 @@ static __device__ __forceinline__ void TransportElectrons(adept::TrackManager<Tr
// For now, just count that we hit something.

// Kill the particle if it left the world.
if (nextState.Top() != nullptr) {
if (!nextState.IsOutside()) {
AdePTNavigator::RelocateToNextVolume(pos, dir, nextState);

// Move to the next boundary.
navState = nextState;
// Check if the next volume belongs to the GPU region and push it to the appropriate queue
const auto nextvolume = navState.Top();
const int nextlvolID = nextvolume->GetLogicalVolume()->id();
#ifndef ADEPT_USE_SURF
const int nextlvolID = navState.Top()->GetLogicalVolume()->id();
#else
const int nextlvolID = navState.GetLogicalId();
#endif
VolAuxData const &nextauxData = auxDataArray[nextlvolID];
if (nextauxData.fGPUregion > 0)
survive();
Expand Down
16 changes: 11 additions & 5 deletions include/AdePT/kernels/gammas.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,13 @@ __global__ void TransportGammas(adept::TrackManager<Track> *gammas, Secondaries
double localTime = currentTrack.localTime;
double properTime = currentTrack.properTime;
auto navState = currentTrack.navState;
const auto volume = navState.Top();
adeptint::TrackData trackdata;
// the MCC vector is indexed by the logical volume id
int lvolID = volume->GetLogicalVolume()->id();
#ifndef ADEPT_USE_SURF
int lvolID = navState.Top()->GetLogicalVolume()->id();
#else
int lvolID = navState.GetLogicalId();
#endif
VolAuxData const &auxData = auxDataArray[lvolID];

auto survive = [&](bool leak = false) {
Expand Down Expand Up @@ -117,14 +120,17 @@ __global__ void TransportGammas(adept::TrackManager<Track> *gammas, Secondaries
// For now, just count that we hit something.

// Kill the particle if it left the world.
if (nextState.Top() != nullptr) {
if (!nextState.IsOutside()) {
AdePTNavigator::RelocateToNextVolume(pos, dir, nextState);

// Move to the next boundary.
navState = nextState;
// Check if the next volume belongs to the GPU region and push it to the appropriate queue
const auto nextvolume = navState.Top();
const int nextlvolID = nextvolume->GetLogicalVolume()->id();
#ifndef ADEPT_USE_SURF
const int nextlvolID = navState.Top()->GetLogicalVolume()->id();
#else
const int nextlvolID = navState.GetLogicalId();
#endif
VolAuxData const &nextauxData = auxDataArray[nextlvolID];
if (nextauxData.fGPUregion > 0)
survive();
Expand Down
37 changes: 22 additions & 15 deletions include/AdePT/navigation/SurfNavigator.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,34 @@ template <typename Real_t>
class SurfNavigator {

public:
using Precision = vecgeom::Precision;
using Vector3D = vecgeom::Vector3D<vecgeom::Precision>;
using VPlacedVolumePtr_t = vecgeom::VPlacedVolume const *;
using SurfData = vgbrep::SurfData<Real_t>;
using Real_b = typename SurfData::Real_b;
using Precision = vecgeom::Precision;
using Vector3D = vecgeom::Vector3D<vecgeom::Precision>;
using SurfData = vgbrep::SurfData<Real_t>;
using Real_b = typename SurfData::Real_b;

static constexpr Precision kBoundaryPush = 10 * vecgeom::kTolerance;

// Locates the point in the geometry volume tree
__host__ __device__ static VPlacedVolumePtr_t LocatePointIn(VPlacedVolumePtr_t vol, Vector3D const &point,
vecgeom::NavigationState &path, bool top,
VPlacedVolumePtr_t exclude = nullptr)
/// @brief Locates the point in the geometry volume tree
/// @param pvol_id Placed volume id to be checked first
/// @param point Point to be checked, in the local frame of pvol
/// @param path Path to a parent of pvol that must contain the point
/// @param top Check first if pvol contains the point
/// @param exclude Placed volume id to exclude from the search
/// @return Index of the placed volume that contains the point
__host__ __device__ static int LocatePointIn(int pvol_id, Vector3D const &point, vecgeom::NavigationState &path,
bool top, int *exclude = nullptr)
{
return vgbrep::protonav::LocatePointIn(vol, point, path, top);
return vgbrep::protonav::BVHSurfNavigator<Real_t>::LocatePointIn(pvol_id, point, path, top, exclude);
}

// Computes the isotropic safety from the globalpoint.
/// @brief Computes the isotropic safety from the globalpoint.
/// @param globalpoint Point in global coordinates
/// @param state Path where to compute safety
/// @return Isotropic safe distance
__host__ __device__ static Precision ComputeSafety(Vector3D const &globalpoint, vecgeom::NavigationState const &state)
{
int closest_surf = 0;
return vgbrep::protonav::ComputeSafety(globalpoint, state, closest_surf);
auto safety = vgbrep::protonav::BVHSurfNavigator<Real_t>::ComputeSafety(globalpoint, state);
return safety;
}

// Computes a step from the globalpoint (which must be in the current volume)
Expand All @@ -67,8 +74,8 @@ class SurfNavigator {
}

vgbrep::CrossedSurface crossed_surf;
auto step =
vgbrep::protonav::BVHSurfNavigator<Real_t>::ComputeStepAndHit(globalpoint, globaldir, in_state, out_state, crossed_surf, step_limit);
auto step = vgbrep::protonav::BVHSurfNavigator<Real_t>::ComputeStepAndHit(globalpoint, globaldir, in_state,
out_state, crossed_surf, step_limit);
return step;
}

Expand Down
22 changes: 12 additions & 10 deletions test/testField/electrons.cu
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

#include <AdePT/copcore/PhysicalConstants.h>

#define NOFLUCTUATION

// Classes for Runge-Kutta integration
#include <AdePT/magneticfield/MagneticFieldEquation.h>
#include <AdePT/magneticfield/DormandPrinceRK45.h>
Expand Down Expand Up @@ -90,10 +88,14 @@ static __device__ __forceinline__ void TransportElectrons(Track *electrons, cons
auto pos = currentTrack.pos;
auto dir = currentTrack.dir;
auto navState = currentTrack.navState;
const auto volume = navState.Top();
const int volumeID = volume->id();
#ifndef ADEPT_USE_SURF
const int volumeID = navState.Top()->GetLogicalVolume()->id();
#else
const int volumeID = navState.GetLogicalId();
#endif

// the MCC vector is indexed by the logical volume id
const int theMCIndex = MCIndex[volume->GetLogicalVolume()->id()];
const int theMCIndex = MCIndex[volumeID];

auto survive = [&] {
currentTrack.energy = energy;
Expand Down Expand Up @@ -213,8 +215,8 @@ static __device__ __forceinline__ void TransportElectrons(Track *electrons, cons
constexpr Precision thresholdDiff = 3.0e-3;
bool diffLength = false, badPosition = false, badDirection = false;
vecgeom::NavigationState &currNavState = navState;
bool sameLevel = nextState.GetLevel() == nextStateHx.GetLevel();
bool sameIndex = nextState.GetNavIndex() == nextStateHx.GetNavIndex();
bool sameLevel = nextState.GetLevel() == nextStateHx.GetLevel();
bool sameIndex = nextState.GetNavIndex() == nextStateHx.GetNavIndex();

if (std::fabs(helixStepLength - geometryStepLength) > 1.0e-4 * helixStepLength) {
bool sameNextVol = (nextState.GetLevel() == nextStateHx.GetLevel()) &&
Expand Down Expand Up @@ -247,8 +249,8 @@ static __device__ __forceinline__ void TransportElectrons(Track *electrons, cons
}
#endif
} else {
geometryStepLength = AdePTNavigator::ComputeStepAndNextVolume(pos, dir, geometricalStepLengthFromPhysics, navState,
nextState, kPush);
geometryStepLength = AdePTNavigator::ComputeStepAndNextVolume(pos, dir, geometricalStepLengthFromPhysics,
navState, nextState, kPush);
pos += geometryStepLength * dir;
}

Expand Down Expand Up @@ -353,7 +355,7 @@ static __device__ __forceinline__ void TransportElectrons(Track *electrons, cons
atomicAdd(&globalScoring->hits, 1);

// Kill the particle if it left the world.
if (nextState.Top() != nullptr) {
if (!nextState.IsOutside()) {
AdePTNavigator::RelocateToNextVolume(pos, dir, nextState);

// Move to the next boundary.
Expand Down
11 changes: 7 additions & 4 deletions test/testField/gammas.cu
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@ __global__ void TransportGammas(Track *gammas, const adept::MParray *active, Sec
auto pos = currentTrack.pos;
auto dir = currentTrack.dir;
auto navState = currentTrack.navState;
const auto volume = navState.Top();
const int volumeID = volume->id();
#ifndef ADEPT_USE_SURF
const int volumeID = navState.Top()->GetLogicalVolume()->id();
#else
const int volumeID = navState.GetLogicalId();
#endif
// the MCC vector is indexed by the logical volume id
const int theMCIndex = MCIndex[volume->GetLogicalVolume()->id()];
const int theMCIndex = MCIndex[volumeID];

auto survive = [&] {
currentTrack.energy = energy;
Expand Down Expand Up @@ -102,7 +105,7 @@ __global__ void TransportGammas(Track *gammas, const adept::MParray *active, Sec
atomicAdd(&globalScoring->hits, 1);

// Kill the particle if it left the world.
if (nextState.Top() != nullptr) {
if (!nextState.IsOutside()) {
AdePTNavigator::RelocateToNextVolume(pos, dir, nextState);

// Move to the next boundary.
Expand Down
19 changes: 19 additions & 0 deletions test/testField/testField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
#include <VecGeom/management/BVHManager.h>
#include <VecGeom/gdml/Frontend.h>
#include <VecGeom/management/CudaManager.h>
#ifdef ADEPT_USE_SURF
#include <VecGeom/surfaces/BrepHelper.h>
#endif

#include <AdePT/copcore/SystemOfUnits.h>
#include <AdePT/base/ArgParser.h>
Expand Down Expand Up @@ -171,7 +174,9 @@ void FreeG4HepEm(G4HepEmState *state)
void InitBVH()
{
vecgeom::cxx::BVHManager::Init();
#ifndef ADEPT_USE_SURF
vecgeom::cxx::BVHManager::DeviceInit();
#endif
}

void PrintScoringPerVolume(const vecgeom::VPlacedVolume *placed, const ScoringPerVolume *scoring, int level = 0)
Expand Down Expand Up @@ -243,8 +248,22 @@ int main(int argc, char *argv[])
// Load and synchronize the geometry on the GPU
std::cout << "synchronizing VecGeom geometry to GPU ...\n";
auto &cudaManager = vecgeom::cxx::CudaManager::Instance();
#ifdef ADEPT_USE_SURF
#ifdef ADEPT_USE_SURF_SINGLE
using BrepHelper = vgbrep::BrepHelper<float>;
#else
using BrepHelper = vgbrep::BrepHelper<double>;
#endif
#endif

#ifndef ADEPT_USE_SURF
cudaManager.LoadGeometry(world);
cudaManager.Synchronize();
#else
if (!BrepHelper::Instance().Convert()) return 1;
BrepHelper::Instance().PrintSurfData();
cudaManager.SynchronizeNavigationTable();
#endif
InitBVH();

auto time_cpu = timer.Stop();
Expand Down
4 changes: 4 additions & 0 deletions test/testField/testField.cu
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,11 @@ __global__ void InitPrimaries(ParticleGenerator generator, int startEvent, int n
track.dir = {1.0, 0, 0};
}
track.navState.Clear();
#ifndef ADEPT_USE_SURF
AdePTNavigator::LocatePointIn(world, track.pos, track.navState, true);
#else
AdePTNavigator::LocatePointIn(vecgeom::NavigationState::WorldId(), track.pos, track.navState, true);
#endif

atomicAdd(&globalScoring->numElectrons, 1);
}
Expand Down
Loading