4f0d8225fa
This is meant to be an example that is used to test a Rust intrinsic against, which will replace it. The interface is fairly direct and doesn't address more nuanced or interesting permutations one can do, nevermind on types other than bytes. The ultimate goal is for direct LLVM support for this.
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())
|
|
}
|
|
}
|