Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
94c4fd5
always block encode doc vectors (wip)
tteofili Jan 29, 2026
5c0770a
adjusted bulk encoding tail in native scorers
tteofili Jan 30, 2026
aea2bbb
refactor
tteofili Jan 30, 2026
02cd0e8
[CI] Auto commit changes from spotless
Jan 30, 2026
e975e33
Merge branch 'main' of github.com:elastic/elasticsearch into dbbq_bul…
tteofili Jan 30, 2026
87e2d07
Merge branch 'dbbq_bulkencode_dv' of github.com:tteofili/elasticsearc…
tteofili Jan 30, 2026
d9bdf8f
Merge branch 'main' of github.com:elastic/elasticsearch into dbbq_bul…
tteofili Jan 31, 2026
759fbac
Merge branch 'main' of github.com:elastic/elasticsearch into dbbq_bul…
tteofili Feb 3, 2026
817cba7
fixed native tail scoring
tteofili Feb 3, 2026
bfe5402
Merge branch 'main' of github.com:elastic/elasticsearch into dbbq_bul…
tteofili Feb 3, 2026
dfa963f
Merge branch 'main' of github.com:elastic/elasticsearch into dbbq_bul…
tteofili Feb 4, 2026
8c65392
Merge branch 'main' of github.com:elastic/elasticsearch into dbbq_bul…
tteofili Feb 4, 2026
5338547
Update docs/changelog/141598.yaml
tteofili Feb 4, 2026
3a0bae7
Merge branch 'main' of github.com:elastic/elasticsearch into dbbq_bul…
tteofili Feb 4, 2026
85fa7d1
Merge branch 'dbbq_bulkencode_dv' of github.com:tteofili/elasticsearc…
tteofili Feb 4, 2026
101353f
messed up merge fixed
tteofili Feb 4, 2026
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
5 changes: 5 additions & 0 deletions docs/changelog/141598.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
area: Vector Search
issues: []
pr: 141598
summary: DiskBBQ - Always block encode doc vectors
type: enhancement
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,31 @@ public float scoreBulk(
float centroidDp,
float[] scores
) throws IOException {
return scoreBulk(
q,
queryLowerInterval,
queryUpperInterval,
queryComponentSum,
queryAdditionalCorrection,
similarityFunction,
centroidDp,
scores,
bulkSize
);
}

public float scoreBulk(
byte[] q,
float queryLowerInterval,
float queryUpperInterval,
int queryComponentSum,
float queryAdditionalCorrection,
VectorSimilarityFunction similarityFunction,
float centroidDp,
float[] scores,
int bulkSize
) throws IOException {
assert bulkSize <= this.bulkSize : "supplied bulkSize > this scorer's bulkSize";
quantizeScoreBulk(q, bulkSize, scores);
in.readFloats(lowerIntervals, 0, bulkSize);
in.readFloats(upperIntervals, 0, bulkSize);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,8 @@ public float scoreBulk(
float queryAdditionalCorrection,
VectorSimilarityFunction similarityFunction,
float centroidDp,
float[] scores
float[] scores,
int bulkSize
) throws IOException {
assert q.length == length * 4;
// 128 / 8 == 16
Expand All @@ -414,7 +415,8 @@ public float scoreBulk(
queryAdditionalCorrection,
similarityFunction,
centroidDp,
scores
scores,
bulkSize
);
} else if (PanamaESVectorUtilSupport.VECTOR_BITSIZE == 128) {
return score128Bulk(
Expand All @@ -424,7 +426,8 @@ public float scoreBulk(
queryAdditionalCorrection,
similarityFunction,
centroidDp,
scores
scores,
bulkSize
);
}
}
Expand All @@ -439,7 +442,8 @@ private float score128Bulk(
float queryAdditionalCorrection,
VectorSimilarityFunction similarityFunction,
float centroidDp,
float[] scores
float[] scores,
int bulkSize
) throws IOException {
int limit = FLOAT_SPECIES_128.loopBound(bulkSize);
int i = 0;
Expand Down Expand Up @@ -501,6 +505,21 @@ private float score128Bulk(
}
}
}
if (limit < bulkSize) {
maxScore = scoreTailIndividually(
queryAdditionalCorrection,
similarityFunction,
centroidDp,
scores,
bulkSize,
limit,
offset,
ay,
ly,
y1,
maxScore
);
}
in.seek(offset + 16L * bulkSize);
return maxScore;
}
Expand All @@ -512,7 +531,8 @@ private float score256Bulk(
float queryAdditionalCorrection,
VectorSimilarityFunction similarityFunction,
float centroidDp,
float[] scores
float[] scores,
int bulkSize
) throws IOException {
int limit = FLOAT_SPECIES_256.loopBound(bulkSize);
int i = 0;
Expand Down Expand Up @@ -574,7 +594,82 @@ private float score256Bulk(
}
}
}
if (limit < bulkSize) {
maxScore = scoreTailIndividually(
queryAdditionalCorrection,
similarityFunction,
centroidDp,
scores,
bulkSize,
limit,
offset,
ay,
ly,
y1,
maxScore
);
}
in.seek(offset + 16L * bulkSize);
return maxScore;
}

float scoreTailIndividually(
float queryAdditionalCorrection,
VectorSimilarityFunction similarityFunction,
float centroidDp,
float[] scores,
int bulkSize,
int limit,
long offset,
float ay,
float ly,
float y1,
float maxScore
) {
for (int j = limit; j < bulkSize; j++) {
float ax = memorySegment.get(
ValueLayout.JAVA_FLOAT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN),
offset + (long) j * Float.BYTES
);

float lx = memorySegment.get(
ValueLayout.JAVA_FLOAT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN),
offset + 4L * bulkSize + (long) j * Float.BYTES
) - ax;

