Skip to content

Commit d2eb3dd

Browse files
rfsalievethanglaseryuejiaointelahuber21mihaic
authored
Initial implementation of SVS Runtime package (#208)
Co-authored-by: ethanglaser <ethan.glaser@intel.com> Co-authored-by: yuejiaointel <yue.jiao@intel.com> Co-authored-by: Andreas Huber <9201869+ahuber21@users.noreply.github.com> Co-authored-by: ethanglaser <42726565+ethanglaser@users.noreply.github.com> Co-authored-by: Andreas Huber <andreas.huber@intel.com> Co-authored-by: Mihai Capotă <mihai@mihaic.ro>
1 parent 640ee6d commit d2eb3dd

29 files changed

+3618
-6
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Copyright 2025 Intel Corporation
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: Build and test C++ Runtime Bindings
16+
17+
on:
18+
push:
19+
branches:
20+
- main
21+
pull_request:
22+
23+
permissions:
24+
contents: read
25+
26+
# This allows a subsequently queued workflow run to interrupt previous runs
27+
concurrency:
28+
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
29+
cancel-in-progress: true
30+
31+
jobs:
32+
build-cpp-runtime-bindings:
33+
name: Build and unit tests for C++ runtime bindings
34+
runs-on: ubuntu-22.04
35+
strategy:
36+
matrix:
37+
include:
38+
- name: "with static library"
39+
enable_lvq_leanvec: "ON"
40+
suffix: ""
41+
- name: "public only"
42+
enable_lvq_leanvec: "OFF"
43+
suffix: "-public-only"
44+
fail-fast: false
45+
46+
steps:
47+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
48+
49+
- name: Build Docker image
50+
run: |
51+
docker build -t svs-manylinux228:latest -f docker/x86_64/manylinux228/Dockerfile .
52+
53+
- name: Build libraries in Docker container
54+
run: |
55+
docker run --rm \
56+
-v ${{ github.workspace }}:/workspace \
57+
-w /workspace \
58+
-e ENABLE_LVQ_LEANVEC=${{ matrix.enable_lvq_leanvec }} \
59+
-e SUFFIX=${{ matrix.suffix }} \
60+
svs-manylinux228:latest \
61+
/bin/bash -c "chmod +x docker/x86_64/build-cpp-runtime-bindings.sh && ./docker/x86_64/build-cpp-runtime-bindings.sh"
62+
63+
- name: Upload cpp runtime bindings artifacts
64+
uses: actions/upload-artifact@v4
65+
with:
66+
name: svs-cpp-runtime-bindings${{ matrix.suffix }}
67+
path: svs-cpp-runtime-bindings${{ matrix.suffix }}.tar.gz
68+
retention-days: 7 # Reduce retention due to size
69+
70+
# Run unit tests that were built as part of this job
71+
- name: Run unit tests in Docker container
72+
run: |
73+
docker run --rm \
74+
-v ${{ github.workspace }}:/workspace \
75+
-w /workspace \
76+
svs-manylinux228:latest \
77+
/bin/bash -c "source /etc/bashrc || true && ctest --test-dir bindings/cpp/build_cpp_bindings/tests --output-on-failure --verbose"
78+
79+
# Run full test script using the built artifacts
80+
test:
81+
name: Integration tests for C++ runtime
82+
needs: build-cpp-runtime-bindings
83+
runs-on: ubuntu-22.04
84+
strategy:
85+
matrix:
86+
include:
87+
- name: "with static library"
88+
suffix: ""
89+
- name: "public only"
90+
suffix: "-public-only"
91+
92+
steps:
93+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
94+
95+
- name: Build Docker image
96+
run: |
97+
docker build -t svs-manylinux228:latest -f docker/x86_64/manylinux228/Dockerfile .
98+
99+
# Need to download for a new job
100+
- name: Download shared libraries
101+
uses: actions/download-artifact@v4
102+
with:
103+
name: svs-cpp-runtime-bindings${{ matrix.suffix }}
104+
path: runtime_lib
105+
106+
- name: List available artifacts
107+
run: |
108+
ls -la runtime_lib/
109+
110+
- name: Test in Docker container
111+
run: |
112+
docker run --rm \
113+
-v ${{ github.workspace }}:/workspace \
114+
-v ${{ github.workspace }}/runtime_lib:/runtime_lib \
115+
-w /workspace \
116+
-e SUFFIX=${{ matrix.suffix }} \
117+
svs-manylinux228:latest \
118+
/bin/bash -c "chmod +x docker/x86_64/test-cpp-runtime-bindings.sh && ./docker/x86_64/test-cpp-runtime-bindings.sh"

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Build directories
2-
/build*/
2+
build/
3+
build-*/
4+
build_*/
35
usr/
46
wheelhouse/
57

bindings/cpp/CMakeLists.txt

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
# Copyright 2025 Intel Corporation
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
cmake_minimum_required(VERSION 3.21)
16+
project(svs_runtime VERSION 0.0.11 LANGUAGES CXX)
17+
set(TARGET_NAME svs_runtime)
18+
19+
set(SVS_RUNTIME_HEADERS
20+
include/svs/runtime/version.h
21+
include/svs/runtime/api_defs.h
22+
include/svs/runtime/training.h
23+
include/svs/runtime/vamana_index.h
24+
include/svs/runtime/dynamic_vamana_index.h
25+
include/svs/runtime/flat_index.h
26+
)
27+
28+
set(SVS_RUNTIME_SOURCES
29+
src/svs_runtime_utils.h
30+
src/dynamic_vamana_index_impl.h
31+
src/dynamic_vamana_index_leanvec_impl.h
32+
src/training_impl.h
33+
src/flat_index_impl.h
34+
src/api_defs.cpp
35+
src/training.cpp
36+
src/vamana_index.cpp
37+
src/dynamic_vamana_index.cpp
38+
src/flat_index.cpp
39+
)
40+
41+
option(SVS_RUNTIME_ENABLE_LVQ_LEANVEC "Enable compilation of SVS runtime with LVQ and LeanVec support" ON)
42+
if (SVS_RUNTIME_ENABLE_LVQ_LEANVEC)
43+
message(STATUS "SVS runtime will be built with LVQ support")
44+
else()
45+
message(STATUS "SVS runtime will be built without LVQ or LeanVec support")
46+
endif()
47+
48+
add_library(${TARGET_NAME} SHARED
49+
${SVS_RUNTIME_HEADERS}
50+
${SVS_RUNTIME_SOURCES}
51+
)
52+
53+
target_include_directories(${TARGET_NAME} PRIVATE
54+
${CMAKE_CURRENT_SOURCE_DIR}/include
55+
)
56+
57+
find_package(OpenMP REQUIRED)
58+
target_link_libraries(${TARGET_NAME} PUBLIC OpenMP::OpenMP_CXX)
59+
60+
target_compile_options(${TARGET_NAME} PRIVATE
61+
-DSVS_ENABLE_OMP=1
62+
-fvisibility=hidden
63+
)
64+
65+
if(UNIX AND NOT APPLE)
66+
# Don't export 3rd-party symbols from the lib
67+
target_link_options(${TARGET_NAME} PRIVATE "SHELL:-Wl,--exclude-libs,ALL")
68+
endif()
69+
70+
target_compile_features(${TARGET_NAME} INTERFACE cxx_std_20)
71+
set_target_properties(${TARGET_NAME} PROPERTIES PUBLIC_HEADER "${SVS_RUNTIME_HEADERS}")
72+
set_target_properties(${TARGET_NAME} PROPERTIES CXX_STANDARD 20)
73+
set_target_properties(${TARGET_NAME} PROPERTIES CXX_STANDARD_REQUIRED ON)
74+
set_target_properties(${TARGET_NAME} PROPERTIES CXX_EXTENSIONS OFF)
75+
set_target_properties(${TARGET_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} )
76+
77+
if (SVS_RUNTIME_ENABLE_LVQ_LEANVEC)
78+
if(DEFINED SVS_LVQ_HEADER AND DEFINED SVS_LEANVEC_HEADER)
79+
# expected that pre-defined headers are implementation headers
80+
message(STATUS "Using pre-defined LVQ header: ${SVS_LVQ_HEADER}")
81+
message(STATUS "Using pre-defined LeanVec header: ${SVS_LEANVEC_HEADER}")
82+
else()
83+
set(SVS_LVQ_HEADER "svs/extensions/vamana/lvq.h")
84+
set(SVS_LEANVEC_HEADER "svs/extensions/vamana/leanvec.h")
85+
endif()
86+
87+
if(RUNTIME_BINDINGS_PRIVATE_SOURCE_BUILD)
88+
message(STATUS "Building directly from private sources")
89+
target_link_libraries(${TARGET_NAME} PRIVATE
90+
svs::svs
91+
)
92+
link_mkl_static(${TARGET_NAME})
93+
elseif(TARGET svs::svs)
94+
message(FATAL_ERROR
95+
"Pre-built LVQ/LeanVec SVS library cannot be used in SVS main build. "
96+
"Please build SVS Runtime using bindings/cpp directory as CMake source root."
97+
)
98+
else()
99+
# Links to LTO-enabled static library, requires GCC/G++ 11.2
100+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11.2" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "11.3")
101+
set(SVS_URL "https://github.com/intel/ScalableVectorSearch/releases/download/v1.0.0-dev/svs-shared-library-1.0.0-NIGHTLY-20251119-807-lto.tar.gz"
102+
CACHE STRING "URL to download SVS shared library")
103+
else()
104+
message(WARNING
105+
"Pre-built LVQ/LeanVec SVS library requires GCC/G++ v.11.2 to apply LTO optimizations."
106+
"Current compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}"
107+
)
108+
set(SVS_URL "https://github.com/intel/ScalableVectorSearch/releases/download/v0.0.11/svs-shared-library-0.0.11.tar.gz"
109+
CACHE STRING "URL to download SVS shared library")
110+
endif()
111+
include(FetchContent)
112+
FetchContent_Declare(
113+
svs
114+
URL ${SVS_URL}
115+
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
116+
)
117+
FetchContent_MakeAvailable(svs)
118+
list(APPEND CMAKE_PREFIX_PATH "${svs_SOURCE_DIR}")
119+
find_package(svs REQUIRED)
120+
target_link_libraries(${TARGET_NAME} PRIVATE
121+
svs::svs
122+
svs::svs_compile_options
123+
svs::svs_static_library
124+
)
125+
endif()
126+
target_compile_definitions(${TARGET_NAME} PRIVATE
127+
PUBLIC "SVS_LVQ_HEADER=\"${SVS_LVQ_HEADER}\""
128+
PUBLIC "SVS_LEANVEC_HEADER=\"${SVS_LEANVEC_HEADER}\""
129+
)
130+
else()
131+
# Include the SVS library directly if needed.
132+
if (NOT TARGET svs::svs)
133+
add_subdirectory("../.." "${CMAKE_CURRENT_BINARY_DIR}/svs")
134+
endif()
135+
target_link_libraries(${TARGET_NAME} PRIVATE
136+
svs::svs
137+
svs_compile_options
138+
svs_x86_options_base
139+
)
140+
endif()
141+
142+
# installing
143+
include(GNUInstallDirs)
144+
145+
set(SVS_RUNTIME_EXPORT_NAME ${TARGET_NAME})
146+
set(VERSION_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/${SVS_RUNTIME_EXPORT_NAME}ConfigVersion.cmake")
147+
set(SVS_RUNTIME_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/svs_runtime)
148+
set(SVS_RUNTIME_COMPONENT_NAME "Runtime")
149+
150+
install(TARGETS ${TARGET_NAME}
151+
EXPORT ${SVS_RUNTIME_EXPORT_NAME}
152+
COMPONENT ${SVS_RUNTIME_COMPONENT_NAME}
153+
LIBRARY DESTINATION lib
154+
PUBLIC_HEADER DESTINATION include/svs/runtime
155+
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
156+
)
157+
158+
install(DIRECTORY include/svs/runtime
159+
COMPONENT ${SVS_RUNTIME_COMPONENT_NAME}
160+
DESTINATION include/svs
161+
FILES_MATCHING PATTERN "*.h"
162+
)
163+
164+
install(EXPORT ${SVS_RUNTIME_EXPORT_NAME}
165+
COMPONENT ${SVS_RUNTIME_COMPONENT_NAME}
166+
NAMESPACE svs::
167+
DESTINATION ${SVS_RUNTIME_CONFIG_INSTALL_DIR}
168+
)
169+
170+
include(CMakePackageConfigHelpers)
171+
configure_package_config_file(
172+
"${CMAKE_CURRENT_LIST_DIR}/runtimeConfig.cmake.in"
173+
"${CMAKE_CURRENT_BINARY_DIR}/${SVS_RUNTIME_EXPORT_NAME}Config.cmake"
174+
INSTALL_DESTINATION "${SVS_RUNTIME_CONFIG_INSTALL_DIR}"
175+
)
176+
177+
# Don't make compatibility guarantees until we reach a compatibility milestone.
178+
write_basic_package_version_file(
179+
${VERSION_CONFIG}
180+
VERSION ${PROJECT_VERSION}
181+
COMPATIBILITY ExactVersion
182+
)
183+
184+
install(FILES
185+
"${CMAKE_CURRENT_BINARY_DIR}/${SVS_RUNTIME_EXPORT_NAME}Config.cmake"
186+
"${VERSION_CONFIG}"
187+
COMPONENT ${SVS_RUNTIME_COMPONENT_NAME}
188+
DESTINATION "${SVS_RUNTIME_CONFIG_INSTALL_DIR}"
189+
)
190+
191+
# Build tests if requested
192+
if(SVS_BUILD_RUNTIME_TESTS)
193+
add_subdirectory(tests)
194+
endif()

0 commit comments

Comments
 (0)