Skip to content

Commit 7a9aedc

Browse files
SVS v1
Signed-off-by: Alexandr Guzhva <alexanderguzhva@gmail.com>
1 parent 3b330dd commit 7a9aedc

24 files changed

Lines changed: 1827 additions & 22 deletions

.ycm_extra_conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
flags = [
3838
"-Wall",
3939
"-Wextra",
40-
"-std=c++17",
40+
"-std=c++20",
4141
"-x",
4242
"c++",
4343
"-isystem",

CMakeLists.txt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ endif()
3333
knowhere_option(WITH_UT "Build with UT test" OFF)
3434
knowhere_option(WITH_ASAN "Build with ASAN" OFF)
3535
knowhere_option(WITH_DISKANN "Build with diskann index" OFF)
36+
knowhere_option(WITH_SVS "Build with SVS (Intel Scalable Vector Search) index" OFF)
3637
knowhere_option(WITH_BENCHMARK "Build with benchmark" OFF)
3738
knowhere_option(WITH_COVERAGE "Build with coverage" OFF)
3839
knowhere_option(WITH_CCACHE "Build with ccache" ON)
@@ -121,7 +122,7 @@ if(APPLE)
121122
list(APPEND CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "${_SDK_PATH}/usr/include")
122123
list(APPEND CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "${_SDK_PATH}/usr/include")
123124
endif()
124-
set(CMAKE_CXX_STANDARD 17)
125+
set(CMAKE_CXX_STANDARD 20)
125126
set(CMAKE_OSX_DEPLOYMENT_TARGET
126127
"10.15"
127128
CACHE STRING "Minimum OS X deployment version" FORCE)
@@ -207,6 +208,16 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64|amd64)")
207208

208209
endif()
209210

