add all_lane_counts feature to enable non-power-of-2 lane counts <= 64

This commit is contained in:
Jacob Lifshay 2022-07-29 16:12:24 -07:00
parent 691c8b29e6
commit 8742a86b1d
5 changed files with 217 additions and 98 deletions

View File

@ -241,6 +241,10 @@ jobs:
- "--features std"
- "--features generic_const_exprs"
- "--features std --features generic_const_exprs"
- "--features all_lane_counts"
- "--features all_lane_counts --features std"
- "--features all_lane_counts --features generic_const_exprs"
- "--features all_lane_counts --features std --features generic_const_exprs"
steps:
- uses: actions/checkout@v2

View File

@ -13,6 +13,7 @@ default = ["as_crate"]
as_crate = []
std = []
generic_const_exprs = []
all_lane_counts = []
[target.'cfg(target_arch = "wasm32")'.dev-dependencies.wasm-bindgen]
version = "0.2"

View File

@ -23,24 +23,20 @@ pub trait SupportedLaneCount: Sealed {
impl<const LANES: usize> Sealed for LaneCount<LANES> {}
impl SupportedLaneCount for LaneCount<1> {
type BitMask = [u8; 1];
}
impl SupportedLaneCount for LaneCount<2> {
type BitMask = [u8; 1];
}
impl SupportedLaneCount for LaneCount<4> {
type BitMask = [u8; 1];
}
impl SupportedLaneCount for LaneCount<8> {
type BitMask = [u8; 1];
}
impl SupportedLaneCount for LaneCount<16> {
type BitMask = [u8; 2];
}
impl SupportedLaneCount for LaneCount<32> {
type BitMask = [u8; 4];
}
impl SupportedLaneCount for LaneCount<64> {
type BitMask = [u8; 8];
macro_rules! supported_lane_count {
($($lanes:literal),+) => {
$(
impl SupportedLaneCount for LaneCount<$lanes> {
type BitMask = [u8; ($lanes + 7) / 8];
}
)+
};
}
supported_lane_count!(1, 2, 4, 8, 16, 32, 64);
#[cfg(feature = "all_lane_counts")]
supported_lane_count!(
3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63
);

View File

@ -8,3 +8,6 @@ publish = false
version = "0.10"
default-features = false
features = ["alloc"]
[features]
all_lane_counts = []

View File

@ -333,6 +333,39 @@ pub fn test_ternary_elementwise<
);
}
#[doc(hidden)]
#[macro_export]
macro_rules! test_lanes_helper {
($($(#[$meta:meta])* $fn_name:ident $lanes:literal;)+) => {
$(
#[test]
$(#[$meta])*
fn $fn_name() {
implementation::<$lanes>();
}
)+
};
(
$(#[$meta:meta])+;
$($(#[$meta_before:meta])+ $fn_name_before:ident $lanes_before:literal;)*
$fn_name:ident $lanes:literal;
$($fn_name_rest:ident $lanes_rest:literal;)*
) => {
$crate::test_lanes_helper!(
$(#[$meta])+;
$($(#[$meta_before])+ $fn_name_before $lanes_before;)*
$(#[$meta])+ $fn_name $lanes;
$($fn_name_rest $lanes_rest;)*
);
};
(
$(#[$meta_ignored:meta])+;
$($(#[$meta:meta])+ $fn_name:ident $lanes:literal;)+
) => {
$crate::test_lanes_helper!($($(#[$meta])+ $fn_name $lanes;)+);
};
}
/// Expand a const-generic test into separate tests for each possible lane count.
#[macro_export]
macro_rules! test_lanes {
@ -351,51 +384,90 @@ fn implementation<const $lanes: usize>()
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
fn lanes_1() {
implementation::<1>();
}
$crate::test_lanes_helper!(
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)];
lanes_1 1;
lanes_2 2;
lanes_4 4;
);
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
fn lanes_2() {
implementation::<2>();
}
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
fn lanes_4() {
implementation::<4>();
}
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
fn lanes_8() {
implementation::<8>();
}
$crate::test_lanes_helper!(
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)];
lanes_8 8;
lanes_16 16;
lanes_32 32;
lanes_64 64;
);
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
fn lanes_16() {
implementation::<16>();
}
#[cfg(feature = "all_lane_counts")]
$crate::test_lanes_helper!(
// test some odd and even non-power-of-2 lengths on miri
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)];
lanes_3 3;
lanes_5 5;
lanes_6 6;
);
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg(feature = "all_lane_counts")]
#[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
fn lanes_32() {
implementation::<32>();
}
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
fn lanes_64() {
implementation::<64>();
}
$crate::test_lanes_helper!(
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)];
lanes_7 7;
lanes_9 9;
lanes_10 10;
lanes_11 11;
lanes_12 12;
lanes_13 13;
lanes_14 14;
lanes_15 15;
lanes_17 17;
lanes_18 18;
lanes_19 19;
lanes_20 20;
lanes_21 21;
lanes_22 22;
lanes_23 23;
lanes_24 24;
lanes_25 25;
lanes_26 26;
lanes_27 27;
lanes_28 28;
lanes_29 29;
lanes_30 30;
lanes_31 31;
lanes_33 33;
lanes_34 34;
lanes_35 35;
lanes_36 36;
lanes_37 37;
lanes_38 38;
lanes_39 39;
lanes_40 40;
lanes_41 41;
lanes_42 42;
lanes_43 43;
lanes_44 44;
lanes_45 45;
lanes_46 46;
lanes_47 47;
lanes_48 48;
lanes_49 49;
lanes_50 50;
lanes_51 51;
lanes_52 52;
lanes_53 53;
lanes_54 54;
lanes_55 55;
lanes_56 56;
lanes_57 57;
lanes_58 58;
lanes_59 59;
lanes_60 60;
lanes_61 61;
lanes_62 62;
lanes_63 63;
);
}
)*
}
@ -416,47 +488,90 @@ fn implementation<const $lanes: usize>()
core_simd::LaneCount<$lanes>: core_simd::SupportedLaneCount,
$body
#[test]
#[should_panic]
fn lanes_1() {
implementation::<1>();
}
$crate::test_lanes_helper!(
#[should_panic];
lanes_1 1;
lanes_2 2;
lanes_4 4;
);
#[test]
#[should_panic]
fn lanes_2() {
implementation::<2>();
}
#[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
$crate::test_lanes_helper!(
#[should_panic];
lanes_8 8;
lanes_16 16;
lanes_32 32;
lanes_64 64;
);
#[test]
#[should_panic]
fn lanes_4() {
implementation::<4>();
}
#[cfg(feature = "all_lane_counts")]
$crate::test_lanes_helper!(
// test some odd and even non-power-of-2 lengths on miri
#[should_panic];
lanes_3 3;
lanes_5 5;
lanes_6 6;
);
#[test]
#[should_panic]
fn lanes_8() {
implementation::<8>();
}
#[test]
#[should_panic]
fn lanes_16() {
implementation::<16>();
}
#[test]
#[should_panic]
fn lanes_32() {
implementation::<32>();
}
#[test]
#[should_panic]
fn lanes_64() {
implementation::<64>();
}
#[cfg(feature = "all_lane_counts")]
#[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow
$crate::test_lanes_helper!(
#[should_panic];
lanes_7 7;
lanes_9 9;
lanes_10 10;
lanes_11 11;
lanes_12 12;
lanes_13 13;
lanes_14 14;
lanes_15 15;
lanes_17 17;
lanes_18 18;
lanes_19 19;
lanes_20 20;
lanes_21 21;
lanes_22 22;
lanes_23 23;
lanes_24 24;
lanes_25 25;
lanes_26 26;
lanes_27 27;
lanes_28 28;
lanes_29 29;
lanes_30 30;
lanes_31 31;
lanes_33 33;
lanes_34 34;
lanes_35 35;
lanes_36 36;
lanes_37 37;
lanes_38 38;
lanes_39 39;
lanes_40 40;
lanes_41 41;
lanes_42 42;
lanes_43 43;
lanes_44 44;
lanes_45 45;
lanes_46 46;
lanes_47 47;
lanes_48 48;
lanes_49 49;
lanes_50 50;
lanes_51 51;
lanes_52 52;
lanes_53 53;
lanes_54 54;
lanes_55 55;
lanes_56 56;
lanes_57 57;
lanes_58 58;
lanes_59 59;
lanes_60 60;
lanes_61 61;
lanes_62 62;
lanes_63 63;
);
}
)*
}