Skip to content

fixes + substrate work: dn_tree, OntologySchema multi-parent, codex P2, simd_caps, PR-X10 A6 distance kernels#193

Merged
AdaWorldAPI merged 6 commits into
masterfrom
claude/continue-ndarray-x0Oaw
May 21, 2026
Merged

fixes + substrate work: dn_tree, OntologySchema multi-parent, codex P2, simd_caps, PR-X10 A6 distance kernels#193
AdaWorldAPI merged 6 commits into
masterfrom
claude/continue-ndarray-x0Oaw

Conversation

@AdaWorldAPI
Copy link
Copy Markdown
Owner

@AdaWorldAPI AdaWorldAPI commented May 21, 2026

Summary

Five threads across the post-#192 backlog and the PR-X10 W1-W2 sprint, all on the same branch per the task's single-branch development constraint. Each commit is self-contained and independently mergeable; reviewer can request a split if preferred.

Thread Commit Scope
dn_tree::make_probability_mask p=0.5 infinite recursion 428f4969 Two characters: >=>. Plus regression tests + Pillar 13 drift-check switches from lr=0.25 workaround to canonical lr=0.5.
OntologySchema OWL multi-inheritance 6a6acdf6 EntityClass.extra_parents field, parents() iterator, is_ancestor BFS upgrade. 3 new regression tests.
is_ancestor codex P2 + fmt (CI fixes on this same PR) 510d5f36 Drop MAX_VISITS=4096 hard cap that could false-negative on large biomedical ontologies (FMA 75k / ChEBI 200k+ classes). visited: HashSet already provides O(N) termination. Plus rustfmt 1.95.0 collapse.
simd_caps substrate-graduation ef07808f First step of the substrate-graduation thread (#192 wrap-up note 1). src/hpc/simd_caps.rssrc/simd_caps.rs with pub use crate::simd_caps; back-compat re-export in crate::hpc::*. No API breakage; cross-repo use ndarray::hpc::simd_caps::* imports keep working unmodified.
PR-X10 A6 closeoutl1/l2/linf_f64_simd slice kernels 5441435a Three slice-shape geometric distance kernels: l1_f64_simd (Manhattan), l2_f64_simd (Euclidean), linf_f64_simd (Chebyshev). Salvaged from the rolled-back PR #160 cross-repo arc (lance-graph heel_f64x8::{l1, l2, linf}_f64_simd), re-landed at crate::hpc::distance per the crate::hpc::linalg/mod.rs hard boundary ("No distance metrics — those live in crate::hpc::distance"). 12 new tests, all 24 hpc::distance tests pass. Polyfill-clean (no target_feature, no unsafe).

Why all in one PR

Branch constraint: the task description pins all development to claude/continue-ndarray-x0Oaw, so commits stack on the same branch sequentially. Each commit is logically independent — if you want them split into separate PRs, the cleanest path is to merge in chronological order and then re-base any remaining commits onto fresh master. Otherwise they review fine together since they touch entirely disjoint files except for the back-compat re-export line in src/hpc/mod.rs.

dn_tree fix (428f4969)

Production usage (DNConfig default lr=0.03 with boost up to ~30 → effective_lr ≈ 0.9) never hit p=0.5 exactly so the bug was dormant. Pillar 13's independently-derived probability_mask used the strict p > 0.5 and correctly fell through to the AND-cascade — that was the canonical reference this fix matches.

Two regression tests:

  • make_probability_mask_at_half_terminates — would stack-overflow if the fix regresses.
  • make_probability_mask_at_half_is_bernoulli_half — empirical popcount mean over N=1024 lands within 16 SEs of 32.

The Pillar 13 drift-check (pillar_13_matches_production_bundle_into) updates TEST_LR from 0.25 → 0.5 — the canonical mid-range value the pillar was originally designed for. Still passes bit-exactly across all 16 trials.

OntologySchema multi-parent (6a6acdf6)

Why it matters now: the lance-graph FMA OWL hydrator spec (PR-D-1) pipes ~75k anatomical classes through this code path. Silently discarding multi-parent edges would corrupt closure-based reasoning everywhere — type-gated cascade propagation in the cognitive shader, is_ancestor queries, the closure axes Pillar 14 drift-checks.

Back-compat: EntityClass.parent: Option<Box<str>> keeps its semantics — first-observed parent IRI. New extra_parents: Vec<Box<str>> holds the rest. Single-parent ontologies (RDFS-style chain test fixtures) are unchanged byte-for-byte.

is_ancestor BFS rewrite: previous linear walk via entity.parent would miss any ancestor reachable only through the second/third parent of a multi-inheritance class. Now uses BFS over entity.parents() (chains primary + extras). Single-parent chains still terminate at parent==None in the original O(depth) shape — no perf regression on the common case.

3 new regression tests: is_ancestor_multi_parent_direct, is_ancestor_multi_parent_transitive_through_second_parent (the bug case the previous implementation silently missed), entity_class_parents_iterator_yields_all.

Codex P2 + FMT (510d5f36)

chatgpt-codex-connector on 6a6acdf669: the new BFS had a hard MAX_VISITS=4096 cap that could produce false-negatives on schemas with more than 4096 reachable superclass nodes. FMA has 75k classes; ChEBI has 200k+. Removed; termination is still guaranteed by visited: HashSet<&str> (each parent IRI enters at most once, gated frontier pushes ⇒ O(unique IRIs reachable) total work, finite by schema finiteness).

simd_caps graduation (ef07808f)

First step in the substrate-graduation thread documented in #192's wrap-up note. The hpc/ namespace was the rustynum migration staging area; substrate-tier modules are accumulated there but architecturally belong at crate root next to simd.rs / simd_runtime/.

simd_caps is the smallest and cleanest first move:

  • No internal hpc/ dependencies (only std::sync::LazyLock).
  • 8 internal callers; back-compat re-export keeps them working unchanged.
  • Pure CPU-detection metadata; the most polyfill-adjacent module in hpc/.

Changes:

  • src/hpc/simd_caps.rssrc/simd_caps.rs (git mv).
  • src/lib.rs adds #[cfg(feature = "std")] pub mod simd_caps;. std-gate retained for now (uses std::sync::LazyLock); core::sync::LazyLock follow-up could lift it.
  • src/hpc/mod.rs replaces pub mod simd_caps; with pub use crate::simd_caps; — keeps crate::hpc::simd_caps::* resolving for cross-repo use ndarray::hpc::simd_caps::* imports.

Next graduation candidates (deferred): fingerprint, dn_tree, ogit_bridge, splat3d. Each is its own focused PR following the same pattern; cognitive layer stays inside hpc/.

PR-X10 A6 closeout — slice-shape geometric distance (5441435a)

Lands the three slice-shape kernels designated as worker A6 in pr-x10-linalg-core-design.md (lines 173-191). These are the salvaged kernels from the rolled-back PR #160 cross-repo arc (lance-graph heel_f64x8::{l1, l2, linf}_f64_simd), re-landed in ndarray at crate::hpc::distance per the crate::hpc::linalg/mod.rs hard boundary ("No distance metrics — those live in crate::hpc::distance").

The PR-X10 design doc named the destination as linalg/distance.rs, but the linalg-core sprint that landed on master made the call to keep distance at top-level crate::hpc::distance (sibling to linalg). This commit follows that decision — the slice-shape L1/L2/L∞ are natural extensions of the existing 3D-point-cloud distance functions already in the module.

Kernels:

  • l1_f64_simd(a, b) -> f64 — Σ |a_i - b_i| (EXACT precision class)
  • l2_f64_simd(a, b) -> f64 — √Σ (a_i - b_i)² (VERIFY — 1 ULP from sqrt)
  • linf_f64_simd(a, b) -> f64 — max |a_i - b_i| (EXACT precision class)

All three follow the heel_f64x8::cosine_f64_simd idiom: F64x8 polyfill chunked path (8 elements per iteration) + scalar remainder. No target_feature, no unsafe — runtime dispatch is owned by the polyfill (AVX-512 native zmm / AVX2 2×ymm / scalar [f64; 8]).

Tests (12 new):

  • Self-distance is exactly 0.0 for each kernel
  • Empty inputs return 0.0
  • Boundary cases: 17-element inputs (1 chunk + 1 remainder), pythagoras on (3,0)/(0,4) for L2, max-pick within chunk for L∞
  • Parity vs scalar on 10 sizes spanning chunk-aligned + remainder (n=1,7,8,15,16,17,64,199,200,1024), SplitMix64-seeded corpora
  • Mismatched-length slices use min(a.len(), b.len()), no panic

Status of PR-X10's W1-W2 sprint after this commit: all A1-A12 worker outputs present on master. The Hilbert-3D L4 P0-4 gate from pp13-brutally-honest-tester-verdict.md is already cleared on master (Skilling 2004 algorithm, 13 tests including exhaustive 4096-cell bijection + connectivity). PP13's pillar-side P0-1/P0-2/P0-3 findings (Pillar 6/7.5/8 structural threshold failures) are also resolved on master — 131 pillar tests pass under --features pillar. PR-X10 W1-W2 sprint is now CLOSED with this commit.

Verification (across all five commits)

cargo build -p ndarray --lib --no-default-features                       # clean
cargo build -p ndarray --lib --features runtime-dispatch                 # clean
cargo test -p ndarray --lib --features pillar dn_tree::tests             # 2 new tests pass
cargo test -p ndarray --lib --features pillar pillar_13_matches          # bit-exact at lr=0.5
cargo test -p ndarray --lib --features ogit_bridge hpc::ogit_bridge::schema  # 18 tests
cargo test -p ndarray --lib --features runtime-dispatch simd_caps::      # 10 tests, new path
cargo test -p ndarray --lib --features runtime-dispatch cpu_ops::        # 6 tests
cargo test -p ndarray --lib hpc::distance                                # 24 tests (12 new)
cargo test -p ndarray --lib --features pillar hpc::pillar                # 131 tests
cargo fmt --all --check                                                  # clean
cargo clippy --features "ogit_bridge,runtime-dispatch" --lib -- -D warnings  # clean

Threads accounted for

Thread Status
dn_tree p=0.5 ✅ this PR
OntologySchema multi-parent ✅ this PR
Codex P2 (MAX_VISITS) + FMT CI ✅ this PR
Substrate graduation — simd_caps only ✅ this PR (first module; fingerprint/dn_tree/ogit_bridge/splat3d deferred)
PR-X10 W1-W2 sprint A6 closeout ✅ this PR (Hilbert-3D L4 + pillar P0-1/2/3 already resolved on master; A6 was the only outstanding worker)
Pillar 15/16/17 production-kernel activations Deferred — gated on PR-X4/X9/X12 workers landing (W4-W7 of the substrate-execution plan)

Summary by CodeRabbit

  • New Features

    • Added three new distance metric functions for vector comparisons: Manhattan distance (L1), Euclidean distance (L2), and Chebyshev distance (L∞).
    • Centralized SIMD capability detection system for improved performance optimization.
  • Bug Fixes

    • Fixed infinite recursion issue in probability mask generation for edge cases.
    • Enhanced ontology schema to support multi-parent inheritance relationships with improved ancestor detection.
  • Chores

    • Expanded test coverage for distance metrics and schema functionality.

Review Change Stack

claude added 2 commits May 21, 2026 13:19
Latent bug surfaced during the Pillar 13 drift-check wiring (#191):
`make_probability_mask` used `p >= 0.5` to invert the (1-p) mask,
which recursed with `1.0 - 0.5 = 0.5` infinitely whenever p was
exactly 0.5. Pillar 13's independent re-derivation used the strict
`p > 0.5` and correctly fell through to the AND-cascade — that's
the canonical reference this fix matches.

Real production usage (DNConfig default lr=0.03 with boost ~30 →
effective_lr ≈ 0.9) never hit 0.5 exactly so the bug was dormant.
Now that it's fixed:

  * Update Pillar 13's drift-check to use lr=0.5 (its canonical
    mid-range value per the pillar spec) instead of the lr=0.25
    workaround. The drift-check now exercises the previously-broken
    branch and continues to pass bit-exactly.
  * Add two regression tests on dn_tree itself:
    - `make_probability_mask_at_half_terminates` — would
      stack-overflow if the fix regresses.
    - `make_probability_mask_at_half_is_bernoulli_half` —
      empirical popcount mean over N=1024 lands near 32 within
      16 standard errors.

No public API change. The fix is two characters: `>=` → `>`.
OWL permits a class to declare multiple `rdfs:subClassOf` triples
(multi-inheritance); biomedical ontologies (FMA's ~75k anatomical
classes, ChEBI, GO) use it extensively. Production `OntologySchema`
previously stored a single `parent: Option<Box<str>>` and the
`from_triples` loop silently overwrote on each new `subClassOf`
triple — the second declared parent won, the first was discarded
without warning.

Identified during the FMA hydrator spec review
(lance-graph/.claude/specs/pr-d-1-fma-owl-hydrator.md): Pattern D
hydrates OWL ontologies through this code path, and silently losing
half a class's inheritance edges would corrupt any downstream
closure-based reasoning (is_ancestor, type-gated propagation).

Changes:

1. `EntityClass` gains `extra_parents: Vec<Box<str>>` — additional
   parents beyond the first-observed. `parent: Option<Box<str>>`
   keeps the first observed parent (back-compat for single-parent
   consumers that read `.parent` directly).

2. `EntityClass::parents()` accessor — iterator over every parent
   in source order. Use this in preference to reading `.parent`
   when the caller's logic must cover multi-inheritance.

3. `from_triples` no longer silently overwrites: the first
   subClassOf populates `parent`; later ones append to
   `extra_parents` (dedup against the existing primary + extras).

4. `is_ancestor` walks the multi-parent DAG via BFS instead of the
   linear parent chain — this is the case the previous
   implementation silently missed. MAX_VISITS=4096 caps total work
   (defensive guard against cycles); single-parent chains still
   terminate at parent==None in the original O(depth) shape.

3 new regression tests:
- `is_ancestor_multi_parent_direct` — two `subClassOf` triples on
  one class; both parents reachable.
- `is_ancestor_multi_parent_transitive_through_second_parent` —
  the bug case: ancestor only reachable through the second parent
  chain. Would fail on the previous implementation.
- `entity_class_parents_iterator_yields_all` — parents() surfaces
  every declared parent.

All 18 ogit_bridge::schema tests pass; lib fmt + clippy clean.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6a6acdf669

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/hpc/ogit_bridge/schema.rs Outdated
Comment on lines +696 to +697
if visits > MAX_VISITS {
return false;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid false negatives from fixed MAX_VISITS limit

The new multi-parent traversal returns false once visits > 4096, which can incorrectly reject real ancestor relationships in large acyclic ontologies (or dense imported DAGs) where a descendant has more than 4096 reachable superclass nodes before the target ancestor is popped. This cap is now on total explored nodes rather than chain depth, so correctness depends on graph size/order rather than ancestry, and downstream closure checks can silently miss valid ancestors.

Useful? React with 👍 / 👎.

claude added 2 commits May 21, 2026 13:34
…(codex P2)

Two CI fixes on PR #193:

1) Codex P2 — Drop the MAX_VISITS=4096 hard cap in `is_ancestor`.
   The previous cap could produce false-negatives on large
   biomedical ontologies (FMA: 75k classes; ChEBI: 200k+ classes)
   where a descendant has more than 4096 reachable superclass
   nodes before the target ancestor is popped.

   Termination is still guaranteed by the `visited: HashSet<&str>`:
   every parent IRI enters at most once, frontier pushes are
   gated on `visited.insert(...)`, so the total work bound is
   O(unique IRIs reachable from descendant) — finite by the
   schema's own finiteness. No explicit cap needed.

2) Rustfmt 1.95.0 collapse on the new
   `make_probability_mask_at_half_is_bernoulli_half` test
   assertion — same canonical-fmt collapse as prior hotfixes.

