use crate::OpDefRegistration;
use crate::{Category, OpDef, Signature, TypedParam};
const OP_DMA_FROM_NVME: &str = "io.dma_from_nvme";
const OP_WRITE_BACK_TO_NVME: &str = "io.write_back_to_nvme";
const OP_ZEROCOPY_MAP: &str = "mem.zerocopy_map";
const OP_UNMAP: &str = "mem.unmap";
const SIG_DMA_FROM_NVME: Signature = Signature {
inputs: &[
TypedParam {
name: "fd",
ty: "i32",
},
TypedParam {
name: "offset",
ty: "u64",
},
TypedParam {
name: "length",
ty: "u64",
},
],
outputs: &[TypedParam {
name: "handle",
ty: "GpuBufferHandle",
}],
attrs: &[],
bytes_extraction: false,
};
const SIG_WRITE_BACK_TO_NVME: Signature = Signature {
inputs: &[
TypedParam {
name: "handle",
ty: "GpuBufferHandle",
},
TypedParam {
name: "fd",
ty: "i32",
},
TypedParam {
name: "offset",
ty: "u64",
},
],
outputs: &[],
attrs: &[],
bytes_extraction: false,
};
const SIG_ZEROCOPY_MAP: Signature = Signature {
inputs: &[TypedParam {
name: "fd",
ty: "i32",
}],
outputs: &[TypedParam {
name: "handle",
ty: "GpuBufferHandle",
}],
attrs: &[],
bytes_extraction: false,
};
const SIG_UNMAP: Signature = Signature {
inputs: &[TypedParam {
name: "handle",
ty: "GpuBufferHandle",
}],
outputs: &[],
attrs: &[],
bytes_extraction: false,
};
inventory::submit! {
OpDefRegistration::new(|| OpDef {
id: OP_DMA_FROM_NVME,
dialect: "io",
category: Category::Intrinsic,
signature: SIG_DMA_FROM_NVME,
lowerings: crate::LoweringTable::empty(),
laws: &[],
compose: None,
})
}
inventory::submit! {
OpDefRegistration::new(|| OpDef {
id: OP_WRITE_BACK_TO_NVME,
dialect: "io",
category: Category::Intrinsic,
signature: SIG_WRITE_BACK_TO_NVME,
lowerings: crate::LoweringTable::empty(),
laws: &[],
compose: None,
})
}
inventory::submit! {
OpDefRegistration::new(|| OpDef {
id: OP_ZEROCOPY_MAP,
dialect: "io",
category: Category::Intrinsic,
signature: SIG_ZEROCOPY_MAP,
lowerings: crate::LoweringTable::empty(),
laws: &[],
compose: None,
})
}
inventory::submit! {
OpDefRegistration::new(|| OpDef {
id: OP_UNMAP,
dialect: "io",
category: Category::Intrinsic,
signature: SIG_UNMAP,
lowerings: crate::LoweringTable::empty(),
laws: &[],
compose: None,
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::registry::{DialectRegistry, Target};
#[test]
fn every_io_op_registers() -> Result<(), String> {
let _lock = crate::registry::registry_test_lock();
DialectRegistry::install(DialectRegistry::from_inventory());
let reg = DialectRegistry::global();
for op in [
OP_DMA_FROM_NVME,
OP_WRITE_BACK_TO_NVME,
OP_ZEROCOPY_MAP,
OP_UNMAP,
] {
let id = reg.intern_op(op);
let def = reg
.lookup(id)
.ok_or_else(|| {
format!(
"Fix: op `{op}` must register via inventory::submit!(OpDefRegistration{{...}}); restore the registration in this dialect."
)
})?;
assert_eq!(def.id, op);
assert_eq!(def.category, Category::Intrinsic);
}
Ok(())
}
#[test]
fn io_ops_have_no_gpu_lowering() {
let _lock = crate::registry::registry_test_lock();
DialectRegistry::install(DialectRegistry::from_inventory());
let reg = DialectRegistry::global();
for op in [
OP_DMA_FROM_NVME,
OP_WRITE_BACK_TO_NVME,
OP_ZEROCOPY_MAP,
OP_UNMAP,
] {
let id = reg.intern_op(op);
assert!(
reg.get_lowering(id, Target::PrimaryText).is_none(),
"{op} must not carry a primary-text lowering until a backend opts in"
);
}
}
#[test]
fn io_ops_use_structured_intrinsic_sentinel_not_custom_cpu_paths() {
let _lock = crate::registry::registry_test_lock();
DialectRegistry::install(DialectRegistry::from_inventory());
let reg = DialectRegistry::global();
for op in [
OP_DMA_FROM_NVME,
OP_WRITE_BACK_TO_NVME,
OP_ZEROCOPY_MAP,
OP_UNMAP,
] {
let id = reg.intern_op(op);
let def = reg.lookup(id).unwrap();
assert!(
vyre_foundation::cpu_op::is_cpu_reference_sentinel(def.lowerings.cpu_ref),
"{op} must not install a custom CPU path; Category C io ops require concrete backend lowering"
);
}
}
#[test]
fn io_dialect_is_distinct_from_stdlib() {
let _lock = crate::registry::registry_test_lock();
DialectRegistry::install(DialectRegistry::from_inventory());
let reg = DialectRegistry::global();
let id = reg.intern_op(OP_DMA_FROM_NVME);
let def = reg.lookup(id).unwrap();
assert_eq!(def.dialect, "io");
}
}