usearch 2.8.7 → 2.8.9
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/CITATION.cff +1 -1
- package/CMakeLists.txt +3 -3
- package/CONTRIBUTING.md +26 -3
- package/Cargo.toml +1 -1
- package/Dockerfile +16 -0
- package/README.md +41 -38
- package/VERSION +1 -0
- package/binding.gyp +57 -8
- package/conanfile.py +1 -1
- package/include/usearch/index.hpp +1 -1
- package/include/usearch/index_plugins.hpp +28 -24
- package/javascript/README.md +64 -12
- package/javascript/lib.cpp +11 -3
- package/javascript/usearch.js +4 -2
- package/javascript/usearch.test.js +15 -0
- package/package.json +1 -2
- package/setup.py +76 -15
- package/simsimd/README.md +14 -13
- package/simsimd/include/simsimd/probability.h +2 -2
- package/simsimd/package.json +1 -1
- package/wasmer.toml +1 -1
- package/. npmignore +0 -14
- package/.gitignore +0 -95
- package/.vscode/launch.json +0 -181
- package/.vscode/settings.json +0 -180
- package/.vscode/tasks.json +0 -71
- package/Package.swift +0 -41
- package/csharp/.editorconfig +0 -361
- package/csharp/Cloud.Unum.USearch.sln +0 -34
- package/csharp/DEV_SETUP.md +0 -51
- package/csharp/Directory.Build.props +0 -29
- package/csharp/README.md +0 -74
- package/csharp/build_and_test.cmd +0 -31
- package/csharp/build_and_test.sh +0 -30
- package/csharp/nuget/nuget-package.props +0 -33
- package/csharp/pack.sh +0 -56
- package/csharp/src/Cloud.Unum.USearch.Tests/Cloud.Unum.USearch.Tests.csproj +0 -39
- package/csharp/src/Cloud.Unum.USearch.Tests/USearchIndexTests.cs +0 -1013
- package/csharp/src/Cloud.Unum.USearch.Tests/Usings.cs +0 -1
- package/docs/_static/custom.css +0 -26
- package/docs/_static/custom.js +0 -7
- package/docs/benchmarks.md +0 -245
- package/docs/benchmarks.rst +0 -5
- package/docs/c/index.rst +0 -11
- package/docs/c/reference.rst +0 -7
- package/docs/conf.dox +0 -2668
- package/docs/conf.py +0 -53
- package/docs/contributing.rst +0 -5
- package/docs/cpp/index.rst +0 -11
- package/docs/cpp/reference.rst +0 -17
- package/docs/csharp/index.rst +0 -6
- package/docs/format.md +0 -86
- package/docs/format.rst +0 -5
- package/docs/golang/index.rst +0 -6
- package/docs/index.rst +0 -33
- package/docs/java/index.rst +0 -11
- package/docs/java/reference.rst +0 -7
- package/docs/javascript/index.rst +0 -11
- package/docs/javascript/reference.rst +0 -12
- package/docs/python/index.rst +0 -11
- package/docs/python/reference.rst +0 -42
- package/docs/rust/index.rst +0 -6
- package/docs/swift/index.rst +0 -6
- package/docs/wolfram/index.rst +0 -6
- package/golang/README.md +0 -95
- package/golang/go.mod +0 -3
- package/golang/lib.go +0 -379
- package/golang/lib_test.go +0 -108
- package/java/README.md +0 -22
- package/java/cloud/unum/usearch/Index.java +0 -337
- package/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp +0 -197
- package/java/cloud/unum/usearch/cloud_unum_usearch_Index.h +0 -125
- package/java/test/IndexTest.java +0 -30
- package/objc/USearchObjective.mm +0 -299
- package/objc/include/USearchObjective.h +0 -154
- package/python/README.md +0 -292
- package/python/lib.cpp +0 -1216
- package/python/scripts/bench.ipynb +0 -193
- package/python/scripts/bench.py +0 -137
- package/python/scripts/bench_exact.py +0 -44
- package/python/scripts/cluster.ipynb +0 -160
- package/python/scripts/index_faiss.py +0 -100
- package/python/scripts/join.py +0 -155
- package/python/scripts/test_index.py +0 -247
- package/python/scripts/test_jit.py +0 -231
- package/python/scripts/test_sparse.py +0 -32
- package/python/scripts/test_tooling.py +0 -133
- package/python/usearch/__init__.py +0 -0
- package/python/usearch/client.py +0 -124
- package/python/usearch/eval.py +0 -470
- package/python/usearch/index.py +0 -1401
- package/python/usearch/io.py +0 -113
- package/python/usearch/numba.py +0 -121
- package/python/usearch/server.py +0 -137
- package/rust/README.md +0 -66
- package/rust/lib.cpp +0 -136
- package/rust/lib.hpp +0 -69
- package/rust/lib.rs +0 -610
- package/simsimd/CMakeLists.txt +0 -67
- package/simsimd/cpp/bench.cxx +0 -206
- package/simsimd/package-ci.json +0 -10
- package/simsimd/setup.py +0 -86
- package/swift/Index+Sugar.swift +0 -153
- package/swift/README.md +0 -48
- package/swift/Test.swift +0 -37
- package/swift/USearch.swift +0 -8
- package/wasm/CMakeLists.txt +0 -7
- package/wasm/README.md +0 -13
- package/wasm/lib.cpp +0 -5
- package/wolfram/CMakeLists.txt +0 -18
- package/wolfram/README.md +0 -13
- package/wolfram/lib.cpp +0 -160
- package/wolfram/test.wls +0 -27
package/simsimd/cpp/bench.cxx
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
#include <cmath> // `std::sqrt`
|
|
2
|
-
#include <thread> // `std::thread`
|
|
3
|
-
|
|
4
|
-
#include <benchmark/benchmark.h>
|
|
5
|
-
|
|
6
|
-
#define SIMSIMD_RSQRT(x) (1 / sqrtf(x))
|
|
7
|
-
#define SIMSIMD_LOG(x) (logf(x))
|
|
8
|
-
#include <simsimd/simsimd.h>
|
|
9
|
-
|
|
10
|
-
namespace bm = benchmark;
|
|
11
|
-
|
|
12
|
-
template <typename return_at, typename... args_at>
|
|
13
|
-
constexpr std::size_t number_of_arguments(return_at (*f)(args_at...)) {
|
|
14
|
-
return sizeof...(args_at);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
template <typename scalar_at, std::size_t dimensions_ak> struct vectors_pair_gt {
|
|
18
|
-
scalar_at a[dimensions_ak]{};
|
|
19
|
-
scalar_at b[dimensions_ak]{};
|
|
20
|
-
|
|
21
|
-
std::size_t dimensions() const noexcept { return dimensions_ak; }
|
|
22
|
-
std::size_t size_bytes() const noexcept { return dimensions_ak * sizeof(scalar_at); }
|
|
23
|
-
|
|
24
|
-
void set(scalar_at v) noexcept {
|
|
25
|
-
for (std::size_t i = 0; i != dimensions_ak; ++i)
|
|
26
|
-
a[i] = b[i] = v;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
void randomize() noexcept {
|
|
30
|
-
|
|
31
|
-
double a2_sum = 0, b2_sum = 0;
|
|
32
|
-
for (std::size_t i = 0; i != dimensions_ak; ++i) {
|
|
33
|
-
if constexpr (std::is_integral_v<scalar_at>)
|
|
34
|
-
a[i] = static_cast<scalar_at>(rand()), b[i] = static_cast<scalar_at>(rand());
|
|
35
|
-
else {
|
|
36
|
-
double ai = double(rand()) / double(RAND_MAX), bi = double(rand()) / double(RAND_MAX);
|
|
37
|
-
a2_sum += ai * ai, b2_sum += bi * bi;
|
|
38
|
-
a[i] = static_cast<scalar_at>(ai), b[i] = static_cast<scalar_at>(bi);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Normalize the vectors:
|
|
43
|
-
if constexpr (!std::is_integral_v<scalar_at>) {
|
|
44
|
-
a2_sum = std::sqrt(a2_sum);
|
|
45
|
-
b2_sum = std::sqrt(b2_sum);
|
|
46
|
-
for (std::size_t i = 0; i != dimensions_ak; ++i)
|
|
47
|
-
a[i] = static_cast<scalar_at>(a[i] / a2_sum), b[i] = static_cast<scalar_at>(b[i] / b2_sum);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
template <typename pair_at, typename metric_at = void>
|
|
53
|
-
static void measure(bm::State& state, metric_at metric, metric_at baseline) {
|
|
54
|
-
|
|
55
|
-
pair_at pair;
|
|
56
|
-
pair.randomize();
|
|
57
|
-
// pair.set(1);
|
|
58
|
-
|
|
59
|
-
double c_baseline = baseline(pair.a, pair.b, pair.dimensions());
|
|
60
|
-
double c = 0;
|
|
61
|
-
std::size_t iterations = 0;
|
|
62
|
-
for (auto _ : state)
|
|
63
|
-
bm::DoNotOptimize((c = metric(pair.a, pair.b, pair.dimensions()))), iterations++;
|
|
64
|
-
|
|
65
|
-
state.counters["bytes"] = bm::Counter(iterations * pair.size_bytes() * 2, bm::Counter::kIsRate);
|
|
66
|
-
state.counters["pairs"] = bm::Counter(iterations, bm::Counter::kIsRate);
|
|
67
|
-
|
|
68
|
-
double delta = std::abs(c - c_baseline) > 0.0001 ? std::abs(c - c_baseline) : 0;
|
|
69
|
-
double error = delta != 0 && c_baseline != 0 ? delta / c_baseline : 0;
|
|
70
|
-
state.counters["abs_delta"] = delta;
|
|
71
|
-
state.counters["relative_error"] = error;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
template <typename scalar_at, typename metric_at = void>
|
|
75
|
-
void register_(std::string name, metric_at* distance_func, metric_at* baseline_func) {
|
|
76
|
-
|
|
77
|
-
using pair_dims_t = vectors_pair_gt<scalar_at, 1536>;
|
|
78
|
-
using pair_bytes_t = vectors_pair_gt<scalar_at, 1536 / sizeof(scalar_at)>;
|
|
79
|
-
|
|
80
|
-
std::size_t seconds = 10;
|
|
81
|
-
std::size_t threads = 1; // std::thread::hardware_concurrency(); // 1;
|
|
82
|
-
std::string name_dims = name + "_" + std::to_string(pair_dims_t{}.dimensions()) + "d";
|
|
83
|
-
std::string name_bytes = name + "_" + std::to_string(pair_bytes_t{}.size_bytes()) + "b";
|
|
84
|
-
|
|
85
|
-
bm::RegisterBenchmark(name_dims.c_str(), measure<pair_dims_t, metric_at*>, distance_func, baseline_func)
|
|
86
|
-
->MinTime(seconds)
|
|
87
|
-
->Threads(threads);
|
|
88
|
-
bm::RegisterBenchmark(name_bytes.c_str(), measure<pair_bytes_t, metric_at*>, distance_func, baseline_func)
|
|
89
|
-
->MinTime(seconds)
|
|
90
|
-
->Threads(threads);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
int main(int argc, char** argv) {
|
|
94
|
-
|
|
95
|
-
bool compiled_with_sve = false;
|
|
96
|
-
bool compiled_with_neon = false;
|
|
97
|
-
bool compiled_with_avx2 = false;
|
|
98
|
-
bool compiled_with_avx512vpopcntdq = false;
|
|
99
|
-
bool compiled_with_avx512vnni = false;
|
|
100
|
-
|
|
101
|
-
#if defined(__ARM_FEATURE_SVE)
|
|
102
|
-
compiled_with_sve = true;
|
|
103
|
-
#endif
|
|
104
|
-
#if defined(__ARM_NEON)
|
|
105
|
-
compiled_with_neon = true;
|
|
106
|
-
#endif
|
|
107
|
-
#if defined(__AVX2__)
|
|
108
|
-
compiled_with_avx2 = true;
|
|
109
|
-
#endif
|
|
110
|
-
#if defined(__AVX512VPOPCNTDQ__)
|
|
111
|
-
compiled_with_avx512vpopcntdq = true;
|
|
112
|
-
#endif
|
|
113
|
-
#if defined(__AVX512VNNI__)
|
|
114
|
-
compiled_with_avx512vnni = true;
|
|
115
|
-
#endif
|
|
116
|
-
|
|
117
|
-
// Log supported functionality
|
|
118
|
-
char const* flags[2] = {"false", "true"};
|
|
119
|
-
std::printf("Benchmarking Similarity Measures\n");
|
|
120
|
-
std::printf("\n");
|
|
121
|
-
std::printf("- Arm NEON support enabled: %s\n", flags[compiled_with_neon]);
|
|
122
|
-
std::printf("- Arm SVE support enabled: %s\n", flags[compiled_with_sve]);
|
|
123
|
-
std::printf("- x86 AVX2 support enabled: %s\n", flags[compiled_with_avx2]);
|
|
124
|
-
std::printf("- x86 AVX512VPOPCNTDQ support enabled: %s\n", flags[compiled_with_avx512vpopcntdq]);
|
|
125
|
-
std::printf("- x86 AVX512VNNI support enabled: %s\n", flags[compiled_with_avx512vnni]);
|
|
126
|
-
std::printf("\n");
|
|
127
|
-
|
|
128
|
-
// Run the benchmarks
|
|
129
|
-
bm::Initialize(&argc, argv);
|
|
130
|
-
if (bm::ReportUnrecognizedArguments(argc, argv))
|
|
131
|
-
return 1;
|
|
132
|
-
|
|
133
|
-
#if SIMSIMD_TARGET_ARM_NEON
|
|
134
|
-
register_<simsimd_f16_t>("neon_f16_ip", simsimd_neon_f16_ip, simsimd_accurate_f16_ip);
|
|
135
|
-
register_<simsimd_f16_t>("neon_f16_cos", simsimd_neon_f16_cos, simsimd_accurate_f16_cos);
|
|
136
|
-
register_<simsimd_f16_t>("neon_f16_l2sq", simsimd_neon_f16_l2sq, simsimd_accurate_f16_l2sq);
|
|
137
|
-
register_<simsimd_f16_t>("neon_f16_kl", simsimd_neon_f16_kl, simsimd_accurate_f16_kl);
|
|
138
|
-
register_<simsimd_f16_t>("neon_f16_js", simsimd_neon_f16_js, simsimd_accurate_f16_js);
|
|
139
|
-
|
|
140
|
-
register_<simsimd_f32_t>("neon_f32_ip", simsimd_neon_f32_ip, simsimd_accurate_f32_ip);
|
|
141
|
-
register_<simsimd_f32_t>("neon_f32_cos", simsimd_neon_f32_cos, simsimd_accurate_f32_cos);
|
|
142
|
-
register_<simsimd_f32_t>("neon_f32_l2sq", simsimd_neon_f32_l2sq, simsimd_accurate_f32_l2sq);
|
|
143
|
-
register_<simsimd_f32_t>("neon_f32_kl", simsimd_neon_f32_kl, simsimd_accurate_f32_kl);
|
|
144
|
-
register_<simsimd_f32_t>("neon_f32_js", simsimd_neon_f32_js, simsimd_accurate_f32_js);
|
|
145
|
-
|
|
146
|
-
register_<simsimd_i8_t>("neon_i8_cos", simsimd_neon_i8_cos, simsimd_accurate_i8_cos);
|
|
147
|
-
register_<simsimd_i8_t>("neon_i8_l2sq", simsimd_neon_i8_l2sq, simsimd_accurate_i8_l2sq);
|
|
148
|
-
#endif
|
|
149
|
-
|
|
150
|
-
#if SIMSIMD_TARGET_ARM_SVE
|
|
151
|
-
register_<simsimd_f16_t>("sve_f16_ip", simsimd_sve_f16_ip, simsimd_accurate_f16_ip);
|
|
152
|
-
register_<simsimd_f16_t>("sve_f16_cos", simsimd_sve_f16_cos, simsimd_accurate_f16_cos);
|
|
153
|
-
register_<simsimd_f16_t>("sve_f16_l2sq", simsimd_sve_f16_l2sq, simsimd_accurate_f16_l2sq);
|
|
154
|
-
|
|
155
|
-
register_<simsimd_f32_t>("sve_f32_ip", simsimd_sve_f32_ip, simsimd_accurate_f32_ip);
|
|
156
|
-
register_<simsimd_f32_t>("sve_f32_cos", simsimd_sve_f32_cos, simsimd_accurate_f32_cos);
|
|
157
|
-
register_<simsimd_f32_t>("sve_f32_l2sq", simsimd_sve_f32_l2sq, simsimd_accurate_f32_l2sq);
|
|
158
|
-
#endif
|
|
159
|
-
|
|
160
|
-
#if SIMSIMD_TARGET_X86_AVX2
|
|
161
|
-
register_<simsimd_f16_t>("avx2_f16_ip", simsimd_avx2_f16_ip, simsimd_accurate_f16_ip);
|
|
162
|
-
register_<simsimd_f16_t>("avx2_f16_cos", simsimd_avx2_f16_cos, simsimd_accurate_f16_cos);
|
|
163
|
-
register_<simsimd_f16_t>("avx2_f16_l2sq", simsimd_avx2_f16_l2sq, simsimd_accurate_f16_l2sq);
|
|
164
|
-
register_<simsimd_f16_t>("avx2_f16_kl", simsimd_avx2_f16_kl, simsimd_accurate_f16_kl);
|
|
165
|
-
register_<simsimd_f16_t>("avx2_f16_js", simsimd_avx2_f16_js, simsimd_accurate_f16_js);
|
|
166
|
-
|
|
167
|
-
register_<simsimd_i8_t>("avx2_i8_cos", simsimd_avx2_i8_cos, simsimd_accurate_i8_cos);
|
|
168
|
-
register_<simsimd_i8_t>("avx2_i8_l2sq", simsimd_avx2_i8_l2sq, simsimd_accurate_i8_l2sq);
|
|
169
|
-
#endif
|
|
170
|
-
|
|
171
|
-
#if SIMSIMD_TARGET_X86_AVX512
|
|
172
|
-
register_<simsimd_f16_t>("avx512_f16_ip", simsimd_avx512_f16_ip, simsimd_accurate_f16_ip);
|
|
173
|
-
register_<simsimd_f16_t>("avx512_f16_cos", simsimd_avx512_f16_cos, simsimd_accurate_f16_cos);
|
|
174
|
-
register_<simsimd_f16_t>("avx512_f16_l2sq", simsimd_avx512_f16_l2sq, simsimd_accurate_f16_l2sq);
|
|
175
|
-
register_<simsimd_f16_t>("avx512_f16_kl", simsimd_avx512_f16_kl, simsimd_accurate_f16_kl);
|
|
176
|
-
register_<simsimd_f16_t>("avx512_f16_js", simsimd_avx512_f16_js, simsimd_accurate_f16_js);
|
|
177
|
-
|
|
178
|
-
register_<simsimd_i8_t>("avx512_i8_cos", simsimd_avx512_i8_cos, simsimd_accurate_i8_cos);
|
|
179
|
-
register_<simsimd_i8_t>("avx512_i8_l2sq", simsimd_avx512_i8_l2sq, simsimd_accurate_i8_l2sq);
|
|
180
|
-
|
|
181
|
-
register_<simsimd_f32_t>("avx512_f32_ip", simsimd_avx512_f32_ip, simsimd_accurate_f32_ip);
|
|
182
|
-
register_<simsimd_f32_t>("avx512_f32_cos", simsimd_avx512_f32_cos, simsimd_accurate_f32_cos);
|
|
183
|
-
register_<simsimd_f32_t>("avx512_f32_l2sq", simsimd_avx512_f32_l2sq, simsimd_accurate_f32_l2sq);
|
|
184
|
-
register_<simsimd_f32_t>("avx512_f32_kl", simsimd_avx512_f32_kl, simsimd_accurate_f32_kl);
|
|
185
|
-
register_<simsimd_f32_t>("avx512_f32_js", simsimd_avx512_f32_js, simsimd_accurate_f32_js);
|
|
186
|
-
#endif
|
|
187
|
-
|
|
188
|
-
register_<simsimd_f16_t>("serial_f16_ip", simsimd_serial_f16_ip, simsimd_accurate_f16_ip);
|
|
189
|
-
register_<simsimd_f16_t>("serial_f16_cos", simsimd_serial_f16_cos, simsimd_accurate_f16_cos);
|
|
190
|
-
register_<simsimd_f16_t>("serial_f16_l2sq", simsimd_serial_f16_l2sq, simsimd_accurate_f16_l2sq);
|
|
191
|
-
register_<simsimd_f16_t>("serial_f16_kl", simsimd_serial_f16_kl, simsimd_accurate_f16_kl);
|
|
192
|
-
register_<simsimd_f16_t>("serial_f16_js", simsimd_serial_f16_js, simsimd_accurate_f16_js);
|
|
193
|
-
|
|
194
|
-
register_<simsimd_f32_t>("serial_f32_ip", simsimd_serial_f32_ip, simsimd_accurate_f32_ip);
|
|
195
|
-
register_<simsimd_f32_t>("serial_f32_cos", simsimd_serial_f32_cos, simsimd_accurate_f32_cos);
|
|
196
|
-
register_<simsimd_f32_t>("serial_f32_l2sq", simsimd_serial_f32_l2sq, simsimd_accurate_f32_l2sq);
|
|
197
|
-
register_<simsimd_f32_t>("serial_f32_kl", simsimd_serial_f32_kl, simsimd_accurate_f32_kl);
|
|
198
|
-
register_<simsimd_f32_t>("serial_f32_js", simsimd_serial_f32_js, simsimd_accurate_f32_js);
|
|
199
|
-
|
|
200
|
-
register_<simsimd_i8_t>("serial_i8_cos", simsimd_serial_i8_cos, simsimd_accurate_i8_cos);
|
|
201
|
-
register_<simsimd_i8_t>("serial_i8_l2sq", simsimd_serial_i8_l2sq, simsimd_accurate_i8_l2sq);
|
|
202
|
-
|
|
203
|
-
bm::RunSpecifiedBenchmarks();
|
|
204
|
-
bm::Shutdown();
|
|
205
|
-
return 0;
|
|
206
|
-
}
|
package/simsimd/package-ci.json
DELETED
package/simsimd/setup.py
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sys
|
|
3
|
-
import platform
|
|
4
|
-
from os.path import dirname
|
|
5
|
-
from setuptools import setup, Extension
|
|
6
|
-
|
|
7
|
-
import glob
|
|
8
|
-
import numpy
|
|
9
|
-
|
|
10
|
-
__version__ = open("VERSION", "r").read().strip()
|
|
11
|
-
__lib_name__ = "simsimd"
|
|
12
|
-
|
|
13
|
-
compile_args = []
|
|
14
|
-
link_args = []
|
|
15
|
-
macros_args = []
|
|
16
|
-
|
|
17
|
-
if sys.platform == "linux":
|
|
18
|
-
compile_args.append("-std=c11")
|
|
19
|
-
compile_args.append("-O3")
|
|
20
|
-
compile_args.append("-ffast-math")
|
|
21
|
-
compile_args.append("-fdiagnostics-color=always")
|
|
22
|
-
|
|
23
|
-
# Disable warnings
|
|
24
|
-
compile_args.append("-w")
|
|
25
|
-
|
|
26
|
-
# Enable OpenMP for Linux
|
|
27
|
-
compile_args.append("-fopenmp")
|
|
28
|
-
link_args.append("-lgomp")
|
|
29
|
-
|
|
30
|
-
# Add vectorized `logf` implementation from the `glibc`
|
|
31
|
-
link_args.append("-lm")
|
|
32
|
-
|
|
33
|
-
if sys.platform == "darwin":
|
|
34
|
-
compile_args.append("-std=c11")
|
|
35
|
-
compile_args.append("-O3")
|
|
36
|
-
compile_args.append("-ffast-math")
|
|
37
|
-
|
|
38
|
-
# Disable warnings
|
|
39
|
-
compile_args.append("-w")
|
|
40
|
-
|
|
41
|
-
if sys.platform == "win32":
|
|
42
|
-
compile_args.append("/std:c11")
|
|
43
|
-
compile_args.append("/O2")
|
|
44
|
-
compile_args.append("/fp:fast")
|
|
45
|
-
|
|
46
|
-
# Dealing with MinGW linking errors
|
|
47
|
-
# https://cibuildwheel.readthedocs.io/en/stable/faq/#windows-importerror-dll-load-failed-the-specific-module-could-not-be-found
|
|
48
|
-
compile_args.append("/d2FH4-")
|
|
49
|
-
|
|
50
|
-
ext_modules = [
|
|
51
|
-
Extension(
|
|
52
|
-
"simsimd",
|
|
53
|
-
sources=["python/lib.c"],
|
|
54
|
-
include_dirs=["include", numpy.get_include()],
|
|
55
|
-
extra_compile_args=compile_args,
|
|
56
|
-
extra_link_args=link_args,
|
|
57
|
-
define_macros=macros_args,
|
|
58
|
-
),
|
|
59
|
-
]
|
|
60
|
-
|
|
61
|
-
this_directory = os.path.abspath(dirname(__file__))
|
|
62
|
-
with open(os.path.join(this_directory, "README.md"), "r", encoding="utf8") as f:
|
|
63
|
-
long_description = f.read()
|
|
64
|
-
|
|
65
|
-
setup(
|
|
66
|
-
name=__lib_name__,
|
|
67
|
-
version=__version__,
|
|
68
|
-
author="Ash Vardanian",
|
|
69
|
-
author_email="1983160+ashvardanian@users.noreply.github.com",
|
|
70
|
-
url="https://github.com/ashvardanian/simsimd",
|
|
71
|
-
description="Vector Similarity Functions 3x-200x Faster than SciPy and NumPy",
|
|
72
|
-
long_description=long_description,
|
|
73
|
-
long_description_content_type="text/markdown",
|
|
74
|
-
license="Apache-2.0",
|
|
75
|
-
classifiers=[
|
|
76
|
-
"Development Status :: 5 - Production/Stable",
|
|
77
|
-
"Natural Language :: English",
|
|
78
|
-
"Intended Audience :: Developers",
|
|
79
|
-
"Intended Audience :: Information Technology",
|
|
80
|
-
"License :: OSI Approved :: Apache Software License",
|
|
81
|
-
"Programming Language :: C",
|
|
82
|
-
"Programming Language :: Python :: Implementation :: CPython",
|
|
83
|
-
],
|
|
84
|
-
ext_modules=ext_modules,
|
|
85
|
-
zip_safe=False,
|
|
86
|
-
)
|
package/swift/Index+Sugar.swift
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Index+Sugar.swift
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// Created by Ash Vardanian on 5/11/23.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
@available(iOS 13, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
|
|
9
|
-
extension USearchIndex {
|
|
10
|
-
public typealias Key = USearchKey
|
|
11
|
-
public typealias Metric = USearchMetric
|
|
12
|
-
public typealias Scalar = USearchScalar
|
|
13
|
-
|
|
14
|
-
/// Adds a labeled vector to the index.
|
|
15
|
-
/// - Parameter key: Unique identifer for that object.
|
|
16
|
-
/// - Parameter vector: Single-precision vector.
|
|
17
|
-
/// - Throws: If runs out of memory.
|
|
18
|
-
public func add(key: USearchKey, vector: ArraySlice<Float32>) {
|
|
19
|
-
vector.withContiguousStorageIfAvailable {
|
|
20
|
-
addSingle(key: key, vector: $0.baseAddress!)
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/// Adds a labeled vector to the index.
|
|
25
|
-
/// - Parameter key: Unique identifer for that object.
|
|
26
|
-
/// - Parameter vector: Single-precision vector.
|
|
27
|
-
/// - Throws: If runs out of memory.
|
|
28
|
-
public func add(key: USearchKey, vector: Array<Float32>) {
|
|
29
|
-
add(key: key, vector: vector[...])
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/// Approximate nearest neighbors search.
|
|
33
|
-
/// - Parameter vector: Single-precision query vector.
|
|
34
|
-
/// - Parameter count: Upper limit on the number of matches to retrieve.
|
|
35
|
-
/// - Returns: Labels and distances to closest approximate matches in decreasing similarity order.
|
|
36
|
-
/// - Throws: If runs out of memory.
|
|
37
|
-
public func search(vector: ArraySlice<Float32>, count: Int) -> ([Key], [Float]) {
|
|
38
|
-
var matches: [Key] = Array(repeating: 0, count: count)
|
|
39
|
-
var distances: [Float] = Array(repeating: 0, count: count)
|
|
40
|
-
let results = vector.withContiguousStorageIfAvailable {
|
|
41
|
-
searchSingle(vector: $0.baseAddress!, count: CUnsignedInt(count), keys: &matches, distances: &distances)
|
|
42
|
-
}
|
|
43
|
-
matches.removeLast(count - Int(results!))
|
|
44
|
-
distances.removeLast(count - Int(results!))
|
|
45
|
-
return (matches, distances)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/// Approximate nearest neighbors search.
|
|
49
|
-
/// - Parameter vector: Single-precision query vector.
|
|
50
|
-
/// - Parameter count: Upper limit on the number of matches to retrieve.
|
|
51
|
-
/// - Returns: Labels and distances to closest approximate matches in decreasing similarity order.
|
|
52
|
-
/// - Throws: If runs out of memory.
|
|
53
|
-
public func search(vector: Array<Float32>, count: Int) -> ([Key], [Float]) {
|
|
54
|
-
return search(vector: vector[...], count: count)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/// Adds a labeled vector to the index.
|
|
58
|
-
/// - Parameter key: Unique identifer for that object.
|
|
59
|
-
/// - Parameter vector: Double-precision vector.
|
|
60
|
-
/// - Throws: If runs out of memory.
|
|
61
|
-
public func add(key: Key, vector: ArraySlice<Float64>) {
|
|
62
|
-
vector.withContiguousStorageIfAvailable {
|
|
63
|
-
addDouble(key: key, vector: $0.baseAddress!)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/// Adds a labeled vector to the index.
|
|
68
|
-
/// - Parameter key: Unique identifer for that object.
|
|
69
|
-
/// - Parameter vector: Double-precision vector.
|
|
70
|
-
/// - Throws: If runs out of memory.
|
|
71
|
-
public func add(key: Key, vector: Array<Float64>) {
|
|
72
|
-
add(key: key, vector: vector[...])
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/// Approximate nearest neighbors search.
|
|
76
|
-
/// - Parameter vector: Double-precision query vector.
|
|
77
|
-
/// - Parameter count: Upper limit on the number of matches to retrieve.
|
|
78
|
-
/// - Returns: Labels and distances to closest approximate matches in decreasing similarity order.
|
|
79
|
-
/// - Throws: If runs out of memory.
|
|
80
|
-
public func search(vector: ArraySlice<Float64>, count: Int) -> ([Key], [Float]) {
|
|
81
|
-
var matches: [Key] = Array(repeating: 0, count: count)
|
|
82
|
-
var distances: [Float] = Array(repeating: 0, count: count)
|
|
83
|
-
let results = vector.withContiguousStorageIfAvailable {
|
|
84
|
-
searchDouble(vector: $0.baseAddress!, count: CUnsignedInt(count), keys: &matches, distances: &distances)
|
|
85
|
-
}
|
|
86
|
-
matches.removeLast(count - Int(results!))
|
|
87
|
-
distances.removeLast(count - Int(results!))
|
|
88
|
-
return (matches, distances)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/// Approximate nearest neighbors search.
|
|
92
|
-
/// - Parameter vector: Double-precision query vector.
|
|
93
|
-
/// - Parameter count: Upper limit on the number of matches to retrieve.
|
|
94
|
-
/// - Returns: Labels and distances to closest approximate matches in decreasing similarity order.
|
|
95
|
-
/// - Throws: If runs out of memory.
|
|
96
|
-
public func search(vector: Array<Float64>, count: Int) -> ([Key], [Float]) {
|
|
97
|
-
search(vector: vector[...], count: count)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
#if arch(arm64)
|
|
101
|
-
|
|
102
|
-
/// Adds a labeled vector to the index.
|
|
103
|
-
/// - Parameter key: Unique identifer for that object.
|
|
104
|
-
/// - Parameter vector: Half-precision vector.
|
|
105
|
-
/// - Throws: If runs out of memory.
|
|
106
|
-
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
|
|
107
|
-
public func add(key: Key, vector: ArraySlice<Float16>) {
|
|
108
|
-
vector.withContiguousStorageIfAvailable { buffer in
|
|
109
|
-
addHalf(key: key, vector: buffer.baseAddress!)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/// Adds a labeled vector to the index.
|
|
114
|
-
/// - Parameter key: Unique identifer for that object.
|
|
115
|
-
/// - Parameter vector: Half-precision vector.
|
|
116
|
-
/// - Throws: If runs out of memory.
|
|
117
|
-
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
|
|
118
|
-
public func add(key: Key, vector: Array<Float16>) {
|
|
119
|
-
add(key: key, vector: vector[...])
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/// Approximate nearest neighbors search.
|
|
123
|
-
/// - Parameter vector: Half-precision query vector.
|
|
124
|
-
/// - Parameter count: Upper limit on the number of matches to retrieve.
|
|
125
|
-
/// - Returns: Labels and distances to closest approximate matches in decreasing similarity order.
|
|
126
|
-
/// - Throws: If runs out of memory.
|
|
127
|
-
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
|
|
128
|
-
public func search(vector: ArraySlice<Float16>, count: Int) -> ([Key], [Float]) {
|
|
129
|
-
var matches: [Key] = Array(repeating: 0, count: count)
|
|
130
|
-
var distances: [Float] = Array(repeating: 0, count: count)
|
|
131
|
-
let results = vector.withContiguousStorageIfAvailable {
|
|
132
|
-
searchHalf(vector: $0.baseAddress!, count: CUnsignedInt(count), keys: &matches, distances: &distances)
|
|
133
|
-
}
|
|
134
|
-
matches.removeLast(count - Int(results!))
|
|
135
|
-
distances.removeLast(count - Int(results!))
|
|
136
|
-
return (matches, distances)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/// Approximate nearest neighbors search.
|
|
140
|
-
/// - Parameter vector: Half-precision query vector.
|
|
141
|
-
/// - Parameter count: Upper limit on the number of matches to retrieve.
|
|
142
|
-
/// - Returns: Labels and distances to closest approximate matches in decreasing similarity order.
|
|
143
|
-
/// - Throws: If runs out of memory.
|
|
144
|
-
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
|
|
145
|
-
public func search(vector: Array<Float16>, count: Int) -> ([Key], [Float]) {
|
|
146
|
-
search(vector: vector[...], count: count)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
#endif
|
|
150
|
-
|
|
151
|
-
/// Number of vectors in the index.
|
|
152
|
-
public var count: Int { return Int(length) }
|
|
153
|
-
}
|
package/swift/README.md
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# USearch for Swift
|
|
2
|
-
|
|
3
|
-
## Installation
|
|
4
|
-
|
|
5
|
-
```txt
|
|
6
|
-
https://github.com/unum-cloud/usearch
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
## Quickstart
|
|
10
|
-
|
|
11
|
-
```swift
|
|
12
|
-
let index = USearchIndex.make(metric: .Cos, dimensions: 3, connectivity: 8)
|
|
13
|
-
let vectorA: [Float32] = [0.3, 0.5, 1.2] // `Float32` and `Float64` are always supported
|
|
14
|
-
let vectorB: [Float32] = [0.4, 0.2, 1.2] // `Float16` supports on the OS & hardware version
|
|
15
|
-
index.add(key: 42, vector: vectorA) // Pass full arrays or slices
|
|
16
|
-
index.add(key: 43, vector: vectorB)
|
|
17
|
-
|
|
18
|
-
let results = index.search(vector: vectorA, count: 10)
|
|
19
|
-
assert(results.0[0] == 42)
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
If using in a SwiftUI application, make sure to annulate the void responses:
|
|
23
|
-
|
|
24
|
-
```swift
|
|
25
|
-
import SwiftUI
|
|
26
|
-
import USearch
|
|
27
|
-
|
|
28
|
-
@main
|
|
29
|
-
struct USearchMobileApp: App {
|
|
30
|
-
var body: some Scene {
|
|
31
|
-
WindowGroup {
|
|
32
|
-
let index = USearchIndex.make(metric: .IP, dimensions: 2, connectivity: 16, quantization: .F32)
|
|
33
|
-
let _ = index.reserve(10)
|
|
34
|
-
let coordiantes: Array<Float32> = [40.177200, 44.503490]
|
|
35
|
-
let _ = index.add(key: 10, vector: coordiantes)
|
|
36
|
-
VStack {
|
|
37
|
-
Text("USearch index contains \(index.length) vectors")
|
|
38
|
-
Spacer()
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
You can find a working example of using USearch with SwiftUI maps at [ashvardanian/SwiftVectorSearch](https://github.com/ashvardanian/SwiftVectorSearch).
|
|
47
|
-
|
|
48
|
-
[](https://github.com/ashvardanian/SwiftVectorSearch)
|
package/swift/Test.swift
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// File.swift
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// Created by Ash Vardanian on 5/11/23.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
import Foundation
|
|
9
|
-
import USearch
|
|
10
|
-
import XCTest
|
|
11
|
-
|
|
12
|
-
@available(iOS 13, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
|
|
13
|
-
class Test: XCTestCase {
|
|
14
|
-
func testUnit() throws {
|
|
15
|
-
let index = USearchIndex.make(metric: USearchMetric.l2sq, dimensions: 4, connectivity: 8, quantization: USearchScalar.F32)
|
|
16
|
-
let vectorA: [Float32] = [0.3, 0.5, 1.2, 1.4]
|
|
17
|
-
let vectorB: [Float32] = [0.4, 0.2, 1.2, 1.1]
|
|
18
|
-
index.reserve(2)
|
|
19
|
-
|
|
20
|
-
// Adding a slice
|
|
21
|
-
index.add(key: 42, vector: vectorA[...])
|
|
22
|
-
|
|
23
|
-
// Adding a vector
|
|
24
|
-
index.add(key: 43, vector: vectorB)
|
|
25
|
-
|
|
26
|
-
let results = index.search(vector: vectorA, count: 10)
|
|
27
|
-
assert(results.0[0] == 42)
|
|
28
|
-
|
|
29
|
-
assert(index.contains(key: 42))
|
|
30
|
-
assert(index.count(key: 42) == 1)
|
|
31
|
-
assert(index.count(key: 49) == 0)
|
|
32
|
-
index.rename(from: 42, to: 49)
|
|
33
|
-
assert(index.count(key: 49) == 1)
|
|
34
|
-
index.remove(key: 49)
|
|
35
|
-
assert(index.count(key: 49) == 0)
|
|
36
|
-
}
|
|
37
|
-
}
|
package/swift/USearch.swift
DELETED
package/wasm/CMakeLists.txt
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
include(emscripten)
|
|
2
|
-
|
|
3
|
-
# Setting the compiler globally is never a good idea! set(CMAKE_C_COMPILER emcc) set(CMAKE_CXX_COMPILER em++)
|
|
4
|
-
|
|
5
|
-
add_executable(usearch_wasm lib.cpp)
|
|
6
|
-
setup_target(usearch_wasm)
|
|
7
|
-
set_target_properties(usearch_wasm PROPERTIES CXX_STANDARD 11)
|
package/wasm/README.md
DELETED
package/wasm/lib.cpp
DELETED
package/wolfram/CMakeLists.txt
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
if(NOT WOLFRAM_PATH)
|
|
3
|
-
set(WOLFRAM_PATH "/usr/local/Wolfram/Mathematica")
|
|
4
|
-
endif()
|
|
5
|
-
|
|
6
|
-
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${WOLFRAM_PATH}/SystemFiles/Links/WSTP/DeveloperKit/Linux-x86-64/CompilerAdditions/")
|
|
7
|
-
include(WSTP)
|
|
8
|
-
include_directories("${WOLFRAM_PATH}/SystemFiles/IncludeFiles/C/")
|
|
9
|
-
link_directories("${WOLFRAM_PATH}/SystemFiles/Libraries/Linux-x86-64/")
|
|
10
|
-
|
|
11
|
-
add_library(usearchWFM SHARED lib.cpp)
|
|
12
|
-
|
|
13
|
-
# Link against the Wolfram LibraryLink library
|
|
14
|
-
target_link_libraries(usearchWFM WSTP::STATIC_LIBRARY)
|
|
15
|
-
|
|
16
|
-
# Set the output name of the library to be compatible with Wolfram Language
|
|
17
|
-
set_target_properties(usearchWFM PROPERTIES PREFIX "" OUTPUT_NAME "usearchWFM")
|
|
18
|
-
set_target_properties(usearchWFM PROPERTIES CXX_STANDARD 11)
|