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