Skip to content
Draft
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
25 changes: 22 additions & 3 deletions .github/workflows/build-cpp-runtime-bindings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ concurrency:
jobs:
build-cpp-runtime-bindings:
runs-on: ubuntu-22.04
strategy:
matrix:
include:
- name: "with static library"
enable_lvq_leanvec: "ON"
suffix: ""
- name: "public only"
enable_lvq_leanvec: "OFF"
suffix: "-public-only"

steps:
- uses: actions/checkout@v5
Expand All @@ -50,19 +59,28 @@ jobs:
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
-e ENABLE_LVQ_LEANVEC=${{ matrix.enable_lvq_leanvec }} \
-e SUFFIX=${{ matrix.suffix }} \
svs-manylinux228:latest \
/bin/bash -c "chmod +x docker/x86_64/build-cpp-runtime-bindings.sh && ./docker/x86_64/build-cpp-runtime-bindings.sh"

- name: Upload cpp runtime bindings artifacts
uses: actions/upload-artifact@v4
with:
name: svs-cpp-runtime-bindings
path: svs-cpp-runtime-bindings.tar.gz
name: svs-cpp-runtime-bindings${{ matrix.suffix }}
path: svs-cpp-runtime-bindings${{ matrix.suffix }}.tar.gz
retention-days: 7 # Reduce retention due to size

test:
needs: build-cpp-runtime-bindings
runs-on: ubuntu-22.04
strategy:
matrix:
include:
- name: "with static library"
suffix: ""
- name: "public only"
suffix: "-public-only"

steps:
- uses: actions/checkout@v5
Expand All @@ -75,7 +93,7 @@ jobs:
- name: Download shared libraries
uses: actions/download-artifact@v4
with:
name: svs-cpp-runtime-bindings
name: svs-cpp-runtime-bindings${{ matrix.suffix }}
path: runtime_lib

- name: List available artifacts
Expand All @@ -88,5 +106,6 @@ jobs:
-v ${{ github.workspace }}:/workspace \
-v ${{ github.workspace }}/runtime_lib:/runtime_lib \
-w /workspace \
-e SUFFIX=${{ matrix.suffix }} \
svs-manylinux228:latest \
/bin/bash -c "chmod +x docker/x86_64/test-cpp-runtime-bindings.sh && ./docker/x86_64/test-cpp-runtime-bindings.sh"
5 changes: 3 additions & 2 deletions bindings/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ set(TARGET_NAME svs_runtime)
set(SVS_RUNTIME_HEADERS
include/svs/runtime/version.h
include/svs/runtime/api_defs.h
include/svs/runtime/training.h
include/svs/runtime/vamana_index.h
include/svs/runtime/dynamic_vamana_index.h
include/svs/runtime/flat_index.h
Expand All @@ -30,7 +29,6 @@ set(SVS_RUNTIME_SOURCES
src/dynamic_vamana_index_impl.h
src/flat_index_impl.h
src/api_defs.cpp
src/training.cpp
src/vamana_index.cpp
src/dynamic_vamana_index.cpp
src/flat_index.cpp
Expand All @@ -39,6 +37,8 @@ set(SVS_RUNTIME_SOURCES
option(SVS_RUNTIME_ENABLE_LVQ_LEANVEC "Enable compilation of SVS runtime with LVQ and LeanVec support" ON)
if (SVS_RUNTIME_ENABLE_LVQ_LEANVEC)
message(STATUS "SVS runtime will be built with LVQ support")
list(APPEND SVS_RUNTIME_HEADERS include/svs/runtime/training.h)
list(APPEND SVS_RUNTIME_SOURCES src/training.cpp)
else()
message(STATUS "SVS runtime will be built without LVQ or LeanVec support")
endif()
Expand Down Expand Up @@ -129,6 +129,7 @@ DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
endif()
target_compile_definitions(${TARGET_NAME} PRIVATE
SVS_RUNTIME_ENABLE_LVQ_LEANVEC
PUBLIC "SVS_LVQ_HEADER=\"${SVS_LVQ_HEADER}\""
PUBLIC "SVS_LEANVEC_HEADER=\"${SVS_LEANVEC_HEADER}\""
)
Expand Down
8 changes: 4 additions & 4 deletions bindings/cpp/src/dynamic_vamana_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,11 @@
#include <svs/core/data.h>
#include <svs/core/distance.h>
#include <svs/core/query_result.h>
#include <svs/cpuid.h>
#include <svs/extensions/vamana/scalar.h>
#include <svs/lib/float16.h>
#include <svs/orchestrators/dynamic_vamana.h>
#include <svs/quantization/scalar/scalar.h>

#include SVS_LVQ_HEADER
#include SVS_LEANVEC_HEADER

namespace svs {
namespace runtime {

Expand Down Expand Up @@ -119,8 +115,10 @@ struct DynamicVamanaIndexManagerBase : public DynamicVamanaIndex {
};

using DynamicVamanaIndexManager = DynamicVamanaIndexManagerBase<DynamicVamanaIndexImpl>;
#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
using DynamicVamanaIndexLeanVecImplManager =
DynamicVamanaIndexManagerBase<DynamicVamanaIndexLeanVecImpl>;
#endif

} // namespace

Expand Down Expand Up @@ -176,6 +174,7 @@ Status DynamicVamanaIndex::load(
});
}

#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
// Specialization to build LeanVec-based Vamana index with specified leanvec dims
Status DynamicVamanaIndexLeanVec::build(
DynamicVamanaIndex** index,
Expand Down Expand Up @@ -215,6 +214,7 @@ Status DynamicVamanaIndexLeanVec::build(
*index = new DynamicVamanaIndexLeanVecImplManager{std::move(impl)};
});
}
#endif

} // namespace runtime
} // namespace svs
8 changes: 4 additions & 4 deletions bindings/cpp/src/dynamic_vamana_index_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
#pragma once

