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