Skip to content

Apple GPU R1 (start): device-resident bmm (op-to-op residency) - #34

Merged
gstoner merged 1 commit into
mainfrom
apple-gpu-resident-r1
May 30, 2026
Merged

gstoner merged 1 commit into
mainfrom
apple-gpu-resident-r1

Conversation

@gstoner

@gstoner gstoner commented May 30, 2026

Copy link
Copy Markdown
Owner

First handle-taking kernel entry point in the GPU-resident activation build-out
(docs/apple_gpu_resident_activations_plan.md). Proves the core mechanism:
a producer op's output feeds the consumer with no host round-trip.

What

  • tessera_apple_gpu_bmm_dev_f32(TsDeviceTensor A, B, O, …) — the inputs'
    shared MTLBuffers (from DeviceTensor handles, R0) are used in place (no
    newBufferWithBytes upload), and the MPSGraph result is written straight
    into the output buffer
    via resultsDictionary (no readBytes). It reuses
    the existing bmm graph cache key, so it shares the compiled graph with the
    host-ptr path.
  • runtime._apple_gpu_bmm_device(A, B) — both inputs DeviceTensors,
    returns a resident DeviceTensor [batch,M,N]. f32; [batch,M,K] × [batch|1,K,N] (with B-broadcast).
  • Non-Apple stub parity (host bmm into O->data).

The proof

test_chain_keeps_intermediate_resident: C = bmm(A,B); D = bmm(C, E) — the
intermediate C is consumed by the second bmm directly as a DeviceTensor,
never materialized to host; only the final D is read back. A 4-deep chain test
reads back only at the very end. This is the mechanism that lets the decode loop
stop round-tripping activations.

Tests

tests/unit/test_apple_gpu_resident_bmm.py6 tests: vs numpy, B-broadcast,
2-bmm resident chain, 4-deep chain (host read only at the end), non-f32
rejection, symbol export.

Scope (this PR vs. the rest of R1)

This lands the keystone (bmm) and proves op-to-op residency end-to-end.
Remaining R1 (follow-up PRs): handle entry points for absorb_decode /
rowops / the Gumbel sampler, and threading handles through the metadata dispatch
loop with lazy materialization.

Verification (local, Apple Silicon)

  • resident-bmm + device-tensor suite: 19/19; apple_gpu + mla + buffer-pool sweep: 534 passed
  • buffer-pool RAII gate: pass (the dev path uses existing buffers — no raw allocs)
  • mypy ratchet: clean (only the pre-existing environmental torch-import error)

CI on this repo is uniformly red on main (Python 3.8–3.11 matrix, missing
optional deps) — same state PRs #17#33 merged through. The local signal above
is green.

🤖 Generated with Claude Code

First handle-taking kernel entry point in the GPU-resident activation build-out.

- apple_gpu_runtime.mm: mpsg_run_bmm_dev + tessera_apple_gpu_bmm_dev_f32(
  TsDeviceTensor A, B, O, ...). The inputs' shared MTLBuffers (from DeviceTensor
  handles) are used in place — no host upload — and the MPSGraph result is
  written straight into the output buffer via resultsDictionary — no readback.
  Reuses the bmm graph cache key (same compiled graph as the host-ptr path).
- apple_gpu_runtime_stub.cpp: non-Apple parity (host bmm into O->data).
- runtime.py: _apple_gpu_bmm_dev_f32 ctypes wrapper + _apple_gpu_bmm_device(
  A: DeviceTensor, B: DeviceTensor) -> DeviceTensor — allocates a resident
  output and returns it; f32, [batch,M,K] x [batch|1,K,N].
- tests/unit/test_apple_gpu_resident_bmm.py: 6 tests — vs numpy, B-broadcast,
  a 2-bmm chain whose intermediate is consumed as a DeviceTensor without a
  readback, a 4-deep chain read back only at the end, non-f32 rejection, symbol
  export.
- docs: plan R0 marked done, R1 marked started with the remaining handle ops
  (absorb_decode / rowops / gumbel) + dispatch-loop threading noted.

ts_dev_alloc-style persistent buffers only; no new tessera_* ABI symbols, so the
runtime ABI dashboard is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3c0ca14c7c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread python/tessera/runtime.py
Comment on lines +4978 to +4979
runtime = _load_apple_gpu_runtime()
sym = getattr(runtime, "tessera_apple_gpu_bmm_dev_f32", None)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require resident-bmm symbol before accepting cached runtime

When TESSERA_APPLE_GPU_RUNTIME_LIB or the CMake build directory points at a library built before this change, _load_apple_gpu_runtime() still accepts it because its symbol gate was not extended for tessera_apple_gpu_bmm_dev_f32; this new lookup then returns None and every resident-bmm call is silently unavailable instead of forcing the rebuild path the loader uses for prior runtime additions. Please add the new symbol to the loader's required-symbol checks so stale cached runtimes do not disable the feature.

Useful? React with 👍 / 👎.

@gstoner
gstoner merged commit 4e2ab47 into main May 30, 2026
8 of 26 checks passed
@gstoner
gstoner deleted the apple-gpu-resident-r1 branch May 30, 2026 16:23
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