Skip to content

fix(test): tolerate boundary-tie in IVF distance_range assertions#6999

Merged
BubbleCal merged 1 commit into
lance-format:mainfrom
xuanyu-z:fix/ivf-distance-range-boundary-tie
May 29, 2026
Merged

fix(test): tolerate boundary-tie in IVF distance_range assertions#6999
BubbleCal merged 1 commit into
lance-format:mainfrom
xuanyu-z:fix/ivf-distance-range-boundary-tie

Conversation

@xuanyu-z
Copy link
Copy Markdown
Contributor

Problem

test_build_ivf_pq::case_3 (DistanceType::Dot) fails on linux-arm with:

assertion `left == right` failed
  left: 4
  right: 5
at rust/lance/src/index/vector/ivf/v2.rs:4321

The test partitions top-k results around part_dist = dists[part_idx] using:

  • left filter: strict d < part_dist, limit part_idx
  • right filter: inclusive d >= part_dist, limit k - part_idx

It then asserts left_res.num_rows() == part_idx and that the row-id ordering matches the original top-k.

Root cause

When dists[part_idx - 1] == dists[part_idx], two vectors tie at the partition boundary:

  • the strict-less left filter excludes both tied vectors → left_res has part_idx - 1 rows
  • the inclusive right filter includes both tied vectors → one row shifts from left to right, and the trailing original row drops off right_res's limit
  • the original row-id ordering of the tied vectors is determined by an internal tiebreaker, so the row-id assertions can fail even when the count matches

The failure is deterministic per architecture but architecture-dependent because ARM NEON uses fused multiply-add (FMA) for SIMD dot products by default, while x86 (without -mfma) does separate mul+add. FMA produces a single rounding for a*b + c; separate ops produce two. For Dot distance specifically — which has fewer transformations than L2 or Cosine — this ULP-level difference is enough to make two distances tie on ARM that don't tie on x86. Random vectors generated from StdRng::seed_from_u64([13; 32]) happen to hit such a tie at the partition boundary on ARM.

Fix

Detect the tie explicitly (dists[part_idx - 1] == part_dist) and weaken the count and row-id assertions for the affected positions only. The unconditional distance-value assertions immediately below (left_dists < part_dist, right_dists >= part_dist) still verify partition correctness in both branches.

Related

Similar test relaxations on this code area:

Test plan

The IVF distance_range test partitions top-k results around `part_dist`
using a strict-less left filter (`d < part_dist`) and an inclusive right
filter (`d >= part_dist`). When the boundary vector ties with the
adjacent one (`dists[part_idx - 1] == dists[part_idx]`), the partition
becomes ambiguous: the strict-less filter excludes both tied vectors,
shifting one row from left to right and dropping the trailing row off
right_res's limit.

This surfaced on linux-arm for `test_build_ivf_pq::case_3` (DistanceType::Dot)
because ARM SIMD FMA produces tied float32 dot products that x86's
separate mul+add does not, making the failure deterministic per
architecture but architecture-dependent.

Detect the tie explicitly and weaken the count and row-id assertions
for the affected positions only. The distance-value assertions remain
unconditional and still verify partition correctness in both cases.
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@github-actions github-actions Bot added the bug Something isn't working label May 29, 2026
Copy link
Copy Markdown
Contributor

@BubbleCal BubbleCal left a comment

Choose a reason for hiding this comment

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

LGTM!

@codecov
Copy link
Copy Markdown

codecov Bot commented May 29, 2026

Codecov Report

❌ Patch coverage is 60.00000% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
rust/lance/src/index/vector/ivf/v2.rs 60.00% 6 Missing ⚠️

📢 Thoughts on this report? Let us know!

@BubbleCal BubbleCal merged commit ab34ed6 into lance-format:main May 29, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants