Skip to content

tanh: give aarch64 cores without FEAT_FP16 an f32-roundtrip f16 kernel - #2584

Open
czoli1976 wants to merge 1 commit into
sonos:mainfrom
czoli1976:perf/sigmoid-tanh-f16-lut
Open

tanh: give aarch64 cores without FEAT_FP16 an f32-roundtrip f16 kernel#2584
czoli1976 wants to merge 1 commit into
sonos:mainfrom
czoli1976:perf/sigmoid-tanh-f16-lut

Conversation

@czoli1976

Copy link
Copy Markdown
Contributor

sigmoid_f16 and silu_f16 both fall back to NEON kernels that widen into an f32 scratch when FEAT_FP16 is missing (arm64simd_sigmoid_f16_4n, arm64simd_silu_f16_4n). tanh_f16 had no such kernel, so that branch left it on generic::HTanh8 — a scalar loop. This adds the matching roundtrip kernel and registers it there.

Twelve lines of wiring: the kernel is one ew_impl_f16_via_f32! over the existing arm64simd_tanh_f32_4n, exactly as the sigmoid and silu ones are.

Numbers

elements generic scalar f32 roundtrip
1024 838 Melem/s 1.723 Gelem/s 2.06x
65536 835 Melem/s 1.755 Gelem/s 2.10x

Both arms in one process. Cores with FEAT_FP16 are untouched — they keep arm64fp16_tanh_f16_8n, which at 7.9 Gelem/s is far ahead of either of these.

Accuracy moves toward the reference rather than away: the roundtrip evaluates the f32 Padé and rounds once at the end, where HTanh8 evaluates a lower-degree Padé in f16 throughout. Same change of character the sigmoid fallback already made.

How I got here

I set out to put a 2^16 lookup table behind sigmoid_f16 and tanh_f16, as #2568/#2579/#2583 do for gelu, erf and silu. Measuring first killed it: the table tops out at ~3.9 Gelem/s for any f16 unary — it is a scalar gather, bound by load issue rather than by the cost of the function — while the native FEAT_FP16 kernels run at 7.33 (sigmoid) and 7.90 (tanh) Gelem/s. A table would have been a 2x regression on every core that has FEAT_FP16.

What the same measurements did show is that the non-FEAT_FP16 branch was leaving 2x on the table for tanh, which is what this PR is.

Tests

tract-linalg 4421, tract-core 270, test-f16 2378 — green. cargo fmt --all and cargo clippy clean.

🍍

sigmoid_f16 and silu_f16 fall back to NEON kernels that widen into an f32
scratch when FEAT_FP16 is missing, but tanh_f16 had no such kernel and dropped
to the generic scalar one instead. Add the matching roundtrip kernel and
register it on that branch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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