Skip to content

Commit 9ef63db

Browse files
fix: SimSIMD dynamic dispatch (#5870)
* fix: SimSIMD dynamic dispatch was added * fix: additional logging added * fix: additional logging added * fix: simsimd dynamic dispatch updated * fix: so library build * fix: makefile updated * fix: dynamic dispatch * fix: cleanup * fix: dynamic/header only libs build * fix: Makefile checkout * fix: cleanup * fix: review comments * fix: review comments * fix: review comments * fix: review comments * fix: review comments * fix: review comments * fix: review comments * fix: review comments * Update src/core/search/vector_utils.cc Co-authored-by: Roman Gershman <[email protected]> Signed-off-by: Volodymyr Yavdoshenko <[email protected]> --------- Signed-off-by: Volodymyr Yavdoshenko <[email protected]> Co-authored-by: Roman Gershman <[email protected]>
1 parent d6a570c commit 9ef63db

File tree

7 files changed

+64
-36
lines changed

7 files changed

+64
-36
lines changed

src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
option(ENABLE_GIT_VERSION "Build with Git metadata" OFF)
22

3-
option(USE_SIMSIMD "Enable SimSIMD vector optimizations" OFF)
3+
option(WITH_SIMSIMD "Enable SimSIMD vector optimizations" OFF)
44
option(SIMSIMD_NATIVE_F16 "Enable native float16 support in SimSIMD" OFF)
55
option(WITH_SEARCH "Enable compilation of search module" ON)
66

src/core/search/CMakeLists.txt

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,13 @@ add_library(dfly_search_core base.cc ast_expr.cc query_driver.cc search.cc indic
1212
target_link_libraries(dfly_search_core base redis_lib absl::strings
1313
TRDP::reflex TRDP::uni-algo TRDP::hnswlib)
1414

15-
if(USE_SIMSIMD)
15+
if(WITH_SIMSIMD)
1616
target_link_libraries(dfly_search_core TRDP::simsimd)
17-
target_compile_definitions(dfly_search_core PRIVATE USE_SIMSIMD=1)
18-
19-
# Conditionally disable native float16 support (default behavior)
20-
if(NOT SIMSIMD_NATIVE_F16)
21-
target_compile_definitions(dfly_search_core PRIVATE
22-
SIMSIMD_NATIVE_F16=0
23-
SIMSIMD_NATIVE_BF16=0)
24-
endif()
17+
target_compile_definitions(dfly_search_core PRIVATE
18+
WITH_SIMSIMD=1
19+
SIMSIMD_DYNAMIC_DISPATCH=1
20+
SIMSIMD_NATIVE_F16=$<IF:$<BOOL:${SIMSIMD_NATIVE_F16}>,1,0>
21+
SIMSIMD_NATIVE_BF16=$<IF:$<BOOL:${SIMSIMD_NATIVE_F16}>,1,0>)
2522
endif()
2623

2724
cxx_test(compressed_sorted_set_test dfly_search_core LABELS DFLY)
@@ -31,14 +28,11 @@ cxx_test(rax_tree_test redis_test_lib LABELS DFLY)
3128
cxx_test(search_parser_test dfly_search_core LABELS DFLY)
3229
cxx_test(search_test redis_test_lib dfly_search_core LABELS DFLY)
3330

34-
if(USE_SIMSIMD)
31+
if(WITH_SIMSIMD)
3532
target_link_libraries(search_test TRDP::simsimd)
36-
target_compile_definitions(search_test PRIVATE USE_SIMSIMD=1)
37-
38-
# Conditionally disable native float16 support (default behavior)
39-
if(NOT SIMSIMD_NATIVE_F16)
40-
target_compile_definitions(search_test PRIVATE
41-
SIMSIMD_NATIVE_F16=0
42-
SIMSIMD_NATIVE_BF16=0)
43-
endif()
33+
target_compile_definitions(search_test PRIVATE
34+
WITH_SIMSIMD=1
35+
SIMSIMD_DYNAMIC_DISPATCH=1
36+
SIMSIMD_NATIVE_F16=$<IF:$<BOOL:${SIMSIMD_NATIVE_F16}>,1,0>
37+
SIMSIMD_NATIVE_BF16=$<IF:$<BOOL:${SIMSIMD_NATIVE_F16}>,1,0>)
4438
endif()

src/core/search/search_test.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ class SearchTest : public ::testing::Test {
149149
static void SetUpTestSuite() {
150150
auto* tlh = mi_heap_get_backing();
151151
init_zmalloc_threadlocal(tlh);
152+
// Initialize SimSIMD runtime for tests that may exercise vector kernels
153+
InitSimSIMD();
152154
}
153155

154156
SearchTest() {
@@ -967,6 +969,8 @@ TEST_F(SearchTest, VectorDistanceConsistency) {
967969
}
968970

969971
static void BM_VectorSearch(benchmark::State& state) {
972+
// Ensure SimSIMD dynamic dispatch is initialized for the benchmark
973+
InitSimSIMD();
970974
unsigned ndims = state.range(0);
971975
unsigned nvecs = state.range(1);
972976

@@ -1659,6 +1663,8 @@ TEST(CosineDistanceTest, ZeroVectors) {
16591663

16601664
// Unified vector distance benchmarks using VectorDistance function
16611665
static void BM_VectorDistance(benchmark::State& state) {
1666+
// Ensure SimSIMD dynamic dispatch is initialized for the benchmark
1667+
InitSimSIMD();
16621668
size_t dims = state.range(0);
16631669
size_t num_pairs = state.range(1);
16641670
VectorSimilarity sim = static_cast<VectorSimilarity>(state.range(2));
@@ -1691,6 +1697,8 @@ static void BM_VectorDistance(benchmark::State& state) {
16911697

16921698
// Intensive benchmark with batch processing
16931699
static void BM_VectorDistance_Intensive(benchmark::State& state) {
1700+
// Ensure SimSIMD dynamic dispatch is initialized for the benchmark
1701+
InitSimSIMD();
16941702
size_t dims = 512; // Fixed medium size
16951703
size_t batch_size = 1000;
16961704
VectorSimilarity sim = static_cast<VectorSimilarity>(state.range(0));

src/core/search/vector_utils.cc

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ using namespace std;
1515

1616
namespace {
1717

18-
#ifdef USE_SIMSIMD
19-
// Native float16 support is controlled via CMake option SIMSIMD_NATIVE_F16
20-
// Default behavior disables native F16/BF16 for maximum compatibility
18+
#ifdef WITH_SIMSIMD
2119
#include <simsimd/simsimd.h>
2220
#endif
2321

@@ -29,7 +27,7 @@ namespace {
2927

3028
// Euclidean vector distance: sqrt( sum: (u[i] - v[i])^2 )
3129
FAST_MATH float L2Distance(const float* u, const float* v, size_t dims) {
32-
#ifdef USE_SIMSIMD
30+
#ifdef WITH_SIMSIMD
3331
simsimd_distance_t distance = 0;
3432
simsimd_l2_f32(u, v, dims, &distance);
3533
return static_cast<float>(distance);
@@ -44,7 +42,7 @@ FAST_MATH float L2Distance(const float* u, const float* v, size_t dims) {
4442
// Inner product distance: 1 - dot_product(u, v)
4543
// For normalized vectors, this is equivalent to cosine distance
4644
FAST_MATH float IPDistance(const float* u, const float* v, size_t dims) {
47-
#ifdef USE_SIMSIMD
45+
#ifdef WITH_SIMSIMD
4846
// Use SimSIMD dot product and convert to inner product distance: 1 - dot(u, v).
4947
simsimd_distance_t dot = 0;
5048
simsimd_dot_f32(u, v, dims, &dot);
@@ -58,7 +56,7 @@ FAST_MATH float IPDistance(const float* u, const float* v, size_t dims) {
5856
}
5957

6058
FAST_MATH float CosineDistance(const float* u, const float* v, size_t dims) {
61-
#ifdef USE_SIMSIMD
59+
#ifdef WITH_SIMSIMD
6260
simsimd_distance_t distance = 0;
6361
simsimd_cos_f32(u, v, dims, &distance);
6462
return static_cast<float>(distance);
@@ -112,4 +110,10 @@ float VectorDistance(const float* u, const float* v, size_t dims, VectorSimilari
112110
return 0.0f;
113111
}
114112

113+
void InitSimSIMD() {
114+
#if defined(WITH_SIMSIMD)
115+
(void)simsimd_capabilities();
116+
#endif
117+
}
118+
115119
} // namespace dfly::search

src/core/search/vector_utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
namespace dfly::search {
1010

11+
// Initializes SimSIMD runtime if dynamic dispatch is enabled.
12+
void InitSimSIMD();
13+
1114
OwnedFtVector BytesToFtVector(std::string_view value);
1215

1316
// Returns std::nullopt if value can not be converted to the vector

src/external_libs.cmake

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,33 @@ add_third_party(
164164
LIB libhdr_histogram_static.a
165165
)
166166

167-
if(USE_SIMSIMD)
167+
if(WITH_SIMSIMD)
168+
# Compute integer macros for native half-precision support.
169+
set(SIMSIMD_NATIVE_F16_VAL 0)
170+
set(SIMSIMD_NATIVE_BF16_VAL 0)
171+
if(SIMSIMD_NATIVE_F16)
172+
set(SIMSIMD_NATIVE_F16_VAL 1)
173+
set(SIMSIMD_NATIVE_BF16_VAL 1)
174+
endif()
175+
176+
# Build statically via add_third_party using the C shim with dynamic dispatch.
168177
add_third_party(
169178
simsimd
170179
URL https://github.com/ashvardanian/SimSIMD/archive/refs/tags/v6.5.3.tar.gz
171-
BUILD_COMMAND echo SKIP
172-
INSTALL_COMMAND cp -R <SOURCE_DIR>/include ${THIRD_PARTY_LIB_DIR}/simsimd/
173-
LIB "none"
180+
BUILD_IN_SOURCE 1
181+
BUILD_COMMAND bash -c "\
182+
mkdir -p ${THIRD_PARTY_LIB_DIR}/simsimd/lib && \
183+
${CMAKE_C_COMPILER} -O3 -fPIC -DNDEBUG \
184+
-DSIMSIMD_DYNAMIC_DISPATCH=1 \
185+
-DSIMSIMD_NATIVE_F16=${SIMSIMD_NATIVE_F16_VAL} \
186+
-DSIMSIMD_NATIVE_BF16=${SIMSIMD_NATIVE_BF16_VAL} \
187+
-I<SOURCE_DIR>/include -c <SOURCE_DIR>/c/lib.c -o <SOURCE_DIR>/lib.o && \
188+
ar rcs <SOURCE_DIR>/libsimsimd.a <SOURCE_DIR>/lib.o"
189+
INSTALL_COMMAND bash -c "\
190+
mkdir -p ${THIRD_PARTY_LIB_DIR}/simsimd/include ${THIRD_PARTY_LIB_DIR}/simsimd/lib && \
191+
cp -R <SOURCE_DIR>/include/* ${THIRD_PARTY_LIB_DIR}/simsimd/include/ && \
192+
cp <SOURCE_DIR>/libsimsimd.a ${THIRD_PARTY_LIB_DIR}/simsimd/lib/"
193+
LIB libsimsimd.a
174194
)
175195
endif()
176196

@@ -196,10 +216,3 @@ add_library(TRDP::fast_float INTERFACE IMPORTED)
196216
add_dependencies(TRDP::fast_float fast_float_project)
197217
set_target_properties(TRDP::fast_float PROPERTIES
198218
INTERFACE_INCLUDE_DIRECTORIES "${FAST_FLOAT_INCLUDE_DIR}")
199-
200-
if(USE_SIMSIMD)
201-
add_library(TRDP::simsimd INTERFACE IMPORTED)
202-
add_dependencies(TRDP::simsimd simsimd_project)
203-
set_target_properties(TRDP::simsimd PROPERTIES
204-
INTERFACE_INCLUDE_DIRECTORIES "${SIMSIMD_INCLUDE_DIR}")
205-
endif()

src/server/main_service.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ extern "C" {
3434
#include "base/flag_utils.h"
3535
#include "base/flags.h"
3636
#include "base/logging.h"
37+
#include "core/search/vector_utils.h"
3738
#include "facade/dragonfly_connection.h"
3839
#include "facade/error.h"
3940
#include "facade/reply_builder.h"
@@ -914,6 +915,11 @@ void Service::Init(util::AcceptServer* acceptor, std::vector<facade::Listener*>
914915
InitRedisTables();
915916
facade::Connection::Init(pp_.size());
916917

918+
#if defined(WITH_SEARCH)
919+
// Initialize SimSIMD runtime if needed (explicit, avoids implicit static initializers)
920+
dfly::search::InitSimSIMD();
921+
#endif
922+
917923
config_registry.RegisterMutable("dbfilename");
918924
config_registry.Register("dbnum"); // equivalent to databases in redis.
919925
config_registry.Register("dir");

0 commit comments

Comments
 (0)