code wiki / (root) / nx_speculative_verify_test.nx

nx_speculative_verify_test.nx source

↩ module page · 152 lines · 6516 B

1// nx_speculative_verify_test.nx -- smoke for H3 speculative decoding. 2 3import "nx_syscalls.nx" 4import "nx_speculative_verify.nx" 5 6func main() -> i64 { 7 // ----- 1. Session construction ----- 8 let s: *NxSpeculativeSession = nx_speculative_session_new(2024, 8) 9 if nx_spec_session_is_valid(s) != 1 { return 1 } 10 if nx_spec_session_request_id(s) != 2024 { return 2 } 11 if nx_spec_session_max_k(s) != 8 { return 3 } 12 if nx_spec_total_drafted(s) != 0 { return 4 } 13 if nx_spec_total_accepted(s) != 0 { return 5 } 14 if nx_spec_total_committed(s) != 0 { return 6 } 15 if nx_spec_total_rounds(s) != 0 { return 7 } 16 if nx_spec_acceptance_rate_q16(s) != 0 { return 8 } 17 18 // Workspace buffers. 19 let draft: *i64 = (sys_mmap(128)) as *i64 20 let flags: *i64 = (sys_mmap(128)) as *i64 21 let out: *i64 = (sys_mmap(128)) as *i64 22 23 // ----- 2. All-accept round (8/8) ----- 24 var i: i64 = 0 25 while i < 8 { 26 draft[i] = 100 + i 27 flags[i] = 1 28 i = i + 1 29 } 30 let committed1: i64 = nx_speculative_verify(s, draft, flags, 8, 999, out) 31 // Accepted 8 + 1 bonus = 9 committed 32 if committed1 != 9 { return 9 } 33 // Check committed sequence: 100..107 then 999 34 if out[0] != 100 { return 10 } 35 if out[7] != 107 { return 11 } 36 if out[8] != 999 { return 12 } 37 if nx_spec_total_drafted(s) != 8 { return 13 } 38 if nx_spec_total_accepted(s) != 8 { return 14 } 39 if nx_spec_total_committed(s) != 9 { return 15 } 40 if nx_spec_total_rounds(s) != 1 { return 16 } 41 // Acceptance rate Q16 = 8/8 * 65536 = 65536 42 if nx_spec_acceptance_rate_q16(s) != 65536 { return 17 } 43 44 // ----- 3. Partial-accept round (3/5) ----- 45 let s2: *NxSpeculativeSession = nx_speculative_session_new(7, 8) 46 draft[0] = 200 47 draft[1] = 201 48 draft[2] = 202 49 draft[3] = 203 50 draft[4] = 204 51 flags[0] = 1 52 flags[1] = 1 53 flags[2] = 1 54 flags[3] = 0 // reject at index 3 55 flags[4] = 1 // -- ignored after first reject 56 let committed2: i64 = nx_speculative_verify(s2, draft, flags, 5, 777, out) 57 // Accepted 3 + 1 bonus = 4 committed 58 if committed2 != 4 { return 18 } 59 if out[0] != 200 { return 19 } 60 if out[1] != 201 { return 20 } 61 if out[2] != 202 { return 21 } 62 if out[3] != 777 { return 22 } 63 if nx_spec_total_drafted(s2) != 5 { return 23 } 64 if nx_spec_total_accepted(s2) != 3 { return 24 } 65 if nx_spec_total_committed(s2) != 4 { return 25 } 66 67 // ----- 4. All-reject round (0/4) ----- 68 flags[0] = 0 69 flags[1] = 0 70 flags[2] = 0 71 flags[3] = 0 72 let committed3: i64 = nx_speculative_verify(s2, draft, flags, 4, 555, out) 73 // Accepted 0 + 1 bonus = 1 committed 74 if committed3 != 1 { return 26 } 75 if out[0] != 555 { return 27 } 76 if nx_spec_total_drafted(s2) != 9 { return 28 } 77 if nx_spec_total_accepted(s2) != 3 { return 29 } 78 if nx_spec_total_committed(s2) != 5 { return 30 } 79 if nx_spec_total_rounds(s2) != 2 { return 31 } 80 81 // ----- 5. Acceptance rate Q16 = 3/9 * 65536 = 21845 ----- 82 if nx_spec_acceptance_rate_q16(s2) != 21845 { return 32 } 83 84 // ----- 6. Single-token round (k=1) ----- 85 let s3: *NxSpeculativeSession = nx_speculative_session_new(8, 4) 86 draft[0] = 42 87 flags[0] = 1 88 let committed4: i64 = nx_speculative_verify(s3, draft, flags, 1, 88, out) 89 if committed4 != 2 { return 33 } 90 if out[0] != 42 { return 34 } 91 if out[1] != 88 { return 35 } 92 93 // ----- 7. Bad k_actual ----- 94 if nx_speculative_verify(s, draft, flags, 0, 0, out) != (0 - NX_SPEC_BAD_K) { return 36 } 95 if nx_speculative_verify(s, draft, flags, -1, 0, out) != (0 - NX_SPEC_BAD_K) { return 37 } 96 // session max_k is 8; k=9 is over the per-session ceiling. 97 if nx_speculative_verify(s, draft, flags, 9, 0, out) != (0 - NX_SPEC_BAD_K) { return 38 } 98 // Even if session.max_k allowed it, NX_SPEC_MAX_K caps at 16. 99 let s_big: *NxSpeculativeSession = nx_speculative_session_new(9, NX_SPEC_MAX_K) 100 if nx_speculative_verify(s_big, draft, flags, NX_SPEC_MAX_K + 1, 0, out) != (0 - NX_SPEC_BAD_K) { return 39 } 101 102 // ----- 8. Null pointers rejected ----- 103 let null_p: *i64 = (0 as i64) as *i64 104 if nx_speculative_verify(s, null_p, flags, 4, 0, out) != (0 - NX_SPEC_BAD_INPUT) { return 40 } 105 if nx_speculative_verify(s, draft, null_p, 4, 0, out) != (0 - NX_SPEC_BAD_INPUT) { return 41 } 106 if nx_speculative_verify(s, draft, flags, 4, 0, null_p) != (0 - NX_SPEC_BAD_INPUT) { return 42 } 107 108 // ----- 9. Bad session_new inputs ----- 109 if (nx_speculative_session_new(1, 0) as i64) != 0 { return 43 } 110 if (nx_speculative_session_new(1, -1) as i64) != 0 { return 44 } 111 if (nx_speculative_session_new(1, NX_SPEC_MAX_K + 1) as i64) != 0 { return 45 } 112 113 // ----- 10. Tamper detection ----- 114 let tamper_s: *NxSpeculativeSession = nx_speculative_session_new(11, 4) 115 tamper_s.canary_post = 0xDEADBEEF 116 if nx_spec_session_is_valid(tamper_s) != 0 { return 46 } 117 if nx_speculative_verify(tamper_s, draft, flags, 4, 0, out) != (0 - NX_SPEC_TAMPER) { return 47 } 118 if nx_spec_total_drafted(tamper_s) != -1 { return 48 } 119 if nx_spec_total_accepted(tamper_s) != -1 { return 49 } 120 if nx_spec_acceptance_rate_q16(tamper_s) != -1 { return 50 } 121 122 // ----- 11. Sealed-enum gates ----- 123 if nx_spec_verdict_is_valid(NX_SPEC_OK) != 1 { return 51 } 124 if nx_spec_verdict_is_valid(NX_SPEC_TAMPER) != 1 { return 52 } 125 if nx_spec_verdict_is_valid(-1) != 0 { return 53 } 126 if nx_spec_verdict_is_valid(NX_SPEC_N_VERDICTS) != 0 { return 54 } 127 128 // ----- 12. Monotonic stats invariant ----- 129 // After several mixed rounds, accepted <= drafted, rounds <= committed. 130 if s2.total_accepted > s2.total_drafted { return 55 } 131 if s2.total_rounds > s2.total_committed { return 56 } 132 // committed == accepted + rounds (one bonus per round). 133 if s2.total_committed != (s2.total_accepted + s2.total_rounds) { return 57 } 134 135 // ----- 13. Reject-at-first round (0 accepted but valid) ----- 136 let s4: *NxSpeculativeSession = nx_speculative_session_new(12, 4) 137 flags[0] = 0 138 flags[1] = 1 139 flags[2] = 1 140 flags[3] = 1 141 draft[0] = 50 142 draft[1] = 51 143 draft[2] = 52 144 draft[3] = 53 145 let committed5: i64 = nx_speculative_verify(s4, draft, flags, 4, 999, out) 146 if committed5 != 1 { return 58 } 147 if out[0] != 999 { return 59 } 148 if nx_spec_total_accepted(s4) != 0 { return 60 } 149 if nx_spec_acceptance_rate_q16(s4) != 0 { return 61 } // 0/4 * 65536 = 0 150 151 return 0 152}