usearch 2.6.1 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/. npmignore +14 -0
- package/.cmake-format.py +19 -0
- package/.github/workflows/Dockerfile.libs +3 -3
- package/.github/workflows/prerelease.yml +85 -64
- package/.github/workflows/release.yml +18 -16
- package/.gitignore +1 -1
- package/.vscode/launch.json +47 -14
- package/.vscode/settings.json +7 -0
- package/.vscode/tasks.json +44 -8
- package/CITATION.cff +1 -1
- package/CMakeLists.txt +218 -67
- package/Cargo.toml +1 -1
- package/README.md +1 -1
- package/binding.gyp +3 -2
- package/build.gradle +19 -10
- package/c/CMakeLists.txt +21 -48
- package/c/README.md +5 -5
- package/c/lib.cpp +52 -7
- package/c/test.c +137 -94
- package/c/usearch.h +42 -0
- package/cmake/clipp.cmake +0 -1
- package/cmake/jemalloc.cmake +21 -37
- package/conanfile.py +1 -1
- package/cpp/CMakeLists.txt +14 -123
- package/cpp/bench.cpp +0 -12
- package/cpp/test.cpp +29 -1
- package/csharp/nuget/nuget-package.props +1 -1
- package/docs/compilation.md +23 -16
- package/docs/conf.py +1 -1
- package/golang/README.md +52 -51
- package/golang/lib.go +1 -1
- package/golang/lib_test.go +4 -1
- package/include/usearch/index.hpp +2 -2
- package/include/usearch/index_plugins.hpp +345 -160
- package/javascript/lib.cpp +204 -250
- package/javascript/usearch.js +440 -2
- package/javascript/usearch.test.js +37 -0
- package/package.json +10 -5
- package/python/lib.cpp +96 -225
- package/python/scripts/bench_exact.py +2 -2
- package/python/scripts/test_jit.py +2 -13
- package/python/scripts/test_sparse.py +1 -1
- package/python/scripts/test_tooling.py +26 -5
- package/rust/lib.cpp +12 -4
- package/rust/lib.hpp +7 -0
- package/rust/lib.rs +170 -10
- package/setup.py +14 -4
- package/wasm/CMakeLists.txt +4 -12
- package/wasm/lib.cpp +1 -1
- package/wasmer.toml +1 -1
- package/javascript/docs.js +0 -111
- package/javascript/test.js +0 -32
- package/javascript/usearch.d.ts +0 -110
- package/tsconfig.json +0 -8
package/CMakeLists.txt
CHANGED
|
@@ -1,21 +1,31 @@
|
|
|
1
1
|
# This CMake file is heavily inspired by following `usearch` CMake:
|
|
2
2
|
# https://github.com/nlohmann/json/blob/develop/CMakeLists.txt
|
|
3
3
|
cmake_minimum_required(VERSION 3.1)
|
|
4
|
-
project(
|
|
4
|
+
project(
|
|
5
|
+
usearch
|
|
6
|
+
VERSION 0.6.0
|
|
7
|
+
LANGUAGES C CXX
|
|
8
|
+
)
|
|
5
9
|
|
|
6
10
|
# Determine if USearch is built as a subproject (using `add_subdirectory`) or if it is the main project
|
|
7
11
|
set(USEARCH_IS_MAIN_PROJECT OFF)
|
|
8
12
|
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
|
9
13
|
set(USEARCH_IS_MAIN_PROJECT ON)
|
|
10
|
-
endif()
|
|
14
|
+
endif ()
|
|
11
15
|
|
|
12
16
|
# Options
|
|
13
17
|
option(USEARCH_INSTALL "Install CMake targets" OFF)
|
|
14
|
-
|
|
15
|
-
option(
|
|
18
|
+
|
|
19
|
+
option(USEARCH_USE_OPENMP "Use OpenMP for a thread pool" OFF)
|
|
20
|
+
option(USEARCH_USE_SIMSIMD "Use SimSIMD hardware-accelerated metrics" OFF)
|
|
21
|
+
option(USEARCH_USE_JEMALLOC "Use JeMalloc for faster memory allocations" OFF)
|
|
22
|
+
option(USEARCH_USE_NATIVE_F16 "Use native half-precision types" OFF)
|
|
23
|
+
|
|
24
|
+
option(USEARCH_BUILD_TEST_CPP "Compile a native unit test in C++" ${USEARCH_IS_MAIN_PROJECT})
|
|
25
|
+
option(USEARCH_BUILD_BENCH_CPP "Compile a native benchmark in C++" ${USEARCH_IS_MAIN_PROJECT})
|
|
26
|
+
option(USEARCH_BUILD_LIB_C "Compile a native library for the C 99 interface" OFF)
|
|
27
|
+
option(USEARCH_BUILD_TEST_C "Compile a test for the C 99 interface" OFF)
|
|
16
28
|
option(USEARCH_BUILD_WOLFRAM "Compile Wolfram Language bindings" OFF)
|
|
17
|
-
option(USEARCH_BUILD_CLIB "Compile a native library for the C 99 interface" OFF)
|
|
18
|
-
option(USEARCH_BUILD_CTEST "Compile a test for the C 99 interface" OFF)
|
|
19
29
|
|
|
20
30
|
# Includes
|
|
21
31
|
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
|
|
@@ -28,17 +38,19 @@ endif ()
|
|
|
28
38
|
|
|
29
39
|
# Configuration
|
|
30
40
|
include(GNUInstallDirs)
|
|
31
|
-
set(USEARCH_TARGET_NAME
|
|
32
|
-
set(USEARCH_CONFIG_INSTALL_DIR
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
set(
|
|
41
|
+
set(USEARCH_TARGET_NAME ${PROJECT_NAME})
|
|
42
|
+
set(USEARCH_CONFIG_INSTALL_DIR
|
|
43
|
+
"${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}"
|
|
44
|
+
CACHE INTERNAL ""
|
|
45
|
+
)
|
|
46
|
+
set(USEARCH_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}")
|
|
47
|
+
set(USEARCH_TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
|
|
48
|
+
set(USEARCH_CMAKE_CONFIG_TEMPLATE "cmake/config.cmake.in")
|
|
49
|
+
set(USEARCH_CMAKE_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
|
37
50
|
set(USEARCH_CMAKE_VERSION_CONFIG_FILE "${USEARCH_CMAKE_CONFIG_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
|
|
38
51
|
set(USEARCH_CMAKE_PROJECT_CONFIG_FILE "${USEARCH_CMAKE_CONFIG_DIR}/${PROJECT_NAME}Config.cmake")
|
|
39
52
|
set(USEARCH_CMAKE_PROJECT_TARGETS_FILE "${USEARCH_CMAKE_CONFIG_DIR}/${PROJECT_NAME}Targets.cmake")
|
|
40
|
-
set(USEARCH_PKGCONFIG_INSTALL_DIR
|
|
41
|
-
|
|
53
|
+
set(USEARCH_PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/pkgconfig")
|
|
42
54
|
|
|
43
55
|
# Define our header-only library
|
|
44
56
|
add_library(${USEARCH_TARGET_NAME} INTERFACE)
|
|
@@ -46,66 +58,42 @@ add_library(${PROJECT_NAME}::${USEARCH_TARGET_NAME} ALIAS ${USEARCH_TARGET_NAME}
|
|
|
46
58
|
set(USEARCH_INCLUDE_BUILD_DIR "${PROJECT_SOURCE_DIR}/include/")
|
|
47
59
|
if (${CMAKE_VERSION} VERSION_LESS "3.8.0")
|
|
48
60
|
target_compile_features(${USEARCH_TARGET_NAME} INTERFACE cxx_range_for)
|
|
49
|
-
else()
|
|
61
|
+
else ()
|
|
50
62
|
target_compile_features(${USEARCH_TARGET_NAME} INTERFACE cxx_std_11)
|
|
51
|
-
endif()
|
|
63
|
+
endif ()
|
|
52
64
|
|
|
53
65
|
# Core compilation settings affecting "index.hpp"
|
|
54
66
|
target_compile_definitions(
|
|
55
|
-
${USEARCH_TARGET_NAME}
|
|
56
|
-
INTERFACE
|
|
57
|
-
$<$<NOT:$<BOOL:${JSON_GlobalUDLs}>>:USEARCH_USE_OPENMP=0>
|
|
67
|
+
${USEARCH_TARGET_NAME} INTERFACE $<$<NOT:$<BOOL:${USEARCH_USE_OPENMP}>>:USEARCH_USE_OPENMP=0>
|
|
58
68
|
)
|
|
59
69
|
|
|
60
70
|
# Supplementary compilation settings affecting "index_plugins.hpp"
|
|
61
71
|
target_compile_definitions(
|
|
62
|
-
${USEARCH_TARGET_NAME}
|
|
63
|
-
INTERFACE
|
|
64
|
-
$<$<NOT:$<BOOL:${JSON_GlobalUDLs}>>:USEARCH_USE_NATIVE_F16=0>
|
|
72
|
+
${USEARCH_TARGET_NAME} INTERFACE $<$<NOT:$<BOOL:${USEARCH_USE_NATIVE_F16}>>:USEARCH_USE_NATIVE_F16=0>
|
|
65
73
|
)
|
|
66
74
|
|
|
67
75
|
target_compile_definitions(
|
|
68
|
-
${USEARCH_TARGET_NAME}
|
|
69
|
-
INTERFACE
|
|
70
|
-
$<$<NOT:$<BOOL:${JSON_GlobalUDLs}>>:USEARCH_USE_SIMSIMD=0>
|
|
76
|
+
${USEARCH_TARGET_NAME} INTERFACE $<$<NOT:$<BOOL:${USEARCH_USE_SIMSIMD}>>:USEARCH_USE_SIMSIMD=0>
|
|
71
77
|
)
|
|
72
78
|
|
|
73
79
|
target_include_directories(
|
|
74
|
-
${USEARCH_TARGET_NAME}
|
|
75
|
-
|
|
76
|
-
$<BUILD_INTERFACE:${USEARCH_INCLUDE_BUILD_DIR}>
|
|
77
|
-
$<INSTALL_INTERFACE:include>
|
|
80
|
+
${USEARCH_TARGET_NAME} ${USEARCH_SYSTEM_INCLUDE} INTERFACE $<BUILD_INTERFACE:${USEARCH_INCLUDE_BUILD_DIR}>
|
|
81
|
+
$<INSTALL_INTERFACE:include>
|
|
78
82
|
)
|
|
79
83
|
|
|
80
84
|
# Install a pkg-config file, so other tools can find this
|
|
81
|
-
configure_file(
|
|
82
|
-
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkg-config.pc.in"
|
|
83
|
-
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
|
|
84
|
-
)
|
|
85
|
+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkg-config.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc")
|
|
85
86
|
|
|
86
|
-
# Install a custom package version config file instead of
|
|
87
|
-
#
|
|
88
|
-
# https://github.com/nlohmann/json/issues/1697
|
|
87
|
+
# Install a custom package version config file instead of write_basic_package_version_file to ensure that it's
|
|
88
|
+
# architecture-independent https://github.com/nlohmann/json/issues/1697
|
|
89
89
|
include(CMakePackageConfigHelpers)
|
|
90
|
-
configure_file(
|
|
91
|
-
|
|
92
|
-
${USEARCH_CMAKE_VERSION_CONFIG_FILE}
|
|
93
|
-
@ONLY
|
|
94
|
-
)
|
|
95
|
-
configure_file(
|
|
96
|
-
${USEARCH_CMAKE_CONFIG_TEMPLATE}
|
|
97
|
-
${USEARCH_CMAKE_PROJECT_CONFIG_FILE}
|
|
98
|
-
@ONLY
|
|
99
|
-
)
|
|
90
|
+
configure_file("cmake/usearchConfigVersion.cmake.in" ${USEARCH_CMAKE_VERSION_CONFIG_FILE} @ONLY)
|
|
91
|
+
configure_file(${USEARCH_CMAKE_CONFIG_TEMPLATE} ${USEARCH_CMAKE_PROJECT_CONFIG_FILE} @ONLY)
|
|
100
92
|
|
|
101
|
-
if(USEARCH_INSTALL)
|
|
102
|
-
install(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
)
|
|
106
|
-
install(
|
|
107
|
-
FILES ${USEARCH_CMAKE_PROJECT_CONFIG_FILE} ${USEARCH_CMAKE_VERSION_CONFIG_FILE}
|
|
108
|
-
DESTINATION ${USEARCH_CONFIG_INSTALL_DIR}
|
|
93
|
+
if (USEARCH_INSTALL)
|
|
94
|
+
install(DIRECTORY ${USEARCH_INCLUDE_BUILD_DIR} DESTINATION ${USEARCH_INCLUDE_INSTALL_DIR})
|
|
95
|
+
install(FILES ${USEARCH_CMAKE_PROJECT_CONFIG_FILE} ${USEARCH_CMAKE_VERSION_CONFIG_FILE}
|
|
96
|
+
DESTINATION ${USEARCH_CONFIG_INSTALL_DIR}
|
|
109
97
|
)
|
|
110
98
|
export(
|
|
111
99
|
TARGETS ${USEARCH_TARGET_NAME}
|
|
@@ -115,31 +103,194 @@ if(USEARCH_INSTALL)
|
|
|
115
103
|
install(
|
|
116
104
|
TARGETS ${USEARCH_TARGET_NAME}
|
|
117
105
|
EXPORT ${USEARCH_TARGETS_EXPORT_NAME}
|
|
118
|
-
INCLUDES
|
|
106
|
+
INCLUDES
|
|
107
|
+
DESTINATION ${USEARCH_INCLUDE_INSTALL_DIR}
|
|
119
108
|
)
|
|
120
109
|
install(
|
|
121
110
|
EXPORT ${USEARCH_TARGETS_EXPORT_NAME}
|
|
122
111
|
NAMESPACE ${PROJECT_NAME}::
|
|
123
112
|
DESTINATION ${USEARCH_CONFIG_INSTALL_DIR}
|
|
124
113
|
)
|
|
125
|
-
install(
|
|
126
|
-
|
|
127
|
-
|
|
114
|
+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" DESTINATION ${USEARCH_PKGCONFIG_INSTALL_DIR})
|
|
115
|
+
endif ()
|
|
116
|
+
|
|
117
|
+
# Find required packages
|
|
118
|
+
if (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
|
|
119
|
+
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
|
|
120
|
+
set(CMAKE_HAVE_THREADS_LIBRARY 1)
|
|
121
|
+
set(CMAKE_USE_WIN32_THREADS_INIT 0)
|
|
122
|
+
set(CMAKE_USE_PTHREADS_INIT 1)
|
|
123
|
+
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
|
124
|
+
endif ()
|
|
125
|
+
find_package(Threads REQUIRED)
|
|
126
|
+
|
|
127
|
+
if (USEARCH_USE_OPENMP)
|
|
128
|
+
find_package(OpenMP REQUIRED)
|
|
129
|
+
endif ()
|
|
130
|
+
|
|
131
|
+
if (USEARCH_USE_JEMALLOC)
|
|
132
|
+
include(jemalloc)
|
|
133
|
+
endif ()
|
|
134
|
+
|
|
135
|
+
# Set default build type to Release
|
|
136
|
+
if (NOT CMAKE_BUILD_TYPE)
|
|
137
|
+
set(CMAKE_BUILD_TYPE RelWithDebInfo)
|
|
138
|
+
endif ()
|
|
139
|
+
|
|
140
|
+
# Include directories
|
|
141
|
+
set(USEARCH_HEADER_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/fp16/include"
|
|
142
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/simsimd/include"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Function to setup target
|
|
146
|
+
function (setup_target TARGET_NAME)
|
|
147
|
+
# Compiler-specific options List of all possible compiler IDs:
|
|
148
|
+
# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html
|
|
149
|
+
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
150
|
+
target_compile_options(
|
|
151
|
+
${TARGET_NAME}
|
|
152
|
+
PRIVATE $<$<CONFIG:RELEASE>:-O3>
|
|
153
|
+
$<$<CONFIG:RELWITHDEBINFO>:-O3
|
|
154
|
+
-g>
|
|
155
|
+
$<$<CONFIG:DEBUG>:-g
|
|
156
|
+
-fsanitize=address
|
|
157
|
+
-fsanitize=leak
|
|
158
|
+
-fsanitize=alignment
|
|
159
|
+
-fsanitize=undefined
|
|
160
|
+
>
|
|
161
|
+
-ffast-math
|
|
162
|
+
-fPIC
|
|
163
|
+
-Wall
|
|
164
|
+
-Wextra
|
|
165
|
+
-Wno-conversion
|
|
166
|
+
-Wno-unknown-pragmas
|
|
167
|
+
-march=native
|
|
168
|
+
-fmax-errors=1
|
|
169
|
+
-pedantic
|
|
170
|
+
-fdiagnostics-color=always
|
|
171
|
+
-ftime-report
|
|
172
|
+
)
|
|
173
|
+
target_link_options(
|
|
174
|
+
${TARGET_NAME}
|
|
175
|
+
PRIVATE
|
|
176
|
+
$<$<CONFIG:DEBUG>:-g
|
|
177
|
+
-fsanitize=address
|
|
178
|
+
-fsanitize=leak
|
|
179
|
+
-fsanitize=alignment
|
|
180
|
+
-fsanitize=undefined
|
|
181
|
+
>
|
|
182
|
+
-fPIC
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
if (USEARCH_USE_OPENMP)
|
|
186
|
+
target_link_libraries(${TARGET_NAME} PRIVATE OpenMP::OpenMP_CXX)
|
|
187
|
+
endif ()
|
|
188
|
+
|
|
189
|
+
if (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
|
|
190
|
+
target_link_libraries(${TARGET_NAME} PRIVATE Threads::Threads)
|
|
191
|
+
endif ()
|
|
192
|
+
|
|
193
|
+
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
194
|
+
target_compile_options(
|
|
195
|
+
${TARGET_NAME}
|
|
196
|
+
PRIVATE $<$<CONFIG:RELEASE>:-O3>
|
|
197
|
+
$<$<CONFIG:RELWITHDEBINFO>:-O3
|
|
198
|
+
-g>
|
|
199
|
+
$<$<CONFIG:DEBUG>:-g
|
|
200
|
+
-fsanitize=address
|
|
201
|
+
-fsanitize=alignment
|
|
202
|
+
-fsanitize=undefined
|
|
203
|
+
>
|
|
204
|
+
-ffast-math
|
|
205
|
+
-fPIC
|
|
206
|
+
-pedantic
|
|
207
|
+
-Wfatal-errors
|
|
208
|
+
# Don't complain if the for-loops were not vectorzied
|
|
209
|
+
-Wpass-failed=transform-warning
|
|
210
|
+
-fcolor-diagnostics
|
|
211
|
+
-ftime-trace
|
|
212
|
+
)
|
|
213
|
+
target_link_options(
|
|
214
|
+
${TARGET_NAME}
|
|
215
|
+
PRIVATE
|
|
216
|
+
$<$<CONFIG:DEBUG>:-g
|
|
217
|
+
-fsanitize=address
|
|
218
|
+
-fsanitize=alignment
|
|
219
|
+
-fsanitize=undefined
|
|
220
|
+
>
|
|
221
|
+
-fPIC
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
# Check if the compiler is AppleClang, and if not, add the leak sanitizer
|
|
225
|
+
if (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
|
|
226
|
+
# It's likely AppleClang Adjust options as needed for AppleClang
|
|
227
|
+
else ()
|
|
228
|
+
# It's likely LLVM Clang
|
|
229
|
+
target_compile_options(${TARGET_NAME} PRIVATE $<$<CONFIG:DEBUG>:-fsanitize=leak>)
|
|
230
|
+
target_link_options(${TARGET_NAME} PRIVATE $<$<CONFIG:DEBUG>:-fsanitize=leak>)
|
|
231
|
+
endif ()
|
|
232
|
+
|
|
233
|
+
if (USEARCH_USE_OPENMP)
|
|
234
|
+
target_link_libraries(${TARGET_NAME} PRIVATE OpenMP::OpenMP_CXX)
|
|
235
|
+
endif ()
|
|
236
|
+
|
|
237
|
+
if (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
|
|
238
|
+
target_link_libraries(
|
|
239
|
+
${TARGET_NAME} PRIVATE "-framework CoreFoundation" "-framework Security" Threads::Threads
|
|
240
|
+
)
|
|
241
|
+
else ()
|
|
242
|
+
target_link_libraries(${TARGET_NAME} PRIVATE Threads::Threads)
|
|
243
|
+
endif ()
|
|
244
|
+
|
|
245
|
+
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "NVIDIA" OR CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC")
|
|
246
|
+
target_compile_options(${TARGET_NAME} PRIVATE $<$<CONFIG:RELEASE>:-O3>)
|
|
247
|
+
target_compile_definitions(${TARGET_NAME} PRIVATE --expt-relaxed-constexpr --extended-lambda)
|
|
248
|
+
set_property(SOURCE bench.cpp PROPERTY LANGUAGE CUDA)
|
|
249
|
+
set_target_properties(${TARGET_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
|
250
|
+
set_target_properties(${TARGET_NAME} PROPERTIES CUDA_ARCHITECTURES "86")
|
|
251
|
+
|
|
252
|
+
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
|
|
253
|
+
target_compile_options(${TARGET_NAME} PRIVATE -w -ferror-limit=1)
|
|
254
|
+
|
|
255
|
+
elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
|
256
|
+
target_compile_options(
|
|
257
|
+
${TARGET_NAME} PRIVATE $<$<CONFIG:DEBUG>:/DEBUG> $<$<CONFIG:RELEASE>:/O2> $<$<CONFIG:RELWITHDEBINFO>:/O2
|
|
258
|
+
/DEBUG>
|
|
259
|
+
)
|
|
260
|
+
endif ()
|
|
261
|
+
|
|
262
|
+
target_include_directories(${TARGET_NAME} PRIVATE ${USEARCH_HEADER_INCLUDES})
|
|
263
|
+
set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR})
|
|
264
|
+
set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR})
|
|
265
|
+
set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
|
266
|
+
set_target_properties(${TARGET_NAME} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
|
267
|
+
set_target_properties(${TARGET_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
|
268
|
+
set_target_properties(${TARGET_NAME} PROPERTIES CXX_STANDARD 17)
|
|
269
|
+
|
|
270
|
+
# Core compilation settings affecting "index.hpp"
|
|
271
|
+
target_compile_definitions(${TARGET_NAME} PRIVATE $<$<NOT:$<BOOL:${USEARCH_USE_OPENMP}>>:USEARCH_USE_OPENMP=0>)
|
|
272
|
+
|
|
273
|
+
# Supplementary compilation settings affecting "index_plugins.hpp"
|
|
274
|
+
target_compile_definitions(
|
|
275
|
+
${TARGET_NAME} PRIVATE $<$<NOT:$<BOOL:${USEARCH_USE_NATIVE_F16}>>:USEARCH_USE_NATIVE_F16=0>
|
|
128
276
|
)
|
|
129
|
-
endif()
|
|
130
277
|
|
|
131
|
-
|
|
278
|
+
target_compile_definitions(${TARGET_NAME} PRIVATE $<$<NOT:$<BOOL:${USEARCH_USE_SIMSIMD}>>:USEARCH_USE_SIMSIMD=0>)
|
|
279
|
+
|
|
280
|
+
endfunction ()
|
|
281
|
+
|
|
282
|
+
if (${USEARCH_BUILD_TEST_CPP} OR ${USEARCH_BUILD_BENCH_CPP})
|
|
132
283
|
add_subdirectory(cpp)
|
|
133
|
-
endif()
|
|
284
|
+
endif ()
|
|
134
285
|
|
|
135
|
-
if(${USEARCH_BUILD_WOLFRAM})
|
|
286
|
+
if (${USEARCH_BUILD_WOLFRAM})
|
|
136
287
|
add_subdirectory(wolfram)
|
|
137
|
-
endif()
|
|
288
|
+
endif ()
|
|
138
289
|
|
|
139
|
-
if(${USEARCH_BUILD_WASM})
|
|
290
|
+
if (${USEARCH_BUILD_WASM})
|
|
140
291
|
add_subdirectory(wasm)
|
|
141
|
-
endif()
|
|
292
|
+
endif ()
|
|
142
293
|
|
|
143
|
-
if (${
|
|
294
|
+
if (${USEARCH_BUILD_LIB_C} OR ${USEARCH_BUILD_TEST_C})
|
|
144
295
|
add_subdirectory(c)
|
|
145
|
-
endif()
|
|
296
|
+
endif ()
|
package/Cargo.toml
CHANGED
package/README.md
CHANGED
package/binding.gyp
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"simsimd/include",
|
|
11
11
|
],
|
|
12
12
|
"dependencies": ["<!(node -p \"require('node-addon-api').gyp\")"],
|
|
13
|
+
"defines": ["USEARCH_USE_SIMSIMD=1"],
|
|
13
14
|
"cflags": [
|
|
14
15
|
"-fexceptions",
|
|
15
16
|
"-Wno-unknown-pragmas",
|
|
@@ -19,7 +20,7 @@
|
|
|
19
20
|
"-fexceptions",
|
|
20
21
|
"-Wno-unknown-pragmas",
|
|
21
22
|
"-Wno-maybe-uninitialized",
|
|
22
|
-
"-std=c++
|
|
23
|
+
"-std=c++17",
|
|
23
24
|
],
|
|
24
25
|
"xcode_settings": {
|
|
25
26
|
"GCC_ENABLE_CPP_EXCEPTIONS": "YES",
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
"msvs_settings": {
|
|
30
31
|
"VCCLCompilerTool": {
|
|
31
32
|
"ExceptionHandling": 1,
|
|
32
|
-
"AdditionalOptions": ["-std:c++
|
|
33
|
+
"AdditionalOptions": ["-std:c++17"],
|
|
33
34
|
}
|
|
34
35
|
},
|
|
35
36
|
}
|
package/build.gradle
CHANGED
|
@@ -96,27 +96,36 @@ publishing {
|
|
|
96
96
|
name = "USearch"
|
|
97
97
|
description = "Smaller & Faster Single-File Vector Search Engine from Unum"
|
|
98
98
|
url = "https://github.com/unum-cloud/usearch"
|
|
99
|
+
|
|
99
100
|
licenses {
|
|
100
101
|
license {
|
|
101
102
|
name = 'The Apache License, Version 2.0'
|
|
102
103
|
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
|
|
103
104
|
}
|
|
104
105
|
}
|
|
106
|
+
|
|
107
|
+
scm {
|
|
108
|
+
connection = 'scm:git:git://github.com/unum-cloud/usearch.git'
|
|
109
|
+
developerConnection = 'scm:git:ssh://github.com/unum-cloud/usearch.git'
|
|
110
|
+
url = 'https://github.com/unum-cloud/usearch'
|
|
111
|
+
}
|
|
112
|
+
|
|
105
113
|
}
|
|
106
114
|
}
|
|
107
115
|
}
|
|
108
116
|
|
|
117
|
+
|
|
109
118
|
// Publishing to GitHub is much easier ;)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
repositories {
|
|
120
|
+
maven {
|
|
121
|
+
name = "OSSRH"
|
|
122
|
+
url = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/"
|
|
123
|
+
credentials {
|
|
124
|
+
username = System.getenv("MAVEN_USERNAME")
|
|
125
|
+
password = System.getenv("MAVEN_PASSWORD")
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
120
129
|
|
|
121
130
|
repositories {
|
|
122
131
|
maven {
|
package/c/CMakeLists.txt
CHANGED
|
@@ -1,52 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# This article discusses a better way to allow building either static or shared libraries
|
|
1
|
+
if (USEARCH_BUILD_TEST_C)
|
|
2
|
+
add_executable(test_c test.c lib.cpp)
|
|
3
|
+
setup_target(test_c)
|
|
4
|
+
include(CTest)
|
|
5
|
+
enable_testing()
|
|
6
|
+
add_test(NAME test_c COMMAND test_c)
|
|
7
|
+
endif ()
|
|
8
|
+
|
|
9
|
+
# This article discusses a better way to allow building either static or shared libraries:
|
|
11
10
|
# https://alexreinking.com/blog/building-a-dual-shared-and-static-library-with-cmake.html
|
|
12
|
-
if (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
16
|
-
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -static")
|
|
17
|
-
endif()
|
|
18
|
-
|
|
19
|
-
add_library(usearch_c STATIC "${CMAKE_CURRENT_SOURCE_DIR}/lib.cpp")
|
|
20
|
-
else()
|
|
21
|
-
add_library(usearch_c SHARED "${CMAKE_CURRENT_SOURCE_DIR}/lib.cpp")
|
|
22
|
-
endif()
|
|
23
|
-
|
|
24
|
-
set_target_properties(usearch_c PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
|
25
|
-
set_target_properties(usearch_c PROPERTIES CXX_STANDARD 11)
|
|
26
|
-
set_target_properties(usearch_c PROPERTIES C_STANDARD 99)
|
|
27
|
-
|
|
28
|
-
target_include_directories(usearch_c PRIVATE ${USEARCH_PUNNED_INCLUDE_DIRS})
|
|
29
|
-
set_target_properties(usearch_c PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
|
30
|
-
set_target_properties(usearch_c PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
|
31
|
-
set_target_properties(usearch_c PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
target_include_directories(usearch_c PRIVATE ${USEARCH_PUNNED_INCLUDE_DIRS})
|
|
11
|
+
if (USEARCH_BUILD_LIB_C)
|
|
12
|
+
add_library(usearch_c SHARED lib.cpp)
|
|
13
|
+
add_library(usearch_static_c STATIC lib.cpp)
|
|
35
14
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
15
|
+
# Set the compile options for the static library
|
|
16
|
+
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
17
|
+
target_compile_options(usearch_static_c PRIVATE -static-libstdc++)
|
|
18
|
+
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
19
|
+
target_compile_options(usearch_static_c PRIVATE -static)
|
|
20
|
+
endif ()
|
|
40
21
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
endif()
|
|
44
|
-
if (${USEARCH_LOOKUP_LABEL})
|
|
45
|
-
target_compile_definitions(usearch_c PRIVATE USEARCH_LOOKUP_LABEL=1)
|
|
46
|
-
endif()
|
|
22
|
+
setup_target(usearch_c)
|
|
23
|
+
setup_target(usearch_static_c)
|
|
47
24
|
|
|
48
|
-
|
|
49
|
-
add_executable(test_c "${CMAKE_CURRENT_SOURCE_DIR}/test.c")
|
|
50
|
-
target_link_libraries(test_c usearch_c)
|
|
51
|
-
set_target_properties(test_c PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
|
52
|
-
endif()
|
|
25
|
+
endif ()
|
package/c/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
## Installation
|
|
4
4
|
|
|
5
5
|
The simplest form to integrate is to copy the contents of `usearch/c/` into your project.
|
|
6
|
-
To build the library `libusearch_c`, pass enable the `
|
|
6
|
+
To build the library `libusearch_static_c` and `libusearch_c`, pass enable the `USEARCH_BUILD_LIB_C` CMake option:
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
cmake -B ./build -DUSEARCH_BUILD_LIB_C=1 -DUSEARCH_BUILD_TEST_C=1 -DUSEARCH_BUILD_TEST_CPP=0 -DUSEARCH_BUILD_BENCH_CPP=0
|
|
10
|
+
make -C ./build
|
|
11
|
+
./build/test_c
|
|
12
|
+
```
|
|
13
13
|
|
|
14
14
|
## Quickstart
|
|
15
15
|
|
package/c/lib.cpp
CHANGED
|
@@ -87,15 +87,17 @@ USEARCH_EXPORT usearch_index_t usearch_init(usearch_init_options_t* options, use
|
|
|
87
87
|
metric_kind_t metric_kind = to_native_metric(options->metric_kind);
|
|
88
88
|
scalar_kind_t scalar_kind = to_native_scalar(options->quantization);
|
|
89
89
|
|
|
90
|
-
auto metric_lambda = [options](byte_t const* a, byte_t const* b) -> usearch_distance_t {
|
|
91
|
-
return options->metric((void const*)a, (void const*)b);
|
|
92
|
-
};
|
|
93
90
|
metric_punned_t metric = //
|
|
94
|
-
options->metric ? metric_punned_t(
|
|
95
|
-
|
|
91
|
+
!options->metric ? metric_punned_t(options->dimensions, metric_kind, scalar_kind)
|
|
92
|
+
: metric_punned_t(options->dimensions, //
|
|
93
|
+
reinterpret_cast<std::uintptr_t>(options->metric), //
|
|
94
|
+
metric_punned_signature_t::array_array_k, //
|
|
95
|
+
metric_kind, scalar_kind);
|
|
96
96
|
|
|
97
97
|
index_dense_t index = index_dense_t::make(metric, config);
|
|
98
98
|
index_dense_t* result_ptr = new index_dense_t(std::move(index));
|
|
99
|
+
if (!result_ptr || !*result_ptr)
|
|
100
|
+
*error = "Out of memory!";
|
|
99
101
|
return result_ptr;
|
|
100
102
|
}
|
|
101
103
|
|
|
@@ -235,8 +237,8 @@ USEARCH_EXPORT size_t usearch_remove(usearch_index_t index, usearch_key_t key, u
|
|
|
235
237
|
return result.completed;
|
|
236
238
|
}
|
|
237
239
|
|
|
238
|
-
USEARCH_EXPORT size_t usearch_rename(
|
|
239
|
-
|
|
240
|
+
USEARCH_EXPORT size_t usearch_rename( //
|
|
241
|
+
usearch_index_t index, usearch_key_t from, usearch_key_t to, usearch_error_t* error) {
|
|
240
242
|
|
|
241
243
|
assert(index && error);
|
|
242
244
|
labeling_result_t result = reinterpret_cast<index_dense_t*>(index)->rename(from, to);
|
|
@@ -244,4 +246,47 @@ USEARCH_EXPORT size_t usearch_rename(usearch_index_t index, usearch_key_t from,
|
|
|
244
246
|
*error = result.error.release();
|
|
245
247
|
return result.completed;
|
|
246
248
|
}
|
|
249
|
+
|
|
250
|
+
USEARCH_EXPORT usearch_distance_t usearch_distance( //
|
|
251
|
+
void const* vector_first, void const* vector_second, //
|
|
252
|
+
usearch_scalar_kind_t scalar_kind, size_t dimensions, //
|
|
253
|
+
usearch_metric_kind_t metric_kind, usearch_error_t* error) {
|
|
254
|
+
|
|
255
|
+
(void)error;
|
|
256
|
+
metric_punned_t metric(dimensions, to_native_metric(metric_kind), to_native_scalar(scalar_kind));
|
|
257
|
+
return metric((byte_t const*)vector_first, (byte_t const*)vector_second);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
USEARCH_EXPORT void usearch_exact_search( //
|
|
261
|
+
void const* dataset, size_t dataset_count, size_t dataset_stride, //
|
|
262
|
+
void const* queries, size_t queries_count, size_t queries_stride, //
|
|
263
|
+
usearch_scalar_kind_t scalar_kind, size_t dimensions, //
|
|
264
|
+
usearch_metric_kind_t metric_kind, size_t count, size_t threads, //
|
|
265
|
+
usearch_key_t* keys, size_t keys_stride, //
|
|
266
|
+
usearch_distance_t* distances, size_t distances_stride, //
|
|
267
|
+
usearch_error_t* error) {
|
|
268
|
+
|
|
269
|
+
metric_punned_t metric(dimensions, to_native_metric(metric_kind), to_native_scalar(scalar_kind));
|
|
270
|
+
executor_default_t executor(threads);
|
|
271
|
+
static exact_search_t search;
|
|
272
|
+
exact_search_results_t result = search( //
|
|
273
|
+
(byte_t const*)dataset, dataset_count, dataset_stride, //
|
|
274
|
+
(byte_t const*)queries, queries_count, queries_stride, //
|
|
275
|
+
count, metric);
|
|
276
|
+
|
|
277
|
+
if (!result) {
|
|
278
|
+
*error = "Out of memory, allocating a temporary buffer for batch results";
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Export results into the output buffer
|
|
283
|
+
for (std::size_t query_idx = 0; query_idx != queries_count; ++query_idx) {
|
|
284
|
+
auto query_result = result.at(query_idx);
|
|
285
|
+
auto query_keys = (usearch_key_t*)((byte_t*)keys + query_idx * keys_stride);
|
|
286
|
+
auto query_distances = (usearch_distance_t*)((byte_t*)distances + query_idx * distances_stride);
|
|
287
|
+
for (std::size_t i = 0; i != count; ++i)
|
|
288
|
+
query_keys[i] = static_cast<usearch_key_t>(query_result[i].offset),
|
|
289
|
+
query_distances[i] = static_cast<usearch_distance_t>(query_result[i].distance);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
247
292
|
}
|