Skip to main content

oxirs_vec/gpu/
device.rs

1//! GPU device information and management
2//!
3//! The published `oxirs-vec` build reports a simulated device (Pure Rust). Real
4//! CUDA device enumeration (`cudaGetDeviceProperties`, `cudaMemGetInfo`, ...) lives
5//! in the quarantined `oxirs-vec-adapter-cuda` crate (publish = false) per the
6//! COOLJAPAN Pure Rust Policy v2.
7
8use anyhow::Result;
9
10/// GPU device information
11#[derive(Debug, Clone)]
12pub struct GpuDevice {
13    pub device_id: i32,
14    pub name: String,
15    pub compute_capability: (i32, i32),
16    pub total_memory: usize,
17    pub free_memory: usize,
18    pub max_threads_per_block: i32,
19    pub max_blocks_per_grid: i32,
20    pub warp_size: i32,
21    pub memory_bandwidth: f32,
22    pub peak_flops: f64,
23}
24
25impl GpuDevice {
26    /// Create a simulated GPU device for testing or when no CUDA device is available
27    fn simulated(device_id: i32) -> Self {
28        Self {
29            device_id,
30            name: format!("Simulated GPU {device_id}"),
31            compute_capability: (7, 5),
32            total_memory: 8 * 1024 * 1024 * 1024,
33            free_memory: 6 * 1024 * 1024 * 1024,
34            max_threads_per_block: 1024,
35            max_blocks_per_grid: 65535,
36            warp_size: 32,
37            memory_bandwidth: 900.0,
38            peak_flops: 14000.0,
39        }
40    }
41
42    /// Get information about a specific GPU device
43    pub fn get_device_info(device_id: i32) -> Result<Self> {
44        // Pure Rust build: report a simulated device. CUDA-backed device
45        // enumeration is provided by oxirs-vec-adapter-cuda.
46        tracing::warn!("CUDA not available - using simulated GPU device");
47        Ok(Self::simulated(device_id))
48    }
49
50    /// Get information about all available GPU devices
51    pub fn get_all_devices() -> Result<Vec<Self>> {
52        // Pure Rust build: simulate two GPUs. CUDA-backed enumeration is provided
53        // by oxirs-vec-adapter-cuda.
54        tracing::warn!("CUDA not available - using simulated GPU devices");
55        Ok(vec![Self::get_device_info(0)?, Self::get_device_info(1)?])
56    }
57
58    /// Check if this device supports a specific compute capability
59    pub fn supports_compute_capability(&self, major: i32, minor: i32) -> bool {
60        self.compute_capability.0 > major
61            || (self.compute_capability.0 == major && self.compute_capability.1 >= minor)
62    }
63
64    /// Get theoretical peak memory bandwidth in GB/s
65    pub fn peak_memory_bandwidth(&self) -> f32 {
66        self.memory_bandwidth
67    }
68
69    /// Get theoretical peak compute performance in GFLOPS
70    pub fn peak_compute_performance(&self) -> f64 {
71        self.peak_flops
72    }
73
74    /// Calculate optimal thread block configuration for given problem size
75    pub fn calculate_optimal_block_config(&self, problem_size: usize) -> (i32, i32) {
76        let optimal_threads = (self.max_threads_per_block as f32 * 0.75) as i32; // Use 75% of max
77        let blocks_needed = ((problem_size as f32) / (optimal_threads as f32)).ceil() as i32;
78        let blocks = blocks_needed.min(self.max_blocks_per_grid);
79        (blocks, optimal_threads)
80    }
81}