Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion crates/cognitive-shader-driver/src/mailbox_soa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use lance_graph_contract::cognitive_shader::MetaWord;
use lance_graph_contract::collapse_gate::MailboxId;
use lance_graph_contract::kanban::{ExecTarget, KanbanColumn, KanbanMove};
use lance_graph_contract::qualia::QualiaI4_16D;
use lance_graph_contract::soa_view::{MailboxSoaOwner, MailboxSoaView};
use lance_graph_contract::soa_view::{IdentityPlane, MailboxSoaOwner, MailboxSoaView};

/// Canonical named-fingerprint plane width: 256 × u64 = 16,384 bits
/// (mirrors `bindspace::WORDS_PER_FP`; defined locally so the mailbox does NOT
Expand Down Expand Up @@ -729,6 +729,23 @@ impl<const N: usize> MailboxSoaView for MailboxSoA<N> {
fn phase(&self) -> KanbanColumn {
self.phase
}
/// Override the deferred-binding default: the in-RAM owner DOES carry the
/// content/topic/angle identity planes (W1b), so the value-side Hamming
/// distance (`graph::mailbox_scan::DistanceMeans::Hamming`) can compute over
/// the real view, not just the unit-test fake. Guarded by `populated` — never
/// reads a zero-padded capacity row (same logical-row discipline as
/// `n_rows()`); a query into `populated..N` returns `None`.
#[inline]
fn identity_plane_at(&self, row: usize, plane: IdentityPlane) -> Option<&[u64]> {
if row >= self.populated {
return None;
}
Some(match plane {
IdentityPlane::Content => self.content_row(row),
IdentityPlane::Topic => self.topic_row(row),
IdentityPlane::Angle => self.angle_row(row),
})
}
#[inline]
fn energy(&self) -> &[f32] {
&self.energy
Expand Down Expand Up @@ -1208,6 +1225,32 @@ mod tests {
assert_eq!(mb.sigma_at(2), 0, "sigma[2] must reset to 0");
}

/// `identity_plane_at` (the `MailboxSoaView` override, #545 codex P2): the real
/// owner DOES carry the W1b planes, so the value-side Hamming distance can read
/// them on the live view (not just the unit-test fake). Guarded by `populated`:
/// a row beyond the logical size returns `None`, never a zero-padded capacity row.
#[test]
fn identity_plane_at_returns_planes_and_guards_padding() {
let mut mb: MailboxSoA<4> = MailboxSoA::new(1, 0, 1.0);
mb.set_populated(2);
let mut c0 = vec![0u64; WORDS_PER_FP];
c0[0] = 0b1011;
mb.set_content(0, &c0);
// populated row → Some, byte-identical to content_row.
assert_eq!(
mb.identity_plane_at(0, IdentityPlane::Content),
Some(mb.content_row(0))
);
// topic/angle planes default zero but are still materialized (Some).
assert_eq!(
mb.identity_plane_at(0, IdentityPlane::Topic),
Some(mb.topic_row(0))
);
// row beyond `populated` (2) → None: never a zero-padded capacity row.
assert_eq!(mb.identity_plane_at(2, IdentityPlane::Content), None);
assert_eq!(mb.identity_plane_at(3, IdentityPlane::Angle), None);
}

// ── test 15: W1b dense identity planes — parity with BindSpace ───────────

/// **The W1b "test the new" proof.** The content/topic/angle Hamming identity
Expand Down
28 changes: 28 additions & 0 deletions crates/lance-graph-contract/src/soa_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@
use crate::collapse_gate::MailboxId;
use crate::kanban::{KanbanColumn, KanbanMove, RubiconTransitionError};

/// Which dense identity plane a value-side read selects — the orthogonal
/// perspective axes of a node's content (`E-TENANT-ANGLE-RANK-IS-CAM-PQ-ADC`).
/// Each is a `WORDS_PER_FP`-u64 fingerprint in the value slab; reading one is a
/// **value decode** (the costed tier), never the zero-decode key path.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum IdentityPlane {
/// The content identity fingerprint plane.
Content,
/// The topic identity fingerprint plane.
Topic,
/// The angle (perspective) identity fingerprint plane.
Angle,
}

/// A transparent, read-only view over one mailbox's SoA columns.
///
/// Implementors return **borrows** (`&[T]`) or `Copy` scalars — never clones of the
Expand Down Expand Up @@ -125,6 +139,20 @@ pub trait MailboxSoaView {
None
}

/// `row`'s dense identity-plane fingerprint (`WORDS_PER_FP` u64) for the
/// selected [`IdentityPlane`] — content / topic / angle. This is the
/// **value-side** read behind the costed distance/sweep tier
/// (`E-TENANT-ANGLE-RANK-IS-CAM-PQ-ADC`): a Hamming/CAM rank "from an angle"
/// reads this plane, so unlike the key facets it is **NOT zero value decode**.
///
/// **Default = `None` (zero-fallback, deferred binding)** — a view that has not
/// materialized the planes returns `None`; the in-RAM `MailboxSoA` owner
/// (which carries content/topic/angle planes, W1b) overrides this.
#[inline]
fn identity_plane_at(&self, _row: usize, _plane: IdentityPlane) -> Option<&[u64]> {
None
}

// NOTE (follow-up): the qualia column (`QualiaI4_16D`) accessor is intentionally omitted —
// add `fn qualia(&self) -> &[crate::qualia::QualiaI4_16D]` when the first consumer
// (planner strategy selection) needs it; keep the read surface minimal until then.
Expand Down
73 changes: 65 additions & 8 deletions crates/lance-graph/src/graph/mailbox_scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

use lance_graph_contract::canonical_node::EdgeCodecFlavor;
use lance_graph_contract::hhtl::NiblePath;
use lance_graph_contract::soa_view::MailboxSoaView;
use lance_graph_contract::soa_view::{IdentityPlane, MailboxSoaView};

use crate::graph::graph_router::Backend;

Expand Down Expand Up @@ -226,13 +226,18 @@ pub enum DistanceMeans {
/// triangle inequality). Key-only, zero value decode
/// (`E-PANCAKES-IS-RADIX-IS-HHTL`).
PrefixDepth,
// ── value-decode means (the costed tier — named here as the dispatch
// surface; wired on their own branch with their own cost gate, never
// mixed into the zero-decode facets; `E-TENANT-ANGLE-RANK-IS-CAM-PQ-ADC`,
// `E-HELIX-IS-EXACT-LOCATION`): ──
// Hamming(plane) — fingerprint popcount over a content/topic/angle plane;
// HelixAngular — Signed360 exact-orthogonal-location distance;
// PqAdc — CAM-PQ asymmetric distance (IVF probe + tables).
/// **Hamming over an identity plane** (`IdentityPlane`: content / topic /
/// angle) — the popcount of the XOR of the two nodes' fingerprint planes.
/// This is the **costed tier**: it reads the value-side plane
/// (`MailboxSoaView::identity_plane_at`), so — unlike `PrefixDepth` — it is
/// **NOT zero value decode** (`E-TENANT-ANGLE-RANK-IS-CAM-PQ-ADC`). The right
/// use of popcount: homogeneous 16K-bit fingerprint bits, not the
/// heterogeneous GUID key.
Hamming(IdentityPlane),
// ── further value means (named; wired as they land, same costed tier):
// HelixAngular — Signed360 exact-orthogonal-location distance
// (`E-HELIX-IS-EXACT-LOCATION`);
// PqAdc — CAM-PQ asymmetric distance (IVF probe + tables).
}

/// Distance between two nodes (rows, each a GUID) under the chosen `means`.
Expand All @@ -258,6 +263,12 @@ pub fn node_distance<V: MailboxSoaView>(
let cpd = pa.common_prefix_depth(pb);
Some(u32::from((pa.depth() - cpd) + (pb.depth() - cpd)))
}
// COSTED tier: reads the value-side plane (NOT zero value decode).
DistanceMeans::Hamming(plane) => {
let fa = view.identity_plane_at(a, plane)?;
let fb = view.identity_plane_at(b, plane)?;
Some(fa.iter().zip(fb).map(|(x, y)| (x ^ y).count_ones()).sum())
}
}
}

