Skip to content

Reorganize lagoon test suite by operation category#35

Merged
sigilante merged 5 commits into
mainfrom
sigilante/test-reorg
May 30, 2026
Merged

Reorganize lagoon test suite by operation category#35
sigilante merged 5 commits into
mainfrom
sigilante/test-reorg

Conversation

@sigilante
Copy link
Copy Markdown
Collaborator

Summary

The suite was split by arity (single-args / double-args-elementwise) plus array-utils — an arbitrary scheme that had aged badly: double-args-elementwise was 5,617 lines / 618 arms mixing arithmetic with comparisons, and its name no longer described its contents (it had picked up the sub/mod/mods regression tests too).

Regroup the 959 moved arms by what they actually test:

file arms covers
lagoon-arithmetic 330 add sub mul div mod (+ scalar / regression)
lagoon-compare-reduce 378 gth gte lth lte equ neq, min max, argmin argmax, any all, cumsum prod
lagoon-builders 190 eye zeros ones iota magic range linspace
lagoon-rounding 32 rounding-mode behavior (cumsum/linspace per mode)
lagoon-linalg 15 dot mmul (trace/diag)
lagoon-unary 2 abs, el-wise-op
lagoon-indexing 12 get/set item/row, structural ops

lagoon-fails (5) and lagoon-unsigned (18) are unchanged — validation and uint-kind smoke coverage stay coherent as-is. Total arm count conserved exactly: 982 before and after.

How

Pure mechanical move: arm bodies are byte-identical, every new file gets the same canonical preamble (the is-equal/is-close helpers + ^| |_ [atol rtol], which all three sources already shared). Done with a script that asserts arm-count conservation and errors on any unrouted arm. One category (indexing) was inserted and run on a live ship (~nec) to confirm the new file structure compiles and passes.

Scope

This is the file-reorg pass only. The larger win — de-duplicating the hand-written cartesian-product arms (op × bloq × shape × kind) into a table-driven harness — is a separate follow-up, now much easier to do per-category.

Note

Touches the same test files as #34 (which adds a 1-D any/all test to the old array-utils). Whichever lands first, I'll rebase the other — the 1-D test belongs in lagoon-compare-reduce under this layout.

🤖 Generated with Claude Code

Regroup the suite from arity-based (single-args / double-args-elementwise
+ array-utils) to operation-category files: arithmetic, compare-reduce,
builders, rounding, linalg, unary, indexing. lagoon-fails and
lagoon-unsigned are unchanged.

Pure mechanical move: arm bodies are byte-identical and every new file
gets the same canonical preamble (the is-equal/is-close helpers and
^| |_ [atol rtol] that all three sources already shared). Done with a
script that asserts arm-count conservation and errors on any unrouted
arm; one category (indexing) was built and run on a live ship to confirm
the new structure compiles. Arm count conserved exactly (983 before and
after, including the test-any-all-1d added by #34).

File-reorg pass only; de-duplicating the cartesian-product arms is a
follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sigilante sigilante force-pushed the sigilante/test-reorg branch from e8458a4 to c17dbaf Compare May 30, 2026 16:37
sigilante and others added 4 commits May 30, 2026 11:48
The arithmetic suite was 330 hand-written arms: each of add/sub/mul/div/
mod spelled out for 9 shapes x 8 (bloq,kind) combos, almost all asserting
op(ones,ones) == constant. Replace with two iterators (each-real over
precisions x representative shapes, each-uint over uint bloqs x shapes)
plus a small per-precision value table, and one arm per op built on
`fill`. 330 arms / 3338 lines -> 13 arms / ~160 lines.

Inputs are now built with `fill` instead of inline per-bloq float
literals, and a `test-sub-asym` row (fives - threes = twos) is included
so the asymmetric case is always covered -- exactly the gap that let the
sub return-buffer bug hide behind symmetric ones-minus-ones data.

Validated on a live ship: the harness builds and runs; add/mul/div/mod
(real and uint) pass, and test-sub-asym correctly fails against the old
sub jet (which computes y-x), confirming the table detects what the
symmetric tests could not.

Continuation of the test reorg; same pattern can fold the other
categories next.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The compare-reduce suite was 379 hand-written arms. Replace with the same
iterator approach as arithmetic plus a reduction iterator (each-vec, one
distinct-valued vector per precision):

- Comparisons (gth/gte/lth/lte, real + uint) become one arm per op per
  branch -- both the true- and false-producing cases across precisions
  and shapes. The old suite tested only the symmetric ones-vs-ones case,
  so it exercised just one branch per op; this now covers both.
- Reductions (min/max/cumsum/argmin/argmax) read the reduced scalar via
  its ravel head, independent of min/max's output shape, and argmin/
  argmax assert the forward (ravel) index.
- any/all kept as before.

379 arms / 3731 lines -> ~19 arms / ~190 lines.

Validated on a live ship: builds and runs; comparisons, min/max/cumsum,
and argmin pass, and test-argmax correctly fails against the old
reversed-index argmax jet -- demonstrating the harness detects the index
bug the symmetric-only tests could not.

Multi-assertion inside an iterator gate would not compile here, so each
assertion is its own arm (still ~20x fewer than the hand-written suite).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The builders suite was 190 hand-written arms (eye/zeros/ones/range/
linspace across precisions and shapes). Replace with the shared iterator
approach: zeros/ones cross-checked against `fill` over precisions x
shapes, and eye/range/linspace checked against small explicitly-built
canons over precisions.

190 arms / 1748 lines -> 9 arms / ~115 lines. Validated on a live ship:
all pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The 32 rounding arms (cumsum of an 11-point linspace built under each
rounding mode, compared to a mode-specific reference) shared identical
boilerplate differing only in [precision, direction, mode, canon].
Collapse to one 32-row table plus a single iterator arm.

32 arms / 283 lines -> 1 arm + table / ~70 lines. Validated on a live
ship: passes. The reference values are unchanged from the originals.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sigilante sigilante merged commit 2a671a0 into main May 30, 2026
@sigilante sigilante deleted the sigilante/test-reorg branch May 30, 2026 17:17
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