Add CUDA graph capture (CudaStream.BeginCapture/EndCapture, CudaGraph, CudaGraphExec) - #1602
mfagerlund wants to merge 2 commits into
Conversation
…, CudaGraphExec Records a fixed-shape sequence of stream submissions once and replays it with a single cuGraphLaunch. New public surface lives in ILGPU.Runtime.Cuda and is CUDA-only, like CuBlas/CuFFT; the cross-backend abstractions are untouched (the methods are on the sealed CudaStream, not AcceleratorStream). - CudaStream.BeginCapture/EndCapture (cuStreamBeginCapture_v2 / cuStreamEndCapture) - CudaGraph.Instantiate -> CudaGraphExec.Launch (cuGraphInstantiateWithFlags / cuGraphLaunch), with cuGraphDestroy / cuGraphExecDestroy on dispose - Driver bindings added to CudaAPI.xml (regenerated via DllImports.tt) with CudaError-wrapped helpers in CudaAPI.cs - New handle types are AcceleratorObject subclasses following the CudaProfilingMarker lifetime pattern (BindScoped / VerifyDisposed) - CudaGraphCapture tests (SkippableFact, CUDA-only): capture records without executing; each Launch replays exactly once; a multi-launch capture replays the whole sequence per launch cuGraphExecUpdate and manual node-graph construction are intentionally out of scope for this first cut.
|
Heads-up on the second commit: it bumps the repo-wide copyright year |
Remove the c:\slask\ILGPU / c:\slask\graphbench local filesystem paths from the artifact; keep the technical facts (fork, commit ea51bcb, on-device numbers). The PR is now public (m4rs-mt/ILGPU#1602).
|
Thank you for this contribution 👍! The implementation is minimal and idiomatic, and it follows the established CUDA runtime conventions closely ( Target branch: I recommend retargeting this PR to Finally, a note on our roadmap. We have a v2.0 line in progress. Graph capture ports forward cleanly, as it resides in the Cuda runtime directory |
Summary
Adds a small, additive wrapper over the CUDA driver's stream-capture and graph API: record a fixed-shape sequence of launches once (
CudaStream.BeginCapture/EndCapture→CudaGraph), instantiate it (CudaGraph.Instantiate→CudaGraphExec), and replay the whole sequence with a singlecuGraphLaunch(CudaGraphExec.Launch).The new types live in
ILGPU.Runtime.Cudaand are CUDA-only by design — the same shape of contribution asCuBlas/CuFFT/CuRand. Nothing in the cross-backend abstraction changes; OpenCL/CPU/Velocity are untouched, because the methods are on the sealedCudaStream, not onAcceleratorStream.Performance characterization (please read — this is not a universal speedup)
CUDA graphs amortize host-side launch dispatch across a repeated, fixed-shape sequence of launches.
Measured on an RTX 4090 on this branch (kernels only; eager vs. one
cuGraphLaunchper step):The intended consumers are small-network training/inference loops (RL policies, control nets, small MLPs) where the C# launch path, not the GPU, is the bottleneck.
API
Because an instantiated graph is a reusable handle and
Launchis one call, graphs compose: captureprep,batch, andfinalizeseparately and runprep; for (i < N) batch; finalize;withNa plain host loop bound — no re-capture whenNchanges.Scope
cuGraphExecUpdate(re-binding parameters without re-instantiating) is intentionally deferred to a follow-up; manual node-graph construction is out of scope.cuGraphInstantiateWithFlagsis CUDA 11.4+. If older drivers need supporting, that entry point can be selected by driver version — happy to adjust.Implementation notes
Src/ILGPU/Runtime/Cuda/CudaAPI.xmland the P/Invoke layer is regenerated by the existingDllImports.tt;CudaError-wrapped helpers sit inCudaAPI.csnext to the stream helpers.CudaGraph/CudaGraphExecareAcceleratorObjectsubclasses using the same lifetime/BindScoped/CudaException.VerifyDisposedpattern asCudaProfilingMarker.Tests
Src/ILGPU.Tests/CudaGraphCapture.cs(registered inConfigurations.txt):SkippableFacts guarded onAcceleratorType != Cuda, so they exercise CUDA hardware and Skip elsewhere (CUDA runners are disabled in CI). They assert that capture records without executing, eachLaunchreplays exactly once, and an N-launch capture replays the whole sequence per launch. 6/6 green on a 4090.A note on timing
I can see you're mid-flight on 2.0 (
new_architecture_v2); this targetsmasteras a purely additive change to the current CUDA runtime. No rush at all — happy to align it with your design preferences, or to hold and fold it into the 2.0 runtime if you'd prefer that.