code wiki / (root) / nx_bench_companion_test.nx

nx_bench_companion_test.nx source

↩ module page · 150 lines · 6357 B

1// nx_bench_companion_test.nx -- smoke for the bench-capture primitive. 2// 3// Drives a small parallel-companion session through known operations, 4// captures the report, and asserts every substrate counter has the 5// exact value the operations should have produced. Substrate-honest: 6// every assertion compares against a counter the operations actually 7// drove, not an aspirational target. 8 9import "nx_syscalls.nx" 10import "nx_tier.nx" 11import "nx_actor.nx" 12import "nx_message.nx" 13import "nx_resource_arbiter.nx" 14import "nx_interrupt_broker.nx" 15import "nx_session.nx" 16import "nx_bench_companion.nx" 17 18func main() -> i64 { 19 let now: nx_size = 1000000 20 21 // 1: verdict enum 22 if nx_bc_v_is_valid(NX_BC_V_OK) != 1 { return 1 } 23 if nx_bc_v_is_valid(NX_BC_V_INVALID) != 1 { return 2 } 24 if nx_bc_v_is_valid(NX_BC_V_N) != 0 { return 3 } 25 if nx_bc_v_is_valid(-1) != 0 { return 4 } 26 27 // 2: empty report after construction 28 let r: *NxBenchReport = nx_bc_report_new() 29 if (r as i64) == 0 { return 5 } 30 if r.n_actors != 0 { return 6 } 31 if r.verdict != NX_BC_V_OK { return 7 } 32 if nx_bc_report_verdict(r) != NX_BC_V_OK { return 8 } 33 34 // 3: build a session + drive known operations 35 let s: *NxSession = nx_session_new_default(now) 36 if nx_session_is_ready(s) != 1 { return 9 } 37 38 // Spawn 3 actors 39 nx_session_spawn_actor(s, 101, 1, 80, 0, now) 40 nx_session_spawn_actor(s, 102, 4, 60, 0, now) 41 nx_session_spawn_actor(s, 103, 5, 50, 0, now) 42 43 // Subscribe 102 + 103 to LLM_TOKEN (= 2 subscriptions) 44 nx_session_subscribe(s, 102, NX_MS_KIND_LLM_TOKEN) 45 nx_session_subscribe(s, 103, NX_MS_KIND_LLM_TOKEN) 46 47 // Step actor 101 twice (= 2 steps in scheduler counter) 48 nx_ac_step(s.scheduler, 101, 5000, now + 100) 49 nx_ac_step(s.scheduler, 101, 5000, now + 200) 50 51 // Complete 101 + fail 102 (forces specific final counts) 52 nx_ac_complete(s.scheduler, 101) 53 nx_ac_fail(s.scheduler, 102) 54 // 103 stays in READY (counted as neither completed nor failed) 55 56 // Set up arbiter + grant 1 request fully + deny 1 57 nx_ra_set_budget(s.arbiter, NX_RA_KIND_VRAM_BYTES, 1000) 58 nx_ra_set_max_share(s.arbiter, NX_RA_KIND_VRAM_BYTES, 1024) 59 let out_buf: *u8 = sys_mmap(8) 60 let out_g: *i64 = out_buf as *i64 61 nx_ra_request(s.arbiter, 101, NX_RA_KIND_VRAM_BYTES, 500, 80, 0, out_g, now) 62 // Try a request that would exceed budget -- denial 63 nx_ra_request(s.arbiter, 102, NX_RA_KIND_VRAM_BYTES, 600, 60, 0, out_g, now) 64 65 // File an operator interrupt + arbitrate against a yieldable op 66 nx_ib_file(s.broker, 9001, NX_IB_KIND_OPERATOR_INPUT, NX_IB_DL_REALTIME, 95, 0, now) 67 let op: *NxRunningOp = nx_ib_op_new(101, 50, now, 100000, now + 1000, 1) 68 nx_ib_arbitrate(s.broker, 9001, op, now + 2000) 69 70 // 4: capture session counters into the report 71 if nx_bc_capture(s, r, 11, now + 3000) != NX_BC_V_OK { return 10 } 72 73 // 5: scheduler counters match operations 74 if r.n_actors != 3 { return 11 } 75 if r.actors_completed != 1 { return 12 } 76 if r.actors_failed != 1 { return 13 } 77 // Actor 103 still READY, 101 completed, 102 failed 78 if r.actors_running != 0 { return 14 } 79 if r.actors_waiting != 0 { return 15 } 80 if r.total_actor_steps != 2 { return 16 } 81 if r.cumulative_runtime_us != 10000 { return 17 } // 2 steps * 5000us 82 if r.epoch_count != 0 { return 18 } 83 if nx_bc_report_actors_completed(r) != 1 { return 19 } 84 if nx_bc_report_total_steps(r) != 2 { return 20 } 85 86 // 6: bus counters -- 2 subscriptions to LLM_TOKEN 87 if r.n_subscriptions != 2 { return 21 } 88 89 // 7: multiplexer empty (we never pushed) 90 if r.mux_pending != 0 { return 22 } 91 92 // 8: arbiter counters -- 1 grant_full (101 got 500/500) + 1 grant_partial 93 // (102 requested 600 but free_pool was 500 -> partial grant of 500). 94 // nx_ra_request grants what it can when free_pool < requested, rather 95 // than denying outright; that's the cooperative arbitration discipline. 96 if r.arb_grants_full != 1 { return 23 } 97 if r.arb_grants_partial != 1 { return 24 } 98 if r.arb_denials != 0 { return 25 } 99 if r.arb_preemptions != 0 { return 26 } 100 101 // 9: broker counters -- 1 grant (operator input on yieldable op) 102 if r.broker_grants != 1 { return 27 } 103 if r.broker_refusals != 0 { return 28 } 104 if r.broker_deadline_misses != 0 { return 29 } 105 106 // 10: captured_at_us recorded 107 if r.captured_at_us != (now + 3000) { return 30 } 108 if r.verdict != NX_BC_V_OK { return 31 } 109 110 // 11: capture into null report rejected cleanly 111 let null_r: *NxBenchReport = (0 as i64) as *NxBenchReport 112 if nx_bc_capture(s, null_r, 11, now) != NX_BC_V_NULL_REPORT { return 32 } 113 114 // 12: capture from null session rejected 115 let null_s: *NxSession = (0 as i64) as *NxSession 116 if nx_bc_capture(null_s, r, 11, now) != NX_BC_V_NULL_SESSION { return 33 } 117 118 // 13: capture from a not-ready session rejected 119 let bad_s: *NxSession = nx_session_new(0, 1, 1, 1, 1, 1, 1, 1000000, 1, 50000, now) 120 if nx_bc_capture(bad_s, r, 11, now) != NX_BC_V_SESSION_NOT_READY { return 34 } 121 122 // 14: capture with negative subscription-kinds-to-count rejected 123 if nx_bc_capture(s, r, -1, now) != NX_BC_V_INVALID { return 35 } 124 125 // 15: paired-diff -- capture again after spawning 1 more actor 126 let r2: *NxBenchReport = nx_bc_report_new() 127 nx_session_spawn_actor(s, 104, 5, 40, 0, now) 128 nx_ac_step(s.scheduler, 103, 3000, now + 4000) 129 nx_bc_capture(s, r2, 11, now + 5000) 130 131 let diff: *NxBenchReport = nx_bc_report_new() 132 if nx_bc_diff(r, r2, diff) != NX_BC_V_OK { return 36 } 133 // 1 new actor, 1 new step, +3000 runtime 134 if diff.n_actors != 1 { return 37 } 135 if diff.total_actor_steps != 1 { return 38 } 136 if diff.cumulative_runtime_us != 3000 { return 39 } 137 if diff.captured_at_us != 2000 { return 40 } // 5000 - 3000 138 139 // 16: diff null guards 140 if nx_bc_diff(null_r, r2, diff) != NX_BC_V_NULL_REPORT { return 41 } 141 if nx_bc_diff(r, null_r, diff) != NX_BC_V_NULL_REPORT { return 42 } 142 if nx_bc_diff(r, r2, null_r) != NX_BC_V_NULL_REPORT { return 43 } 143 144 // 17: accessor null guards 145 if nx_bc_report_verdict(null_r) != NX_BC_V_NULL_REPORT { return 44 } 146 if nx_bc_report_actors_completed(null_r) != 0 { return 45 } 147 if nx_bc_report_total_steps(null_r) != 0 { return 46 } 148 149 return 0 150}