211+
if(WITH_SVS)
212+
if(NOT __X86_64)
213+
message(FATAL_ERROR "SVS is only supported on x86_64 platforms")
214+
endif()
215+
add_definitions(-DKNOWHERE_WITH_SVS)
216+
else()
217+
knowhere_file_glob(GLOB_RECURSE KNOWHERE_SVS_SRCS src/index/svs/*.cc)
218+
list(REMOVE_ITEM KNOWHERE_SRCS ${KNOWHERE_SVS_SRCS})
219+
endif()
220+
210221
knowhere_file_glob(GLOB_RECURSE KNOWHERE_GPU_SRCS src/index/gpu/flat_gpu/*.cc
211222
src/index/gpu/ivf_gpu/*.cc)
212223
list(REMOVE_ITEM KNOWHERE_SRCS ${KNOWHERE_GPU_SRCS})
@@ -243,7 +254,8 @@ if(WITH_CUVS)
243254
CUDA::cusolver)
244255
endif()
245256

246-
target_link_libraries(knowhere PUBLIC ${KNOWHERE_LINKER_LIBS})
257+
target_link_libraries(knowhere PRIVATE ${KNOWHERE_LINKER_LIBS})
258+
target_link_libraries(knowhere PUBLIC Boost::boost nlohmann_json::nlohmann_json glog::glog Folly::folly prometheus-cpp::core opentelemetry-cpp::opentelemetry_trace)
247259

248260
if (WITH_CARDINAL)
249261
target_link_libraries(knowhere PRIVATE "-Wl,--no-as-needed" ${CARDINAL_LIBS} "-Wl,--as-needed")

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ CONAN_BASE_FLAGS := --update --build=missing
2121
WITH_GPU ?=
2222
WITH_UT ?=
2323
WITH_ASAN ?=
24+
WITH_SVS ?=
2425
WITH_CARDINAL ?=
2526
WITH_DEBUG ?=
2627
CONAN_PROFILE ?=
@@ -48,7 +49,7 @@ else
4849
endif
4950

5051
# ---------- Compose conan flags from user flags ----------
51-
CONAN_FLAGS := $(CONAN_BASE_FLAGS) -s compiler.libcxx=$(LIBCXX) -s build_type=$(BUILD_TYPE) -s compiler.cppstd=17
52+
CONAN_FLAGS := $(CONAN_BASE_FLAGS) -s compiler.libcxx=$(LIBCXX) -s build_type=$(BUILD_TYPE) -s compiler.cppstd=20
5253

5354
# DiskANN and liburing require libaio (Linux-only).
5455
ifneq ($(UNAME_S),Darwin)
@@ -71,6 +72,10 @@ ifdef WITH_ASAN
7172
CONAN_FLAGS += -o with_asan=True
7273
endif
7374

75+
ifdef WITH_SVS
76+
CONAN_FLAGS += -o with_svs=True
77+
endif
78+
7479
ifdef WITH_CARDINAL
7580
CONAN_FLAGS += -o with_cardinal=True
7681
endif
@@ -140,6 +145,7 @@ help: ## Show available targets
140145
@echo " WITH_GPU=True Enable GPU (cuVS) build"
141146
@echo " WITH_UT=True Enable unit tests"
142147
@echo " WITH_ASAN=True Enable AddressSanitizer"
148+
@echo " WITH_SVS=True Enable SVS (Intel Scalable Vector Search, x86 only)"
143149
@echo " WITH_CARDINAL=True Enable Cardinal build"
144150
@echo " WITH_DEBUG=True Debug build (default: Release)"
145151
@echo " CONAN_PROFILE=<p> Use a custom Conan profile (e.g. clang, gcc-15)"

benchmark/CMakeLists.txt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ benchmark_test(benchmark_float_range hdf5/benchmark_float_range.cpp)
5555
benchmark_test(benchmark_float_range_bitset hdf5/benchmark_float_range_bitset.cpp)
5656
benchmark_test(benchmark_simd_qps hdf5/benchmark_simd_qps.cpp)
5757

58+
# Float benchmarks use milvus::LocalFileManager directly
59+
target_link_libraries(benchmark_float milvus-common)
60+
target_link_libraries(benchmark_float_bitset milvus-common)
61+
target_link_libraries(benchmark_float_qps milvus-common)
62+
target_link_libraries(benchmark_float_range milvus-common)
63+
target_link_libraries(benchmark_float_range_bitset milvus-common)
64+
65+
if(WITH_SVS)
66+
benchmark_test(benchmark_svs_float_qps hdf5/benchmark_svs_float_qps.cpp)
67+
benchmark_test(benchmark_svs_vamana_float_qps hdf5/benchmark_svs_vamana_float_qps.cpp)
68+
endif()
69+
5870
benchmark_test(gen_hdf5_file hdf5/gen_hdf5_file.cpp)
5971
benchmark_test(gen_fbin_file hdf5/gen_fbin_file.cpp)
6072

@@ -63,7 +75,8 @@ benchmark_test(gen_fbin_file hdf5/gen_fbin_file.cpp)
6375
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64|amd64|X86_64)$")
6476
message(STATUS "Building sparse SIMD benchmark for ${CMAKE_SYSTEM_PROCESSOR}")
6577
add_executable(benchmark_sparse_simd benchmark_sparse_simd.cpp)
66-
target_link_libraries(benchmark_sparse_simd knowhere)
78+
target_link_libraries(benchmark_sparse_simd knowhere knowhere_utils
79+
-Wl,--no-as-needed -laio -Wl,--as-needed)
6780
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
6881
target_compile_options(benchmark_sparse_simd PRIVATE -mavx512f -mavx512dq)
6982
endif()

benchmark/Makefile.sparse_simd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Usage: make -f Makefile.sparse_simd
33

44
CXX ?= g++
5-
CXXFLAGS = -std=c++17 -O3 -Wall -I../include -I.. -mavx512f -mavx512dq
5+
CXXFLAGS = -std=c++20 -O3 -Wall -I../include -I.. -mavx512f -mavx512dq
66
LDFLAGS = -pthread
77

88
# Detect build directory
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
4+
// with the License. You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software distributed under the License
9+
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10+
// or implied. See the License for the specific language governing permissions and limitations under the License.
11+
12+
#include <gtest/gtest.h>
13+
14+
#include <thread>
15+
#include <vector>
16+
17+
#include "benchmark_knowhere.h"
18+
#include "knowhere/comp/index_param.h"
19+
#include "knowhere/comp/knowhere_config.h"
20+
#include "knowhere/dataset.h"
21+
22+
class Benchmark_svs_float_qps : public Benchmark_knowhere, public ::testing::Test {
23+
public:
24+
template <typename T>
25+
void
26+
test_flat(const knowhere::Json& cfg) {
27+
auto conf = cfg;
28+
29+
float expected_recall = 1.0f;
30+
conf[knowhere::meta::TOPK] = topk_;
31+
32+
std::string data_type_str = get_data_type_name<T>();
33+
printf("\n[%0.3f s] %s | %s(%s) | k=%d, R@=%.4f\n", get_time_diff(), ann_test_name_.c_str(),
34+
index_type_.c_str(), data_type_str.c_str(), topk_, expected_recall);
35+
printf("================================================================================\n");
36+
for (auto thread_num : THREAD_NUMs_) {
37+
CALC_TIME_SPAN(task<T>(conf, thread_num, nq_));
38+
printf(" thread_num = %2d, elapse = %6.3fs, VPS = %.3f\n", thread_num, TDIFF_, nq_ / TDIFF_);
39+
std::fflush(stdout);
40+
}
41+
printf("================================================================================\n");
42+
printf("[%.3f s] Test '%s/%s' done\n\n", get_time_diff(), ann_test_name_.c_str(), index_type_.c_str());
43+
}
44+
45+
private:
46+
template <typename T>
47+
void
48+
task(const knowhere::Json& conf, int32_t worker_num, int32_t nq_total) {
49+
auto worker = [&](int32_t idx_start, int32_t num) {
50+
num = std::min(num, nq_total - idx_start);
51+
for (int32_t i = 0; i < num; i++) {
52+
auto ds_ptr = knowhere::GenDataSet(1, dim_, (const float*)xq_ + (idx_start + i) * dim_);
53+
auto query = knowhere::ConvertToDataTypeIfNeeded<T>(ds_ptr);
54+
index_.value().Search(query, conf, nullptr);
55+
}
56+
};
57+
58+
std::vector<std::thread> thread_vector(worker_num);
59+
for (int32_t i = 0; i < worker_num; i++) {
60+
int32_t idx_start, req_num;
61+
req_num = nq_total / worker_num;
62+
if (nq_total % worker_num != 0) {
63+
req_num++;
64+
}
65+
idx_start = req_num * i;
66+
thread_vector[i] = std::thread(worker, idx_start, req_num);
67+
}
68+
for (int32_t i = 0; i < worker_num; i++) {
69+
thread_vector[i].join();
70+
}
71+
}
72+
73+
protected:
74+
void
75+
SetUp() override {
76+
T0_ = elapsed();
77+
set_ann_test_name("sift-128-euclidean");
78+
parse_ann_test_name();
79+
load_hdf5_data<knowhere::fp32>();
80+
81+
cfg_[knowhere::meta::METRIC_TYPE] = metric_type_;
82+
knowhere::KnowhereConfig::SetSimdType(knowhere::KnowhereConfig::SimdType::AVX2);
83+
knowhere::KnowhereConfig::SetBuildThreadPoolSize(default_build_thread_num);
84+
knowhere::KnowhereConfig::SetSearchThreadPoolSize(default_search_thread_num);
85+
printf("faiss::distance_compute_blas_threshold: %ld\n", knowhere::KnowhereConfig::GetBlasThreshold());
86+
}
87+
88+
void
89+
TearDown() override {
90+
free_all();
91+
}
92+
93+
protected:
94+
const int32_t topk_ = 100;
95+
const std::vector<int32_t> THREAD_NUMs_ = {8};
96+
};
97+
98+
#define TEST_INDEX(NAME, T, X) \
99+
index_file_name = get_index_name<T>(X); \
100+
create_index<T>(index_file_name, conf); \
101+
test_##NAME<T>(conf)
102+
103+
TEST_F(Benchmark_svs_float_qps, TEST_FAISS_FLAT) {
104+
index_type_ = knowhere::IndexEnum::INDEX_FAISS_IDMAP;
105+
106+
std::string index_file_name;
107+
knowhere::Json conf = cfg_;
108+
std::vector<int32_t> params = {};
109+
110+
TEST_INDEX(flat, knowhere::fp32, params);
111+
}
112+
113+
#ifdef KNOWHERE_WITH_SVS
114+
TEST_F(Benchmark_svs_float_qps, TEST_SVS_FLAT) {
115+
index_type_ = knowhere::IndexEnum::INDEX_SVS_FLAT;
116+
117+
std::string index_file_name;
118+
knowhere::Json conf = cfg_;
119+
std::vector<int32_t> params = {};
120+
121+
TEST_INDEX(flat, knowhere::fp32, params);
122+
}
123+
#endif

0 commit comments

Comments
 (0)