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.
Files changed (54) hide show
  1. package/. npmignore +14 -0
  2. package/.cmake-format.py +19 -0
  3. package/.github/workflows/Dockerfile.libs +3 -3
  4. package/.github/workflows/prerelease.yml +85 -64
  5. package/.github/workflows/release.yml +18 -16
  6. package/.gitignore +1 -1
  7. package/.vscode/launch.json +47 -14
  8. package/.vscode/settings.json +7 -0
  9. package/.vscode/tasks.json +44 -8
  10. package/CITATION.cff +1 -1
  11. package/CMakeLists.txt +218 -67
  12. package/Cargo.toml +1 -1
  13. package/README.md +1 -1
  14. package/binding.gyp +3 -2
  15. package/build.gradle +19 -10
  16. package/c/CMakeLists.txt +21 -48
  17. package/c/README.md +5 -5
  18. package/c/lib.cpp +52 -7
  19. package/c/test.c +137 -94
  20. package/c/usearch.h +42 -0
  21. package/cmake/clipp.cmake +0 -1
  22. package/cmake/jemalloc.cmake +21 -37
  23. package/conanfile.py +1 -1
  24. package/cpp/CMakeLists.txt +14 -123
  25. package/cpp/bench.cpp +0 -12
  26. package/cpp/test.cpp +29 -1
  27. package/csharp/nuget/nuget-package.props +1 -1
  28. package/docs/compilation.md +23 -16
  29. package/docs/conf.py +1 -1
  30. package/golang/README.md +52 -51
  31. package/golang/lib.go +1 -1
  32. package/golang/lib_test.go +4 -1
  33. package/include/usearch/index.hpp +2 -2
  34. package/include/usearch/index_plugins.hpp +345 -160
  35. package/javascript/lib.cpp +204 -250
  36. package/javascript/usearch.js +440 -2
  37. package/javascript/usearch.test.js +37 -0
  38. package/package.json +10 -5
  39. package/python/lib.cpp +96 -225
  40. package/python/scripts/bench_exact.py +2 -2
  41. package/python/scripts/test_jit.py +2 -13
  42. package/python/scripts/test_sparse.py +1 -1
  43. package/python/scripts/test_tooling.py +26 -5
  44. package/rust/lib.cpp +12 -4
  45. package/rust/lib.hpp +7 -0
  46. package/rust/lib.rs +170 -10
  47. package/setup.py +14 -4
  48. package/wasm/CMakeLists.txt +4 -12
  49. package/wasm/lib.cpp +1 -1
  50. package/wasmer.toml +1 -1
  51. package/javascript/docs.js +0 -111
  52. package/javascript/test.js +0 -32
  53. package/javascript/usearch.d.ts +0 -110
  54. package/tsconfig.json +0 -8