No behavioral change beyond removing the artificial cap.
…t re-export

First step in the substrate-graduation thread documented in #192's
wrap-up: lift the substrate-tier modules out of `hpc/` (which was
the rustynum migration staging area) to crate root, where they sit
in scope of the W1a polyfill contract and no longer carry the
spurious `std`-gate inherited from `hpc/`.

`simd_caps` is the smallest and cleanest first move:
  * No internal `hpc/` dependencies (only `use std::sync::LazyLock`).
  * 8 internal callers; back-compat re-export keeps them working.
  * Pure CPU-detection metadata; the most polyfill-adjacent module
    in the entire `hpc/` set.

Changes:

1. `src/hpc/simd_caps.rs` → `src/simd_caps.rs` (file move).
2. `src/lib.rs` adds `#[cfg(feature = "std")] pub mod simd_caps;`.
   The std-gate is retained for now (uses `std::sync::LazyLock`);
   lifting it to `core::sync::LazyLock` is a separate follow-up.
3. `src/hpc/mod.rs` replaces `pub mod simd_caps;` with
   `pub use crate::simd_caps;` — keeps `crate::hpc::simd_caps::*`
   resolving for cross-repo consumers (lance-graph, WoA, MedCare,
   q2 may have `use ndarray::hpc::simd_caps::*` imports that this
   preserves untouched).

