trueno/monitor/
backends.rs1#[cfg(feature = "cuda-monitor")]
4use super::GpuMemoryMetrics;
5#[cfg(any(all(feature = "gpu", not(target_arch = "wasm32")), feature = "cuda-monitor"))]
6use super::MonitorError;
7#[cfg(any(all(feature = "gpu", not(target_arch = "wasm32")), feature = "cuda-monitor"))]
8use super::{GpuBackend, GpuDeviceInfo, GpuVendor};
9
10#[cfg(all(feature = "gpu", not(target_arch = "wasm32")))]
16pub(crate) fn query_wgpu_device_info(device_index: u32) -> Result<GpuDeviceInfo, MonitorError> {
17 use crate::backends::gpu::runtime;
18
19 runtime::block_on(async {
20 let instance = crate::backends::gpu::shared_instance();
22
23 let adapters = instance.enumerate_adapters(crate::backends::gpu::gpu_backends());
26
27 if adapters.is_empty() {
28 return Err(MonitorError::NoDevice);
29 }
30
31 let adapter =
32 adapters.get(device_index as usize).ok_or(MonitorError::InvalidDevice(device_index))?;
33
34 let info = adapter.get_info();
35
36 let backend = match info.backend {
38 wgpu::Backend::Vulkan => GpuBackend::Vulkan,
39 wgpu::Backend::Metal => GpuBackend::Metal,
40 wgpu::Backend::Dx12 => GpuBackend::Dx12,
41 wgpu::Backend::Gl => GpuBackend::OpenGl,
42 wgpu::Backend::BrowserWebGpu => GpuBackend::WebGpu,
43 wgpu::Backend::Noop => GpuBackend::Cpu,
44 };
45
46 let vendor = GpuVendor::from_vendor_id(info.vendor);
48
49 let limits = adapter.limits();
51 let vram_estimate = limits.max_buffer_size;
53
54 Ok(GpuDeviceInfo::new(device_index, info.name, vendor, backend)
55 .with_vram(vram_estimate)
56 .with_driver_version(format!("{:?}", info.driver_info)))
57 })
58}
59
60#[cfg(all(feature = "gpu", not(target_arch = "wasm32")))]
62pub(crate) fn enumerate_wgpu_devices() -> Result<Vec<GpuDeviceInfo>, MonitorError> {
63 use crate::backends::gpu::runtime;
64
65 runtime::block_on(async {
66 let instance = crate::backends::gpu::shared_instance();
68 let adapters = instance.enumerate_adapters(crate::backends::gpu::gpu_backends());
70
71 if adapters.is_empty() {
72 return Err(MonitorError::NoDevice);
73 }
74
75 let mut devices = Vec::with_capacity(adapters.len());
76
77 for (idx, adapter) in adapters.iter().enumerate() {
78 let info: wgpu::AdapterInfo = adapter.get_info();
79
80 let backend = match info.backend {
81 wgpu::Backend::Vulkan => GpuBackend::Vulkan,
82 wgpu::Backend::Metal => GpuBackend::Metal,
83 wgpu::Backend::Dx12 => GpuBackend::Dx12,
84 wgpu::Backend::Gl => GpuBackend::OpenGl,
85 wgpu::Backend::BrowserWebGpu => GpuBackend::WebGpu,
86 wgpu::Backend::Noop => GpuBackend::Cpu,
87 };
88
89 let vendor = GpuVendor::from_vendor_id(info.vendor);
90 let limits = adapter.limits();
91
92 devices.push(
93 GpuDeviceInfo::new(idx as u32, info.name, vendor, backend)
94 .with_vram(limits.max_buffer_size)
95 .with_driver_version(format!("{:?}", info.driver_info)),
96 );
97 }
98
99 Ok(devices)
100 })
101}
102
103#[cfg(feature = "cuda-monitor")]
113pub fn query_cuda_device_info(device_index: u32) -> Result<GpuDeviceInfo, MonitorError> {
114 use trueno_gpu::CudaDeviceInfo;
115
116 let cuda_info = CudaDeviceInfo::query(device_index)
117 .map_err(|e| MonitorError::BackendInit(format!("CUDA query failed: {}", e)))?;
118
119 Ok(GpuDeviceInfo::new(
120 cuda_info.index,
121 cuda_info.name,
122 GpuVendor::Nvidia, GpuBackend::Cuda,
124 )
125 .with_vram(cuda_info.total_memory))
126}
127
128#[cfg(feature = "cuda-monitor")]
130pub fn enumerate_cuda_devices() -> Result<Vec<GpuDeviceInfo>, MonitorError> {
131 use trueno_gpu::CudaDeviceInfo;
132
133 let cuda_devices = CudaDeviceInfo::enumerate()
134 .map_err(|e| MonitorError::BackendInit(format!("CUDA enumerate failed: {}", e)))?;
135
136 Ok(cuda_devices
137 .into_iter()
138 .map(|cuda_info| {
139 GpuDeviceInfo::new(cuda_info.index, cuda_info.name, GpuVendor::Nvidia, GpuBackend::Cuda)
140 .with_vram(cuda_info.total_memory)
141 })
142 .collect())
143}
144
145#[cfg(feature = "cuda-monitor")]
149pub fn query_cuda_memory(device_index: u32) -> Result<GpuMemoryMetrics, MonitorError> {
150 use trueno_gpu::driver::CudaContext;
151 use trueno_gpu::CudaMemoryInfo;
152
153 let ctx = CudaContext::new(device_index as i32)
154 .map_err(|e| MonitorError::BackendInit(format!("CUDA context failed: {}", e)))?;
155
156 let mem = CudaMemoryInfo::query(&ctx)
157 .map_err(|e| MonitorError::QueryFailed(format!("CUDA memory query failed: {}", e)))?;
158
159 Ok(GpuMemoryMetrics::new(mem.total, mem.used(), mem.free))
160}
161
162#[cfg(feature = "cuda-monitor")]
164#[must_use]
165pub fn cuda_monitor_available() -> bool {
166 trueno_gpu::cuda_monitoring_available()
167}
168
169#[cfg(not(feature = "cuda-monitor"))]
171#[must_use]
172pub fn cuda_monitor_available() -> bool {
173 false
174}