code wiki / _hdl_build / nx_nofloat_lm_gate.nx

nx_nofloat_lm_gate.nx source

↩ module page · 295 lines · 17415 B

1// nx_nofloat_lm_gate.nx -- THE CAPSTONE: a tiny TRANSFORMER LANGUAGE MODEL trains END-TO-END on next-token 2// prediction, in PURE INTEGER Q16 (CAP-NF-LM). Full LM forward: 3// X = embed(E, ids) -> pre-norm transformer block (attn+RoPE+causal-softmax+SwiGLU-FFN+residuals) 4// -> rmsnorm_rows -> logits = H_n . W_lm -> loss = softmax-cross-entropy(logits, next-token ids) 5// Composed ENTIRELY from gradcheck-verified ops + the two new LM-head ops (embed gather/scatter, fused softce). 6// 7// A1 embed gradcheck : dE (gather backward = scatter-add) == finite difference. 8// A2 softce gradcheck : dlogits (fused CE identity softmax-onehot) == finite difference. 9// A3 full-LM gradcheck wrt W_lm : the LM-head gradient through CE == finite diff. 10// A4 full-LM gradcheck wrt E : the LONGEST chain -- E's gradient flows back through head+norm+FFN+attention 11// +RoPE+softmax+embed (the WHOLE model) == finite diff. This proves end-to-end backprop of the LM. 12// D neg-control teeth ; C bit-exact. 13// B THE LM FITS (memorizes a FIXED sequence) : train E + W_lm (through the full forward; gradient traverses the whole block) on a 14// next-token task (ids 0,1,2,3 -> 1,2,3,0); assert CE loss drops substantially from ~ln(V). 15// 16// Evidence -> knowledge/status/nofloat_lm.log. Sovereign: nx_nofloat_autograd + nx_syscalls (pure integer). 17// HONEST scope: single-head, single-block, tiny vocab; multi-head/GQA + deeper stack + scale remain. expect_exit: 0 18import "nx_nofloat_autograd.nx" 19import "nx_syscalls.nx" 20import "nx_gate_emit_lib.nx" 21 22const LLOG: *u8 = "knowledge/status/nofloat_lm.log" 23const Q16: i64 = 65536 24 25 26func g_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } 27func l_ws(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 28func l_wn(fd: i64, v: i64) -> i64 { let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(fd,"-" as *u8,1);m=0-m} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(fd,b,k); return 0 } 29// deterministic small nonzero init (zero-init = dead-gradient trap): values in ~[-0.25, 0.25] Q16 30func lm_init(arr: *i64, n: i64, seed: i64) -> i64 { var i: i64=0; while i<n { arr[i] = (((i*7 + seed*13 + 1) % 11) - 5) * 3277; i=i+1 } return 0 } 31 32// ---- full LM forward; W = ptr-array of 9 weight arrays [E,Wq,Wk,Wv,Wo,Wg,Wu,Wd,Wlm]; leaves[i]<->W[i], leaves[9]=logits ---- 33func lm_fwd(tape: *i64, vals: *i64, st: *i64, W: *i64, ids: *i64, tgt: *i64, T: i64, dm: i64, ffn: i64, V: i64, scale: i64, leaves: *i64) -> i64 { 34 let E: *i64 = W[0] as *i64; let Wq: *i64 = W[1] as *i64; let Wk: *i64 = W[2] as *i64; let Wv: *i64 = W[3] as *i64; let Wo: *i64 = W[4] as *i64 35 let Wg: *i64 = W[5] as *i64; let Wu: *i64 = W[6] as *i64; let Wd: *i64 = W[7] as *i64; let Wlm: *i64 = W[8] as *i64 36 st[0]=0; st[1]=0 37 let nE: i64 = nfa_leaf(tape,vals,st,V,dm,E,0) 38 let nWq: i64 = nfa_leaf(tape,vals,st,dm,dm,Wq,0) 39 let nWk: i64 = nfa_leaf(tape,vals,st,dm,dm,Wk,0) 40 let nWv: i64 = nfa_leaf(tape,vals,st,dm,dm,Wv,0) 41 let nWo: i64 = nfa_leaf(tape,vals,st,dm,dm,Wo,0) 42 let nWg: i64 = nfa_leaf(tape,vals,st,dm,ffn,Wg,0) 43 let nWu: i64 = nfa_leaf(tape,vals,st,dm,ffn,Wu,0) 44 let nWd: i64 = nfa_leaf(tape,vals,st,ffn,dm,Wd,0) 45 let nWlm:i64 = nfa_leaf(tape,vals,st,dm,V,Wlm,0) 46 let nX: i64 = nfa_embed(tape,vals,st,nE,ids,T) 47 let nXn: i64 = nfa_rmsnorm_rows(tape,vals,st,nX) 48 let nQ: i64 = nfa_matmul(tape,vals,st,nXn,nWq) 49 let nK: i64 = nfa_matmul(tape,vals,st,nXn,nWk) 50 let nV: i64 = nfa_matmul(tape,vals,st,nXn,nWv) 51 let nQr: i64 = nfa_rope(tape,vals,st,nQ) 52 let nKr: i64 = nfa_rope(tape,vals,st,nK) 53 let nS: i64 = nfa_matmul_nt(tape,vals,st,nQr,nKr) 54 let nSs: i64 = nfa_cmul(tape,vals,st,nS,scale) 55 let nA: i64 = nfa_softmax_rows(tape,vals,st,nSs,1) 56 let nO: i64 = nfa_matmul(tape,vals,st,nA,nV) 57 let nOp: i64 = nfa_matmul(tape,vals,st,nO,nWo) 58 let nH: i64 = nfa_vadd(tape,vals,st,nX,nOp) 59 let nHn: i64 = nfa_rmsnorm_rows(tape,vals,st,nH) 60 let nG: i64 = nfa_matmul(tape,vals,st,nHn,nWg) 61 let nU: i64 = nfa_matmul(tape,vals,st,nHn,nWu) 62 let nSg: i64 = nfa_silu(tape,vals,st,nG) 63 let nHs: i64 = nfa_hadamard(tape,vals,st,nSg,nU) 64 let nDp: i64 = nfa_matmul(tape,vals,st,nHs,nWd) 65 let nY: i64 = nfa_vadd(tape,vals,st,nH,nDp) 66 let nYn: i64 = nfa_rmsnorm_rows(tape,vals,st,nY) 67 let nLg: i64 = nfa_matmul(tape,vals,st,nYn,nWlm) 68 let nLoss: i64 = nfa_softce_rows(tape,vals,st,nLg,tgt) 69 leaves[0]=nE; leaves[1]=nWq; leaves[2]=nWk; leaves[3]=nWv; leaves[4]=nWo 70 leaves[5]=nWg; leaves[6]=nWu; leaves[7]=nWd; leaves[8]=nWlm; leaves[9]=nLg 71 return nLoss 72} 73func lm_lossval(tape: *i64, vals: *i64, st: *i64, W: *i64, ids: *i64, tgt: *i64, T: i64, dm: i64, ffn: i64, V: i64, scale: i64) -> i64 { 74 let lv: *i64 = sys_mmap(10*8) as *i64 75 let nLoss: i64 = lm_fwd(tape,vals,st,W,ids,tgt,T,dm,ffn,V,scale,lv) 76 return nfa_val(tape,vals,nLoss,0) 77} 78// gradcheck wrt weight array widx (leaves[widx]); extract ALL analytic grads first (lm_lossval rebuilds the tape). 79func lm_gc_w(tape: *i64, vals: *i64, grads: *i64, st: *i64, W: *i64, ids: *i64, tgt: *i64, T: i64, dm: i64, ffn: i64, V: i64, scale: i64, leaves: *i64, widx: i64, h: i64, tol_q: i64, floor_q: i64, worst: *i64) -> i64 { 80 let nLoss: i64 = lm_fwd(tape,vals,st,W,ids,tgt,T,dm,ffn,V,scale,leaves) 81 nfa_backward(tape,vals,grads,st[0],nLoss) 82 let nnode: i64 = leaves[widx] 83 let cnt: i64 = tape[7*nnode+3]*tape[7*nnode+4] 84 let ana: *i64 = sys_mmap(64*8) as *i64 85 var c: i64=0 86 while c<cnt { ana[c]=nfa_grad(tape,grads,nnode,c); c=c+1 } 87 let arr: *i64 = W[widx] as *i64 88 var ok: i64=1; worst[0]=0 89 var i: i64=0 90 while i<cnt { 91 let old: i64 = arr[i] 92 arr[i]=old+h; let lp: i64 = lm_lossval(tape,vals,st,W,ids,tgt,T,dm,ffn,V,scale) 93 arr[i]=old-h; let lm2: i64 = lm_lossval(tape,vals,st,W,ids,tgt,T,dm,ffn,V,scale) 94 arr[i]=old 95 let fd: i64 = ((lp-lm2)*Q16)/(2*h) 96 let num: i64 = g_abs(fd-ana[i]) 97 var den: i64 = g_abs(ana[i]); if den<floor_q { den=floor_q } 98 if num >= ((tol_q*den)>>16) { ok=0 } 99 let rel: i64 = (num*1000)/den 100 if rel>worst[0] { worst[0]=rel } 101 i=i+1 102 } 103 return ok 104} 105 106// ---- A1 embed standalone: loss = mse(embed(E,ids), tgt) ---- 107func emb_loss(tape: *i64, vals: *i64, st: *i64, E: *i64, ids: *i64, Tg: *i64, V: i64, dm: i64, T: i64, leaves: *i64) -> i64 { 108 st[0]=0; st[1]=0 109 let nE: i64 = nfa_leaf(tape,vals,st,V,dm,E,0) 110 let nX: i64 = nfa_embed(tape,vals,st,nE,ids,T) 111 let nt: i64 = nfa_leaf(tape,vals,st,T,dm,Tg,0) 112 let loss: i64 = nfa_mse(tape,vals,st,nX,nt) 113 leaves[0]=nE 114 return loss 115} 116func emb_lossval(tape: *i64, vals: *i64, st: *i64, E: *i64, ids: *i64, Tg: *i64, V: i64, dm: i64, T: i64) -> i64 { 117 let lv: *i64 = sys_mmap(8) as *i64 118 let loss: i64 = emb_loss(tape,vals,st,E,ids,Tg,V,dm,T,lv) 119 return nfa_val(tape,vals,loss,0) 120} 121 122// ---- A2 softce standalone: loss = softce(logits_leaf, tgt) ---- 123func ce_loss(tape: *i64, vals: *i64, st: *i64, L: *i64, tgt: *i64, T: i64, V: i64, leaves: *i64) -> i64 { 124 st[0]=0; st[1]=0 125 let nL: i64 = nfa_leaf(tape,vals,st,T,V,L,0) 126 let loss: i64 = nfa_softce_rows(tape,vals,st,nL,tgt) 127 leaves[0]=nL 128 return loss 129} 130func ce_lossval(tape: *i64, vals: *i64, st: *i64, L: *i64, tgt: *i64, T: i64, V: i64) -> i64 { 131 let lv: *i64 = sys_mmap(8) as *i64 132 let loss: i64 = ce_loss(tape,vals,st,L,tgt,T,V,lv) 133 return nfa_val(tape,vals,loss,0) 134} 135 136func main() -> i64 { 137 g_puts("nx_nofloat_lm gate (a tiny TRANSFORMER LM trains end-to-end on next-token, PURE INTEGER Q16)\n" as *u8) 138 var pass: i64=0; var total: i64=0 139 let tape: *i64 = sys_mmap(512*7*8) as *i64 140 let vals: *i64 = sys_mmap(16384*8) as *i64 141 let grads: *i64 = sys_mmap(16384*8) as *i64 142 let st: *i64 = sys_mmap(2*8) as *i64 143 let h: i64 = 512; let floor_q: i64 = 4096 144 let worst: *i64 = sys_mmap(8) as *i64 145 146 // ---- A1: embed gradcheck (V=3,dm=2,T=3; ids gather rows 0,2,1; one repeats nothing here) ---- 147 let eE: *i64 = sys_mmap(6*8) as *i64; lm_init(eE,6,1) 148 let eids: *i64 = sys_mmap(3*8) as *i64; eids[0]=0; eids[1]=2; eids[2]=1 149 let eTg: *i64 = sys_mmap(6*8) as *i64; eTg[0]=13107; eTg[1]=0-6554; eTg[2]=19661; eTg[3]=6554; eTg[4]=0-26214; eTg[5]=32768 150 let elv: *i64 = sys_mmap(8) as *i64 151 let el: i64 = emb_loss(tape,vals,st,eE,eids,eTg,3,2,3,elv) 152 nfa_backward(tape,vals,grads,st[0],el) 153 let enode: i64 = elv[0] 154 let eana: *i64 = sys_mmap(8*8) as *i64 155 var ec: i64=0 156 while ec<6 { eana[ec]=nfa_grad(tape,grads,enode,ec); ec=ec+1 } 157 var e_ok: i64=1; var e_worst: i64=0 158 var ei: i64=0 159 while ei<6 { 160 let old: i64=eE[ei]; eE[ei]=old+h; let lp: i64=emb_lossval(tape,vals,st,eE,eids,eTg,3,2,3); eE[ei]=old-h; let lm2: i64=emb_lossval(tape,vals,st,eE,eids,eTg,3,2,3); eE[ei]=old 161 let fd: i64=((lp-lm2)*Q16)/(2*h); let num: i64=g_abs(fd-eana[ei]); var den: i64=g_abs(eana[ei]); if den<floor_q{den=floor_q} 162 if num >= ((4096*den)>>16) { e_ok=0 } 163 let rel: i64=(num*1000)/den; if rel>e_worst{e_worst=rel} 164 ei=ei+1 165 } 166 g_puts(" [measure] embed worst rel grad err = " as *u8); g_pn(e_worst); g_puts(" /1000 (tol=62)\n" as *u8) 167 pass=pass+g_check("A1: embed gradcheck -- gather backward (scatter-add) == finite differences" as *u8, e_ok); total=total+1 168 169 // ---- A2: softce gradcheck (T=2,V=3) ---- 170 let cL: *i64 = sys_mmap(6*8) as *i64; cL[0]=32768; cL[1]=0-16384; cL[2]=49152; cL[3]=16384; cL[4]=65536; cL[5]=0-32768 171 let ctg: *i64 = sys_mmap(2*8) as *i64; ctg[0]=1; ctg[1]=2 172 let clv: *i64 = sys_mmap(8) as *i64 173 let cl: i64 = ce_loss(tape,vals,st,cL,ctg,2,3,clv) 174 nfa_backward(tape,vals,grads,st[0],cl) 175 let cnode: i64 = clv[0] 176 let cana: *i64 = sys_mmap(8*8) as *i64 177 var cc: i64=0 178 while cc<6 { cana[cc]=nfa_grad(tape,grads,cnode,cc); cc=cc+1 } 179 var c_ok: i64=1; var c_worst: i64=0 180 var ci: i64=0 181 while ci<6 { 182 let old: i64=cL[ci]; cL[ci]=old+h; let lp: i64=ce_lossval(tape,vals,st,cL,ctg,2,3); cL[ci]=old-h; let lm2: i64=ce_lossval(tape,vals,st,cL,ctg,2,3); cL[ci]=old 183 let fd: i64=((lp-lm2)*Q16)/(2*h); let num: i64=g_abs(fd-cana[ci]); var den: i64=g_abs(cana[ci]); if den<floor_q{den=floor_q} 184 if num >= ((8192*den)>>16) { c_ok=0 } // tol 1/8 (ln/exp fixed-point approximation) 185 let rel: i64=(num*1000)/den; if rel>c_worst{c_worst=rel} 186 ci=ci+1 187 } 188 g_puts(" [measure] softce worst rel grad err = " as *u8); g_pn(c_worst); g_puts(" /1000 (tol=125)\n" as *u8) 189 pass=pass+g_check("A2: softce gradcheck -- fused softmax-CE (softmax-onehot) backward == finite differences" as *u8, c_ok); total=total+1 190 191 // ---- LM dims + weights ---- 192 let T: i64=4; let dm: i64=4; let ffn: i64=8; let V: i64=4; let scale: i64=32768 // 1/sqrt(4)=0.5 193 let E: *i64 = sys_mmap(V*dm*8) as *i64; lm_init(E,V*dm,1) 194 let Wq: *i64 = sys_mmap(dm*dm*8) as *i64; lm_init(Wq,dm*dm,2) 195 let Wk: *i64 = sys_mmap(dm*dm*8) as *i64; lm_init(Wk,dm*dm,3) 196 let Wv: *i64 = sys_mmap(dm*dm*8) as *i64; lm_init(Wv,dm*dm,4) 197 let Wo: *i64 = sys_mmap(dm*dm*8) as *i64; lm_init(Wo,dm*dm,5) 198 let Wg: *i64 = sys_mmap(dm*ffn*8) as *i64; lm_init(Wg,dm*ffn,6) 199 let Wu: *i64 = sys_mmap(dm*ffn*8) as *i64; lm_init(Wu,dm*ffn,7) 200 let Wd: *i64 = sys_mmap(ffn*dm*8) as *i64; lm_init(Wd,ffn*dm,8) 201 let Wlm:*i64 = sys_mmap(dm*V*8) as *i64; lm_init(Wlm,dm*V,9) 202 let W: *i64 = sys_mmap(9*8) as *i64 203 W[0]=E as i64; W[1]=Wq as i64; W[2]=Wk as i64; W[3]=Wv as i64; W[4]=Wo as i64; W[5]=Wg as i64; W[6]=Wu as i64; W[7]=Wd as i64; W[8]=Wlm as i64 204 let ids: *i64 = sys_mmap(T*8) as *i64; ids[0]=0; ids[1]=1; ids[2]=2; ids[3]=3 205 let tgt: *i64 = sys_mmap(T*8) as *i64; tgt[0]=1; tgt[1]=2; tgt[2]=3; tgt[3]=0 206 let leaves: *i64 = sys_mmap(10*8) as *i64 207 208 // ---- A3: full-LM gradcheck wrt Wlm (widx 8) ---- 209 let a3_ok: i64 = lm_gc_w(tape,vals,grads,st,W,ids,tgt,T,dm,ffn,V,scale,leaves,8,h,8192,floor_q,worst) 210 g_puts(" [measure] full-LM dL/dWlm worst rel grad err = " as *u8); g_pn(worst[0]); g_puts(" /1000 (tol=125)\n" as *u8) 211 pass=pass+g_check("A3: full-LM gradcheck wrt Wlm (LM head through CE) == finite differences" as *u8, a3_ok); total=total+1 212 213 // ---- A4: full-LM gradcheck wrt E (widx 0) -- the LONGEST chain (head+norm+FFN+attn+RoPE+softmax+embed) ---- 214 let a4_ok: i64 = lm_gc_w(tape,vals,grads,st,W,ids,tgt,T,dm,ffn,V,scale,leaves,0,h,16384,floor_q,worst) 215 g_puts(" [measure] full-LM dL/dE worst rel grad err = " as *u8); g_pn(worst[0]); g_puts(" /1000 (tol=250)\n" as *u8) 216 pass=pass+g_check("A4: full-LM gradcheck wrt E through the WHOLE model == finite differences (end-to-end backprop)" as *u8, a4_ok); total=total+1 217 218 // ---- D: neg-control teeth (Wlm grad) ---- 219 let nLd: i64 = lm_fwd(tape,vals,st,W,ids,tgt,T,dm,ffn,V,scale,leaves) 220 nfa_backward(tape,vals,grads,st[0],nLd) 221 let dana: i64 = nfa_grad(tape,grads,leaves[8],0) 222 let old0: i64 = Wlm[0]; Wlm[0]=old0+h; let lpd: i64=lm_lossval(tape,vals,st,W,ids,tgt,T,dm,ffn,V,scale); Wlm[0]=old0-h; let lmd: i64=lm_lossval(tape,vals,st,W,ids,tgt,T,dm,ffn,V,scale); Wlm[0]=old0 223 let dfd: i64 = ((lpd-lmd)*Q16)/(2*h) 224 let dbad: i64 = 0 - dana 225 var dden: i64 = g_abs(dana); if dden<floor_q { dden=floor_q } 226 var caught: i64 = 1 227 if g_abs(dfd-dbad) < ((8192*dden)>>16) { caught=0 } 228 pass=pass+g_check("D: neg-control -- a WRONG LM gradient is rejected (teeth)" as *u8, caught); total=total+1 229 230 // ---- B: the LM FITS (memorizes a FIXED sequence) next-token (train E + Wlm through the full forward; grad traverses the whole block) ---- 231 let gbuf: *i64 = sys_mmap(64*8) as *i64 232 var lf: i64=0; var ll: i64=0 233 var ep: i64=0 234 while ep < 8000 { 235 let nLoss: i64 = lm_fwd(tape,vals,st,W,ids,tgt,T,dm,ffn,V,scale,leaves) 236 nfa_backward(tape,vals,grads,st[0],nLoss) 237 if ep==0 { lf = nfa_val(tape,vals,nLoss,0) } 238 ll = nfa_val(tape,vals,nLoss,0) 239 // update E (widx 0) and Wlm (widx 8) 240 let nE2: i64 = leaves[0]; let cE: i64 = V*dm 241 var z: i64=0 242 while z<cE { gbuf[z]=nfa_grad(tape,grads,nE2,z); z=z+1 } 243 nfa_sgd(E, gbuf, cE, 2048) 244 let nWl: i64 = leaves[8]; let cWl: i64 = dm*V 245 z=0 246 while z<cWl { gbuf[z]=nfa_grad(tape,grads,nWl,z); z=z+1 } 247 nfa_sgd(Wlm, gbuf, cWl, 2048) 248 ep=ep+1 249 } 250 g_puts(" [measure] LM next-token CE loss: start=" as *u8); g_pn(lf); g_puts(" end=" as *u8); g_pn(ll); g_puts(" (ln(V)=ln4 ~ 90852 Q16)\n" as *u8) 251 var fits: i64 = 1 252 if ll*2 > lf { fits=0 } // >= 50% CE reduction = it fit the fixed sequence (memorization, not generalization) 253 if lf <= 0 { fits=0 } 254 pass=pass+g_check("B: the LM FITS (memorizes a FIXED sequence) -- next-token CE loss drops >=50% via end-to-end backprop (E+Wlm trained)" as *u8, fits); total=total+1 255 256 // ---- C: bit-exact ---- 257 let E2: *i64 = sys_mmap(V*dm*8) as *i64; lm_init(E2,V*dm,1) 258 let Wlm2:*i64 = sys_mmap(dm*V*8) as *i64; lm_init(Wlm2,dm*V,9) 259 let W2: *i64 = sys_mmap(9*8) as *i64 260 W2[0]=E2 as i64; W2[1]=Wq as i64; W2[2]=Wk as i64; W2[3]=Wv as i64; W2[4]=Wo as i64; W2[5]=Wg as i64; W2[6]=Wu as i64; W2[7]=Wd as i64; W2[8]=Wlm2 as i64 261 let lvc: *i64 = sys_mmap(10*8) as *i64 262 let gbuf2: *i64 = sys_mmap(64*8) as *i64 263 var ep2: i64=0 264 while ep2 < 8000 { 265 let nLoss: i64 = lm_fwd(tape,vals,st,W2,ids,tgt,T,dm,ffn,V,scale,lvc) 266 nfa_backward(tape,vals,grads,st[0],nLoss) 267 let nE2: i64=lvc[0]; var z: i64=0 268 while z<V*dm { gbuf2[z]=nfa_grad(tape,grads,nE2,z); z=z+1 } 269 nfa_sgd(E2, gbuf2, V*dm, 2048) 270 let nWl: i64=lvc[8]; z=0 271 while z<dm*V { gbuf2[z]=nfa_grad(tape,grads,nWl,z); z=z+1 } 272 nfa_sgd(Wlm2, gbuf2, dm*V, 2048) 273 ep2=ep2+1 274 } 275 var bitexact: i64 = 1 276 var zc: i64=0 277 while zc<V*dm { if E2[zc]!=E[zc] { bitexact=0 } zc=zc+1 } 278 zc=0 279 while zc<dm*V { if Wlm2[zc]!=Wlm[zc] { bitexact=0 } zc=zc+1 } 280 pass=pass+g_check("C: bit-exact -- training the LM twice gives IDENTICAL integer weights (determinism)" as *u8, bitexact); total=total+1 281 282 // ---- emit ---- 283 var okall: i64=0; if pass==total { okall=1 } 284 let logf: i64 = sys_openat_append(LLOG, 420) 285 if logf >= 0 { 286 l_ws(logf,"NOFLOATLM 1-block 1-head V=4 A1_embed=" as *u8); l_wn(logf,e_ok); l_ws(logf," A2_softce=" as *u8); l_wn(logf,c_ok) 287 l_ws(logf," A3_Wlm=" as *u8); l_wn(logf,a3_ok); l_ws(logf," A4_E_fullchain=" as *u8); l_wn(logf,a4_ok); l_ws(logf," D=" as *u8); l_wn(logf,caught) 288 l_ws(logf," B_fits=" as *u8); l_wn(logf,fits); l_ws(logf," CE_start=" as *u8); l_wn(logf,lf); l_ws(logf," CE_end=" as *u8); l_wn(logf,ll); l_ws(logf," C_bitexact=" as *u8); l_wn(logf,bitexact) 289 if okall==1 { l_ws(logf," verdict=GREEN\n" as *u8) } else { l_ws(logf," verdict=RED\n" as *u8) } 290 sys_close(logf) 291 } 292 g_puts("---- nofloat_lm gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 293 if okall==1 { g_puts("verdict=GREEN (a tiny transformer LM trains end-to-end on next-token prediction in pure integer Q16)\n" as *u8); sys_exit(0); return 0 } 294 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 295}