et-abi 0.4.0

Shared host/device ABI types (kernel launch arguments) for et-rs / ET-SoC-1
Documentation

et-abi

Shared host/device ABI types for the Esperanto ET-SoC-1, used by the et-rs host driver and the et-k-rs device-side kernel library.

A kernel launch passes its arguments by pointer: the host stages an argument struct in device memory and the firmware delivers its address to the kernel (in register a0). This crate defines those argument structs once, so the host launcher and the device kernel cannot drift on field order, sizes, or padding.

Because both the host (x86-64) and the device (RV64) are little-endian, the in-memory #[repr(C)] layout is the wire layout: the host takes the struct's bytes with [DeviceArgs::as_bytes] and the kernel reinterprets the pointer with [DeviceArgs::from_ptr]. No serialisation step is involved.

The crate is no_std with no dependencies, so it builds for the host and for the riscv64imac-unknown-none-elf device target alike.

use et_abi::{DeviceArgs, ReduceArgs};

// Host: build the args the kernel will read.
let args = ReduceArgs { input: 0x8005_0000, out: 0x8006_0000, n: 1024, n_harts: 64 };
let bytes: &[u8] = args.as_bytes();

// Device: recover them from the pointer the firmware passed in a0.
// let args = unsafe { ReduceArgs::from_ptr(a0 as *const u8) };

It also holds the architectural constants both sides must agree on: CACHE_LINE (the per-hart output stride, so host padding and device writes match and avoid false sharing), HARTS_PER_SHIRE, and HARTS_PER_NEIGHBOURHOOD.

Tensor-extension ABI

The sGEMM kernel and its host launcher share GemmArgs, a second argument struct for single-precision GEMM:

use et_abi::{DeviceArgs, GemmArgs};

let args = GemmArgs {
    a:        a_device_addr,
    b:        b_device_addr,
    c:        c_device_addr,
    n_shires: 1,
    m: 64, n: 64, k: 64,
    lda: 256, ldb: 256, ldc: 256,  // row strides in bytes; multiple of 64
    alpha: 1.0, beta: 0.0,
};

GemmArgs is 64 bytes exactly (4 x u64 for pointers / shire count, 8 x u32/f32 for dimensions, strides, and scaling). A compile-time assertion (assert!(size_of::<GemmArgs>() == 64)) guards the layout.

The crate also exports the tensor-extension architectural constants:

Constant Value Meaning
TENSOR_ALIGN 64 Minimum alignment (bytes) for tensor load/store addresses and leading dimensions.
GEMM_TILE_M 16 sGEMM output tile rows.
GEMM_TILE_K 16 sGEMM inner-dimension tile size.
GEMM_TILE_N 16 sGEMM output tile columns; N must be a multiple of this value.
MINIONS_PER_SHIRE 32 Minion cores per compute shire; used to compute the cyclic tile step.

Thanks

Thanks to AiNEKKO https://nekko.ai/ and AI Foundry https://aifoundry.org/ for allowing me time on their community ET-SoC-1 servers to develop this code.

The ET-SoC-1 ET Platform SDK and software emulator can be found on their GitHub: https://github.com/aifoundry-org/et-platform

Licence

Apache-2.0, matching the ET Platform SDK headers this crate binds to.
ET-SoC-1 ET Platform API is under the Apache 2 License.