Repository navigation
fix(update): UpdatePlan must not read the destination when beta == 0; add execute_uninit - #317
Merged
Merged
Conversation
UpdatePlan::execute and ErasedUpdatePlan::execute always replayed
`alpha*f(src) + beta*dst`, so even beta == 0 read the old destination.
BLAS semantics (and the fresh-output accumulate tcontract needs) require
beta == 0 to be write-only: otherwise NaN/garbage in D propagates through
0 * NaN and a fresh output can never be represented as uninitialized.
- Branch on num_traits::{Zero, One, PartialEq}: beta.is_zero() replays
`*dst = alpha * value` (or `*dst = value` when alpha.is_one()), never
forming a destination read. -0.0 counts as zero; NaN stays on the read
path.
- Add UpdatePlan::execute_uninit and ErasedUpdatePlan::execute_uninit
(beta implicitly zero) that fully initialize every reachable slot,
following the existing *_uninit validation-before-write convention.
- Tests: typed and erased f32/f64/c64, contiguous/permuted, NaN-poisoned
destinations and poisoned MaybeUninit, serial and two-worker, -0.0 and
NaN beta. alloc_matrix asserts zero allocations for the uninit replay.
shinaoka
enabled auto-merge (squash)
October 17, 2026 11:57
Repository rules reviewRepository rules review (ddbe17bcb64969a062d2a052f61afbdec9cd18c3...62d259f3e4e99e871082e660e2f78abfd668f7ea) Verdict: pass Findings: - [warn] llm-skipped (External LLM Review) <unknown>: External LLM review was skipped External LLM review is permanently disabled; deterministic checks only. |
shinaoka
added a commit
that referenced
this pull request
Oct 17, 2026
* chore: release strided 0.6.0 (all crates) Allocation-free API (#316, #306) and UpdatePlan beta=0 (#317). Versions unified on the workspace at 0.6.0. Release note: docs/worklogs/2026-10-17-release-0.6.0.md. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * bench(basic): set the S3 smoke thresholds from the slowest machine seen The GitHub-hosted runner measured S3a 1.87 / S3b 3.15 after #317 made the beta == 0 compiled baseline write-only; the reference host measures ~1.5 / ~2.2. Initial thresholds 2.5 / 4.0, to be tightened from CI history (#306). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #316, found by the tcontract 0.3 pre-review (tcontract-rs#121).
UpdatePlan::executereplayed*dst = alpha * value + beta * *dstunconditionally. BLAS semantics require that beta == 0 does not read the destination; otherwise NaN or garbage in D leaks through0 * NaN = NaN, and a fresh output can never be represented as uninitialized.Zero::is_zero, so -0.0 counts as zero and a NaN beta keeps the read path),UpdatePlanandErasedUpdatePlantake a write-only replay (*dst = alpha * value). The bounds gainZero + One + PartialEq.UpdatePlan::execute_uninitandErasedUpdatePlan::execute_uninitwrite intoMaybeUninitstorage with beta implicitly 0. Validation and the overlap check happen before any write, and every reachable slot is initialized.execute_uninitinitializes every slot, including a layout with holes.alloc_matrixarms assert 0 allocations at rank 1..=8.copy_plan.rs97.2%,erased.rs87.6%, all 48 files pass.cargo test --profile ci, the parallel lane and--no-default-featuresare green.This lands before the 0.6.0 release PR.
🤖 Generated with Claude Code