Skip to content

Commit e856f30

Browse files
authored
Merge pull request #29 from AdaWorldAPI/claude/continue-session-0mAVa
add Pumpkin voxel modules, jitson JIT engine, holo optics, and SIMD enhancements`
2 parents c5bf928 + 99de5f3 commit e856f30

14 files changed

Lines changed: 3153 additions & 0 deletions

src/hpc/aabb.rs

Lines changed: 461 additions & 0 deletions
Large diffs are not rendered by default.

src/hpc/arrow_bridge.rs

Lines changed: 363 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,209 @@ impl BindNodeV2 {
598598
}
599599
}
600600

601+
// ============================================================================
602+
// Per-Row Types: ThreePlaneRowBuffer, SoakingRowBuffer, BindNodeV2Row
603+
// ============================================================================
604+
605+
/// Three-plane fingerprint row buffer: holds S/P/O binary fingerprints for
606+
/// a single row, suitable for zero-copy Arrow interop.
607+
///
608+
/// Total: 3 x 2048 = 6144 bytes per row.
609+
#[derive(Debug, Clone)]
610+
pub struct ThreePlaneRowBuffer {
611+
/// Subject binary fingerprint (2048 bytes).
612+
pub s_binary: Vec<u8>,
613+
/// Predicate binary fingerprint (2048 bytes).
614+
pub p_binary: Vec<u8>,
615+
/// Object binary fingerprint (2048 bytes).
616+
pub o_binary: Vec<u8>,
617+
}
618+
619+
impl ThreePlaneRowBuffer {
620+
/// Create a zeroed three-plane row buffer.
621+
pub fn new() -> Self {
622+
Self {
623+
s_binary: vec![0u8; PLANE_BINARY_BYTES],
624+
p_binary: vec![0u8; PLANE_BINARY_BYTES],
625+
o_binary: vec![0u8; PLANE_BINARY_BYTES],
626+
}
627+
}
628+
629+
/// Create from three Plane references (copies their cached bit patterns).
630+
pub fn from_planes(s: &mut Plane, p: &mut Plane, o: &mut Plane) -> Self {
631+
s.ensure_cache();
632+
p.ensure_cache();
633+
o.ensure_cache();
634+
Self {
635+
s_binary: s.bits_bytes_ref().to_vec(),
636+
p_binary: p.bits_bytes_ref().to_vec(),
637+
o_binary: o.bits_bytes_ref().to_vec(),
638+
}
639+
}
640+
641+
/// Compute S XOR P XOR O composite fingerprint.
642+
pub fn xor_spo(&self) -> Vec<u8> {
643+
let mut result = vec![0u8; PLANE_BINARY_BYTES];
644+
for i in 0..PLANE_BINARY_BYTES {
645+
result[i] = self.s_binary[i] ^ self.p_binary[i] ^ self.o_binary[i];
646+
}
647+
result
648+
}
649+
650+
/// Per-plane Hamming distance to another row buffer.
651+
///
652+
/// Returns `(subject_dist, predicate_dist, object_dist)`.
653+
pub fn hamming_distance(&self, other: &ThreePlaneRowBuffer) -> (u64, u64, u64) {
654+
let ds = hamming_distance_raw(&self.s_binary, &other.s_binary);
655+
let dp = hamming_distance_raw(&self.p_binary, &other.p_binary);
656+
let do_ = hamming_distance_raw(&self.o_binary, &other.o_binary);
657+
(ds, dp, do_)
658+
}
659+
660+
/// Total byte size of this row buffer (always 3 * PLANE_BINARY_BYTES).
661+
pub fn total_bytes(&self) -> usize {
662+
3 * PLANE_BINARY_BYTES
663+
}
664+
}
665+
666+
impl Default for ThreePlaneRowBuffer {
667+
fn default() -> Self {
668+
Self::new()
669+
}
670+
}
671+
672+
/// Soaking row buffer: nullable i8 accumulator for a single plane of a single row.
673+
///
674+
/// When `data` is `Some`, the buffer is active (Form state).
675+
/// When `data` is `None`, the buffer has been crystallized or nulled.
676+
#[derive(Debug, Clone)]
677+
pub struct SoakingRowBuffer {
678+
/// Soaking data (None = nulled/crystallized).
679+
pub data: Option<Vec<i8>>,
680+
/// Dimension count.
681+
pub dims: usize,
682+
}
683+
684+
impl SoakingRowBuffer {
685+
/// Create a new active soaking row buffer, zeroed.
686+
pub fn new(dims: usize) -> Self {
687+
Self {
688+
data: Some(vec![0i8; dims]),
689+
dims,
690+
}
691+
}
692+
693+
/// Crystallize: convert soaking (int8) to binary fingerprint via sign().
694+
///
695+
/// Consumes the soaking data and returns a binary vector.
696+
/// After crystallization, the buffer is nulled.
697+
pub fn crystallize(&mut self) -> Vec<u8> {
698+
let soaking = match self.data.take() {
699+
Some(d) => d,
700+
None => return vec![0u8; (self.dims + 7) / 8],
701+
};
702+
let n_bytes = (soaking.len() + 7) / 8;
703+
let mut bits = vec![0u8; n_bytes];
704+
for (i, &val) in soaking.iter().enumerate() {
705+
if val > 0 {
706+
bits[i / 8] |= 1 << (i % 8);
707+
}
708+
}
709+
bits
710+
}
711+
712+
/// Returns `true` when soaking is still active (not nulled/crystallized).
713+
pub fn is_active(&self) -> bool {
714+
self.data.is_some()
715+
}
716+
717+
/// Null out the soaking data (transition to inactive).
718+
pub fn null_out(&mut self) {
719+
self.data = None;
720+
}
721+
}
722+
723+
/// Complete bind_nodes_v2 row type combining fingerprints, soaking, gate,
724+
/// and NARS truth values.
725+
///
726+
/// This is a streamlined per-row type that pairs `ThreePlaneRowBuffer` with
727+
/// per-plane `SoakingRowBuffer`s for the full Lance schema.
728+
#[derive(Debug, Clone)]
729+
pub struct BindNodeV2Row {
730+
/// Three-plane binary fingerprints.
731+
pub fingerprints: ThreePlaneRowBuffer,
732+
/// Subject soaking accumulator.
733+
pub s_soaking: SoakingRowBuffer,
734+
/// Predicate soaking accumulator.
735+
pub p_soaking: SoakingRowBuffer,
736+
/// Object soaking accumulator.
737+
pub o_soaking: SoakingRowBuffer,
738+
/// Gate lifecycle state.
739+
pub gate: GateState,
740+
/// NARS frequency (u16 fixed-point).
741+
pub nars_frequency: u16,
742+
/// NARS confidence (u16 fixed-point).
743+
pub nars_confidence: u16,
744+
}
745+
746+
impl BindNodeV2Row {
747+
/// Create a new row in Form state with active soaking.
748+
pub fn new(dims: usize) -> Self {
749+
Self {
750+
fingerprints: ThreePlaneRowBuffer::new(),
751+
s_soaking: SoakingRowBuffer::new(dims),
752+
p_soaking: SoakingRowBuffer::new(dims),
753+
o_soaking: SoakingRowBuffer::new(dims),
754+
gate: GateState::Form,
755+
nars_frequency: 32768,
756+
nars_confidence: 0,
757+
}
758+
}
759+
760+
/// Crystallize all three soaking buffers, folding sign bits into fingerprints.
761+
/// Transitions from Form to Flow.
762+
pub fn crystallize(&mut self) {
763+
if self.gate != GateState::Form {
764+
return;
765+
}
766+
// Fold each soaking into its binary plane
767+
if let Some(ref soaking) = self.s_soaking.data {
768+
fold_sign_into_binary(&mut self.fingerprints.s_binary, soaking);
769+
}
770+
if let Some(ref soaking) = self.p_soaking.data {
771+
fold_sign_into_binary(&mut self.fingerprints.p_binary, soaking);
772+
}
773+
if let Some(ref soaking) = self.o_soaking.data {
774+
fold_sign_into_binary(&mut self.fingerprints.o_binary, soaking);
775+
}
776+
self.s_soaking.null_out();
777+
self.p_soaking.null_out();
778+
self.o_soaking.null_out();
779+
self.gate = GateState::Flow;
780+
}
781+
782+
/// Freeze: transition from Flow to Freeze.
783+
pub fn freeze(&mut self) {
784+
if self.gate == GateState::Flow {
785+
self.gate = GateState::Freeze;
786+
}
787+
}
788+
}
789+
790+
/// Fold soaking sign bits into a binary fingerprint (shared helper).
791+
fn fold_sign_into_binary(binary: &mut [u8], soaking: &[i8]) {
792+
let bit_count = (binary.len() * 8).min(soaking.len());
793+
for i in 0..bit_count {
794+
let byte_idx = i / 8;
795+
let bit_idx = i % 8;
796+
if soaking[i] > 0 {
797+
binary[byte_idx] |= 1 << bit_idx;
798+
} else {
799+
binary[byte_idx] &= !(1 << bit_idx);
800+
}
801+
}
802+
}
803+
601804
#[cfg(test)]
602805
mod tests {
603806
use super::*;
@@ -982,4 +1185,164 @@ mod tests {
9821185
assert_eq!(slice.len(), 3 * BINARY_BYTES);
9831186
assert_eq!(slice[BINARY_BYTES], 0xAB);
9841187
}
1188+
1189+
// ================================================================
1190+
// ThreePlaneRowBuffer tests
1191+
// ================================================================
1192+
1193+
#[test]
1194+
fn three_plane_row_buffer_new() {
1195+
let buf = ThreePlaneRowBuffer::new();
1196+
assert_eq!(buf.s_binary.len(), PLANE_BINARY_BYTES);
1197+
assert_eq!(buf.p_binary.len(), PLANE_BINARY_BYTES);
1198+
assert_eq!(buf.o_binary.len(), PLANE_BINARY_BYTES);
1199+
assert_eq!(buf.total_bytes(), 3 * PLANE_BINARY_BYTES);
1200+
}
1201+
1202+
#[test]
1203+
fn three_plane_row_buffer_default() {
1204+
let buf = ThreePlaneRowBuffer::default();
1205+
assert_eq!(buf.total_bytes(), 6144);
1206+
}
1207+
1208+
#[test]
1209+
fn three_plane_row_buffer_from_planes() {
1210+
let (mut s, mut p, mut o) = make_test_planes();
1211+
let buf = ThreePlaneRowBuffer::from_planes(&mut s, &mut p, &mut o);
1212+
assert_eq!(buf.s_binary.len(), PLANE_BINARY_BYTES);
1213+
// Non-trivial planes should produce non-zero binaries
1214+
assert!(buf.s_binary.iter().any(|&b| b != 0));
1215+
}
1216+
1217+
#[test]
1218+
fn three_plane_row_buffer_xor_spo() {
1219+
let mut buf = ThreePlaneRowBuffer::new();
1220+
buf.s_binary[0] = 0xFF;
1221+
buf.p_binary[0] = 0x0F;
1222+
buf.o_binary[0] = 0xAA;
1223+
let xor = buf.xor_spo();
1224+
assert_eq!(xor[0], 0xFF ^ 0x0F ^ 0xAA);
1225+
assert_eq!(xor[1], 0); // rest is zero
1226+
}
1227+
1228+
#[test]
1229+
fn three_plane_row_buffer_hamming_self_zero() {
1230+
let (mut s, mut p, mut o) = make_test_planes();
1231+
let buf = ThreePlaneRowBuffer::from_planes(&mut s, &mut p, &mut o);
1232+
let (ds, dp, do_) = buf.hamming_distance(&buf);
1233+
assert_eq!(ds, 0);
1234+
assert_eq!(dp, 0);
1235+
assert_eq!(do_, 0);
1236+
}
1237+
1238+
#[test]
1239+
fn three_plane_row_buffer_hamming_different() {
1240+
let mut buf1 = ThreePlaneRowBuffer::new();
1241+
let mut buf2 = ThreePlaneRowBuffer::new();
1242+
buf1.s_binary.fill(0xFF);
1243+
buf2.s_binary.fill(0x00);
1244+
let (ds, dp, _) = buf1.hamming_distance(&buf2);
1245+
assert_eq!(ds, PLANE_BINARY_BYTES as u64 * 8);
1246+
assert_eq!(dp, 0); // both zero
1247+
}
1248+
1249+
// ================================================================
1250+
// SoakingRowBuffer tests
1251+
// ================================================================
1252+
1253+
#[test]
1254+
fn soaking_row_buffer_new() {
1255+
let buf = SoakingRowBuffer::new(100);
1256+
assert!(buf.is_active());
1257+
assert_eq!(buf.dims, 100);
1258+
assert_eq!(buf.data.as_ref().unwrap().len(), 100);
1259+
}
1260+
1261+
#[test]
1262+
fn soaking_row_buffer_crystallize() {
1263+
let mut buf = SoakingRowBuffer::new(8);
1264+
buf.data.as_mut().unwrap().copy_from_slice(&[1, -1, 1, -1, 1, -1, 1, -1]);
1265+
let bits = buf.crystallize();
1266+
assert_eq!(bits[0], 0b01010101);
1267+
assert!(!buf.is_active()); // should be nulled after crystallize
1268+
}
1269+
1270+
#[test]
1271+
fn soaking_row_buffer_crystallize_inactive() {
1272+
let mut buf = SoakingRowBuffer::new(16);
1273+
buf.null_out();
1274+
assert!(!buf.is_active());
1275+
let bits = buf.crystallize();
1276+
// Should return zeroed bits when inactive
1277+
assert!(bits.iter().all(|&b| b == 0));
1278+
}
1279+
1280+
#[test]
1281+
fn soaking_row_buffer_null_out() {
1282+
let mut buf = SoakingRowBuffer::new(10);
1283+
assert!(buf.is_active());
1284+
buf.null_out();
1285+
assert!(!buf.is_active());
1286+
}
1287+
1288+
// ================================================================
1289+
// BindNodeV2Row tests
1290+
// ================================================================
1291+
1292+
#[test]
1293+
fn bind_node_v2_row_new() {
1294+
let row = BindNodeV2Row::new(100);
1295+
assert_eq!(row.gate, GateState::Form);
1296+
assert!(row.s_soaking.is_active());
1297+
assert!(row.p_soaking.is_active());
1298+
assert!(row.o_soaking.is_active());
1299+
assert_eq!(row.nars_frequency, 32768);
1300+
assert_eq!(row.nars_confidence, 0);
1301+
assert_eq!(row.fingerprints.total_bytes(), 6144);
1302+
}
1303+
1304+
#[test]
1305+
fn bind_node_v2_row_crystallize() {
1306+
let mut row = BindNodeV2Row::new(16);
1307+
// Put some data in soaking
1308+
row.s_soaking.data.as_mut().unwrap().fill(1);
1309+
row.crystallize();
1310+
assert_eq!(row.gate, GateState::Flow);
1311+
assert!(!row.s_soaking.is_active());
1312+
assert!(!row.p_soaking.is_active());
1313+
assert!(!row.o_soaking.is_active());
1314+
}
1315+
1316+
#[test]
1317+
fn bind_node_v2_row_lifecycle() {
1318+
let mut row = BindNodeV2Row::new(16);
1319+
assert_eq!(row.gate, GateState::Form);
1320+
1321+
// Cannot freeze from Form
1322+
row.freeze();
1323+
assert_eq!(row.gate, GateState::Form);
1324+
1325+
// Crystallize: Form -> Flow
1326+
row.crystallize();
1327+
assert_eq!(row.gate, GateState::Flow);
1328+
1329+
// Double crystallize is no-op
1330+
row.crystallize();
1331+
assert_eq!(row.gate, GateState::Flow);
1332+
1333+
// Freeze: Flow -> Freeze
1334+
row.freeze();
1335+
assert_eq!(row.gate, GateState::Freeze);
1336+
}
1337+
1338+
#[test]
1339+
fn bind_node_v2_row_crystallize_folds_sign() {
1340+
let mut row = BindNodeV2Row::new(16);
1341+
// Set subject soaking to all positive
1342+
row.s_soaking.data.as_mut().unwrap().fill(5);
1343+
row.crystallize();
1344+
// First 2 bytes of s_binary should have bits set (16 bits = 2 bytes)
1345+
assert_eq!(row.fingerprints.s_binary[0], 0xFF);
1346+
assert_eq!(row.fingerprints.s_binary[1], 0xFF);
1347+
}
9851348
}

0 commit comments

Comments
 (0)