nodedb_query/simd_filter/
runtime.rs1use super::scalar::{
6 CmpOp, scalar_cmp_f64, scalar_cmp_i64, scalar_eq_u32, scalar_ne_u32, scalar_range_i64,
7};
8
9pub struct FilterSimdRuntime {
11 pub eq_u32: fn(&[u32], u32) -> Vec<u64>,
13 pub ne_u32: fn(&[u32], u32) -> Vec<u64>,
15 pub gt_f64: fn(&[f64], f64) -> Vec<u64>,
17 pub gte_f64: fn(&[f64], f64) -> Vec<u64>,
19 pub lt_f64: fn(&[f64], f64) -> Vec<u64>,
21 pub lte_f64: fn(&[f64], f64) -> Vec<u64>,
23 pub gt_i64: fn(&[i64], i64) -> Vec<u64>,
25 pub gte_i64: fn(&[i64], i64) -> Vec<u64>,
27 pub lt_i64: fn(&[i64], i64) -> Vec<u64>,
29 pub lte_i64: fn(&[i64], i64) -> Vec<u64>,
31 pub range_i64: fn(&[i64], i64, i64) -> Vec<u64>,
33 pub name: &'static str,
34}
35
36impl FilterSimdRuntime {
37 pub fn detect() -> Self {
38 #[cfg(target_arch = "x86_64")]
39 {
40 if std::is_x86_feature_detected!("avx512f") {
41 return Self {
42 eq_u32: super::avx512::avx512_eq_u32,
43 ne_u32: super::avx512::avx512_ne_u32,
44 gt_f64: super::avx512::avx512_gt_f64,
45 gte_f64: super::avx512::avx512_gte_f64,
46 lt_f64: super::avx512::avx512_lt_f64,
47 lte_f64: super::avx512::avx512_lte_f64,
48 gt_i64: super::avx512::avx512_gt_i64,
49 gte_i64: super::avx512::avx512_gte_i64,
50 lt_i64: super::avx512::avx512_lt_i64,
51 lte_i64: super::avx512::avx512_lte_i64,
52 range_i64: super::avx512::avx512_range_i64,
53 name: "avx512",
54 };
55 }
56 if std::is_x86_feature_detected!("avx2") {
57 return Self {
58 eq_u32: super::avx2::avx2_eq_u32,
59 ne_u32: super::avx2::avx2_ne_u32,
60 gt_f64: super::avx2::avx2_gt_f64,
61 gte_f64: super::avx2::avx2_gte_f64,
62 lt_f64: super::avx2::avx2_lt_f64,
63 lte_f64: super::avx2::avx2_lte_f64,
64 gt_i64: super::avx2::avx2_gt_i64,
65 gte_i64: super::avx2::avx2_gte_i64,
66 lt_i64: super::avx2::avx2_lt_i64,
67 lte_i64: super::avx2::avx2_lte_i64,
68 range_i64: super::avx2::avx2_range_i64,
69 name: "avx2",
70 };
71 }
72 }
73 #[cfg(target_arch = "aarch64")]
74 {
75 return Self {
76 eq_u32: super::neon::neon_eq_u32,
77 ne_u32: super::neon::neon_ne_u32,
78 gt_f64: super::neon::neon_gt_f64,
79 gte_f64: super::neon::neon_gte_f64,
80 lt_f64: super::neon::neon_lt_f64,
81 lte_f64: super::neon::neon_lte_f64,
82 gt_i64: super::neon::neon_gt_i64,
83 gte_i64: super::neon::neon_gte_i64,
84 lt_i64: super::neon::neon_lt_i64,
85 lte_i64: super::neon::neon_lte_i64,
86 range_i64: super::neon::neon_range_i64,
87 name: "neon",
88 };
89 }
90 #[cfg(target_arch = "wasm32")]
91 {
92 return Self {
93 eq_u32: super::wasm::wasm_eq_u32,
94 ne_u32: super::wasm::wasm_ne_u32,
95 gt_f64: |v, t| scalar_cmp_f64(v, t, CmpOp::Gt),
96 gte_f64: |v, t| scalar_cmp_f64(v, t, CmpOp::Gte),
97 lt_f64: |v, t| scalar_cmp_f64(v, t, CmpOp::Lt),
98 lte_f64: |v, t| scalar_cmp_f64(v, t, CmpOp::Lte),
99 gt_i64: |v, t| scalar_cmp_i64(v, t, CmpOp::Gt),
100 gte_i64: |v, t| scalar_cmp_i64(v, t, CmpOp::Gte),
101 lt_i64: |v, t| scalar_cmp_i64(v, t, CmpOp::Lt),
102 lte_i64: |v, t| scalar_cmp_i64(v, t, CmpOp::Lte),
103 range_i64: scalar_range_i64,
104 name: "wasm-simd128",
105 };
106 }
107 #[allow(unreachable_code)]
108 Self {
109 eq_u32: scalar_eq_u32,
110 ne_u32: scalar_ne_u32,
111 gt_f64: |v, t| scalar_cmp_f64(v, t, CmpOp::Gt),
112 gte_f64: |v, t| scalar_cmp_f64(v, t, CmpOp::Gte),
113 lt_f64: |v, t| scalar_cmp_f64(v, t, CmpOp::Lt),
114 lte_f64: |v, t| scalar_cmp_f64(v, t, CmpOp::Lte),
115 gt_i64: |v, t| scalar_cmp_i64(v, t, CmpOp::Gt),
116 gte_i64: |v, t| scalar_cmp_i64(v, t, CmpOp::Gte),
117 lt_i64: |v, t| scalar_cmp_i64(v, t, CmpOp::Lt),
118 lte_i64: |v, t| scalar_cmp_i64(v, t, CmpOp::Lte),
119 range_i64: scalar_range_i64,
120 name: "scalar",
121 }
122 }
123}
124
125static FILTER_RUNTIME: std::sync::OnceLock<FilterSimdRuntime> = std::sync::OnceLock::new();
126
127pub fn filter_runtime() -> &'static FilterSimdRuntime {
129 FILTER_RUNTIME.get_or_init(FilterSimdRuntime::detect)
130}