code wiki / (root) / tensor_ir.nx

tensor_ir.nx

buildroot/runtime/tensor_ir.nx

19586 B535 linesdepth 3pulls 3 transitivereach 1 importersview sourcekind tooltopic tensor
docsdependenciesstructsconstsfunctions

about

tensor_ir.nx -- Nishi tensor intermediate representation. Phase 2.2 of docs/AI_VRAM_ARCHITECTURE.md. Models tensor operators as first-class IR so the compiler can do static shape + dtype analysis, fuse adjacent ops at compile time, and emit register-efficient kernels (CUDA, SPIR-V, RV64+RVV). Why this is the AI win nobody else ships: every other framework (PyTorch, JAX, vLLM, llama.cpp) does kernel fusion at runtime via tracing or hand-written CUDA. Whole-program comptime info in NishiLang lets us fuse + specialize at COMPILE time, with no runtime kernel-launch overhead. Status (v0.0.1): operator definitions + Tensor struct + Layout enum. Fusion pass + lowering pass are subsequent commits.

dependencies 1 imports · 1 importers

syscalls.nx tensor_ir.nx tensor_lower.nx

imports: syscalls.nx

imported by: tensor_lower.nx

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main tir_graph_new tir_add_tensor tir_tensor_at tir_bytes tir_numel tir_dtype_bits tir_add_node tir_node_at tir_tensor_at ↻ tir_tensor_at ↻ tir_infer_matmul tir_bytes ↻ tir_fuse_graph tir_node_at ↻ tir_op_is_unary_ew tir_op_is_binary_ew tir_fuse_into tir_node_at ↻

structs

42struct TirTensor {
139struct TirNode {
149struct TirGraph {

consts

21const TIR_DT_FP32: i64 = 0
22const TIR_DT_FP16: i64 = 1
23const TIR_DT_BF16: i64 = 2
24const TIR_DT_FP8: i64 = 3
25const TIR_DT_INT8: i64 = 4
26const TIR_DT_INT4: i64 = 5
27const TIR_DT_INT2: i64 = 6
28const TIR_DT_TERN: i64 = 7 // ternary {-1, 0, +1} packed
29const TIR_DT_BOOL: i64 = 8
33const TIR_LAY_DENSE: i64 = 0 // contiguous row-major
34const TIR_LAY_STRIDED: i64 = 1 // arbitrary strides per dim
35const TIR_LAY_BLOCKED: i64 = 2 // K x K micro-tiles (cache-friendly)
36const TIR_LAY_NHWC: i64 = 3 // image: batch x H x W x channels
37const TIR_LAY_NCHW: i64 = 4 // image: batch x channels x H x W
38const TIR_LAY_PACKED: i64 = 5 // sub-byte (int4/int2/ternary)
92const TIR_OP_LOAD: i64 = 0 // load constant / weight tensor
93const TIR_OP_PARAM: i64 = 1 // function parameter (input)
94const TIR_OP_RESHAPE: i64 = 2 // change view, no data copy
95const TIR_OP_TRANSPOSE: i64 = 3
96const TIR_OP_CAST: i64 = 4 // dtype conversion
97const TIR_OP_QUANTIZE: i64 = 5 // fp -> int (with scale/zp)
98const TIR_OP_DEQUANTIZE: i64 = 6 // int -> fp
101const TIR_OP_ADD: i64 = 10
102const TIR_OP_SUB: i64 = 11
103const TIR_OP_MUL: i64 = 12
104const TIR_OP_DIV: i64 = 13
105const TIR_OP_NEG: i64 = 14
106const TIR_OP_RELU: i64 = 15
107const TIR_OP_GELU: i64 = 16
108const TIR_OP_SILU: i64 = 17
109const TIR_OP_SIGMOID: i64 = 18
110const TIR_OP_TANH: i64 = 19
113const TIR_OP_SUM: i64 = 30
114const TIR_OP_MEAN: i64 = 31
115const TIR_OP_MAX: i64 = 32
116const TIR_OP_MIN: i64 = 33
117const TIR_OP_ARGMAX: i64 = 34
120const TIR_OP_RMS_NORM: i64 = 40
121const TIR_OP_LAYER_NORM: i64 = 41
122const TIR_OP_SOFTMAX: i64 = 42
125const TIR_OP_MATMUL: i64 = 50
126const TIR_OP_CONV2D: i64 = 51
127const TIR_OP_ATTENTION: i64 = 52 // fused QKV attention
128const TIR_OP_ROPE: i64 = 53 // rotary positional embedding
129const TIR_OP_EMBED: i64 = 54 // embedding lookup
133const TIR_OP_MATMUL_INT4: i64 = 60
134const TIR_OP_MATMUL_FP8: i64 = 61
135const TIR_OP_ATTN_INT4_KV: i64 = 62 // attention with int4 KV cache
160const TIR_NODE_BYTES: i64 = 64 // sizeof TirNode rounded
161const TIR_TENSOR_BYTES: i64 = 64
226const TIR_SHAPE_MISMATCH: i64 = -1
227const TIR_RANK_MISMATCH: i64 = -2
228const TIR_UNSUPPORTED_OP: i64 = -3

functions

54func tir_numel(t: *TirTensor) -> i64 {
64func tir_dtype_bits(dt: i64) -> i64 {
79func tir_bytes(t: *TirTensor) -> i64 {
163func tir_graph_new(cap: i64) -> *TirGraph {
called by 2: mainmain
175func tir_node_at(g: *TirGraph, id: i64) -> *TirNode {
180func tir_tensor_at(g: *TirGraph, id: i64) -> *TirTensor {
186func tir_add_tensor(g: *TirGraph, rank: i64, shape: *i64,
called by 2: mainmain calls 2: tir_tensor_attir_bytes
202func tir_add_node(g: *TirGraph, op: i64, n_inputs: i64,
called by 2: mainmain calls 2: tir_node_attir_tensor_at
232func tir_infer_elemwise(in_a: *TirTensor, in_b: *TirTensor,
calls 1: tir_bytes
250func tir_infer_matmul(in_a: *TirTensor, in_b: *TirTensor,
called by 1: main calls 1: tir_bytes
270func tir_infer_reshape(in_t: *TirTensor, out: *TirTensor) -> i64 {
279func tir_infer_cast(in_t: *TirTensor, target_dtype: i64,
calls 1: tir_bytes
290func tir_infer_reduce(in_t: *TirTensor, axis: i64,
calls 1: tir_bytes
315func tir_infer_attention(q: *TirTensor, k: *TirTensor, v: *TirTensor,
calls 1: tir_bytes
362func tir_op_is_unary_ew(op: i64) -> i64 {
373func tir_op_is_binary_ew(op: i64) -> i64 {
384func tir_fuse_into(consumer: *TirNode, producer_id: i64) -> i64 {
called by 1: tir_fuse_graph
396func tir_fuse_graph(g: *TirGraph) -> i64 {
432func main() -> i64 {