tropical_gemm/
backend.rs

1use crate::simd::SimdLevel;
2
3/// Available backends for tropical GEMM.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum Backend {
6    /// Pure Rust portable implementation.
7    Portable,
8    /// SIMD-accelerated (AVX2, NEON, etc.).
9    Simd,
10}
11
12impl Backend {
13    /// Get the currently active backend based on CPU features.
14    pub fn current() -> Self {
15        match crate::simd::simd_level() {
16            SimdLevel::Scalar => Backend::Portable,
17            _ => Backend::Simd,
18        }
19    }
20
21    /// Get a description of the current SIMD capabilities.
22    pub fn description() -> String {
23        let level = crate::simd::simd_level();
24        match level {
25            SimdLevel::Scalar => "Portable (no SIMD)".to_string(),
26            SimdLevel::Sse2 => "x86-64 SSE2 (128-bit)".to_string(),
27            SimdLevel::Avx => "x86-64 AVX (256-bit float)".to_string(),
28            SimdLevel::Avx2 => "x86-64 AVX2 (256-bit)".to_string(),
29            SimdLevel::Avx512 => "x86-64 AVX-512 (512-bit)".to_string(),
30            SimdLevel::Neon => "ARM NEON (128-bit)".to_string(),
31        }
32    }
33}
34
35/// Get information about the library configuration.
36pub fn version_info() -> String {
37    format!(
38        "tropical-gemm v{}\nBackend: {}\nSIMD Level: {:?}",
39        env!("CARGO_PKG_VERSION"),
40        Backend::description(),
41        crate::simd::simd_level()
42    )
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn test_backend_detection() {
51        let backend = Backend::current();
52        println!("Current backend: {:?}", backend);
53        println!("Description: {}", Backend::description());
54        println!("Version info:\n{}", version_info());
55
56        // Verify backend is one of the expected values
57        assert!(backend == Backend::Portable || backend == Backend::Simd);
58    }
59
60    #[test]
61    fn test_backend_description_not_empty() {
62        let desc = Backend::description();
63        assert!(!desc.is_empty());
64        // Description should mention SIMD type or portable
65        assert!(
66            desc.contains("Portable")
67                || desc.contains("SSE2")
68                || desc.contains("AVX")
69                || desc.contains("NEON")
70        );
71    }
72
73    #[test]
74    fn test_version_info_format() {
75        let info = version_info();
76        assert!(info.contains("tropical-gemm v"));
77        assert!(info.contains("Backend:"));
78        assert!(info.contains("SIMD Level:"));
79    }
80
81    #[test]
82    fn test_backend_debug() {
83        let backend = Backend::current();
84        let debug_str = format!("{:?}", backend);
85        assert!(debug_str == "Portable" || debug_str == "Simd");
86    }
87
88    #[test]
89    fn test_backend_clone() {
90        let backend = Backend::current();
91        let cloned = backend;
92        assert_eq!(backend, cloned);
93    }
94
95    #[test]
96    fn test_backend_eq() {
97        assert_eq!(Backend::Portable, Backend::Portable);
98        assert_eq!(Backend::Simd, Backend::Simd);
99        assert_ne!(Backend::Portable, Backend::Simd);
100    }
101}