blob: 646cd5f338335075624f5b747d0bb44856364eb1 [file] [log] [blame]
#![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())
}
}