No public-API breakage; the test suite picks up the new path
(test names now `simd_caps::tests::*` rather than `hpc::simd_caps::*`),
all 10 tests pass under both default and `runtime-dispatch` configs.
The 8 internal callers (`crate::simd_avx512`, `crate::hpc::p64_bridge`,
`crate::simd_runtime::{cpu_ops, add_mul, vnni_dot}`) continue using
`crate::hpc::simd_caps::*` via the re-export and work unmodified.

Next graduation candidates (deferred to follow-up PRs):
  - `fingerprint` (bitwise substrate; raw `u64` polyfill audit)
  - `dn_tree` (bitwise substrate; same audit)
  - `ogit_bridge` (pure logic, no SIMD primitives)
  - `splat3d` (already uses `crate::simd::*` polyfilled types)

Each move follows the same pattern: relocate file, drop std-gate
inheritance where unneeded, keep back-compat re-export. Cognitive
layer (pillar, plane, seal, merkle_tree, deepnsm, …) stays inside
`hpc/` and keeps its legitimate std-gate.
@AdaWorldAPI AdaWorldAPI changed the title fix(dn_tree): p=0.5 infinite recursion + feat(ogit_bridge): multi-parent OntologySchema fixes + substrate work: dn_tree p=0.5, OntologySchema multi-parent, codex P2, simd_caps graduation May 21, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fc430622-278b-4e31-a677-6e53e9509af2

