use tract_data::internal::f16;
const CHUNK: usize = 256;
const SILU_CHUNK: usize = 1024;
#[target_feature(enable = "avx512f")]
unsafe fn cvt_f16_to_f32(src: &[f16], dst: &mut [f32]) {
use core::arch::x86_64::*;
let n = src.len();
debug_assert!(dst.len() >= n);
let chunks = n / 16;
unsafe {
for k in 0..chunks {
let m = _mm256_loadu_si256(src.as_ptr().add(k * 16) as *const __m256i);
let z = _mm512_cvtph_ps(m);
_mm512_storeu_ps(dst.as_mut_ptr().add(k * 16), z);
}
for k in (chunks * 16)..n {
*dst.get_unchecked_mut(k) = src.get_unchecked(k).to_f32();
}
}
}
#[target_feature(enable = "avx512f")]
unsafe fn cvt_f32_to_f16(src: &[f32], dst: &mut [f16]) {
use core::arch::x86_64::*;
let n = src.len();
debug_assert!(dst.len() >= n);
let chunks = n / 16;
unsafe {
for k in 0..chunks {
let z = _mm512_loadu_ps(src.as_ptr().add(k * 16));
let m = _mm512_cvtps_ph::<0>(z);
_mm256_storeu_si256(dst.as_mut_ptr().add(k * 16) as *mut __m256i, m);
}
for k in (chunks * 16)..n {
*dst.get_unchecked_mut(k) = f16::from_f32(*src.get_unchecked(k));
}
}
}
ew_impl_f16_via_f32!(
x86_64_avx512_hardswish_f16_64n,
64,
32,
CHUNK,
64,
cvt_f16_to_f32,
cvt_f32_to_f16,
super::act::x86_64_avx512_hardswish_f32_64n
);
#[cfg(test)]
pub mod test_x86_64_avx512_hardswish_f16_64n {
use super::*;
hardswish_frame_tests!(
is_x86_feature_detected!("avx512f"),
f16,
x86_64_avx512_hardswish_f16_64n
);
}
ew_impl_f16_via_f32!(
x86_64_avx512_leaky_relu_f16_64n,
64,
32,
CHUNK,
64,
cvt_f16_to_f32,
cvt_f32_to_f16,
super::act::x86_64_avx512_leaky_relu_f32_64n,
f16,
alpha => alpha.to_f32()
);
#[cfg(test)]
pub mod test_x86_64_avx512_leaky_relu_f16_64n {
use super::*;
leaky_relu_frame_tests!(
is_x86_feature_detected!("avx512f"),
f16,
x86_64_avx512_leaky_relu_f16_64n
);
}
ew_impl_f16_via_f32!(
x86_64_avx512_sigmoid_f16_16n,
16,
16,
CHUNK,
64,
cvt_f16_to_f32,
cvt_f32_to_f16,
super::avx512_sigmoid_f32
);
#[cfg(test)]
pub mod test_x86_64_avx512_sigmoid_f16_16n {
use super::*;
sigmoid_frame_tests!(is_x86_feature_detected!("avx512f"), f16, x86_64_avx512_sigmoid_f16_16n);
}
ew_impl_f16_via_f32!(
x86_64_avx512_tanh_f16_16n,
16,
16,
CHUNK,
64,
cvt_f16_to_f32,
cvt_f32_to_f16,
super::avx512_tanh_f32
);
#[cfg(test)]
pub mod test_x86_64_avx512_tanh_f16_16n {
use super::*;
tanh_frame_tests!(is_x86_feature_detected!("avx512f"), f16, x86_64_avx512_tanh_f16_16n);
}
ew_impl_f16_via_f32!(
x86_64_avx512_silu_f16_16n,
16,
16,
SILU_CHUNK,
64,
cvt_f16_to_f32,
cvt_f32_to_f16,
super::avx512_silu_f32
);
#[cfg(test)]
pub mod test_x86_64_avx512_silu_f16_16n {
use super::*;
silu_frame_tests!(is_x86_feature_detected!("avx512f"), f16, x86_64_avx512_silu_f16_16n);
}
ew_impl_f16_via_f32!(
x86_64_avx512_gelu_f16_16n,
16,
16,
CHUNK,
64,
cvt_f16_to_f32,
cvt_f32_to_f16,
super::act::x86_64_avx512_gelu_f32_16n
);
#[cfg(test)]
pub mod test_x86_64_avx512_gelu_f16_16n {
use super::*;
gelu_frame_tests!(is_x86_feature_detected!("avx512f"), f16, x86_64_avx512_gelu_f16_16n);
}