### Example: eltwise_mul.rs using KernelSource::new Source: https://docs.rs/taconite/latest/taconite/compile/struct.KernelSource.html Example from the repository (examples/eltwise_mul.rs) showing how to create a KernelSource with new and pass it to Toolchain::compile_kernel. It also demonstrates compiling a design, loading a kernel, and running it on the NPU. ```rust fn main() -> Result<(), Box> { let args: Vec = std::env::args().skip(1).collect(); let [mlir, source, out] = &args[..] else { return Err("usage: eltwise_mul ".into()); }; let (mlir, out) = (PathBuf::from(mlir), PathBuf::from(out)); let text = std::fs::read_to_string(&mlir)?; let arch = Arch::of_mlir(&text).ok_or("the MLIR names no npu1/npu2 device")?; let n = elements(&text).ok_or("no memref in the runtime sequence")?; let mut tc = Toolchain::from_env()?; if let Some(launcher) = std::env::var_os("IRON_TOOL_LAUNCHER") { tc = tc.with_launcher([launcher]); } let obj = out.join(arch.as_str()).join("mul.o"); let (xclbin, insts) = (out.join("eltwise_mul.xclbin"), out.join("eltwise_mul.insts.bin")); let t = Instant::now(); tc.compile_kernel(&KernelSource::new(source, arch), &obj)?; println!("kernel {} ({:.1} s)", obj.display(), t.elapsed().as_secs_f64()); let t = Instant::now(); tc.compile_design(&Design::new(&mlir, out.join("work")).link(&obj), &xclbin, &insts)?; println!("design {} + {} ({:.1} s)", xclbin.display(), insts.display(), t.elapsed().as_secs_f64()); let session = Session::open(0)?; let kernel = session.load_kernel(&xclbin, &insts, None, n as u64)?; let (mut a, mut b, c) = (session.alloc_of::(n)?, session.alloc_of::(n)?, session.alloc_of::(n)?); // A fixed LCG over [-4, 4): reproducible without a rand dependency. let mut seed = 0x2545_f491u32; let mut next = || { seed = seed.wrapping_mul(1_664_525).wrapping_add(1_013_904_223); f32_to_bf16((seed >> 8) as f32 / (1u32 << 24) as f32 * 8.0 - 4.0) }; a.as_mut_slice::().iter_mut().for_each(|x| *x = next()); b.as_mut_slice::().iter_mut().for_each(|x| *x = next()); a.sync_to_device()?; b.sync_to_device()?; let took = kernel.run(&[&a, &b, &c])?; c.sync_from_device()?; let (a, b, c) = (a.as_slice::(), b.as_slice::(), c.as_slice::()); let mut bad = 0; for i in 0..n { let want = bf16_to_f32(f32_to_bf16(bf16_to_f32(a[i]) * bf16_to_f32(b[i]))); let got = bf16_to_f32(c[i]); if (got - want).abs() > 0.04 * want.abs() + 1e-6 { if bad < 5 { eprintln!("[{i}] {} * {} = {got}, want {want}", bf16_to_f32(a[i]), bf16_to_f32(b[i])); } bad += 1; } } println!("npu {n} elements in {:.3} ms, {bad} mismatches", took.as_secs_f64() * 1e3); if bad > 0 { return Err(format!("{bad} of {n} elements differ from the CPU").into()); } Ok(()) } ``` -------------------------------- ### Run XRT kernel and read result with as_slice (direct_eltwise_mul.rs) Source: https://docs.rs/taconite/latest/taconite/struct.Buffer.html Example from examples/direct_eltwise_mul.rs (line 76) showing how to open a session, load a kernel, run it, sync from device, and use `as_slice::()` to get the result buffer as a slice. ```rust 48fn run_xrt( 49 xclbin: &Path, 50 insts: &Path, 51 a: &[u16], 52 b: &[u16], 53) -> Result<(Vec, Vec), Box> { 54 let n = a.len(); 55 let t = Instant::now(); 56 let session = Session::open(0)?; 57 let opened = t.elapsed(); 58 let t = Instant::now(); 59 let kernel = session.load_kernel(xclbin, insts, None, n as u64)?; 60 let loaded = t.elapsed(); 61 let t = Instant::now(); 62 let (mut ab, mut bb, cb) = (session.alloc_of::(n)?, session.alloc_of::(n)?, session.alloc_of::(n)?); 63 println!( 64 "xrt: open {:.1} ms, load {:.1} ms, 3 buffers {:.1} ms", 65 opened.as_secs_f64() * 1e3, 66 loaded.as_secs_f64() * 1e3, 67 t.elapsed().as_secs_f64() * 1e3 68 ); 69 ab.write(a)?; 70 bb.write(b)?; 71 let mut times = Vec::new(); 72 for _ in 0..RUNS { 73 times.push(kernel.run(&[&ab, &bb, &cb])?); 74 } 75 cb.sync_from_device()?; 76 Ok((cb.as_slice::().to_vec(), times)) 77} ``` -------------------------------- ### sync_from_device example from examples/direct_eltwise_mul.rs Source: https://docs.rs/taconite/latest/taconite/direct/struct.Buffer.html This example shows a complete run_direct function that opens a direct session, loads a kernel, allocates buffers, runs the kernel multiple times, and finally calls cb.sync_from_device() to synchronize the buffer from the device before reading its contents. It prints timing and context information. The sync_from_device call is at line 125. ```rust fn run_direct( xclbin: &Path, insts: &Path, a: &[u16], b: &[u16], ) -> Result<(Vec, Vec), Box> { use taconite::direct::Session; let n = a.len(); let t = Instant::now(); let device = Session::open(0)?; let opened = t.elapsed(); let (cols, rows) = device.array(); println!( "direct: {cols}x{rows} array, AIE {:?}, firmware {:?}, power {:?}", device.aie_version()?, device.firmware_version()?, device.power_mode()? ); let t = Instant::now(); let kernel = device.load_kernel(xclbin, insts, None, n as u64)?; let loaded = t.elapsed(); let t = Instant::now(); let (mut ab, mut bb, cb) = (device.alloc_of::(n)?, device.alloc_of::(n)?, device.alloc_of::(n)?); println!( "direct: open {:.1} ms, load {:.1} ms, 3 buffers {:.1} ms", opened.as_secs_f64() * 1e3, loaded.as_secs_f64() * 1e3, t.elapsed().as_secs_f64() * 1e3 ); ab.write(a)?; bb.write(b)?; let mut times = Vec::new(); for _ in 0..RUNS { match kernel.run(&[&ab, &bb, &cb]) { Ok(t) => times.push(t), Err(e) => { for c in device.contexts().unwrap_or_default() { eprintln!(" {c:?}"); } return Err(e.into()); } } } for c in device.contexts()? { println!("direct: context {c:?}"); } cb.sync_from_device()?; Ok((cb.as_slice::().to_vec(), times)) } ``` -------------------------------- ### Example: eltwise_mul.rs using Toolchain::from_env() Source: https://docs.rs/taconite/latest/taconite/compile/struct.Toolchain.html This example from the repository demonstrates using Toolchain::from_env() to compile a kernel and design, then run it on an NPU. It shows how to optionally set a launcher via IRON_TOOL_LAUNCHER, compile with compile_kernel and compile_design, and verify results against a CPU computation. The code includes a fixed LCG for reproducible random data and checks for mismatches. ```rust 25fn main() -> Result<(), Box> { 26 let args: Vec = std::env::args().skip(1).collect(); 27 let [mlir, source, out] = &args[..] else { 28 return Err("usage: eltwise_mul ".into()); 29 }; 30 let (mlir, out) = (PathBuf::from(mlir), PathBuf::from(out)); 31 let text = std::fs::read_to_string(&mlir)?; 32 let arch = Arch::of_mlir(&text).ok_or("the MLIR names no npu1/npu2 device")?; 33 let n = elements(&text).ok_or("no memref in the runtime sequence")?; 34 35 let mut tc = Toolchain::from_env()?; 36 if let Some(launcher) = std::env::var_os("IRON_TOOL_LAUNCHER") { 37 tc = tc.with_launcher([launcher]); 38 } 39 let obj = out.join(arch.as_str()).join("mul.o"); 40 let (xclbin, insts) = (out.join("eltwise_mul.xclbin"), out.join("eltwise_mul.insts.bin")); 41 42 let t = Instant::now(); 43 tc.compile_kernel(&KernelSource::new(source, arch), &obj)?; 44 println!("kernel {} ({:.1} s)", obj.display(), t.elapsed().as_secs_f64()); 45 let t = Instant::now(); 46 tc.compile_design(&Design::new(&mlir, out.join("work")).link(&obj), &xclbin, &insts)?; 47 println!("design {} + {} ({:.1} s)", xclbin.display(), insts.display(), t.elapsed().as_secs_f64()); 48 49 let session = Session::open(0)?; 50 let kernel = session.load_kernel(&xclbin, &insts, None, n as u64)?; 51 let (mut a, mut b, c) = (session.alloc_of::(n)?, session.alloc_of::(n)?, session.alloc_of::(n)?); 52 // A fixed LCG over [-4, 4): reproducible without a rand dependency. 53 let mut seed = 0x2545_f491u32; 54 let mut next = || { 55 seed = seed.wrapping_mul(1_664_525).wrapping_add(1_013_904_223); 56 f32_to_bf16((seed >> 8) as f32 / (1u32 << 24) as f32 * 8.0 - 4.0) 57 }; 58 a.as_mut_slice::().iter_mut().for_each(|x| *x = next()); 59 b.as_mut_slice::().iter_mut().for_each(|x| *x = next()); 60 a.sync_to_device()?; 61 b.sync_to_device()?; 62 let took = kernel.run(&[&a, &b, &c])?; 63 c.sync_from_device()?; 64 65 let (a, b, c) = (a.as_slice::(), b.as_slice::(), c.as_slice::()); 66 let mut bad = 0; 67 for i in 0..n { 68 let want = bf16_to_f32(f32_to_bf16(bf16_to_f32(a[i]) * bf16_to_f32(b[i]))); 69 let got = bf16_to_f32(c[i]); 70 if (got - want).abs() > 0.04 * want.abs() + 1e-6 { 71 if bad < 5 { 72 eprintln!("[{i}] {} * {} = {got}, want {want}", bf16_to_f32(a[i]), bf16_to_f32(b[i])); 73 } 74 bad += 1; 75 } 76 } 77 println!("npu {n} elements in {:.3} ms, {bad} mismatches", took.as_secs_f64() * 1e3); 78 if bad > 0 { 79 return Err(format!("{bad} of {n} elements differ from the CPU").into()); 80 } 81 Ok(()) 82} ``` -------------------------------- ### Toolchain::with_peano Source: https://docs.rs/taconite/latest/taconite/compile/struct.Toolchain.html Sets the Peano install directory to use. The directory should contain the `bin/clang++` executable. ```APIDOC ## Toolchain::with_peano ### Description Sets the Peano install directory to use. The directory should contain the `bin/clang++` executable. ### Method `pub fn with_peano(self, peano: impl Into) -> Self` ### Parameters - **peano** (impl Into) - Required - Path to the Peano install directory. ### Returns - `Self` - The Toolchain with the updated Peano path. ### Example ```rust let tc = Toolchain::from_env()?.with_peano("/path/to/peano"); ``` ``` -------------------------------- ### Vk::record Source: https://docs.rs/taconite/latest/taconite/gpu/struct.Vk.html Starts recording a GPU plan, returning a Recorder that can be used to build the plan. ```APIDOC ## Vk::record ### Description Starts recording a GPU plan, returning a Recorder that can be used to build the plan. ### Method pub fn record(&mut self) -> Result, Error> ### Parameters None ### Returns - **Result, Error>** - A Recorder for building the plan or an error. ``` -------------------------------- ### Run direct eltwise mul and read buffer as slice Source: https://docs.rs/taconite/latest/taconite/direct/struct.Buffer.html Example from examples/direct_eltwise_mul.rs showing how to open a device, load a kernel, allocate buffers, run the kernel, sync from device, and read the result as a slice using as_slice::(). ```rust 79fn run_direct( 80 xclbin: &Path, 81 insts: &Path, 82 a: &[u16], 83 b: &[u16], 84) -> Result<(Vec, Vec), Box> { 85 use taconite::direct::Session; 86 let n = a.len(); 87 let t = Instant::now(); 88 let device = Session::open(0)?; 89 let opened = t.elapsed(); 90 let (cols, rows) = device.array(); 91 println!( 92 "direct: {cols}x{rows} array, AIE {:?}, firmware {:?}, power {:?}", 93 device.aie_version()?, 94 device.firmware_version()?, 95 device.power_mode()? 96 ); 97 let t = Instant::now(); 98 let kernel = device.load_kernel(xclbin, insts, None, n as u64)?; 99 let loaded = t.elapsed(); 100 let t = Instant::now(); 101 let (mut ab, mut bb, cb) = (device.alloc_of::(n)?, device.alloc_of::(n)?, device.alloc_of::(n)?); 102 println!( 103 "direct: open {:.1} ms, load {:.1} ms, 3 buffers {:.1} ms", 104 opened.as_secs_f64() * 1e3, 105 loaded.as_secs_f64() * 1e3, 106 t.elapsed().as_secs_f64() * 1e3 107 ); 108 ab.write(a)?; 109 bb.write(b)?; 110 let mut times = Vec::new(); 111 for _ in 0..RUNS { 112 match kernel.run(&[&ab, &bb, &cb]) { 113 Ok(t) => times.push(t), 114 Err(e) => { 115 for c in device.contexts().unwrap_or_default() { 116 eprintln!(" {c:?}"); 117 } 118 return Err(e.into()); 119 } 120 } 121 } 122 for c in device.contexts()? { 123 println!("direct: context {c:?}"); 124 } 125 cb.sync_from_device()?; 126 Ok((cb.as_slice::().to_vec(), times)) 127} ``` -------------------------------- ### View::write Source: https://docs.rs/taconite/latest/taconite/gpu/struct.View.html Writes the given data at the start of the view. Only works with host-visible memory. ```APIDOC ## View::write ### Description Writes the given data at the start of the view. Only works with host-visible memory. ### Method `pub fn write(&self, data: &[T])` ### Parameters - `data` (&[T]) - Required - The data to write. `T` must implement `Copy`. ### Returns - `()` - No return value. ``` -------------------------------- ### sync_from_device in direct_eltwise_mul.rs Source: https://docs.rs/taconite/latest/taconite/struct.Buffer.html Example from `examples/direct_eltwise_mul.rs` (line 75) showing `cb.sync_from_device()?` after a kernel run, then reading the result via `as_slice::()`. ```rust fn run_xrt( xclbin: &Path, insts: &Path, a: &[u16], b: &[u16], ) -> Result<(Vec, Vec), Box> { let n = a.len(); let t = Instant::now(); let session = Session::open(0)?; let opened = t.elapsed(); let t = Instant::now(); let kernel = session.load_kernel(xclbin, insts, None, n as u64)?; let loaded = t.elapsed(); let t = Instant::now(); let (mut ab, mut bb, cb) = (session.alloc_of::(n)?, session.alloc_of::(n)?, session.alloc_of::(n)?); println!( "xrt: open {:.1} ms, load {:.1} ms, 3 buffers {:.1} ms", opened.as_secs_f64() * 1e3, loaded.as_secs_f64() * 1e3, t.elapsed().as_secs_f64() * 1e3 ); ab.write(a)?; bb.write(b)?; let mut times = Vec::new(); for _ in 0..RUNS { times.push(kernel.run(&[&ab, &bb, &cb])?); } cb.sync_from_device()?; Ok((cb.as_slice::().to_vec(), times)) } ``` -------------------------------- ### Toolchain::new Source: https://docs.rs/taconite/latest/taconite/compile/struct.Toolchain.html Creates a new Toolchain from the path to an mlir-aie install. The Peano compiler is located automatically via environment variables or standard locations. ```APIDOC ## Toolchain::new ### Description Creates a new Toolchain from the path to an mlir-aie install. The Peano compiler is located automatically via environment variables or standard locations. ### Method new ### Signature pub fn new(mlir_aie: impl Into) -> Self ### Parameters - **mlir_aie** (impl Into) - Required - The path to the mlir-aie install directory (the `mlir_aie` directory of the pip wheel, or `$MLIR_AIE_INSTALL_DIR`). ### Behavior Peano is looked for where mlir-aie itself looks: `$PEANO_INSTALL_DIR`, then `/peano`, then the `llvm-aie` wheel beside it. ### Returns A new Toolchain instance. ``` -------------------------------- ### pub fn threads() -> usize Source: https://docs.rs/taconite/latest/taconite/cpu/fn.threads.html Returns the number of host threads to use. The default is the machine's thread count, capped at 16. The value is fixed once the pool has started. ```APIDOC ## pub fn threads() -> usize ### Description Returns the number of host threads to use. The default is the machine's thread count, capped at 16. The value is fixed once the pool has started. ### Function Signature ```rust pub fn threads() -> usize ``` ### Parameters None. ### Return Value - **usize** - The number of host threads to use. ### Notes - Defaults to the machine's thread count, up to 16. - The value is fixed once the pool has started. ``` -------------------------------- ### Recorder::copy Source: https://docs.rs/taconite/latest/taconite/gpu/struct.Recorder.html Copies the contents of a source view to the start of a destination view. ```APIDOC ## Recorder::copy ### Description Copies `src` over the start of `dst`. ### Method `pub fn copy(&mut self, src: View, dst: View)` ### Parameters - `src` (View) - Required - The source view to copy from. - `dst` (View) - Required - The destination view to copy to. ### Returns `()` ``` -------------------------------- ### Session::open_path Source: https://docs.rs/taconite/latest/taconite/direct/struct.Session.html Opens the accel node at the given path and sets up the device heap. Returns a Result with the Session or an Error. ```APIDOC ## Session::open_path ### Description Opens the accel node at the given path and sets up the device heap. Returns a `Result` with the `Session` or an `Error`. ### Method `pub fn open_path(path: &Path) -> Result` ### Parameters - `path` (&Path) - Required - The path to the accel node. ### Returns - `Result` - The opened `Session` or an `Error`. ``` -------------------------------- ### Regex::is_match_at_start Source: https://docs.rs/taconite/latest/taconite/pyre/struct.Regex.html Checks if the text matches the pattern from the start, equivalent to Python's re.match. ```APIDOC ## Regex::is_match_at_start ### Description Checks if the text matches the pattern from the start, equivalent to Python's re.match. ### Method `pub fn is_match_at_start(&self, text: &str) -> bool` ### Parameters - `text` (&str) - Required - The text to match from the start. ### Returns - `bool` - True if the text matches from the start, false otherwise. ### Example ```rust let regex = Regex::new(r"\d+", Flags::default())?; let is_match = regex.is_match_at_start("123abc"); ``` ``` -------------------------------- ### Kernel::start Source: https://docs.rs/taconite/latest/taconite/direct/struct.Kernel.html Launches the kernel without waiting. The returned Run borrows the argument buffers until Run::wait is called. ```APIDOC ## Kernel::start ### Description Launches the kernel without waiting. The returned `Run` borrows the argument buffers until `Run::wait` is called. ### Method `pub fn start<'a>(&'a self, args: &[&'a Buffer]) -> Result, Error>` ### Parameters - **args** (`&[&Buffer]`) - Required - The argument buffers for the kernel. ### Returns - `Result, Error>` - A `Run` handle that borrows the argument buffers, or an `Error` if the launch fails. ### Example ```rust let kernel = Kernel::new(...); let buffers = vec![buffer1, buffer2]; let run = kernel.start(&buffers)?; ``` ``` -------------------------------- ### View::read Source: https://docs.rs/taconite/latest/taconite/gpu/struct.View.html Reads `n` elements of type `T` from the start of the view. Only works with host-visible memory. ```APIDOC ## View::read ### Description Reads `n` elements of type `T` from the start of the view. Only works with host-visible memory. ### Method `pub fn read(&self, n: usize) -> Vec` ### Parameters - `n` (usize) - Required - The number of elements to read. ### Returns - `Vec` - A vector containing the read elements. `T` must implement `Copy` and `Default`. ``` -------------------------------- ### Session::open Source: https://docs.rs/taconite/latest/taconite/direct/struct.Session.html Opens the NPU device at /dev/accel/accel (0 on a laptop). Returns a Result with the Session or an Error. ```APIDOC ## Session::open ### Description Opens the NPU device at `/dev/accel/accel` (0 on a laptop). Returns a `Result` with the `Session` or an `Error`. ### Method `pub fn open(device_index: u32) -> Result` ### Parameters - `device_index` (u32) - Required - The device index to open. ### Returns - `Result` - The opened `Session` or an `Error`. ### Example ```rust let device = Session::open(0)?; ``` ``` -------------------------------- ### run Source: https://docs.rs/taconite/latest/taconite/direct/struct.Kernel.html Launches the kernel over the given buffer arguments and waits for it, returning the time from submission to completion. Inputs must have been synced to device, outputs need sync from device before reading. ```APIDOC ## run ### Description Launches the kernel over `args` (its buffer arguments in order, at most `MAX_ARGS`) and waits for it; returns the time from submission to completion. Inputs must have been `sync_to_device`d, outputs need `sync_from_device` before reading. ### Method `pub fn run(&self, args: &[&Buffer]) -> Result` ### Parameters - **args** (`&[&Buffer]`) - Required - A slice of references to `Buffer` objects representing the kernel's arguments in order. At most `MAX_ARGS` arguments are allowed. ### Return Value - `Result` - On success, the duration from submission to completion. On failure, an `Error`. ``` -------------------------------- ### View::at Source: https://docs.rs/taconite/latest/taconite/gpu/struct.View.html Returns a new View representing `bytes` bytes starting at offset `off` (which must be a multiple of 256). ```APIDOC ## View::at ### Description Returns a new View representing `bytes` bytes starting at offset `off` (which must be a multiple of 256). ### Method `pub fn at(&self, off: u64, bytes: u64) -> View` ### Parameters - `off` (u64) - Required - The offset in bytes, must be a multiple of 256. - `bytes` (u64) - Required - The number of bytes to include in the new view. ### Returns - `View` - A new View representing the specified range. ``` -------------------------------- ### pub fn npu_total(&self) -> Duration Source: https://docs.rs/taconite/latest/taconite/struct.Timing.html Returns the total NPU dispatch time, summing all entries under keys starting with 'npu:'. ```APIDOC ## pub fn npu_total(&self) -> Duration ### Description Returns the total NPU dispatch time, summing all entries under keys starting with 'npu:'. ### Method npu_total ### Parameters None ### Returns - **Duration** - The total NPU dispatch time. ``` -------------------------------- ### pub fn load_kernel(&self, xclbin: &[Path], insts: &[Path], kernel_name: Option<&str>, ops_per_run: u64) -> Result Source: https://docs.rs/taconite/latest/taconite/struct.Session.html Loads an xclbin and instruction stream, returning a Kernel. Kernels sharing the same xclbin and kernel name share a hardware context. The ops_per_run parameter declares the work per Kernel::run for QoS reporting. ```APIDOC ## pub fn load_kernel(&self, xclbin: &[Path], insts: &[Path], kernel_name: Option<&str>, ops_per_run: u64) -> Result ### Description Loads an xclbin + instruction stream. Kernels naming the same xclbin (and kernel name) share one hardware context, resident until the last of them is dropped – dropping them frees the context for another (NPU2 holds 16, across every process). `kernel_name` is the kernel inside the xclbin (`None`: its first — IRON’s is `MLIR_AIE`). `ops_per_run` is the work one `Kernel::run` performs — `2·M·K·N` for a GEMM, a multiply-add counting two — declared to the driver as the context’s QoS `gops` (rounded to whole GOP, the field’s unit; a kernel under half a GOP declares nothing). It is how `xrt-smi` and the desktop’s NPU ACTIVITY card turn the context’s completion count into operations per second; see `iron_xrt_shim.h` for why it can’t change how the context is scheduled. ### Method load_kernel ### Signature pub fn load_kernel(&self, xclbin: &[Path], insts: &[Path], kernel_name: Option<&str>, ops_per_run: u64) -> Result ### Parameters - **xclbin** (&[Path]) - Required - Path to the xclbin file. - **insts** (&[Path]) - Required - Path to the instruction stream. - **kernel_name** (Option<&str>) - Optional - Name of the kernel inside the xclbin. `None` selects the first kernel. - **ops_per_run** (u64) - Required - Work performed per `Kernel::run`, used for QoS reporting. ### Returns - **Result** - A `Kernel` handle on success, or an `Error` on failure. ``` -------------------------------- ### pub fn get(&self, key: &str) -> Duration Source: https://docs.rs/taconite/latest/taconite/struct.Timing.html Retrieves the duration associated with the given key. Returns a core::time::Duration. ```APIDOC ## pub fn get(&self, key: &str) -> Duration ### Description Retrieves the duration associated with the given key. ### Method get ### Parameters - **key** (&str) - Required - The key identifying the timing stage. ### Returns - **Duration** - The duration associated with the key. ``` -------------------------------- ### Toolchain::from_env Source: https://docs.rs/taconite/latest/taconite/compile/struct.Toolchain.html Creates a new Toolchain from environment variables. It uses the $MLIR_AIE_INSTALL_DIR environment variable (exported by mlir-aie's env_setup.sh) and optionally $AIECC_PATH to name the aiecc binary. ```APIDOC ## Toolchain::from_env ### Description Creates a new Toolchain from environment variables. It uses the `$MLIR_AIE_INSTALL_DIR` environment variable (exported by mlir-aie's `env_setup.sh`) and optionally `$AIECC_PATH` to name the aiecc binary. ### Method `pub fn from_env() -> Result` ### Parameters None. ### Returns - `Result` - A Result containing the new Toolchain or an Error. ### Example ```rust let mut tc = Toolchain::from_env()?; ``` ``` -------------------------------- ### Recorder::cut Source: https://docs.rs/taconite/latest/taconite/gpu/struct.Recorder.html Ends the plan recorded so far and starts a new one, allowing the new plan to see everything written by the previous plan. ```APIDOC ## Recorder::cut ### Description Ends the plan recorded so far and goes on recording a new one: submitted after it, the new one sees everything it wrote. ### Method `pub fn cut(&mut self) -> Result` ### Parameters None. ### Returns `Result` ``` -------------------------------- ### Plan::submit Source: https://docs.rs/taconite/latest/taconite/gpu/index.html Submits the recorded command buffer for execution without waiting for completion. ```APIDOC ## Plan::submit ### Description Submits the recorded command buffer for execution without waiting for completion. ### Method submit ### Parameters - None explicitly documented. ### Returns - **Result** (type not specified) - Indicates success or failure. ``` -------------------------------- ### Plan::run Source: https://docs.rs/taconite/latest/taconite/gpu/index.html Replays a recorded chain of dispatches by submitting the command buffer and waiting for completion. ```APIDOC ## Plan::run ### Description Replays a recorded chain of dispatches by submitting the command buffer and waiting for completion. ### Method run ### Parameters - None explicitly documented. ### Returns - **Result** (type not specified) - Indicates success or failure. ``` -------------------------------- ### direct_eltwise_mul main function Source: https://docs.rs/taconite/latest/taconite/fn.f32_to_bf16.html Parses command-line arguments (mode, xclbin, insts.bin, elements), generates inputs, runs the kernel via run_xrt or run_direct, and reports mismatches against CPU results. ```rust fn main() -> Result<(), Box> { let args: Vec = std::env::args().skip(1).collect(); let [mode, xclbin, insts, n] = &args[..] else { return Err("usage: direct_eltwise_mul ".into()); }; let (xclbin, insts, n) = (Path::new(xclbin), Path::new(insts), n.parse::()?); let (a, b) = (inputs(n, 0x2545_f491), inputs(n, 0x9e37_79b9)); let t = Instant::now(); let (c, times) = match mode.as_str() { "xrt" => run_xrt(xclbin, insts, &a, &b)?, "direct" => run_direct(xclbin, insts, &a, &b)?, other => return Err(format!("unknown mode {other}").into()), }; println!("{mode}: setup+runs {:.1} ms", t.elapsed().as_secs_f64() * 1e3); report(×); let bad = (0..n) .filter(|&i| { let want = bf16_to_f32(f32_to_bf16(bf16_to_f32(a[i]) * bf16_to_f32(b[i]))); (bf16_to_f32(c[i]) - want).abs() > 0.04 * want.abs() + 1e-6 }) .count(); println!("{n} elements, {bad} mismatches"); if bad > 0 { return Err(format!("{bad} of {n} elements differ from the CPU").into()); } Ok(()) } ``` -------------------------------- ### lower_simple(c: char) -> char Source: https://docs.rs/taconite/latest/taconite/unicode/fn.lower_simple.html Returns the simple (one-character) lowercase mapping of the given character, as used by Python's `re` module for case folding. For example, U+0130 (İ) maps to `i`. ```APIDOC ## lower_simple(c: char) -> char ### Description Returns the simple (one-character) lowercase mapping of the given character, as used by Python's `re` module for case folding. For example, U+0130 (İ) maps to `i`. ### Function Signature `pub fn lower_simple(c: char) -> char` ### Parameters - **c** (char) - The input character to map to its lowercase equivalent. ### Return Value - **char** - The simple lowercase mapping of the input character. ### Example ```rust let result = lower_simple('İ'); assert_eq!(result, 'i'); ``` ``` -------------------------------- ### Plan::run Source: https://docs.rs/taconite/latest/taconite/gpu/struct.Plan.html Submits the plan and waits for it to complete. Inputs must be written before calling, and outputs are readable after it returns. ```APIDOC ## Plan::run ### Description Submits the plan and waits for it to complete. Inputs must be written before calling, and outputs are readable after it returns. ### Method run ### Signature pub fn run(&self, vk: &Vk) -> Result ### Parameters - **vk** (&Vk) - Required - Reference to the Vulkan context. ### Returns - **Result** - Duration of the run on success, or an Error on failure. ``` -------------------------------- ### Session::load_kernel Source: https://docs.rs/taconite/latest/taconite/direct/struct.Session.html Loads an xclbin and instruction stream, creating a Kernel that shares a hardware context with other kernels using the same xclbin and kernel name. The context runs the xclbin's PDI, and ops_per_run is declared as QoS gops. ```APIDOC ## Session::load_kernel ### Description Loads an xclbin + instruction stream, as `crate::Session::load_kernel` does: kernels naming the same xclbin (and kernel name) share one hardware context, resident until the last of them is dropped. The context runs the xclbin's one PDI whatever `kernel_name` says; the name only tells contexts apart. `ops_per_run` is declared to the driver as the context's QoS `gops`. ### Method `pub fn load_kernel(&self, xclbin: &Path, insts: &Path, kernel_name: Option<&str>, ops_per_run: u64) -> Result` ### Parameters - `xclbin` (`&Path`) - Required - Path to the xclbin file. - `insts` (`&Path`) - Required - Path to the instruction stream file. - `kernel_name` (`Option<&str>`) - Optional - Name to distinguish contexts; the actual kernel is determined by the xclbin's PDI. - `ops_per_run` (`u64`) - Required - Declared QoS gops for the context. ### Returns - `Result` - A `Kernel` handle on success, or an `Error` on failure. ### Example ```rust let kernel = device.load_kernel(xclbin, insts, None, n as u64)?; ``` ``` -------------------------------- ### Buffer::sub Source: https://docs.rs/taconite/latest/taconite/direct/struct.Buffer.html Creates a view of a portion of the buffer, starting at an offset and spanning a specified number of bytes. The returned Buffer is a kernel argument with syncs covering only its bytes, and it keeps the allocation alive. ```APIDOC ## Buffer::sub ### Description Creates a view of `bytes` bytes of this buffer from `offset`, a `Buffer` in its own right: a kernel argument (the NPU is handed its address) with syncs that cover its bytes only. It keeps the allocation alive itself, as `crate::Buffer::sub`’s does. ### Method sub ### Signature pub fn sub(&self, offset: usize, bytes: usize) -> Result ### Parameters - **offset** (usize) - Required - The byte offset into the buffer where the sub-buffer starts. - **bytes** (usize) - Required - The number of bytes the sub-buffer spans. ### Returns - **Result** - A `Buffer` representing the sub-buffer, or an `Error` if the parameters are invalid. ``` -------------------------------- ### category(c: char) -> &'static str Source: https://docs.rs/taconite/latest/taconite/unicode/fn.category.html Returns the Unicode general category of the given character as a static string. For example, 'Lu' for uppercase letter, 'Nd' for decimal digit, and 'Cn' if the character is unassigned. ```APIDOC ## category(c: char) -> &'static str ### Description Returns the Unicode general category of the given character as a static string. For example, 'Lu' for uppercase letter, 'Nd' for decimal digit, and 'Cn' if the character is unassigned. ### Function Signature pub fn category(c: char) -> &'static str ### Parameters - **c** (char) - Required - The character to query. ### Return Value - **&'static str** - The Unicode general category of the character (e.g., "Lu", "Nd", "Cn"). ### Example ```rust let cat = taconite::unicode::category('A'); assert_eq!(cat, "Lu"); ``` ``` -------------------------------- ### Vk::new Source: https://docs.rs/taconite/latest/taconite/gpu/struct.Vk.html Creates a new Vk instance using the first non-CPU GPU device (e.g., not llvmpipe) if a Vulkan loader and such a device are available. ```APIDOC ## Vk::new ### Description Creates a new Vk instance using the first non-CPU GPU device (e.g., not llvmpipe) if a Vulkan loader and such a device are available. ### Method pub fn new() -> Result ### Parameters None ### Returns - **Result** - The new Vk instance or an error if no suitable GPU is found. ``` -------------------------------- ### CloneToUninit::clone_to_uninit Source: https://docs.rs/taconite/latest/taconite/gpu/struct.View.html Performs copy-assignment from self to dest. This is a nightly-only experimental API. ```APIDOC ## CloneToUninit::clone_to_uninit ### Description Performs copy-assignment from `self` to `dest`. This is a nightly-only experimental API. ### Method unsafe fn clone_to_uninit(&self, dest: *mut u8) ### Parameters - `dest` (*mut u8) - Required - Destination pointer for the copy. ### Notes - This method is part of the `CloneToUninit` trait, which is nightly-only experimental. ``` -------------------------------- ### pub fn take(&mut self, bytes: u64) -> Result Source: https://docs.rs/taconite/latest/taconite/gpu/struct.Arena.html Takes a view of the specified number of bytes from the arena. Returns a Result containing a View on success or an Error on failure. ```APIDOC ## pub fn take(&mut self, bytes: u64) -> Result ### Description Takes a view of the specified number of bytes from the arena. Returns a Result containing a View on success or an Error on failure. ### Method pub fn take ### Parameters - **bytes** (u64) - Required - The number of bytes to allocate for the view. ### Return - **Result** - A View on success, or an Error on failure. ### Example ```rust let view = arena.take(1024)?; ``` ``` -------------------------------- ### Toolchain::with_launcher Source: https://docs.rs/taconite/latest/taconite/compile/struct.Toolchain.html Sets a launcher for all tools invoked by the Toolchain. The launcher is prepended to the tool command, allowing execution through a script or container. ```APIDOC ## Toolchain::with_launcher ### Description Runs every tool as `launcher… tool args…`, e.g. through a script that execs its arguments inside a container. This is useful on hosts that cannot run the binaries directly, such as NixOS. ### Method `pub fn with_launcher(self, launcher: I) -> Self` ### Parameters - **launcher** (I) - Required - An iterator of items that can be converted into `OsString`, representing the launcher command and its arguments. ### Returns - **Self** - The updated `Toolchain` instance. ### Example ```rust let mut tc = Toolchain::from_env()?; if let Some(launcher) = std::env::var_os("IRON_TOOL_LAUNCHER") { tc = tc.with_launcher([launcher]); } ``` ``` -------------------------------- ### Toolchain::peano Source: https://docs.rs/taconite/latest/taconite/compile/struct.Toolchain.html Returns the path to the peano tool. ```APIDOC ## Toolchain::peano ### Description Returns the path to the peano tool. ### Method `pub fn peano(&self) -> &Path` ### Returns - **&Path** - The path to the peano executable. ``` -------------------------------- ### KernelSource::new Source: https://docs.rs/taconite/latest/taconite/compile/struct.KernelSource.html Creates a new KernelSource instance with the given source path and architecture. This is used to specify the kernel source for compilation. ```APIDOC ## KernelSource::new ### Description Creates a new `KernelSource` instance with the given source path and architecture. This is used to specify the kernel source for compilation. ### Method `pub fn new(source: impl Into, arch: Arch) -> Self` ### Parameters - **source** (impl Into) - Required - The path to the kernel source file. - **arch** (Arch) - Required - The target architecture for the kernel. ### Returns - **Self** - A new `KernelSource` instance. ### Example ```rust let kernel_source = KernelSource::new("kernel.cc", Arch::Npu1); ``` ``` -------------------------------- ### include Source: https://docs.rs/taconite/latest/taconite/compile/struct.KernelSource.html Adds an include directory to the compiler invocation using the -I flag. ```APIDOC ## include ### Description Adds an include directory to the compiler invocation using the `-I` flag. ### Method `pub fn include(self, dir: impl Into) -> Self` ### Parameters - **dir** (PathBuf) - Required - The directory to add as an include path. ### Returns - **Self** - The updated `KernelSource` instance for chaining. ```