Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 15 additions & 16 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,27 +89,26 @@ message(STATUS "BUILD_PYTHON_BINDINGS:${BUILD_PYTHON_BINDINGS}")
message(STATUS "BUILD_C_BINDINGS:${BUILD_C_BINDINGS}")
message(STATUS "BUILD_TOOLS:${BUILD_TOOLS}")

option(RABITQ_ENABLE_AVX512 "Compile RaBitQ with AVX-512 support" OFF)

if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64" AND NOT ANDROID AND NOT IOS)
include(CheckCCompilerFlag)

check_c_compiler_flag("-mavx2" COMPILER_SUPPORTS_AVX2)
check_c_compiler_flag("-mavx512f -mavx512bw -mavx512vl" COMPILER_SUPPORTS_AVX512)

if(COMPILER_SUPPORTS_AVX2 OR COMPILER_SUPPORTS_AVX512)
include(CheckCXXCompilerFlag)

check_cxx_compiler_flag("-mavx2 -mfma" COMPILER_SUPPORTS_RABITQ_AVX2)
check_cxx_compiler_flag(
"-mavx512f -mavx512bw -mavx512dq -mfma"
COMPILER_SUPPORTS_RABITQ_AVX512)
check_cxx_compiler_flag(
"-mavx512f -mavx512bw -mavx512dq -mavx512vpopcntdq -mfma"
COMPILER_SUPPORTS_RABITQ_AVX512_POPCNT)

if(COMPILER_SUPPORTS_RABITQ_AVX2 AND
COMPILER_SUPPORTS_RABITQ_AVX512 AND
COMPILER_SUPPORTS_RABITQ_AVX512_POPCNT)
set(RABITQ_SUPPORTED ON)
add_definitions(-DRABITQ_SUPPORTED=1)
if(RABITQ_ENABLE_AVX512 AND COMPILER_SUPPORTS_AVX512)
add_definitions(-DRABITQ_COMPILED_AVX512=1)
set(RABITQ_ARCH_FLAG "${MATH_MARCH_FLAG_AVX512}")
else()
set(RABITQ_ARCH_FLAG "${MATH_MARCH_FLAG_AVX2}")
endif()
else()
set(RABITQ_SUPPORTED OFF)
add_definitions(-DRABITQ_SUPPORTED=0)
message(STATUS "RaBitQ support disabled - compiler does not support AVX2 or AVX-512")
message(STATUS "RaBitQ support disabled - compiler cannot build all runtime dispatch variants")
endif()
elseif(IOS)
set(RABITQ_SUPPORTED OFF)
Expand All @@ -120,7 +119,7 @@ else()
add_definitions(-DRABITQ_SUPPORTED=0)
message(STATUS "RaBitQ support disabled - only supported on Linux x86_64")
endif()
message(STATUS "RABITQ_ARCH_FLAG: ${RABITQ_ARCH_FLAG}")
message(STATUS "RABITQ_SUPPORTED: ${RABITQ_SUPPORTED}")

# DiskAnn support (Linux x86_64 only; libaio loaded at runtime via dlopen)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|i686|i386" AND NOT ANDROID AND NOT IOS)
Expand Down
20 changes: 0 additions & 20 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,6 @@
include(${PROJECT_ROOT_DIR}/cmake/bazel.cmake)
include(${PROJECT_ROOT_DIR}/cmake/option.cmake)

if(RABITQ_SUPPORTED AND AUTO_DETECT_ARCH)
set(HNSW_RABITQ_FILES
hnsw_rabitq_query_algorithm.cc
hnsw_rabitq_streamer.cc
hnsw_rabitq_searcher.cc
hnsw_rabitq_entity.cc
rabitq_reformer.cc
rabitq_converter.cc
)
set(HNSW_RABITQ_FILES_FULL ${HNSW_RABITQ_FILES})
list(TRANSFORM HNSW_RABITQ_FILES_FULL PREPEND "algorithm/hnsw_rabitq/")
foreach(FILE ${HNSW_RABITQ_FILES_FULL})
set_source_files_properties(
${FILE}
PROPERTIES
COMPILE_FLAGS "${RABITQ_ARCH_FLAG}"
)
endforeach()
endif()

# utility/block_heap.cc uses AVX2 intrinsics guarded by __AVX2__. When the
# host toolchain supports it, compile this source with an AVX2-capable
# -march so AVX2 codegen is emitted. zvec_core glob-collects this source
Expand Down
12 changes: 1 addition & 11 deletions src/core/algorithm/hnsw_rabitq/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
include(${PROJECT_ROOT_DIR}/cmake/bazel.cmake)
include(${PROJECT_ROOT_DIR}/cmake/option.cmake)

