matmul — matrix multiply benchmark
Three compute targets in Tish, all using native imports.
examples/matmul/
tish-metal/ native Tish module — tiled MSL compute kernel
tish-mlx/ native Tish module — Apple MLX via mlx-rs
src/
main.tish CPU — import nothing, just Tish primitives
matmul_gpu.tish Metal — import { matmul_f32, run_f32 } from 'tish:metal'
matmul_mlx.tish MLX — import { matmul_f32 } from 'tish:mlx'
crates/
matmul_gpu/ standalone Rust binary (direct Metal, no Tish)
matmul_mlx/ standalone Rust binary (direct MLX, no Tish)
The tish-metal and tish-mlx directories are local native Tish modules.
They live here in the example — not in core Tish — and are resolved by the
compiler via the package.json / sibling-directory lookup in the native module system.
Running
CPU (Tish native compilation — f64 primitives)
tish build src/main.tish -o matmul-cpu --native-backend rust
./matmul-cpuMetal GPU
# From examples/matmul/
tish build src/matmul_gpu.tish -o matmul-gpu --native-backend rust
./matmul-gpuApple MLX
mlx-rs vendors the MLX C library — no brew install needed, only Xcode CLT.
First build takes a few minutes while CMake compiles MLX from source.
# From examples/matmul/
tish build src/matmul_mlx.tish -o matmul-mlx --native-backend rust
./matmul-mlxStandalone Rust binaries (no Tish required)
cargo build --release -p matmul_gpu && ./target/release/matmul-gpu
cargo build --release -p matmul_mlx && ./target/release/matmul-mlxHow the native module system works
import { matmul_f32 } from 'tish:metal' triggers the compiler to:
- Look for
tish-metal/package.jsonin sibling directories - Read
"tish": { "crate": "tish-metal", "export": "metal_object" } - Add
tish-metalas a Cargo dependency in the generated binary - Call
tish_metal::metal_object()to get the module's export object
The metal_object() function (in tish-metal/src/lib.rs) returns a
Value::Object containing matmul_f32, run_f32, and device_name as
Value::Function entries. No changes to core Tish needed.