Skip to content

Commit 84ddd16

Browse files
authored
feat: update lumina lib to v0.2.1 (alibaba#208)
1 parent 78a980f commit 84ddd16

18 files changed

Lines changed: 807 additions & 128 deletions

test/inte/global_index_test.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,6 +2490,15 @@ TEST_P(GlobalIndexTest, TestLuceneWriteCommitScanReadIndexWithScore) {
24902490
/*pre_filter=*/std::nullopt)));
24912491
ASSERT_TRUE(index_result->ToString().find("row ids: {0,1,2}") != std::string::npos);
24922492
}
2493+
{
2494+
std::optional<RoaringBitmap64> pre_filter = RoaringBitmap64::From({1, 2, 3});
2495+
ASSERT_OK_AND_ASSIGN(
2496+
auto index_result,
2497+
index_reader->VisitFullTextSearch(std::make_shared<FullTextSearch>(
2498+
"f0",
2499+
/*limit=*/10, "document", FullTextSearch::SearchType::MATCH_ALL, pre_filter)));
2500+
ASSERT_TRUE(index_result->ToString().find("row ids: {1,2}") != std::string::npos);
2501+
}
24932502
{
24942503
ASSERT_OK_AND_ASSIGN(auto index_result,
24952504
index_reader->VisitFullTextSearch(std::make_shared<FullTextSearch>(

third_party/lumina/OptionsReference.md

Lines changed: 0 additions & 107 deletions
This file was deleted.

third_party/lumina/VERSION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
tag: v0.1.0
2-
bd7ac880cf34af4d267fcaf16773627cad122463
1+
tag: v0.2.1
2+
c88ce90ed44b7037e3a307a36627cbd030e5eb60

third_party/lumina/include/lumina/api/Dataset.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
1817
#pragma once
1918

2019
#include <cstdint>

third_party/lumina/include/lumina/core/Constants.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#pragma once
18+
#include <cstdint>
1819
#include <string_view>
1920
namespace lumina::core {
2021

@@ -56,6 +57,7 @@ constexpr std::string_view kEncodingType = "encoding.type"; // Encoding type
5657
constexpr std::string_view kEncodingRawf32 = "rawf32";
5758
constexpr std::string_view kEncodingSQ8 = "sq8";
5859
constexpr std::string_view kEncodingPQ = "pq";
60+
constexpr std::string_view kEncodingRabitQ = "rabitq";
5961
constexpr std::string_view kEncodingDummy = "dummy";
6062

6163
// IO options
@@ -88,6 +90,7 @@ constexpr std::string_view kExtensionPrefix = "extension.";
8890
constexpr std::string_view kExtensionSearchWithFilter = "extension.search_with_filter";
8991
constexpr std::string_view kExtensionCkptThreshold = "extension.build.ckpt.threshold";
9092
constexpr std::string_view kExtensionCkptCount = "extension.build.ckpt.count";
93+
constexpr std::string_view kExtensionGetVector = "extension.search.get_vector";
9194

9295
/* constexpr std::string_view kExtensionFilterDsl = "filter.dsl"; */
9396
/* constexpr std::string_view kExtensionFilterTags = "filter.tags"; */

third_party/lumina/include/lumina/distance/EncodedDistance.h

Lines changed: 151 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,74 @@
1616

1717
#pragma once
1818

19+
#include <cstddef>
1920
#include <cstdint>
2021
#include <lumina/distance/Metric.h>
2122
#include <lumina/distance/MetricDistance.h>
23+
#include <lumina/distance/encode_space/EncodedRowSource.h>
2224
#include <lumina/distance/encode_space/EncodingTypes.h>
2325
#include <span>
26+
#include <type_traits>
27+
#include <utility>
2428

2529
namespace lumina::dist {
2630

31+
// Encoded Distance Interface (CPO)
32+
//
33+
// This file defines the core abstraction for computing distances between a floating-point query
34+
// and encoded (compressed/quantized) vectors.
35+
//
36+
// Workflow Overview:
37+
// 1. Prepare: One-time processing of the query for a specific encoding (e.g., building
38+
// lookup tables for PQ or pre-calculating distance components). This amortizes the cost
39+
// of complex setup across many distance evaluations.
40+
// 2. Evaluate: Use the prepared state to compute distances for many rows.
41+
// - BatchEval: Best for contiguous scans (dense layout).
42+
// - GatherEval: Best for graph/IVF traversal where candidate rows are scattered.
43+
//
44+
// Design Goals:
45+
// - Performance: Enables SIMD/ISA-specific optimizations (like AVX-512 gather) via TagInvoke.
46+
// - Decoupling: Uses `EncodedRowSource` to abstract memory layout (flat, strided, or aux-data)
47+
// away from the distance logic.
48+
// - Stability: The API remains constant even if the underlying encoding format changes.
49+
2750
struct PrepareTag {
51+
/**
52+
* @brief Transforms a raw query into a "Prepared State" optimized for a specific encoding.
53+
*
54+
* Why use this?
55+
* For many encodings (like Product Quantization), calculating a distance requires expensive
56+
* per-query setup (e.g., pre-computing 256 distances to codebook centroids). 'Prepare'
57+
* ensures this work is done only once per search.
58+
*
59+
* @param m The Metric (e.g., MetricL2, MetricIP).
60+
* @param e The Encoding (e.g., SQ8, PQ).
61+
* @param q The raw floating-point query vector.
62+
* @param ctx Additional encoding-specific resources (e.g., codebooks, headers).
63+
* @return An opaque state object (S) to be passed to Eval/Gather functions.
64+
*/
2865
template <class M, class E, class... Ctx>
2966
requires TagInvocable<PrepareTag, M, E, std::span<const float>, Ctx&&...>
3067
constexpr auto operator()(const M& m, const E& e, std::span<const float> q, Ctx&&... ctx) const
3168
noexcept(noexcept(TagInvoke(std::declval<PrepareTag>(), m, e, q, std::forward<Ctx>(ctx)...)))
3269
-> TagInvokeResult<PrepareTag, M, E, std::span<const float>, Ctx&&...>
3370
{
34-
return TagInvoke(*this, m, e, q, ctx...);
71+
return TagInvoke(*this, m, e, q, std::forward<Ctx>(ctx)...);
3572
}
3673
};
3774
inline constexpr PrepareTag Prepare {};
3875

3976
struct EvalEncodedTag {
77+
/**
78+
* @brief Computes distance for a single encoded row.
79+
*
80+
* Typically used within a loop when manual flow control is needed. However, for
81+
* performance-critical code, BatchEval or GatherEval are usually preferred as they
82+
* allow the implementation to use SIMD more effectively.
83+
*
84+
* @param s The prepared state from Prepare().
85+
* @param r A view to a single encoded row (e.g., encode_space::EncodedRow).
86+
*/
4087
template <class M, class E, class S, class R>
4188
requires TagInvocable<EvalEncodedTag, M, E, const S&, const R&>
4289
constexpr auto operator()(const M& m, const E& e, const S& s, const R& r) const
@@ -49,6 +96,15 @@ struct EvalEncodedTag {
4996
inline constexpr EvalEncodedTag EvalEncoded {};
5097

5198
struct BatchEvalEncodedTag {
99+
/**
100+
* @brief Computes distances for a contiguous block of encoded rows.
101+
*
102+
* Optimized for exhaustive scans. The implementation can assume rows are adjacent in memory,
103+
* allowing for efficient linear prefetching and unrolled SIMD processing.
104+
*
105+
* @param b Description of the contiguous batch (base pointer + count).
106+
* @param out Pointer to output float array (must hold at least b.n elements).
107+
*/
52108
template <class M, class E, class S>
53109
requires TagInvocable<BatchEvalEncodedTag, M, E, const S&, const encode_space::EncodedBatch&, float*>
54110
constexpr void operator()(const M& m, const E& e, const S& s, const encode_space::EncodedBatch& b, float* out) const
@@ -59,4 +115,98 @@ struct BatchEvalEncodedTag {
59115
};
60116
inline constexpr BatchEvalEncodedTag BatchEvalEncoded {};
61117

118+
struct GatherEvalEncodedTag {
119+
/**
120+
* @brief Computes distances for a non-contiguous set of row IDs.
121+
*
122+
* The primary workhorse for graph-based or IVF search. Given a list of candidate IDs,
123+
* this function "gathers" the encoded data and computes distances.
124+
*
125+
* Performance Note: Specializations of this tag often use ISA-specific instructions
126+
* (e.g., VPGATHERDD) or software pipelining to hide memory latency during random access.
127+
*
128+
* @param data The data source (models EncodedRowSource) providing mapping from ID to memory.
129+
* @param rowIds The list of logical row IDs to evaluate.
130+
* @param results Output span for distances (must match rowIds size).
131+
*/
132+
template <class M, class E, class S>
133+
requires TagInvocable<GatherEvalEncodedTag, M, E, const S&, const std::byte*, std::span<const uint64_t>,
134+
std::span<float>>
135+
constexpr void operator()(const M& m, const E& e, const S& s, const std::byte* recordsBase,
136+
std::span<const uint64_t> rowIds, std::span<float> results) const
137+
noexcept(noexcept(TagInvoke(std::declval<GatherEvalEncodedTag>(), m, e, s, recordsBase, rowIds, results)))
138+
{
139+
TagInvoke(*this, m, e, s, recordsBase, rowIds, results);
140+
}
141+
142+
template <class M, class E, class S, class DataSource>
143+
requires(encode_space::EncodedRowSource<std::remove_cvref_t<DataSource>> &&
144+
TagInvocable<GatherEvalEncodedTag, M, E, const S&, const DataSource&, std::span<const uint64_t>,
145+
std::span<float>>)
146+
constexpr void operator()(const M& m, const E& e, const S& s, const DataSource& data,
147+
std::span<const uint64_t> rowIds, std::span<float> results) const
148+
noexcept(noexcept(TagInvoke(std::declval<GatherEvalEncodedTag>(), m, e, s, data, rowIds, results)))
149+
{
150+
TagInvoke(*this, m, e, s, data, rowIds, results);
151+
}
152+
153+
template <class M, class E, class S, class DataSource>
154+
requires(encode_space::EncodedRowSource<std::remove_cvref_t<DataSource>> &&
155+
!TagInvocable<GatherEvalEncodedTag, M, E, const S&, const DataSource&, std::span<const uint64_t>,
156+
std::span<float>>)
157+
constexpr void operator()(const M& m, const E& e, const S& s, const DataSource& data,
158+
std::span<const uint64_t> rowIds, std::span<float> results) const
159+
noexcept(noexcept(encode_space::GetEncodedRow(data, uint64_t {})) && noexcept(
160+
EvalEncoded(m, e, s, encode_space::GetEncodedRow(data, uint64_t {}))))
161+
{
162+
for (std::size_t i = 0; i < rowIds.size(); ++i) {
163+
const auto row = encode_space::GetEncodedRow(data, rowIds[i]);
164+
results[i] = EvalEncoded(m, e, s, row);
165+
}
166+
}
167+
};
168+
inline constexpr GatherEvalEncodedTag GatherEvalEncoded {};
169+
170+
struct GatherEvalEncodedWithLowerBoundsTag {
171+
/**
172+
* @brief Evaluates distances AND returns a lower-bound estimate for each row.
173+
*
174+
* This is an optimization for multi-stage search (e.g., DiskANN).
175+
*
176+
* Lower bounds (D_lb) guarantee that D_true >= D_lb. In search algorithms, if D_lb is
177+
* already greater than the current search radius, we can skip further processing of this
178+
* candidate.
179+
*
180+
* Note: Not all encodings support lower bounds. If unsupported, use the standard GatherEvalEncoded.
181+
*
182+
* @param results Output span for the (potentially approximate) distances.
183+
* @param lowerBounds Output span for the lower-bound estimates.
184+
*/
185+
template <class M, class E, class S>
186+
requires TagInvocable<GatherEvalEncodedWithLowerBoundsTag, M, E, const S&, const std::byte*,
187+
std::span<const uint64_t>, std::span<float>, std::span<float>>
188+
constexpr void operator()(const M& m, const E& e, const S& s, const std::byte* recordsBase,
189+
std::span<const uint64_t> rowIds, std::span<float> results,
190+
std::span<float> lowerBounds) const
191+
noexcept(noexcept(TagInvoke(std::declval<GatherEvalEncodedWithLowerBoundsTag>(), m, e, s, recordsBase, rowIds,
192+
results, lowerBounds)))
193+
{
194+
TagInvoke(*this, m, e, s, recordsBase, rowIds, results, lowerBounds);
195+
}
196+
197+
template <class M, class E, class S, class DataSource>
198+
requires(encode_space::EncodedRowSource<std::remove_cvref_t<DataSource>> &&
199+
TagInvocable<GatherEvalEncodedWithLowerBoundsTag, M, E, const S&, const DataSource&,
200+
std::span<const uint64_t>, std::span<float>, std::span<float>>)
201+
constexpr void operator()(const M& m, const E& e, const S& s, const DataSource& data,
202+
std::span<const uint64_t> rowIds, std::span<float> results,
203+
std::span<float> lowerBounds) const
204+
noexcept(noexcept(TagInvoke(std::declval<GatherEvalEncodedWithLowerBoundsTag>(), m, e, s, data, rowIds, results,
205+
lowerBounds)))
206+
{
207+
TagInvoke(*this, m, e, s, data, rowIds, results, lowerBounds);
208+
}
209+
};
210+
inline constexpr GatherEvalEncodedWithLowerBoundsTag GatherEvalEncodedWithLowerBounds {};
211+
62212
} // namespace lumina::dist

0 commit comments

Comments
 (0)