Skip to main content

tensorlogic_scirs_backend/
capabilities.rs

1//! Backend capability detection and reporting.
2
3use tensorlogic_infer::{BackendCapabilities, DType, DeviceType, Feature, TlCapabilities};
4
5use crate::Scirs2Exec;
6
7impl Scirs2Exec {
8    fn build_capabilities() -> BackendCapabilities {
9        let mut caps = BackendCapabilities::new("SciRS2 Backend", env!("CARGO_PKG_VERSION"));
10
11        // Add supported devices
12        caps.supported_devices.insert(DeviceType::CPU);
13        if cfg!(feature = "gpu") {
14            caps.supported_devices.insert(DeviceType::GPU);
15        }
16
17        // Add supported dtypes
18        caps.supported_dtypes.insert(DType::F32);
19        caps.supported_dtypes.insert(DType::F64);
20
21        // Add features
22        caps.features.insert(Feature::Autodiff);
23        caps.features.insert(Feature::BatchExecution);
24
25        // SIMD acceleration
26        #[cfg(feature = "simd")]
27        {
28            caps.features.insert(Feature::SIMDAcceleration);
29        }
30
31        // GPU acceleration
32        #[cfg(feature = "gpu")]
33        {
34            caps.features.insert(Feature::GPUAcceleration);
35        }
36
37        // Set tensor limits
38        caps.max_tensor_dims = 16; // ndarray limit
39
40        caps
41    }
42}
43
44impl TlCapabilities for Scirs2Exec {
45    fn capabilities(&self) -> &BackendCapabilities {
46        // Use OnceLock for safe lazy initialization (Rust 2024 edition)
47        use std::sync::OnceLock;
48        static CAPS: OnceLock<BackendCapabilities> = OnceLock::new();
49
50        CAPS.get_or_init(Self::build_capabilities)
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn test_get_capabilities() {
60        let executor = Scirs2Exec::new();
61        let caps = executor.capabilities();
62
63        assert_eq!(caps.name, "SciRS2 Backend");
64        assert!(!caps.version.is_empty());
65        assert!(caps.supported_devices.contains(&DeviceType::CPU));
66        assert!(caps.max_tensor_dims > 0);
67    }
68
69    #[test]
70    fn test_dtype_support() {
71        let executor = Scirs2Exec::new();
72        let caps = executor.capabilities();
73
74        assert!(caps.supported_dtypes.contains(&DType::F64));
75        assert!(caps.supported_dtypes.contains(&DType::F32));
76    }
77
78    #[test]
79    fn test_features() {
80        let executor = Scirs2Exec::new();
81        let caps = executor.capabilities();
82
83        assert!(caps.features.contains(&Feature::Autodiff));
84        assert!(caps.features.contains(&Feature::BatchExecution));
85    }
86
87    #[test]
88    fn test_available_devices() {
89        let executor = Scirs2Exec::new();
90        let devices = executor.available_devices();
91
92        assert!(devices.contains(&DeviceType::CPU));
93    }
94}