sklears_simd/
lib.rs

1#![allow(dead_code)]
2#![allow(non_snake_case)]
3#![allow(missing_docs)]
4#![allow(deprecated)]
5#![allow(unexpected_cfgs)]
6//! SIMD-optimized operations for sklears
7//!
8//! This crate provides SIMD-accelerated implementations of common machine learning operations
9//! using Rust's portable SIMD API and platform-specific intrinsics.
10
11#![allow(incomplete_features)]
12// Note: no-std feature is temporarily disabled until implementation is complete
13#![cfg_attr(feature = "no-std", no_std)]
14// Portable SIMD is unstable and requires nightly Rust
15// #![cfg_attr(feature = "nightly", feature(portable_simd))]
16
17#[cfg(feature = "no-std")]
18extern crate alloc;
19
20#[cfg(feature = "no-std")]
21use alloc::{boxed::Box, string::String, vec::Vec};
22
23pub mod activation;
24pub mod adaptive_optimization;
25pub mod advanced_optimizations;
26pub mod allocator;
27pub mod approximate;
28pub mod audio_processing;
29pub mod batch_operations;
30pub mod benchmark_framework;
31pub mod bit_operations;
32pub mod clustering;
33pub mod comprehensive_benchmarks;
34pub mod compression;
35pub mod custom_accelerator;
36pub mod distance;
37pub mod distributions;
38pub mod energy_benchmarks;
39pub mod error_correction;
40pub mod external_integration;
41pub mod fluent;
42pub mod fpga;
43pub mod gpu;
44pub mod gpu_memory;
45pub mod half_precision;
46pub mod image_processing;
47pub mod intrinsics;
48pub mod kernels;
49pub mod loss;
50pub mod matrix;
51pub mod memory;
52pub mod middleware;
53pub mod multi_gpu;
54pub mod neuromorphic;
55#[cfg(feature = "no-std")]
56pub mod no_std;
57pub mod optimization;
58pub mod optimization_hints;
59pub mod performance_hooks;
60pub mod performance_monitor;
61pub mod plugin_architecture;
62pub mod profiling;
63pub mod quantum;
64pub mod reduction;
65pub mod regression;
66#[cfg(target_arch = "riscv64")]
67pub mod riscv_vector;
68pub mod safe_simd;
69pub mod safety;
70pub mod search;
71pub mod signal_processing;
72pub mod sorting;
73pub mod target;
74pub mod tpu;
75pub mod traits;
76pub mod validation;
77pub mod vector;
78
79// Re-export key types and functions
80pub use clustering::LinkageType;
81
82/// Platform-specific SIMD capabilities
83#[derive(Debug, Clone, Copy)]
84pub struct SimdCapabilities {
85    pub sse: bool,
86    pub sse2: bool,
87    pub sse3: bool,
88    pub ssse3: bool,
89    pub sse41: bool,
90    pub sse42: bool,
91    pub avx: bool,
92    pub avx2: bool,
93    pub avx512: bool,
94    pub neon: bool,
95    pub riscv_vector: bool,
96    pub riscv_vlen: usize,
97}
98
99impl SimdCapabilities {
100    /// Detect available SIMD instructions on the current platform
101    pub fn detect() -> Self {
102        Self {
103            #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
104            sse: is_x86_feature_detected!("sse"),
105            #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
106            sse2: is_x86_feature_detected!("sse2"),
107            #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
108            sse3: is_x86_feature_detected!("sse3"),
109            #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
110            ssse3: is_x86_feature_detected!("ssse3"),
111            #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
112            sse41: is_x86_feature_detected!("sse4.1"),
113            #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
114            sse42: is_x86_feature_detected!("sse4.2"),
115            #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
116            avx: is_x86_feature_detected!("avx"),
117            #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
118            avx2: is_x86_feature_detected!("avx2"),
119            #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
120            avx512: is_x86_feature_detected!("avx512f"),
121            #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
122            sse: false,
123            #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
124            sse2: false,
125            #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
126            sse3: false,
127            #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
128            ssse3: false,
129            #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
130            sse41: false,
131            #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
132            sse42: false,
133            #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
134            avx: false,
135            #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
136            avx2: false,
137            #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
138            avx512: false,
139            #[cfg(target_arch = "aarch64")]
140            neon: true,
141            #[cfg(not(target_arch = "aarch64"))]
142            neon: false,
143
144            #[cfg(target_arch = "riscv64")]
145            riscv_vector: {
146                #[cfg(target_arch = "riscv64")]
147                {
148                    crate::riscv_vector::RiscVVectorCaps::detect().available
149                }
150                #[cfg(not(target_arch = "riscv64"))]
151                {
152                    false
153                }
154            },
155            #[cfg(not(target_arch = "riscv64"))]
156            riscv_vector: false,
157
158            #[cfg(target_arch = "riscv64")]
159            riscv_vlen: {
160                #[cfg(target_arch = "riscv64")]
161                {
162                    crate::riscv_vector::RiscVVectorCaps::detect().vlen
163                }
164                #[cfg(not(target_arch = "riscv64"))]
165                {
166                    0
167                }
168            },
169            #[cfg(not(target_arch = "riscv64"))]
170            riscv_vlen: 0,
171        }
172    }
173
174    /// Get the best available SIMD width for f32 operations
175    pub fn best_f32_width(&self) -> usize {
176        if self.avx512 {
177            16 // 512 bits / 32 bits
178        } else if self.avx2 || self.avx {
179            8 // 256 bits / 32 bits
180        } else if self.sse || self.neon {
181            4 // 128 bits / 32 bits
182        } else if self.riscv_vector && self.riscv_vlen > 0 {
183            self.riscv_vlen / 32 // VLEN bits / 32 bits per f32
184        } else {
185            1 // Scalar fallback
186        }
187    }
188
189    /// Get the best available SIMD width for f64 operations
190    pub fn best_f64_width(&self) -> usize {
191        if self.avx512 {
192            8 // 512 bits / 64 bits
193        } else if self.avx2 || self.avx {
194            4 // 256 bits / 64 bits
195        } else if self.sse2 || self.neon {
196            2 // 128 bits / 64 bits
197        } else if self.riscv_vector && self.riscv_vlen > 0 {
198            self.riscv_vlen / 64 // VLEN bits / 64 bits per f64
199        } else {
200            1 // Scalar fallback
201        }
202    }
203
204    /// Get the platform name for current SIMD capabilities
205    pub fn platform_name(&self) -> &'static str {
206        if self.avx512 {
207            "AVX-512"
208        } else if self.avx2 {
209            "AVX2"
210        } else if self.avx {
211            "AVX"
212        } else if self.sse42 {
213            "SSE4.2"
214        } else if self.sse41 {
215            "SSE4.1"
216        } else if self.ssse3 {
217            "SSSE3"
218        } else if self.sse3 {
219            "SSE3"
220        } else if self.sse2 {
221            "SSE2"
222        } else if self.sse {
223            "SSE"
224        } else if self.neon {
225            "NEON"
226        } else if self.riscv_vector {
227            "RISC-V Vector"
228        } else {
229            "Scalar"
230        }
231    }
232}
233
234/// Global SIMD capabilities detection
235pub static SIMD_CAPS: once_cell::sync::Lazy<SimdCapabilities> =
236    once_cell::sync::Lazy::new(SimdCapabilities::detect);
237
238#[allow(non_snake_case)]
239#[cfg(test)]
240mod tests {
241    use super::*;
242
243    #[test]
244    fn test_simd_detection() {
245        let caps = SimdCapabilities::detect();
246        println!("SIMD Capabilities: {:?}", caps);
247
248        // At least one width should be available
249        assert!(caps.best_f32_width() >= 1);
250        assert!(caps.best_f64_width() >= 1);
251    }
252}