Skip to main content

Transient buffer lifetime reuse

At a glance

QuestionAnswer
ProblemReuse compatible physical storage for large logical transients with disjoint lifetimes.
Reads / writesThe planner consumes declared lifetimes and emits allocation assignments.
OwnershipLogical resources remain graph-owned; compiled allocations follow the plan.
Output contractDeterministic logical-to-physical assignments with peak-byte accounting.
Expected workCPU-side interval planning over declared transient requests.
ChunksChunk identity remains logical and is not implicitly repacked.
Conditions / budgetsPlanning occurs at graph compilation and never changes an encoding topology.
Neighborhoodgraph resource lifetimes โ†’ planner โ†’ compiled transient allocations.

Overviewโ€‹

Large GPU algorithms frequently need scratch buffers that are never live at the same time. A sort workspace may be dead before an FFT temporary is needed; hierarchical reduction partials disappear before a later solver phase.

node โ†’ 0 1 2 3 4 5 6 7 8 9
sort scratch โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
FFT temp โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
reduction โ–ˆโ–ˆโ–ˆ

Allocating all three independently makes peak physical memory equal to their sum even though their lifetimes do not overlap. A graph compiler can instead map compatible logical buffers onto fewer physical allocations.

What is reusedโ€‹

Lifetime reuse targets heavyweight transient buffers: reduction partials, sort workspace, FFT temporaries, sparse workspace and similar scratch resources.

It deliberately does not reuse GPUValueArena scalar slots. Hundreds of 32-bit values cost only hundreds or thousands of bytes, while stable scalar offsets make WGSL, traces and debugging substantially easier to understand.

Safetyโ€‹

Two logical buffers can share storage only when:

  1. their graph-node lifetimes do not overlap;
  2. the physical allocation satisfies the required usage flags;
  3. the physical allocation is at least as large as the logical buffer.

The first planner uses greedy best-fit interval reuse. It is deterministic and intentionally conservative.

Exampleโ€‹

A: 8 MiB, nodes 0โ€“3 โ”€โ”€โ”€โ”€โ”€โ”
โ”œโ”€ physical allocation 0: 8 MiB
B: 6 MiB, nodes 5โ€“8 โ”€โ”€โ”€โ”€โ”€โ”˜

C: 4 MiB, nodes 2โ€“7 โ”€โ”€โ”€โ”€โ”€โ”€โ”€ physical allocation 1: 4 MiB

Logical storage is 18 MiB; peak physical storage is 12 MiB.

Compiler integrationโ€‹

This PR introduces the planning policy separately from physical graph allocation. The next integration step can derive lifetimes from resource accesses in the dependency-ordered graph and feed assignments into transient allocation. Keeping policy separate makes it straightforward to test aliasing safety before changing resource ownership.