1use crate::{Error, Result, execution::KernelContract};
4use std::sync::Arc;
5
6#[derive(Clone)]
8pub struct NpuKernel {
9 pub(crate) inner: Arc<KernelInner>,
10}
11pub(crate) struct KernelInner {
12 pub device: crate::fabric::Device,
13 pub artifact: crate::loom::Artifact,
14 pub columns: u16,
15 pub contract: KernelContract,
16 _reservation: Option<crate::residency::MemoryReservation>,
17}
18impl NpuKernel {
19 pub(crate) unsafe fn load(
20 device: crate::fabric::Device,
21 artifact: &crate::loom::Artifact,
22 columns: u16,
23 contract: KernelContract,
24 budget: Option<&crate::residency::MemoryBudget>,
25 ) -> Result<Self> {
26 contract.validate()?;
27 if device.endpoint().engine() != crate::fabric::Engine::Xdna
28 || artifact.target() != device.target().as_str()
29 || !(1..=8).contains(&columns)
30 || !contract.constants.is_empty()
31 {
32 return Err(Error::Unsupported(
33 "XDNA requires an exact device profile, 1..=8 columns, and buffer-only bindings"
34 .into(),
35 ));
36 }
37 let reservation = budget
38 .map(|budget| budget.reserve(artifact.bytes().len()))
39 .transpose()?;
40 Ok(Self {
41 inner: Arc::new(KernelInner {
42 device,
43 artifact: artifact.clone(),
44 columns,
45 contract,
46 _reservation: reservation,
47 }),
48 })
49 }
50 pub fn contract(&self) -> &KernelContract {
52 &self.inner.contract
53 }
54 pub fn artifact(&self) -> &crate::loom::Artifact {
56 &self.inner.artifact
57 }
58}