nx_vitpose_preprocess_gate.nx source
↩ module page · 51 lines · 2954 B
1// nx_vitpose_preprocess_gate.nx -- proof of resize+normalize: ImageNet normalize (hand-computed) + bilinear blend.
2// expect_exit: 0
3import "nx_syscalls.nx"
4import "nx_f32.nx"
5import "nx_f32_cvt.nx"
6import "nx_f32_div.nx"
7import "nx_vitpose_preprocess.nx"
8
9func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return sys_write(1,s,n) }
10func close(a: i64, b: i64, tol: i64) -> i64 { if nx_f32_lt(nx_f32_abs(nx_f32_sub(a,b)), tol)==1 { return 1 } return 0 }
11func mk(n: i64, d: i64) -> i64 { return nx_f32_div(nx_i32_to_f32(n), nx_i32_to_f32(d)) }
12
13func main(argc: i64, argv: *i64) -> i64 {
14 var pass: i64 = 0
15 let tol: i64 = mk(1, 100)
16 let mean: *i64 = sys_mmap(8*3) as *i64; let std: *i64 = sys_mmap(8*3) as *i64
17 mean[0]=mk(485,1000); mean[1]=mk(456,1000); mean[2]=mk(406,1000)
18 std[0]=mk(229,1000); std[1]=mk(224,1000); std[2]=mk(225,1000)
19
20 // P1: identity resize 2x2 -> 2x2, pixel(0,0)=(255,0,128) -> ImageNet normalize
21 let rgb: *i64 = sys_mmap(8*2*2*3) as *i64
22 var i: i64=0; while i<12 { rgb[i]=0; i=i+1 }
23 rgb[0]=255; rgb[1]=0; rgb[2]=128
24 let out: *i64 = sys_mmap(8*3*2*2) as *i64
25 vitpose_resize_normalize(rgb, 2, 2, 2, 2, mean, std, out)
26 // R=(1-.485)/.229=2.249 ; G=(-.456)/.224=-2.036 ; B=(.502-.406)/.225=0.427 ; planes: R=out[0..3],G=out[4..7],B=out[8..11]
27 if close(out[0], mk(2249,1000), tol)==1 { if close(out[4], nx_f32_neg(mk(2036,1000)), tol)==1 { if close(out[8], mk(427,1000), tol)==1 {
28 pass = pass + 1; gp("P1 ImageNet normalize (R=2.25,G=-2.04,B=0.43) OK\n" as *u8)
29 } } }
30 if close(out[0], mk(2249,1000), tol)==0 { gp("P1 FAIL\n" as *u8) }
31
32 // P2: bilinear resize 2x2 -> 3x3, grayscale values [0,10,20,30], mean=0 std=1 -> middle = 15/255
33 let m0: *i64 = sys_mmap(8*3) as *i64; let s1: *i64 = sys_mmap(8*3) as *i64
34 i=0; while i<3 { m0[i]=nx_i32_to_f32(0); s1[i]=nx_i32_to_f32(1); i=i+1 }
35 let g: *i64 = sys_mmap(8*2*2*3) as *i64
36 // pixel(0,0)=0 (0,1)=10 (1,0)=20 (1,1)=30, all channels
37 g[0]=0;g[1]=0;g[2]=0; g[3]=10;g[4]=10;g[5]=10; g[6]=20;g[7]=20;g[8]=20; g[9]=30;g[10]=30;g[11]=30
38 let o2: *i64 = sys_mmap(8*3*3*3) as *i64
39 vitpose_resize_normalize(g, 2, 2, 3, 3, m0, s1, o2)
40 // middle output pixel (oy=1,ox=1), channel R = out[0*9 + 1*3 + 1] = out[4]; value = 0.25*(0+10+20+30)/255 = 15/255
41 if close(o2[4], mk(15,255), tol)==1 { pass = pass + 1; gp("P2 bilinear middle = 15/255 OK\n" as *u8) } else { gp("P2 FAIL\n" as *u8) }
42
43 // P3: corner (0,0) of the 3x3 = clamps toward pixel(0,0)=0 -> 0
44 if close(o2[0], nx_i32_to_f32(0), tol)==1 { pass = pass + 1; gp("P3 corner clamp = 0 OK\n" as *u8) } else { gp("P3 FAIL\n" as *u8) }
45
46 gp("PREPROCESS-GATE pass=" as *u8)
47 let bb: *u8=sys_mmap(8); bb[0]=(48+pass) as u8; sys_write(1,bb,1); gp("/3\n" as *u8)
48 if pass == 3 { gp("PREPROCESS-GATE GREEN 3/3 (ImageNet normalize + bilinear resize + clamp)\n" as *u8); sys_exit(0) }
49 sys_exit(1)
50 return 0
51}