Skip to content

Commit 8693cf9

Browse files
authored
refactor: turbo quantizer (#546)
1 parent f9ef15a commit 8693cf9

30 files changed

Lines changed: 1261 additions & 25 deletions

examples/c++/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
1212
if(NOT DEFINED HOST_BUILD_DIR)
1313
set(HOST_BUILD_DIR "build")
1414
endif()
15-
1615
get_filename_component(ZVEC_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
16+
1717
set(ZVEC_INCLUDE_DIR ${ZVEC_ROOT_DIR}/src/include)
1818
set(ZVEC_LIB_DIR ${ZVEC_ROOT_DIR}/${HOST_BUILD_DIR}/lib)
1919

src/core/framework/index_factory.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#include <turbo/quantizer/quantizer.h>
1516
#include <zvec/core/framework/index_factory.h>
1617

1718
namespace zvec {
@@ -257,5 +258,18 @@ std::vector<std::string> IndexFactory::AllRefiners(void) {
257258
return ailego::Factory<IndexRefiner>::Classes();
258259
}
259260

261+
std::shared_ptr<turbo::Quantizer> IndexFactory::CreateQuantizer(
262+
const std::string &name) {
263+
return ailego::Factory<zvec::turbo::Quantizer>::MakeShared(name.c_str());
264+
}
265+
266+
bool IndexFactory::HasQuantizer(const std::string &name) {
267+
return ailego::Factory<turbo::Quantizer>::Has(name.c_str());
268+
}
269+
270+
std::vector<std::string> IndexFactory::AllQuantizers(void) {
271+
return ailego::Factory<turbo::Quantizer>::Classes();
272+
}
273+
260274
} // namespace core
261275
} // namespace zvec

src/core/framework/index_meta.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ struct IndexMetaFormatHeader {
3030
uint32_t space_id;
3131
uint32_t attachment_offset;
3232
uint32_t attachment_size;
33-
uint8_t reserved_[4092];
33+
uint32_t extra_meta_size;
34+
uint8_t reserved_[4088];
3435
};
3536

3637
static_assert(sizeof(IndexMetaFormatHeader) % 32 == 0,
@@ -47,6 +48,7 @@ void IndexMeta::serialize(std::string *out) const {
4748
format.dimension = dimension_;
4849
format.unit_size = unit_size_;
4950
format.space_id = space_id_;
51+
format.extra_meta_size = extra_meta_size_;
5052

5153
if (!metric_name_.empty()) {
5254
ailego::Params item;
@@ -141,7 +143,9 @@ bool IndexMeta::deserialize(const void *data, size_t len) {
141143
data_type_ = static_cast<IndexMeta::DataType>(format->data_type);
142144
dimension_ = format->dimension;
143145
unit_size_ = format->unit_size;
144-
element_size_ = IndexMeta::ElementSizeof(data_type_, unit_size_, dimension_);
146+
extra_meta_size_ = format->extra_meta_size;
147+
element_size_ = IndexMeta::ElementSizeof(data_type_, unit_size_, dimension_) +
148+
extra_meta_size_;
145149
space_id_ = format->space_id;
146150

147151
// Read attachment

src/include/zvec/core/framework/index_factory.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@
2929
#include <zvec/core/framework/index_streamer.h>
3030
#include <zvec/core/framework/index_trainer.h>
3131

32+
namespace zvec {
33+
namespace turbo {
34+
class Quantizer;
35+
} // namespace turbo
36+
} // namespace zvec
37+
3238
namespace zvec {
3339
namespace core {
3440

@@ -167,6 +173,16 @@ struct IndexFactory {
167173

168174
//! Retrieve all refiner classes
169175
static std::vector<std::string> AllRefiners(void);
176+
177+
//! Create a quantizer by name
178+
static std::shared_ptr<zvec::turbo::Quantizer> CreateQuantizer(
179+
const std::string &name);
180+
181+
//! Test if the quantizer exists
182+
static bool HasQuantizer(const std::string &name);
183+
184+
//! Retrieve all quantizer classes
185+
static std::vector<std::string> AllQuantizers(void);
170186
};
171187

172188
//! Register Index Metric
@@ -283,5 +299,13 @@ struct IndexFactory {
283299
#define INDEX_FACTORY_REGISTER_REFINER(__IMPL__, ...) \
284300
INDEX_FACTORY_REGISTER_REFINER_ALIAS(__IMPL__, __IMPL__, ##__VA_ARGS__)
285301

302+
//! Register Quantizer
303+
#define INDEX_FACTORY_REGISTER_QUANTIZER_ALIAS(__NAME__, __IMPL__, ...) \
304+
AILEGO_FACTORY_REGISTER(__NAME__, turbo::Quantizer, __IMPL__, ##__VA_ARGS__)
305+
306+
//! Register Quantizer
307+
#define INDEX_FACTORY_REGISTER_QUANTIZER(__IMPL__, ...) \
308+
INDEX_FACTORY_REGISTER_QUANTIZER_ALIAS(__IMPL__, __IMPL__, ##__VA_ARGS__)
309+
286310
} // namespace core
287311
} // namespace zvec

src/include/zvec/core/framework/index_meta.h

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class IndexMeta {
4040
DT_BINARY64 = 8,
4141
};
4242

43+
4344
/*! Major Orders
4445
*/
4546
enum MajorOrder {
@@ -77,6 +78,7 @@ class IndexMeta {
7778
dimension_(rhs.dimension_),
7879
unit_size_(rhs.unit_size_),
7980
element_size_(rhs.element_size_),
81+
extra_meta_size_(rhs.extra_meta_size_),
8082
space_id_(rhs.space_id_),
8183
metric_revision_(rhs.metric_revision_),
8284
converter_revision_(rhs.converter_revision_),
@@ -112,6 +114,7 @@ class IndexMeta {
112114
dimension_(rhs.dimension_),
113115
unit_size_(rhs.unit_size_),
114116
element_size_(rhs.element_size_),
117+
extra_meta_size_(rhs.extra_meta_size_),
115118
space_id_(rhs.space_id_),
116119
metric_revision_(rhs.metric_revision_),
117120
converter_revision_(rhs.converter_revision_),
@@ -173,6 +176,7 @@ class IndexMeta {
173176
searcher_params_ = std::move(rhs.searcher_params_);
174177
streamer_params_ = std::move(rhs.streamer_params_);
175178
attributes_ = std::move(rhs.attributes_);
179+
extra_meta_size_ = rhs.extra_meta_size_;
176180

177181
return *this;
178182
}
@@ -211,6 +215,7 @@ class IndexMeta {
211215
searcher_params_ = std::move(rhs.searcher_params_);
212216
streamer_params_ = std::move(rhs.streamer_params_);
213217
attributes_ = std::move(rhs.attributes_);
218+
extra_meta_size_ = rhs.extra_meta_size_;
214219

215220
return *this;
216221
}
@@ -249,6 +254,7 @@ class IndexMeta {
249254
searcher_params_.clear();
250255
streamer_params_.clear();
251256
attributes_.clear();
257+
extra_meta_size_ = 0;
252258
}
253259

254260
//! Retrieve major order information
@@ -281,6 +287,11 @@ class IndexMeta {
281287
return element_size_;
282288
}
283289

290+
//! Retrieve extra meta size in bytes
291+
uint32_t extra_meta_size(void) const {
292+
return extra_meta_size_;
293+
}
294+
284295
//! Retrieve space id
285296
uint64_t space_id(void) const {
286297
return space_id_;
@@ -429,7 +440,8 @@ class IndexMeta {
429440
//! Set dimension of feature
430441
void set_dimension(uint32_t dim) {
431442
dimension_ = dim;
432-
element_size_ = IndexMeta::ElementSizeof(data_type_, unit_size_, dim);
443+
element_size_ = IndexMeta::ElementSizeof(data_type_, unit_size_, dim) +
444+
extra_meta_size_;
433445
}
434446

435447
//! Set meta information of feature
@@ -443,14 +455,21 @@ class IndexMeta {
443455
data_type_ = data_type;
444456
dimension_ = dim;
445457
unit_size_ = unit;
446-
element_size_ = ElementSizeof(data_type, unit, dim);
458+
element_size_ = ElementSizeof(data_type, unit, dim) + extra_meta_size_;
447459
}
448460

449461
//! Set meta information of feature
450462
void set_meta(DataType data_type, uint32_t dim) {
451463
this->set_meta(data_type, UnitSizeof(data_type), dim);
452464
}
453465

466+
//! Set extra meta size
467+
void set_extra_meta_size(uint32_t size) {
468+
extra_meta_size_ = size;
469+
element_size_ =
470+
ElementSizeof(data_type_, unit_size_, dimension_) + extra_meta_size_;
471+
}
472+
454473
//! Set information of metric
455474
template <typename TName, typename TParams>
456475
void set_metric(TName &&name, uint32_t rev, TParams &&params) {
@@ -586,6 +605,7 @@ class IndexMeta {
586605
uint32_t dimension_{0};
587606
uint32_t unit_size_{0};
588607
uint32_t element_size_{0};
608+
uint32_t extra_meta_size_{0};
589609
uint64_t space_id_{0};
590610
uint32_t metric_revision_{0};
591611
uint32_t converter_revision_{0};
@@ -632,6 +652,19 @@ class IndexQueryMeta {
632652
unit_size_(unit),
633653
element_size_(IndexMeta::ElementSizeof(data_type, unit, dim)) {}
634654

655+
//! Constructor
656+
IndexQueryMeta(IndexMeta::MetaType meta_type, IndexMeta::DataType data_type,
657+
uint32_t unit, uint32_t dim, uint32_t quantize_type,
658+
uint32_t extra_meta_size)
659+
: meta_type_(meta_type),
660+
data_type_(data_type),
661+
dimension_(dim),
662+
unit_size_(unit),
663+
quantize_type_(quantize_type),
664+
extra_meta_size_(extra_meta_size),
665+
element_size_(IndexMeta::ElementSizeof(data_type, unit, dim) +
666+
extra_meta_size_) {}
667+
635668
//! Constructor
636669
IndexQueryMeta(IndexMeta::DataType data_type, uint32_t dim)
637670
: IndexQueryMeta{IndexMeta::MetaType::MT_DENSE, data_type,
@@ -673,10 +706,21 @@ class IndexQueryMeta {
673706
return element_size_;
674707
}
675708

709+
//! Retrieve quantize type
710+
uint32_t quantize_type(void) const {
711+
return quantize_type_;
712+
}
713+
714+
//! Retrieve extra meta size in bytes
715+
uint32_t extra_meta_size(void) const {
716+
return extra_meta_size_;
717+
}
718+
676719
//! Set dimension of feature
677720
void set_dimension(uint32_t dim) {
678721
dimension_ = dim;
679-
element_size_ = IndexMeta::ElementSizeof(data_type_, unit_size_, dim);
722+
element_size_ = IndexMeta::ElementSizeof(data_type_, unit_size_, dim) +
723+
extra_meta_size_;
680724
}
681725

682726
//! Set meta type
@@ -689,24 +733,47 @@ class IndexQueryMeta {
689733
data_type_ = data_type;
690734
}
691735

736+
//! Set extra meta size
737+
void set_extra_meta_size(uint32_t size) {
738+
extra_meta_size_ = size;
739+
element_size_ =
740+
IndexMeta::ElementSizeof(data_type_, unit_size_, dimension_) +
741+
extra_meta_size_;
742+
}
743+
692744
//! Set meta information of feature
693745
void set_meta(IndexMeta::DataType data_type, uint32_t unit, uint32_t dim) {
694746
data_type_ = data_type;
695747
dimension_ = dim;
696748
unit_size_ = unit;
697-
element_size_ = IndexMeta::ElementSizeof(data_type, unit, dim);
749+
element_size_ =
750+
IndexMeta::ElementSizeof(data_type, unit, dim) + extra_meta_size_;
698751
}
699752

700753
//! Set meta information of feature
701754
void set_meta(IndexMeta::DataType data_type, uint32_t dim) {
702755
this->set_meta(data_type, IndexMeta::UnitSizeof(data_type), dim);
703756
}
704757

758+
//! Set meta information of feature with quantize type and extra meta size
759+
void set_meta(IndexMeta::DataType data_type, uint32_t dim,
760+
uint32_t quantize_type, uint32_t extra_meta_size) {
761+
data_type_ = data_type;
762+
dimension_ = dim;
763+
unit_size_ = IndexMeta::UnitSizeof(data_type);
764+
quantize_type_ = quantize_type;
765+
extra_meta_size_ = extra_meta_size;
766+
element_size_ =
767+
IndexMeta::ElementSizeof(data_type, unit_size_, dim) + extra_meta_size_;
768+
}
769+
705770
private:
706771
IndexMeta::MetaType meta_type_{IndexMeta::MetaType::MT_DENSE};
707772
IndexMeta::DataType data_type_{IndexMeta::DataType::DT_UNDEFINED};
708773
uint32_t dimension_{0};
709774
uint32_t unit_size_{0};
775+
uint32_t quantize_type_{0};
776+
uint32_t extra_meta_size_{0};
710777
uint32_t element_size_{0};
711778
};
712779

src/include/zvec/turbo/turbo.h

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,30 +36,56 @@ using UniformQuantizeFunc = void (*)(const float *in, size_t dim, float scale,
3636
enum class MetricType {
3737
kSquaredEuclidean,
3838
kCosine,
39+
kInnerProduct,
3940
kMipsSquaredEuclidean,
4041
kUnknown,
4142
};
4243

4344
enum class DataType {
45+
kInt4,
4446
kInt8,
47+
kFp16,
48+
kFp32,
4549
kUnknown,
4650
};
4751

4852
enum class QuantizeType {
4953
kDefault,
5054
kUniform,
55+
kRecord,
56+
kFp16,
57+
kFp32,
58+
kPQ,
59+
kRabit
60+
};
61+
62+
enum class CpuArchType {
63+
kAuto,
64+
kScalar,
65+
// x86 SIMD
66+
kSSE,
67+
kAVX,
68+
kAVX2,
69+
kAVX512,
70+
kAVX512VNNI,
71+
kAVX512FP16,
72+
// ARM SIMD
73+
kNEON,
74+
kSVE,
75+
kSVE2
5176
};
5277

5378
DistanceFunc get_distance_func(MetricType metric_type, DataType data_type,
54-
QuantizeType quantize_type);
79+
QuantizeType quantize_type,
80+
CpuArchType cpu_arch_type = CpuArchType::kAuto);
5581

56-
BatchDistanceFunc get_batch_distance_func(MetricType metric_type,
57-
DataType data_type,
58-
QuantizeType quantize_type);
82+
BatchDistanceFunc get_batch_distance_func(
83+
MetricType metric_type, DataType data_type, QuantizeType quantize_type,
84+
CpuArchType cpu_arch_type = CpuArchType::kAuto);
5985

60-
QueryPreprocessFunc get_query_preprocess_func(MetricType metric_type,
61-
DataType data_type,
62-
QuantizeType quantize_type);
86+
QueryPreprocessFunc get_query_preprocess_func(
87+
MetricType metric_type, DataType data_type, QuantizeType quantize_type,
88+
CpuArchType cpu_arch_type = CpuArchType::kAuto);
6389

6490
// Returns the SIMD kernel for the uniform quantizer on the current CPU for
6591
// the given output data_type, or nullptr if no SIMD implementation is

src/turbo/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ file(GLOB_RECURSE ALL_SRCS *.cc *.c *.h)
1919
# subdirectory).
2020
if(NOT ANDROID AND AUTO_DETECT_ARCH)
2121
if (HOST_ARCH MATCHES "^(x86|x64)$")
22-
file(GLOB_RECURSE AVX512_VNNI_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/avx512_vnni/*.cc)
22+
file(GLOB_RECURSE AVX512_VNNI_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/distance/avx512_vnni/*.cc)
2323
set_source_files_properties(
2424
${AVX512_VNNI_SRCS}
2525
PROPERTIES
@@ -29,8 +29,8 @@ if(NOT ANDROID AND AUTO_DETECT_ARCH)
2929
endif()
3030

3131
cc_library(
32-
NAME zvec_turbo STATIC STRICT PACKED
32+
NAME zvec_turbo STATIC STRICT ALWAYS_LINK PACKED
3333
SRCS ${ALL_SRCS}
3434
LIBS zvec_ailego
35-
INCS ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_ROOT_DIR}/src/include
35+
INCS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/distance ${PROJECT_ROOT_DIR}/src/include
3636
)

src/turbo/avx512_vnni/record_quantized_int8/common.h renamed to src/turbo/distance/avx512_vnni/record_quantized_int8/common.h

File renamed without changes.

src/turbo/avx512_vnni/record_quantized_int8/cosine.cc renamed to src/turbo/distance/avx512_vnni/record_quantized_int8/cosine.cc

File renamed without changes.

src/turbo/avx512_vnni/record_quantized_int8/cosine.h renamed to src/turbo/distance/avx512_vnni/record_quantized_int8/cosine.h

File renamed without changes.

0 commit comments

Comments
 (0)