ironaccelerator_levelzero/
backend.rs1use ironaccelerator_core::{
5 Backend, BackendKind, Capability, CapabilityFlags, ComputeTier, DeviceDescriptor, DeviceId,
6 Result, Vendor,
7};
8
9use crate::drv::{EnumeratedDevice, ZE_DEVICE_TYPE_GPU, ZE_DEVICE_TYPE_VPU};
10
11pub struct LevelZeroBackend;
12pub static LEVELZERO_BACKEND: LevelZeroBackend = LevelZeroBackend;
13
14impl Backend for LevelZeroBackend {
15 fn kind(&self) -> BackendKind {
16 BackendKind::LevelZero
17 }
18
19 fn is_available(&self) -> bool {
20 crate::drv::is_available() && !crate::drv::enumerate().is_empty()
21 }
22
23 fn enumerate(&self) -> Result<Vec<DeviceDescriptor>> {
24 Ok(crate::drv::enumerate().into_iter().map(describe).collect())
25 }
26
27 fn capabilities(&self, device: u32) -> Result<CapabilityFlags> {
28 crate::drv::enumerate()
29 .into_iter()
30 .find(|d| d.ordinal == device)
31 .map(|d| flags_for(&d))
32 .ok_or(ironaccelerator_core::Error::InvalidArgument(
33 "level-zero device ordinal out of range",
34 ))
35 }
36}
37
38fn flags_for(d: &EnumeratedDevice) -> CapabilityFlags {
41 let mut flags = CapabilityFlags::FP32
42 | CapabilityFlags::FP16
43 | CapabilityFlags::BF16
44 | CapabilityFlags::INT8
45 | CapabilityFlags::MULTI_STREAM;
46 if d.type_ == ZE_DEVICE_TYPE_GPU {
47 flags |= CapabilityFlags::WMMA | CapabilityFlags::INT4;
48 }
49 flags
50}
51
52fn describe(d: EnumeratedDevice) -> DeviceDescriptor {
53 let vendor = match d.vendor_id {
54 0x8086 => Vendor::Intel,
55 0x10DE => Vendor::Nvidia,
56 0x1002 => Vendor::Amd,
57 _ => Vendor::Other,
58 };
59
60 let flags = flags_for(&d);
61 let (tier, arch_prefix) = match d.type_ {
62 ZE_DEVICE_TYPE_GPU => (ComputeTier::Consumer, "xe"),
63 ZE_DEVICE_TYPE_VPU => (ComputeTier::Mobile, "vpu"),
64 _ => (ComputeTier::Baseline, "ze"),
65 };
66
67 DeviceDescriptor {
68 id: DeviceId {
69 backend: BackendKind::LevelZero,
70 ordinal: d.ordinal,
71 },
72 vendor,
73 name: d.name,
74 arch: format!("{arch_prefix}-{:04x}", d.device_id),
75 total_memory_bytes: d.max_mem_alloc_size,
76 multiprocessor_count: d
77 .num_slices
78 .saturating_mul(d.num_subslices_per_slice)
79 .saturating_mul(d.num_eus_per_subslice),
80 clock_khz: d.core_clock_khz,
81 capability: Capability {
82 flags,
83 tier,
84 fp16_tflops: None,
85 fp8_tflops: None,
86 mem_bandwidth_gbs: None,
87 },
88 }
89}