if(AUTO_DETECT_ARCH)
foreach(FILE ${HNSW_RABITQ_FILES})
set_source_files_properties(
${FILE}
PROPERTIES
COMPILE_FLAGS "${RABITQ_ARCH_FLAG}"
)
endforeach()
endif()

if(NOT APPLE)
set(CORE_KNN_HNSW_RABITQ_LDFLAGS
"-Wl,--exclude-libs,libparquet.a:libarrow.a:libarrow_bundled_dependencies.a")
Expand All @@ -24,4 +14,4 @@ cc_library(
INCS . ${PROJECT_ROOT_DIR}/src ${PROJECT_ROOT_DIR}/src/core ${PROJECT_ROOT_DIR}/src/core/algorithm
LDFLAGS "${CORE_KNN_HNSW_RABITQ_LDFLAGS}"
VERSION "${PROXIMA_ZVEC_VERSION}"
)
)
20 changes: 5 additions & 15 deletions src/db/index/common/schema.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@

namespace zvec {

#if defined(RABITQ_COMPILED_AVX512)
constexpr const int kRabitqCompiledAvx512 = RABITQ_COMPILED_AVX512;
#else
constexpr const int kRabitqCompiledAvx512 = 0;
#endif

std::unordered_map<DataType, std::set<QuantizeType>> quantize_type_map = {
{DataType::VECTOR_FP32,
{QuantizeType::FP16, QuantizeType::INT4, QuantizeType::INT8,
Expand Down Expand Up @@ -184,16 +178,12 @@ Status FieldSchema::validate() const {
"RabitQ is not supported on this platform (Linux x86_64 only)");
#endif
auto &flags = zvec::ailego::internal::CpuFeatures::static_flags_;
if (!flags.AVX2 && !flags.AVX512F) {
const bool supports_rabitq_avx2 = flags.AVX2 && flags.FMA;
const bool supports_rabitq_avx512 =
flags.AVX512F && flags.AVX512BW && flags.AVX512DQ;
if (!supports_rabitq_avx2 && !supports_rabitq_avx512) {
return Status::NotSupported(
"RabitQ requires AVX2/AVX512F to be supported");
}

if constexpr (kRabitqCompiledAvx512) {
if (!flags.AVX512F) {
return Status::NotSupported(
"RabitQ compiled with AVX512F while runtime does not support");
}
"RabitQ requires AVX2/FMA or AVX512F/BW/DQ to be supported");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <memory>
#include <string>
#include <gtest/gtest.h>
#include <rabitqlib/utils/cpu_features.hpp>
#include "zvec/ailego/container/params.h"
#include "zvec/ailego/utility/file_helper.h"
#include "zvec/core/framework/index_holder.h"
Expand Down Expand Up @@ -45,6 +46,10 @@ std::string HnswRabitqStreamerTest::dir_("hnswRabitqStreamerTest");
shared_ptr<IndexMeta> HnswRabitqStreamerTest::index_meta_ptr_;

void HnswRabitqStreamerTest::SetUp(void) {
if (!rabitqlib::cpu::has_avx512_core() && !rabitqlib::cpu::has_avx2()) {
GTEST_SKIP() << "CPU does not support AVX2/FMA or AVX512F/BW/DQ";
}

index_meta_ptr_.reset(new (nothrow)
IndexMeta(IndexMeta::DataType::DT_FP32, dim));
index_meta_ptr_->set_metric("SquaredEuclidean", 0, ailego::Params());
Expand Down
41 changes: 41 additions & 0 deletions tests/core/algorithm/hnsw_rabitq/rabitq_dispatch_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2025-present the zvec project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gtest/gtest.h>
#include <rabitqlib/simd/dispatch.hpp>
#include <rabitqlib/simd/space_dispatch.hpp>
#include <rabitqlib/utils/cpu_features.hpp>

namespace zvec {
namespace core {

TEST(RabitqDispatchTest, SelectsBestAvailableExcodeImplementation) {
if (!rabitqlib::cpu::has_avx512_core() && !rabitqlib::cpu::has_avx2()) {
GTEST_SKIP() << "CPU does not support AVX2/FMA or AVX512F/BW/DQ";
}

constexpr size_t kExBits = 2;
const auto table = rabitqlib::simd::resolve_excode_ip_table();

if (rabitqlib::cpu::has_avx512_core()) {
EXPECT_EQ(table[kExBits],
&rabitqlib::simd::excode_ipimpl::ip64_fxu2_avx512);
} else {
ASSERT_TRUE(rabitqlib::cpu::has_avx2());
EXPECT_EQ(table[kExBits], &rabitqlib::simd::excode_ipimpl::ip64_fxu2_avx2);
}
}

} // namespace core
} // namespace zvec
76 changes: 76 additions & 0 deletions thirdparty/RaBitQ-Library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,79 @@ add_library(rabitqlib INTERFACE)
target_include_directories(
rabitqlib SYSTEM INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/RaBitQ-Library-0.1/include"
)

if(RABITQ_SUPPORTED)
set(RABITQ_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/RaBitQ-Library-0.1")

set(RABITQ_COMMON_SOURCES
"${RABITQ_SOURCE_DIR}/src/utils/cpu_features.cpp"
"${RABITQ_SOURCE_DIR}/src/simd/dispatch.cpp"
)
set(RABITQ_AVX2_SOURCES
"${RABITQ_SOURCE_DIR}/src/simd/pack_excode_avx2.cpp"
"${RABITQ_SOURCE_DIR}/src/simd/space_excode_avx2.cpp"
"${RABITQ_SOURCE_DIR}/src/simd/space_avx2.cpp"
"${RABITQ_SOURCE_DIR}/src/simd/fastscan_avx2.cpp"
"${RABITQ_SOURCE_DIR}/src/simd/warmup_avx2.cpp"
"${RABITQ_SOURCE_DIR}/src/simd/rotator_avx2.cpp"
"${RABITQ_SOURCE_DIR}/src/index/hnsw_search_avx2.cpp"
)
set(RABITQ_AVX512_SOURCES
"${RABITQ_SOURCE_DIR}/src/simd/pack_excode_avx512.cpp"
"${RABITQ_SOURCE_DIR}/src/simd/space_excode_avx512.cpp"
"${RABITQ_SOURCE_DIR}/src/simd/space_avx512.cpp"
"${RABITQ_SOURCE_DIR}/src/simd/fastscan_avx512.cpp"
"${RABITQ_SOURCE_DIR}/src/simd/rotator_avx512.cpp"
)
set(RABITQ_AVX512_POPCNT_SOURCES
"${RABITQ_SOURCE_DIR}/src/simd/warmup_avx512.cpp"
)
set(RABITQ_HNSW_AVX512_SOURCES
"${RABITQ_SOURCE_DIR}/src/index/hnsw_search_avx512_core.cpp"
)
set(RABITQ_HNSW_AVX512_POPCNT_SOURCES
"${RABITQ_SOURCE_DIR}/src/index/hnsw_search_avx512_popcnt.cpp"
)

add_library(
rabitqlib_runtime STATIC
${RABITQ_COMMON_SOURCES}
${RABITQ_AVX2_SOURCES}
${RABITQ_AVX512_SOURCES}
${RABITQ_AVX512_POPCNT_SOURCES}
${RABITQ_HNSW_AVX512_SOURCES}
${RABITQ_HNSW_AVX512_POPCNT_SOURCES}
)
target_include_directories(
rabitqlib_runtime SYSTEM PUBLIC "${RABITQ_SOURCE_DIR}/include"
)
set_target_properties(
rabitqlib_runtime PROPERTIES POSITION_INDEPENDENT_CODE ON
)

set_source_files_properties(
${RABITQ_AVX2_SOURCES}
PROPERTIES COMPILE_OPTIONS "-mavx2;-mfma"
)
set_source_files_properties(
${RABITQ_AVX512_SOURCES}
PROPERTIES COMPILE_OPTIONS "-mavx512f;-mavx512bw;-mavx512dq;-mfma"
)
set_source_files_properties(
${RABITQ_AVX512_POPCNT_SOURCES}
PROPERTIES
COMPILE_OPTIONS "-mavx512f;-mavx512bw;-mavx512dq;-mavx512vpopcntdq;-mfma"
)
set_source_files_properties(
${RABITQ_HNSW_AVX512_SOURCES}
PROPERTIES
COMPILE_OPTIONS "-mavx512f;-mavx512bw;-mavx512dq;-mavx2;-mfma"
)
set_source_files_properties(
${RABITQ_HNSW_AVX512_POPCNT_SOURCES}
PROPERTIES
COMPILE_OPTIONS "-mavx512f;-mavx512bw;-mavx512dq;-mavx512vpopcntdq;-mfma"
)

target_link_libraries(rabitqlib INTERFACE rabitqlib_runtime)
endif()
2 changes: 1 addition & 1 deletion thirdparty/RaBitQ-Library/RaBitQ-Library-0.1
Submodule RaBitQ-Library-0.1 updated 80 files
+3 −0 .gitignore
+75 −3 CMakeLists.txt
+4 −1 README.md
+9 −5 example.sh
+24 −0 example_py.sh
+4 −121 include/rabitqlib/fastscan/fastscan.hpp
+4 −202 include/rabitqlib/fastscan/highacc_fastscan.hpp
+94 −11 include/rabitqlib/index/estimator.hpp
+127 −85 include/rabitqlib/index/hnsw/hnsw.hpp
+3 −4 include/rabitqlib/index/ivf/initializer.hpp
+32 −7 include/rabitqlib/index/ivf/ivf.hpp
+9 −4 include/rabitqlib/index/query.hpp
+50 −0 include/rabitqlib/index/symqg/qg.hpp
+10 −227 include/rabitqlib/quantization/pack_excode.hpp
+3 −3 include/rabitqlib/quantization/rabitq_impl.hpp
+14 −0 include/rabitqlib/simd/dispatch.hpp
+36 −0 include/rabitqlib/simd/fastscan_dispatch.hpp
+29 −0 include/rabitqlib/simd/pack_excode_dispatch.hpp
+16 −0 include/rabitqlib/simd/rotator_dispatch.hpp
+44 −0 include/rabitqlib/simd/space_dispatch.hpp
+26 −0 include/rabitqlib/simd/warmup_dispatch.hpp
+7 −0 include/rabitqlib/utils/buffer.hpp
+19 −0 include/rabitqlib/utils/cpu_features.hpp
+2 −0 include/rabitqlib/utils/memory.hpp
+4 −103 include/rabitqlib/utils/rotator.hpp
+23 −761 include/rabitqlib/utils/space.hpp
+28 −183 include/rabitqlib/utils/warmup_space.hpp
+20 −0 pyproject.toml
+67 −0 python_bindings/CMakeLists.txt
+9 −0 python_bindings/__init__.py
+73 −0 python_bindings/bindings_common.hpp
+199 −0 python_bindings/hnsw_bindings.cpp
+181 −0 python_bindings/ivf_bindings.cpp
+31 −0 python_bindings/rabitq_bindings.cpp
+139 −0 python_bindings/symqg_bindings.cpp
+12 −0 sample/cpp/CMakeLists.txt
+0 −0 sample/cpp/hnsw_rabitq_indexing.cpp
+4 −17 sample/cpp/hnsw_rabitq_querying.cpp
+0 −0 sample/cpp/ivf_rabitq_indexing.cpp
+0 −0 sample/cpp/ivf_rabitq_querying.cpp
+0 −0 sample/cpp/quantizer.cpp
+0 −0 sample/cpp/symqg_indexing.cpp
+0 −0 sample/cpp/symqg_querying.cpp
+71 −0 sample/python/hnsw_rabitq_indexing.py
+67 −0 sample/python/hnsw_rabitq_querying.py
+62 −0 sample/python/ivf_rabitq_indexing.py
+69 −0 sample/python/ivf_rabitq_querying.py
+46 −0 sample/python/symqg_indexing.py
+67 −0 sample/python/symqg_querying.py
+77 −0 sample/python/utils.py
+32 −0 src/index/hnsw_search_avx2.cpp
+193 −0 src/index/hnsw_search_avx2_kernels.hpp
+33 −0 src/index/hnsw_search_avx512_core.cpp
+119 −0 src/index/hnsw_search_avx512_kernels.hpp
+32 −0 src/index/hnsw_search_avx512_popcnt.cpp
+362 −0 src/simd/dispatch.cpp
+171 −0 src/simd/fastscan_avx2.cpp
+190 −0 src/simd/fastscan_avx512.cpp
+31 −0 src/simd/pack_excode_avx2.cpp
+31 −0 src/simd/pack_excode_avx512.cpp
+237 −0 src/simd/pack_excode_kernels.hpp
+53 −0 src/simd/rotator_avx2.cpp
+67 −0 src/simd/rotator_avx512.cpp
+187 −0 src/simd/space_avx2.cpp
+145 −0 src/simd/space_avx512.cpp
+328 −0 src/simd/space_excode_avx2.cpp
+364 −0 src/simd/space_excode_avx512.cpp
+142 −0 src/simd/warmup_avx2.cpp
+77 −0 src/simd/warmup_avx512.cpp
+79 −0 src/utils/cpu_features.cpp
+1 −0 tests/.gitignore
+51 −0 tests/CMakeLists.txt
+74 −0 tests/README.md
+103 −0 tests/common/test_data.cpp
+58 −0 tests/common/test_data.hpp
+84 −0 tests/common/test_helpers.hpp
+142 −0 tests/integration/bit_pack_unpack_test.cpp
+11 −0 tests/unit/rabitqlib/utils/cpu_features_test.cpp
+77 −0 tests/unit/rabitqlib/utils/rotator_test.cpp
+156 −0 tests/unit/rabitqlib/utils/space_test.cpp
Loading