Skip to content

Commit 07a7a03

Browse files
committed
simd: surface the runtime-dispatch trampolines through ndarray::simd::*
The W1a consumer invariant is "all SIMD from ndarray::simd", but the simd_runtime trampolines (matmul_bf16_to_f32, matmul_f32, gemm_u8_i8, vnni_dot_u8_i8, matmul_i8_to_i32) were only reachable as ndarray::simd_runtime::* -- forcing consumers (the tesseract-rs recognizer's int8 GEMM among them) off the canonical polyfill import path. Re-export them under simd:: behind the runtime-dispatch feature. matmul_i8_to_i32 needs care: on x86_64+std the name already exists in simd:: (the hpc::amx_matmul re-export -- the IDENTICAL function the simd_runtime wrapper #[inline(always)]-aliases), so the trampoline re-export is gated not(target_arch = "x86_64") to make the import path arch-uniform without a name collision. Pure re-exports of the same tier ladders -- bit-identical by construction, no new pub fn in any simd_*.rs, so the W1a three-backend ceremony is not triggered. Verified: builds with and without runtime-dispatch; 233 simd lib tests green; clippy -D warnings + fmt clean; the tesseract-rs consumer flip reproduces its byte-parity E2E regression ("qLLiy,,") through the new path unchanged. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016b33swuXE23hKtqxsHu9p1
1 parent 5760284 commit 07a7a03

1 file changed

Lines changed: 18 additions & 0 deletions

File tree

src/simd.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,24 @@ pub use crate::hpc::heel_f64x8::cosine_f32_to_f64_simd;
614614
// `backend::gemm_bf16` (portable scalar / NEON / wasm-SIMD paths).
615615
#[cfg(all(feature = "std", target_arch = "x86_64"))]
616616
pub use crate::hpc::amx_matmul::{amx_available, matmul_i8_to_i32};
617+
// Runtime-dispatch trampolines (`simd_runtime`, feature = "runtime-dispatch")
618+
// surfaced through the canonical `ndarray::simd::*` namespace — the W1a
619+
// consumer invariant is "all SIMD from `ndarray::simd`", so consumers that
620+
// were importing `ndarray::simd_runtime::{matmul_*, gemm_u8_i8, ...}`
621+
// directly (e.g. the tesseract-rs recognizer's int8 GEMM) can now stay on
622+
// the one polyfill import path. These are thin `#[inline(always)]` aliases
623+
// of the SAME underlying tier ladders (`hpc::amx_matmul`, `simd_int_ops`),
624+
// so switching import paths is bit-identical by construction.
625+
#[cfg(feature = "runtime-dispatch")]
626+
pub use crate::simd_runtime::{gemm_u8_i8, matmul_bf16_to_f32, matmul_f32, vnni_dot_u8_i8};
627+
// `matmul_i8_to_i32` already has its canonical `simd::` name on
628+
// x86_64 + std (the `hpc::amx_matmul` re-export above — the identical
629+
// function `simd_runtime::matmul_i8_to_i32` wraps). Off x86_64 the name
630+
// only exists via the runtime-dispatch trampoline, re-exported here so the
631+
// import path is arch-uniform; the cfg keeps the two aliases from
632+
// colliding when both features hold on x86_64.
633+
#[cfg(all(feature = "runtime-dispatch", not(target_arch = "x86_64")))]
634+
pub use crate::simd_runtime::matmul_i8_to_i32;
617635
// Tile-dispatching sibling of the polyfill `bf16_tile_gemm_16x16` below:
618636
// AMX TDPBF16PS → AVX-512 VDPBF16PS → the same FMA polyfill kernel, selected
619637
// at runtime. Same W1a rationale as `matmul_i8_to_i32` — consumers reach the

0 commit comments

Comments
 (0)