Repository navigation
Pilot: ndarray-simd leaky_relu kernel as additional x86_64 candidate - #3
Conversation
…candidate linalg had no element-wise kernel built on the ndarray fork's simd::F32x16 polyfill instead of hand intrinsics/asm, so there was no real measurement of that path against the existing hand-tuned AVX-512 leaky_relu kernel. Adds x86_64_ndarray_leaky_relu_f32_16n via the same routine_ew_rust! registration the other x86_64 activation kernels use, declared at X86_64Avx2 (the tier ndarray's F32x16 actually compiles to in a non-avx512f-target build), wires it into the existing leaky_relu_frame_tests! correctness harness, and adds it to the leaky_relu bench alongside the existing AVX-512 asm kernel and the generic scalar reference. The existing kernel's ISA level (avx512f) keeps it the selected default: nothing about kernel selection changes. The bench file itself had bit-rotted (Tensor::as_slice_mut no longer exists, an aarch64-only #[target_feature(enable = "fp16")] variant, and 16-byte tensor alignment too narrow for the AVX-512 kernels' vmovaps) and needed a minimal repair to build and run at all; fixed alongside adding the new kernel calls.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_61eff607-44cc-44c6-8703-71d8a9b36cf2) |
|
Correction to the benchmark in the PR description. It was run without any This box is Sapphire-Rapids-class ( With the correct build flags, the ndarray-simd kernel is essentially on par with the hand-tuned AVX-512 asm (very slightly ahead, within noise) — not 3.8x slower as the original PR description said. That number was a build-configuration artifact, not a fair result. I'll leave the PR description's numbers uncorrected in place (for the record) and treat this comment as the accurate result. Given this, the earlier "no cutover justified" verdict doesn't hold as strongly — the ndarray-backed kernel is a legitimate, competitive candidate on real target hardware. Still not proposing a cutover from this one pilot alone (one op, one shape, one machine) — but the evidence now points toward "worth expanding the pilot to more ops" rather than "the polyfill underperforms." Generated by Claude Code |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_fb9494e7-5637-4a52-94b1-e5d9a2fa1a47) |
Summary
Staged pilot for migrating tract-linalg's intrinsics/asm element-wise kernels onto the AdaWorldAPI
ndarrayfork'ssimd::F32x16polyfill (see #2). This PR touches exactly one op, additively.Op picked:
leaky_relu(f32). It was chosen overerf.rs(explicitly out of scope — hand-unrolled 4x zmm FMA chains, a bad first pilot) because its existing AVX-512 kernel (x86_64_avx512_leaky_relu_f32_64ninlinalg/src/x86_64/act.rs) is short, branch-free (a compare mask + blend), and has no GEMM/microkernel entanglement — a clean one-op comparison.What's here
x86_64_ndarray_leaky_relu_f32_16n, built onndarray::simd::F32x16(splat/from_slice/simd_gt/select/copy_to_slice) instead of the existing kernel's rawstd::arch::asm!AVX-512 body. Registered via the sameroutine_ew_rust!macro every neighboring x86_64 activation kernel uses, declaredisa(X86_64Avx2)— the tierndarray::simd::F32x16actually compiles to in a build without a globalavx512ftarget feature (tract doesn't set one).x86_64_avx512_leaky_relu_f32_64nkernel is untouched. Kernel selection is ISA-level-based (isa.rs), andX86_64Avx512foutranksX86_64Avx2, so the old kernel remains the winner on any AVX-512 machine — confirmed by running the dispatcher directly (see below).leaky_relu_frame_tests!macro (property + trivial cases against the generic scalar reference) the same way every other kernel in this family is — no new test harness.benches/leaky_relu.rs, following the existing criterion pattern in that file (which also needed a small pre-existing bit-rot fix — see below).ndarrayas an x86_64-only dependency oftract-linalg(it wasn't a dependency of this crate before).Benchmark: real numbers, run on this sandbox (x86_64, AVX-512F present)
linalg(auto-dispatch) matchinglinalg-avx512-asmexactly confirms the existing hand-tuned kernel is still the one selected by default — this PR changes nothing about that.The ndarray-polyfill kernel is ~3.8x slower than the hand-tuned AVX-512 asm here, and slower than even the naive scalar loop. Plausible reasons (not chased further — this is a pilot, not an optimization pass): this build has no global
avx512ftarget feature, sondarray::simd::F32x16compiles to its AVX2-composed-of-two-__m256fallback rather than a native__m512; the new kernel processes 16 lanes/iteration via unalignedfrom_slice/copy_to_slicewith no unrolling, vs. the existing kernel's 4x-unrolled 64-wide masked-store body.This is a staged pilot, not a migration
🍍
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_012wrzeZAdwGYTCKoxamwQht
🤖 Generated with Claude Code
Generated by Claude Code