75 lines
2.3 KiB
Rust
75 lines
2.3 KiB
Rust
|
#![feature(portable_simd)]
|
||
|
use core::{fmt, ops::RangeInclusive};
|
||
|
use proptest;
|
||
|
use test_helpers::{self, biteq, make_runner, prop_assert_biteq};
|
||
|
|
||
|
fn swizzle_dyn_scalar_ver<const N: usize>(values: [u8; N], idxs: [u8; N]) -> [u8; N] {
|
||
|
let mut array = [0; N];
|
||
|
for (i, k) in idxs.into_iter().enumerate() {
|
||
|
if (k as usize) < N {
|
||
|
array[i] = values[k as usize];
|
||
|
};
|
||
|
}
|
||
|
array
|
||
|
}
|
||
|
|
||
|
test_helpers::test_lanes! {
|
||
|
fn swizzle_dyn<const N: usize>() {
|
||
|
match_simd_with_fallback(
|
||
|
&core_simd::simd::Simd::<u8, N>::swizzle_dyn,
|
||
|
&swizzle_dyn_scalar_ver,
|
||
|
&|_, _| true,
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn match_simd_with_fallback<Scalar, ScalarResult, Vector, VectorResult, const N: usize>(
|
||
|
fv: &dyn Fn(Vector, Vector) -> VectorResult,
|
||
|
fs: &dyn Fn([Scalar; N], [Scalar; N]) -> [ScalarResult; N],
|
||
|
check: &dyn Fn([Scalar; N], [Scalar; N]) -> bool,
|
||
|
) where
|
||
|
Scalar: Copy + fmt::Debug + SwizzleStrategy,
|
||
|
ScalarResult: Copy + biteq::BitEq + fmt::Debug + SwizzleStrategy,
|
||
|
Vector: Into<[Scalar; N]> + From<[Scalar; N]> + Copy,
|
||
|
VectorResult: Into<[ScalarResult; N]> + From<[ScalarResult; N]> + Copy,
|
||
|
{
|
||
|
test_swizzles_2(&|x: [Scalar; N], y: [Scalar; N]| {
|
||
|
proptest::prop_assume!(check(x, y));
|
||
|
let result_v: [ScalarResult; N] = fv(x.into(), y.into()).into();
|
||
|
let result_s: [ScalarResult; N] = fs(x, y);
|
||
|
crate::prop_assert_biteq!(result_v, result_s);
|
||
|
Ok(())
|
||
|
});
|
||
|
}
|
||
|
|
||
|
fn test_swizzles_2<A: fmt::Debug + SwizzleStrategy, B: fmt::Debug + SwizzleStrategy>(
|
||
|
f: &dyn Fn(A, B) -> proptest::test_runner::TestCaseResult,
|
||
|
) {
|
||
|
let mut runner = make_runner();
|
||
|
runner
|
||
|
.run(
|
||
|
&(A::swizzled_strategy(), B::swizzled_strategy()),
|
||
|
|(a, b)| f(a, b),
|
||
|
)
|
||
|
.unwrap();
|
||
|
}
|
||
|
|
||
|
pub trait SwizzleStrategy {
|
||
|
type Strategy: proptest::strategy::Strategy<Value = Self>;
|
||
|
fn swizzled_strategy() -> Self::Strategy;
|
||
|
}
|
||
|
|
||
|
impl SwizzleStrategy for u8 {
|
||
|
type Strategy = RangeInclusive<u8>;
|
||
|
fn swizzled_strategy() -> Self::Strategy {
|
||
|
0..=64
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<T: fmt::Debug + SwizzleStrategy, const N: usize> SwizzleStrategy for [T; N] {
|
||
|
type Strategy = test_helpers::array::UniformArrayStrategy<T::Strategy, Self>;
|
||
|
fn swizzled_strategy() -> Self::Strategy {
|
||
|
Self::Strategy::new(T::swizzled_strategy())
|
||
|
}
|
||
|
}
|