@@ -1,123 +1,14 @@
1
- cmake_minimum_required(VERSION 3.1)
2
-
3
- option(USEARCH_USE_OPENMP "Use OpenMP for a thread pool" OFF)
4
- option(USEARCH_USE_SIMSIMD "Use SimSIMD hardware-accelerated metrics" OFF)
5
- option(USEARCH_USE_JEMALLOC "Use JeMalloc for faster memory allocations" OFF)
6
-
7
- # Make "Release" by default
8
- if(NOT CMAKE_BUILD_TYPE)
9
- set(CMAKE_BUILD_TYPE Release)
10
- endif()
11
-
12
- # List of all possible compiler IDs:
13
- # https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html
14
- if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
15
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
16
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")
17
- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -g")
18
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address -fsanitize=leak -fsanitize=alignment -fsanitize=undefined")
19
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra -Wno-conversion -Wno-unknown-pragmas")
20
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
21
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmax-errors=1")
22
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
23
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
24
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftime-report")
25
-
26
- if(${USEARCH_USE_OPENMP})
27
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
28
- endif()
29
-
30
- elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
31
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
32
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")
33
- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -g")
34
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address -fsanitize=leak -fsanitize=alignment -fsanitize=undefined")
35
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wfatal-errors")
36
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
37
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
38
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftime-trace")
39
-
40
- if(${USEARCH_USE_OPENMP})
41
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
42
- endif()
43
-
44
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "NVIDIA" OR CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC")
45
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
46
- set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --extended-lambda")
47
- set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -gencode arch=compute_86,code=sm_86")
48
- set_property(SOURCE bench.cpp PROPERTY LANGUAGE CUDA)
49
- set_target_properties(bench PROPERTIES POSITION_INDEPENDENT_CODE ON)
50
- set_target_properties(bench PROPERTIES CUDA_ARCHITECTURES "86")
51
-
52
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
53
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w")
54
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ferror-limit=1")
55
-
56
- elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
57
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /DEBUG")
58
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2")
59
- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /O2 /DEBUG")
60
- endif()
61
-
62
- if(APPLE)
63
- set(CMAKE_THREAD_LIBS_INIT "-lpthread")
64
- set(CMAKE_HAVE_THREADS_LIBRARY 1)
65
- set(CMAKE_USE_WIN32_THREADS_INIT 0)
66
- set(CMAKE_USE_PTHREADS_INIT 1)
67
- set(THREADS_PREFER_PTHREAD_FLAG ON)
68
- endif()
69
-
70
- find_package(Threads REQUIRED)
71
-
72
- if(${USEARCH_USE_OPENMP})
73
- find_package(OpenMP REQUIRED)
74
- include_directories(${OPENMP_INCLUDE_DIRS})
75
- endif()
76
-
77
- if(${USEARCH_USE_JEMALLOC})
78
- include(jemalloc)
79
- endif()
80
-
81
- include(clipp)
82
-
83
- set(USEARCH_PUNNED_INCLUDE_DIRS
84
- "${CMAKE_CURRENT_SOURCE_DIR}/../include"
85
- "${CMAKE_CURRENT_SOURCE_DIR}/../fp16/include"
86
- "${CMAKE_CURRENT_SOURCE_DIR}/../simsimd/include"
87
- "${CMAKE_CURRENT_SOURCE_DIR}/"
88
- )
89
-
90
- if(${USEARCH_BUILD_TEST})
91
- add_executable(test test.cpp)
92
- target_link_libraries(test PRIVATE Threads::Threads)
93
- target_include_directories(test PRIVATE ${USEARCH_PUNNED_INCLUDE_DIRS})
94
- set_target_properties(test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
95
- set_target_properties(test PROPERTIES CXX_STANDARD 17)
96
-
97
- if(${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13)
98
- include(CTest)
99
- enable_testing()
100
- add_test(NAME test COMMAND test)
101
- endif()
102
- endif()
103
-
104
- if(${USEARCH_BUILD_BENCHMARK})
105
- add_executable(bench bench.cpp)
106
- target_link_libraries(bench PRIVATE Threads::Threads)
107
- target_include_directories(bench PRIVATE ${USEARCH_PUNNED_INCLUDE_DIRS})
108
- set_target_properties(bench PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
109
- set_target_properties(bench PROPERTIES CXX_STANDARD 17)
110
-
111
- if(${USEARCH_USE_SIMSIMD})
112
- target_compile_definitions(bench PRIVATE USEARCH_USE_SIMSIMD=1)
113
- endif()
114
-
115
- if(${USEARCH_USE_OPENMP})
116
- target_compile_definitions(bench PRIVATE USEARCH_USE_OPENMP=1)
117
- target_link_libraries(bench PRIVATE ${OPENMP_LIBRARIES})
118
- endif()
119
-
120
- if(${USEARCH_USE_JEMALLOC})
121
- target_link_libraries(bench PRIVATE ${JEMALLOC_LIBRARIES})
122
- endif()
123
- endif()
1
+ if (USEARCH_BUILD_TEST_CPP)
2
+ add_executable(test_cpp test.cpp)
3
+ setup_target(test_cpp)
4
+ include(CTest)
5
+ enable_testing()
6
+ add_test(NAME test_cpp COMMAND test_cpp)
7
+ endif ()
8
+
9
+ if (USEARCH_BUILD_BENCH_CPP)
10
+ include(clipp)
11
+ add_executable(bench_cpp bench.cpp)
12
+ setup_target(bench_cpp)
13
+ target_include_directories(bench_cpp PRIVATE ${clipp_SOURCE_DIR}/include)
14
+ endif ()
package/cpp/bench.cpp CHANGED
@@ -135,18 +135,6 @@ struct alignas(32) persisted_matrix_gt {
135
135
  std::size_t size_bytes() const noexcept { return rows * row_size_bytes(); }
136
136
  };
137
137
 
138
- template <typename scalar_at> //
139
- struct vectors_view_gt {
140
- using scalar_t = scalar_at;
141
-
142
- scalar_t const* begin_{};
143
- std::size_t count_{};
144
- std::size_t stride_{};
145
-
146
- std::size_t size() const noexcept { return count_; }
147
- scalar_t const* at(std::size_t i) const noexcept { return begin_ + i * stride_; }
148
- };
149
-
150
138
  template <typename scalar_at, typename vector_id_at> //
151
139
  struct persisted_dataset_gt {
152
140
  using scalar_t = scalar_at;
package/cpp/test.cpp CHANGED
@@ -1,9 +1,12 @@
1
1
  /**
2
2
  * @brief A trivial test.
3
3
  */
4
- #include <algorithm>
4
+ #include <algorithm> // `std::shuffle`
5
+ #include <cassert> // `assert`
6
+ #include <random> // `std::default_random_engine`
5
7
  #include <stdexcept>
6
8
  #include <unordered_map>
9
+ #include <vector> // for std::vector
7
10
 
8
11
  #include <usearch/index.hpp>
9
12
  #include <usearch/index_dense.hpp>
@@ -234,6 +237,26 @@ template <typename key_at, typename slot_at> void test_tanimoto(std::size_t dime
234
237
  });
235
238
  }
236
239
 
240
+ void test_exact_search(std::size_t dataset_count, std::size_t queries_count, std::size_t wanted_count) {
241
+ std::size_t dimensions = 10;
242
+ metric_punned_t metric(dimensions, metric_kind_t::cos_k);
243
+
244
+ std::random_device rd;
245
+ std::mt19937 gen(rd());
246
+ std::uniform_real_distribution<> dis(0.0, 1.0);
247
+ std::vector<float> dataset(dataset_count * dimensions);
248
+ std::generate(dataset.begin(), dataset.end(), [&] { return dis(gen); });
249
+
250
+ exact_search_t search;
251
+ auto results = search( //
252
+ (byte_t const*)dataset.data(), dataset_count, dimensions * sizeof(float), //
253
+ (byte_t const*)dataset.data(), queries_count, dimensions * sizeof(float), //
254
+ wanted_count, metric);
255
+
256
+ for (std::size_t i = 0; i < results.size(); ++i)
257
+ assert(results.at(i)[0].offset == i); // Validate the top match
258
+ }
259
+
237
260
  template <typename index_at> void test_sets(index_at&& index) {
238
261
 
239
262
  using index_t = typename std::remove_reference<index_at>::type;
@@ -272,6 +295,11 @@ template <typename index_at> void test_sets_moved(index_config_t const& config)
272
295
 
273
296
  int main(int, char**) {
274
297
 
298
+ for (std::size_t dataset_count : {10, 100})
299
+ for (std::size_t queries_count : {1, 10})
300
+ for (std::size_t wanted_count : {1, 5})
301
+ test_exact_search(dataset_count, queries_count, wanted_count);
302
+
275
303
  for (std::size_t collection_size : {10, 500})
276
304
  for (std::size_t dimensions : {97, 256}) {
277
305
  std::printf("Indexing %zu vectors with cos: <float, std::int64_t, std::uint32_t> \n", collection_size);
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <Project>
3
3
  <PropertyGroup>
4
- <Version Condition="'$(Version)' == ''">2.6.1</Version>
4
+ <Version Condition="'$(Version)' == ''">2.7.1</Version>
5
5
 
6
6
  <Authors>Unum</Authors>
7
7
  <Company>Unum</Company>
@@ -13,15 +13,16 @@ Linux:
13
13
 
14
14
  ```sh
15
15
  sudo apt-get update
16
- sudo apt-get install cmake g++-12 build-essential libjemalloc-dev
16
+ sudo apt-get install cmake build-essential libjemalloc-dev
17
17
  cmake -B ./build_release \
18
- -DCMAKE_CXX_COMPILER="g++-12" \
19
18
  -DCMAKE_BUILD_TYPE=Release \
20
- -DUSEARCH_BUILD_TEST=1 \
21
19
  -DUSEARCH_USE_OPENMP=1 \
22
20
  -DUSEARCH_USE_SIMSIMD=1 \
23
21
  -DUSEARCH_USE_JEMALLOC=1 \
24
- -DUSEARCH_BUILD_BENCHMARK=1 \
22
+ -DUSEARCH_BUILD_TEST_CPP=1 \
23
+ -DUSEARCH_BUILD_BENCH_CPP=1 \
24
+ -DUSEARCH_BUILD_LIB_C=1 \
25
+ -DUSEARCH_BUILD_TEST_C=1 \
25
26
  && \
26
27
  make -C ./build_release -j
27
28
  ```
@@ -35,8 +36,8 @@ cmake -B ./build_release \
35
36
  -DCMAKE_CXX_COMPILER="/opt/homebrew/opt/llvm/bin/clang++" \
36
37
  -DUSEARCH_USE_OPENMP=1 \
37
38
  -DUSEARCH_USE_SIMSIMD=1 \
38
- -DUSEARCH_BUILD_BENCHMARK=1 \
39
- -DUSEARCH_BUILD_TEST=1 \
39
+ -DUSEARCH_BUILD_BENCH_CPP=1 \
40
+ -DUSEARCH_BUILD_TEST_CPP=1 \
40
41
  && \
41
42
  make -C ./build_release -j
42
43
  ```
@@ -53,7 +54,9 @@ cppcheck --enable=all --force --suppress=cstyleCast --suppress=unusedFunction \
53
54
  Testing:
54
55
 
55
56
  ```sh
56
- cmake -DCMAKE_BUILD_TYPE=Debug -B ./build_debug && make -C ./build_debug && ./build_debug/test
57
+ cmake -DUSEARCH_BUILD_TEST_CPP=1 -B ./build_debug
58
+ cmake --build ./build_debug --config Debug
59
+ ./build_debug/test_cpp
57
60
  ```
58
61
 
59
62
  ## Python 3
@@ -85,7 +88,7 @@ cibuildwheel --platform linux
85
88
  Node.JS:
86
89
 
87
90
  ```sh
88
- npm install && node javascript/test.js
91
+ npm install && node --test ./javascript/usearch.test.js
89
92
  npm publish
90
93
  ```
91
94
 
@@ -93,7 +96,7 @@ WebAssembly:
93
96
 
94
97
  ```sh
95
98
  emcmake cmake -B ./build -DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -s TOTAL_MEMORY=64MB" && emmake make -C ./build
96
- node ./build/test.js
99
+ node ./build/usearch.test.js
97
100
  ```
98
101
 
99
102
  If you don't yet have `emcmake` installed:
@@ -124,7 +127,7 @@ javac -h . Index.java
124
127
 
125
128
  # Ubuntu:
126
129
  g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux cloud_unum_usearch_Index.cpp -o cloud_unum_usearch_Index.o
127
- g++ -shared -fPIC -o libusearch.so cloud_unum_usearch_Index.o -lc
130
+ g++ -shared -fPIC -o libusearch_c.so cloud_unum_usearch_Index.o -lc
128
131
 
129
132
  # Windows
130
133
  g++ -c -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 cloud_unum_usearch_Index.cpp -o cloud_unum_usearch_Index.o
@@ -152,22 +155,26 @@ swift test -v
152
155
  ## C 99
153
156
 
154
157
  There are a few ways to compile the C 99 USearch SDK.
155
- Using the Makefile:
158
+ Using the Makefile, specifying the targets you need:
156
159
 
157
160
  ```sh
158
161
  make -C ./c libusearch_c.so
159
162
  ```
160
163
 
161
- Using CMake:
164
+ With options:
162
165
 
163
166
  ```sh
164
- cmake -B ./build_release -DUSEARCH_BUILD_CLIB=1 && make -C ./build_release -j
167
+ make USEARCH_USE_OPENMP=1 USEARCH_USE_SIMSIMD=1 -C ./c libusearch_c.so
165
168
  ```
166
169
 
167
- Linux:
170
+ Using CMake:
168
171
 
169
172
  ```sh
170
- g++ -std=c++11 -shared -fPIC c/lib.cpp -I ./include/ -I ./fp16/include/ -o libusearch_c.so
173
+ cmake -B ./build_release -DUSEARCH_BUILD_LIB_C=1 -DUSEARCH_BUILD_TEST_C=1 -DUSEARCH_USE_OPENMP=1 -DUSEARCH_USE_SIMSIMD=1
174
+ cmake --build ./build_release --config Release -j
175
+ ./build_release/test_c
176
+ # On Windows:
177
+ .\build_release\test_c.exe
171
178
  ```
172
179
 
173
180
 
@@ -177,7 +184,7 @@ GoLang bindings are based on C.
177
184
  So one should first compile the C library, link it with GoLang, and only then run tests.
178
185
 
179
186
  ```sh
180
- make -C ./c libusearch_c.so && mv ./c/libusearch_c.so ./golang/libusearch_c.so
187
+ make -C ./c libusearch_c.so && mv ./c/libusearch_c.so ./golang/ && cp ./c/usearch.h ./golang/
181
188
  cd golang && go test -v ; cd ..
182
189
  ```
183
190
 
package/docs/conf.py CHANGED
@@ -50,4 +50,4 @@ html_baseurl = "/docs/usearch/"
50
50
  breathe_projects = {"USearch": "../build/xml"}
51
51
  breathe_default_project = "USearch"
52
52
 
53
- js_source_path = "../javascript/docs.js"
53
+ js_source_path = "../javascript/usearch.js"
package/golang/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  Download and install from the Debian package from the latest release.
8
8
  Substitute `<release_tag>`, `<arch>`, and `<usearch_version>` with your settings.
9
9
 
10
- ```
10
+ ```sh
11
11
  wget https://github.com/unum-cloud/usearch/releases/download/<release_tag>/usearch_linux_<arch>_<usearch_version>.deb
12
12
  dpkg -i usearch_<arch>_<usearch_version>.deb
13
13
  ```
@@ -17,7 +17,7 @@ dpkg -i usearch_<arch>_<usearch_version>.deb
17
17
  Run a `winlibinstaller.bat` script from the main repository in the folder where you will run `go run`.
18
18
  That will install the USearch library and include in the same folder` where the script was run.
19
19
 
20
- ```
20
+ ```sh
21
21
  .\usearch\winlibinstaller.bat
22
22
  ```
23
23
 
@@ -25,10 +25,11 @@ That will install the USearch library and include in the same folder` where the
25
25
 
26
26
  Download and unpack a zip archive from the latest release.
27
27
  Move the USearch library and the include file to their respective folders.
28
- ```
28
+
29
+ ```sh
29
30
  wget https://github.com/unum-cloud/usearch/releases/download/<release_tag>/usearch_macOS_<arch>_<usearch_version>.zip
30
31
  unzip usearch_macOS_<arch>_<usearch_version>.zip
31
- sudo mv libusearch.so /usr/local/lib && sudo mv usearch.h /usr/local/include
32
+ sudo mv libusearch_c.so /usr/local/lib && sudo mv usearch.h /usr/local/include
32
33
 
33
34
  ```
34
35
 
@@ -36,60 +37,60 @@ sudo mv libusearch.so /usr/local/lib && sudo mv usearch.h /usr/local/include
36
37
 
37
38
  1. Create a `go.mod` file:
38
39
 
39
- ```
40
- module usearch_example
40
+ ```
41
+ module usearch_example
41
42
 
42
- go <go_version>
43
- ```
43
+ go <go_version>
44
+ ```
44
45
 
45
46
  2. Create an `example.go`:
46
47
 
47
- ```golang
48
- package main
49
-
50
- import (
51
- "fmt"
52
- usearch "github.com/unum-cloud/usearch/golang"
53
- )
54
-
55
- func main() {
56
-
57
- // Create Index
58
- vector_size := 3
59
- vectors_count := 100
60
- conf := usearch.DefaultConfig(uint(vector_size))
61
- index,err := usearch.NewIndex(conf)
62
- if err != nil {
63
- panic("Failed to create Index")
64
- }
65
- defer index.Destroy()
66
-
67
- // Add to Index
68
- err = index.Reserve(uint(vectors_count))
69
- for i := 0; i < vectors_count; i++ {
70
- err = index.Add(usearch.Key(i), []float32{float32(i), float32(i+1), float32(i+2)})
71
- if err != nil {
72
- panic("Failed to add")
73
- }
74
- }
75
-
76
- // Search
77
- keys, distances, err := index.Search([]float32{0.0, 1.0, 2.0}, 3)
78
- if err != nil {
79
- panic("Failed to search")
80
- }
81
- fmt.Println(keys, distances)
82
- }
83
- ```
48
+ ```golang
49
+ package main
50
+
51
+ import (
52
+ "fmt"
53
+ usearch "github.com/unum-cloud/usearch/golang"
54
+ )
55
+
56
+ func main() {
57
+
58
+ // Create Index
59
+ vector_size := 3
60
+ vectors_count := 100
61
+ conf := usearch.DefaultConfig(uint(vector_size))
62
+ index,err := usearch.NewIndex(conf)
63
+ if err != nil {
64
+ panic("Failed to create Index")
65
+ }
66
+ defer index.Destroy()
67
+
68
+ // Add to Index
69
+ err = index.Reserve(uint(vectors_count))
70
+ for i := 0; i < vectors_count; i++ {
71
+ err = index.Add(usearch.Key(i), []float32{float32(i), float32(i+1), float32(i+2)})
72
+ if err != nil {
73
+ panic("Failed to add")
74
+ }
75
+ }
76
+
77
+ // Search
78
+ keys, distances, err := index.Search([]float32{0.0, 1.0, 2.0}, 3)
79
+ if err != nil {
80
+ panic("Failed to search")
81
+ }
82
+ fmt.Println(keys, distances)
83
+ }
84
+ ```
84
85
 
85
86
  3. Get USearch:
86
87
 
87
- ```
88
- go get github.com/unum-cloud/usearch/golang
89
- ```
88
+ ```sh
89
+ go get github.com/unum-cloud/usearch/golang
90
+ ```
90
91
 
91
92
  4. Run:
92
93
 
93
- ```
94
- go run example.go
95
- ```
94
+ ```sh
95
+ go run example.go
96
+ ```
package/golang/lib.go CHANGED
@@ -6,7 +6,7 @@ import (
6
6
  )
7
7
 
8
8
  /*
9
- #cgo LDFLAGS: -L. -lusearch
9
+ #cgo LDFLAGS: -L. -lusearch_c
10
10
  #include "usearch.h"
11
11
  #include <stdlib.h>
12
12
  */
@@ -3,6 +3,7 @@ package usearch
3
3
  import (
4
4
  "runtime"
5
5
  "testing"
6
+ "math"
6
7
  )
7
8
 
8
9
  func TestUSearch(t *testing.T) {
@@ -98,7 +99,9 @@ func TestUSearch(t *testing.T) {
98
99
  if err != nil {
99
100
  t.Fatalf("Failed to search: %s", err)
100
101
  }
101
- if keys[0] != 42 || distances[0] != 0.0 {
102
+
103
+ const tolerance = 1e-2 // For example, this sets the tolerance to 0.01
104
+ if keys[0] != 42 || math.Abs(float64(distances[0])) > tolerance {
102
105
  t.Fatalf("Expected result 42 with distance 0, got key %d with distance %f", keys[0], distances[0])
103
106
  }
104
107
  })
@@ -10,7 +10,7 @@
10
10
  #define UNUM_USEARCH_HPP
11
11
 
12
12
  #define USEARCH_VERSION_MAJOR 2
13
- #define USEARCH_VERSION_MINOR 6
13
+ #define USEARCH_VERSION_MINOR 7
14
14
  #define USEARCH_VERSION_PATCH 1
15
15
 
16
16
  // Inferring C++ version
@@ -268,7 +268,7 @@ template <typename scalar_at> class span_gt {
268
268
  * @brief Similar to `std::vector`, but doesn't support dynamic resizing.
269
269
  * On the bright side, this can't throw exceptions.
270
270
  */
271
- template <typename scalar_at, typename allocator_at> class buffer_gt {
271
+ template <typename scalar_at, typename allocator_at = std::allocator<scalar_at>> class buffer_gt {
272
272
  scalar_at* data_;
273
273
  std::size_t size_;
274
274