HNSW packed-index neighbour evaluation (2.3.1)#143
Conversation
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 2 minutes Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (29)
WalkthroughThis PR adds a ChangesNeighbour-scoring benchmark and write-lock invariant changes
Sequence Diagram(s)sequenceDiagram
participant SearchTest
participant CpuHnsw
participant WriteGraphScope
participant WriteLockAssertingSource
SearchTest->>CpuHnsw: write_graph(closure)
CpuHnsw->>WriteGraphScope: enter_if_enabled()
SearchTest->>CpuHnsw: search(query)
CpuHnsw->>WriteLockAssertingSource: batch_distances(query, candidates)
WriteLockAssertingSource->>CpuHnsw: current_thread_holds_write_graph_for_test()
CpuHnsw-->>WriteLockAssertingSource: false
WriteLockAssertingSource-->>CpuHnsw: distances
sequenceDiagram
participant NeighbourScoringBench
participant SupportRs
participant ProfilingSource
participant CpuHnsw
participant ReportRs
NeighbourScoringBench->>SupportRs: make_fixture(dimension, candidate_count)
SupportRs-->>NeighbourScoringBench: ScoringFixture
NeighbourScoringBench->>SupportRs: write_lane_utilisation_report()
SupportRs->>ReportRs: write_lane_utilisation_report_csv(rows)
NeighbourScoringBench->>SupportRs: write_build_profile_report()
SupportRs->>ProfilingSource: wrap SyntheticSource
SupportRs->>CpuHnsw: build(profiling_source)
SupportRs->>ProfilingSource: take_snapshot()
SupportRs->>ReportRs: write_build_profile_report_csv(rows)
NeighbourScoringBench->>ProfilingSource: batch_distances(query, candidates)
Possibly related PRs
Suggested labels: Suggested reviewers: Poem
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (3 errors, 2 warnings)
✅ Passed checks (15 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph. If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced. chutoro-test-support/src/lib.rs Comment on lines +46 to +57 pub fn set(key: &'static str, value: &str) -> Self {
let lock = env_lock();
let guard = Self {
key,
previous: env::var_os(key),
_lock: lock,
};
// SAFETY: all test environment mutations through this helper are
// serialized by ENV_LOCK and restored while holding the lock.
unsafe { env::set_var(key, value) };
guard
}❌ New issue: Code Duplication |
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph. If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced. chutoro-benches/src/neighbour_scoring/report.rs Comment on file }
fn csv_escape(field: &str) -> Cow<'_, str> {
if field.contains(',') || field.contains('"') || field.contains('\n') || field.contains('\r') {❌ New issue: Complex Conditional |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
There was a problem hiding this comment.
Sorry @leynos, your pull request is larger than the review limit of 150000 diff characters
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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 `@chutoro-core/src/hnsw/cpu/internal.rs`:
- Around line 22-66: Add a brief comment near WRITE_GRAPH_MARKER_ENABLE_COUNT
and WRITE_GRAPH_DEPTH explaining the two-tier design: the enable flag in
enable_write_graph_marker/disable_write_graph_marker is process-wide so any
Rayon worker entering write_graph is tracked once tests opt in, while
current_thread_holds_write_graph and WriteGraphScope use thread-local depth so
only the thread actually executing the write closure reports ownership; make
clear this avoids cross-thread false positives/negatives and should not be
collapsed into a single global boolean.
In `@chutoro-core/src/hnsw/cpu/test_helpers.rs`:
- Line 13: The WriteGraphMarkerGuard type is currently defined as an empty-brace
struct, so update it to a unit struct and adjust its construction sites
accordingly. Locate WriteGraphMarkerGuard in the HNSW CPU test helpers and
remove the braces from the type definition, then replace any
WriteGraphMarkerGuard {} instantiations with the unit form to keep the API
idiomatic and consistent.
In `@chutoro-core/src/hnsw/tests/write_lock.rs`:
- Around line 101-119: In `distance_batch`, the write-lock assertion is
happening before the output-length validation, which increments `scoring_calls`
even on rejected mismatched inputs. Update the method in `write_lock` so the
`pairs.len() != out.len()` check runs first, and only call
`assert_not_writing_graph()` after the lengths are confirmed to match. Keep the
rest of `distance_batch` unchanged, including the `distance_value` loop and
error return.
In `@chutoro-test-support/src/lib.rs`:
- Around line 12-109: Document that EnvVarGuard is non-reentrant and only one
guard may be alive at a time on a thread, since EnvVarGuard holds the ENV_LOCK
MutexGuard for its full lifetime and env_lock() will block on nested
acquisition. Update the EnvVarGuard struct-level docs and/or the
with_env_mutation/set/remove docs to state this restriction plainly, using the
EnvVarGuard and env_lock symbols so it’s easy to find. Keep the wording explicit
that attempting to create a second guard while one is active will deadlock/hang
rather than being supported.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2f7be0ee-d3c5-4931-bffe-ee70dcf71250
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (25)
.config/nextest.toml.gitignorechutoro-benches/Cargo.tomlchutoro-benches/benches/extraction.rschutoro-benches/benches/neighbour_scoring.rschutoro-benches/benches/neighbour_scoring/profiling.rschutoro-benches/benches/neighbour_scoring/support.rschutoro-benches/src/lib.rschutoro-benches/src/neighbour_scoring/build_profile.rschutoro-benches/src/neighbour_scoring/mod.rschutoro-benches/src/neighbour_scoring/profiling.rschutoro-benches/src/neighbour_scoring/report.rschutoro-benches/tests/neighbour_scoring_support.rschutoro-core/src/hnsw/cpu/internal.rschutoro-core/src/hnsw/cpu/test_helpers.rschutoro-core/src/hnsw/tests/mod.rschutoro-core/src/hnsw/tests/write_lock.rschutoro-test-support/src/lib.rsdocs/adr-003-soa-prefetch-adapter-boundary.mddocs/chutoro-design.mddocs/developers-guide.mddocs/execplans/2-2-6-property-based-backend-parity-suite.mddocs/execplans/2-3-1-hnsw-neighbour-evaluation-using-packed-indices.mddocs/roadmap.mdscripts/bench-neighbour-scoring.sh
|
@coderabbitai resume |
✅ Action performedReviews resumed. |
ee3efcb to
60bd7a4
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
.config/nextest.toml (1)
113-117: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winStrip the duplicated
[[profile.ci.overrides]]header — same defect as the default profile block.Identical issue to the
profile.default.overridesaddition above: the header line appears twice consecutively before the comment/filter/slow-timeout fields. Remove the stray duplicate.🔧 Proposed fix
-[[profile.ci.overrides]] [[profile.ci.overrides]] # Write-lock proptest can exceed the default timeout under CI load. filter = "test(/generated_hnsw_scoring_does_not_run_inside_write_graph_scope/)" slow-timeout = { period = "600s", terminate-after = 1, grace-period = "5s" }🤖 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 @.config/nextest.toml around lines 113 - 117, The `[[profile.ci.overrides]]` block has a duplicated table header, which should be removed so the overrides entry is declared only once. Update the `profile.ci.overrides` section in the nextest config to keep a single `[[profile.ci.overrides]]` header before the comment, filter, and slow-timeout fields, matching the intended structure used in the `profile.default.overrides` block.
🤖 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 `@chutoro-benches/benches/extraction.rs`:
- Line 19: Hoist the shared Criterion CLI probe out of the extraction bench so
it is not duplicated per benchmark file. Move is_exact_benchmark_probe into a
common support module such as chutoro-benches/src/lib.rs, then update
extraction.rs and the matching hnsw bench to call that shared helper instead of
keeping separate copies; if the same warm-up/measurement adjustment pattern is
repeated, centralize that too (for example by extracting the
configure_extraction_group-style logic).
In `@chutoro-benches/benches/hnsw.rs`:
- Around line 137-139: The exact-probe short-circuit and the `SourceBenchSpec`
label both hard-code the `"text_levenshtein"` string, so they can drift and
break the `should_short_circuit_exact_text_probe` behavior. Extract that label
into a shared constant in `hnsw.rs` and use it both in
`should_short_circuit_exact_text_probe` and where the `SourceBenchSpec` is
constructed. This keeps the `CpuHnsw` benchmark label and the exact-probe check
in sync and lets the compiler catch future renames.
In `@chutoro-benches/benches/neighbour_scoring.rs`:
- Around line 38-49: Stop duplicating the truthy environment flag parsing in
should_use_short_measurement_value and reuse the shared helper already used by
should_collect_build_profile_value. Extract the
trim/lowercase/"1"|"true"|"on"|"yes" predicate into a single exported helper in
build_profile.rs, re-export it through mod.rs with the other #[doc(hidden)]
utilities, and update both should_use_short_measurement() and
should_collect_build_profile_value() to delegate to that shared function. Add or
reuse tests so the parser behavior remains covered in one place.
In `@chutoro-benches/benches/neighbour_scoring/support.rs`:
- Line 29: The report directory name is duplicated, so keep a single source of
truth by exporting the existing REPORT_DIR_NAME from build_profile.rs (using the
same pub #[doc(hidden)] pattern as report_path_value) and re-exporting it from
mod.rs. Then update support.rs to import and use that shared constant instead of
declaring its own literal, so the directory creation logic and reported path
stay in sync.
---
Duplicate comments:
In @.config/nextest.toml:
- Around line 113-117: The `[[profile.ci.overrides]]` block has a duplicated
table header, which should be removed so the overrides entry is declared only
once. Update the `profile.ci.overrides` section in the nextest config to keep a
single `[[profile.ci.overrides]]` header before the comment, filter, and
slow-timeout fields, matching the intended structure used in the
`profile.default.overrides` block.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 3d40e31e-06f2-424f-83d0-e70a7a95ef7d
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (28)
.config/nextest.toml.gitignorechutoro-benches/Cargo.tomlchutoro-benches/benches/extraction.rschutoro-benches/benches/hnsw.rschutoro-benches/benches/neighbour_scoring.rschutoro-benches/benches/neighbour_scoring/profiling.rschutoro-benches/benches/neighbour_scoring/support.rschutoro-benches/src/lib.rschutoro-benches/src/neighbour_scoring/build_profile.rschutoro-benches/src/neighbour_scoring/mod.rschutoro-benches/src/neighbour_scoring/profiling.rschutoro-benches/src/neighbour_scoring/report.rschutoro-benches/tests/neighbour_scoring_support.rschutoro-core/src/hnsw/cpu/internal.rschutoro-core/src/hnsw/cpu/test_helpers.rschutoro-core/src/hnsw/tests/mod.rschutoro-core/src/hnsw/tests/write_lock.rschutoro-core/tests/nextest_config.rschutoro-test-support/src/lib.rsdocs/adr-003-soa-prefetch-adapter-boundary.mddocs/chutoro-design.mddocs/developers-guide.mddocs/execplans/2-2-6-property-based-backend-parity-suite.mddocs/execplans/2-3-1-hnsw-neighbour-evaluation-using-packed-indices.mddocs/roadmap.mddocs/users-guide.mdscripts/bench-neighbour-scoring.sh
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph. If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced. chutoro-benches/tests/neighbour_scoring_support.rs Comment on lines +186 to +196 fn build_profile_report_target_honours_cargo_target_dir() {
let report_parent_dir = report_parent_dir_value(Some("/tmp/chutoro-target-dir"));
let actual_path = build_profile_report_target_value(Some("yes"), &report_parent_dir);
assert_eq!(
actual_path.as_deref(),
Some(Utf8Path::new(
"/tmp/chutoro-target-dir/benchmarks/neighbour_scoring_build_profile.csv",
)),
);
}❌ New issue: Code Duplication |
This comment was marked as resolved.
This comment was marked as resolved.
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@chutoro-benches/benches/neighbour_scoring/support.rs`:
- Around line 233-274: write_build_profile_report_for_point_counts is using
report_target only as a gate/return value, but still writes via
open_report_dir(report_parent_dir) and BUILD_PROFILE_REPORT, which can diverge
from the caller’s intended path. Update the function to derive the output file
from report_target directly, or validate that report_target matches
report_path_value(report_parent_dir, BUILD_PROFILE_REPORT) before opening the
file. Keep the success path and the actual write destination aligned so the
returned Utf8PathBuf always reflects where write_build_profile_report_csv wrote
the report.
In `@chutoro-benches/src/neighbour_scoring/mod.rs`:
- Around line 40-47: The #[expect] annotations in neighbour_scoring::mod are
using a non-existent Clippy lint name, so update the expectations to use only
valid lint IDs; remove clippy::integer_division_remainder_used or replace it
with the correct lint if that was intended, and apply the same correction to the
other two matching expectation blocks in this module.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5bf01346-b4de-4402-beac-28588b70380c
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (29)
.config/nextest.tomlchutoro-benches/Cargo.tomlchutoro-benches/benches/extraction.rschutoro-benches/benches/hnsw.rschutoro-benches/benches/mst.rschutoro-benches/benches/neighbour_scoring.rschutoro-benches/benches/neighbour_scoring/profiling.rschutoro-benches/benches/neighbour_scoring/support.rschutoro-benches/src/criterion_support.rschutoro-benches/src/lib.rschutoro-benches/src/neighbour_scoring/build_profile.rschutoro-benches/src/neighbour_scoring/mod.rschutoro-benches/src/neighbour_scoring/profiling.rschutoro-benches/src/neighbour_scoring/report.rschutoro-benches/tests/neighbour_scoring_support.rschutoro-core/src/hnsw/cpu/internal.rschutoro-core/src/hnsw/cpu/test_helpers.rschutoro-core/src/hnsw/tests/mod.rschutoro-core/src/hnsw/tests/write_lock.rschutoro-core/tests/nextest_config.rschutoro-test-support/src/lib.rsdocs/adr-003-soa-prefetch-adapter-boundary.mddocs/chutoro-design.mddocs/developers-guide.mddocs/execplans/2-2-6-property-based-backend-parity-suite.mddocs/execplans/2-3-1-hnsw-neighbour-evaluation-using-packed-indices.mddocs/roadmap.mddocs/users-guide.mdscripts/bench-neighbour-scoring.sh
55ffac7 to
04fea8d
Compare
Draft execution plan for roadmap item 2.3.1 (restructure HNSW neighbour evaluation to use packed indices and an SoA layout, prefetching blocks and scoring outside the write lock; see docs/chutoro-design.md §6.3). The plan scopes the work honestly: reconnaissance shows Phase 2.2 already delivered most of the intent — scoring already runs outside the write lock (planner under the read lock; score_trim_jobs lock-free), DensePointView SoA packing already exists internal to the dense adapter, and candidate ids are already packed slices. The residual deltas are provider-internal prefetch (behind a non-default feature with a go/no-go gate), SoA packing-buffer reuse, core-side allocation hygiene, a write-lock invariant guard, and benchmark evidence (Criterion + critcmp + hyperfine). Records the hexagonal-boundary decision to keep SoA/prefetch private to the dense adapter and a behaviour-preserving validation strategy. Status: DRAFT, pending community-of-experts revisions and approval before implementation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fold the Logisphere design-review panel's verdict (REVISE) and all twelve required revisions into the execplan. The panel verified, against the code, that 2.3.1's structural intent is largely satisfied by Phase 2.2 and that the genuine residual is an unrealised pack -> unpack -> repack round-trip at the DataSource port plus an unmeasured allocation/prefetch question that the distance cache (always present, fragmenting batches to miss-only subsets) likely renders negligible. Key changes: - Split into committed scope (write-lock-free-scoring invariant guard via a same-thread marker, design-doc/ADR documentation, and a measurement harness) and evidence-gated conditional scope (core allocation hygiene, a query-centric port override plus aligned SoA buffer reuse, and packing-step prefetch). - Name the packed-index round-trip and make the query-centric override the load-bearing prerequisite for buffer reuse. - Add the cache-fragmentation reality; Milestone 0 now measures miss-subset distributions, the scoring share of build wall-time, and distance-cache lock contention, and re-centres benchmark buckets on the realistic 8-48 regime with cycle counts as the primary keep/drop signal. - Correct the invariant guard to a same-thread marker, the scratch buffer to Vec<AlignedBlock>, and forbid shared scratch; pre-commit search.rs module extraction to respect the 400-line limit. - Defer the structural levers (cross-node beam scoring, secondary dimension- major SoA copy, batch_distances_into) to a separate evidence-first item recorded in ADR-003. Status remains DRAFT, pending approval before implementation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make explicit in the 2.3.1 ExecPlan that the three deferred structural optimisations (cross-node beam scoring, secondary dimension-major SoA copy, batch_distances_into out-buffer reuse) must be created as their own checkbox items in docs/roadmap.md during implementation, not merely recorded in ADR-003. - Reword the deferred section to state the roadmap entries are mandatory and independent of the Milestone 0 go/no-go, with suggested numbers 2.3.3-2.3.5 to be reconciled with the live roadmap. - Add an explicit "Create the deferred roadmap items" step to Milestone 2 and fix the list numbering. - Record the change in the revision note. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the Criterion neighbour-scoring benchmark used by milestone 0 to measure realistic and diagnostic candidate buckets across dense vector dimensions. Include CSV report helpers, build-profile instrumentation, and a Hyperfine wrapper so the benchmark evidence can be reproduced. Move reusable environment mutation handling into `chutoro-test-support` and keep benchmark support coverage behind narrow library seams that run under the normal test harness. Shorten existing extraction benchmark exact probes so the workspace `make test` gate remains deterministic. Record the implementation history, CodeRabbit outcomes, and validation results in the execplan.
Update the 2.3.1 execplan with the Milestone 0 Criterion baseline, build-profile CSV results, Hyperfine corroboration, and `perf stat` counters. Keep the conditional E1-E3 decisions open until a concrete candidate delta is measured against this baseline. Record the zero-finding CodeRabbit review for the evidence update.
Add a test-only `write_graph` marker and asserting data source to prove that HNSW distance scoring does not run while the current thread holds the graph write lock. Keep the marker opt-in and reference-counted so unrelated property and benchmark-backed tests avoid overhead, and overlapping opt-in tests do not disable the marker for each other. Record C1 validation and CodeRabbit results in the execplan.
Update the execplan checklist now that the C1 guard implementation, validation, and CodeRabbit review have been committed.
Add ADR-003 and document the 2.3.1 evidence that keeps SoA, prefetch, and packing policy private to dense adapters. Create deferred roadmap items for cross-node beam scoring, persistent SoA storage, and `batch_distances_into`, and document the neighbour scoring benchmark workflow plus write-lock scoring contracts.
Mark the conditional E1-E3 implementation work as dropped because the measured HNSW batch-scoring share did not clear the pre-registered threshold for speculative structural changes. Mark roadmap 2.3.1 complete on the verified adapter-boundary scope and leave the structural levers in their deferred evidence-gated roadmap items.
Extract the CSV quoting predicate into a single-pass helper while preserving the existing escaping behaviour for commas, quotes, newlines, and carriage returns. Extend the report CSV coverage to exercise newline and carriage-return fields explicitly.
Extract the shared environment lock and previous-value capture path into `EnvVarGuard::with_env_mutation`. Keep `set` and `remove` focused on their unsafe mutations while preserving guard construction before environment changes. Address review findings by making the neighbour-scoring median helper name carry its sorted-input contract and by adding property coverage for that contract. Add a focused nextest timeout override for the write-lock HNSW proptest, which repeatedly exceeded the default timeout only under the full parallel suite.
Explain the write-graph marker split between process-wide enablement and thread-local nesting depth, document the non-reentrant `EnvVarGuard` behaviour, and correct the neighbour_scoring benchmark env var name in the developers guide.
Clarify the write-graph marker ownership model and keep the HNSW write-lock test helper idiomatic. Move write-lock batch length validation before scoring assertions, and record the non-reentrant `EnvVarGuard` contract with restore and serialization coverage. Keep neighbour-scoring environment and path reads at bench edges, document the diagnostic benchmark flow, and bound the HNSW Criterion exact probes so nextest can validate the full suite.
Add a `typecheck` Makefile target so the requested gate is executable and covers all workspace targets and features. Exercise the neighbour-scoring report path through the `CARGO_TARGET_DIR` environment adapter while avoiding nested `EnvVarGuard` acquisition. Bound HNSW Criterion exact probes used by nextest so the full test gate does not run long-form benchmark workloads while normal `cargo bench` behaviour remains unchanged.
Restore the incremental-session example to one fenced Rust block and remove duplicate prose that caused hidden doctest lines to be parsed as headings by markdownlint. Remove extra blank lines in the benchmark guide sections so the Markdown gates pass after the rebase.
Centralize Criterion exact-probe handling, neighbour-scoring truthy flag parsing, and the shared benchmark report directory constant. Add focused coverage for exact-probe branching, report-file generation, and the neighbour-scoring shell-script wiring so those benchmark seams cannot regress silently.
Extract the shared neighbour-scoring build-profile path assertion so the env-driven and direct target-dir tests keep distinct setup paths without repeating the expected report path.
Reuse shared Criterion exact-probe helpers in the neighbour-scoring and MST benchmarks so nextest probes stay bounded without changing normal benchmark runs. Add focused harness coverage for neighbour-scoring report generation, profiling counters, scoring fixtures, and HNSW exact-probe predicates. Tighten the review nits around duplicate ignore entries, write-graph marker assertions, shell script linting, secure temporary log directories, and the users guide pointer to maintainer diagnostics.
Preserve main's Criterion discovery helpers alongside this branch's benchmark exact-probe support after rebasing onto `origin/main`. Keep nextest benchmark case execution bounded by detecting exact probes launched under nextest, while leaving ordinary Criterion `--exact` runs available for direct benchmark smoke coverage.
Keep the neighbour-scoring diagnostic harness scoped to synthetic fixed candidate scoring after rebasing onto the dataset recipe infrastructure from `origin/main`. Also repair the users' guide session example structure so Markdown linting continues to pass on the rebased branch.
04fea8d to
752672d
Compare
|
@coderabbitai resume |
✅ Action performedReviews resumed. |
|
@coderabbitai Have the following failed checks now been resolved? If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures. Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. (Treat documentation and validation coverage as in scope). ❌ Failed checks (3 errors, 2 warnings)
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== support.rs full ==='
cat -n chutoro-benches/benches/neighbour_scoring/support.rs
echo '=== neighbour_scoring.rs full ==='
cat -n chutoro-benches/benches/neighbour_scoring.rs
echo '=== profiling.rs (bench) ==='
cat -n chutoro-benches/benches/neighbour_scoring/profiling.rs
echo '=== search for expect(dead_code) / expect(unused_imports) ==='
rg -n '#\[expect\(' chutoro-benches/benches -g '*.rs'
echo '=== search for report_target usage ==='
rg -n 'report_target' chutoro-benches -g '*.rs'
echo '=== build_profile.rs ==='
cat -n chutoro-benches/src/neighbour_scoring/build_profile.rsLength of output: 40380 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== search for clippy expect attributes ==='
rg -n 'expect\(clippy' chutoro-benches -g '*.rs' || echo "none found"
echo '=== search for compiler warnings suppressions across benches crate broadly ==='
rg -n '#\[allow\(' chutoro-benches/benches -g '*.rs'
echo '=== check tests file for neighbour_scoring_support.rs full context around report_target tests to see if mismatch test exists ==='
sed -n '1,220p' chutoro-benches/tests/neighbour_scoring_support.rsLength of output: 937 🏁 Script executed: #!/bin/bash
set -euo pipefail
sed -n '1,220p' chutoro-benches/tests/neighbour_scoring_support.rsLength of output: 7464
Unit Architecture / Domain Architecture — still broken, same root cause. Rust Compiler Lint Integrity / part of Architectural Complexity — still broken.
These cover every item in the module rather than the specific unused import or item. Note: I found no Testing (Overall) — still not resolved. None of this is out of scope — fix it directly in this PR. AI coding-agent prompt |
Summary
Adds the execution plan for roadmap item 2.3.1 — Restructure HNSW
neighbour evaluation to use packed indices and an SoA layout, prefetching
blocks and scoring outside the write lock (see
docs/chutoro-design.md§6.3).The plan document is
docs/execplans/2-3-1-hnsw-neighbour-evaluation-using-packed-indices.md.This PR now contains the approved implementation and review follow-up changes for this plan.
How the plan was produced
HNSW insertion write-lock path, the dense provider's SoA infrastructure, and
the benchmark/test/docs surface; researched prior art (instant-distance,
hnswlib), stable-Rust
_mm_prefetch, andhyperfine/Criterion methodology.pre-mortem, alternatives, chair synthesis): verdict REVISE. All twelve
required revisions were folded into the committed draft.
Key findings shaping the plan
scoring already runs outside the write lock (planner under the read lock;
score_trim_jobslock-free), and the dense adapter already packs query-centricbatches into a 64-byte-aligned, 16-lane-padded, dimension-major SoA
DensePointView.dense provider does not override
batch_distances, so packed ids are turnedinto pairs and the query is re-derived inside the adapter.
the adapter are the cache-miss subset — frequently too small to pack —
capping any allocation/prefetch win. The plan makes this a measured question.
Plan shape
invariant guard; a
docs/chutoro-design.md§6.3 implementation-update; anADR (
adr-003) recording the adapter boundary and deferred structural levers;and a
neighbour_scoringmeasurement harness (also the canonical 2.4.1artefact).
threshold): core-side allocation hygiene, a query-centric port override with
aligned SoA buffer reuse, and packing-step prefetch behind a non-default
simd_prefetchfeature. A committed-scope-only outcome is an explicit success.SoA copy,
batch_distances_into) are deferred to a separateevidence-first item, recorded in ADR-003.
All deltas are behaviour-preserving under fixed seeds; validation leans on the
existing search-correctness, idempotency, mutation, and backend-parity suites
plus the new invariant guard, with Criterion +
critcmp+ cycle counts +hyperfinefor performance evidence.Validation of this PR
make markdownlintpasses (0 errors).make check-fmtpasses.make lintpasses.make typecheckpasses.make testpasses: 1061 passed, 1 skipped.References
🤖 Generated with Claude Code