#include "svs_runtime_utils.h"
#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
#include "training_impl.h"
#endif

#include <svs/runtime/dynamic_vamana_index.h>

Expand All @@ -29,15 +31,11 @@
#include <svs/core/data.h>
#include <svs/core/distance.h>
#include <svs/core/query_result.h>
#include <svs/cpuid.h>
#include <svs/extensions/vamana/scalar.h>
#include <svs/lib/float16.h>
#include <svs/orchestrators/dynamic_vamana.h>
#include <svs/quantization/scalar/scalar.h>

#include SVS_LVQ_HEADER
#include SVS_LEANVEC_HEADER

namespace svs {
namespace runtime {

Expand Down Expand Up @@ -496,6 +494,7 @@ class DynamicVamanaIndexImpl {
size_t ntotal_soft_deleted{0};
};

#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
struct DynamicVamanaIndexLeanVecImpl : public DynamicVamanaIndexImpl {
DynamicVamanaIndexLeanVecImpl(
std::unique_ptr<svs::DynamicVamana>&& impl,
Expand Down Expand Up @@ -596,6 +595,7 @@ struct DynamicVamanaIndexLeanVecImpl : public DynamicVamanaIndexImpl {
return kind;
}
};
#endif

} // namespace runtime
} // namespace svs
1 change: 0 additions & 1 deletion bindings/cpp/src/flat_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include <svs/core/data.h>
#include <svs/core/distance.h>
#include <svs/core/query_result.h>
#include <svs/cpuid.h>
#include <svs/extensions/vamana/scalar.h>

namespace svs {
Expand Down
22 changes: 20 additions & 2 deletions bindings/cpp/src/svs_runtime_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@
#include <svs/core/data.h>
#include <svs/core/distance.h>
#include <svs/core/query_result.h>
#include <svs/cpuid.h>
#include <svs/extensions/vamana/scalar.h>
#include <svs/lib/exception.h>
#include <svs/lib/float16.h>
#include <svs/orchestrators/dynamic_vamana.h>
#include <svs/quantization/scalar/scalar.h>

#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
#ifndef SVS_LVQ_HEADER
#define SVS_LVQ_HEADER "svs/quantization/lvq/lvq.h"
#endif
Expand All @@ -49,6 +49,8 @@

#include SVS_LVQ_HEADER
#include SVS_LEANVEC_HEADER
#include <svs/cpuid.h>
#endif

namespace svs::runtime {

Expand Down Expand Up @@ -92,7 +94,9 @@ inline auto runtime_error_wrapper(Callable&& func) noexcept -> Status {
}
}

#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
using LeanVecMatricesType = svs::leanvec::LeanVecMatrices<svs::Dynamic>;
#endif

namespace storage {

Expand All @@ -105,6 +109,7 @@ inline constexpr bool is_simple_dataset<svs::data::SimpleData<Elem, Extent, Allo
template <typename T>
concept IsSimpleDataset = is_simple_dataset<T>;

#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
// Consolidated storage kind checks using constexpr functions
inline constexpr bool is_lvq_storage(StorageKind kind) {
return kind == StorageKind::LVQ4x0 || kind == StorageKind::LVQ4x4 ||
Expand All @@ -115,6 +120,7 @@ inline constexpr bool is_leanvec_storage(StorageKind kind) {
return kind == StorageKind::LeanVec4x4 || kind == StorageKind::LeanVec4x8 ||
kind == StorageKind::LeanVec8x8;
}
#endif

// Storage kind processing
// Most kinds map to std::byte storage, but some have specific element types.
Expand All @@ -129,12 +135,14 @@ template <StorageKind K> struct StorageKindTag {
SVS_DEFINE_STORAGE_KIND_TAG(FP32);
SVS_DEFINE_STORAGE_KIND_TAG(FP16);
SVS_DEFINE_STORAGE_KIND_TAG(SQI8);
#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
SVS_DEFINE_STORAGE_KIND_TAG(LVQ4x0);
SVS_DEFINE_STORAGE_KIND_TAG(LVQ4x4);
SVS_DEFINE_STORAGE_KIND_TAG(LVQ4x8);
SVS_DEFINE_STORAGE_KIND_TAG(LeanVec4x4);
SVS_DEFINE_STORAGE_KIND_TAG(LeanVec4x8);
SVS_DEFINE_STORAGE_KIND_TAG(LeanVec8x8);
#endif

#undef SVS_DEFINE_STORAGE_KIND_TAG

Expand All @@ -153,6 +161,7 @@ template <typename T>
using SQDatasetType = svs::quantization::scalar::
SQDataset<T, svs::Dynamic, svs::data::Blocked<svs::lib::Allocator<T>>>;

#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
template <size_t Primary, size_t Residual>
using LVQDatasetType = svs::quantization::lvq::LVQDataset<
Primary,
Expand All @@ -168,6 +177,7 @@ using LeanDatasetType = svs::leanvec::LeanDataset<
svs::Dynamic,
svs::Dynamic,
svs::data::Blocked<svs::lib::Allocator<std::byte>>>;
#endif

// Storage type mapping - use macro to reduce repetition
template <StorageTag Tag> struct StorageType;
Expand All @@ -181,12 +191,14 @@ template <StorageTag Tag> using StorageType_t = typename StorageType<Tag>::type;
DEFINE_STORAGE_TYPE(FP32, SimpleDatasetType<float>);
DEFINE_STORAGE_TYPE(FP16, SimpleDatasetType<svs::Float16>);
DEFINE_STORAGE_TYPE(SQI8, SQDatasetType<std::int8_t>);
#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
DEFINE_STORAGE_TYPE(LVQ4x0, LVQDatasetType<4, 0>);
DEFINE_STORAGE_TYPE(LVQ4x4, LVQDatasetType<4, 4>);
DEFINE_STORAGE_TYPE(LVQ4x8, LVQDatasetType<4, 8>);
DEFINE_STORAGE_TYPE(LeanVec4x4, LeanDatasetType<4, 4>);
DEFINE_STORAGE_TYPE(LeanVec4x8, LeanDatasetType<4, 8>);
DEFINE_STORAGE_TYPE(LeanVec8x8, LeanDatasetType<8, 8>);
#endif

#undef DEFINE_STORAGE_TYPE

Expand All @@ -211,6 +223,7 @@ SQStorageType make_storage(const svs::data::ConstSimpleDataView<float>& data, Po
return SQStorageType::compress(data, pool);
}

#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
template <
svs::quantization::lvq::IsLVQDataset LVQStorageType,
svs::threads::ThreadPool Pool>
Expand All @@ -232,16 +245,19 @@ LeanVecStorageType make_storage(
data, std::move(matrices), pool, 0, svs::lib::MaybeStatic{leanvec_d}
);
}
#endif

template <StorageTag Tag, typename... Args>
auto make_storage(Tag&& SVS_UNUSED(tag), Args&&... args) {
return make_storage<StorageType_t<Tag>>(std::forward<Args>(args)...);
}

inline bool is_supported_storage_kind(StorageKind kind) {
inline bool is_supported_storage_kind([[maybe_unused]] StorageKind kind) {
#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
if (is_lvq_storage(kind) || is_leanvec_storage(kind)) {
return svs::detail::lvq_leanvec_enabled();
}
#endif
return true;
}

Expand All @@ -259,6 +275,7 @@ auto dispatch_storage_kind(StorageKind kind, F&& f, Args&&... args) {
return f(FP16Tag{}, std::forward<Args>(args)...);
case StorageKind::SQI8:
return f(SQI8Tag{}, std::forward<Args>(args)...);
#ifdef SVS_RUNTIME_ENABLE_LVQ_LEANVEC
case StorageKind::LVQ4x0:
return f(LVQ4x0Tag{}, std::forward<Args>(args)...);
case StorageKind::LVQ4x4:
Expand All @@ -271,6 +288,7 @@ auto dispatch_storage_kind(StorageKind kind, F&& f, Args&&... args) {
return f(LeanVec4x8Tag{}, std::forward<Args>(args)...);
case StorageKind::LeanVec8x8:
return f(LeanVec8x8Tag{}, std::forward<Args>(args)...);
#endif
default:
throw ANNEXCEPTION("not supported SVS storage kind");
}
Expand Down
4 changes: 2 additions & 2 deletions docker/x86_64/build-cpp-runtime-bindings.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ mkdir -p /workspace/bindings/cpp/build_cpp_bindings /workspace/install_cpp_bindi

# Build and install runtime bindings library
cd /workspace/bindings/cpp/build_cpp_bindings
CC=gcc CXX=g++ cmake .. -DCMAKE_INSTALL_PREFIX=/workspace/install_cpp_bindings -DCMAKE_INSTALL_LIBDIR=lib
CC=gcc CXX=g++ cmake .. -DCMAKE_INSTALL_PREFIX=/workspace/install_cpp_bindings -DCMAKE_INSTALL_LIBDIR=lib -DSVS_RUNTIME_ENABLE_LVQ_LEANVEC=${ENABLE_LVQ_LEANVEC:-ON}
cmake --build . -j
cmake --install .

# Create tarball with symlink for compatibility
cd /workspace/install_cpp_bindings && \
ln -s lib lib64 && \
tar -czvf /workspace/svs-cpp-runtime-bindings.tar.gz .
tar -czvf /workspace/svs-cpp-runtime-bindings${SUFFIX}.tar.gz .
2 changes: 1 addition & 1 deletion docker/x86_64/test-cpp-runtime-bindings.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ conda install -y mkl=2022.2.1 mkl-devel=2022.2.1
# TODO: point to root repo eventually
git clone -b svs-io https://github.com/ahuber21/faiss.git
cd faiss
sed -i "s|set(SVS_URL .*|set(SVS_URL \"file:///runtime_lib/svs-cpp-runtime-bindings${PLATFORM_NAME}.tar.gz\" CACHE STRING \"SVS URL\")|" faiss/CMakeLists.txt
sed -i "s|set(SVS_URL .*|set(SVS_URL \"file:///runtime_lib/svs-cpp-runtime-bindings${SUFFIX}.tar.gz\" CACHE STRING \"SVS URL\")|" faiss/CMakeLists.txt

echo "================================================"
echo " Runnning validation of library against FAISS CI"
Expand Down
Loading