peclet-dem 0.4.0
Performance-portable XPBD Discrete Element Method (Kokkos + ArborX)
Loading...
Searching...
No Matches
solver_fused.hpp File Reference

dem — fused colour sweeps: one persistent kernel per sweep instead of one kernel launch per colour. More...

#include <algorithm>
#include <cstdlib>
#include <vector>
#include <Kokkos_Core.hpp>
#include "contact_preprocessing.hpp"

Go to the source code of this file.

Classes

struct  peclet::dem::FusedSweepCtx
 Device-side context for a fused colour sweep: the colour offsets (numColors+1, uploaded from buildColorBucketsKokkos's host vector), the barrier counter, and the largest colour bucket (grid sizing). More...
 
struct  peclet::dem::FusedLoopSpec
 Device-side iteration loop: run up to maxIters sweeps of the colour classes inside ONE kernel, evaluating the adaptive stop on-device (the same residual the host loop read back between launches — the readback round trip and the CUDA-graph capture disappear entirely). More...
 

Namespaces

namespace  peclet
 
namespace  peclet::dem
 

Functions

bool peclet::dem::demFusedWanted (bool graphReplayAvailable)
 Fused-sweep policy (read once).
 
FusedSweepCtx peclet::dem::demMakeFusedCtx (CpExec &space, const std::vector< int > &offs, Kokkos::View< int *, CpMem > offsDev, Kokkos::View< unsigned *, CpMem > bar)
 Fill a FusedSweepCtx from buildColorBucketsKokkos's host offsets: async-upload them into the pooled device view and record the largest bucket.
 

Detailed Description

dem — fused colour sweeps: one persistent kernel per sweep instead of one kernel launch per colour.

The impulse step is host-submission-bound (measured ~3,300 kernel launches per step at 25k; the CUDA-graph pass reduced the replay cost but the capture still re-emits ~200 kernels per captured iteration). The colour-to-colour sequencing is the Gauss–Seidel dependency, so the per-colour launches can be collapsed into ONE kernel that iterates the colours device-side with a grid-wide barrier between them. Colour classes are body-disjoint, each work item is computed by exactly one thread with the same per-item math as the launch path, and the barrier reproduces the launch path's colour ordering — the fused sweep is bit-identical.

The barrier is a software grid barrier (monotone arrival counter, reset per launch), NOT cooperative-groups grid sync: it needs no -rdc compilation, no cooperative-launch driver support, and captures into CUDA graphs like any plain kernel. Deadlock-freedom comes from launching at most cudaOccupancyMaxActiveBlocksPerMultiprocessor blocks — every launched block is co-resident, exactly the invariant cooperative launch enforces.

CUDA-only; every other backend (and PECLET_DEM_NO_FUSED=1) keeps the per-colour launch path.

Definition in file solver_fused.hpp.