int targetComponentSum = memorySegment.get(
ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN),
offset + 8L * bulkSize + (long) j * Integer.BYTES
);

float additionalCorrection = memorySegment.get(
ValueLayout.JAVA_FLOAT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN),
offset + 12L * bulkSize + (long) j * Float.BYTES
);

float qcDist = scores[j];

float res = ax * ay * dimensions + lx * ay * targetComponentSum + ax * ly * y1 + lx * ly * qcDist;

if (similarityFunction == EUCLIDEAN) {
res = res * -2f + additionalCorrection + queryAdditionalCorrection + 1f;
res = Math.max(1f / res, 0f);
scores[j] = res;
maxScore = Math.max(maxScore, res);
} else {
res = res + queryAdditionalCorrection + additionalCorrection - centroidDp;

if (similarityFunction == MAXIMUM_INNER_PRODUCT) {
res = VectorUtil.scaleMaxInnerProductScore(res);
scores[j] = res;
maxScore = Math.max(maxScore, res);
} else {
res = Math.max((res + 1f) * 0.5f, 0f);
scores[j] = res;
maxScore = Math.max(maxScore, res);
}
}
}
return maxScore;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,8 @@ public float scoreBulk(
float queryAdditionalCorrection,
VectorSimilarityFunction similarityFunction,
float centroidDp,
float[] scores
float[] scores,
int bulkSize
) throws IOException {
assert q.length == length * 2;
// 128 / 8 == 16
Expand All @@ -306,7 +307,8 @@ public float scoreBulk(
queryAdditionalCorrection,
similarityFunction,
centroidDp,
scores
scores,
bulkSize
);
} else if (PanamaESVectorUtilSupport.VECTOR_BITSIZE == 128) {
return score128Bulk(
Expand All @@ -316,7 +318,8 @@ public float scoreBulk(
queryAdditionalCorrection,
similarityFunction,
centroidDp,
scores
scores,
bulkSize
);
}
}
Expand All @@ -331,7 +334,8 @@ private float score128Bulk(
float queryAdditionalCorrection,
VectorSimilarityFunction similarityFunction,
float centroidDp,
float[] scores
float[] scores,
int bulkSize
) throws IOException {
int limit = FLOAT_SPECIES_128.loopBound(bulkSize);
int i = 0;
Expand Down Expand Up @@ -393,6 +397,22 @@ private float score128Bulk(
}
}
}
if (limit < bulkSize) {
// missing vectors to score
maxScore = scoreTailIndividually(
queryAdditionalCorrection,
similarityFunction,
centroidDp,
scores,
bulkSize,
limit,
offset,
ay,
ly,
y1,
maxScore
);
}
in.seek(offset + 16L * bulkSize);
return maxScore;
}
Expand All @@ -404,7 +424,8 @@ private float score256Bulk(
float queryAdditionalCorrection,
VectorSimilarityFunction similarityFunction,
float centroidDp,
float[] scores
float[] scores,
int bulkSize
) throws IOException {
int limit = FLOAT_SPECIES_256.loopBound(bulkSize);
int i = 0;
Expand Down Expand Up @@ -466,7 +487,84 @@ private float score256Bulk(
}
}
}
if (limit < bulkSize) {
// missing vectors to score
maxScore = scoreTailIndividually(
queryAdditionalCorrection,
similarityFunction,
centroidDp,
scores,
bulkSize,
limit,
offset,
ay,
ly,
y1,
maxScore
);
}
in.seek(offset + 16L * bulkSize);
return maxScore;
}

private float scoreTailIndividually(
float queryAdditionalCorrection,
VectorSimilarityFunction similarityFunction,
float centroidDp,
float[] scores,
int bulkSize,
int limit,
long offset,
float ay,
float ly,
float y1,
float maxScore
) {
for (int j = limit; j < bulkSize; j++) {
float ax = memorySegment.get(
ValueLayout.JAVA_FLOAT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN),
offset + (long) j * Float.BYTES
);

float lx = memorySegment.get(
ValueLayout.JAVA_FLOAT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN),
offset + 4L * bulkSize + (long) j * Float.BYTES
);
lx = (lx - ax) * TWO_BIT_SCALE;

int targetComponentSum = memorySegment.get(
ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN),
offset + 8L * bulkSize + (long) j * Integer.BYTES
);

float additionalCorrection = memorySegment.get(
ValueLayout.JAVA_FLOAT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN),
offset + 12L * bulkSize + (long) j * Float.BYTES
);

float qcDist = scores[j];

float res = ax * ay * dimensions + lx * ay * targetComponentSum + ax * ly * y1 + lx * ly * qcDist;

if (similarityFunction == EUCLIDEAN) {
res = res * -2f + additionalCorrection + queryAdditionalCorrection + 1f;
res = Math.max(1f / res, 0f);
scores[j] = res;
maxScore = Math.max(maxScore, res);
} else {
res = res + queryAdditionalCorrection + additionalCorrection - centroidDp;

if (similarityFunction == MAXIMUM_INNER_PRODUCT) {
res = VectorUtil.scaleMaxInnerProductScore(res);
scores[j] = res;
maxScore = Math.max(maxScore, res);
} else {
res = Math.max((res + 1f) * 0.5f, 0f);
scores[j] = res;
maxScore = Math.max(maxScore, res);
}
}
}
return maxScore;
}
}
Loading