code wiki / _hdl_build / nx_vec_vq.nx

nx_vec_vq.nx source

↩ module page · 42 lines · 2491 B

1// nx_vec_vq.nx -- R-VEC-4 of the onsite-search S-class ladder: SOVEREIGN vector quantization (LIBRARY). Raw f32 2// embedding vectors blow the RAM budget at 366k scale (Rule 21); VQ compresses each vector to ONE codebook index 3// -- "a codebook" of representative centroids (cited srch_vq.raw, Vector_quantization). k-means (Lloyd): assign 4// each vector to its nearest centroid, move each centroid to the mean of its members, repeat. Integer, no-float, 5// deterministic init (evenly-spaced seeds). HONEST SCOPE: single-codebook VQ; PRODUCT quantization (split the 6// vector into sub-spaces, a codebook per sub-space) is the named extension for finer compression. 7// 8// exports: vr_vq_train, vr_vq_encode, vr_vq_decode. license_tier: ORIGINAL 9import "nx_syscalls.nx" 10 11// squared L2 distance 12func vq_l2(a: *i64, b: *i64, D: i64) -> i64 { var s: i64=0; var i: i64=0; while i<D { let d: i64=a[i]-b[i]; s=s+d*d; i=i+1 } return s } 13 14// encode: index of the nearest centroid (the compressed code for `vec`) 15func vr_vq_encode(vec: *i64, cb: *i64, K: i64, D: i64) -> i64 { 16 var best: i64=0; var bd: i64=vq_l2(vec, cb, D); var k: i64=1 17 while k<K { let ck: *i64=((cb as i64)+k*D*8) as *i64; let d: i64=vq_l2(vec, ck, D); if d<bd { bd=d; best=k } k=k+1 } 18 return best 19} 20 21// decode: reconstruct the vector as its centroid (pointer into the codebook) 22func vr_vq_decode(cb: *i64, idx: i64, D: i64) -> *i64 { return ((cb as i64)+idx*D*8) as *i64 } 23 24// train K centroids over N D-dim vectors with `iters` Lloyd iterations; writes the codebook cb[K*D]. 25func vr_vq_train(V: *i64, N: i64, D: i64, K: i64, iters: i64, cb: *i64) -> i64 { 26 var k: i64=0 27 while k<K { let src: *i64=((V as i64)+(k*N/K)*D*8) as *i64; var d: i64=0; while d<D { cb[k*D+d]=src[d]; d=d+1 } k=k+1 } 28 let assign: *i64=sys_mmap(8*(N+2)) as *i64 29 let sum: *i64=sys_mmap(8*K*D) as *i64 30 let cnt: *i64=sys_mmap(8*(K+2)) as *i64 31 var it: i64=0 32 while it<iters { 33 var i: i64=0 34 while i<N { let vi: *i64=((V as i64)+i*D*8) as *i64; assign[i]=vr_vq_encode(vi, cb, K, D); i=i+1 } 35 var z: i64=0; while z<K*D { sum[z]=0; z=z+1 } z=0; while z<K { cnt[z]=0; z=z+1 } 36 i=0 37 while i<N { let a: i64=assign[i]; let vi: *i64=((V as i64)+i*D*8) as *i64; var d: i64=0; while d<D { sum[a*D+d]=sum[a*D+d]+vi[d]; d=d+1 } cnt[a]=cnt[a]+1; i=i+1 } 38 k=0; while k<K { if cnt[k]>0 { var d: i64=0; while d<D { cb[k*D+d]=sum[k*D+d]/cnt[k]; d=d+1 } } k=k+1 } 39 it=it+1 40 } 41 return 0 42}