use himada_core::HardwareDNA;
pub fn sin_batch_f64_scalar(a: &[f64], c: &mut [f64]) {
let len = a.len().min(c.len());
for i in 0..len {
c[i] = a[i].sin();
}
}
pub fn sin_batch_f64_supported(_: &HardwareDNA) -> bool { true }
#[cfg(target_arch = "aarch64")]
pub fn sin_batch_f64_neon(a: &[f64], c: &mut [f64]) {
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
while i + 2 <= len {
let va = std::arch::aarch64::vld1q_f64(a.as_ptr().add(i));
let mut arr: [f64; 2] = std::mem::transmute(va);
arr[0] = arr[0].sin();
arr[1] = arr[1].sin();
let vr: std::arch::aarch64::float64x2_t = std::mem::transmute(arr);
std::arch::aarch64::vst1q_f64(c.as_mut_ptr().add(i), vr);
i += 2;
}
}
for j in i..len {
c[j] = a[j].sin();
}
}
#[cfg(target_arch = "aarch64")]
pub fn sin_batch_f64_neon_supported(_: &HardwareDNA) -> bool { true }
#[cfg(not(target_arch = "aarch64"))]
pub fn sin_batch_f64_neon(_: &[f64], _: &mut [f64]) {}
#[cfg(not(target_arch = "aarch64"))]
pub fn sin_batch_f64_neon_supported(_: &HardwareDNA) -> bool { false }
#[cfg(target_arch = "x86_64")]
pub fn sin_batch_f64_sse(a: &[f64], c: &mut [f64]) {
use std::arch::x86_64::*;
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
if is_x86_feature_detected!("sse2") {
while i + 2 <= len {
let va = _mm_loadu_pd(a.as_ptr().add(i));
let mut arr: [f64; 2] = std::mem::transmute(va);
arr[0] = arr[0].sin();
arr[1] = arr[1].sin();
_mm_storeu_pd(c.as_mut_ptr().add(i), _mm_loadu_pd(arr.as_ptr()));
i += 2;
}
}
}
for j in i..len {
c[j] = a[j].sin();
}
}
#[cfg(target_arch = "x86_64")]
pub fn sin_batch_f64_sse_supported(dna: &HardwareDNA) -> bool {
dna.cpu.features.iter().any(|f| f == "SSE2")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn sin_batch_f64_sse(_: &[f64], _: &mut [f64]) {}
#[cfg(not(target_arch = "x86_64"))]
pub fn sin_batch_f64_sse_supported(_: &HardwareDNA) -> bool { false }
#[cfg(target_arch = "x86_64")]
pub fn sin_batch_f64_avx2(a: &[f64], c: &mut [f64]) {
use std::arch::x86_64::*;
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
if is_x86_feature_detected!("avx2") {
while i + 4 <= len {
let va = _mm256_loadu_pd(a.as_ptr().add(i));
let mut arr: [f64; 4] = std::mem::transmute(va);
arr[0] = arr[0].sin();
arr[1] = arr[1].sin();
arr[2] = arr[2].sin();
arr[3] = arr[3].sin();
_mm256_storeu_pd(c.as_mut_ptr().add(i), _mm256_loadu_pd(arr.as_ptr()));
i += 4;
}
}
}
for j in i..len {
c[j] = a[j].sin();
}
}
#[cfg(target_arch = "x86_64")]
pub fn sin_batch_f64_avx2_supported(dna: &HardwareDNA) -> bool {
dna.cpu.features.iter().any(|f| f == "AVX2")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn sin_batch_f64_avx2(_: &[f64], _: &mut [f64]) {}
#[cfg(not(target_arch = "x86_64"))]
pub fn sin_batch_f64_avx2_supported(_: &HardwareDNA) -> bool { false }
pub fn cos_batch_f64_scalar(a: &[f64], c: &mut [f64]) {
let len = a.len().min(c.len());
for i in 0..len {
c[i] = a[i].cos();
}
}
pub fn cos_batch_f64_supported(_: &HardwareDNA) -> bool { true }
#[cfg(target_arch = "aarch64")]
pub fn cos_batch_f64_neon(a: &[f64], c: &mut [f64]) {
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
while i + 2 <= len {
let va = std::arch::aarch64::vld1q_f64(a.as_ptr().add(i));
let mut arr: [f64; 2] = std::mem::transmute(va);
arr[0] = arr[0].cos();
arr[1] = arr[1].cos();
let vr: std::arch::aarch64::float64x2_t = std::mem::transmute(arr);
std::arch::aarch64::vst1q_f64(c.as_mut_ptr().add(i), vr);
i += 2;
}
}
for j in i..len {
c[j] = a[j].cos();
}
}
#[cfg(target_arch = "aarch64")]
pub fn cos_batch_f64_neon_supported(_: &HardwareDNA) -> bool { true }
#[cfg(not(target_arch = "aarch64"))]
pub fn cos_batch_f64_neon(_: &[f64], _: &mut [f64]) {}
#[cfg(not(target_arch = "aarch64"))]
pub fn cos_batch_f64_neon_supported(_: &HardwareDNA) -> bool { false }
#[cfg(target_arch = "x86_64")]
pub fn cos_batch_f64_sse(a: &[f64], c: &mut [f64]) {
use std::arch::x86_64::*;
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
if is_x86_feature_detected!("sse2") {
while i + 2 <= len {
let va = _mm_loadu_pd(a.as_ptr().add(i));
let mut arr: [f64; 2] = std::mem::transmute(va);
arr[0] = arr[0].cos();
arr[1] = arr[1].cos();
_mm_storeu_pd(c.as_mut_ptr().add(i), _mm_loadu_pd(arr.as_ptr()));
i += 2;
}
}
}
for j in i..len {
c[j] = a[j].cos();
}
}
#[cfg(target_arch = "x86_64")]
pub fn cos_batch_f64_sse_supported(dna: &HardwareDNA) -> bool {
dna.cpu.features.iter().any(|f| f == "SSE2")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn cos_batch_f64_sse(_: &[f64], _: &mut [f64]) {}
#[cfg(not(target_arch = "x86_64"))]
pub fn cos_batch_f64_sse_supported(_: &HardwareDNA) -> bool { false }
#[cfg(target_arch = "x86_64")]
pub fn cos_batch_f64_avx2(a: &[f64], c: &mut [f64]) {
use std::arch::x86_64::*;
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
if is_x86_feature_detected!("avx2") {
while i + 4 <= len {
let va = _mm256_loadu_pd(a.as_ptr().add(i));
let mut arr: [f64; 4] = std::mem::transmute(va);
arr[0] = arr[0].cos();
arr[1] = arr[1].cos();
arr[2] = arr[2].cos();
arr[3] = arr[3].cos();
_mm256_storeu_pd(c.as_mut_ptr().add(i), _mm256_loadu_pd(arr.as_ptr()));
i += 4;
}
}
}
for j in i..len {
c[j] = a[j].cos();
}
}
#[cfg(target_arch = "x86_64")]
pub fn cos_batch_f64_avx2_supported(dna: &HardwareDNA) -> bool {
dna.cpu.features.iter().any(|f| f == "AVX2")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn cos_batch_f64_avx2(_: &[f64], _: &mut [f64]) {}
#[cfg(not(target_arch = "x86_64"))]
pub fn cos_batch_f64_avx2_supported(_: &HardwareDNA) -> bool { false }
pub fn tan_batch_f64_scalar(a: &[f64], c: &mut [f64]) {
let len = a.len().min(c.len());
for i in 0..len {
c[i] = a[i].tan();
}
}
pub fn tan_batch_f64_supported(_: &HardwareDNA) -> bool { true }
#[cfg(target_arch = "aarch64")]
pub fn tan_batch_f64_neon(a: &[f64], c: &mut [f64]) {
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
while i + 2 <= len {
let va = std::arch::aarch64::vld1q_f64(a.as_ptr().add(i));
let mut arr: [f64; 2] = std::mem::transmute(va);
arr[0] = arr[0].tan();
arr[1] = arr[1].tan();
let vr: std::arch::aarch64::float64x2_t = std::mem::transmute(arr);
std::arch::aarch64::vst1q_f64(c.as_mut_ptr().add(i), vr);
i += 2;
}
}
for j in i..len {
c[j] = a[j].tan();
}
}
#[cfg(target_arch = "aarch64")]
pub fn tan_batch_f64_neon_supported(_: &HardwareDNA) -> bool { true }
#[cfg(not(target_arch = "aarch64"))]
pub fn tan_batch_f64_neon(_: &[f64], _: &mut [f64]) {}
#[cfg(not(target_arch = "aarch64"))]
pub fn tan_batch_f64_neon_supported(_: &HardwareDNA) -> bool { false }
#[cfg(target_arch = "x86_64")]
pub fn tan_batch_f64_sse(a: &[f64], c: &mut [f64]) {
use std::arch::x86_64::*;
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
if is_x86_feature_detected!("sse2") {
while i + 2 <= len {
let va = _mm_loadu_pd(a.as_ptr().add(i));
let mut arr: [f64; 2] = std::mem::transmute(va);
arr[0] = arr[0].tan();
arr[1] = arr[1].tan();
_mm_storeu_pd(c.as_mut_ptr().add(i), _mm_loadu_pd(arr.as_ptr()));
i += 2;
}
}
}
for j in i..len {
c[j] = a[j].tan();
}
}
#[cfg(target_arch = "x86_64")]
pub fn tan_batch_f64_sse_supported(dna: &HardwareDNA) -> bool {
dna.cpu.features.iter().any(|f| f == "SSE2")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn tan_batch_f64_sse(_: &[f64], _: &mut [f64]) {}
#[cfg(not(target_arch = "x86_64"))]
pub fn tan_batch_f64_sse_supported(_: &HardwareDNA) -> bool { false }
#[cfg(target_arch = "x86_64")]
pub fn tan_batch_f64_avx2(a: &[f64], c: &mut [f64]) {
use std::arch::x86_64::*;
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
if is_x86_feature_detected!("avx2") {
while i + 4 <= len {
let va = _mm256_loadu_pd(a.as_ptr().add(i));
let mut arr: [f64; 4] = std::mem::transmute(va);
arr[0] = arr[0].tan();
arr[1] = arr[1].tan();
arr[2] = arr[2].tan();
arr[3] = arr[3].tan();
_mm256_storeu_pd(c.as_mut_ptr().add(i), _mm256_loadu_pd(arr.as_ptr()));
i += 4;
}
}
}
for j in i..len {
c[j] = a[j].tan();
}
}
#[cfg(target_arch = "x86_64")]
pub fn tan_batch_f64_avx2_supported(dna: &HardwareDNA) -> bool {
dna.cpu.features.iter().any(|f| f == "AVX2")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn tan_batch_f64_avx2(_: &[f64], _: &mut [f64]) {}
#[cfg(not(target_arch = "x86_64"))]
pub fn tan_batch_f64_avx2_supported(_: &HardwareDNA) -> bool { false }
pub fn sin_batch_f32_scalar(a: &[f32], c: &mut [f32]) {
let len = a.len().min(c.len());
for i in 0..len {
c[i] = a[i].sin();
}
}
pub fn sin_batch_f32_supported(_: &HardwareDNA) -> bool { true }
#[cfg(target_arch = "aarch64")]
pub fn sin_batch_f32_neon(a: &[f32], c: &mut [f32]) {
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
while i + 4 <= len {
let va = std::arch::aarch64::vld1q_f32(a.as_ptr().add(i));
let mut arr: [f32; 4] = std::mem::transmute(va);
arr[0] = arr[0].sin();
arr[1] = arr[1].sin();
arr[2] = arr[2].sin();
arr[3] = arr[3].sin();
let vr: std::arch::aarch64::float32x4_t = std::mem::transmute(arr);
std::arch::aarch64::vst1q_f32(c.as_mut_ptr().add(i), vr);
i += 4;
}
}
for j in i..len {
c[j] = a[j].sin();
}
}
#[cfg(target_arch = "aarch64")]
pub fn sin_batch_f32_neon_supported(_: &HardwareDNA) -> bool { true }
#[cfg(not(target_arch = "aarch64"))]
pub fn sin_batch_f32_neon(_: &[f32], _: &mut [f32]) {}
#[cfg(not(target_arch = "aarch64"))]
pub fn sin_batch_f32_neon_supported(_: &HardwareDNA) -> bool { false }
#[cfg(target_arch = "x86_64")]
pub fn sin_batch_f32_sse(a: &[f32], c: &mut [f32]) {
use std::arch::x86_64::*;
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
if is_x86_feature_detected!("sse2") {
while i + 4 <= len {
let va = _mm_loadu_ps(a.as_ptr().add(i));
let mut arr: [f32; 4] = std::mem::transmute(va);
arr[0] = arr[0].sin();
arr[1] = arr[1].sin();
arr[2] = arr[2].sin();
arr[3] = arr[3].sin();
_mm_storeu_ps(c.as_mut_ptr().add(i), _mm_loadu_ps(arr.as_ptr()));
i += 4;
}
}
}
for j in i..len {
c[j] = a[j].sin();
}
}
#[cfg(target_arch = "x86_64")]
pub fn sin_batch_f32_sse_supported(dna: &HardwareDNA) -> bool {
dna.cpu.features.iter().any(|f| f == "SSE2")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn sin_batch_f32_sse(_: &[f32], _: &mut [f32]) {}
#[cfg(not(target_arch = "x86_64"))]
pub fn sin_batch_f32_sse_supported(_: &HardwareDNA) -> bool { false }
#[cfg(target_arch = "x86_64")]
pub fn sin_batch_f32_avx2(a: &[f32], c: &mut [f32]) {
use std::arch::x86_64::*;
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
if is_x86_feature_detected!("avx2") {
while i + 8 <= len {
let va = _mm256_loadu_ps(a.as_ptr().add(i));
let mut arr: [f32; 8] = std::mem::transmute(va);
arr[0] = arr[0].sin();
arr[1] = arr[1].sin();
arr[2] = arr[2].sin();
arr[3] = arr[3].sin();
arr[4] = arr[4].sin();
arr[5] = arr[5].sin();
arr[6] = arr[6].sin();
arr[7] = arr[7].sin();
_mm256_storeu_ps(c.as_mut_ptr().add(i), _mm256_loadu_ps(arr.as_ptr()));
i += 8;
}
}
}
for j in i..len {
c[j] = a[j].sin();
}
}
#[cfg(target_arch = "x86_64")]
pub fn sin_batch_f32_avx2_supported(dna: &HardwareDNA) -> bool {
dna.cpu.features.iter().any(|f| f == "AVX2")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn sin_batch_f32_avx2(_: &[f32], _: &mut [f32]) {}
#[cfg(not(target_arch = "x86_64"))]
pub fn sin_batch_f32_avx2_supported(_: &HardwareDNA) -> bool { false }
pub fn cos_batch_f32_scalar(a: &[f32], c: &mut [f32]) {
let len = a.len().min(c.len());
for i in 0..len {
c[i] = a[i].cos();
}
}
pub fn cos_batch_f32_supported(_: &HardwareDNA) -> bool { true }
#[cfg(target_arch = "aarch64")]
pub fn cos_batch_f32_neon(a: &[f32], c: &mut [f32]) {
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
while i + 4 <= len {
let va = std::arch::aarch64::vld1q_f32(a.as_ptr().add(i));
let mut arr: [f32; 4] = std::mem::transmute(va);
arr[0] = arr[0].cos();
arr[1] = arr[1].cos();
arr[2] = arr[2].cos();
arr[3] = arr[3].cos();
let vr: std::arch::aarch64::float32x4_t = std::mem::transmute(arr);
std::arch::aarch64::vst1q_f32(c.as_mut_ptr().add(i), vr);
i += 4;
}
}
for j in i..len {
c[j] = a[j].cos();
}
}
#[cfg(target_arch = "aarch64")]
pub fn cos_batch_f32_neon_supported(_: &HardwareDNA) -> bool { true }
#[cfg(not(target_arch = "aarch64"))]
pub fn cos_batch_f32_neon(_: &[f32], _: &mut [f32]) {}
#[cfg(not(target_arch = "aarch64"))]
pub fn cos_batch_f32_neon_supported(_: &HardwareDNA) -> bool { false }
#[cfg(target_arch = "x86_64")]
pub fn cos_batch_f32_sse(a: &[f32], c: &mut [f32]) {
use std::arch::x86_64::*;
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
if is_x86_feature_detected!("sse2") {
while i + 4 <= len {
let va = _mm_loadu_ps(a.as_ptr().add(i));
let mut arr: [f32; 4] = std::mem::transmute(va);
arr[0] = arr[0].cos();
arr[1] = arr[1].cos();
arr[2] = arr[2].cos();
arr[3] = arr[3].cos();
_mm_storeu_ps(c.as_mut_ptr().add(i), _mm_loadu_ps(arr.as_ptr()));
i += 4;
}
}
}
for j in i..len {
c[j] = a[j].cos();
}
}
#[cfg(target_arch = "x86_64")]
pub fn cos_batch_f32_sse_supported(dna: &HardwareDNA) -> bool {
dna.cpu.features.iter().any(|f| f == "SSE2")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn cos_batch_f32_sse(_: &[f32], _: &mut [f32]) {}
#[cfg(not(target_arch = "x86_64"))]
pub fn cos_batch_f32_sse_supported(_: &HardwareDNA) -> bool { false }
#[cfg(target_arch = "x86_64")]
pub fn cos_batch_f32_avx2(a: &[f32], c: &mut [f32]) {
use std::arch::x86_64::*;
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
if is_x86_feature_detected!("avx2") {
while i + 8 <= len {
let va = _mm256_loadu_ps(a.as_ptr().add(i));
let mut arr: [f32; 8] = std::mem::transmute(va);
arr[0] = arr[0].cos();
arr[1] = arr[1].cos();
arr[2] = arr[2].cos();
arr[3] = arr[3].cos();
arr[4] = arr[4].cos();
arr[5] = arr[5].cos();
arr[6] = arr[6].cos();
arr[7] = arr[7].cos();
_mm256_storeu_ps(c.as_mut_ptr().add(i), _mm256_loadu_ps(arr.as_ptr()));
i += 8;
}
}
}
for j in i..len {
c[j] = a[j].cos();
}
}
#[cfg(target_arch = "x86_64")]
pub fn cos_batch_f32_avx2_supported(dna: &HardwareDNA) -> bool {
dna.cpu.features.iter().any(|f| f == "AVX2")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn cos_batch_f32_avx2(_: &[f32], _: &mut [f32]) {}
#[cfg(not(target_arch = "x86_64"))]
pub fn cos_batch_f32_avx2_supported(_: &HardwareDNA) -> bool { false }
pub fn tan_batch_f32_scalar(a: &[f32], c: &mut [f32]) {
let len = a.len().min(c.len());
for i in 0..len {
c[i] = a[i].tan();
}
}
pub fn tan_batch_f32_supported(_: &HardwareDNA) -> bool { true }
#[cfg(target_arch = "aarch64")]
pub fn tan_batch_f32_neon(a: &[f32], c: &mut [f32]) {
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
while i + 4 <= len {
let va = std::arch::aarch64::vld1q_f32(a.as_ptr().add(i));
let mut arr: [f32; 4] = std::mem::transmute(va);
arr[0] = arr[0].tan();
arr[1] = arr[1].tan();
arr[2] = arr[2].tan();
arr[3] = arr[3].tan();
let vr: std::arch::aarch64::float32x4_t = std::mem::transmute(arr);
std::arch::aarch64::vst1q_f32(c.as_mut_ptr().add(i), vr);
i += 4;
}
}
for j in i..len {
c[j] = a[j].tan();
}
}
#[cfg(target_arch = "aarch64")]
pub fn tan_batch_f32_neon_supported(_: &HardwareDNA) -> bool { true }
#[cfg(not(target_arch = "aarch64"))]
pub fn tan_batch_f32_neon(_: &[f32], _: &mut [f32]) {}
#[cfg(not(target_arch = "aarch64"))]
pub fn tan_batch_f32_neon_supported(_: &HardwareDNA) -> bool { false }
#[cfg(target_arch = "x86_64")]
pub fn tan_batch_f32_sse(a: &[f32], c: &mut [f32]) {
use std::arch::x86_64::*;
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
if is_x86_feature_detected!("sse2") {
while i + 4 <= len {
let va = _mm_loadu_ps(a.as_ptr().add(i));
let mut arr: [f32; 4] = std::mem::transmute(va);
arr[0] = arr[0].tan();
arr[1] = arr[1].tan();
arr[2] = arr[2].tan();
arr[3] = arr[3].tan();
_mm_storeu_ps(c.as_mut_ptr().add(i), _mm_loadu_ps(arr.as_ptr()));
i += 4;
}
}
}
for j in i..len {
c[j] = a[j].tan();
}
}
#[cfg(target_arch = "x86_64")]
pub fn tan_batch_f32_sse_supported(dna: &HardwareDNA) -> bool {
dna.cpu.features.iter().any(|f| f == "SSE2")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn tan_batch_f32_sse(_: &[f32], _: &mut [f32]) {}
#[cfg(not(target_arch = "x86_64"))]
pub fn tan_batch_f32_sse_supported(_: &HardwareDNA) -> bool { false }
#[cfg(target_arch = "x86_64")]
pub fn tan_batch_f32_avx2(a: &[f32], c: &mut [f32]) {
use std::arch::x86_64::*;
let len = a.len().min(c.len());
let mut i = 0;
unsafe {
if is_x86_feature_detected!("avx2") {
while i + 8 <= len {
let va = _mm256_loadu_ps(a.as_ptr().add(i));
let mut arr: [f32; 8] = std::mem::transmute(va);
arr[0] = arr[0].tan();
arr[1] = arr[1].tan();
arr[2] = arr[2].tan();
arr[3] = arr[3].tan();
arr[4] = arr[4].tan();
arr[5] = arr[5].tan();
arr[6] = arr[6].tan();
arr[7] = arr[7].tan();
_mm256_storeu_ps(c.as_mut_ptr().add(i), _mm256_loadu_ps(arr.as_ptr()));
i += 8;
}
}
}
for j in i..len {
c[j] = a[j].tan();
}
}
#[cfg(target_arch = "x86_64")]
pub fn tan_batch_f32_avx2_supported(dna: &HardwareDNA) -> bool {
dna.cpu.features.iter().any(|f| f == "AVX2")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn tan_batch_f32_avx2(_: &[f32], _: &mut [f32]) {}
#[cfg(not(target_arch = "x86_64"))]
pub fn tan_batch_f32_avx2_supported(_: &HardwareDNA) -> bool { false }