From 07a5e665bc60f6e0b80b612ce4182cdf428d1f3f Mon Sep 17 00:00:00 2001 From: Jeroen Van Der Donckt Date: Sat, 11 Feb 2023 13:54:08 +0100 Subject: [PATCH] :recycle: further decoupling of traits --- src/simd/config.rs | 12 +++++ src/simd/generic.rs | 76 +++++++++++++++++++++----------- src/simd/mod.rs | 4 +- src/simd/simd_f16_ignore_nans.rs | 35 +++++---------- src/simd/simd_f32_ignore_nans.rs | 35 +++++---------- src/simd/simd_f64_ignore_nans.rs | 35 +++++---------- src/simd/simd_i16.rs | 38 ++++++---------- src/simd/simd_i32.rs | 38 ++++++---------- src/simd/simd_i64.rs | 38 ++++++---------- src/simd/simd_i8.rs | 38 ++++++---------- src/simd/simd_u16.rs | 39 ++++++---------- src/simd/simd_u32.rs | 38 ++++++---------- src/simd/simd_u64.rs | 38 ++++++---------- src/simd/simd_u8.rs | 38 ++++++---------- 14 files changed, 198 insertions(+), 304 deletions(-) diff --git a/src/simd/config.rs b/src/simd/config.rs index 9b1d50b..ee2a7bb 100644 --- a/src/simd/config.rs +++ b/src/simd/config.rs @@ -16,6 +16,9 @@ pub trait SIMDInstructionSet { // ----------------------------- x86_64 / x86 ----------------------------- +// SIMDIstructionSet only implented for SSE +// -> necessary to auto implement SIMDCore & SIMDArgMinMax in generic.rs + pub struct SSE; pub struct SSEFloatIgnoreNaN; pub struct SSEFloatReturnNaN; @@ -24,6 +27,9 @@ impl SIMDInstructionSet for SSE { const REGISTER_SIZE: usize = 128; } +// SIMDInstructionSet only implented for AVX2 +// -> necessary to auto implement SIMDCore & SIMDArgMinMax in generic.rs + pub struct AVX2; // for f32 and f64 AVX is enough pub struct AVX2FloatIgnoreNaN; pub struct AVX2FloatReturnNaN; @@ -32,6 +38,9 @@ impl SIMDInstructionSet for AVX2 { const REGISTER_SIZE: usize = 256; } +// SIMDInstructionSet only implented for AVX512 +// -> necessary to auto implement SIMDCore & SIMDArgMinMax in generic.rs + pub struct AVX512; pub struct AVX512FloatIgnoreNaN; pub struct AVX512FloatReturnNaN; @@ -42,6 +51,9 @@ impl SIMDInstructionSet for AVX512 { // ----------------------------- aarch64 / arm ----------------------------- +// SIMDInstructionSet only implented for NEON +// -> necessary to auto implement SIMDCore & SIMDArgMinMax in generic.rs + pub struct NEON; pub struct NEONFloatIgnoreNaN; pub struct NEONFloatReturnNaN; diff --git a/src/simd/generic.rs b/src/simd/generic.rs index 207f7f5..4a77c1d 100644 --- a/src/simd/generic.rs +++ b/src/simd/generic.rs @@ -1,5 +1,6 @@ -use num_traits::{AsPrimitive, Float}; +use num_traits::{AsPrimitive, Float, PrimInt}; +use super::config::SIMDInstructionSet; use super::task::*; use crate::scalar::{ScalarArgMinMax, SCALAR}; @@ -12,6 +13,9 @@ where SIMDVecDtype: Copy, SIMDMaskDtype: Copy, { + /// The target feature for the SIMD operations + const TARGET_FEATURE: &'static str; + /// Integers > this value **cannot** be accurately represented in SIMDVecDtype const MAX_INDEX: usize; /// Initial index value for the SIMD vector @@ -215,33 +219,33 @@ where } } -// Implement SIMDCore where SIMDOps is implemented +// Implement SIMDCore where SIMDOps is implemented for signed and unsigned integers (PrimInt) impl SIMDCore for T where - ScalarDType: Copy + PartialOrd + AsPrimitive, + ScalarDType: PrimInt + AsPrimitive, SIMDVecDtype: Copy, SIMDMaskDtype: Copy, - T: SIMDOps, + T: SIMDOps + SIMDInstructionSet, { - // Use the default implementation + // Use the implementation } // --------------- Float Ignore NaNs -/// SIMD operations for setting a SIMD vector to a scalar value. +/// SIMD operations for setting a SIMD vector to a scalar value (only required for floats) pub trait SIMDSetOps where - ScalarDType: Copy, + ScalarDType: Float, { unsafe fn _mm_set1(a: ScalarDType) -> SIMDVecDtype; } -/// SIMDCore trait that ignore NaNs (for float types) +/// SIMDCore trait that ignore NaNs (for floats) pub trait SIMDCoreFloatIgnoreNaN: SIMDOps + SIMDSetOps where - ScalarDType: Copy + PartialOrd + AsPrimitive + Float, + ScalarDType: Float + AsPrimitive, SIMDVecDtype: Copy, SIMDMaskDtype: Copy, { @@ -346,22 +350,22 @@ where } } -// Implement SIMDCoreFloatIgnoreNaNs where SIMDOps + SIMDSetOps is implemented +// Implement SIMDCoreFloatIgnoreNaNs where SIMDOps + SIMDSetOps is implemented for floats (Float) impl SIMDCoreFloatIgnoreNaN for T where - SCALARDType: Copy + PartialOrd + AsPrimitive + Float, + SCALARDType: Float + AsPrimitive, SIMDVecDtype: Copy, SIMDMaskDtype: Copy, T: SIMDOps + SIMDSetOps, { - // Use the default implementation + // Use the implementation } // --------------- Float Return NaNs -// IDEA: make SIMDOps extend this trait & provide empty default implementations +// IDEA: make SIMDOps extend this trait & provide empty implementations // pub trait SIMDOrdTransformOps // where @@ -385,6 +389,10 @@ where // ------------------------------- ArgMinMax SIMD TRAIT ------------------------------ +// --------------- Default + +/// The default SIMDArgMinMax trait (can be implemented for signed and unsigned integers + floats) +/// TODO: decide if we create a separate trait for floats when returning NaNs #[allow(clippy::missing_safety_doc)] // TODO: add safety docs? pub trait SIMDArgMinMax: SIMDCore @@ -394,12 +402,8 @@ where SIMDMaskDtype: Copy, { /// Returns the index of the minimum and maximum value in the array - unsafe fn argminmax(data: &[ScalarDType]) -> (usize, usize); - - // Is necessary to have a separate function for this so we can call it in the - // argminmax function when we add the target feature to the function. - #[inline(always)] - unsafe fn _argminmax(data: &[ScalarDType]) -> (usize, usize) + #[target_feature(enable = Self::TARGET_FEATURE)] + unsafe fn argminmax(data: &[ScalarDType]) -> (usize, usize) where SCALAR: ScalarArgMinMax, { @@ -407,6 +411,18 @@ where } } +// Implement SIMDArgMinMax where SIMDCore is implemented for signed and unsigned integers (PrimInt) +impl + SIMDArgMinMax for T +where + SCALARDType: PrimInt + AsPrimitive, + SIMDVecDtype: Copy, + SIMDMaskDtype: Copy, + T: SIMDCore + SIMDInstructionSet, +{ + // Use the implementation +} + #[allow(clippy::missing_safety_doc)] // TODO: add safety docs? pub trait SIMDArgMinMaxFloatIgnoreNaN< ScalarDType, @@ -414,17 +430,13 @@ pub trait SIMDArgMinMaxFloatIgnoreNaN< SIMDMaskDtype, const LANE_SIZE: usize, >: SIMDCoreFloatIgnoreNaN where - ScalarDType: Copy + PartialOrd + AsPrimitive + Float, + ScalarDType: Float + AsPrimitive, SIMDVecDtype: Copy, SIMDMaskDtype: Copy, { /// Returns the index of the minimum and maximum value in the array - unsafe fn argminmax(data: &[ScalarDType]) -> (usize, usize); - - // Is necessary to have a separate function for this so we can call it in the - // argminmax function when we add the target feature to the function. - #[inline(always)] - unsafe fn _argminmax(data: &[ScalarDType]) -> (usize, usize) + #[target_feature(enable = Self::TARGET_FEATURE)] + unsafe fn argminmax(data: &[ScalarDType]) -> (usize, usize) where SCALAR: ScalarArgMinMax, { @@ -432,6 +444,18 @@ pub trait SIMDArgMinMaxFloatIgnoreNaN< } } +// Implement SIMDArgMinMaxFloatIgnoreNaN where SIMDCoreFloatIgnoreNaN is implemented for floats (Float) +impl + SIMDArgMinMaxFloatIgnoreNaN for T +where + SCALARDType: Float + AsPrimitive, + SIMDVecDtype: Copy, + SIMDMaskDtype: Copy, + T: SIMDCoreFloatIgnoreNaN, +{ + // Use the implementation +} + // TODO: update this to use the new SIMD trait #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] macro_rules! unimplement_simd { diff --git a/src/simd/mod.rs b/src/simd/mod.rs index 62dd4a9..0d9eb70 100644 --- a/src/simd/mod.rs +++ b/src/simd/mod.rs @@ -9,9 +9,9 @@ pub use generic::*; mod simd_f16_ignore_nans; // mod simd_f16_return_nans; mod simd_f32_ignore_nans; -mod simd_f32_return_nans; +// mod simd_f32_return_nans; mod simd_f64_ignore_nans; -mod simd_f64_return_nans; +// mod simd_f64_return_nans; // SIGNED INT mod simd_i16; mod simd_i32; diff --git a/src/simd/simd_f16_ignore_nans.rs b/src/simd/simd_f16_ignore_nans.rs index 158d1a1..1fd3539 100644 --- a/src/simd/simd_f16_ignore_nans.rs +++ b/src/simd/simd_f16_ignore_nans.rs @@ -1,7 +1,7 @@ #[cfg(feature = "half")] use super::config::SIMDInstructionSet; #[cfg(feature = "half")] -use super::generic::{SIMDArgMinMaxFloatIgnoreNaN, SIMDOps, SIMDSetOps}; +use super::generic::{SIMDOps, SIMDSetOps}; #[cfg(feature = "half")] #[cfg(target_arch = "aarch64")] @@ -61,6 +61,8 @@ mod avx2 { } impl SIMDOps for AVX2FloatIgnoreNaN { + const TARGET_FEATURE: &'static str = "avx2"; + const INITIAL_INDEX: __m256i = unsafe { std::mem::transmute([ 0i16, 1i16, 2i16, 3i16, 4i16, 5i16, 6i16, 7i16, 8i16, 9i16, 10i16, 11i16, 12i16, @@ -172,20 +174,13 @@ mod avx2 { } } - impl SIMDArgMinMaxFloatIgnoreNaN for AVX2FloatIgnoreNaN { - #[target_feature(enable = "avx2")] - unsafe fn argminmax(data: &[f16]) -> (usize, usize) { - Self::_argminmax(data) - } - } - //----- TESTS ----- #[cfg(test)] mod tests { use super::AVX2FloatIgnoreNaN as AVX2; - use super::SIMDArgMinMaxFloatIgnoreNaN; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMaxFloatIgnoreNaN; use half::f16; @@ -296,6 +291,8 @@ mod sse { } impl SIMDOps for SSEFloatIgnoreNaN { + const TARGET_FEATURE: &'static str = "sse4.1"; + const INITIAL_INDEX: __m128i = unsafe { std::mem::transmute([0i16, 1i16, 2i16, 3i16, 4i16, 5i16, 6i16, 7i16]) }; const INDEX_INCREMENT: __m128i = @@ -399,20 +396,13 @@ mod sse { } } - impl SIMDArgMinMaxFloatIgnoreNaN for SSEFloatIgnoreNaN { - #[target_feature(enable = "sse4.1")] - unsafe fn argminmax(data: &[f16]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ----------------------------------------- TESTS ----------------------------------------- #[cfg(test)] mod tests { - use super::SIMDArgMinMaxFloatIgnoreNaN; use super::SSEFloatIgnoreNaN as SSE; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMaxFloatIgnoreNaN; use half::f16; @@ -507,6 +497,8 @@ mod avx512 { } impl SIMDOps for AVX512FloatIgnoreNaN { + const TARGET_FEATURE: &'static str = "avx512bw"; + const INITIAL_INDEX: __m512i = unsafe { std::mem::transmute([ 0i16, 1i16, 2i16, 3i16, 4i16, 5i16, 6i16, 7i16, 8i16, 9i16, 10i16, 11i16, 12i16, @@ -623,20 +615,13 @@ mod avx512 { } } - impl SIMDArgMinMaxFloatIgnoreNaN for AVX512FloatIgnoreNaN { - #[target_feature(enable = "avx512bw")] - unsafe fn argminmax(data: &[f16]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ----------------------------------------- TESTS ----------------------------------------- #[cfg(test)] mod tests { use super::AVX512FloatIgnoreNaN as AVX512; - use super::SIMDArgMinMaxFloatIgnoreNaN; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMaxFloatIgnoreNaN; use half::f16; diff --git a/src/simd/simd_f32_ignore_nans.rs b/src/simd/simd_f32_ignore_nans.rs index 670500c..e4277b1 100644 --- a/src/simd/simd_f32_ignore_nans.rs +++ b/src/simd/simd_f32_ignore_nans.rs @@ -1,5 +1,5 @@ use super::config::SIMDInstructionSet; -use super::generic::{SIMDArgMinMaxFloatIgnoreNaN, SIMDOps, SIMDSetOps}; +use super::generic::{SIMDOps, SIMDSetOps}; #[cfg(target_arch = "aarch64")] use std::arch::aarch64::*; #[cfg(target_arch = "arm")] @@ -22,6 +22,8 @@ mod avx2 { const LANE_SIZE: usize = AVX2::LANE_SIZE_32; impl SIMDOps for AVX2FloatIgnoreNaN { + const TARGET_FEATURE: &'static str = "avx"; + const INITIAL_INDEX: __m256 = unsafe { std::mem::transmute([ 0.0f32, 1.0f32, 2.0f32, 3.0f32, 4.0f32, 5.0f32, 6.0f32, 7.0f32, @@ -69,20 +71,13 @@ mod avx2 { } } - impl SIMDArgMinMaxFloatIgnoreNaN for AVX2FloatIgnoreNaN { - #[target_feature(enable = "avx")] - unsafe fn argminmax(data: &[f32]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { use super::AVX2FloatIgnoreNaN as AVX2; - use super::SIMDArgMinMaxFloatIgnoreNaN; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMaxFloatIgnoreNaN; extern crate dev_utils; use dev_utils::utils; @@ -175,6 +170,8 @@ mod sse { const LANE_SIZE: usize = SSE::LANE_SIZE_32; impl SIMDOps for SSEFloatIgnoreNaN { + const TARGET_FEATURE: &'static str = "sse4.1"; + const INITIAL_INDEX: __m128 = unsafe { std::mem::transmute([0.0f32, 1.0f32, 2.0f32, 3.0f32]) }; const INDEX_INCREMENT: __m128 = @@ -219,20 +216,13 @@ mod sse { } } - impl SIMDArgMinMaxFloatIgnoreNaN for SSEFloatIgnoreNaN { - #[target_feature(enable = "sse4.1")] - unsafe fn argminmax(data: &[f32]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::SIMDArgMinMaxFloatIgnoreNaN; use super::SSEFloatIgnoreNaN as SSE; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMaxFloatIgnoreNaN; extern crate dev_utils; use dev_utils::utils; @@ -309,6 +299,8 @@ mod avx512 { const LANE_SIZE: usize = AVX512::LANE_SIZE_32; impl SIMDOps for AVX512FloatIgnoreNaN { + const TARGET_FEATURE: &'static str = "avx512f"; + const INITIAL_INDEX: __m512 = unsafe { std::mem::transmute([ 0.0f32, 1.0f32, 2.0f32, 3.0f32, 4.0f32, 5.0f32, 6.0f32, 7.0f32, 8.0f32, 9.0f32, @@ -357,20 +349,13 @@ mod avx512 { } } - impl SIMDArgMinMaxFloatIgnoreNaN for AVX512FloatIgnoreNaN { - #[target_feature(enable = "avx512f")] - unsafe fn argminmax(data: &[f32]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { use super::AVX512FloatIgnoreNaN as AVX512; - use super::SIMDArgMinMaxFloatIgnoreNaN; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMaxFloatIgnoreNaN; extern crate dev_utils; use dev_utils::utils; diff --git a/src/simd/simd_f64_ignore_nans.rs b/src/simd/simd_f64_ignore_nans.rs index a5e9a96..78728ee 100644 --- a/src/simd/simd_f64_ignore_nans.rs +++ b/src/simd/simd_f64_ignore_nans.rs @@ -1,6 +1,6 @@ #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] use super::config::SIMDInstructionSet; -use super::generic::{SIMDArgMinMaxFloatIgnoreNaN, SIMDOps, SIMDSetOps}; +use super::generic::{SIMDOps, SIMDSetOps}; #[cfg(target_arch = "x86")] use std::arch::x86::*; #[cfg(target_arch = "x86_64")] @@ -22,6 +22,8 @@ mod avx2 { const LANE_SIZE: usize = AVX2::LANE_SIZE_64; impl SIMDOps for AVX2FloatIgnoreNaN { + const TARGET_FEATURE: &'static str = "avx"; + const INITIAL_INDEX: __m256d = unsafe { std::mem::transmute([0.0f64, 1.0f64, 2.0f64, 3.0f64]) }; const INDEX_INCREMENT: __m256d = @@ -66,20 +68,13 @@ mod avx2 { } } - impl SIMDArgMinMaxFloatIgnoreNaN for AVX2FloatIgnoreNaN { - #[target_feature(enable = "avx")] - unsafe fn argminmax(data: &[f64]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { use super::AVX2FloatIgnoreNaN as AVX2; - use super::SIMDArgMinMaxFloatIgnoreNaN; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMaxFloatIgnoreNaN; extern crate dev_utils; use dev_utils::utils; @@ -157,6 +152,8 @@ mod sse { const LANE_SIZE: usize = SSE::LANE_SIZE_64; impl SIMDOps for SSEFloatIgnoreNaN { + const TARGET_FEATURE: &'static str = "sse4.1"; // TODO: check if this is correct + const INITIAL_INDEX: __m128d = unsafe { std::mem::transmute([0.0f64, 1.0f64]) }; const INDEX_INCREMENT: __m128d = unsafe { std::mem::transmute([LANE_SIZE as f64; LANE_SIZE]) }; @@ -200,20 +197,13 @@ mod sse { } } - impl SIMDArgMinMaxFloatIgnoreNaN for SSEFloatIgnoreNaN { - #[target_feature(enable = "sse4.1")] - unsafe fn argminmax(data: &[f64]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::SIMDArgMinMaxFloatIgnoreNaN; use super::SSEFloatIgnoreNaN as SSE; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMaxFloatIgnoreNaN; extern crate dev_utils; use dev_utils::utils; @@ -279,6 +269,8 @@ mod avx512 { const LANE_SIZE: usize = AVX512::LANE_SIZE_64; impl SIMDOps for AVX512FloatIgnoreNaN { + const TARGET_FEATURE: &'static str = "avx512f"; + const INITIAL_INDEX: __m512d = unsafe { std::mem::transmute([ 0.0f64, 1.0f64, 2.0f64, 3.0f64, 4.0f64, 5.0f64, 6.0f64, 7.0f64, @@ -326,20 +318,13 @@ mod avx512 { } } - impl SIMDArgMinMaxFloatIgnoreNaN for AVX512FloatIgnoreNaN { - #[target_feature(enable = "avx512f")] - unsafe fn argminmax(data: &[f64]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { use super::AVX512FloatIgnoreNaN as AVX512; - use super::SIMDArgMinMaxFloatIgnoreNaN; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMaxFloatIgnoreNaN; extern crate dev_utils; use dev_utils::utils; diff --git a/src/simd/simd_i16.rs b/src/simd/simd_i16.rs index 918d10e..114522a 100644 --- a/src/simd/simd_i16.rs +++ b/src/simd/simd_i16.rs @@ -1,5 +1,5 @@ use super::config::SIMDInstructionSet; -use super::generic::{SIMDArgMinMax, SIMDOps}; +use super::generic::SIMDOps; #[cfg(target_arch = "aarch64")] use std::arch::aarch64::*; #[cfg(target_arch = "arm")] @@ -21,6 +21,8 @@ mod avx2 { const LANE_SIZE: usize = AVX2::LANE_SIZE_16; impl SIMDOps for AVX2 { + const TARGET_FEATURE: &'static str = "avx2"; + const INITIAL_INDEX: __m256i = unsafe { std::mem::transmute([ 0i16, 1i16, 2i16, 3i16, 4i16, 5i16, 6i16, 7i16, 8i16, 9i16, 10i16, 11i16, 12i16, @@ -122,19 +124,13 @@ mod avx2 { } } - impl SIMDArgMinMax for AVX2 { - #[target_feature(enable = "avx2")] - unsafe fn argminmax(data: &[i16]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX2}; + use super::AVX2; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -229,6 +225,8 @@ mod sse { const LANE_SIZE: usize = SSE::LANE_SIZE_16; impl SIMDOps for SSE { + const TARGET_FEATURE: &'static str = "sse4.1"; + const INITIAL_INDEX: __m128i = unsafe { std::mem::transmute([0i16, 1i16, 2i16, 3i16, 4i16, 5i16, 6i16, 7i16]) }; const INDEX_INCREMENT: __m128i = @@ -322,19 +320,13 @@ mod sse { } } - impl SIMDArgMinMax for SSE { - #[target_feature(enable = "sse4.1")] - unsafe fn argminmax(data: &[i16]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, SSE}; + use super::SSE; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -413,6 +405,8 @@ mod avx512 { const LANE_SIZE: usize = AVX512::LANE_SIZE_16; impl SIMDOps for AVX512 { + const TARGET_FEATURE: &'static str = "avx512bw"; + const INITIAL_INDEX: __m512i = unsafe { std::mem::transmute([ 0i16, 1i16, 2i16, 3i16, 4i16, 5i16, 6i16, 7i16, 8i16, 9i16, 10i16, 11i16, 12i16, @@ -519,19 +513,13 @@ mod avx512 { } } - impl SIMDArgMinMax for AVX512 { - #[target_feature(enable = "avx512bw")] - unsafe fn argminmax(data: &[i16]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX512}; + use super::AVX512; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; diff --git a/src/simd/simd_i32.rs b/src/simd/simd_i32.rs index f762bf4..5c88a84 100644 --- a/src/simd/simd_i32.rs +++ b/src/simd/simd_i32.rs @@ -1,5 +1,5 @@ use super::config::SIMDInstructionSet; -use super::generic::{SIMDArgMinMax, SIMDOps}; +use super::generic::SIMDOps; #[cfg(target_arch = "aarch64")] use std::arch::aarch64::*; #[cfg(target_arch = "arm")] @@ -21,6 +21,8 @@ mod avx2 { const LANE_SIZE: usize = AVX2::LANE_SIZE_32; impl SIMDOps for AVX2 { + const TARGET_FEATURE: &'static str = "avx2"; + const INITIAL_INDEX: __m256i = unsafe { std::mem::transmute([0i32, 1i32, 2i32, 3i32, 4i32, 5i32, 6i32, 7i32]) }; const INDEX_INCREMENT: __m256i = @@ -58,19 +60,13 @@ mod avx2 { } } - impl SIMDArgMinMax for AVX2 { - #[target_feature(enable = "avx2")] - unsafe fn argminmax(data: &[i32]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX2}; + use super::AVX2; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -149,6 +145,8 @@ mod sse { const LANE_SIZE: usize = SSE::LANE_SIZE_32; impl SIMDOps for SSE { + const TARGET_FEATURE: &'static str = "sse4.1"; + const INITIAL_INDEX: __m128i = unsafe { std::mem::transmute([0i32, 1i32, 2i32, 3i32]) }; const INDEX_INCREMENT: __m128i = unsafe { std::mem::transmute([LANE_SIZE as i32; LANE_SIZE]) }; @@ -185,19 +183,13 @@ mod sse { } } - impl SIMDArgMinMax for SSE { - #[target_feature(enable = "sse4.1")] - unsafe fn argminmax(data: &[i32]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, SSE}; + use super::SSE; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -264,6 +256,8 @@ mod avx512 { const LANE_SIZE: usize = AVX512::LANE_SIZE_32; impl SIMDOps for AVX512 { + const TARGET_FEATURE: &'static str = "avx512f"; + const INITIAL_INDEX: __m512i = unsafe { std::mem::transmute([ 0i32, 1i32, 2i32, 3i32, 4i32, 5i32, 6i32, 7i32, 8i32, 9i32, 10i32, 11i32, 12i32, @@ -305,19 +299,13 @@ mod avx512 { } } - impl SIMDArgMinMax for AVX512 { - #[target_feature(enable = "avx512f")] - unsafe fn argminmax(data: &[i32]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX512}; + use super::AVX512; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; diff --git a/src/simd/simd_i64.rs b/src/simd/simd_i64.rs index 4364818..9f84822 100644 --- a/src/simd/simd_i64.rs +++ b/src/simd/simd_i64.rs @@ -1,6 +1,6 @@ #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] use super::config::SIMDInstructionSet; -use super::generic::{SIMDArgMinMax, SIMDOps}; +use super::generic::SIMDOps; #[cfg(target_arch = "x86")] use std::arch::x86::*; #[cfg(target_arch = "x86_64")] @@ -18,6 +18,8 @@ mod avx2 { const LANE_SIZE: usize = AVX2::LANE_SIZE_64; impl SIMDOps for AVX2 { + const TARGET_FEATURE: &'static str = "avx2"; + const INITIAL_INDEX: __m256i = unsafe { std::mem::transmute([0i64, 1i64, 2i64, 3i64]) }; const INDEX_INCREMENT: __m256i = unsafe { std::mem::transmute([LANE_SIZE as i64; LANE_SIZE]) }; @@ -54,19 +56,13 @@ mod avx2 { } } - impl SIMDArgMinMax for AVX2 { - #[target_feature(enable = "avx2")] - unsafe fn argminmax(data: &[i64]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX2}; + use super::AVX2; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -145,6 +141,8 @@ mod sse { const LANE_SIZE: usize = SSE::LANE_SIZE_64; impl SIMDOps for SSE { + const TARGET_FEATURE: &'static str = "sse4.2"; + const INITIAL_INDEX: __m128i = unsafe { std::mem::transmute([0i64, 1i64]) }; const INDEX_INCREMENT: __m128i = unsafe { std::mem::transmute([LANE_SIZE as i64; LANE_SIZE]) }; @@ -181,19 +179,13 @@ mod sse { } } - impl SIMDArgMinMax for SSE { - #[target_feature(enable = "sse4.2")] - unsafe fn argminmax(data: &[i64]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, SSE}; + use super::SSE; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -260,6 +252,8 @@ mod avx512 { const LANE_SIZE: usize = AVX512::LANE_SIZE_64; impl SIMDOps for AVX512 { + const TARGET_FEATURE: &'static str = "avx512f"; + const INITIAL_INDEX: __m512i = unsafe { std::mem::transmute([0i64, 1i64, 2i64, 3i64, 4i64, 5i64, 6i64, 7i64]) }; const INDEX_INCREMENT: __m512i = @@ -297,19 +291,13 @@ mod avx512 { } } - impl SIMDArgMinMax for AVX512 { - #[target_feature(enable = "avx512f")] - unsafe fn argminmax(data: &[i64]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX512}; + use super::AVX512; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; diff --git a/src/simd/simd_i8.rs b/src/simd/simd_i8.rs index 8ef7950..172ed58 100644 --- a/src/simd/simd_i8.rs +++ b/src/simd/simd_i8.rs @@ -1,5 +1,5 @@ use super::config::SIMDInstructionSet; -use super::generic::{SIMDArgMinMax, SIMDOps}; +use super::generic::SIMDOps; #[cfg(target_arch = "aarch64")] use std::arch::aarch64::*; #[cfg(target_arch = "arm")] @@ -21,6 +21,8 @@ mod avx2 { const LANE_SIZE: usize = AVX2::LANE_SIZE_8; impl SIMDOps for AVX2 { + const TARGET_FEATURE: &'static str = "avx2"; + const INITIAL_INDEX: __m256i = unsafe { std::mem::transmute([ 0i8, 1i8, 2i8, 3i8, 4i8, 5i8, 6i8, 7i8, 8i8, 9i8, 10i8, 11i8, 12i8, 13i8, 14i8, @@ -127,19 +129,13 @@ mod avx2 { } } - impl SIMDArgMinMax for AVX2 { - #[target_feature(enable = "avx2")] - unsafe fn argminmax(data: &[i8]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX2}; + use super::AVX2; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -224,6 +220,8 @@ mod sse { const LANE_SIZE: usize = SSE::LANE_SIZE_8; impl SIMDOps for SSE { + const TARGET_FEATURE: &'static str = "sse4.1"; + const INITIAL_INDEX: __m128i = unsafe { std::mem::transmute([ 0i8, 1i8, 2i8, 3i8, 4i8, 5i8, 6i8, 7i8, 8i8, 9i8, 10i8, 11i8, 12i8, 13i8, 14i8, @@ -325,19 +323,13 @@ mod sse { } } - impl SIMDArgMinMax for SSE { - #[target_feature(enable = "sse4.1")] - unsafe fn argminmax(data: &[i8]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, SSE}; + use super::SSE; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -406,6 +398,8 @@ mod avx512 { const LANE_SIZE: usize = AVX512::LANE_SIZE_8; impl SIMDOps for AVX512 { + const TARGET_FEATURE: &'static str = "avx512bw"; + const INITIAL_INDEX: __m512i = unsafe { std::mem::transmute([ 0i8, 1i8, 2i8, 3i8, 4i8, 5i8, 6i8, 7i8, 8i8, 9i8, 10i8, 11i8, 12i8, 13i8, 14i8, @@ -518,19 +512,13 @@ mod avx512 { } } - impl SIMDArgMinMax for AVX512 { - #[target_feature(enable = "avx512bw")] - unsafe fn argminmax(data: &[i8]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX512}; + use super::AVX512; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; diff --git a/src/simd/simd_u16.rs b/src/simd/simd_u16.rs index 1aa569c..97ac020 100644 --- a/src/simd/simd_u16.rs +++ b/src/simd/simd_u16.rs @@ -1,5 +1,5 @@ use super::config::SIMDInstructionSet; -use super::generic::{SIMDArgMinMax, SIMDOps}; +use super::generic::SIMDOps; #[cfg(target_arch = "aarch64")] use std::arch::aarch64::*; #[cfg(target_arch = "arm")] @@ -44,6 +44,8 @@ mod avx2 { } impl SIMDOps for AVX2 { + const TARGET_FEATURE: &'static str = "avx2"; + const INITIAL_INDEX: __m256i = unsafe { std::mem::transmute([ 0i16, 1i16, 2i16, 3i16, 4i16, 5i16, 6i16, 7i16, 8i16, 9i16, 10i16, 11i16, 12i16, @@ -148,20 +150,13 @@ mod avx2 { } } - // ------------------------------------ ARGMINMAX -------------------------------------- - impl SIMDArgMinMax for AVX2 { - #[target_feature(enable = "avx2")] - unsafe fn argminmax(data: &[u16]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX2}; + use super::AVX2; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -269,6 +264,8 @@ mod sse { } impl SIMDOps for SSE { + const TARGET_FEATURE: &'static str = "sse4.1"; + const INITIAL_INDEX: __m128i = unsafe { std::mem::transmute([0i16, 1i16, 2i16, 3i16, 4i16, 5i16, 6i16, 7i16]) }; const INDEX_INCREMENT: __m128i = @@ -365,19 +362,13 @@ mod sse { } } - impl SIMDArgMinMax for SSE { - #[target_feature(enable = "sse4.1")] - unsafe fn argminmax(data: &[u16]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ----------------------------------------- TESTS ----------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, SSE}; + use super::SSE; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -469,6 +460,8 @@ mod avx512 { } impl SIMDOps for AVX512 { + const TARGET_FEATURE: &'static str = "avx512bw"; + const INITIAL_INDEX: __m512i = unsafe { std::mem::transmute([ 0i16, 1i16, 2i16, 3i16, 4i16, 5i16, 6i16, 7i16, 8i16, 9i16, 10i16, 11i16, 12i16, @@ -578,20 +571,14 @@ mod avx512 { } } - impl SIMDArgMinMax for AVX512 { - #[target_feature(enable = "avx512bw")] - unsafe fn argminmax(data: &[u16]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ----------------------------------------- TESTS ----------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX512}; + use super::AVX512; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; diff --git a/src/simd/simd_u32.rs b/src/simd/simd_u32.rs index 7c170ac..ef0b275 100644 --- a/src/simd/simd_u32.rs +++ b/src/simd/simd_u32.rs @@ -1,5 +1,5 @@ use super::config::SIMDInstructionSet; -use super::generic::{SIMDArgMinMax, SIMDOps}; +use super::generic::SIMDOps; #[cfg(target_arch = "aarch64")] use std::arch::aarch64::*; #[cfg(target_arch = "arm")] @@ -47,6 +47,8 @@ mod avx2 { } impl SIMDOps for AVX2 { + const TARGET_FEATURE: &'static str = "avx2"; + const INITIAL_INDEX: __m256i = unsafe { std::mem::transmute([0i32, 1i32, 2i32, 3i32, 4i32, 5i32, 6i32, 7i32]) }; const INDEX_INCREMENT: __m256i = @@ -103,19 +105,13 @@ mod avx2 { } } - impl SIMDArgMinMax for AVX2 { - #[target_feature(enable = "avx2")] - unsafe fn argminmax(data: &[u32]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX2}; + use super::AVX2; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -208,6 +204,8 @@ mod sse { } impl SIMDOps for SSE { + const TARGET_FEATURE: &'static str = "sse4.1"; + const INITIAL_INDEX: __m128i = unsafe { std::mem::transmute([0i32, 1i32, 2i32, 3i32]) }; const INDEX_INCREMENT: __m128i = unsafe { std::mem::transmute([LANE_SIZE as i32; LANE_SIZE]) }; @@ -263,19 +261,13 @@ mod sse { } } - impl SIMDArgMinMax for SSE { - #[target_feature(enable = "sse4.1")] - unsafe fn argminmax(data: &[u32]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ----------------------------------------- TESTS ----------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, SSE}; + use super::SSE; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -356,6 +348,8 @@ mod avx512 { } impl SIMDOps for AVX512 { + const TARGET_FEATURE: &'static str = "avx512f"; + const INITIAL_INDEX: __m512i = unsafe { std::mem::transmute([ 0i32, 1i32, 2i32, 3i32, 4i32, 5i32, 6i32, 7i32, 8i32, 9i32, 10i32, 11i32, 12i32, @@ -416,19 +410,13 @@ mod avx512 { } } - impl SIMDArgMinMax for AVX512 { - #[target_feature(enable = "avx512f")] - unsafe fn argminmax(data: &[u32]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX512}; + use super::AVX512; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; diff --git a/src/simd/simd_u64.rs b/src/simd/simd_u64.rs index 8d394a0..964035e 100644 --- a/src/simd/simd_u64.rs +++ b/src/simd/simd_u64.rs @@ -1,6 +1,6 @@ #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] use super::config::SIMDInstructionSet; -use super::generic::{SIMDArgMinMax, SIMDOps}; +use super::generic::SIMDOps; #[cfg(target_arch = "x86")] use std::arch::x86::*; #[cfg(target_arch = "x86_64")] @@ -44,6 +44,8 @@ mod avx2 { } impl SIMDOps for AVX2 { + const TARGET_FEATURE: &'static str = "avx2"; + const INITIAL_INDEX: __m256i = unsafe { std::mem::transmute([0i64, 1i64, 2i64, 3i64]) }; const INDEX_INCREMENT: __m256i = unsafe { std::mem::transmute([LANE_SIZE as i64; LANE_SIZE]) }; @@ -99,19 +101,13 @@ mod avx2 { } } - impl SIMDArgMinMax for AVX2 { - #[target_feature(enable = "avx2")] - unsafe fn argminmax(data: &[u64]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX2}; + use super::AVX2; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -204,6 +200,8 @@ mod sse { } impl SIMDOps for SSE { + const TARGET_FEATURE: &'static str = "sse4.2"; + const INITIAL_INDEX: __m128i = unsafe { std::mem::transmute([0i64, 1i64]) }; const INDEX_INCREMENT: __m128i = unsafe { std::mem::transmute([LANE_SIZE as i64; LANE_SIZE]) }; @@ -259,19 +257,13 @@ mod sse { } } - impl SIMDArgMinMax for SSE { - #[target_feature(enable = "sse4.2")] - unsafe fn argminmax(data: &[u64]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ----------------------------------------- TESTS ----------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, SSE}; + use super::SSE; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -352,6 +344,8 @@ mod avx512 { } impl SIMDOps for AVX512 { + const TARGET_FEATURE: &'static str = "avx512f"; + const INITIAL_INDEX: __m512i = unsafe { std::mem::transmute([0i64, 1i64, 2i64, 3i64, 4i64, 5i64, 6i64, 7i64]) }; const INDEX_INCREMENT: __m512i = @@ -408,19 +402,13 @@ mod avx512 { } } - impl SIMDArgMinMax for AVX512 { - #[target_feature(enable = "avx512f")] - unsafe fn argminmax(data: &[u64]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX512}; + use super::AVX512; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; diff --git a/src/simd/simd_u8.rs b/src/simd/simd_u8.rs index dcbaddd..8eb6ba2 100644 --- a/src/simd/simd_u8.rs +++ b/src/simd/simd_u8.rs @@ -1,5 +1,5 @@ use super::config::SIMDInstructionSet; -use super::generic::{SIMDArgMinMax, SIMDOps}; +use super::generic::SIMDOps; #[cfg(target_arch = "aarch64")] use std::arch::aarch64::*; #[cfg(target_arch = "arm")] @@ -44,6 +44,8 @@ mod avx2 { } impl SIMDOps for AVX2 { + const TARGET_FEATURE: &'static str = "avx2"; + const INITIAL_INDEX: __m256i = unsafe { std::mem::transmute([ 0i8, 1i8, 2i8, 3i8, 4i8, 5i8, 6i8, 7i8, 8i8, 9i8, 10i8, 11i8, 12i8, 13i8, 14i8, @@ -153,19 +155,13 @@ mod avx2 { } } - impl SIMDArgMinMax for AVX2 { - #[target_feature(enable = "avx2")] - unsafe fn argminmax(data: &[u8]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ------------------------------------ TESTS -------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX2}; + use super::AVX2; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -263,6 +259,8 @@ mod sse { } impl SIMDOps for SSE { + const TARGET_FEATURE: &'static str = "sse4.1"; + const INITIAL_INDEX: __m128i = unsafe { std::mem::transmute([ 0i8, 1i8, 2i8, 3i8, 4i8, 5i8, 6i8, 7i8, 8i8, 9i8, 10i8, 11i8, 12i8, 13i8, 14i8, @@ -367,19 +365,13 @@ mod sse { } } - impl SIMDArgMinMax for SSE { - #[target_feature(enable = "sse4.1")] - unsafe fn argminmax(data: &[u8]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ----------------------------------------- TESTS ----------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, SSE}; + use super::SSE; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils; @@ -461,6 +453,8 @@ mod avx512 { } impl SIMDOps for AVX512 { + const TARGET_FEATURE: &'static str = "avx512bw"; + const INITIAL_INDEX: __m512i = unsafe { std::mem::transmute([ 0i8, 1i8, 2i8, 3i8, 4i8, 5i8, 6i8, 7i8, 8i8, 9i8, 10i8, 11i8, 12i8, 13i8, 14i8, @@ -576,20 +570,14 @@ mod avx512 { } } - impl SIMDArgMinMax for AVX512 { - #[target_feature(enable = "avx512bw")] - unsafe fn argminmax(data: &[u8]) -> (usize, usize) { - Self::_argminmax(data) - } - } - // ----------------------------------------- TESTS ----------------------------------------- #[cfg(test)] mod tests { - use super::{SIMDArgMinMax, AVX512}; + use super::AVX512; use crate::scalar::generic::scalar_argminmax; + use crate::simd::generic::SIMDArgMinMax; extern crate dev_utils; use dev_utils::utils;