Skip to main content

shared_roundtrip/
shared_roundtrip.rs

1//! Execute GPU fill -> NPU passthrough -> GPU copy on one imported allocation.
2//! Usage: shared_roundtrip <passthrough.xclbin> <instructions.bin> <bytes>
3//! The supplied design must use the MLIR_AIE ABI (A, unused B, C), copying A to C.
4use hrx::{
5    Result,
6    execution::{Access, BindingContract, KernelContract, MemoryPlacement, Runtime},
7};
8fn main() -> Result<()> {
9    let args: Vec<_> = std::env::args().collect();
10    if args.len() != 4 {
11        return Err(hrx::Error::Message(
12            "usage: shared_roundtrip <passthrough.xclbin> <instructions.bin> <bytes>".into(),
13        ));
14    }
15    let bytes = args[3]
16        .parse::<usize>()
17        .map_err(|e| hrx::Error::Message(e.to_string()))?;
18    let runtime = Runtime::new()?;
19    // This example accepts trusted local artifacts with the documented ABI.
20    let program = unsafe { runtime.npu(0)?.load_program(&args[1]) }?;
21    let binding = |bytes, access| BindingContract {
22        bytes,
23        access,
24        alignment: 4,
25        layout: "u32 passthrough".into(),
26    };
27    let contract = KernelContract {
28        bindings: vec![
29            binding(bytes, Access::Read),
30            binding(4096, Access::Read),
31            binding(bytes, Access::Write),
32        ],
33        constants: vec![],
34    };
35    let kernel = unsafe { program.kernel(&std::fs::read(&args[2])?, contract) }?;
36    let a = runtime.allocate(bytes, MemoryPlacement::Shared(program.clone()))?;
37    let b = runtime.allocate(4096, MemoryPlacement::Shared(program.clone()))?;
38    let c = runtime.allocate(bytes, MemoryPlacement::Shared(program.clone()))?;
39    let result = runtime.allocate(bytes, MemoryPlacement::Shared(program.clone()))?;
40    let mut graph = runtime.graph();
41    graph.fill(a.view(), 0x5a)?;
42    graph.npu(&kernel, &[a.view(), b.view(), c.view()])?;
43    graph.copy(result.view(), c.view())?;
44    let graph = graph.prepare()?;
45    for _ in 0..10 {
46        graph.submit()?.wait()?;
47        let mapped = result.map_read()?;
48        if mapped.iter().any(|&b| b != 0x5a) {
49            return Err(hrx::Error::Message("GPU/NPU roundtrip mismatch".into()));
50        }
51    }
52    println!(
53        "GPU -> NPU -> GPU: all {bytes} bytes correct, 10 executions, {} prepared regions",
54        graph.regions()
55    );
56    Ok(())
57}