1#![cfg_attr(feature = "no-std", no_std)]
12#![allow(clippy::ifs_same_cond)]
17#![allow(clippy::nonminimal_bool)]
18#![allow(clippy::eq_op)]
19
20#[cfg(feature = "no-std")]
21extern crate alloc;
22
23#[cfg(feature = "no-std")]
25#[macro_export]
26macro_rules! println {
27 ($($arg:tt)*) => {{}};
28}
29
30#[cfg(feature = "no-std")]
31#[macro_export]
32macro_rules! eprintln {
33 ($($arg:tt)*) => {{}};
34}
35
36#[cfg(all(
40 any(target_arch = "x86", target_arch = "x86_64"),
41 not(feature = "no-std")
42))]
43#[macro_export]
44macro_rules! simd_feature_detected {
45 ($feature:tt) => {
46 std::arch::is_x86_feature_detected!($feature)
47 };
48}
49
50#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), feature = "no-std"))]
51#[macro_export]
52#[allow(unused_macros)]
53macro_rules! simd_feature_detected {
54 ($feature:tt) => {
55 false
56 };
57}
58
59#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
60#[macro_export]
61#[allow(unused_macros)]
62macro_rules! simd_feature_detected {
63 ($feature:tt) => {
64 false
65 };
66}
67
68pub mod activation;
71pub mod adaptive_optimization;
72pub mod advanced_optimizations;
73pub mod allocator;
74pub mod approximate;
75pub mod audio_processing;
76pub mod batch_operations;
77pub mod benchmark_framework;
78pub mod bit_operations;
79pub mod clustering;
80pub mod comprehensive_benchmarks;
81pub mod compression;
82pub mod custom_accelerator;
83pub mod distance;
84pub mod distributions;
85pub mod energy_benchmarks;
86pub mod error_correction;
87pub mod external_integration;
88pub mod fluent;
89pub mod fpga;
90pub mod half_precision;
91pub mod image_processing;
92pub mod intrinsics;
93pub mod kernels;
94pub mod loss;
95pub mod matrix;
96pub mod memory;
97pub mod middleware;
98pub mod neuromorphic;
99#[cfg(feature = "no-std")]
100pub mod no_std;
101pub mod optimization;
102pub mod optimization_hints;
103pub mod performance_hooks;
104pub mod performance_monitor;
105pub mod plugin_architecture;
106pub mod profiling;
107pub mod quantum;
108pub mod reduction;
109pub mod regression;
110#[cfg(target_arch = "riscv64")]
111pub mod riscv_vector;
112pub mod safe_simd;
113pub mod safety;
114pub mod search;
115pub mod signal_processing;
116pub mod sorting;
117pub mod target;
118pub mod tpu;
119pub mod traits;
120pub mod validation;
121pub mod vector;
122
123pub use clustering::LinkageType;
125
126#[derive(Debug, Clone, Copy)]
128pub struct SimdCapabilities {
129 pub sse: bool,
130 pub sse2: bool,
131 pub sse3: bool,
132 pub ssse3: bool,
133 pub sse41: bool,
134 pub sse42: bool,
135 pub avx: bool,
136 pub avx2: bool,
137 pub avx512: bool,
138 pub neon: bool,
139 pub riscv_vector: bool,
140 pub riscv_vlen: usize,
141}
142
143impl SimdCapabilities {
144 pub fn detect() -> Self {
146 Self {
147 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
148 sse: simd_feature_detected!("sse"),
149 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
150 sse2: simd_feature_detected!("sse2"),
151 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
152 sse3: simd_feature_detected!("sse3"),
153 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
154 ssse3: simd_feature_detected!("ssse3"),
155 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
156 sse41: simd_feature_detected!("sse4.1"),
157 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
158 sse42: simd_feature_detected!("sse4.2"),
159 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
160 avx: simd_feature_detected!("avx"),
161 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
162 avx2: simd_feature_detected!("avx2"),
163 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
164 avx512: simd_feature_detected!("avx512f"),
165 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
166 sse: false,
167 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
168 sse2: false,
169 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
170 sse3: false,
171 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
172 ssse3: false,
173 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
174 sse41: false,
175 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
176 sse42: false,
177 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
178 avx: false,
179 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
180 avx2: false,
181 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
182 avx512: false,
183 #[cfg(target_arch = "aarch64")]
184 neon: true,
185 #[cfg(not(target_arch = "aarch64"))]
186 neon: false,
187
188 #[cfg(target_arch = "riscv64")]
189 riscv_vector: {
190 #[cfg(target_arch = "riscv64")]
191 {
192 crate::riscv_vector::RiscVVectorCaps::detect().available
193 }
194 #[cfg(not(target_arch = "riscv64"))]
195 {
196 false
197 }
198 },
199 #[cfg(not(target_arch = "riscv64"))]
200 riscv_vector: false,
201
202 #[cfg(target_arch = "riscv64")]
203 riscv_vlen: {
204 #[cfg(target_arch = "riscv64")]
205 {
206 crate::riscv_vector::RiscVVectorCaps::detect().vlen
207 }
208 #[cfg(not(target_arch = "riscv64"))]
209 {
210 0
211 }
212 },
213 #[cfg(not(target_arch = "riscv64"))]
214 riscv_vlen: 0,
215 }
216 }
217
218 pub fn best_f32_width(&self) -> usize {
220 if self.avx512 {
221 16 } else if self.avx2 || self.avx {
223 8 } else if self.sse || self.neon {
225 4 } else if self.riscv_vector && self.riscv_vlen > 0 {
227 self.riscv_vlen / 32 } else {
229 1 }
231 }
232
233 pub fn best_f64_width(&self) -> usize {
235 if self.avx512 {
236 8 } else if self.avx2 || self.avx {
238 4 } else if self.sse2 || self.neon {
240 2 } else if self.riscv_vector && self.riscv_vlen > 0 {
242 self.riscv_vlen / 64 } else {
244 1 }
246 }
247
248 pub fn platform_name(&self) -> &'static str {
250 if self.avx512 {
251 "AVX-512"
252 } else if self.avx2 {
253 "AVX2"
254 } else if self.avx {
255 "AVX"
256 } else if self.sse42 {
257 "SSE4.2"
258 } else if self.sse41 {
259 "SSE4.1"
260 } else if self.ssse3 {
261 "SSSE3"
262 } else if self.sse3 {
263 "SSE3"
264 } else if self.sse2 {
265 "SSE2"
266 } else if self.sse {
267 "SSE"
268 } else if self.neon {
269 "NEON"
270 } else if self.riscv_vector {
271 "RISC-V Vector"
272 } else {
273 "Scalar"
274 }
275 }
276}
277
278pub static SIMD_CAPS: once_cell::sync::Lazy<SimdCapabilities> =
280 once_cell::sync::Lazy::new(SimdCapabilities::detect);
281
282#[allow(non_snake_case)]
283#[cfg(all(test, not(feature = "no-std")))]
284mod tests {
285 use super::*;
286
287 #[test]
288 fn test_simd_detection() {
289 let caps = SimdCapabilities::detect();
290 println!("SIMD Capabilities: {:?}", caps);
291
292 assert!(caps.best_f32_width() >= 1);
294 assert!(caps.best_f64_width() >= 1);
295 }
296}