Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
132 commits
Select commit Hold shift + click to select a range
b1313a4
refactor: add quantizer and distance
richyreachy Jun 29, 2026
45d9b54
fix: add turo quantizer
richyreachy Jun 30, 2026
e82d73f
refactor: add quantizer
richyreachy Jun 30, 2026
829f53e
refactor: update meta
richyreachy Jun 30, 2026
f084630
refactor: update meta
richyreachy Jun 30, 2026
c3c4ca3
refactor: add fp32 quantizer
richyreachy Jun 30, 2026
ec4ea1f
refactor: add quantizer
richyreachy Jun 30, 2026
e36f0c5
refactor: quantizer
richyreachy Jun 30, 2026
c1cdd0b
refactor: add scalar
richyreachy Jun 30, 2026
628982d
fix: fix cosine
richyreachy Jul 1, 2026
de33220
fix: add quantizer
richyreachy Jul 1, 2026
49780f8
fix: fix quantizer
richyreachy Jul 1, 2026
b1d4849
fix: remove unused var
richyreachy Jul 2, 2026
f0fdf5d
fix: header
richyreachy Jul 2, 2026
0c4cec6
fix: header
richyreachy Jul 2, 2026
73f5bc3
fix: header
richyreachy Jul 2, 2026
89843dd
add preprocessor
zzlin237 Jul 2, 2026
437a754
fix: fix symbol
richyreachy Jul 2, 2026
e16cda5
add untest
zzlin237 Jul 2, 2026
22b87d8
Merge remote-tracking branch 'origin/refactor/turbo_quantizer' into r…
zzlin237 Jul 2, 2026
f3a6782
remove extra doc
zzlin237 Jul 2, 2026
81d8eb5
tmp
zzlin237 Jul 2, 2026
f9b43f1
tmp
zzlin237 Jul 3, 2026
fc7efd8
tmp
zzlin237 Jul 3, 2026
642b8bf
Merge remote-tracking branch 'upstream/main' into refactor/turbo_prep…
zzlin237 Jul 3, 2026
79a08eb
style: fix clang-format issues from upstream merge
zzlin237 Jul 3, 2026
78ace2b
style: fix clang-format issues in turbo module
zzlin237 Jul 3, 2026
54c9b05
Merge branch 'refactor/turbo_preprocessor' into refactor/turbo_pq
zzlin237 Jul 3, 2026
b80bc4d
fix: LNK1120
zzlin237 Jul 3, 2026
71b33df
Merge remote-tracking branch 'origin/refactor/turbo_preprocessor' int…
zzlin237 Jul 3, 2026
6ae749c
tmp
zzlin237 Jul 3, 2026
281fdb4
Rename to conform to the style guide
zzlin237 Jul 3, 2026
10cbe03
Rename to conform to the style guide
zzlin237 Jul 3, 2026
39aa1ee
Merge branch 'refactor/turbo_preprocessor' of https://github.com/zzli…
zzlin237 Jul 3, 2026
8734866
pq_int8
zzlin237 Jul 3, 2026
74e9f93
tmp
zzlin237 Jul 3, 2026
c2026cb
Merge branch 'main' into refactor/turbo_quantizer
richyreachy Jul 3, 2026
c468e12
Merge branch 'main' into refactor/turbo_preprocessor
zzlin237 Jul 3, 2026
7c5d299
tmp
zzlin237 Jul 6, 2026
8ecdd17
uniform func sign
zzlin237 Jul 6, 2026
f1a838e
support ip/cosine
zzlin237 Jul 6, 2026
58ea18c
support ip/cosine
zzlin237 Jul 6, 2026
cb66180
Merge branch 'main' into refactor/turbo_quantizer
richyreachy Jul 6, 2026
3122b17
set upper
zzlin237 Jul 6, 2026
64595d1
norm match
zzlin237 Jul 6, 2026
17e5a0d
rollback
zzlin237 Jul 6, 2026
3e8abad
add int4
zzlin237 Jul 7, 2026
3470e4b
Merge remote-tracking branch 'upstream/main' into refactor/turbo_prep…
zzlin237 Jul 7, 2026
a6ecfb6
Merge remote-tracking branch 'richyreachy/refactor/turbo_quantizer' i…
zzlin237 Jul 7, 2026
cb36a54
Merge branch 'refactor/turbo_preprocessor' of https://github.com/zzli…
zzlin237 Jul 7, 2026
cca2f45
Merge remote-tracking branch 'upstream/main' into refactor/turbo_pq
zzlin237 Jul 7, 2026
a621398
Merge remote-tracking branch 'richyreachy/refactor/turbo_quantizer' i…
zzlin237 Jul 7, 2026
5b23f09
clang-format
zzlin237 Jul 7, 2026
06da5d7
debug
zzlin237 Jul 7, 2026
1c2de23
Merge remote-tracking branch 'upstream/main' into refactor/turbo_prep…
zzlin237 Jul 7, 2026
8406e9f
remove train to create int fht
zzlin237 Jul 7, 2026
abc7a4b
remove train to create int fht
zzlin237 Jul 7, 2026
05a4f4f
Merge remote-tracking branch 'upstream/main' into refactor/turbo_pq
zzlin237 Jul 7, 2026
8edecca
clang-format
zzlin237 Jul 9, 2026
75148aa
Merge remote-tracking branch 'upstream/main' into refactor/turbo_pq
zzlin237 Jul 9, 2026
d600917
clang-format
zzlin237 Jul 9, 2026
ac17ee9
fix: add neon
richyreachy Jul 10, 2026
7bb01c3
fix: add arm arch
richyreachy Jul 10, 2026
bd1bd50
Merge branch 'refactor/turbo_quantizer' of github.com:richyreachy/zve…
richyreachy Jul 10, 2026
ea71d23
CpuArchType
zzlin237 Jul 10, 2026
6abf1b8
CpuArchType FHT
zzlin237 Jul 10, 2026
ea816cc
reset preprocessor
zzlin237 Jul 10, 2026
03700da
Merge remote-tracking branch 'richyreachy/refactor/turbo_quantizer' i…
zzlin237 Jul 10, 2026
b909b4d
add neon
zzlin237 Jul 10, 2026
c826ab8
Merge branch 'main' into refactor/turbo_quantizer
richyreachy Jul 10, 2026
403c123
fix: add meta
richyreachy Jul 10, 2026
b3e6a56
fix: query meta
richyreachy Jul 10, 2026
11e8966
Merge remote-tracking branch 'richyreachy/refactor/turbo_quantizer' i…
zzlin237 Jul 13, 2026
3cd090c
clang-format
zzlin237 Jul 13, 2026
936cdf8
Merge branch 'refactor/turbo_preprocessor' of https://github.com/zzli…
zzlin237 Jul 14, 2026
aa4a4f9
reuse k-mean
zzlin237 Jul 14, 2026
128dcfd
add spherical
zzlin237 Jul 14, 2026
389d36f
remove sym_func
zzlin237 Jul 14, 2026
4287131
fix: fix alignment
richyreachy Jul 15, 2026
3943566
refactor: move header file
richyreachy Jul 15, 2026
05d43de
Merge branch 'main' into refactor/turbo_quantizer
richyreachy Jul 15, 2026
0d27ec3
num_chunk
zzlin237 Jul 15, 2026
084b475
fix: remove comment
richyreachy Jul 15, 2026
e6fa14e
Merge branch 'refactor/turbo_quantizer' of github.com:richyreachy/zve…
richyreachy Jul 15, 2026
931c61d
tmp
zzlin237 Jul 15, 2026
7552df5
fix: fix empty line
richyreachy Jul 15, 2026
28fe49a
add RotateType
zzlin237 Jul 15, 2026
bc9149d
add RotateType
zzlin237 Jul 15, 2026
7606006
Merge remote-tracking branch 'richyreachy/refactor/turbo_quantizer' i…
zzlin237 Jul 15, 2026
19c6578
merge main
zzlin237 Jul 15, 2026
8997541
Unified Scheduling Mode
zzlin237 Jul 16, 2026
ec946b1
Adjust Directory
zzlin237 Jul 16, 2026
6b20747
fix enum
zzlin237 Jul 17, 2026
4065035
add helper
zzlin237 Jul 17, 2026
e024bc8
debug
zzlin237 Jul 17, 2026
52951da
Runtime Distribution
zzlin237 Jul 17, 2026
7893d31
merge
zzlin237 Jul 17, 2026
22134a0
merge preprocessor
zzlin237 Jul 17, 2026
d4cce4c
debug
zzlin237 Jul 20, 2026
de5fa14
add use_zero_mean
zzlin237 Jul 20, 2026
fed115e
:tmp:
zzlin237 Jul 20, 2026
8bd8068
tmp
zzlin237 Jul 20, 2026
bed708c
tmp
zzlin237 Jul 20, 2026
2ba6a59
remove spherical
zzlin237 Jul 21, 2026
ca529dd
allow cosine
zzlin237 Jul 21, 2026
a3695b0
debug
zzlin237 Jul 22, 2026
ca6b526
debug
zzlin237 Jul 22, 2026
fa7dc9d
fix neon
zzlin237 Jul 22, 2026
17aa431
copilot fix
zzlin237 Jul 22, 2026
84726e8
unify structure
zzlin237 Jul 23, 2026
a0ceb71
Merge branch 'refactor/turbo_preprocessor' into refactor/turbo_pq
zzlin237 Jul 23, 2026
43dd41a
neon
zzlin237 Jul 23, 2026
c8b00de
tmp
zzlin237 Jul 23, 2026
c48fcb3
clang-format
zzlin237 Jul 23, 2026
a1c0cbb
Merge remote-tracking branch 'upstream/main' into refactor/turbo_pq
zzlin237 Jul 23, 2026
9625382
fix bug
zzlin237 Jul 23, 2026
abf6c32
clang-format
zzlin237 Jul 23, 2026
e800e98
clang-format
zzlin237 Jul 24, 2026
d890061
fix memcpy
zzlin237 Jul 24, 2026
972f96a
Merge remote-tracking branch 'upstream/main' into refactor/turbo_prep…
zzlin237 Jul 24, 2026
a1ddd4d
debug
zzlin237 Jul 24, 2026
7324b9b
debug
zzlin237 Jul 24, 2026
a2f080e
Merge branch 'refactor/turbo_preprocessor' into refactor/turbo_pq
zzlin237 Jul 24, 2026
afadb57
merge
zzlin237 Jul 24, 2026
a5a36e0
Reduce unnecessary changes
zzlin237 Jul 24, 2026
4e69047
Reduce unnecessary changes
zzlin237 Jul 24, 2026
bedd5c3
fix LNK2005
zzlin237 Jul 24, 2026
952521e
add fp16 in pq
zzlin237 Jul 28, 2026
9ef03dc
fix format of fp16
zzlin237 Jul 28, 2026
d52a50a
remote warning
zzlin237 Jul 28, 2026
8adc58e
restruct
zzlin237 Jul 30, 2026
415df61
Merge remote-tracking branch 'upstream/main' into refactor/turbo_pq
zzlin237 Jul 30, 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
6 changes: 5 additions & 1 deletion src/core/interface/index.cc
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,11 @@ int Index::Init(const BaseIndexParam &param) {
return core::IndexError_Runtime;
}

