use std::{ os::raw::{c_char, c_uint}, ptr, }; use crate::nvml::nvmlReturn_t; const VERSION: &'static [u8] = b"418.40.04"; macro_rules! stringify_nmvlreturn_t { ($x:ident => [ $($variant:ident),+ ]) => { match $x { $( nvmlReturn_t::$variant => Some(concat!(stringify!($variant), "\0")), )+ _ => None } } } #[cfg(debug_assertions)] pub(crate) fn unimplemented() -> nvmlReturn_t { unimplemented!() } #[cfg(not(debug_assertions))] pub(crate) fn unimplemented() -> nvmlReturn_t { nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED } pub(crate) fn error_string(result: nvmlReturn_t) -> *const ::std::os::raw::c_char { let text = stringify_nmvlreturn_t!( result => [ NVML_SUCCESS, NVML_ERROR_UNINITIALIZED, NVML_ERROR_INVALID_ARGUMENT, NVML_ERROR_NOT_SUPPORTED, NVML_ERROR_NO_PERMISSION, NVML_ERROR_ALREADY_INITIALIZED, NVML_ERROR_NOT_FOUND, NVML_ERROR_INSUFFICIENT_SIZE, NVML_ERROR_INSUFFICIENT_POWER, NVML_ERROR_DRIVER_NOT_LOADED, NVML_ERROR_TIMEOUT, NVML_ERROR_IRQ_ISSUE, NVML_ERROR_LIBRARY_NOT_FOUND, NVML_ERROR_FUNCTION_NOT_FOUND, NVML_ERROR_CORRUPTED_INFOROM, NVML_ERROR_GPU_IS_LOST, NVML_ERROR_RESET_REQUIRED, NVML_ERROR_OPERATING_SYSTEM, NVML_ERROR_LIB_RM_VERSION_MISMATCH, NVML_ERROR_IN_USE, NVML_ERROR_MEMORY, NVML_ERROR_NO_DATA, NVML_ERROR_VGPU_ECC_NOT_SUPPORTED, NVML_ERROR_INSUFFICIENT_RESOURCES, NVML_ERROR_UNKNOWN ] ); match text { Some(text) => text.as_ptr() as *const _, None => ptr::null(), } } pub(crate) fn shutdown() -> nvmlReturn_t { nvmlReturn_t::NVML_SUCCESS } static mut DEVICE: Option = None; pub(crate) fn init() -> Result<(), nvmlReturn_t> { let platforms = ocl_core::get_platform_ids()?; let device = platforms.iter().find_map(|plat| { let devices = ocl_core::get_device_ids(plat, Some(ocl_core::DeviceType::GPU), None).ok()?; for dev in devices { let vendor = ocl_core::get_device_info(dev, ocl_core::DeviceInfo::VendorId).ok()?; match vendor { ocl_core::DeviceInfoResult::VendorId(0x8086) | ocl_core::DeviceInfoResult::VendorId(0x1002) => {} _ => continue, }; let dev_type = ocl_core::get_device_info(dev, ocl_core::DeviceInfo::Type).ok()?; if let ocl_core::DeviceInfoResult::Type(ocl_core::DeviceType::GPU) = dev_type { return Some(dev); } } None }); unsafe { DEVICE = device }; if device.is_some() { Ok(()) } else { Err(nvmlReturn_t::NVML_ERROR_UNKNOWN) } } pub(crate) fn init_with_flags() -> Result<(), nvmlReturn_t> { init() } impl From for nvmlReturn_t { fn from(_: ocl_core::Error) -> Self { nvmlReturn_t::NVML_ERROR_UNKNOWN } } impl From> for nvmlReturn_t { fn from(result: Result<(), nvmlReturn_t>) -> Self { match result { Ok(()) => nvmlReturn_t::NVML_SUCCESS, Err(e) => e, } } } struct CountingWriter { pub base: T, pub len: usize, } impl std::io::Write for CountingWriter { fn write(&mut self, buf: &[u8]) -> std::io::Result { self.len += buf.len(); self.base.write(buf) } fn flush(&mut self) -> std::io::Result<()> { self.base.flush() } } pub(crate) unsafe fn system_get_driver_version( version_ptr: *mut c_char, length: c_uint, ) -> Result<(), nvmlReturn_t> { if version_ptr == ptr::null_mut() || length == 0 { return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); } let strlen = usize::min(VERSION.len(), (length as usize) - 1); std::ptr::copy_nonoverlapping(VERSION.as_ptr(), version_ptr as _, strlen); *version_ptr.add(strlen) = 0; Ok(()) }