📥 Commits

Reviewing files that changed from the base of the PR and between 5441435 and 8add2d6.

📒 Files selected for processing (1)
  • src/hpc/distance.rs

📝 Walkthrough

Walkthrough

Adds three SIMD-polyfill distance kernels for arbitrary-length f64 slices, centralizes simd_caps at crate root, enables OWL-style multi-parent EntityClass with BFS ancestor resolution, and fixes make_probability_mask’s p==0.5 infinite-recursion bug with tests.

Changes

SIMD Distance Functions

Layer / File(s) Summary
SIMD capability detection infrastructure
src/lib.rs, src/hpc/mod.rs
New pub mod simd_caps at crate root (cfg std) provides lazy SIMD capability detection; hpc re-exports it for backward compatibility.
Distance metric implementations and tests
src/hpc/distance.rs
l1_f64_simd, l2_f64_simd, linf_f64_simd compute L1, L2, and L∞ over min(a.len(), b.len()) using F64x8 chunked processing (8-at-a-time) plus scalar remainder; tests cover self-zero, empty slices, parity vs scalar, L2 Pythagoras, L∞ chunk/remainder selection, and mismatched-length semantics.

Ontology Schema Multi-Parent Inheritance

Layer / File(s) Summary
Multi-parent EntityClass data model
src/hpc/ogit_bridge/schema.rs
Adds extra_parents: Vec<Box<str>> and parents() iterator to yield parent then extra_parents in source order.
Schema construction and ancestor resolution
src/hpc/ogit_bridge/schema.rs
from_triples preserves the first parent and appends distinct subsequent parents to extra_parents; is_ancestor rewritten as BFS over EntityClass::parents() with a visited set; tests validate multi-parent reachability and parents() output.

Probability Mask Edge Case Fix

Layer / File(s) Summary
Probability mask control flow fix and test coverage
src/hpc/dn_tree.rs, src/hpc/pillar/hhtl_contraction.rs
make_probability_mask now uses strict p > 0.5 for the inversion branch so p == 0.5 follows the AND-cascade path; adds regression and empirical tests for termination and Bernoulli(0.5) mean; updates test LR to 0.5 to exercise the fixed branch.

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I stitched eight floats to race in lanes so neat,
DAG branches hum as parents all meet,
Masks that once looped now halt on a dime,
F64 thrums, tests pass in time—hop, celebrate! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title mentions six distinct areas (dn_tree fix, OntologySchema multi-parent, codex P2, simd_caps, PR-X10 A6 distance kernels) but the raw_summary shows five file changes across these topics. While the title references real aspects of the changeset, it reads as a condensed list of changes rather than clearly highlighting the primary change or intent. Consider a more focused title that either emphasizes the main theme (e.g., 'Multi-parent ontology inheritance, distance kernels, and dn_tree fix') or breaks multi-aspect PRs into separate commits with individual titles.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/continue-ndarray-x0Oaw

