code wiki / _hdl_build / nx_nofloat_block_gate.nx

nx_nofloat_block_gate.nx source

↩ module page · 295 lines · 17397 B

1// nx_nofloat_block_gate.nx -- HARD-EVIDENCE gate for a COMPLETE pre-norm TRANSFORMER BLOCK backprop + train, 2// in PURE INTEGER Q16 (CAP-NF-BLOCK). The block (single-head) is the real Qwen-style shape: 3// H = X + Wo * Attn( RoPE, scaled, causal-softmax )( rmsnorm_rows(X) ) [attention sublayer + residual] 4// Y = H + SwiGLU-FFN( rmsnorm_rows(H) ) [FFN sublayer + residual] 5// SwiGLU-FFN(z) = Wd * ( silu(Wg*z) (*) (Wu*z) ) 6// Composed ENTIRELY from gradcheck-verified ops (rmsnorm_rows, matmul, matmul_nt, rope, cmul, softmax_rows, 7// silu, hadamard, vadd, mse). No new backward math -- this proves the COMPOSITION trains. 8// 9// A1 hadamard gradcheck : loss=mse(a(*)b,t); dL/da == finite diff. 10// A2 rmsnorm_rows gradcheck: per-token norm; dL/dx == finite diff. 11// A3 FULL-BLOCK gradcheck wrt Wd (down-proj, short path): dL/dWd == finite diff. 12// A4 FULL-BLOCK gradcheck wrt Wq (the LONGEST chain: through FFN, residual, attention, RoPE, softmax): measured. 13// B the BLOCK TRAINS : with all weights fixed except the down-proj Wd, Y is LINEAR in Wd (convex MSE) -> 14// train Wd from zero to a realizable teacher target; assert loss collapses + Wd converges. A weight DEEP in 15// a full transformer block is driven by the block's own end-to-end backward. 16// C bit-exact ; D neg-control teeth. 17// 18// Evidence -> knowledge/status/nofloat_block.log. Sovereign: nx_nofloat_autograd + nx_syscalls (pure integer). 19// HONEST scope: single-head; multi-head/GQA + multi-block stack are the remaining COMPOSITION. expect_exit: 0 20import "nx_nofloat_autograd.nx" 21import "nx_syscalls.nx" 22import "nx_gate_emit_lib.nx" 23 24const BLOG: *u8 = "knowledge/status/nofloat_block.log" 25const Q16: i64 = 65536 26 27 28func g_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } 29func b_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 } 30func b_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 } 31 32// ---- generic single-input-op gradcheck (op 13=hadamard handled separately; here 14=rmsnorm_rows) ---- 33func one_loss(tape: *i64, vals: *i64, st: *i64, op: i64, Xs: *i64, Bs: *i64, Ts: *i64, r: i64, c: i64, leaves: *i64) -> i64 { 34 st[0]=0; st[1]=0 35 let nX: i64 = nfa_leaf(tape,vals,st,r,c,Xs,0) 36 var ny: i64 = nX 37 if op == 13 { let nB: i64 = nfa_leaf(tape,vals,st,r,c,Bs,0); ny = nfa_hadamard(tape,vals,st,nX,nB) } 38 if op == 14 { ny = nfa_rmsnorm_rows(tape,vals,st,nX) } 39 let nt: i64 = nfa_leaf(tape,vals,st,r,c,Ts,0) 40 let loss: i64 = nfa_mse(tape,vals,st,ny,nt) 41 leaves[0]=nX 42 return loss 43} 44func one_lossval(tape: *i64, vals: *i64, st: *i64, op: i64, Xs: *i64, Bs: *i64, Ts: *i64, r: i64, c: i64) -> i64 { 45 let lv: *i64 = sys_mmap(8) as *i64 46 let loss: i64 = one_loss(tape,vals,st,op,Xs,Bs,Ts,r,c,lv) 47 return nfa_val(tape,vals,loss,0) 48} 49func one_gradcheck(tape: *i64, vals: *i64, grads: *i64, st: *i64, op: i64, Xs: *i64, Bs: *i64, Ts: *i64, r: i64, c: i64, h: i64, tol_q: i64, floor_q: i64, worst: *i64) -> i64 { 50 let lv: *i64 = sys_mmap(8) as *i64 51 let loss: i64 = one_loss(tape,vals,st,op,Xs,Bs,Ts,r,c,lv) 52 nfa_backward(tape,vals,grads,st[0],loss) 53 let nX: i64 = lv[0] 54 var ok: i64=1; worst[0]=0 55 var i: i64=0 56 while i<r*c { 57 let ana: i64 = nfa_grad(tape,grads,nX,i) 58 let xp: *i64 = sys_mmap(r*c*8) as *i64 59 let xm: *i64 = sys_mmap(r*c*8) as *i64 60 var z: i64=0 61 while z<r*c { xp[z]=Xs[z]; xm[z]=Xs[z]; z=z+1 } 62 xp[i]=Xs[i]+h; xm[i]=Xs[i]-h 63 let lp: i64 = one_lossval(tape,vals,st,op,xp,Bs,Ts,r,c) 64 let lm: i64 = one_lossval(tape,vals,st,op,xm,Bs,Ts,r,c) 65 let fd: i64 = ((lp-lm)*Q16)/(2*h) 66 let num: i64 = g_abs(fd-ana) 67 var den: i64 = g_abs(ana); if den<floor_q { den=floor_q } 68 if num >= ((tol_q*den)>>16) { ok=0 } 69 let rel: i64 = (num*1000)/den 70 if rel>worst[0] { worst[0]=rel } 71 i=i+1 72 } 73 return ok 74} 75 76// ---- the full pre-norm transformer block; leaves[0]=nWq, leaves[1]=nWd; returns nY ---- 77func blk_fwd(tape: *i64, vals: *i64, st: *i64, X: *i64, Wq: *i64, Wk: *i64, Wv: *i64, Wo: *i64, Wg: *i64, Wu: *i64, Wd: *i64, T: i64, dm: i64, ffn: i64, scale: i64, leaves: *i64) -> i64 { 78 st[0]=0; st[1]=0 79 let nX: i64 = nfa_leaf(tape,vals,st,T,dm,X,0) 80 let nWq: i64 = nfa_leaf(tape,vals,st,dm,dm,Wq,0) 81 let nWk: i64 = nfa_leaf(tape,vals,st,dm,dm,Wk,0) 82 let nWv: i64 = nfa_leaf(tape,vals,st,dm,dm,Wv,0) 83 let nWo: i64 = nfa_leaf(tape,vals,st,dm,dm,Wo,0) 84 let nWg: i64 = nfa_leaf(tape,vals,st,dm,ffn,Wg,0) 85 let nWu: i64 = nfa_leaf(tape,vals,st,dm,ffn,Wu,0) 86 let nWd: i64 = nfa_leaf(tape,vals,st,ffn,dm,Wd,0) 87 let nXn: i64 = nfa_rmsnorm_rows(tape,vals,st,nX) 88 let nQ: i64 = nfa_matmul(tape,vals,st,nXn,nWq) 89 let nK: i64 = nfa_matmul(tape,vals,st,nXn,nWk) 90 let nV: i64 = nfa_matmul(tape,vals,st,nXn,nWv) 91 let nQr: i64 = nfa_rope(tape,vals,st,nQ) 92 let nKr: i64 = nfa_rope(tape,vals,st,nK) 93 let nS: i64 = nfa_matmul_nt(tape,vals,st,nQr,nKr) 94 let nSs: i64 = nfa_cmul(tape,vals,st,nS,scale) 95 let nA: i64 = nfa_softmax_rows(tape,vals,st,nSs,1) 96 let nO: i64 = nfa_matmul(tape,vals,st,nA,nV) 97 let nOp: i64 = nfa_matmul(tape,vals,st,nO,nWo) 98 let nH: i64 = nfa_vadd(tape,vals,st,nX,nOp) 99 let nHn: i64 = nfa_rmsnorm_rows(tape,vals,st,nH) 100 let nG: i64 = nfa_matmul(tape,vals,st,nHn,nWg) 101 let nU: i64 = nfa_matmul(tape,vals,st,nHn,nWu) 102 let nSg: i64 = nfa_silu(tape,vals,st,nG) 103 let nHs: i64 = nfa_hadamard(tape,vals,st,nSg,nU) 104 let nD: i64 = nfa_matmul(tape,vals,st,nHs,nWd) 105 let nY: i64 = nfa_vadd(tape,vals,st,nH,nD) 106 leaves[0]=nWq; leaves[1]=nWd 107 return nY 108} 109func blk_loss(tape: *i64, vals: *i64, st: *i64, X: *i64, Wq: *i64, Wk: *i64, Wv: *i64, Wo: *i64, Wg: *i64, Wu: *i64, Wd: *i64, Ts: *i64, T: i64, dm: i64, ffn: i64, scale: i64, leaves: *i64) -> i64 { 110 let nY: i64 = blk_fwd(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,Wd,T,dm,ffn,scale,leaves) 111 let nt: i64 = nfa_leaf(tape,vals,st,T,dm,Ts,0) 112 return nfa_mse(tape,vals,st,nY,nt) 113} 114func blk_lossval(tape: *i64, vals: *i64, st: *i64, X: *i64, Wq: *i64, Wk: *i64, Wv: *i64, Wo: *i64, Wg: *i64, Wu: *i64, Wd: *i64, Ts: *i64, T: i64, dm: i64, ffn: i64, scale: i64) -> i64 { 115 let lv: *i64 = sys_mmap(2*8) as *i64 116 let loss: i64 = blk_loss(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,Wd,Ts,T,dm,ffn,scale,lv) 117 return nfa_val(tape,vals,loss,0) 118} 119func blk_out(tape: *i64, vals: *i64, st: *i64, X: *i64, Wq: *i64, Wk: *i64, Wv: *i64, Wo: *i64, Wg: *i64, Wu: *i64, Wd: *i64, T: i64, dm: i64, ffn: i64, scale: i64, outY: *i64) -> i64 { 120 let lv: *i64 = sys_mmap(2*8) as *i64 121 let nY: i64 = blk_fwd(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,Wd,T,dm,ffn,scale,lv) 122 var i: i64=0 123 while i<T*dm { outY[i] = nfa_val(tape,vals,nY,i); i=i+1 } 124 return 0 125} 126 127func main() -> i64 { 128 g_puts("nx_nofloat_block gate (a full pre-norm TRANSFORMER BLOCK backprops + trains in PURE INTEGER Q16)\n" as *u8) 129 var pass: i64=0; var total: i64=0 130 let tape: *i64 = sys_mmap(1024*7*8) as *i64 131 let vals: *i64 = sys_mmap(16384*8) as *i64 132 let grads: *i64 = sys_mmap(16384*8) as *i64 133 let st: *i64 = sys_mmap(2*8) as *i64 134 let h: i64 = 512; let floor_q: i64 = 4096 135 let worst: *i64 = sys_mmap(8) as *i64 136 137 // ---- A1 hadamard gradcheck (2x2) ---- 138 let ha: *i64 = sys_mmap(4*8) as *i64; ha[0]=32768; ha[1]=0-16384; ha[2]=49152; ha[3]=65536 139 let hb: *i64 = sys_mmap(4*8) as *i64; hb[0]=49152; hb[1]=32768; hb[2]=0-32768; hb[3]=16384 140 let ht: *i64 = sys_mmap(4*8) as *i64; ht[0]=13107; ht[1]=0-6554; ht[2]=19661; ht[3]=6554 141 let ha_ok: i64 = one_gradcheck(tape,vals,grads,st,13,ha,hb,ht,2,2,h,4096,floor_q,worst) 142 g_puts(" [measure] hadamard worst rel grad err = " as *u8); g_pn(worst[0]); g_puts(" /1000 (tol=62)\n" as *u8) 143 pass=pass+g_check("A1: hadamard gradcheck -- elementwise mul backward == finite differences" as *u8, ha_ok); total=total+1 144 145 // ---- A2 rmsnorm_rows gradcheck (2 rows x 3 cols) ---- 146 let ra: *i64 = sys_mmap(6*8) as *i64; ra[0]=32768; ra[1]=65536; ra[2]=0-32768; ra[3]=16384; ra[4]=0-49152; ra[5]=24576 147 let rt: *i64 = sys_mmap(6*8) as *i64; rt[0]=13107; rt[1]=52429; rt[2]=0-39322; rt[3]=6554; rt[4]=0-26214; rt[5]=32768 148 let ra_ok: i64 = one_gradcheck(tape,vals,grads,st,14,ra,ra,rt,2,3,h,4096,floor_q,worst) 149 g_puts(" [measure] rmsnorm_rows worst rel grad err = " as *u8); g_pn(worst[0]); g_puts(" /1000 (tol=62)\n" as *u8) 150 pass=pass+g_check("A2: rmsnorm_rows gradcheck -- per-token normalization backward == finite differences" as *u8, ra_ok); total=total+1 151 152 // ---- block dims + weights ---- 153 let T: i64 = 2; let dm: i64 = 2; let ffn: i64 = 4; let scale: i64 = 46341 154 let X: *i64 = sys_mmap(T*dm*8) as *i64; X[0]=32768; X[1]=0-16384; X[2]=49152; X[3]=24576 155 let Wq: *i64 = sys_mmap(dm*dm*8) as *i64; Wq[0]=49152; Wq[1]=0-16384; Wq[2]=32768; Wq[3]=65536 156 let Wk: *i64 = sys_mmap(dm*dm*8) as *i64; Wk[0]=16384; Wk[1]=32768; Wk[2]=0-32768; Wk[3]=49152 157 let Wv: *i64 = sys_mmap(dm*dm*8) as *i64; Wv[0]=65536; Wv[1]=0-32768; Wv[2]=16384; Wv[3]=49152 158 let Wo: *i64 = sys_mmap(dm*dm*8) as *i64; Wo[0]=32768; Wo[1]=16384; Wo[2]=0-16384; Wo[3]=49152 159 let Wg: *i64 = sys_mmap(dm*ffn*8) as *i64; Wg[0]=32768; Wg[1]=0-16384; Wg[2]=49152; Wg[3]=16384; Wg[4]=0-32768; Wg[5]=65536; Wg[6]=24576; Wg[7]=0-8192 160 let Wu: *i64 = sys_mmap(dm*ffn*8) as *i64; Wu[0]=16384; Wu[1]=49152; Wu[2]=0-32768; Wu[3]=32768; Wu[4]=65536; Wu[5]=0-16384; Wu[6]=8192; Wu[7]=40960 161 let Wd: *i64 = sys_mmap(ffn*dm*8) as *i64; Wd[0]=32768; Wd[1]=0-16384; Wd[2]=16384; Wd[3]=49152; Wd[4]=0-32768; Wd[5]=24576; Wd[6]=40960; Wd[7]=0-8192 162 let Tg: *i64 = sys_mmap(T*dm*8) as *i64; Tg[0]=13107; Tg[1]=0-6554; Tg[2]=19661; Tg[3]=6554 163 let lv: *i64 = sys_mmap(2*8) as *i64 164 165 // ---- A3 full-block gradcheck wrt Wd (short path) ---- 166 let loss3: i64 = blk_loss(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,Wd,Tg,T,dm,ffn,scale,lv) 167 nfa_backward(tape,vals,grads,st[0],loss3) 168 let nWd: i64 = lv[1] 169 var a3_ok: i64=1; var a3_worst: i64=0 170 var di: i64=0 171 while di < ffn*dm { 172 let ana: i64 = nfa_grad(tape,grads,nWd,di) 173 let wp: *i64 = sys_mmap(ffn*dm*8) as *i64 174 let wm: *i64 = sys_mmap(ffn*dm*8) as *i64 175 var z: i64=0 176 while z<ffn*dm { wp[z]=Wd[z]; wm[z]=Wd[z]; z=z+1 } 177 wp[di]=Wd[di]+h; wm[di]=Wd[di]-h 178 let lp: i64 = blk_lossval(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,wp,Tg,T,dm,ffn,scale) 179 let lm: i64 = blk_lossval(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,wm,Tg,T,dm,ffn,scale) 180 let fd: i64 = ((lp-lm)*Q16)/(2*h) 181 let num: i64 = g_abs(fd-ana) 182 var den: i64 = g_abs(ana); if den<floor_q { den=floor_q } 183 if num >= ((8192*den)>>16) { a3_ok=0 } 184 let rel: i64 = (num*1000)/den 185 if rel>a3_worst { a3_worst=rel } 186 di=di+1 187 } 188 g_puts(" [measure] block dL/dWd worst rel grad err = " as *u8); g_pn(a3_worst); g_puts(" /1000 (tol=125)\n" as *u8) 189 pass=pass+g_check("A3: FULL-BLOCK gradcheck wrt Wd (FFN down-proj) == finite differences" as *u8, a3_ok); total=total+1 190 191 // ---- A4 full-block gradcheck wrt Wq (the LONGEST chain: FFN<-residual<-attention<-RoPE<-softmax) ---- 192 let loss4: i64 = blk_loss(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,Wd,Tg,T,dm,ffn,scale,lv) 193 nfa_backward(tape,vals,grads,st[0],loss4) 194 let nWq: i64 = lv[0] 195 var a4_ok: i64=1; var a4_worst: i64=0 196 var qi: i64=0 197 while qi < dm*dm { 198 let ana: i64 = nfa_grad(tape,grads,nWq,qi) 199 let wp: *i64 = sys_mmap(dm*dm*8) as *i64 200 let wm: *i64 = sys_mmap(dm*dm*8) as *i64 201 var z: i64=0 202 while z<dm*dm { wp[z]=Wq[z]; wm[z]=Wq[z]; z=z+1 } 203 wp[qi]=Wq[qi]+h; wm[qi]=Wq[qi]-h 204 let lp: i64 = blk_lossval(tape,vals,st,X,wp,Wk,Wv,Wo,Wg,Wu,Wd,Tg,T,dm,ffn,scale) 205 let lm: i64 = blk_lossval(tape,vals,st,X,wm,Wk,Wv,Wo,Wg,Wu,Wd,Tg,T,dm,ffn,scale) 206 let fd: i64 = ((lp-lm)*Q16)/(2*h) 207 let num: i64 = g_abs(fd-ana) 208 var den: i64 = g_abs(ana); if den<floor_q { den=floor_q } 209 if num >= ((16384*den)>>16) { a4_ok=0 } // tol 1/4 (longest fixed-point chain in the block) 210 let rel: i64 = (num*1000)/den 211 if rel>a4_worst { a4_worst=rel } 212 qi=qi+1 213 } 214 g_puts(" [measure] block dL/dWq (full chain) worst rel grad err = " as *u8); g_pn(a4_worst); g_puts(" /1000 (tol=250)\n" as *u8) 215 pass=pass+g_check("A4: FULL-BLOCK gradcheck wrt Wq through FFN+residual+attention+RoPE+softmax == finite diff" as *u8, a4_ok); total=total+1 216 217 // ---- D neg-control teeth (block Wd grad) ---- 218 let lossd: i64 = blk_loss(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,Wd,Tg,T,dm,ffn,scale,lv) 219 nfa_backward(tape,vals,grads,st[0],lossd) 220 let dana: i64 = nfa_grad(tape,grads,lv[1],0) 221 let wp0: *i64 = sys_mmap(ffn*dm*8) as *i64 222 let wm0: *i64 = sys_mmap(ffn*dm*8) as *i64 223 var z0: i64=0 224 while z0<ffn*dm { wp0[z0]=Wd[z0]; wm0[z0]=Wd[z0]; z0=z0+1 } 225 wp0[0]=Wd[0]+h; wm0[0]=Wd[0]-h 226 let dfd: i64 = ((blk_lossval(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,wp0,Tg,T,dm,ffn,scale) - blk_lossval(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,wm0,Tg,T,dm,ffn,scale))*Q16)/(2*h) 227 let dbad: i64 = 0 - dana 228 var dden: i64 = g_abs(dana); if dden<floor_q { dden=floor_q } 229 var caught: i64 = 1 230 if g_abs(dfd-dbad) < ((8192*dden)>>16) { caught=0 } 231 pass=pass+g_check("D: neg-control -- a WRONG block gradient is rejected (teeth)" as *u8, caught); total=total+1 232 233 // ---- B the block TRAINS: fix all weights except Wd (Y linear in Wd -> convex); realizable teacher target ---- 234 let Wdt: *i64 = sys_mmap(ffn*dm*8) as *i64; Wdt[0]=49152; Wdt[1]=0-32768; Wdt[2]=16384; Wdt[3]=65536; Wdt[4]=0-16384; Wdt[5]=32768; Wdt[6]=24576; Wdt[7]=0-49152 235 let tgt: *i64 = sys_mmap(T*dm*8) as *i64 236 blk_out(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,Wdt,T,dm,ffn,scale,tgt) // target = block output with Wd* 237 let Wdp: *i64 = sys_mmap(ffn*dm*8) as *i64 238 var zz: i64=0 239 while zz<ffn*dm { Wdp[zz]=0; zz=zz+1 } // learn Wd from zero 240 let gW: *i64 = sys_mmap(ffn*dm*8) as *i64 241 let lvb: *i64 = sys_mmap(2*8) as *i64 242 var lf: i64=0; var ll: i64=0 243 var ep: i64=0 244 while ep < 8000 { 245 let lossb: i64 = blk_loss(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,Wdp,tgt,T,dm,ffn,scale,lvb) 246 nfa_backward(tape,vals,grads,st[0],lossb) 247 if ep==0 { lf = nfa_val(tape,vals,lossb,0) } 248 ll = nfa_val(tape,vals,lossb,0) 249 var z: i64=0 250 while z<ffn*dm { gW[z]=nfa_grad(tape,grads,lvb[1],z); z=z+1 } 251 nfa_sgd(Wdp, gW, ffn*dm, 1024) 252 ep=ep+1 253 } 254 g_puts(" [measure] block train (Wd) loss: start=" as *u8); g_pn(lf); g_puts(" end=" as *u8); g_pn(ll); g_puts("\n" as *u8) 255 // (T=2,ffn=4 -> Wd is under-determined, so GD reaches a valid minimizer with loss->0, NOT necessarily Wd*; 256 // the honest evidence that the block TRAINS is the loss collapse driven by the end-to-end backward.) 257 var learns: i64 = 1 258 if ll*20 > lf { learns=0 } // >= 95% loss reduction (loss collapses to ~0) 259 if lf <= 100 { learns=0 } // started genuinely untrained 260 pass=pass+g_check("B: the BLOCK TRAINS -- the FFN down-proj is driven by the block's end-to-end backward; loss collapses to ~0" as *u8, learns); total=total+1 261 262 // ---- C bit-exact ---- 263 let Wdp2: *i64 = sys_mmap(ffn*dm*8) as *i64 264 var z2: i64=0 265 while z2<ffn*dm { Wdp2[z2]=0; z2=z2+1 } 266 let gW2: *i64 = sys_mmap(ffn*dm*8) as *i64 267 let lvc: *i64 = sys_mmap(2*8) as *i64 268 var ep2: i64=0 269 while ep2 < 8000 { 270 let lossc: i64 = blk_loss(tape,vals,st,X,Wq,Wk,Wv,Wo,Wg,Wu,Wdp2,tgt,T,dm,ffn,scale,lvc) 271 nfa_backward(tape,vals,grads,st[0],lossc) 272 var z: i64=0 273 while z<ffn*dm { gW2[z]=nfa_grad(tape,grads,lvc[1],z); z=z+1 } 274 nfa_sgd(Wdp2, gW2, ffn*dm, 1024) 275 ep2=ep2+1 276 } 277 var bitexact: i64 = 1 278 var zc: i64=0 279 while zc<ffn*dm { if Wdp2[zc]!=Wdp[zc] { bitexact=0 } zc=zc+1 } 280 pass=pass+g_check("C: bit-exact -- training the block twice gives IDENTICAL integer Wd (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(BLOG, 420) 285 if logf >= 0 { 286 b_ws(logf,"NOFLOATBLOCK pre-norm single-head A1_had=" as *u8); b_wn(logf,ha_ok); b_ws(logf," A2_rmsrows=" as *u8); b_wn(logf,ra_ok) 287 b_ws(logf," A3_Wd=" as *u8); b_wn(logf,a3_ok); b_ws(logf," A4_Wq_fullchain=" as *u8); b_wn(logf,a4_ok); b_ws(logf," D=" as *u8); b_wn(logf,caught) 288 b_ws(logf," B_trains=" as *u8); b_wn(logf,learns); b_ws(logf," C_bitexact=" as *u8); b_wn(logf,bitexact) 289 if okall==1 { b_ws(logf," verdict=GREEN\n" as *u8) } else { b_ws(logf," verdict=RED\n" as *u8) } 290 sys_close(logf) 291 } 292 g_puts("---- nofloat_block 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 full pre-norm transformer block backprops + trains 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}