-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Enable Intel ScalableVectorSearch support #4548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 59 commits
8fd27d6
c499b93
0bd1fdd
6885f30
0215940
d4d1226
48904f3
b4c768a
5cf26a9
11b44f7
9854e82
0df0771
014960d
09c0db5
969d595
9e3c48e
a585e9d
7eb6289
6dbb96f
90b15b6
38b7eea
4f36df5
713cc36
8f16863
034320b
c7c3577
9ff7b53
b2b9819
d31bcb1
483193a
caf1f90
38ef801
42b2208
6873aa3
b51ce17
c7fb7df
42adb07
3378077
363ec05
250b74f
00dd505
4f83fd0
d264256
d7ad33f
32d5063
0a62dee
95bf6bd
0542ed7
021c558
19c9181
ff37171
4f5dc9a
d61d1cb
2e19a56
a28c1ee
87e85c4
b634f6a
da72c1a
fd52aa1
26023b0
741d0ed
4da3db8
53bd413
7a7931c
9e05e00
d7009fc
d5ccad6
8cb7a7e
40dc90d
c45d09a
278e9ba
734e5f3
baa42c9
38fe2ea
dce50d9
c74b659
21f8bf4
2a8bac7
421e582
009e135
1fcbc1e
a9e5235
d7b276f
972818c
ba0e52a
38cc069
2469976
96ba302
be5560c
22600e3
5811cde
f5fb356
3ce665a
c85c538
13e3897
3537df7
4c3c82e
c14ab71
6da649f
b9ef77f
8c80f6a
95e8f66
63ba062
2dce7f4
a5800d4
074f645
01ab8df
2414431
f71cf1e
230d202
27b1b9d
edbe9cd
b709fa1
06a1f31
d4c0557
6539d5e
d6ab3f1
3cedda6
a20d2a7
d895b99
9fdd2f6
6b42374
e6f2c9a
29086ae
211832f
056cb8c
bef9914
0a63ff9
203760c
82ebccf
63542b1
34b0dfa
e755372
26c404e
3871583
64c6910
6650142
83b39e0
4abda24
f715931
268eaca
3e25e2b
0e043e2
a184486
9a0fa75
a2f33f2
e9c76cd
462908d
952563d
34a411f
7dbdd60
ea50f11
7a342f4
faeb765
5d5d464
8c838a4
bf7c9f2
0cf8c2a
6d5ad77
4b6c644
3831e8e
33b0cd3
e672cf5
2af4cf1
d81dc00
f82831a
7bf2b62
2f5bae6
d06d2fb
a4edce0
4bbf61e
2a14910
ca7f66b
7346953
ef7a459
2fd1865
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -100,6 +100,16 @@ set(FAISS_SRC | |
| utils/distances_fused/simdlib_based.cpp | ||
| ) | ||
|
|
||
| if(FAISS_ENABLE_SVS) | ||
| list(APPEND FAISS_SRC | ||
| IndexSVSFlat.cpp | ||
| IndexSVSVamana.cpp | ||
| IndexSVSVamanaLVQ.cpp | ||
| IndexSVSVamanaLeanVec.cpp | ||
| impl/svs_io.cpp | ||
| ) | ||
| endif() | ||
|
|
||
| set(FAISS_HEADERS | ||
| AutoTune.h | ||
| Clustering.h | ||
|
|
@@ -241,6 +251,15 @@ set(FAISS_HEADERS | |
| utils/hamming_distance/avx512-inl.h | ||
| ) | ||
|
|
||
| if(FAISS_ENABLE_SVS) | ||
| list(APPEND FAISS_HEADERS | ||
| IndexSVSFlat.h | ||
| IndexSVSVamana.h | ||
| IndexSVSVamanaLVQ.h | ||
| IndexSVSVamanaLeanVec.h | ||
| ) | ||
| endif() | ||
|
|
||
| if(NOT WIN32) | ||
| list(APPEND FAISS_SRC invlists/OnDiskInvertedLists.cpp) | ||
| list(APPEND FAISS_HEADERS invlists/OnDiskInvertedLists.h) | ||
|
|
@@ -320,6 +339,25 @@ if(NOT WIN32) | |
| endif() | ||
| endif() | ||
|
|
||
| if(FAISS_ENABLE_SVS) | ||
| include(FetchContent) | ||
| set(SVS_URL "https://github.com/intel/ScalableVectorSearch/releases/download/v1.0.0-dev/svs-shared-library-1.0.0-NIGHTLY-20250820.tar.gz") | ||
|
||
| FetchContent_Declare( | ||
| svs | ||
| URL "${SVS_URL}" | ||
| ) | ||
| FetchContent_MakeAvailable(svs) | ||
| list(APPEND CMAKE_PREFIX_PATH "${svs_SOURCE_DIR}") | ||
| find_package(svs REQUIRED) | ||
| target_compile_options(svs::svs INTERFACE "-DSVS_ENABLE_OMP=1") | ||
|
|
||
| target_link_libraries(faiss PUBLIC svs::svs svs::svs_shared_library) | ||
|
||
| target_link_libraries(faiss_avx2 PUBLIC svs::svs svs::svs_shared_library) | ||
| target_link_libraries(faiss_avx512 PUBLIC svs::svs svs::svs_shared_library) | ||
| target_link_libraries(faiss_avx512_spr PUBLIC svs::svs svs::svs_shared_library) | ||
| target_link_libraries(faiss_sve PUBLIC svs::svs svs::svs_shared_library) | ||
| endif() | ||
|
|
||
| # Handle `#include <faiss/foo.h>`. | ||
| target_include_directories(faiss PUBLIC | ||
| $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>) | ||
|
|
@@ -335,6 +373,23 @@ target_include_directories(faiss_avx512_spr PUBLIC | |
| # Handle `#include <faiss/foo.h>`. | ||
| target_include_directories(faiss_sve PUBLIC | ||
| $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>) | ||
| if(FAISS_ENABLE_SVS) | ||
| # Handle `#include <svs/foo.h>`. | ||
| target_include_directories(faiss PUBLIC | ||
| $<BUILD_INTERFACE:${svs_SOURCE_DIR}/include>) | ||
| # Handle `#include <svs/foo.h>`. | ||
| target_include_directories(faiss_avx2 PUBLIC | ||
| $<BUILD_INTERFACE:${svs_SOURCE_DIR}/include>) | ||
| # Handle `#include <svs/foo.h>`. | ||
| target_include_directories(faiss_avx512 PUBLIC | ||
| $<BUILD_INTERFACE:${svs_SOURCE_DIR}/include>) | ||
| # Handle `#include <svs/foo.h>`. | ||
| target_include_directories(faiss_avx512_spr PUBLIC | ||
| $<BUILD_INTERFACE:${svs_SOURCE_DIR}/include>) | ||
| # Handle `#include <svs/foo.h>`. | ||
| target_include_directories(faiss_sve PUBLIC | ||
| $<BUILD_INTERFACE:${svs_SOURCE_DIR}/include>) | ||
| endif() | ||
|
|
||
| set_target_properties(faiss faiss_avx2 faiss_avx512 faiss_avx512_spr faiss_sve PROPERTIES | ||
| POSITION_INDEPENDENT_CODE ON | ||
|
|
@@ -349,6 +404,14 @@ if(WIN32) | |
| target_compile_definitions(faiss_sve PRIVATE FAISS_MAIN_LIB) | ||
| endif() | ||
|
|
||
| if(FAISS_ENABLE_SVS) | ||
| target_compile_definitions(faiss PRIVATE FAISS_ENABLE_SVS) | ||
| target_compile_definitions(faiss_avx2 PRIVATE FAISS_ENABLE_SVS) | ||
| target_compile_definitions(faiss_avx512 PRIVATE FAISS_ENABLE_SVS) | ||
| target_compile_definitions(faiss_avx512_spr PRIVATE FAISS_ENABLE_SVS) | ||
| target_compile_definitions(faiss_sve PRIVATE FAISS_ENABLE_SVS) | ||
| endif() | ||
|
|
||
| if(WIN32) | ||
| set_target_properties(faiss PROPERTIES LINK_FLAGS "-Wl,--export-all-symbols") | ||
| endif() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| /* | ||
| * Copyright (c) Meta Platforms, Inc. and affiliates. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE file in the root directory of this source tree. | ||
| */ | ||
|
|
||
| #include <faiss/IndexSVSFlat.h> | ||
|
|
||
| #include <faiss/impl/FaissAssert.h> | ||
| #include <svs/core/data.h> | ||
| #include <svs/core/query_result.h> | ||
|
|
||
| #include <svs/orchestrators/exhaustive.h> | ||
|
|
||
| namespace faiss { | ||
|
|
||
| IndexSVSFlat::IndexSVSFlat(idx_t d, MetricType metric) : Index(d, metric) {} | ||
|
|
||
| void IndexSVSFlat::add(idx_t n, const float* x) { | ||
| if (!impl) { | ||
| init_impl(n, x); | ||
| return; | ||
| } | ||
|
|
||
| FAISS_THROW_MSG( | ||
| "IndexSVSFlat does not support adding points after initialization"); | ||
| } | ||
|
|
||
| void IndexSVSFlat::reset() { | ||
| if (impl) { | ||
| delete impl; | ||
| impl = nullptr; | ||
| } | ||
| ntotal = 0; | ||
| } | ||
|
|
||
| IndexSVSFlat::~IndexSVSFlat() {} | ||
|
|
||
| void IndexSVSFlat::search( | ||
| idx_t n, | ||
| const float* x, | ||
| idx_t k, | ||
| float* distances, | ||
| idx_t* labels, | ||
| const SearchParameters* params) const { | ||
| FAISS_THROW_IF_NOT(impl); | ||
| FAISS_THROW_IF_NOT(k > 0); | ||
|
|
||
| auto queries = svs::data::ConstSimpleDataView<float>(x, n, d); | ||
|
|
||
| auto results = | ||
| svs::QueryResult<size_t>{queries.size(), static_cast<size_t>(k)}; | ||
| // TODO: Tuable Flat parameters | ||
| impl->search(results.view(), queries, {}); | ||
|
|
||
| svs::threads::parallel_for( | ||
| impl->get_threadpool_handle(), | ||
| svs::threads::StaticPartition(n), | ||
| [&](auto is, auto SVS_UNUSED(tid)) { | ||
| for (auto i : is) { | ||
| for (idx_t j = 0; j < k; ++j) { | ||
| labels[j + i * k] = results.index(i, j); | ||
| distances[j + i * k] = results.distance(i, j); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| void IndexSVSFlat::init_impl(idx_t n, const float* x) { | ||
| auto data = svs::data::SimpleData<float>(n, d); | ||
| auto threadpool = svs::threads::ThreadPoolHandle( | ||
| svs::threads::OMPThreadPool(omp_get_max_threads())); | ||
| ntotal = n; | ||
|
|
||
| svs::threads::parallel_for( | ||
| threadpool, | ||
| svs::threads::StaticPartition(n), | ||
| [&](auto is, auto SVS_UNUSED(tid)) { | ||
| for (auto i : is) { | ||
| data.set_datum(i, std::span<const float>(x + i * d, d)); | ||
| } | ||
| }); | ||
|
|
||
| switch (metric_type) { | ||
| case METRIC_INNER_PRODUCT: | ||
| impl = new svs::Flat(svs::Flat::assemble<float>( | ||
| std::move(data), svs::DistanceIP(), std::move(threadpool))); | ||
| break; | ||
| case METRIC_L2: | ||
| impl = new svs::Flat(svs::Flat::assemble<float>( | ||
| std::move(data), svs::DistanceL2(), std::move(threadpool))); | ||
| break; | ||
| default: | ||
| FAISS_ASSERT(!"not supported SVS distance"); | ||
| } | ||
| } | ||
|
|
||
| void IndexSVSFlat::serialize_impl(std::ostream& out) const { | ||
| FAISS_THROW_IF_NOT_MSG( | ||
| impl, "Cannot serialize: SVS index not initialized."); | ||
|
|
||
| // Write index to temporary files and concatenate the contents | ||
| svs_io::SVSTempDirectory tmp; | ||
| impl->save(tmp.data); | ||
| tmp.write_files_to_stream(out); | ||
| } | ||
|
|
||
| void IndexSVSFlat::deserialize_impl(std::istream& in) { | ||
| FAISS_THROW_IF_MSG( | ||
| impl, "Cannot deserialize: SVS index already initialized."); | ||
|
|
||
| // Write stream to files that can be read by Flat::assemble() | ||
| svs_io::SVSTempDirectory tmp; | ||
| tmp.write_stream_to_files(in); | ||
|
|
||
| auto threadpool = svs::threads::ThreadPoolHandle( | ||
| svs::threads::OMPThreadPool(omp_get_max_threads())); | ||
|
|
||
| switch (metric_type) { | ||
| case METRIC_INNER_PRODUCT: | ||
| impl = new svs::Flat(svs::Flat::assemble<float>( | ||
| svs::VectorDataLoader<float>(tmp.data.string()), | ||
| svs::DistanceIP(), | ||
| std::move(threadpool))); | ||
| break; | ||
| case METRIC_L2: | ||
| impl = new svs::Flat(svs::Flat::assemble<float>( | ||
| svs::VectorDataLoader<float>(tmp.data.string()), | ||
| svs::DistanceL2(), | ||
| std::move(threadpool))); | ||
| break; | ||
| default: | ||
| FAISS_ASSERT(!"not supported SVS distance"); | ||
| } | ||
| } | ||
|
|
||
| } // namespace faiss |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| /* | ||
| * Copyright (c) Meta Platforms, Inc. and affiliates. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE file in the root directory of this source tree. | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <iostream> | ||
|
|
||
| #include <svs/core/distance.h> | ||
|
|
||
| #include <faiss/Index.h> | ||
| #include <faiss/impl/svs_io.h> | ||
|
|
||
| namespace svs { | ||
| class Flat; | ||
| } | ||
|
|
||
| namespace faiss { | ||
|
|
||
| struct IndexSVSFlat : Index { | ||
| // sequential labels | ||
| size_t nlabels{0}; | ||
|
|
||
| IndexSVSFlat() = default; | ||
| IndexSVSFlat(idx_t d, MetricType metric = METRIC_L2); | ||
|
|
||
| ~IndexSVSFlat(); | ||
|
|
||
| void add(idx_t n, const float* x) override; | ||
|
|
||
| void search( | ||
| idx_t n, | ||
| const float* x, | ||
| idx_t k, | ||
| float* distances, | ||
| idx_t* labels, | ||
| const SearchParameters* params = nullptr) const override; | ||
|
|
||
| void reset() override; | ||
|
|
||
| /* The actual SVS implementation */ | ||
| svs::Flat* impl{nullptr}; | ||
|
|
||
| /* Initializes the implementation, using the provided data */ | ||
| virtual void init_impl(idx_t n, const float* x); | ||
|
|
||
| /* Serialization */ | ||
| void serialize_impl(std::ostream& out) const; | ||
| void deserialize_impl(std::istream& in); | ||
| }; | ||
|
|
||
| } // namespace faiss |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the build failure due to this by default being
ON?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by default do we want to keep it
ONor we want o keep itOFF? (concern stems from whether we are confident that SVS works on all platforms that we care to support, with the expected performance levels)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah after discussion, we plan to set OFF by default, and we will create a new CI which will enable it. If it does not break other platforms, eventually we can set ON by default, but that can be a separate PR.