competitive/tools/
avx_helper.rs1#[macro_export]
2macro_rules! avx_helper {
3 (@avx512 $(#[$meta:meta])* $vis:vis fn $name:ident$(<$($T:ident),+>)?($($i:ident: $t:ty),*) -> $ret:ty where [$($clauses:tt)*] $body:block) => {
4 $(#[$meta])*
5 $vis fn $name$(<$($T)*>)?($($i: $t),*) -> $ret
6 where
7 $($clauses)*
8 {
9 if is_x86_feature_detected!("avx512f")
10 && is_x86_feature_detected!("avx512dq")
11 && is_x86_feature_detected!("avx512cd")
12 && is_x86_feature_detected!("avx512bw")
13 && is_x86_feature_detected!("avx512vl")
14 {
15 $crate::avx_helper!(@def_avx512 fn avx512$(<$($T)*>)?($($i: $t),*) -> $ret where [$($clauses)*] $body);
16 unsafe { avx512$(::<$($T),*>)?($($i),*) }
17 } else if is_x86_feature_detected!("avx2") {
18 $crate::avx_helper!(@def_avx2 fn avx2$(<$($T)*>)?($($i: $t),*) -> $ret where [$($clauses)*] $body);
19 unsafe { avx2$(::<$($T),*>)?($($i),*) }
20 } else {
21 $body
22 }
23 }
24 };
25 (@avx2 $(#[$meta:meta])* $vis:vis fn $name:ident$(<$($T:ident),+>)?($($i:ident: $t:ty),*) -> $ret:ty where [$($clauses:tt)*] $body:block) => {
26 $(#[$meta])*
27 $vis fn $name$(<$($T)*>)?($($i: $t),*) -> $ret
28 where
29 $($clauses)*
30 {
31 if is_x86_feature_detected!("avx2") {
32 $crate::avx_helper!(@def_avx2 fn avx2$(<$($T)*>)?($($i: $t),*) -> $ret where [$($clauses)*] $body);
33 unsafe { avx2$(::<$($T),*>)?($($i),*) }
34 } else {
35 $body
36 }
37 }
38 };
39 (@def_avx512 fn $name:ident$(<$($T:ident),+>)?($($args:tt)*) -> $ret:ty where [$($clauses:tt)*] $body:block) => {
40 #[target_feature(enable = "avx512f,avx512dq,avx512cd,avx512bw,avx512vl")]
41 unsafe fn $name$(<$($T)*>)?($($args)*) -> $ret
42 where
43 $($clauses)*
44 $body
45 };
46 (@def_avx2 fn $name:ident$(<$($T:ident),+>)?($($args:tt)*) -> $ret:ty where [$($clauses:tt)*] $body:block) => {
47 #[target_feature(enable = "avx2")]
48 unsafe fn $name$(<$($T)*>)?($($args)*) -> $ret
49 where
50 $($clauses)*
51 $body
52 };
53 (@$tag:ident $(#[$meta:meta])* $vis:vis fn $name:ident$(<$($T:ident),+>)?($($args:tt)*) -> $ret:ty $body:block) => {
54 $crate::avx_helper!(@$tag $(#[$meta])* $vis fn $name$(<$($T)*>)?($($args)*) -> $ret where [] $body);
55 };
56 (@$tag:ident $(#[$meta:meta])* $vis:vis fn $name:ident$(<$($T:ident),+>)?($($args:tt)*) $($t:tt)*) => {
57 $crate::avx_helper!(@$tag $(#[$meta])* $vis fn $name$(<$($T)*>)?($($args)*) -> () $($t)*);
58 };
59 ($($t:tt)*) => {
60 ::std::compile_error!($($t)*);
61 }
62}