code wiki / (root) / nx_lbp_faceindex.nx

nx_lbp_faceindex.nx source

↩ module page · 108 lines · 4927 B

1// nx_lbp_faceindex.nx -- SOVEREIGN face-descriptor RUNG 6: cluster the corpus descriptor store into people. 2// Reads knowledge/status/galx_face_descr.bin (fixed records {cid(72) + 16384 i64}), packs the descriptors, 3// runs cluster_greedy (nx_lbp_core) at a chi-square threshold (arg1, scale=1000), and writes: 4// galx_face_index.tsv = cid \t cluster_id (consumed by the gallery &person= filter) 5// galx_persons.tsv = cluster_id \t count \t rep_cid (sorted by count DESC -> the People dropdown) 6// Prints M / cluster count / top cluster sizes so the threshold can be tuned by MEASUREMENT. 7// Build/run: ./_offc/nx_sov_build_run.elf nx_lbp_faceindex [thresh] license_tier: ORIGINAL 8import "nx_syscalls.nx" 9import "nx_lbp_core.nx" 10const K_MAGIC_8000000: i64 = 8000000 11 12const REC: i64 = 131144 // 72 (cid, null-padded, 8-aligned) + 16384*8 (descriptor) 13const D: i64 = 16384 // 8x8 grid * 256 bins 14 15func fi_atoi(s: *u8) -> i64 { var v: i64=0; var i: i64=0; while s[i]!=(0 as u8) { if s[i]>=(48 as u8) { if s[i]<=(57 as u8) { v=v*10+((s[i] as i64)-48) } } i=i+1 } return v } 16// write decimal v at buf+off; returns number of bytes written 17func fi_num(buf: *u8, off: i64, v: i64) -> i64 { 18 var m: i64=v; if m<0 { m=0-m } 19 let tmp: *u8 = sys_mmap(28); var k: i64=0 20 if m==0 { tmp[0]=48; k=1 } 21 while m>0 { tmp[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } 22 var w: i64=0 23 if v<0 { buf[off]=45 as u8; w=1 } 24 var z: i64=0; while z<k { buf[off+w+z]=tmp[k-1-z]; z=z+1 } 25 return w+k 26} 27func fi_sift(idx: *i64, key: *i64, root0: i64, n: i64) -> i64 { 28 var root: i64=root0; var go: i64=1 29 while go==1 { let c: i64=2*root+1; if c>=n { go=0 } else { var s: i64=root; if key[idx[s]]<key[idx[c]] { s=c } if c+1<n { if key[idx[s]]<key[idx[c+1]] { s=c+1 } } if s==root { go=0 } else { let t: i64=idx[root]; idx[root]=idx[s]; idx[s]=t; root=s } } } 30 return 0 31} 32func fi_heapsort(idx: *i64, key: *i64, n: i64) -> i64 { 33 if n<2 { return 0 } 34 var st: i64=n/2-1; while st>=0 { fi_sift(idx,key,st,n); st=st-1 } 35 var e: i64=n-1; while e>0 { let t: i64=idx[0]; idx[0]=idx[e]; idx[e]=t; fi_sift(idx,key,0,e); e=e-1 } 36 return 0 37} 38 39func main(argc: i64, argv: *i64) -> i64 { 40 var thresh: i64 = K_MAGIC_8000000 41 if argc >= 2 { thresh = fi_atoi(argv[1] as *u8) } 42 43 let szp: *i64 = sys_mmap(16) as *i64 44 let store: *u8 = sys_read_file("knowledge/status/galx_face_descr.bin" as *u8, szp) 45 let fsz: i64 = szp[0] 46 if (store as i64)==0 { lp("FACEINDEX FAIL: no descr store\n" as *u8); sys_exit(1); return 1 } 47 let M: i64 = fsz / REC 48 if M==0 { lp("FACEINDEX FAIL: empty store\n" as *u8); sys_exit(1); return 1 } 49 50 // pack descriptors into a contiguous d-stride array for cluster_greedy 51 let descrs: *i64 = sys_mmap(8*M*D) as *i64 52 var r: i64=0 53 while r<M { 54 let dsrc: *i64 = ((store as i64) + r*REC + 72) as *i64 55 var k: i64=0; while k<D { descrs[r*D+k]=dsrc[k]; k=k+1 } 56 r=r+1 57 } 58 59 let assign: *i64 = sys_mmap(8*M) as *i64 60 let reps: *i64 = sys_mmap(8*M) as *i64 61 let nc: i64 = cluster_greedy(descrs, M, D, thresh, 1000, assign, reps) 62 lp("M=" as *u8); ln(M); lp(" thresh=" as *u8); ln(thresh); lp(" clusters=" as *u8); ln(nc); lp("\n" as *u8) 63 64 let cnt: *i64 = sys_mmap(8*nc) as *i64 65 var ci: i64=0; while ci<nc { cnt[ci]=0; ci=ci+1 } 66 var a: i64=0; while a<M { cnt[assign[a]]=cnt[assign[a]]+1; a=a+1 } 67 68 // galx_face_index.tsv : cid \t cluster 69 let fd1: i64 = sys_openat_wr("knowledge/status/galx_face_index.tsv" as *u8, 0x1a4) 70 let line: *u8 = sys_mmap(256) 71 var ii: i64=0 72 while ii<M { 73 var lo: i64=0; let cb: i64=ii*REC 74 var k: i64=0; while k<69 { line[lo]=store[cb+k]; lo=lo+1; k=k+1 } 75 line[lo]=9 as u8; lo=lo+1 76 lo = lo + fi_num(line, lo, assign[ii]) 77 line[lo]=10 as u8; lo=lo+1 78 sys_write(fd1, line, lo) 79 ii=ii+1 80 } 81 sys_close(fd1) 82 83 // galx_persons.tsv : cluster \t count \t rep_cid (count DESC) 84 let idx: *i64 = sys_mmap(8*nc) as *i64 85 var j: i64=0; while j<nc { idx[j]=j; j=j+1 } 86 fi_heapsort(idx, cnt, nc) 87 let fd2: i64 = sys_openat_wr("knowledge/status/galx_persons.tsv" as *u8, 0x1a4) 88 var rr: i64=nc-1 89 while rr>=0 { 90 let cl: i64=idx[rr] 91 var lo: i64=0 92 lo = lo + fi_num(line, lo, cl) 93 line[lo]=9 as u8; lo=lo+1 94 lo = lo + fi_num(line, lo, cnt[cl]) 95 line[lo]=9 as u8; lo=lo+1 96 let cb: i64=reps[cl]*REC; var k: i64=0; while k<69 { line[lo]=store[cb+k]; lo=lo+1; k=k+1 } 97 line[lo]=10 as u8; lo=lo+1 98 sys_write(fd2, line, lo) 99 rr=rr-1 100 } 101 sys_close(fd2) 102 103 lp("top cluster sizes: " as *u8) 104 var t: i64=nc-1; var shown: i64=0 105 while t>=0 { if shown<10 { ln(cnt[idx[t]]); lp(" " as *u8); shown=shown+1 } t=t-1 } 106 lp("\nnx_lbp_faceindex RUNG6 done -> galx_face_index.tsv + galx_persons.tsv\n" as *u8) 107 sys_exit(0); return 0 108}