code wiki / (root) / nx_rate_ema_test.nx

nx_rate_ema_test.nx source

↩ module page · 50 lines · 2634 B

1// nx_rate_ema_test.nx -- KAT for rolling rate EMA + its integration with the choker. 2// Native sovereign lane; exit 0 = pass, N = assertion N failed. Expecteds hand-computed. 3 4import "nx_str.nx" 5import "nx_rate_ema.nx" 6import "nx_choker.nx" 7 8func main() -> i64 { 9 // ---- rate sample ---- 10 if nx_re_rate_sample(16384, 1000) != 16384 { return 1 } // 16 KiB in 1s = 16384 B/s 11 if nx_re_rate_sample(8000, 500) != 16000 { return 2 } // 8000 B in 0.5s = 16000 B/s 12 if nx_re_rate_sample(100, 0) != 0 { return 3 } // no interval -> 0 13 14 // ---- EMA step ---- 15 if nx_re_ema_update(0, 1000, 500, 1000) != 500 { return 4 } // 0.5*1000 + 0.5*0 16 if nx_re_ema_update(500, 1000, 500, 1000) != 750 { return 5 } // 0.5*1000 + 0.5*500 17 if nx_re_ema_update(123, 999, 1000, 1000) != 999 { return 6 } // alpha=1 -> all sample 18 if nx_re_ema_update(777, 999, 0, 1000) != 777 { return 7 } // alpha=0 -> hold old 19 if nx_re_ema_update(50, 888, 2000, 1000) != 888 { return 8 } // alpha clamps to scale 20 if nx_re_ema_update(5, 42, 500, 0) != 42 { return 9 } // scale<=0 -> raw sample 21 22 // ---- vector update over peers ---- 23 let rates: *i64 = sys_mmap(8 * 8) as *i64 24 let dbs: *i64 = sys_mmap(8 * 8) as *i64 25 rates[0]=0; rates[1]=0; rates[2]=0 26 dbs[0]=1000; dbs[1]=2000; dbs[2]=500 // bytes since last tick 27 // interval 1000ms, alpha 500/1000: sample = delta; ema from 0 = 0.5*delta 28 nx_re_update_all(rates, dbs, 3, 1000, 500, 1000) 29 if rates[0] != 500 { return 10 } // 0.5*1000 30 if rates[1] != 1000 { return 11 } // 0.5*2000 31 if rates[2] != 250 { return 12 } // 0.5*500 32 // second tick: peer1 keeps feeding, peer0 stalls -> EMA tracks the shift 33 dbs[0]=0; dbs[1]=2000; dbs[2]=500 34 nx_re_update_all(rates, dbs, 3, 1000, 500, 1000) 35 if rates[0] != 250 { return 13 } // 0.5*0 + 0.5*500 36 if rates[1] != 1500 { return 14 } // 0.5*2000 + 0.5*1000 37 if rates[2] != 375 { return 15 } // 0.5*500 + 0.5*250 38 39 // ---- INTEGRATION: the smoothed rates feed the choker, fastest peer wins the slot ---- 40 // peer1 has the highest EMA (1500) -> with k=1 it must be the unchoked one. 41 let intr: *i64 = sys_mmap(8 * 8) as *i64 42 let out: *i64 = sys_mmap(8 * 8) as *i64 43 intr[0]=1; intr[1]=1; intr[2]=1 44 if nx_ch_select_top_k(rates, intr, 3, 1, out) != 1 { return 16 } 45 if out[1] != 1 { return 17 } // peer1 = fastest feeder -> reciprocated 46 if out[0] != 0 { return 18 } 47 if out[2] != 0 { return 19 } 48 49 return 0 50}