Inferensys

Glossary

CUDA Graph

CUDA Graph is an NVIDIA CUDA construct that captures a sequence of kernel launches and memory operations into a single, replayable unit to reduce launch overhead and improve GPU utilization.
Operations room with a large monitor wall for system visibility and control.
INFERENCE OPTIMIZATION

What is CUDA Graph?

A CUDA Graph is a NVIDIA CUDA construct that captures a sequence of kernel launches and memory operations into a single, replayable unit, which reduces launch overhead and can be seen as a form of coarse-grained, launch-time fusion.

A CUDA Graph is a NVIDIA CUDA programming model construct that records a sequence of interdependent kernel launches and memory operations into a single, replayable unit called a graph. Once captured, the entire graph can be launched with a single low-overhead CPU call to the driver, replacing numerous individual launches. This is a form of launch-time fusion, amortizing the substantial kernel launch overhead across all captured work. It is particularly effective for inference workloads with static execution patterns.

The primary optimization is the elimination of per-kernel launch latency and driver dispatch overhead. By defining the workflow ahead of time, the CUDA driver can optimize scheduling and dependencies. This makes CUDA Graphs ideal for inference servers using techniques like continuous batching, where the same model execution steps are repeated. Unlike fine-grained kernel fusion, which merges operations computationally, CUDA Graphs fuse the launch mechanism, offering significant speedups for small, frequent kernels.

CUDA GRAPH

Key Features and Characteristics

A CUDA Graph captures a sequence of kernel launches and memory operations into a single, replayable unit, fundamentally altering how work is submitted to the GPU to minimize launch latency and CPU overhead.

01

Graph Capture and Instantiation

A CUDA Graph is constructed in two distinct phases. First, a capture sequence is initiated, during which all subsequent CUDA API calls (e.g., kernel<<<>>>(), cudaMemcpyAsync) are recorded into a graph object instead of executing immediately. This creates a template of operations. The graph is then instantiated into an executable graph, which is a lightweight, optimized representation ready for repeated replay. This separation allows for one-time setup costs to be amortized over many executions.

02

Launch Overhead Elimination

The primary performance benefit stems from eliminating per-launch overhead. In a traditional CUDA stream, each kernel launch incurs costs for:

  • Driver and runtime latency
  • Scheduling work onto the GPU
  • Kernel argument marshaling

A CUDA Graph bundles all work into a single, coarse-grained operation. When the graph is launched (cudaGraphLaunch), the entire sequence is submitted with the overhead of a single launch, not N launches. This is particularly impactful for workloads comprising many small, rapid-fire kernels.

03

Static Workflow Definition

A CUDA Graph represents a static workflow. The graph's structure—the kernels, their dependencies, and the memory addresses they operate on—is fixed at instantiation. This allows the CUDA driver to perform aggressive optimizations upfront:

  • Optimal node scheduling and dependency resolution.
  • Pre-allocation of resources like GPU registers and shared memory.
  • Pre-fetching of kernel arguments to GPU-accessible memory.

This static nature means graphs are ideal for inference loops, solvers, and other compute patterns where the operation sequence is invariant across iterations, even if the input data changes.

04

Conditional and Parameterized Nodes

While the graph structure is static, execution parameters can be updated between launches without re-capturing. This is achieved through:

  • Graph node parameters: Kernel parameters (e.g., pointers to input/output buffers) can be updated using cudaGraphExecKernelNodeSetParams.
  • Conditional nodes: Introduced in CUDA 10, child graphs and conditional nodes (e.g., cudaGraphAddChildGraphNode, cudaGraphAddConditionalNode) allow for limited dynamism, where sub-graphs can be executed based on a runtime condition, blending static optimization with runtime flexibility.
05

Integration with Deep Learning Frameworks

Major frameworks leverage CUDA Graphs to accelerate inference. For example:

  • TensorRT uses graphs to capture the entire engine execution.
  • PyTorch's torch.cuda.CUDAGraph API allows users to capture model-forward passes.
  • Triton Inference Server employs graphs to capture the end-to-end pre-process/model/post-process pipeline.

The typical pattern is warm-up, capture, then replay. The first iteration runs normally to allocate memory and populate caches; this execution is captured into a graph; all subsequent inferences replay the efficient graph.

06

Comparison to Kernel Fusion

CUDA Graphs and kernel fusion are complementary but distinct optimization layers. Kernel fusion is a compile-time optimization that merges multiple computational operators (e.g., Conv + BatchNorm + ReLU) into a single, custom fused kernel to reduce global memory traffic. CUDA Graph is a launch-time optimization that groups multiple, potentially independent, kernel launches (fused or not) into a single submission unit to reduce CPU-driven launch latency. An optimized pipeline often uses both: fused kernels within a CUDA Graph.

PERFORMANCE COMPARISON

CUDA Graph vs. Traditional Stream Execution

A technical comparison of the execution models, focusing on launch overhead, memory usage, and suitability for different inference workloads.

Feature / MetricTraditional Stream ExecutionCUDA Graph Execution

Launch Overhead per Kernel

~5-50 µs

< 1 µs (amortized)

CPU Driver Call Overhead

High (per kernel)

Near-zero (single launch)

Execution Model

Dynamic, sequential enqueue

Static, pre-recorded graph

Kernel Dependency Resolution

Runtime, via streams/events

Pre-defined at capture

Memory Transfer Overhead

Explicit per-copy

Can be fused within graph

Suitability for Micro-Batching

Good

Excellent (fixed pattern)

Dynamic Shape Support

Native

Requires graph re-capture or instantiation

Memory Footprint for Launch State

Lower

Higher (stores entire graph)

Optimal Use Case

Dynamic workloads, variable control flow

Static, repetitive inference pipelines

CUDA GRAPH

Frequently Asked Questions

CUDA Graphs are a core NVIDIA technology for reducing kernel launch overhead by capturing and replaying sequences of operations. This section answers common technical questions for compiler and performance engineers.

A CUDA Graph is a NVIDIA CUDA construct that captures a sequence of kernel launches, memory copies, and synchronization events into a single, replayable unit of work, which reduces launch overhead and enables launch-time optimization.

It works in two phases:

  1. Capture: The application's existing CUDA streams are instrumented to record the graph's structure—the nodes (operations like kernels or memory copies) and their dependencies.
  2. Instantiation & Replay: The captured graph is compiled into an executable form, called a graph instance. This instance can be launched repeatedly with a single API call (cudaGraphLaunch), bypassing the driver overhead associated with individual cudaLaunchKernel calls. The graph's structure is fixed, but node parameters (like kernel arguments or memory addresses) can be updated between replays using graph node update APIs.
Prasad Kumkar

About the author

Prasad Kumkar

CEO & MD, Inference Systems

Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.

His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.