code wiki / _hdl_build / _f64_soak_gate_authored.nx
_f64_soak_gate_authored.nx source
↩ module page · 164 lines · 5597 B
1// _f64_soak_gate_authored.nx -- SOVEREIGN ORACLE anchor + soak gate (ME0b + py-debt
2// retirement for ME0). Pure Nishi end to end: no python, no shell.
3//
4// Phase 1 ANCHOR: nx_f64_oracle_sov must reproduce ALL stored expected values of the
5// 1217-vector KAT set for ops add/sub/mul/div/sqrt. Those vectors were anchored to
6// hardware IEEE once; the sovereign oracle matching them transfers the anchor, after
7// which vector regeneration never needs python again.
8// Phase 2 SOAK: sovereign xorshift64* PRNG generates raw bit patterns (every class:
9// normals, subnormals, zeros, infs, NaNs reachable); for each, impl (nx_f64_*) vs
10// oracle (orc_*) must agree BIT-EXACTLY across all 5 ops.
11//
12// Markers:
13// ANCHOR total= ok= bad= / SOAKBAD op= a= b= impl= orc= / SOAK total= bad=
14// F64SOAKGATE verdict=GREEN|RED
15
16import "nx_syscalls.nx"
17import "nx_f64.nx"
18import "nx_f64_div.nx"
19import "nx_f64_sqrt.nx"
20import "nx_f64_cvt.nx"
21import "nx_f64_oracle_sov.nx"
22import "_f64_kat_vectors.nx"
23
24func f6s_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
25
26func f6s_putn(v: i64) -> i64 {
27 let bb: *u8 = sys_mmap(28)
28 var m: i64 = v
29 if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) }
30 let t: *u8 = sys_mmap(28)
31 var k: i64 = 0
32 if m == 0 { t[0] = 48; k = 1 }
33 while m > 0 { t[k] = 48 + (m % 10); m = m / 10; k = k + 1 }
34 var i: i64 = 0
35 while i < k { bb[i] = t[k-1-i]; i = i + 1 }
36 sys_write(1, bb, k)
37 return 0
38}
39
40func f6s_puthex(v: i64) -> i64 {
41 let bb: *u8 = sys_mmap(20)
42 var i: i64 = 0
43 while i < 16 {
44 let nib: i64 = (v >> ((15 - i) * 4)) & 15
45 if nib < 10 { bb[i] = 48 + nib } else { bb[i] = 55 + nib }
46 i = i + 1
47 }
48 sys_write(1, bb, 16)
49 return 0
50}
51
52// sovereign PRNG: xorshift64* (Vigna), wraps naturally on i64 multiply.
53func f6s_rng(state: *i64) -> i64 {
54 var s: i64 = state[0]
55 s = s ^ ((s >> 12) & 0x000FFFFFFFFFFFFF) // logical >> via mask (12 bits)
56 s = s ^ (s << 25)
57 s = s ^ ((s >> 27) & 0x0000001FFFFFFFFF) // logical >> via mask (27 bits)
58 state[0] = s
59 return s * 2685821657736338717
60}
61
62func f6s_orc(op: i64, a: i64, b: i64) -> i64 {
63 if op == 1 { return orc_add(a, b) }
64 if op == 2 { return orc_sub(a, b) }
65 if op == 3 { return orc_mul(a, b) }
66 if op == 4 { return orc_div(a, b) }
67 if op == 5 { return orc_sqrt(a) }
68 return 0 - 1
69}
70
71func f6s_impl(op: i64, a: i64, b: i64) -> i64 {
72 if op == 1 { return nx_f64_add(a, b) }
73 if op == 2 { return nx_f64_sub(a, b) }
74 if op == 3 { return nx_f64_mul(a, b) }
75 if op == 4 { return nx_f64_div(a, b) }
76 if op == 5 { return nx_f64_sqrt(a) }
77 return 0 - 1
78}
79
80func main() -> i64 {
81 // ---- phase 1: anchor ----
82 let ops: *i64 = sys_mmap(8 * 1400) as *i64
83 let av: *i64 = sys_mmap(8 * 1400) as *i64
84 let bv: *i64 = sys_mmap(8 * 1400) as *i64
85 let ev: *i64 = sys_mmap(8 * 1400) as *i64
86 let n: i64 = f64_kat_fill_all(ops, av, bv, ev)
87
88 var a_total: i64 = 0
89 var a_ok: i64 = 0
90 var a_bad: i64 = 0
91 var i: i64 = 0
92 while i < n {
93 let op: i64 = ops[i]
94 if op >= 1 {
95 if op <= 5 {
96 a_total = a_total + 1
97 let got: i64 = f6s_orc(op, av[i], bv[i])
98 if got == ev[i] {
99 a_ok = a_ok + 1
100 } else {
101 a_bad = a_bad + 1
102 if a_bad <= 25 {
103 f6s_puts("ANCHORBAD i=" as *u8); f6s_putn(i)
104 f6s_puts(" op=" as *u8); f6s_putn(op)
105 f6s_puts(" a=" as *u8); f6s_puthex(av[i])
106 f6s_puts(" b=" as *u8); f6s_puthex(bv[i])
107 f6s_puts(" exp=" as *u8); f6s_puthex(ev[i])
108 f6s_puts(" orc=" as *u8); f6s_puthex(got)
109 f6s_puts("\n" as *u8)
110 }
111 }
112 }
113 }
114 i = i + 1
115 }
116 f6s_puts("ANCHOR total=" as *u8); f6s_putn(a_total)
117 f6s_puts(" ok=" as *u8); f6s_putn(a_ok)
118 f6s_puts(" bad=" as *u8); f6s_putn(a_bad)
119 f6s_puts("\n" as *u8)
120
121 // ---- phase 2: sovereign soak ----
122 let st: *i64 = sys_mmap(16) as *i64
123 st[0] = 88172645463325252 // fixed seed: deterministic, re-runnable
124 var s_total: i64 = 0
125 var s_bad: i64 = 0
126 var round: i64 = 0
127 while round < 40000 {
128 let ra: i64 = f6s_rng(st)
129 let rb: i64 = f6s_rng(st)
130 var op: i64 = 1
131 while op <= 5 {
132 s_total = s_total + 1
133 let gi: i64 = f6s_impl(op, ra, rb)
134 let go: i64 = f6s_orc(op, ra, rb)
135 if gi != go {
136 s_bad = s_bad + 1
137 if s_bad <= 25 {
138 f6s_puts("SOAKBAD op=" as *u8); f6s_putn(op)
139 f6s_puts(" a=" as *u8); f6s_puthex(ra)
140 f6s_puts(" b=" as *u8); f6s_puthex(rb)
141 f6s_puts(" impl=" as *u8); f6s_puthex(gi)
142 f6s_puts(" orc=" as *u8); f6s_puthex(go)
143 f6s_puts("\n" as *u8)
144 }
145 }
146 op = op + 1
147 }
148 round = round + 1
149 }
150 f6s_puts("SOAK total=" as *u8); f6s_putn(s_total)
151 f6s_puts(" bad=" as *u8); f6s_putn(s_bad)
152 f6s_puts("\n" as *u8)
153
154 if a_bad == 0 {
155 if s_bad == 0 {
156 f6s_puts("F64SOAKGATE verdict=GREEN\n" as *u8)
157 return 0
158 }
159 }
160 f6s_puts("F64SOAKGATE verdict=RED\n" as *u8)
161 var rc: i64 = a_bad + s_bad
162 if rc > 100 { rc = 100 }
163 return rc
164}