Skip to content

feat(schema): optional GPU device-memory fields (gpu_allocations_bytes, gpu_live_bytes) — Piccolissimo #252 - #17

Open
jeonghun-jj-lee wants to merge 1 commit into
mainfrom
feat/issue-252-gpu-memory-fields
Open

feat(schema): optional GPU device-memory fields (gpu_allocations_bytes, gpu_live_bytes) — Piccolissimo #252#17
jeonghun-jj-lee wants to merge 1 commit into
mainfrom
feat/issue-252-gpu-memory-fields

Conversation

@jeonghun-jj-lee

Copy link
Copy Markdown

What

Adds two optional, defaulted device-memory fields to the BenchmarkResult schema so the GPU arms of the dimension-ladder scaling benchmark (Piccolissimo #249, ADR 0007 / PR #250) can record the axis the benchmark exists to measure:

  • gpu_allocations_bytes — cumulative device allocation over the timed solve (deterministic GPU analogue of host total_allocations_bytes).
  • gpu_live_bytes — post-solve live device bytes.

Both are Union{Nothing,Int} defaulting to nothing.

Absent-value semantics (documented on the schema): nothing = "device axis not measured" — CPU-arm solves, and any result serialized before these fields existed, deserialize as nothing. A concrete 0 is distinct: it means the device WAS measured and the delta was zero.

Capturing the values during solves is out of scope here — that is consumed by the GPU-arms slice (Piccolissimo #254). This PR is the schema + serialization contract only.

Backward-compatibility guarantee (the hard invariant)

A BenchmarkResult JLD2-serialized under the old schema deserializes as a JLD2.ReconstructedMutable{:BenchmarkResult} once the struct gains fields — which load_results could not convert into Vector{BenchmarkResult} (it threw a MethodError). This PR adds a convert(::Type{BenchmarkResult}, ::JLD2.ReconstructedMutable{:BenchmarkResult}) upgrade shim in storage.jl that reads the fields the old blob carries and defaults any it lacks. It is written generically over the reconstructed field set, so it also tolerates future additive schema changes.

Proof: a committed pre-change fixture test/fixtures/pre_gpu_fields_v1_pregpu0.jld2 (serialized with the schema before these fields existed) plus a regression test that loads it and asserts it comes back as a real Vector{BenchmarkResult} with the GPU fields defaulting to nothing and every pre-existing field intact.

Comparison path

Untouched — no comparison keys on the new fields (AC3). CPU-arm results are unaffected (fields simply default).

Tests

Pkg.test()333 pass, including:

  • GPU device-memory fields (schema + defaults) — omitted ⇒ nothing; explicit 0 distinct from nothing; real GPU values carried.
  • GPU device-memory fields: JLD2 round-trip — new results with GPU values and with defaulted (nothing) fields both round-trip.
  • Backward-compat: pre-GPU-fields fixture still loads — the committed pre-change fixture loads with fields defaulted.

Refs

Piccolissimo #252 (parent #249); ADR 0007 (PR #250). Blocks Piccolissimo #254. After merge, the Piccolissimo scaling env gets re-pinned to this revision (handled separately, per SHA-pinned-env convention).

🤖 Generated with Claude Code

…iccolissimo #252)

Add two optional, defaulted fields to the BenchmarkResult schema so the GPU
arms of the dimension-ladder scaling benchmark (Piccolissimo #249, ADR 0007)
can record device memory — the axis the benchmark exists to measure:

  - gpu_allocations_bytes: cumulative device allocation over the timed solve
  - gpu_live_bytes:        post-solve live device bytes

Both are Union{Nothing,Int} defaulting to `nothing`. Absent-value semantics:
`nothing` = "device axis not measured" (CPU-arm solves, and any result
serialized before these fields existed); a concrete `0` is distinct and means
the device WAS measured with a zero delta. Field names mirror the host
`total_allocations_bytes` convention. Capturing the values during solves is
out of scope here (consumed by the GPU-arms slice, Piccolissimo #254).

Backward-compat (the hard invariant): a BenchmarkResult JLD2-serialized under
the old schema deserializes as a JLD2.ReconstructedMutable once the struct
gains fields, which load_results could not convert. Added a
`convert(::Type{BenchmarkResult}, ::JLD2.ReconstructedMutable{:BenchmarkResult})`
upgrade shim in storage.jl that reads the fields the old blob carries and
defaults any it lacks (written generically so it also tolerates future
additive changes). A committed pre-change fixture
(test/fixtures/pre_gpu_fields_v1_pregpu0.jld2) plus a regression test prove
old baselines still load with the GPU fields defaulting to `nothing`.

Comparison path is untouched: no comparison keys on the new fields (AC3).

Tests: 333 pass, including new gpu-fields default/round-trip testsets and the
backward-compat fixture load.

Refs: Piccolissimo #252, #249; ADR 0007 (PR #250).

Co-Authored-By: Claude Opus 4.8 (1M context) <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