Expand All @@ -277,6 +288,7 @@ mod tests {
keyed_rows: Vec<(u64, usize)>,
paths: Vec<Option<NiblePath>>,
blocks: Vec<Option<EdgeBlock>>,
content_planes: Vec<Option<Vec<u64>>>,
/// Logical populated rows; `None` ⇒ the full `class_ids` length. Set
/// smaller to model the real `MailboxSoA<N>` (zero-padded capacity with
/// `n_rows() == populated < entity_type().len()`).
Expand Down Expand Up @@ -328,6 +340,13 @@ mod tests {
fn edge_block_at(&self, row: usize) -> Option<EdgeBlock> {
self.blocks.get(row).copied().flatten()
}
fn identity_plane_at(&self, row: usize, plane: IdentityPlane) -> Option<&[u64]> {
// Only the Content plane is materialized in this fake.
match plane {
IdentityPlane::Content => self.content_planes.get(row).and_then(|p| p.as_deref()),
IdentityPlane::Topic | IdentityPlane::Angle => None,
}
}
}

fn sample() -> GuardedSoa {
Expand Down Expand Up @@ -356,6 +375,14 @@ mod tests {
None,
None,
],
// content planes (2 u64 each) for the Hamming means; row2 unmaterialized.
content_planes: vec![
Some(vec![0b1011, 0]),
Some(vec![0b1101, 0]),
None,
Some(vec![0, 0]),
Some(vec![u64::MAX, u64::MAX]),
],
logical_n: None,
}
}
Expand Down Expand Up @@ -511,6 +538,36 @@ mod tests {
assert!(d(0, 1).unwrap() < d(0, 4).unwrap());
}

#[test]
fn node_distance_hamming_plane_is_popcount_xor_over_the_value_plane() {
let soa = sample();
// row0 0b1011, row1 0b1101 → XOR 0b0110 → popcount 2.
assert_eq!(
node_distance(&soa, 0, 1, DistanceMeans::Hamming(IdentityPlane::Content)),
Some(2)
);
// self-distance = 0 (metric).
assert_eq!(
node_distance(&soa, 0, 0, DistanceMeans::Hamming(IdentityPlane::Content)),
Some(0)
);
// all-zero vs all-ones over 2×u64 = 128 bits.
assert_eq!(
node_distance(&soa, 3, 4, DistanceMeans::Hamming(IdentityPlane::Content)),
Some(128)
);
// unmaterialized plane (row2) ⇒ None (costed-tier fallback).
assert_eq!(
node_distance(&soa, 0, 2, DistanceMeans::Hamming(IdentityPlane::Content)),
None
);
// a plane this fake doesn't carry ⇒ None (Topic/Angle not materialized).
assert_eq!(
node_distance(&soa, 0, 1, DistanceMeans::Hamming(IdentityPlane::Angle)),
None
);
}

#[test]
fn node_distance_none_without_materialized_path() {
let mut soa = sample();
Expand Down
Loading