shared_roundtrip/
shared_roundtrip.rs1use 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 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}