code wiki / (root) / nx_autograd.nx

nx_autograd.nx

buildroot/runtime/nx_autograd.nx

4881 B104 linesdepth 4pulls 6 transitivereach 9 importersview sourcekind tooltopic autograd
docsdependenciesstructsconstsfunctions

about

nx_autograd.nx -- TRAIN-R1: scalar tape-based reverse-mode autograd. THE training keystone: once gradients are correct and an optimizer drives a loss down, every model the team trains (the FNet text model, the pixel engine) is the SAME loop at larger scale. Inference is already sovereign; this is the missing BACKWARD half. Spec: knowledge/specs/2026-06-09-tutoring-training-substrate-rung1.md. TAPE: stride-5 nodes {op, ai, bi, val, grad} in one i64 array. Construction is EAGER -- creating a node computes its f32 `val` via the EXISTING nx_f32 ops (reuse, never reimplement). Backward = ONE reverse sweep (nodes are built in topological order, so reverse order visits parents before children) accumulating into `grad`: add: g->both | mul: ga+=g*vb, gb+=g*va | sub: ga+=g, gb+=-g | relu: pass g iff input val>0. Seed grad[root]=1.0. The whole engine is ~50 lines BECAUSE the f32 numeric tower already exists. genealogy_id: linnainmaa_1970_reverse_mode_ad + rumelhart_1986_backprop lineage_id: sovereign_scalar_tape_autograd_v1 license_tier: ORIGINAL verdict: GREEN (nx_train_r1_gate 2026-06-14: gradcheck + model-learns + bit-exact)

dependencies 4 imports · 9 importers

nx_f32.nx nx_f32_div.nx nx_f32_cvt.nx nx_syscalls.nx nx_autograd.nx nx_mt_core.nx nx_mt_r0_gate.nx nx_mt_r1_gate.nx nx_mt_r2_gate.nx nx_mt_r3_gate.nx nx_nofloat_vs_float_gate.nx nx_reader_mlp_gate.nx nx_reader_mlp_train.nx nx_train_r1_gate.nx

imports: nx_f32.nxnx_f32_div.nxnx_f32_cvt.nxnx_syscalls.nx

imported by: nx_mt_core.nxnx_mt_r0_gate.nxnx_mt_r1_gate.nxnx_mt_r2_gate.nxnx_mt_r3_gate.nxnx_nofloat_vs_float_gate.nxnx_reader_mlp_gate.nxnx_reader_mlp_train.nxnx_train_r1_gate.nx

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

main sys_mmap ag_leaf nx_i32_to_f32 ag_mul ag_mk nx_f32_mul nx_f32_classify nx_f32_exp_field nx_f32_mant_field nx_f32_sign nx_f32_mant_field ↻ nx_f32_exp_field ↻ ag_backward nx_f32_add nx_f32_classify ↻ nx_f32_sign ↻ nx_f32_mant_field ↻ nx_f32_exp_field ↻ nx_f32_mul ↻ nx_f32_neg nx_f32_gt nx_f32_lt nx_f32_is_nan nx_f32_classify ↻ nx_f32_is_zero nx_f32_classify ↻

structs

none

consts

20const AG_LEAF: i64 = 0
21const AG_ADD: i64 = 1
22const AG_MUL: i64 = 2
23const AG_SUB: i64 = 3
24const AG_RELU: i64 = 4
25const AG_F32_ZERO: i64 = 0 // IEEE-754 binary32 +0.0
26const AG_F32_ONE: i64 = 1065353216 // IEEE-754 binary32 1.0 = 0x3F800000

functions

28func ag_val(tape: *i64, k: i64) -> i64 { return tape[5 * k + 3] }
29func ag_grad(tape: *i64, k: i64) -> i64 { return tape[5 * k + 4] }
32func ag_leaf(tape: *i64, np: *i64, v: i64) -> i64
38func ag_mk(tape: *i64, np: *i64, op: i64, a: i64, b: i64, v: i64) -> i64
44func ag_add(tape: *i64, np: *i64, a: i64, b: i64) -> i64
47func ag_mul(tape: *i64, np: *i64, a: i64, b: i64) -> i64
50func ag_sub(tape: *i64, np: *i64, a: i64, b: i64) -> i64
53func ag_relu(tape: *i64, np: *i64, a: i64) -> i64
60func ag_backward(tape: *i64, n: i64, root: i64) -> i64
93func ag_constf(num: i64, den: i64) -> i64 { return nx_f32_div(nx_i32_to_f32(num), nx_i32_to_f32(den)) }
96func main() -> i64