Skip to content

defk-o08.6: rolling_stats mean_std raises on a bad window, so its loop keeps no bounds check - #72

Merged
DanielLuning merged 1 commit into
mainfrom
defk-o08.6/rolling-guard
Oct 20, 2026
Merged

DanielLuning merged 1 commit into
mainfrom
defk-o08.6/rolling-guard

Conversation

@DanielLuning

Copy link
Copy Markdown
Owner

What changed

The last gap of epic defk-o08, found in its closing check. defk-9za was opened for examples/rolling_stats.exs mean_std, where old = if i >= w, do: x[i - w], else: 0.0 keeps a bounds check. defk-b38 made the compiler drop that check once a raising guard establishes w >= 1, and 9za closed on a test kernel that has the guard. The catalog kernel never got the guard.

  • examples/rolling_stats.exs: mean_std now starts with if w < 1 or w > n, do: raise(ArgumentError, "the window must be in 1..length(x)"). Past the guard, 1 <= w <= n holds: an or that is false narrows both sides. That proves x[i - w], and both out writes, because m = n - w + 1 >= 1 and length(out) == 2 * m. The kernel's comment and the example's header say so.
  • test/non_finite_test.exs: a test used the catalog mean_std with invalid windows (-1, 0) to put a bad value and an out-of-range read or a zero divisor in one flagged strip. The guard now raises first, which is correct in Elixir order, and both modes agree.
    • That test now runs on Defk.NonFiniteTest.Rolling, an unguarded copy of the old kernel. Its assertions and C checks are unchanged.
    • A new test covers the catalog kernel: w = -1, 0 and n + 1 raise the guard's ArgumentError before any read; a NaN with a valid window still raises; w = n succeeds; and the C still checks the window-sum reads once per strip, with no checked read left.
  • docs/performance.md: a new entry 6.42.

Results

From the fast-path report under report: :full, before → after:

  • Bounds checks kept: 3 → 0 (x[i - w], out[i - w + 1], out[m + i - w + 1]).
  • The loop's flagged strip: it carried float, overflow and bounds checks, and now carries only float checks. The overflow checks of the index arithmetic went with the bounds facts.
  • Vectorisation: clang's remark no longer cites "cannot identify array bounds". But the sliding sums are a recurrence, so the loop stays scalar, and no speed-up from vector code is expected.
  • Not timed: the stored scoreboard row is stale until a new measurement is asked for (docs/agents/runs.md).

How it was checked

  • mix ci on the laptop (macOS) passed: 2305 tests, Credo found no issues, Dialyzer reported 0 errors.

  • mix defk.examples --only rolling_stats: the example's check passed, without timing.

  • mix dump_c examples/rolling_stats.exs: Rolling.Kernels.report lists all four accesses as dropped.

  • Touches a promised surface? No: an example script and a test. No CHANGELOG.md entry.

  • Touches test/stability/? No.

…p keeps no bounds check

A raising guard 'if w < 1 or w > n' before the loop gives 1 <= w <= n,
which proves x[i - w] and both out writes: the module's report lists no
kept bounds check (was 3), the flagged strip carries float checks only,
and clang's remark no longer cites the array bounds (the sliding sums
still keep the loop scalar). A window outside 1..length(x) now raises
ArgumentError at the call. non_finite_test's mixed-error strip case moves
to an unguarded copy of the kernel; the catalog kernel gets a test of its
guard (docs/performance.md 6.42). Closes the last gap of epic defk-o08.
DanielLuning pushed a commit that referenced this pull request Oct 20, 2026
…port 3 -> 0 kept bounds checks; non_finite_test's mixed-error case on an unguarded copy; mix ci green."
@DanielLuning
DanielLuning merged commit 2595489 into main Oct 20, 2026
2 checks passed
@DanielLuning
DanielLuning deleted the defk-o08.6/rolling-guard branch October 20, 2026 12:48
DanielLuning pushed a commit that referenced this pull request Oct 20, 2026
…026-10-20) closed the last gap; the closing check's catalog kernels list none of the children's bounds checks (cosine_topk, pcm_mix sum loop, rolling_stats mean_std). Compile time: +3.5% of the work before step 1 after defk-o08.2-o08.5."
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