Comment @coderabbitai help to get the list of available commands and usage tips.

Lands the three slice-shape geometric distance kernels designated as
worker A6 in `pr-x10-linalg-core-design.md` (lines 173-191). These
are the salvaged kernels from the rolled-back PR #160 cross-repo arc
(lance-graph `heel_f64x8::{l1, l2, linf}_f64_simd`), re-landed in
ndarray at `crate::hpc::distance` per the `crate::hpc::linalg/mod.rs`
hard boundary ("No distance metrics — those live in `crate::hpc::distance`").

The PR-X10 design doc named the destination as `linalg/distance.rs`,
but the linalg-core sprint that landed on master made the call to
keep distance at top-level `crate::hpc::distance` (sibling to linalg).
This commit follows that decision — the slice-shape L1/L2/L∞ are
natural extensions of the existing 3D-point-cloud distance functions
already in the module.

# Kernels

- `l1_f64_simd(a, b) -> f64`   — Σ |a_i - b_i|
- `l2_f64_simd(a, b) -> f64`   — √Σ (a_i - b_i)²
- `linf_f64_simd(a, b) -> f64` — max |a_i - b_i|

All three follow the `heel_f64x8::cosine_f64_simd` idiom: `F64x8`
polyfill chunked path (8 elements per iteration) + scalar remainder.
No `target_feature`, no `unsafe` — runtime dispatch is owned by the
polyfill (AVX-512 native zmm / AVX2 2×ymm / scalar `[f64; 8]`).

L1 and L∞ are EXACT precision (no rounding beyond the underlying
subtract). L2 is VERIFY — final `sqrt` is 1 ULP; cross-chunk order
matches the existing heel_f64x8 pattern (sequential across chunks +
lane-tree within each F64x8). Documented in each function's docstring.

# Tests (12 new)

- Self-distance is exactly 0.0 for each kernel
- Empty inputs return 0.0
- Boundary cases: 17 elements (1 chunk + 1 remainder), pythagoras
  on (3,0)/(0,4) for L2, max-pick within chunk for L∞
- Parity vs scalar on 10 sizes spanning chunk-aligned + remainder
  (n=1,7,8,15,16,17,64,199,200,1024), SplitMix64-seeded corpora
- Mismatched-length slices use min(a.len(), b.len()), no panic

All 24 `hpc::distance` tests pass; lib fmt + clippy clean.

# Status of PR-X10's W1-W2 sprint after this commit

A1-A12 worker outputs all present on master:
  A1 matrix.rs, A2 quat.rs, A3 inverse.rs, A4 eig_sym.rs,
  A5 svd.rs, A6 polar.rs + matfn.rs + distance.rs (this commit),
  A7 sh.rs, A8 conv.rs, A9 batched.rs/norm.rs/activations_ext.rs,
  A10 rope.rs/attention.rs, A11 loss.rs, A12 hilbert.rs

The Hilbert-3D L4 P0-4 gate from pp13-brutally-honest-tester-verdict.md
is already cleared on master — `hpc::linalg::hilbert` ships the
Skilling 2004 algorithm (transpose-form + Gray code), with 13 tests
including `level4_all_indices_unique` (exhaustive 4096-cell bijection)
and `level4_curve_is_connected` (exhaustive 4095-pair Manhattan-1
connectivity). All pass.

PP13's pillar-side P0-1/P0-2/P0-3 findings (Pillar 6/7.5/8 PASS-gate
structural failures) are also resolved on master — 131 pillar tests
pass under `--features pillar`, including the previously-flagged
`prove_pillar_6_passes`, `prove_pillar_7_5_pass`, `prove_band_cardiac_pass`,
`prove_band_respiratory_pass`, `prove_band_micro_pass`.

PR-X10 W1-W2 sprint is now CLOSED.
@AdaWorldAPI AdaWorldAPI changed the title fixes + substrate work: dn_tree p=0.5, OntologySchema multi-parent, codex P2, simd_caps graduation fixes + substrate work: dn_tree, OntologySchema multi-parent, codex P2, simd_caps, PR-X10 A6 distance kernels May 21, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/hpc/ogit_bridge/schema.rs (1)

683-720: 💤 Low value

Minor doc inconsistency: comment says "BFS" but the algorithm is DFS.

The implementation uses Vec::pop() (LIFO), making this a depth-first traversal rather than breadth-first. The reachability result is correct either way, but the comment at line 683 is technically inaccurate.

📝 Suggested documentation fix
-        // BFS over the multi-parent DAG. The previous version walked a
+        // DFS over the multi-parent DAG. The previous version walked a

