Skip to content

Add the arm64 NEON implementation of the ScaleInvariantMatrixMatch kernels - #1602

Merged
Mysticial merged 4 commits into
mainfrom
kernels-simm-neon
Oct 17, 2026
Merged

Mysticial merged 4 commits into
mainfrom
kernels-simm-neon

Conversation

@Gin890

@Gin890 Gin890 commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #1601 (the unit tests for these kernels) — review/merge #1601 first, this one only contains the NEON port.

Adds Context_arm64_NEON (float32x4_t, VL = 4) implementing the shared SumATA2/SumError routines from Routines.h, with all four kernel entry points (compute_scale / compute_error, plain and weighted), dispatched for width >= 4 under OK_M1.

The partial-row loads differ from the x86 ISAs by design: instead of the PSHUFB/mask-load tricks, they are lane-insert loads (vld1q_lane_f32) into zeroed vectors:

  • prefix (unaligned row start): loads the 16-byte vector at the row start and zeroes the last align lanes. No back-read, so nothing is read before the row start.
  • tail (last partial row): inserts the length remaining floats into a zeroed vector. Nothing is read past the row end.

This means the kernel has no out-of-bounds reads in either direction, unlike the SSE4.1 path (whose PSHUFB tail load reads up to VL - 1 floats past the row end and relies on the caller's buffer having tail padding — see the TAIL_PAD comment in the test infrastructure from #1601).

Unit tests: the same TestInfra as #1601 (41 width/height pairs, plain + weighted, Default as source of truth, ULP/absolute tolerance) is registered for all sizes with width >= 4 → 64 tests on arm64. Verified locally: full suite passes (5,495 passed / 0 failed), including all 64 NEON tests.

Base automatically changed from kernels-simm-tests to main October 17, 2026 10:01
Add a TestInfra for the four kernel functions (compute_scale and
compute_error, plain and weighted). Each test generates a random
width x height matrix pair (and weight matrix for the weighted
variants), runs the Default path and the ISA path on identical
input, and compares the results.

The Default path is the source of truth, so each ISA registers the
same (width, height, use_weights) combinations against Default.
The sizes cover 1x1 up to 1000x1000, both divisible and
undivisible by the vector lengths (4, 8, 16), including the
short-row cases that exercise unaligned row prefixes and partial
vector tails. The SSE4.1 path back-reads up to 3 floats before a
row start, so the matrices are allocated with 16 floats of head
padding to keep those reads in-bounds.

Scales are not computed exactly by all paths (different addition
orders), so results are compared with a tolerance: pass if within
4096 ULPs, or within 1e-4 of the magnitude of the accumulated sum
(the absolute part covers near-zero results, where ULPs are far
smaller than the accumulated rounding of a multi-million-term sum).

The tests are registered per-ISA in each x86 Core file (SSE,
AVX2, AVX512), guarded by the same PA_AutoDispatch and
CPU_CAPABILITY_CURRENT checks the dispatchers use, so each
architecture only runs the tests for the ISAs it can execute.
Each ISA kernel requires a minimum row width (4 for SSE4.1, 8 for
AVX2, 16 for AVX512): below it, the partial-row loads span past the
row end and can read past the end of the allocation. The test
registration now skips sizes below the ISA's minimum width.

The test matrices also get 15 floats of tail padding after the last
row: the SSE4.1 partial-tail load (PSHUFB-based) reads a full 16-byte
word that extends up to VL - 1 floats past the row end, which would
otherwise run past the allocation on the last row.
…rnels

Context_arm64_NEON implements the same SumATA2/SumError routines with
float32x4_t vectors (VL = 4). The partial-row loads are lane-insert
loads into zeroed vectors, so they never read out of bounds in either
direction (no back-reads at the row start, no reads past the row end),
unlike the SSE4.1 PSHUFB-based loads.

Dispatched for width >= 4 when OK_M1 is enabled; the unit tests
(compare against the Default path) are registered for all test sizes
with width >= 4.
@Mysticial
Mysticial merged commit 43fe28c into main Oct 17, 2026
13 of 14 checks passed
@Mysticial
Mysticial deleted the kernels-simm-neon branch October 17, 2026 10:09
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.

2 participants