Skip to content

Make arena alignment absolute via a base pad - #6

Open
AntonOresten wants to merge 2 commits into
mainfrom
arena-base-pad
Open

Make arena alignment absolute via a base pad#6
AntonOresten wants to merge 2 commits into
mainfrom
arena-base-pad

Conversation

@AntonOresten

Copy link
Copy Markdown
Member

Arena: pad the origin so alignment is absolute

Arena's alignment was defined relative to the slab's first byte, with absolute alignment documented as the slab provider's problem: fine for CUDA's 256-aligned bases, silently short for a Julia Vector's 16/64-aligned base, and an actual correctness fault for odd-based view slabs (a Float32 carve at an absolutely-misaligned address is a kernel fault on a GPU, not a perf note).

The arena now pads its origin by -base mod alignment at construction, when the storage exposes a base address through the new slabbase(slab) hook:

  • DenseVector{UInt8} answers UInt(pointer(slab)) — covers Vector, Mmap, CuArray, JLArray with no extension.
  • The generic answer is nothing: no pad, today's relative contract, for storages without a stable pointer.

Carve addresses are then divisible by alignment wherever the slab landed, costing at most alignment - 1 bytes, once. For CUDA slabs the base is already 256-aligned, so the pad is zero and nothing changes. Offsets, marks, and the watermark stay relative to the padded origin — mark/retract!/reset! and address determinism under capture are untouched. The watermark docstring now notes the + alignment slack when sizing a fresh slab, since a differently-based slab pads differently.

The base is a virtual address, which is the correct notion here: every alignment consumer (cuBLASLt/cuDNN contracts, load/store units) checks the VA, and pages map whole so VA ≡ PA modulo the page size — far above any alignment an arena is asked for. The one real hazard, a base that can move, is made part of the slabbase contract: such storage must answer nothing.

CaptureViolation: docstring rewritten around remeasured ground truth

Re-verified the failure modes on driver 13.3 / CUDA.jl 6.2.1. The old docstring claimed freeing inside the captured region "does not rescue it: the free path errors during capture" — that is no longer true. The rewrite splits the hazard as it actually behaves:

  • Free outside the region or absent (no-op release!, frame closing after capture, escaped buffer): unpaired allocation node, graph launches once, second launch fails with ERROR_INVALID_VALUE, GC-timing dependent.
  • Free inside the region: nodes pair, replay is legal and measured correct — but it stands on driver behavior CUDA.jl documents as unsupported, pays per-replay map/unmap, records fresh addresses on re-capture, and a pool-exhausted allocation mid-capture still escalates to device_synchronize, invalidating the capture with GC disabled.

The guard's doctrine is unchanged — GC spaces refuse under capture, arenas carve — the justification is just no longer stale.

Tests

Two slab-aliasing tests index above the pad; a new testset covers carve-address divisibility on a Vector slab, the nothing-base fallback for view slabs, and the pad counting against the ceiling. 181/181 pass, plus a live check on a CuVector slab (pad 0, carves 256-aligned).

🤖 Generated with Claude Code

@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

AntonOresten and others added 2 commits August 10, 2026 18:17
An arena's alignment was relative to the slab's first byte, leaving
absolute alignment to whoever allocated the slab: fine for CUDA's
256-aligned bases, silently short for a Julia Vector's 16/64, and a
real fault for odd-based view slabs. Pad the origin by -base mod
alignment instead, when the storage exposes a base address through the
new slabbase hook (dense vectors answer their pointer; the generic
answer is nothing, keeping the relative contract). Carve addresses are
now divisible by the alignment wherever the slab landed, for at most
alignment - 1 bytes, once.

Also rewrite the CaptureViolation docstring around remeasured ground
truth (driver 13.3, CUDA.jl 6.2.1): a free recorded inside the captured
region does pair with its allocation node and replays legally, so the
hazard splits in two — an unpaired free fails relaunch with
ERROR_INVALID_VALUE, a paired one works but stands on driver behavior
CUDA.jl documents as unsupported, pays per-replay map/unmap, and still
dies by device_synchronize if the pool is exhausted mid-capture. The
old claim that the free path errors during capture is gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant