Repository navigation
defk-w8r.3: rank parameters in declaration order, so a guard between two arguments bounds the later one - #80
Merged
Conversation
…side A bench (bench/elixir_mode.exs) times two read-only hash kernels, one kernel with writes and two no-loop kernels three ways: the native kernel, its Elixir mode and the example's optimised Elixir, at 1 B to 1 KiB. Elixir mode is 7-17x the kernel at 1 B and 12-15x on a kernel with no loop (its entry alone is ~230 ns), 1.6-3.4x the optimised Elixir on reads and 100-200x on writes. No size-based switch; no decision ticket. Recorded as docs/performance.md 5.14.
…two arguments bounds the later one A gather loop (bench/gather_layer.exs) lists the checks its hot loop keeps. Most of the handwired study's list was already proven away; one was not for a reason of ranking: facts land on a condition's newest atom, and parameters ranked by their C names, so base <= length(x) bounded the length and not base, and base + idx[j] kept its overflow check. The facts scope now carries the parameters' declaration order, and the ranking (newest/2, the product's canonical form) reads it; a scope without one still ranks by name (the unit tests' scopes). The gate shows one module changed, which lost a range-limit test; the guarded gather loop runs about 0.75 ns per term where it was 0.9-1.1; the compiler does +0.5% of its work. Recorded as docs/performance.md 6.45; the rule for users in docs/language.md (raising guards).
2 tasks
DanielLuning
pushed a commit
that referenced
this pull request
Oct 22, 2026
…ters rank in declaration order, so base <= length(x) bounds base and base + idx[j] drops its overflow check; the table of checks and the numbers are docs/performance.md 6.45. Guarded gather loop 0.75 ns per term (was 0.9-1.1); compiler +0.5% work. Stays in progress until the merge."
DanielLuning
pushed a commit
that referenced
this pull request
Oct 22, 2026
…one countdown instead of two counters; fuzzy_search +30% -> +16%, Keccak unchanged (its 12 spills are the saves (8) and the resume dispatch (3), not the counters; 1.3x quiet). Variants V2 (charge on entry) and V3 (no bookkeeping register) measured, not adopted. Tick gap unchanged, mix ci green. docs/performance.md 6.46. Stays in progress until the merge."
DanielLuning
added a commit
that referenced
this pull request
Oct 22, 2026
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.
What changed
Stacked on #79 (defk-vcx.2): merge #79 first.
A gather-loop bench,
bench/gather_layer.exs, lists the runtime checks a sparse layer keeps per term (an[f32]weight array,[i32]indices,r * k + tindexing,base + idxgathers, one[f32]store per row), with and without a raising guard for the shape. Read on today's compiler, most of the handwired study's list was already proven away (product facts, 6.37). One check was not for a reason of ranking: a condition's fact lands on its newest atom, and parameters ranked by their C names, sobase <= length(x)was stored on the length ofxand said nothing aboutbase;base + idx[j]kept its overflow check.The facts scope now carries the parameters' declaration order (
Defk.Facts.scope/1), and the ranking reads it:newest/2, the prover'sle?/walk, the product's canonical form (form_mul/3,mul_facts/3) andnarrowing/2. A scope without an order (the unit tests' scopes) still ranks by name. The design doc already said "parameters first, by position"; ADR-0007 now says so too.docs/language.md(raising guards) tells users the rule: a condition between two arguments bounds the one declared later, so declare an offset after the array it is compared with.What stays in the gather loop is about array contents (the bounds check of the gather itself, the finite checks on
[f32]reads, the non-finite checks on the float multiply and add, the f32 range check on the store), which ADR-0007 keeps out of scope; the loop runs flagged, so each is a flag update, not a branch. The table is indocs/performance.md6.45.Results
mix dump_cboth sides, 113 modules): one module's C changed,Defk.ProductFactsTest.K, which lost one range-limit test on a loop bound; no kernel gained a check; the catalog's bounds (3,301) and overflow (6,050) call sites are unchanged. The report's product hint now names the factors in declaration order (n * dim <= length(m), wasdim * n); the one test that read it is updated.main(two interleaved runs a side, quiet, other CPU 0.1-0.7 cores), about 0.75 ns per term where it was 0.9-1.1. The unguarded kernel, whose C did not change, 0.018 on both.mix dump_crounds a side): +0.5% of the work (reductions; +0.3% withoutSatEx.Kernels), +0.8% of the time (-0.3% without). The ADR-0007 chain is at about +4.0% (-1.9% withoutSatEx.Kernels) of the work before step 1, under its ceiling.How it was checked
mix cion the M-series laptop: 2309 passed, 817 excluded. New tests intest/condition_facts_test.exs("a guard between two parameters"): the gather with both name orders drops the overflow check and keeps the gather's bounds check, the extremes of the dropped check (an i32 extreme with the offset at 0 and at the length: the sum fits, the access raises), the guard's raises, and the agreement properties of both kernels.test/product_facts_test.exs: the hint text's factor order.docs/guides/stability.mdallows. NoCHANGELOG.mdentry.test/stability/? No.