Skip to main content

Piecewise CUDA graphs for PyTorch

Project description

Piecewise CUDA Graphs

Piecewise CUDA Graphs extends the standard PyTorch CUDA graph workflow.

With torch.cuda.graph, one context manager captures one CUDA graph. That works well when the whole region is capture-compatible. piecewise-cuda-graphs keeps the same capture/replay shape, but lets one with piecewise_graph(...) block produce a sequence of CUDA graph segments separated by explicit eager breaks. If no eager breaks occur, the block is captured as a single graph segment.

Use this when most of a workload should run under CUDA graphs, but some sections are not CUDA-graph-compatible or otherwise need to run eagerly. Mark those sections with @no_graph, and make their CUDA inputs/outputs obey the constraints below.

Quick start

Install from source into an environment with PyTorch and CUDA support:

git clone https://github.com/meta-pytorch/piecewise-cuda-graphs.git
cd piecewise-cuda-graphs
pip install -e .

The capture flow is the same as regular CUDA graphs: allocate static buffers, warm up on a side stream, capture, then replay by updating the static inputs. The only addition is @no_graph, which marks functions that should run eagerly between captured graph segments.

import torch
from piecewise_cuda_graphs import CUDAGraphSequence, no_graph, piecewise_graph

@no_graph
def dynamic_scale(x: torch.Tensor) -> None:
    # Cannot be captured: reads a value back to the CPU.
    if x.sum().item() > 0:
        x.clamp_(min=0)

# Pre-allocate static buffers.
static_input = torch.empty(1024, device="cuda")
result = torch.empty(1024, device="cuda")

def workload(src: torch.Tensor, dst: torch.Tensor) -> None:
    dst.copy_(src * 2)
    dynamic_scale(dst)  # ends the current graph segment and runs eagerly
    dst.add_(1.0)

# Warm up on a side stream, as required by CUDA graphs.
s = torch.cuda.Stream()
s.wait_stream(torch.cuda.current_stream())
with torch.cuda.stream(s):
    for _ in range(3):
        static_input.fill_(1.0)
        workload(static_input, result)
torch.cuda.current_stream().wait_stream(s)

# Capture.
seq = CUDAGraphSequence()
with piecewise_graph(seq):
    workload(static_input, result)

# Replay with new data by overwriting the static input buffer.
static_input.fill_(5.0)
seq.replay()

Constraints

  • @no_graph functions must not return CUDA tensors. Write CUDA outputs into pre-allocated buffers passed as arguments.
  • Side streams must be joined back to the capturing stream before entering an @no_graph function or leaving the piecewise_graph context. Set PIECEWISE_CUDA_GRAPHS_DEBUG=1 to add still-unjoined stream id(s) to the resulting error.
  • Usual CUDA graph constraints still apply: replay uses the same tensor addresses captured during warmup/capture.

Additional usage

Explicit split points

force_no_graph() inserts a graph break with no eager work. This can be useful for debugging or isolating capture regions.

from piecewise_cuda_graphs import CUDAGraphSequence, force_no_graph, piecewise_graph

seq = CUDAGraphSequence()
with piecewise_graph(seq):
    a = step1(x)
    force_no_graph()
    b = step2(a)

Sharing memory pools

All graph segments within a sequence share the same CUDA graph memory pool. You can also share pools across sequences:

seq1 = CUDAGraphSequence()
with piecewise_graph(seq1):
    workload_a(buf_a, src_a)

seq2 = CUDAGraphSequence(pool=seq1.pool())
with piecewise_graph(seq2):
    workload_b(buf_b, src_b)

Reference

  • CUDAGraphSequence(pool=None): captured graph/eager segment sequence. Methods: replay(), reset(), pool().
  • piecewise_graph(seq, stream=None, capture_error_mode="global"): capture context, analogous to torch.cuda.graph.
  • @no_graph / @no_graph(enable=...): mark functions that run eagerly inside piecewise_graph.
  • force_no_graph(): explicit split point with no eager work.

For implementation details, see DESIGN.md.

License

BSD 3-Clause License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

piecewise_cuda_graphs-0.1.0rc0.tar.gz (17.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

piecewise_cuda_graphs-0.1.0rc0-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file piecewise_cuda_graphs-0.1.0rc0.tar.gz.

File metadata

  • Download URL: piecewise_cuda_graphs-0.1.0rc0.tar.gz
  • Upload date:
  • Size: 17.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for piecewise_cuda_graphs-0.1.0rc0.tar.gz
Algorithm Hash digest
SHA256 54b640be68ff64b38bf3c9fd0e45808b7313a06868c0331560b7594cb72b9f15
MD5 bc44348d28f120a1cbb38f0c45a85484
BLAKE2b-256 8309e24fcd453cdea5715939a368f6b19f600931817aa8037eb2bb2761d3c614

See more details on using hashes here.

Provenance

The following attestation bundles were made for piecewise_cuda_graphs-0.1.0rc0.tar.gz:

Publisher: publish_release.yml on meta-pytorch/piecewise-cuda-graphs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file piecewise_cuda_graphs-0.1.0rc0-py3-none-any.whl.

File metadata

File hashes

Hashes for piecewise_cuda_graphs-0.1.0rc0-py3-none-any.whl
Algorithm Hash digest
SHA256 939b069ad9de196cd8fc100b3b01d89de8e624f9bf0d99eb6b95cc87bab44d2d
MD5 5c9f0f1085226672004080aea027a136
BLAKE2b-256 fa358659ef0d66cacc292bffd8064dc8b6ad1c60431ecc05556e7b4dd499ab75

See more details on using hashes here.

Provenance

The following attestation bundles were made for piecewise_cuda_graphs-0.1.0rc0-py3-none-any.whl:

Publisher: publish_release.yml on meta-pytorch/piecewise-cuda-graphs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page