if (CreateAndInitConverterReformer(param.quantizer_param, param) != 0) {
// an absent quantizer param behaves the same as a kNone one
const auto quantizer_param = param.quantizer_param
? param.quantizer_param
: std::make_shared<QuantizerParam>();
if (CreateAndInitConverterReformer(*quantizer_param, param) != 0) {
LOG_ERROR("Failed to create and init converter");
return core::IndexError_Runtime;
}
Expand Down
52 changes: 49 additions & 3 deletions src/core/interface/index_param.cc
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,15 @@ ailego::JsonObject BaseIndexParam::SerializeToJsonObject(
// if (preprocess_param) {
// json.set("preprocess_param", preprocess_param->SerializeToJson());
// }
if (!omit_empty_value || quantizer_param.type != QuantizerType::kNone) {
if (quantizer_param) {
if (!omit_empty_value || quantizer_param->type != QuantizerType::kNone) {
json_obj.set("quantizer_param",
quantizer_param->SerializeToJsonObject(omit_empty_value));
}
} else if (!omit_empty_value) {
// no quantizer configured, keep the default(kNone) object as before
json_obj.set("quantizer_param",
quantizer_param.SerializeToJsonObject(omit_empty_value));
QuantizerParam().SerializeToJsonObject(false));
}
// if (refiner_param) {
// json.set("refiner_param", refiner_param->SerializeToJson());
Expand Down Expand Up @@ -239,7 +245,20 @@ bool BaseIndexParam::DeserializeFromJsonObject(
if (json_obj.has("quantizer_param")) {
if (json_obj.get("quantizer_param", &tmp_json_value);
tmp_json_value.is_object()) {
quantizer_param.DeserializeFromJsonObject(tmp_json_value.as_object());
const auto &quantizer_json_obj = tmp_json_value.as_object();
// the concrete param type is determined by the quantizer type
auto quantizer_type = QuantizerType::kNone;
ailego::JsonValue type_json_value;
if (!extract_enum_from_json<QuantizerType>(
quantizer_json_obj, "type", quantizer_type, type_json_value)) {
LOG_ERROR("Error when deserialize json - field:quantizer_param.type");
return false;
}
auto quantizer = QuantizerParam::Create(quantizer_type);
if (!quantizer->DeserializeFromJsonObject(quantizer_json_obj)) {
LOG_ERROR("Error when deserialize json - field:quantizer_param");
}
quantizer_param = std::move(quantizer);
}
}

Expand Down Expand Up @@ -393,6 +412,33 @@ bool QuantizerParam::DeserializeFromJsonObject(
return true;
}

QuantizerParam::Pointer QuantizerParam::Create(QuantizerType t) {
switch (t) {
case QuantizerType::kPQ:
return std::make_shared<PqQuantizerParam>();
default:
return std::make_shared<QuantizerParam>(t);
}
}

ailego::JsonObject PqQuantizerParam::SerializeToJsonObject(
bool omit_empty_value) const {
auto json_obj = QuantizerParam::SerializeToJsonObject(omit_empty_value);
json_obj.set("num_chunk", ailego::JsonValue(num_chunk));
json_obj.set("num_bits", ailego::JsonValue(num_bits));
return json_obj;
}

bool PqQuantizerParam::DeserializeFromJsonObject(
const ailego::JsonObject &json_obj) {
if (!QuantizerParam::DeserializeFromJsonObject(json_obj)) {
return false;
}
DESERIALIZE_VALUE_FIELD(json_obj, num_chunk);
DESERIALIZE_VALUE_FIELD(json_obj, num_bits);
return true;
}

// bool BaseIndexQueryParam::DeserializeFromJsonObject(
// const ailego::JsonObject &json_obj) {
// DESERIALIZE_ENUM_FIELD(json_obj, index_type, IndexType);
Expand Down
2 changes: 1 addition & 1 deletion src/db/index/column/vector_column/engine_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ class ProximaEngineHelper {
convert_to_engine_quantize_type(db_index_params->quantize_type());
quantize_type.has_value()) {
index_param_builder->WithQuantizerParam(
core_interface::QuantizerParam(quantize_type.value()));
core_interface::QuantizerParam::Create(quantize_type.value()));
} else {
return tl::make_unexpected(
Status::InvalidArgument("unsupported quantize type"));
Expand Down
57 changes: 46 additions & 11 deletions src/include/zvec/core/interface/index_param.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,23 +119,49 @@ struct ZVEC_CORE_API SerializableBase {
const ailego::JsonObject &json_obj) = 0;
};

// TODO: maybe a base class for quantizer?
//! Common quantizer params shared by all quantizer types
struct ZVEC_CORE_API QuantizerParam : public SerializableBase {
using Pointer = std::shared_ptr<QuantizerParam>;

QuantizerType type = QuantizerType::kNone;
int num_subquantizers = 8; // M
int num_bits = 8; // bits per subquantizer
bool enable_rotate =
false; // rotate vectors before quantization to reduce error

// Constructors
// QuantizerParam() = default;
QuantizerParam(QuantizerType t = QuantizerType::kNone, int subquantizers = 8,
int bits = 8, bool rotate = false)
: type(t),
num_subquantizers(subquantizers),
num_bits(bits),
enable_rotate(rotate) {}
QuantizerParam(QuantizerType t = QuantizerType::kNone, bool rotate = false)
: type(t), enable_rotate(rotate) {}
virtual ~QuantizerParam() = default;

//! Duplicate the param object, keeping the concrete type
virtual Pointer Clone() const {
return std::make_shared<QuantizerParam>(*this);
}

//! Create the param object matching the quantizer type
static Pointer Create(QuantizerType t);

protected:
friend class BaseIndexParam;
ailego::JsonObject SerializeToJsonObject(
bool omit_empty_value = false) const override;

bool DeserializeFromJsonObject(const ailego::JsonObject &json_obj) override;
};

//! Product-Quantization specific params
struct PqQuantizerParam : public QuantizerParam {
int num_chunk = 8; // M: number of sub-quantizers
int num_bits = 8; // bits per sub-quantizer

// Constructors
PqQuantizerParam(int chunks = 8, int bits = 8, bool rotate = false)
: QuantizerParam(QuantizerType::kPQ, rotate),
num_chunk(chunks),
num_bits(bits) {}

QuantizerParam::Pointer Clone() const override {
return std::make_shared<PqQuantizerParam>(*this);
}

protected:
friend class BaseIndexParam;
Expand Down Expand Up @@ -306,7 +332,16 @@ class ZVEC_CORE_API BaseIndexParam : public SerializableBase {

// pipeline
PreprocessorParam preprocess_param;
QuantizerParam quantizer_param;
//! nullptr means no quantizer is configured (equivalent to kNone)
QuantizerParam::Pointer quantizer_param{nullptr};

QuantizerType quantizer_type() const {
return quantizer_param ? quantizer_param->type : QuantizerType::kNone;
}

bool enable_rotate() const {
return quantizer_param && quantizer_param->enable_rotate;
}

BaseIndexQueryParam::Pointer default_query_param = nullptr;
// virtual std::shared_ptr<BaseIndexQueryParam> GetDefaultQueryParam() const
Expand Down
15 changes: 13 additions & 2 deletions src/include/zvec/core/interface/index_param_builders.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,13 @@ class BaseIndexParamBuilder { // : public
}
ActualIndexParamBuilderType &WithQuantizerParam(
const QuantizerParam &quantizer_param) {
param->quantizer_param = quantizer_param;
param->quantizer_param = quantizer_param.Clone();
return static_cast<ActualIndexParamBuilderType &>(*this);
}
ActualIndexParamBuilderType &WithQuantizerParam(
const QuantizerParam::Pointer &quantizer_param) {
param->quantizer_param =
quantizer_param ? quantizer_param->Clone() : nullptr;
return static_cast<ActualIndexParamBuilderType &>(*this);
}
// ActualIndexParamBuilderType &WithRefinerParam(
Expand Down Expand Up @@ -88,7 +94,12 @@ class BaseIndexParamBuilder { // : public
}

ActualIndexParamBuilderType &WithEnableRotate(bool enable_rotate) {
param->quantizer_param.enable_rotate = enable_rotate;
// copy-on-write: never mutate a param object shared with others
auto quantizer_param = param->quantizer_param
? param->quantizer_param->Clone()
: std::make_shared<QuantizerParam>();
quantizer_param->enable_rotate = enable_rotate;
param->quantizer_param = std::move(quantizer_param);
return static_cast<ActualIndexParamBuilderType &>(*this);
}

Expand Down
36 changes: 36 additions & 0 deletions src/include/zvec/turbo/turbo.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,42 @@ using RotateFunc = void (*)(const float *in, float *out, size_t in_dim,
using UnrotateFunc = void (*)(const float *in, float *out, size_t in_dim,
size_t out_dim, void *ctx);

// PQ kernel function pointer types.
//
// ADC: LUT look-up distance between a PQ code and a query (via LUT).
// pq_code: [num_chunk] uint8_t
// lut: [num_chunk * 256] float
// Uses void* to match DistanceFunc signature for direct assignment.
using PqAdcDistanceFunc = void (*)(const void *pq_code, const void *lut,
size_t num_chunk, float *out);

// SDC kernel: centroid-to-centroid distance between two PQ codes.
// a, b: [num_chunk] uint8_t
// dist_table: [num_chunk * 256 * 256] float
// Uses void* for consistency with DistanceFunc / PqAdcDistanceFunc.
using PqSdcKernelFunc = void (*)(const void *a, const void *b,
const void *dist_table, size_t num_chunk,
float *out);

// Batch ADC: compute distances for multiple PQ codes against a shared LUT.
// Signature matches BatchDistanceFunc for direct assignment (no lambda).
using PqBatchAdcFunc = void (*)(const void **candidates, const void *lut,
size_t num, size_t num_chunk, float *out);

// ISA-dispatched rotate/unrotate kernels.
struct RotatorKernels {
RotateFunc rotate = nullptr;
UnrotateFunc unrotate = nullptr;
};

// data_type selects the code packing layout:
// kInt8: one uint8 per sub-quantizer (256 centroids, stride=256)
struct PqKernels {
PqAdcDistanceFunc adc_distance = nullptr;
PqSdcKernelFunc sdc_distance = nullptr;
PqBatchAdcFunc batch_adc_distance = nullptr;
};

enum class MetricType {
kSquaredEuclidean,
kCosine,
Expand Down Expand Up @@ -142,4 +172,10 @@ get_uniform_quantize_func(DataType data_type);
RotatorKernels get_rotator_kernels(
RotateType rotate_type, CpuArchType cpu_arch_type = CpuArchType::kAuto);

// Returns all PQ kernels dispatched for the given data_type, quantize_type
// and CPU arch.
PqKernels get_pq_kernels(DataType data_type,
QuantizeType quantize_type = QuantizeType::kPQ,
CpuArchType cpu_arch_type = CpuArchType::kAuto);

} // namespace zvec::turbo
Loading
Loading