code wiki / _hdl_build / nx_intfp_moe_gradcheck_gate.nx

nx_intfp_moe_gradcheck_gate.nx source

↩ module page · 116 lines · 8235 B

1// nx_intfp_moe_gradcheck_gate.nx -- 2026 FRONTIER capability in the sovereign integer stack: MIXTURE-OF-EXPERTS 2// routing, gradchecked, NO float. MoE is UNIVERSAL in 2026 (DeepSeek/Qwen/Llama/GLM/Kimi all MoE). The novel part 3// vs a dense FFN is ROUTING: router logits -> top-K experts -> softmax gate over the selected -> weighted expert 4// sum, with the gradient flowing back THROUGH the gate softmax INTO the router. Experts here are linear (the 5// SwiGLU expert is already proven) so the gate focuses on the routing mechanism. Q20 integer, integer finite-diff 6// gradcheck (max-|grad| metric) on the ROUTER Wr (the frontier novelty) AND an expert We. license_tier: ORIGINAL 7import "nx_syscalls.nx" 8 9func w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 10func wn(v: i64) -> i64 { if v==0 { sys_write(1,"0" as *u8,1); return 0 } var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} let t: *u8=sys_mmap(24); var k: i64=0; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} let o: *u8=sys_mmap(24); var q: i64=k-1; var i: i64=0; while q>=0{o[i]=t[q];i=i+1;q=q-1} sys_write(1,o,i); return 0 } 11func iabs(v: i64) -> i64 { if v<0 { return 0-v } return v } 12 13const S: i64 = 1048576 // Q20 14const T: i64 = 3 15const DM: i64 = 6 16const NE: i64 = 4 // experts 17// K=2 (top-2 routing, like DeepSeek/Mixtral) 18 19func fp_exp(xq: i64) -> i64 { let y: i64=(xq*1512776)/S; var yi: i64=0; if y>=0 { yi=y/S } else { yi=0-(((0-y)+S-1)/S) } let yf: i64=y-yi*S; var p: i64=10085; p=58197+(p*yf)/S; p=251882+(p*yf)/S; p=726817+(p*yf)/S; p=S+(p*yf)/S; if yi>=0 { if yi>=31 { return 2000000000 } return p*(1<<yi) } let k: i64=0-yi; if k>=31 { return 0 } return p/(1<<k) } 20 21// slots: 0x 1Wr 2We | 3r 4e1 5e2 6w1 7w2 8oe1 9oe2 10y | 11dWr 12dWe 22// forward: router -> top-2 -> gate softmax -> weighted expert-linear sum; returns L_q32 23func moe_fwd(P: *i64) -> i64 { 24 let x: *i64=P[0] as *i64; let Wr: *i64=P[1] as *i64; let We: *i64=P[2] as *i64 25 let r: *i64=P[3] as *i64; let e1: *i64=P[4] as *i64; let e2: *i64=P[5] as *i64; let w1: *i64=P[6] as *i64; let w2: *i64=P[7] as *i64 26 let oe1: *i64=P[8] as *i64; let oe2: *i64=P[9] as *i64; let y: *i64=P[10] as *i64 27 // router logits r[t,e] 28 var t: i64=0 29 while t<T { var e: i64=0; while e<NE { var acc: i64=0; var k: i64=0; while k<DM { acc=acc+x[t*DM+k]*Wr[k*NE+e]; k=k+1 } r[t*NE+e]=acc/S; e=e+1 } t=t+1 } 30 var Lq: i64=0; t=0 31 while t<T { 32 // top-2 experts by logit 33 var be1: i64=0; var br1: i64=r[t*NE+0]; var e: i64=1; while e<NE { if r[t*NE+e]>br1 { br1=r[t*NE+e]; be1=e } e=e+1 } 34 var be2: i64=0-1; var br2: i64=0-2000000000; e=0; while e<NE { if e!=be1 { if r[t*NE+e]>br2 { br2=r[t*NE+e]; be2=e } } e=e+1 } 35 e1[t]=be1; e2[t]=be2 36 // 2-way softmax gate over {br1, br2}; br1 is the max 37 let ex1: i64=fp_exp(br1-br1); let ex2: i64=fp_exp(br2-br1); let sum: i64=ex1+ex2 38 w1[t]=(ex1*S+sum/2)/sum; w2[t]=(ex2*S+sum/2)/sum 39 // expert-linear outputs oe = x @ We[expert] 40 var i: i64=0 41 while i<DM { var a1: i64=0; var a2: i64=0; var k: i64=0; while k<DM { a1=a1+x[t*DM+k]*We[be1*DM*DM+k*DM+i]; a2=a2+x[t*DM+k]*We[be2*DM*DM+k*DM+i]; k=k+1 } oe1[t*DM+i]=a1/S; oe2[t*DM+i]=a2/S; i=i+1 } 42 // weighted sum + loss 43 i=0; while i<DM { let yv: i64=(w1[t]*oe1[t*DM+i])/S + (w2[t]*oe2[t*DM+i])/S; y[t*DM+i]=yv; Lq=Lq+yv*yv; i=i+1 } 44 t=t+1 45 } 46 return Lq 47} 48// backward: fills dWr, dWe (gradient flows through gate softmax into the router) 49func moe_bwd(P: *i64) -> i64 { 50 let x: *i64=P[0] as *i64; let We: *i64=P[2] as *i64 51 let e1: *i64=P[4] as *i64; let e2: *i64=P[5] as *i64; let w1: *i64=P[6] as *i64; let w2: *i64=P[7] as *i64 52 let oe1: *i64=P[8] as *i64; let oe2: *i64=P[9] as *i64; let y: *i64=P[10] as *i64 53 let dWr: *i64=P[11] as *i64; let dWe: *i64=P[12] as *i64 54 var z: i64=0; while z<DM*NE { dWr[z]=0; z=z+1 } z=0; while z<NE*DM*DM { dWe[z]=0; z=z+1 } 55 var t: i64=0 56 while t<T { 57 let ee1: i64=e1[t]; let ee2: i64=e2[t]; let ww1: i64=w1[t]; let ww2: i64=w2[t] 58 // dy, d(expert outputs)=w*dy, gate-weight grads dw=sum_i dy*oe 59 var dw1: i64=0; var dw2: i64=0; var i: i64=0 60 while i<DM { let dy: i64=2*y[t*DM+i]; let do1: i64=(ww1*dy)/S; let do2: i64=(ww2*dy)/S 61 // dWe[expert][k,i] += x[t,k]*d(expert_out) 62 var k: i64=0; while k<DM { dWe[ee1*DM*DM+k*DM+i]=dWe[ee1*DM*DM+k*DM+i]+(x[t*DM+k]*do1)/S; dWe[ee2*DM*DM+k*DM+i]=dWe[ee2*DM*DM+k*DM+i]+(x[t*DM+k]*do2)/S; k=k+1 } 63 dw1=dw1+(dy*oe1[t*DM+i])/S; dw2=dw2+(dy*oe2[t*DM+i])/S; i=i+1 } 64 // 2-way softmax backward: gate=softmax(r_e1,r_e2); dr_e = w_e*(dw_e - dot), dot=sum w*dw 65 let dot: i64=(ww1*dw1)/S+(ww2*dw2)/S 66 let dre1: i64=(ww1*(dw1-dot))/S; let dre2: i64=(ww2*(dw2-dot))/S 67 // dWr[k,e] += x[t,k]*dr_e (selected experts only; unselected dr=0) 68 var k: i64=0; while k<DM { dWr[k*NE+ee1]=dWr[k*NE+ee1]+(x[t*DM+k]*dre1)/S; dWr[k*NE+ee2]=dWr[k*NE+ee2]+(x[t*DM+k]*dre2)/S; k=k+1 } 69 t=t+1 70 } 71 return 0 72} 73 74func gcheck(name: *u8, P: *i64, Wt: *i64, dW: *i64, ncell: i64) -> i64 { 75 let DELTA: i64=2097; let TOLP: i64=70 // delta~0.002 at Q20; err vs max|grad| 76 var maxabs: i64=1; var q: i64=0; while q<ncell { if iabs(dW[q])>maxabs { maxabs=iabs(dW[q]) } q=q+1 } 77 var npass: i64=0; var worst: i64=0; var i: i64=0 78 while i<ncell { 79 let save: i64=Wt[i] 80 Wt[i]=save+DELTA; let Lp: i64=moe_fwd(P) 81 Wt[i]=save-DELTA; let Lm: i64=moe_fwd(P) 82 Wt[i]=save; let dd: i64=moe_fwd(P) 83 let num: i64=(Lp-Lm)/(2*DELTA); let rel: i64=(iabs(num-dW[i])*1000)/maxabs 84 if rel<=TOLP { npass=npass+1 } else { w(" " as *u8); w(name); w(" cell " as *u8); wn(i); w(" ana=" as *u8); wn(dW[i]); w(" num=" as *u8); wn(num); w(" rel=" as *u8); wn(rel); w("\n" as *u8) } 85 if rel>worst { worst=rel } 86 i=i+1 87 } 88 w(" " as *u8); w(name); w(": " as *u8); wn(npass); w("/" as *u8); wn(ncell); w(" (worst=" as *u8); wn(worst); w("permil of max|grad|=" as *u8); wn(maxabs); w(")\n" as *u8) 89 return npass 90} 91 92func main() -> i64 { 93 w("=== nx_intfp_moe_gradcheck: 2026-FRONTIER Mixture-of-Experts routing (top-2) in Q20 INTEGER, no float ===\n\n" as *u8) 94 let P: *i64=sys_mmap(13*8) as *i64 95 P[0]=sys_mmap(T*DM*8); P[1]=sys_mmap(DM*NE*8); P[2]=sys_mmap(NE*DM*DM*8) 96 P[3]=sys_mmap(T*NE*8); P[4]=sys_mmap(T*8); P[5]=sys_mmap(T*8); P[6]=sys_mmap(T*8); P[7]=sys_mmap(T*8); P[8]=sys_mmap(T*DM*8); P[9]=sys_mmap(T*DM*8); P[10]=sys_mmap(T*DM*8) 97 P[11]=sys_mmap(DM*NE*8); P[12]=sys_mmap(NE*DM*DM*8) 98 let x: *i64=P[0] as *i64; let Wr: *i64=P[1] as *i64; let We: *i64=P[2] as *i64 99 var i: i64=0; while i<T*DM { x[i]=((((i*5+2)%11)-5)*S)/10; i=i+1 } 100 i=0; while i<DM*NE { Wr[i]=((((i*7+3)%13)-6)*S)/12; i=i+1 } // distinct-ish logits so top-2 is stable 101 i=0; while i<NE*DM*DM { We[i]=((((i*3+1)%11)-5)*S)/16; i=i+1 } 102 103 let L0: i64=moe_fwd(P); moe_bwd(P) 104 // report routing 105 let e1: *i64=P[4] as *i64; let e2: *i64=P[5] as *i64; let w1: *i64=P[6] as *i64 106 w(" routing: t0 -> experts [" as *u8); wn(e1[0]); w("," as *u8); wn(e2[0]); w("] gate w1=" as *u8); wn((w1[0]*1000)/S); w("permil ; t1->[" as *u8); wn(e1[1]); w("," as *u8); wn(e2[1]); w("] ; t2->[" as *u8); wn(e1[2]); w("," as *u8); wn(e2[2]); w("]\n" as *u8) 107 w(" forward L_q32=" as *u8); wn(L0); w("\n gradcheck (integer finite-diff):\n" as *u8) 108 let pr: i64=gcheck("Wr(router)" as *u8, P, Wr, P[11] as *i64, DM*NE) // THE frontier novelty: gradient into the router thru the gate 109 let pe: i64=gcheck("We(expert)" as *u8, P, We, P[12] as *i64, NE*DM*DM) // expert weights (per-token routed) 110 let tot: i64=pr+pe; let want: i64=DM*NE+NE*DM*DM 111 w("\n MoE gradcheck: " as *u8); wn(tot); w("/" as *u8); wn(want); w(" cells correct\n" as *u8) 112 w("NX-INTFP-MOE verdict=" as *u8) 113 if tot==want { w("GREEN " as *u8); wn(tot); w("/" as *u8); wn(want); w(" -- 2026-FRONTIER integer MoE routing PROVEN (top-2 + gate softmax + gradient into router), no float. Sovereign stack at the MoE frontier.\n" as *u8) } 114 else { w("RED " as *u8); wn(tot); w("/" as *u8); wn(want); w(" -- routing/gate Q-scaling bug\n" as *u8) } 115 return 0 116}