Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions linalg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,7 @@ harness = false
[[bench]]
name = "avxvnni_i32"
harness = false

[[bench]]
name = "tanh_f16_arm64"
harness = false
25 changes: 25 additions & 0 deletions linalg/benches/tanh_f16_arm64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// f16 tanh on aarch64 cores without FEAT_FP16: generic scalar vs f32 roundtrip.
use criterion::*;
use tract_data::prelude::*;
use tract_linalg::element_wise::ElementWiseKer;

fn bench(c: &mut Criterion) {
for n in [1024usize, 65536] {
let mut t = unsafe { Tensor::uninitialized_aligned::<f16>(&[n], 16).unwrap() };
let input = unsafe { t.as_slice_mut_unchecked::<f16>() };
for (i, x) in input.iter_mut().enumerate() {
*x = f16::from_f32((i as f32 / 10.0).sin() * 5.0);
}
let mut g = c.benchmark_group(format!("tanh_f16/{n}"));
g.throughput(Throughput::Elements(n as u64));
g.bench_function("generic", |b| b.iter(|| tract_linalg::generic::HTanh8::run(input, ())));
#[cfg(target_arch = "aarch64")]
g.bench_function("f32-roundtrip", |b| {
b.iter(|| tract_linalg::arm64::arm64simd_tanh_f16_4n::run(input, ()))
});
g.finish();
}
}

criterion_group!(benches, bench);
criterion_main!(benches);
5 changes: 4 additions & 1 deletion linalg/src/arm64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,9 +510,12 @@ pub fn plug(ops: &mut Ops) {
// TODO: Change this SiLU kernel once we have a native-FP16 one
ops.silu_f16 = Box::new(|| arm64simd_silu_f16_4n::ew());
} else {
log::info!("No native fp16 support; f32-roundtrip NEON sigmoid_f16 and silu_f16 activated");
log::info!(
"No native fp16 support; f32-roundtrip NEON sigmoid_f16, silu_f16 and tanh_f16 activated"
);
ops.sigmoid_f16 = Box::new(|| arm64simd_sigmoid_f16_4n::ew());
ops.silu_f16 = Box::new(|| arm64simd_silu_f16_4n::ew());
ops.tanh_f16 = Box::new(|| arm64simd_tanh_f16_4n::ew());
}
#[cfg(any(target_os = "macos", all(target_os = "ios", feature = "apple-amx-ios")))]
{
Expand Down
1 change: 1 addition & 0 deletions linalg/src/arm64/arm64simd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod unicast;

pub use act_f16::arm64simd_sigmoid_f16_4n;
pub use act_f16::arm64simd_silu_f16_4n;
pub use act_f16::arm64simd_tanh_f16_4n;
pub use by_scalar::*;
pub use gelu::arm64simd_gelu_f32_4n;
pub use gelu_fused::arm64simd_gelu_f32_4n_fused;
Expand Down
18 changes: 18 additions & 0 deletions linalg/src/arm64/arm64simd/act_f16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,21 @@ pub mod test_arm64simd_silu_f16_4n {
use super::*;
silu_frame_tests!(true, f16, arm64simd_silu_f16_4n);
}

// f32-roundtrip f16 tanh for arm64 cores without FEAT_FP16.
ew_impl_f16_via_f32!(
arm64simd_tanh_f16_4n,
4,
4,
CHUNK,
16,
cvt_f16_to_f32,
cvt_f32_to_f16,
super::arm64simd_tanh_f32_4n
);

#[cfg(test)]
pub mod test_arm64simd_tanh_f16_4n {
use super::*;
tanh_frame_tests!(true, f16, arm64simd_tanh_f16_4n);
}