use super::api::{Driver, DriverFFI};
use crate::hardware::{HardwareType, IHardware};
use byteorder::{LittleEndian, ReadBytesExt};
use std::io::Cursor;
#[derive(Debug, Clone)]
pub struct Device {
id: isize,
name: Option<String>,
device_type: Option<HardwareType>,
compute_units: Option<isize>,
}
impl Default for Device {
fn default() -> Self {
Device {
id: -1,
name: None,
device_type: None,
compute_units: None,
}
}
}
impl Device {
pub fn from_isize(id: isize) -> Device {
Device {
id,
..Device::default()
}
}
pub fn from_c(id: DriverFFI::CUdevice) -> Device {
Device {
id: id as isize,
..Device::default()
}
}
pub fn id_c(&self) -> DriverFFI::CUdevice {
self.id as DriverFFI::CUdevice
}
pub fn load_name(&mut self) -> Self {
self.name =
match Driver::load_device_info(self, DriverFFI::CUdevice_attribute::CU_DEVICE_NAME) {
Ok(result) => Some(result.to_string()),
Err(_) => None,
};
self.clone()
}
pub fn load_device_type(&mut self) -> Self {
self.device_type = Some(HardwareType::GPU);
self.clone()
}
pub fn load_compute_units(&mut self) -> Self {
self.compute_units = match Driver::load_device_info(
self,
DriverFFI::CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT,
) {
Ok(result) => Some(result.to_isize()),
Err(_) => None,
};
self.clone()
}
}
impl IHardware for Device {
fn id(&self) -> isize {
self.id
}
fn name(&self) -> Option<String> {
self.name.clone()
}
fn set_name(&mut self, name: Option<String>) -> Self {
self.name = name;
self.clone()
}
fn hardware_type(&self) -> Option<HardwareType> {
self.device_type
}
fn set_hardware_type(&mut self, hardware_type: Option<HardwareType>) -> Self {
self.device_type = hardware_type;
self.clone()
}
fn compute_units(&self) -> Option<isize> {
self.compute_units
}
fn set_compute_units(&mut self, compute_units: Option<isize>) -> Self {
self.compute_units = compute_units;
self.clone()
}
#[allow(missing_docs)]
fn build(self) -> Device {
Device {
id: self.id(),
name: self.name(),
device_type: self.hardware_type(),
compute_units: self.compute_units(),
}
}
}
impl PartialEq for Device {
fn eq(&self, other: &Self) -> bool {
self.id() == other.id()
}
}
#[derive(Debug, Clone)]
pub struct DeviceInfo {
info: Vec<u8>,
}
impl std::fmt::Display for DeviceInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let msg = match String::from_utf8((*self.info).to_owned()) {
Ok(res) => res,
Err(e) => {
format!("Failed to parse DeviceInfo: {}", e.to_string())
}
};
write!(f, "{}", msg)
}
}
impl DeviceInfo {
pub fn new(info: Vec<u8>) -> DeviceInfo {
DeviceInfo { info }
}
#[allow(missing_docs)]
pub fn to_isize(&self) -> isize {
let mut bytes = Cursor::new(&self.info);
bytes.read_u32::<LittleEndian>().unwrap() as isize
}
}