code wiki / _hdl_build / _gpu_bm_compute_gate.nx
_gpu_bm_compute_gate.nx source
↩ module page · 155 lines · 11895 B
1// _gpu_bm_compute_gate.nx -- BARE-METAL SOVEREIGN-GPU rung BM-GPU-C1: compute-class dispatch + GEMM through the
2// sovereign GPFIFO pipeline (model side, toward BM-GPU-7).
3//
4// Extends the FIFO model with engine-class binding: NVC56F_SET_OBJECT @0x0 (REAL FIFO method) binds a class id to
5// a subchannel; methods on a COMPUTE-bound subchannel route to a modeled compute engine. A sovereign driver fills
6// matrices A,B in modeled VRAM, emits a compute-dispatch pushbuffer (SET_OBJECT compute + matrix addrs/dims + LAUNCH),
7// and the modeled engine runs C = A*B, writing C to its GPU VA. The driver reads C and checks it against an
8// INDEPENDENT reference GEMM -> proves the compute COMMAND STREAM was decoded + dispatched correctly.
9//
10// NISHI-ECOSYSTEM-ONLY: our model+driver+command-stream. HONEST SCOPE: SET_OBJECT/class-bind is spec-faithful; the
11// compute-class method OFFSETS here are REPRESENTATIVE (the production NVC6C0/Blackwell QMD + a real SASS GEMM kernel
12// is BM-GPU-7 on real silicon). The modeled engine STANDS IN for SASS execution. This gates the dispatch+result LOGIC.
13//
14// GREEN iff: after the dispatch, C == independent reference GEMM (4x4 int); AND tampers (no SET_OBJECT class-bind /
15// no LAUNCH) leave C unwritten (dispatch is gated on class-bind + launch).
16// Marker -> knowledge/status/gpu_baremetal.log (BMCOMPUTEGATE). license_tier: ORIGINAL
17import "nx_syscalls.nx"
18
19const COMPUTE_CLASS: i64 = 0xCDC0 // Blackwell compute class (representative id)
20const DIM: i64 = 4 // 4x4 matrices
21
22func p(s: *u8) -> i64 { var nn: i64=0; while s[nn]!=(0 as u8){nn=nn+1} sys_write(1,s,nn); return 0 }
23func fp(fd: i64, s: *u8) -> i64 { var nn: i64=0; while s[nn]!=(0 as u8){nn=nn+1} sys_write(fd,s,nn); return 0 }
24func n(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)}; 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{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 }
25func x(v: i64) -> i64 { p("0x" as *u8); let bb:*u8=sys_mmap(20); var k:i64=0; var m:i64=v; if m==0{bb[0]=48;k=1}; while m>0{ let d:i64=m&15; if d<10{bb[k]=(48+d) as u8}else{bb[k]=(87+d) as u8}; m=(m>>4); k=k+1 } var i:i64=0; let o:*u8=sys_mmap(20); while i<k{o[i]=bb[k-1-i];i=i+1} sys_write(1,o,k); return 0 }
26func fx(fd: i64, v: i64) -> i64 { let bb:*u8=sys_mmap(20); var k:i64=0; var m:i64=v; if m==0{bb[0]=48;k=1}; while m>0{ let d:i64=m&15; if d<10{bb[k]=(48+d) as u8}else{bb[k]=(87+d) as u8}; m=(m>>4); k=k+1 } let o:*u8=sys_mmap(20); var i:i64=0; while i<k{o[i]=bb[k-1-i];i=i+1} fp(fd,"0x" as *u8); sys_write(fd,o,k); return 0 }
27func rd32(b: *u8, o: i64) -> i64 { return (b[o] as i64)|((b[o+1] as i64)<<8)|((b[o+2] as i64)<<16)|((b[o+3] as i64)<<24) }
28func wr32(b: *u8, o: i64, v: i64) -> i64 { b[o]=(v&0xff) as u8; b[o+1]=((v>>8)&0xff) as u8; b[o+2]=((v>>16)&0xff) as u8; b[o+3]=((v>>24)&0xff) as u8; return 0 }
29
30// ===== FIFO model with class binding + compute engine =====
31// compute method offsets (representative): A_LO@0x100 A_HI@0x104 B_LO@0x108 B_HI@0x10c C_LO@0x110 C_HI@0x114
32// M@0x118 N@0x11c K@0x120 LAUNCH@0x124. cs[] = compute state: [a,b,c,M,N,K, bound_class_subch1]
33func gpfifo_run_compute(gmem: *u8, pb_off: i64, pb_dwords: i64, cs: *i64) -> i64 {
34 var i: i64 = 0
35 while i < pb_dwords {
36 let hdr: i64 = rd32(gmem, pb_off + i*4); i = i + 1
37 let mode: i64 = (hdr >> 29) & 0x7; let count: i64 = (hdr >> 16) & 0x1fff
38 let subch: i64 = (hdr >> 13) & 0x7; let method0: i64 = (hdr & 0xfff) << 2
39 var j: i64 = 0
40 while j < count {
41 if i >= pb_dwords { j = count } else {
42 let data: i64 = rd32(gmem, pb_off + i*4); i = i + 1
43 var m: i64 = method0; if mode == 1 { m = method0 + j*4 }
44 if m == 0x0 { cs[6] = data } // SET_OBJECT -> bind class to (this) subch
45 if cs[6] == COMPUTE_CLASS { // compute-class methods
46 if m == 0x100 { cs[0] = (cs[0] & (0-1<<32)) | (data & 0xffffffff) } // A_LO
47 if m == 0x104 { cs[0] = (cs[0] & 0xffffffff) | (data << 32) } // A_HI
48 if m == 0x108 { cs[1] = (cs[1] & (0-1<<32)) | (data & 0xffffffff) }
49 if m == 0x10c { cs[1] = (cs[1] & 0xffffffff) | (data << 32) }
50 if m == 0x110 { cs[2] = (cs[2] & (0-1<<32)) | (data & 0xffffffff) }
51 if m == 0x114 { cs[2] = (cs[2] & 0xffffffff) | (data << 32) }
52 if m == 0x118 { cs[3] = data }
53 if m == 0x11c { cs[4] = data }
54 if m == 0x120 { cs[5] = data }
55 if m == 0x124 { // LAUNCH -> run the GEMM (modeled SASS)
56 var ii: i64 = 0
57 while ii < cs[3] {
58 var jj: i64 = 0
59 while jj < cs[4] {
60 var sum: i64 = 0; var kk: i64 = 0
61 while kk < cs[5] {
62 let av: i64 = rd32(gmem, cs[0] + (ii*cs[5]+kk)*4)
63 let bv: i64 = rd32(gmem, cs[1] + (kk*cs[4]+jj)*4)
64 sum = sum + av*bv; kk = kk + 1
65 }
66 wr32(gmem, cs[2] + (ii*cs[4]+jj)*4, sum); jj = jj + 1
67 }
68 ii = ii + 1
69 }
70 }
71 }
72 j = j + 1
73 }
74 }
75 }
76 return 0
77}
78func emit_hdr(gmem: *u8, off: i64, mode: i64, count: i64, subch: i64, method: i64) -> i64 {
79 wr32(gmem, off, (mode << 29) | (count << 16) | (subch << 13) | ((method >> 2) & 0xfff)); return 0
80}
81
82func main() -> i64 {
83 p("=== BARE-METAL SOVEREIGN-GPU BM-GPU-C1: compute-class dispatch + 4x4 GEMM through the GPFIFO pipeline ===\n" as *u8)
84 let gmem: *u8 = sys_mmap(8388608)
85 let A: i64 = 0x10000; let B: i64 = 0x11000; let C: i64 = 0x12000; let PB: i64 = 0x20000
86
87 // ---- driver: fill A (4x4) and B (4x4) in VRAM with known ints; compute the independent reference ----
88 let refC: *i64 = sys_mmap(256)
89 var ii: i64 = 0
90 while ii < DIM { var kk: i64 = 0; while kk < DIM { wr32(gmem, A + (ii*DIM+kk)*4, ii+kk+1); kk=kk+1 } ii=ii+1 } // A[i][k]=i+k+1
91 var kk2: i64 = 0
92 while kk2 < DIM { var jj: i64 = 0; while jj < DIM { wr32(gmem, B + (kk2*DIM+jj)*4, kk2+jj+2); jj=jj+1 } kk2=kk2+1 } // B[k][j]=k+j+2
93 ii = 0
94 while ii < DIM { var jj: i64 = 0; while jj < DIM { var s: i64 = 0; var k: i64 = 0; while k < DIM { s = s + (ii+k+1)*(k+jj+2); k=k+1 } refC[ii*DIM+jj] = s; jj=jj+1 } ii=ii+1 }
95
96 // ---- emit the compute-dispatch pushbuffer: SET_OBJECT(compute) + addrs/dims (9) + LAUNCH ----
97 var o: i64 = 0
98 emit_hdr(gmem, PB+o, 1, 1, 1, 0x0); o=o+4; wr32(gmem, PB+o, COMPUTE_CLASS); o=o+4 // SET_OBJECT compute on subch1
99 emit_hdr(gmem, PB+o, 1, 9, 1, 0x100); o=o+4 // 9 increasing methods @0x100..0x120
100 wr32(gmem, PB+o, A & 0xffffffff); o=o+4; wr32(gmem, PB+o, (A>>32)&0xffffffff); o=o+4
101 wr32(gmem, PB+o, B & 0xffffffff); o=o+4; wr32(gmem, PB+o, (B>>32)&0xffffffff); o=o+4
102 wr32(gmem, PB+o, C & 0xffffffff); o=o+4; wr32(gmem, PB+o, (C>>32)&0xffffffff); o=o+4
103 wr32(gmem, PB+o, DIM); o=o+4; wr32(gmem, PB+o, DIM); o=o+4; wr32(gmem, PB+o, DIM); o=o+4
104 emit_hdr(gmem, PB+o, 1, 1, 1, 0x124); o=o+4; wr32(gmem, PB+o, 1); o=o+4 // LAUNCH
105 let pb_dwords: i64 = o / 4
106
107 // ---- run the dispatch (the FIFO/compute model) ----
108 let cs: *i64 = sys_mmap(128); cs[6] = 0
109 gpfifo_run_compute(gmem, PB, pb_dwords, cs)
110 // compare C (model output) to refC
111 var matched: i64 = 1; var nz: i64 = 0
112 ii = 0
113 while ii < DIM*DIM { let cv: i64 = rd32(gmem, C + ii*4); if cv != refC[ii] { matched = 0 } if cv != 0 { nz = nz + 1 } ii = ii + 1 }
114 p(" GEMM dispatched. C[0,0]=" as *u8); n(rd32(gmem, C)); p(" ref=" as *u8); n(refC[0]); p(" | C[3,3]=" as *u8); n(rd32(gmem, C+15*4)); p(" ref=" as *u8); n(refC[15]); p(" | all_match=" as *u8); n(matched); p(" nonzero=" as *u8); n(nz); p("\n" as *u8)
115
116 // ---- TAMPERS ----
117 // T1: no SET_OBJECT (class never bound) -> compute methods ignored -> C stays 0
118 var z: i64 = 0; while z < DIM*DIM { wr32(gmem, C + z*4, 0); z=z+1 }
119 var o2: i64 = 0
120 emit_hdr(gmem, PB+o2, 1, 9, 1, 0x100); o2=o2+4
121 wr32(gmem,PB+o2,A&0xffffffff);o2=o2+4; wr32(gmem,PB+o2,0);o2=o2+4; wr32(gmem,PB+o2,B&0xffffffff);o2=o2+4; wr32(gmem,PB+o2,0);o2=o2+4
122 wr32(gmem,PB+o2,C&0xffffffff);o2=o2+4; wr32(gmem,PB+o2,0);o2=o2+4; wr32(gmem,PB+o2,DIM);o2=o2+4; wr32(gmem,PB+o2,DIM);o2=o2+4; wr32(gmem,PB+o2,DIM);o2=o2+4
123 emit_hdr(gmem, PB+o2, 1, 1, 1, 0x124); o2=o2+4; wr32(gmem, PB+o2, 1); o2=o2+4
124 let cs2: *i64 = sys_mmap(128); cs2[6] = 0; gpfifo_run_compute(gmem, PB, o2/4, cs2)
125 var t_noobj: i64 = 1; z = 0; while z < DIM*DIM { if rd32(gmem, C+z*4) != 0 { t_noobj = 0 } z=z+1 }
126 // T2: SET_OBJECT but no LAUNCH -> C stays 0
127 z = 0; while z < DIM*DIM { wr32(gmem, C + z*4, 0); z=z+1 }
128 var o3: i64 = 0
129 emit_hdr(gmem, PB+o3, 1, 1, 1, 0x0); o3=o3+4; wr32(gmem, PB+o3, COMPUTE_CLASS); o3=o3+4
130 emit_hdr(gmem, PB+o3, 1, 9, 1, 0x100); o3=o3+4
131 wr32(gmem,PB+o3,A&0xffffffff);o3=o3+4; wr32(gmem,PB+o3,0);o3=o3+4; wr32(gmem,PB+o3,B&0xffffffff);o3=o3+4; wr32(gmem,PB+o3,0);o3=o3+4
132 wr32(gmem,PB+o3,C&0xffffffff);o3=o3+4; wr32(gmem,PB+o3,0);o3=o3+4; wr32(gmem,PB+o3,DIM);o3=o3+4; wr32(gmem,PB+o3,DIM);o3=o3+4; wr32(gmem,PB+o3,DIM);o3=o3+4
133 let cs3: *i64 = sys_mmap(128); cs3[6] = 0; gpfifo_run_compute(gmem, PB, o3/4, cs3) // no LAUNCH method
134 var t_nolaunch: i64 = 1; z = 0; while z < DIM*DIM { if rd32(gmem, C+z*4) != 0 { t_nolaunch = 0 } z=z+1 }
135 p(" [tamper] no-SET_OBJECT C-unwritten=" as *u8); n(t_noobj); p(" no-LAUNCH C-unwritten=" as *u8); n(t_nolaunch); p("\n" as *u8)
136
137 var pass: i64 = 0
138 if matched == 1 { if nz == DIM*DIM { if t_noobj == 1 { if t_nolaunch == 1 { pass = 1 } } } }
139 p(" checks: gemm_matches_reference=" as *u8); n(matched); p(" all16_nonzero=" as *u8); n(nz==16); p(" class-bind-required=" as *u8); n(t_noobj); p(" launch-required=" as *u8); n(t_nolaunch); p("\n" as *u8)
140
141 let lfd: i64 = sys_openat_append("knowledge/status/gpu_baremetal.log" as *u8, 0x1a4)
142 if pass == 1 {
143 p("BMCOMPUTEGATE verdict=GREEN reason=sovereign-compute-dispatch-through-GPFIFO (NVC56F SET_OBJECT binds compute class 0xCDC0 to subch; compute methods set A/B/C addrs + M/N/K; LAUNCH -> modeled engine runs 4x4 int GEMM reading A,B from VRAM, writes C; C MATCHES independent reference; tampers no-class-bind+no-LAUNCH leave C unwritten) SCOPE=compute-DISPATCH+result-LOGIC-vs-model[SET_OBJECT-faithful,compute-methods-representative,engine-stands-in-for-SASS]; real-NVC6C0-QMD+Blackwell-SASS=BM-GPU-7\n" as *u8)
144 if lfd >= 0 {
145 fp(lfd, "BMCOMPUTEGATE verdict=GREEN rung=BM-GPU-C1-compute-dispatch-gemm device=sovereign-compute-FIFO-model class=0xCDC0(rep) gemm=4x4-int C[0,0]=" as *u8); fx(lfd, rd32(gmem,C))
146 fp(lfd, " matches_reference=1 all16_nonzero=1 tampers=held(no-class-bind+no-launch->C-unwritten) scope=dispatch+result-logic-vs-model(SET_OBJECT-faithful;compute-methods-representative;engine-stands-in-for-SASS) next=BM-GPU-6-real-silicon-NATIVE-LINUX / BM-GPU-7-NVC6C0-QMD+Blackwell-SASS-GEMM\n" as *u8)
147 sys_close(lfd)
148 }
149 sys_exit(0); return 0
150 }
151 p("BMCOMPUTEGATE verdict=RED (gemm mismatch or tamper not satisfied)\n" as *u8)
152 if lfd >= 0 { fp(lfd, "BMCOMPUTEGATE verdict=RED see-console\n" as *u8); sys_close(lfd) }
153 sys_exit(1)
154 return 1
155}