Alternatively, to make it true BFS, use VecDeque::pop_front() instead of Vec::pop().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hpc/ogit_bridge/schema.rs` around lines 683 - 720, The comment
incorrectly describes the traversal as "BFS" while the code performs DFS using
`frontier: Vec<&str>` and `frontier.pop()` in the reachability loop; either
update the comment to say "DFS (stack-based) over the multi-parent DAG" or
switch the implementation to true BFS by replacing `frontier: Vec<&str>` with a
`VecDeque<&str>`, use `frontier.push_back(descendant)` /
`frontier.push_back(parent)` and `frontier.pop_front()` in the loop; reference
the `frontier`, `visited`, `descendant`, `ancestor`,
`self.entities.get(current)`, and `entity.parents()` symbols when making the
change so the semantics remain identical apart from traversal order.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/hpc/pillar/hhtl_contraction.rs`:
- Around line 489-494: Comments and rationale around the test lr value are
stale: update all downstream commentary that references lr=0.25, “2 draws per
word”, and the “Why not lr=0.5” block to reflect TEST_LR = 0.5; specifically, in
hhtl_contraction.rs update any explanatory text near TEST_LR and in surrounding
doc/test comments (search for "lr=0.25", "2 draws per word", and "Why not
lr=0.5") so they describe the current behavior with lr=0.5 and why that value is
chosen, removing or rewriting any rationale that assumes the old 0.25 behavior.

---

Nitpick comments:
In `@src/hpc/ogit_bridge/schema.rs`:
- Around line 683-720: The comment incorrectly describes the traversal as "BFS"
while the code performs DFS using `frontier: Vec<&str>` and `frontier.pop()` in
the reachability loop; either update the comment to say "DFS (stack-based) over
the multi-parent DAG" or switch the implementation to true BFS by replacing
`frontier: Vec<&str>` with a `VecDeque<&str>`, use
`frontier.push_back(descendant)` / `frontier.push_back(parent)` and
`frontier.pop_front()` in the loop; reference the `frontier`, `visited`,
`descendant`, `ancestor`, `self.entities.get(current)`, and `entity.parents()`
symbols when making the change so the semantics remain identical apart from
traversal order.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 467d020f-14dc-4a8f-b483-5db7e29ebd8e

📥 Commits

Reviewing files that changed from the base of the PR and between adeba8a and 5441435.

📒 Files selected for processing (7)
  • src/hpc/distance.rs
  • src/hpc/dn_tree.rs
  • src/hpc/mod.rs
  • src/hpc/ogit_bridge/schema.rs
  • src/hpc/pillar/hhtl_contraction.rs
  • src/lib.rs
  • src/simd_caps.rs

Comment on lines +489 to +494
// Was 0.25 to avoid the latent p=0.5 infinite-recursion bug in
// production's make_probability_mask; that bug is fixed in the
// same commit/PR that updates this constant. lr=0.5 now matches
// Pillar 13's canonical mid-range learning rate and exercises
// the previously-broken branch.
const TEST_LR: f64 = 0.5;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the drift-check rationale to match TEST_LR = 0.5.

After switching to 0.5, downstream comments in this test still describe lr=0.25 and “2 draws per word” assumptions. Please align those comments (including the “Why not lr=0.5” block) with current behavior to avoid misleading future edits.

Suggested comment-only cleanup
- // of next_u64() draws per word at p=0.25 (n=ceil(-log2(0.25))=2),
+ // of next_u64() draws per word at TEST_LR=0.5 (n=1),
...
- // 256 words × 2 draws = 1536) than pillar's bundle_step (16 words
- // × 2 draws = 32). Without re-seeding, post-trial-0 RNG states
+ // 256 words × 1 draw = 768) than pillar's bundle_step (16 words
+ // × 1 draw = 16). Without re-seeding, post-trial-0 RNG states
  // diverge.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hpc/pillar/hhtl_contraction.rs` around lines 489 - 494, Comments and
rationale around the test lr value are stale: update all downstream commentary
that references lr=0.25, “2 draws per word”, and the “Why not lr=0.5” block to
reflect TEST_LR = 0.5; specifically, in hhtl_contraction.rs update any
explanatory text near TEST_LR and in surrounding doc/test comments (search for
"lr=0.25", "2 draws per word", and "Why not lr=0.5") so they describe the
current behavior with lr=0.5 and why that value is chosen, removing or rewriting
any rationale that assumes the old 0.25 behavior.

Copy link
Copy Markdown
Owner Author

@chatgpt-codex-connector this is fixed in 510d5f36 (third commit on this PR, pushed about an hour ago). Codex reviewed 6a6acdf669 — the immediately-following commit drops the MAX_VISITS=4096 hard cap entirely.

Verification on current branch head 5441435a (src/hpc/ogit_bridge/schema.rs:693-720):

// BFS over the multi-parent DAG. The previous version walked a
// linear chain via `EntityClass.parent` alone — correct for
// single-inheritance schemas but missed ancestors reachable
// only through `EntityClass.extra_parents` (OWL multi-inheritance,
// common in FMA / ChEBI).
//
// # Termination
//
// `visited` is a monotonically-growing `HashSet<&str>` keyed by
// IRI; each parent IRI enters the set at most once. Frontier
// pushes are gated on `visited.insert(...)`, so every IRI is
// pushed at most once across the entire walk. Total work is
// therefore O(unique IRIs reachable from descendant) — finite
// by the schema's finiteness, regardless of branching factor
// or depth. No explicit visit cap is needed; previous codex P2
// pointed out that a hard cap would produce false-negatives on
// large biomedical ontologies (FMA: 75k classes; ChEBI: 200k+).
let mut frontier: Vec<&str> = vec[descendant];
let mut visited: std::collections::HashSet<&str> = std::collections::HashSet::new();
visited.insert(descendant);
while let Some(current) = frontier.pop() {
    // ... walk parents via entity.parents(), insert into visited+frontier
}

No MAX_VISITS, no visits counter, no if visits > N { return false; }. The visited HashSet's monotonic insert is the sole termination mechanism, bounded by O(unique IRIs reachable from descendant) — finite by schema finiteness regardless of branching factor or depth. FMA (75k classes) and ChEBI (200k+) both fit cleanly.

The fix-commit's message explicitly references this codex finding: "Codex P2 — Drop the MAX_VISITS=4096 hard cap in is_ancestor. The previous cap could produce false-negatives on large biomedical ontologies..." 👍


Generated by Claude Code

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

Same canonical-fmt collapse as the prior pillar/ogit_bridge hotfixes
on this PR. No behavioral change.
@AdaWorldAPI AdaWorldAPI merged commit a0f8fb3 into master May 21, 2026
17 checks passed
AdaWorldAPI pushed a commit that referenced this pull request May 21, 2026
Continues the substrate-graduation thread documented in #192's wrap-up
and extended in #193's simd_caps lift. Five more modules move from
`crate::hpc::*` (the rustynum migration staging area) to crate root
where they sit alongside `simd.rs`, `simd_runtime/`, `simd_caps`, and
the W1a polyfill surface they're supposed to compose with.

| Module | Reason |
|---|---|
| `bitwise`        | Pure SIMD primitives (popcount, hamming over byte slices); already uses `crate::simd::U64x8` polyfill internally; already re-exported via `simd.rs:512`. |
| `heel_f64x8`     | All-F64x8 polyfill consumer (dot, cosine, sum-sq, weighted-hamming); already re-exported via `simd.rs:563`. |
| `distance`       | Spatial 3D + slice-shape L1/L2/L∞ (PR-X10 A6); the linalg/mod.rs hard-boundary comment now points here at root. |
| `byte_scan`      | Pure SIMD utility (needle search, delimiter find). |
| `spatial_hash`   | Pure SIMD utility (bucketing, candidate gather). |

# Why these five, why now

All five satisfied the low-hanging-fruit criteria from #193's wrap-up
discussion:
  1. No internal `hpc/` dependencies (only `super::simd_caps` which
     still resolves correctly because `simd_caps` is itself at crate
     root post-#192).
  2. Already polyfill-clean — no raw-intrinsic refactor needed before
     the move.
  3. Already partially exposed via `crate::simd::*` re-exports.

The next graduation tier (`fingerprint`, `dn_tree`, `ogit_bridge`,
`splat3d`) needs a polyfill audit before it can move, and
`fingerprint` in particular is gated on the W1a-#5 POPCOUNT-U64
primitive landing (so its bit ops can route through `U64xN.popcnt()`
instead of raw `u64.count_ones()`).

# Back-compat preserved end-to-end

Every cross-repo consumer using `ndarray::hpc::{bitwise, heel_f64x8,
distance, byte_scan, spatial_hash}::*` continues to compile
unmodified. The `src/hpc/mod.rs` declarations change from
`pub mod X;` to `pub use crate::X;` — Rust re-exports modules just
like other items, so `crate::hpc::X::*` resolves through to the same
items as `crate::X::*`. Internal `super::simd_caps::simd_caps()`
calls inside the moved files continue to work because `super::` at
crate root resolves to `crate::*` which has `simd_caps` (graduated
in #192).

# Changes

- `git mv` five files from `src/hpc/` to `src/`.
- `src/lib.rs` gains five `#[cfg(feature = "std")] pub mod X;`
  declarations next to the existing `simd_caps` block, each with a
  one-liner docstring naming the graduation source and the
  substrate-tier reason for the move.
- `src/hpc/mod.rs` replaces five `pub mod X;` with `pub use crate::X;`
  (back-compat re-exports).
- `src/hpc/linalg/mod.rs` updates the hard-boundary comment from
  "No distance metrics — those live in `crate::hpc::distance`" to
  point at `crate::distance` (the new canonical path) with a
  parenthetical noting the back-compat re-export.
- The `bitwise.rs` declaration in `src/hpc/mod.rs` is now a comment
  instead of being interleaved with `pub mod hdc`/`pub mod projection`
  to make the graduation status visible at a glance.

# Verification

- `cargo build -p ndarray --lib` — clean
- `cargo build -p ndarray --lib --no-default-features` — clean
  (the new `#[cfg(feature = "std")]` gates match the existing
  `simd_caps` pattern; nostd targets see no change)
- `cargo test -p ndarray --lib bitwise:: distance:: heel_f64x8::
  byte_scan:: spatial_hash::` — all 119 tests on the five graduated
  modules pass at the new path (test names now `bitwise::tests::*`
  rather than `hpc::bitwise::tests::*`)
- `cargo test -p ndarray --lib --features "pillar,ogit_bridge,
  runtime-dispatch" hpc::` — 2167 passed, 0 failed, 28 ignored
- `cargo fmt --all --check` — clean
- `cargo clippy --features "pillar,ogit_bridge,runtime-dispatch"
  --lib -- -D warnings` — clean

# Next graduation candidates (deferred)

- `hpc::fingerprint` — needs W1a-#5 POPCOUNT-U64 to land first so
  bit ops can route through `U64xN.popcnt()` instead of raw
  `u64.count_ones()`. Cognitive-shader-foundation explicitly names
  `Fingerprint<N>` as a MUST-be-in-`ndarray::simd::*` type.
- `hpc::dn_tree` (bitwise core) — same polyfill-audit dependency.
  The cognitive DNTree/DNConfig/TraversalHit state stays in
  `hpc/` after the split.
- `hpc::ogit_bridge` — pure logic, no SIMD, can move once the
  fingerprint + dn_tree audits are out of the way (avoids three
  partial graduations in flight at once).
- `hpc::splat3d` — already mostly polyfill-clean; pure path
  rewrite. Defer because it's a larger consumer surface than
  the five in this PR.
AdaWorldAPI pushed a commit that referenced this pull request May 21, 2026
Continues the substrate-graduation thread from #192 (simd_caps),
#193 (clippy/doc cleanup), and #194 (bitwise/heel_f64x8/distance/
byte_scan/spatial_hash). Same low-hanging-fruit criteria — no
internal hpc/ deps, polyfill-clean, single-line back-compat shim
keeps every existing import resolving.

| Module          | Reason                                                         |
|---|---|
| `aabb`          | SIMD AABB intersection/expansion/distance; only deps are       |
|                 | `crate::simd::F32x16` + `super::simd_caps` (graduated #192).   |
| `nibble`        | 4-bit packed nibble batch ops; only dep is `crate::simd::U8x64`.|
| `palette_codec` | Variable-width palette index codec (1-8 bit packing); zero deps.|
| `property_mask` | AVX-512 VPTERNLOGD bitset queries on block state bits;         |
|                 | only dep is `crate::simd::U64x8`.                              |

# Why these four, why now

All four satisfy the criteria from #194's wrap-up:
  1. No internal `hpc/` dependencies — only `crate::simd::*`
     (polyfill surface) and `super::simd_caps` (which is itself
     at crate root post-#192).
  2. Polyfill-clean — no raw-intrinsic refactor required.
  3. Single in-tree downstream caller (`hpc::framebuffer` uses
     `palette_codec`) → the `pub use crate::palette_codec;`
     back-compat shim keeps that resolution working zero-touch.

# Mechanical changes

- `git mv src/hpc/{aabb,nibble,palette_codec,property_mask}.rs src/`
- `src/lib.rs`: added four `pub mod` declarations under
  `#[cfg(feature = "std")]`, each with a `# Example` rustdoc block
  per CLAUDE.md "all public APIs need doc comments with examples".
- `src/hpc/mod.rs`: replaced the four `pub mod` declarations with
  `pub use crate::{aabb, nibble, palette_codec, property_mask};`
  back-compat re-exports. `crate::hpc::aabb::*` and friends keep
  resolving for every existing call site, identical to how
  `crate::hpc::bitwise::*` works post-#194.

# Clippy / lint cleanup

17 clippy errors surfaced under `-D warnings` once the modules
left the `hpc/mod.rs` `#![allow(clippy::all, ...)]` umbrella.
Fixed each at the canonical Rust idiom (the #194 cleanup pattern,
417131b), no umbrella re-application:

- **manual_div_ceil (6 sites)** — `(n + d - 1) / d` → `n.div_ceil(d)`
  in `nibble.rs` (x2), `palette_codec.rs` (x3), `property_mask.rs`.
- **needless_range_loop (10 sites)** — `for i in start..vec.len()`
  rewrites to `for x in &vec[start..]` (when index unused) or
  `for (i, &x) in iter().enumerate().skip(start)` (when index used).
  Sites: `aabb.rs` x4, `nibble.rs` x3, `palette_codec.rs` x1,
  `property_mask.rs` x2.
- **missing_docs (4 sites)** — added field doc comments on
  `pub struct Aabb { min, max }` and `pub struct Ray { origin,
  inv_dir }`. Previously masked by the `hpc/mod.rs` umbrella's
  `#![allow(missing_docs)]`.

# Doctest correction

Initial `# Example` in `src/lib.rs` for `palette_codec` asserted
`bits_for_palette_size(1) == 1` per the module's own docstring
table, but the impl returns 0 for `palette_size <= 1` (trivial-
palette special case). Changed assertion to use `bits_for_palette_
size(2) == 1` — exercises the same code path with input the impl
actually handles per spec.

# Verification

```
cargo check --lib                                          green
cargo clippy --lib -- -D warnings                          green
cargo clippy --lib --features rayon -- -D warnings         green
cargo clippy --features approx,serde,rayon -- -D warnings  green
cargo test --doc (15 graduated-module doctests)            pass
cargo test --lib (104 unit tests across 4 modules)         pass
```

# What's next

`hpc/` inventory: ~55 → ~51 modules at the staging path. Next-batch
candidates per the same criteria need a deps audit before move:
`framebuffer` (uses `palette_codec` shim, otherwise crate-root),
`ocr_simd`/`ocr_felt`, `audio`. Filed in AGENT_LOG entry for the
follow-up pass.

https://claude.ai/code/session_01HbqooFZHAjaUtFEzhA1R2u
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants