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 = wgpu::Instance::default();
21
22 let adapters = instance.enumerate_adapters(wgpu::Backends::all());
24
25 if adapters.is_empty() {
26 return Err(MonitorError::NoDevice);
27 }
28
29 let adapter =
30 adapters.get(device_index as usize).ok_or(MonitorError::InvalidDevice(device_index))?;
31
32 let info = adapter.get_info();
33
34 let backend = match info.backend {
36 wgpu::Backend::Vulkan => GpuBackend::Vulkan,
37 wgpu::Backend::Metal => GpuBackend::Metal,
38 wgpu::Backend::Dx12 => GpuBackend::Dx12,
39 wgpu::Backend::Gl => GpuBackend::OpenGl,
40 wgpu::Backend::BrowserWebGpu => GpuBackend::WebGpu,
41 wgpu::Backend::Noop => GpuBackend::Cpu,
42 };
43
44 let vendor = GpuVendor::from_vendor_id(info.vendor);
46
47 let limits = adapter.limits();
49 let vram_estimate = limits.max_buffer_size;
51
52 Ok(GpuDeviceInfo::new(device_index, info.name, vendor, backend)
53 .with_vram(vram_estimate)
54 .with_driver_version(format!("{:?}", info.driver_info)))
55 })
56}
57
58#[cfg(all(feature = "gpu", not(target_arch = "wasm32")))]
60pub(crate) fn enumerate_wgpu_devices() -> Result<Vec<GpuDeviceInfo>, MonitorError> {
61 use crate::backends::gpu::runtime;
62
63 runtime::block_on(async {
64 let instance = wgpu::Instance::default();
65 let adapters = instance.enumerate_adapters(wgpu::Backends::all());
66
67 if adapters.is_empty() {
68 return Err(MonitorError::NoDevice);
69 }
70
71 let mut devices = Vec::with_capacity(adapters.len());
72
73 for (idx, adapter) in adapters.iter().enumerate() {
74 let info: wgpu::AdapterInfo = adapter.get_info();
75
76 let backend = match info.backend {
77 wgpu::Backend::Vulkan => GpuBackend::Vulkan,
78 wgpu::Backend::Metal => GpuBackend::Metal,
79 wgpu::Backend::Dx12 => GpuBackend::Dx12,
80 wgpu::Backend::Gl => GpuBackend::OpenGl,
81 wgpu::Backend::BrowserWebGpu => GpuBackend::WebGpu,
82 wgpu::Backend::Noop => GpuBackend::Cpu,
83 };
84
85 let vendor = GpuVendor::from_vendor_id(info.vendor);
86 let limits = adapter.limits();
87
88 devices.push(
89 GpuDeviceInfo::new(idx as u32, info.name, vendor, backend)
90 .with_vram(limits.max_buffer_size)
91 .with_driver_version(format!("{:?}", info.driver_info)),
92 );
93 }
94
95 Ok(devices)
96 })
97}
98
99#[cfg(feature = "cuda-monitor")]
109pub fn query_cuda_device_info(device_index: u32) -> Result<GpuDeviceInfo, MonitorError> {
110 use trueno_gpu::CudaDeviceInfo;
111
112 let cuda_info = CudaDeviceInfo::query(device_index)
113 .map_err(|e| MonitorError::BackendInit(format!("CUDA query failed: {}", e)))?;
114
115 Ok(GpuDeviceInfo::new(
116 cuda_info.index,
117 cuda_info.name,
118 GpuVendor::Nvidia, GpuBackend::Cuda,
120 )
121 .with_vram(cuda_info.total_memory))
122}
123
124#[cfg(feature = "cuda-monitor")]
126pub fn enumerate_cuda_devices() -> Result<Vec<GpuDeviceInfo>, MonitorError> {
127 use trueno_gpu::CudaDeviceInfo;
128
129 let cuda_devices = CudaDeviceInfo::enumerate()
130 .map_err(|e| MonitorError::BackendInit(format!("CUDA enumerate failed: {}", e)))?;
131
132 Ok(cuda_devices
133 .into_iter()
134 .map(|cuda_info| {
135 GpuDeviceInfo::new(cuda_info.index, cuda_info.name, GpuVendor::Nvidia, GpuBackend::Cuda)
136 .with_vram(cuda_info.total_memory)
137 })
138 .collect())
139}
140
141#[cfg(feature = "cuda-monitor")]
145pub fn query_cuda_memory(device_index: u32) -> Result<GpuMemoryMetrics, MonitorError> {
146 use trueno_gpu::driver::CudaContext;
147 use trueno_gpu::CudaMemoryInfo;
148
149 let ctx = CudaContext::new(device_index as i32)
150 .map_err(|e| MonitorError::BackendInit(format!("CUDA context failed: {}", e)))?;
151
152 let mem = CudaMemoryInfo::query(&ctx)
153 .map_err(|e| MonitorError::QueryFailed(format!("CUDA memory query failed: {}", e)))?;
154
155 Ok(GpuMemoryMetrics::new(mem.total, mem.used(), mem.free))
156}
157
158#[cfg(feature = "cuda-monitor")]
160#[must_use]
161pub fn cuda_monitor_available() -> bool {
162 trueno_gpu::cuda_monitoring_available()
163}
164
165#[cfg(not(feature = "cuda-monitor"))]
167#[must_use]
168pub fn cuda_monitor_available() -> bool {
169 false
170}