usearch 2.15.2 → 2.16.0
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/README.md +1 -1
- package/binding.gyp +1 -1
- package/c/CMakeLists.txt +10 -3
- package/cpp/README.md +1 -1
- package/cpp/bench.cpp +2 -2
- package/cpp/test.cpp +16 -0
- package/include/usearch/index.hpp +44 -17
- package/include/usearch/index_dense.hpp +51 -89
- package/include/usearch/index_plugins.hpp +468 -43
- package/javascript/lib.cpp +17 -5
- package/javascript/usearch.test.js +205 -34
- package/package.json +1 -1
- package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
- package/prebuilds/linux-arm64/usearch.node +0 -0
- package/prebuilds/linux-x64/usearch.node +0 -0
- package/simsimd/.git-blame-ignore-revs +2 -0
- package/simsimd/CODE_OF_CONDUCT.md +128 -0
- package/simsimd/CONTRIBUTING.md +84 -26
- package/simsimd/Cargo.lock +1 -1
- package/simsimd/Cargo.toml +4 -4
- package/simsimd/MANIFEST.in +3 -0
- package/simsimd/Package.swift +15 -3
- package/simsimd/README.md +534 -177
- package/simsimd/binding.gyp +6 -2
- package/simsimd/build.rs +13 -1
- package/simsimd/c/lib.c +266 -53
- package/simsimd/include/simsimd/binary.h +321 -112
- package/simsimd/include/simsimd/curved.h +803 -0
- package/simsimd/include/simsimd/dot.h +694 -521
- package/simsimd/include/simsimd/elementwise.h +1437 -0
- package/simsimd/include/simsimd/geospatial.h +9 -3
- package/simsimd/include/simsimd/mesh.h +69 -0
- package/simsimd/include/simsimd/probability.h +234 -206
- package/simsimd/include/simsimd/simsimd.h +1476 -617
- package/simsimd/include/simsimd/sparse.h +1428 -0
- package/simsimd/include/simsimd/spatial.h +1556 -742
- package/simsimd/include/simsimd/types.h +276 -132
- package/simsimd/javascript/lib.c +1 -2
- package/simsimd/javascript/simsimd.ts +4 -4
- package/simsimd/package.json +4 -4
- package/simsimd/rust/lib.rs +179 -1
- package/simsimd/scripts/bench.cxx +1070 -0
- package/simsimd/scripts/bench.ipynb +187 -0
- package/simsimd/{javascript → scripts}/bench.js +1 -1
- package/simsimd/{rust/benches/sqeuclidean.rs → scripts/bench_sqeuclidean.rs} +6 -6
- package/simsimd/scripts/bench_vectors.py +700 -0
- package/simsimd/scripts/bench_vectors_live.py +213 -0
- package/simsimd/scripts/test.c +155 -0
- package/simsimd/{javascript → scripts}/test.mjs +2 -2
- package/simsimd/scripts/test.py +1410 -0
- package/simsimd/swift/{source/SimSIMD.swift → SimSIMD.swift} +6 -2
- package/simsimd/swift/{tests/SimSIMDTests.swift → Test.swift} +1 -1
- /package/simsimd/{rust/benches/cosine.rs → scripts/bench_cosine.rs} +0 -0
- /package/simsimd/{rust/benches/native.rs → scripts/bench_native.rs} +0 -0
package/simsimd/binding.gyp
CHANGED
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
"targets": [
|
|
4
4
|
{
|
|
5
5
|
"target_name": "simsimd",
|
|
6
|
-
"sources": ["javascript/lib.c"],
|
|
6
|
+
"sources": ["javascript/lib.c", "c/lib.c"],
|
|
7
7
|
"include_dirs": ["include"],
|
|
8
|
-
"defines": [
|
|
8
|
+
"defines": [
|
|
9
|
+
"SIMSIMD_NATIVE_F16=0",
|
|
10
|
+
"SIMSIMD_NATIVE_BF16=0",
|
|
11
|
+
"SIMSIMD_DYNAMIC_DISPATCH=1",
|
|
12
|
+
],
|
|
9
13
|
"cflags": [
|
|
10
14
|
"-std=c11",
|
|
11
15
|
"-ffast-math",
|
package/simsimd/build.rs
CHANGED
|
@@ -17,8 +17,20 @@ fn main() {
|
|
|
17
17
|
|
|
18
18
|
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
|
|
19
19
|
let flags_to_try = match target_arch.as_str() {
|
|
20
|
-
"arm" | "aarch64" => vec![
|
|
20
|
+
"arm" | "aarch64" => vec![
|
|
21
|
+
"SIMSIMD_TARGET_SVE2",
|
|
22
|
+
"SIMSIMD_TARGET_SVE_BF16",
|
|
23
|
+
"SIMSIMD_TARGET_SVE_F16",
|
|
24
|
+
"SIMSIMD_TARGET_SVE_I8",
|
|
25
|
+
"SIMSIMD_TARGET_SVE",
|
|
26
|
+
"SIMSIMD_TARGET_NEON_BF16",
|
|
27
|
+
"SIMSIMD_TARGET_NEON_F16",
|
|
28
|
+
"SIMSIMD_TARGET_NEON_I8",
|
|
29
|
+
"SIMSIMD_TARGET_NEON",
|
|
30
|
+
],
|
|
21
31
|
_ => vec![
|
|
32
|
+
"SIMSIMD_TARGET_SIERRA",
|
|
33
|
+
"SIMSIMD_TARGET_TURIN",
|
|
22
34
|
"SIMSIMD_TARGET_SAPPHIRE",
|
|
23
35
|
"SIMSIMD_TARGET_GENOA",
|
|
24
36
|
"SIMSIMD_TARGET_ICE",
|
package/simsimd/c/lib.c
CHANGED
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
#if !defined(SIMSIMD_TARGET_SVE) && (defined(__linux__))
|
|
21
21
|
#define SIMSIMD_TARGET_SVE 1
|
|
22
22
|
#endif
|
|
23
|
+
#if !defined(SIMSIMD_TARGET_SVE2) && (defined(__linux__))
|
|
24
|
+
#define SIMSIMD_TARGET_SVE2 1
|
|
25
|
+
#endif
|
|
23
26
|
#if !defined(SIMSIMD_TARGET_HASWELL) && (defined(_MSC_VER) || defined(__APPLE__) || defined(__linux__))
|
|
24
27
|
#define SIMSIMD_TARGET_HASWELL 1
|
|
25
28
|
#endif
|
|
@@ -35,6 +38,12 @@
|
|
|
35
38
|
#if !defined(SIMSIMD_TARGET_SAPPHIRE) && (defined(__linux__))
|
|
36
39
|
#define SIMSIMD_TARGET_SAPPHIRE 1
|
|
37
40
|
#endif
|
|
41
|
+
#if !defined(SIMSIMD_TARGET_TURIN) && (defined(__linux__))
|
|
42
|
+
#define SIMSIMD_TARGET_TURIN 1
|
|
43
|
+
#endif
|
|
44
|
+
#if !defined(SIMSIMD_TARGET_SIERRA) && (defined(__linux__)) && 0 // TODO: Add target spec to GCC & Clang
|
|
45
|
+
#define SIMSIMD_TARGET_SIERRA 1
|
|
46
|
+
#endif
|
|
38
47
|
|
|
39
48
|
#include <simsimd/simsimd.h>
|
|
40
49
|
|
|
@@ -42,72 +51,167 @@
|
|
|
42
51
|
extern "C" {
|
|
43
52
|
#endif
|
|
44
53
|
|
|
45
|
-
simsimd_capability_t simsimd_capabilities(void) {
|
|
46
|
-
static simsimd_capability_t static_capabilities = simsimd_cap_any_k;
|
|
47
|
-
if (static_capabilities == simsimd_cap_any_k)
|
|
48
|
-
static_capabilities = simsimd_capabilities_implementation();
|
|
49
|
-
return static_capabilities;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
54
|
// Every time a function is called, it checks if the metric is already loaded. If not, it fetches it.
|
|
53
55
|
// If no metric is found, it returns NaN. We can obtain NaN by dividing 0.0 by 0.0, but that annoys
|
|
54
56
|
// the MSVC compiler. Instead we can directly write-in the signaling NaN (0x7FF0000000000001)
|
|
55
57
|
// or the qNaN (0x7FF8000000000000).
|
|
56
|
-
#define
|
|
57
|
-
SIMSIMD_DYNAMIC void simsimd_##name##_##extension(simsimd_##type##_t const*
|
|
58
|
-
simsimd_size_t n, simsimd_distance_t*
|
|
59
|
-
static simsimd_metric_punned_t metric = 0;
|
|
60
|
-
if (metric == 0) {
|
|
61
|
-
simsimd_capability_t used_capability;
|
|
62
|
-
simsimd_find_metric_punned(simsimd_metric_##name##_k, simsimd_datatype_##extension##_k,
|
|
63
|
-
simsimd_capabilities(), simsimd_cap_any_k, &metric, &used_capability);
|
|
64
|
-
if (!metric) {
|
|
65
|
-
*(simsimd_u64_t*)results = 0x7FF0000000000001ull;
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
metric(a, b, n, results);
|
|
58
|
+
#define SIMSIMD_DECLARATION_DENSE(name, extension, type) \
|
|
59
|
+
SIMSIMD_DYNAMIC void simsimd_##name##_##extension(simsimd_##type##_t const *a, simsimd_##type##_t const *b, \
|
|
60
|
+
simsimd_size_t n, simsimd_distance_t *results) { \
|
|
61
|
+
static simsimd_metric_punned_t metric = 0; \
|
|
62
|
+
if (metric == 0) { \
|
|
63
|
+
simsimd_capability_t used_capability; \
|
|
64
|
+
simsimd_find_metric_punned(simsimd_metric_##name##_k, simsimd_datatype_##extension##_k, \
|
|
65
|
+
simsimd_capabilities(), simsimd_cap_any_k, &metric, &used_capability); \
|
|
66
|
+
if (!metric) { \
|
|
67
|
+
*(simsimd_u64_t *)results = 0x7FF0000000000001ull; \
|
|
68
|
+
return; \
|
|
69
|
+
} \
|
|
70
|
+
} \
|
|
71
|
+
metric(a, b, n, results); \
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#define SIMSIMD_DECLARATION_SPARSE(name, extension, type) \
|
|
75
|
+
SIMSIMD_DYNAMIC void simsimd_##name##_##extension(simsimd_##type##_t const *a, simsimd_##type##_t const *b, \
|
|
76
|
+
simsimd_size_t a_length, simsimd_size_t b_length, \
|
|
77
|
+
simsimd_distance_t *result) { \
|
|
78
|
+
static simsimd_metric_sparse_punned_t metric = 0; \
|
|
79
|
+
if (metric == 0) { \
|
|
80
|
+
simsimd_capability_t used_capability; \
|
|
81
|
+
simsimd_find_metric_punned(simsimd_metric_##name##_k, simsimd_datatype_##extension##_k, \
|
|
82
|
+
simsimd_capabilities(), simsimd_cap_any_k, \
|
|
83
|
+
(simsimd_metric_punned_t *)(&metric), &used_capability); \
|
|
84
|
+
if (!metric) { \
|
|
85
|
+
*(simsimd_u64_t *)result = 0x7FF0000000000001ull; \
|
|
86
|
+
return; \
|
|
87
|
+
} \
|
|
88
|
+
} \
|
|
89
|
+
metric(a, b, a_length, b_length, result); \
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
#define SIMSIMD_DECLARATION_CURVED(name, extension, type) \
|
|
93
|
+
SIMSIMD_DYNAMIC void simsimd_##name##_##extension(simsimd_##type##_t const *a, simsimd_##type##_t const *b, \
|
|
94
|
+
simsimd_##type##_t const *c, simsimd_size_t n, \
|
|
95
|
+
simsimd_distance_t *result) { \
|
|
96
|
+
static simsimd_metric_curved_punned_t metric = 0; \
|
|
97
|
+
if (metric == 0) { \
|
|
98
|
+
simsimd_capability_t used_capability; \
|
|
99
|
+
simsimd_find_metric_punned(simsimd_metric_##name##_k, simsimd_datatype_##extension##_k, \
|
|
100
|
+
simsimd_capabilities(), simsimd_cap_any_k, \
|
|
101
|
+
(simsimd_metric_punned_t *)(&metric), &used_capability); \
|
|
102
|
+
if (!metric) { \
|
|
103
|
+
*(simsimd_u64_t *)result = 0x7FF0000000000001ull; \
|
|
104
|
+
return; \
|
|
105
|
+
} \
|
|
106
|
+
} \
|
|
107
|
+
metric(a, b, c, n, result); \
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
#define SIMSIMD_DECLARATION_FMA(name, extension, type) \
|
|
111
|
+
SIMSIMD_DYNAMIC void simsimd_##name##_##extension( \
|
|
112
|
+
simsimd_##type##_t const *a, simsimd_##type##_t const *b, simsimd_##type##_t const *c, simsimd_size_t n, \
|
|
113
|
+
simsimd_distance_t alpha, simsimd_distance_t beta, simsimd_##type##_t *result) { \
|
|
114
|
+
static simsimd_kernel_fma_punned_t metric = 0; \
|
|
115
|
+
if (metric == 0) { \
|
|
116
|
+
simsimd_capability_t used_capability; \
|
|
117
|
+
simsimd_find_metric_punned(simsimd_metric_##name##_k, simsimd_datatype_##extension##_k, \
|
|
118
|
+
simsimd_capabilities(), simsimd_cap_any_k, \
|
|
119
|
+
(simsimd_metric_punned_t *)(&metric), &used_capability); \
|
|
120
|
+
} \
|
|
121
|
+
metric(a, b, c, n, alpha, beta, result); \
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
#define SIMSIMD_DECLARATION_WSUM(name, extension, type) \
|
|
125
|
+
SIMSIMD_DYNAMIC void simsimd_##name##_##extension(simsimd_##type##_t const *a, simsimd_##type##_t const *b, \
|
|
126
|
+
simsimd_size_t n, simsimd_distance_t alpha, \
|
|
127
|
+
simsimd_distance_t beta, simsimd_##type##_t *result) { \
|
|
128
|
+
static simsimd_kernel_wsum_punned_t metric = 0; \
|
|
129
|
+
if (metric == 0) { \
|
|
130
|
+
simsimd_capability_t used_capability; \
|
|
131
|
+
simsimd_find_metric_punned(simsimd_metric_##name##_k, simsimd_datatype_##extension##_k, \
|
|
132
|
+
simsimd_capabilities(), simsimd_cap_any_k, \
|
|
133
|
+
(simsimd_metric_punned_t *)(&metric), &used_capability); \
|
|
134
|
+
} \
|
|
135
|
+
metric(a, b, n, alpha, beta, result); \
|
|
70
136
|
}
|
|
71
137
|
|
|
72
138
|
// Dot products
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
139
|
+
SIMSIMD_DECLARATION_DENSE(dot, i8, i8)
|
|
140
|
+
SIMSIMD_DECLARATION_DENSE(dot, u8, u8)
|
|
141
|
+
SIMSIMD_DECLARATION_DENSE(dot, f16, f16)
|
|
142
|
+
SIMSIMD_DECLARATION_DENSE(dot, bf16, bf16)
|
|
143
|
+
SIMSIMD_DECLARATION_DENSE(dot, f32, f32)
|
|
144
|
+
SIMSIMD_DECLARATION_DENSE(dot, f64, f64)
|
|
145
|
+
SIMSIMD_DECLARATION_DENSE(dot, f16c, f16)
|
|
146
|
+
SIMSIMD_DECLARATION_DENSE(dot, bf16c, bf16)
|
|
147
|
+
SIMSIMD_DECLARATION_DENSE(dot, f32c, f32)
|
|
148
|
+
SIMSIMD_DECLARATION_DENSE(dot, f64c, f64)
|
|
149
|
+
SIMSIMD_DECLARATION_DENSE(vdot, f16c, f16)
|
|
150
|
+
SIMSIMD_DECLARATION_DENSE(vdot, bf16c, bf16)
|
|
151
|
+
SIMSIMD_DECLARATION_DENSE(vdot, f32c, f32)
|
|
152
|
+
SIMSIMD_DECLARATION_DENSE(vdot, f64c, f64)
|
|
85
153
|
|
|
86
154
|
// Spatial distances
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
155
|
+
SIMSIMD_DECLARATION_DENSE(cos, i8, i8)
|
|
156
|
+
SIMSIMD_DECLARATION_DENSE(cos, u8, u8)
|
|
157
|
+
SIMSIMD_DECLARATION_DENSE(cos, f16, f16)
|
|
158
|
+
SIMSIMD_DECLARATION_DENSE(cos, bf16, bf16)
|
|
159
|
+
SIMSIMD_DECLARATION_DENSE(cos, f32, f32)
|
|
160
|
+
SIMSIMD_DECLARATION_DENSE(cos, f64, f64)
|
|
161
|
+
SIMSIMD_DECLARATION_DENSE(l2sq, i8, i8)
|
|
162
|
+
SIMSIMD_DECLARATION_DENSE(l2sq, u8, u8)
|
|
163
|
+
SIMSIMD_DECLARATION_DENSE(l2sq, f16, f16)
|
|
164
|
+
SIMSIMD_DECLARATION_DENSE(l2sq, bf16, bf16)
|
|
165
|
+
SIMSIMD_DECLARATION_DENSE(l2sq, f32, f32)
|
|
166
|
+
SIMSIMD_DECLARATION_DENSE(l2sq, f64, f64)
|
|
167
|
+
SIMSIMD_DECLARATION_DENSE(l2, i8, i8)
|
|
168
|
+
SIMSIMD_DECLARATION_DENSE(l2, u8, u8)
|
|
169
|
+
SIMSIMD_DECLARATION_DENSE(l2, f16, f16)
|
|
170
|
+
SIMSIMD_DECLARATION_DENSE(l2, bf16, bf16)
|
|
171
|
+
SIMSIMD_DECLARATION_DENSE(l2, f32, f32)
|
|
172
|
+
SIMSIMD_DECLARATION_DENSE(l2, f64, f64)
|
|
97
173
|
|
|
98
174
|
// Binary distances
|
|
99
|
-
|
|
100
|
-
|
|
175
|
+
SIMSIMD_DECLARATION_DENSE(hamming, b8, b8)
|
|
176
|
+
SIMSIMD_DECLARATION_DENSE(jaccard, b8, b8)
|
|
101
177
|
|
|
102
178
|
// Probability distributions
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
179
|
+
SIMSIMD_DECLARATION_DENSE(kl, f16, f16)
|
|
180
|
+
SIMSIMD_DECLARATION_DENSE(kl, bf16, bf16)
|
|
181
|
+
SIMSIMD_DECLARATION_DENSE(kl, f32, f32)
|
|
182
|
+
SIMSIMD_DECLARATION_DENSE(kl, f64, f64)
|
|
183
|
+
SIMSIMD_DECLARATION_DENSE(js, f16, f16)
|
|
184
|
+
SIMSIMD_DECLARATION_DENSE(js, bf16, bf16)
|
|
185
|
+
SIMSIMD_DECLARATION_DENSE(js, f32, f32)
|
|
186
|
+
SIMSIMD_DECLARATION_DENSE(js, f64, f64)
|
|
187
|
+
|
|
188
|
+
// Sparse sets
|
|
189
|
+
SIMSIMD_DECLARATION_SPARSE(intersect, u16, u16)
|
|
190
|
+
SIMSIMD_DECLARATION_SPARSE(intersect, u32, u32)
|
|
191
|
+
|
|
192
|
+
// Curved spaces
|
|
193
|
+
SIMSIMD_DECLARATION_CURVED(bilinear, f64, f64)
|
|
194
|
+
SIMSIMD_DECLARATION_CURVED(mahalanobis, f64, f64)
|
|
195
|
+
SIMSIMD_DECLARATION_CURVED(bilinear, f32, f32)
|
|
196
|
+
SIMSIMD_DECLARATION_CURVED(mahalanobis, f32, f32)
|
|
197
|
+
SIMSIMD_DECLARATION_CURVED(bilinear, f16, f16)
|
|
198
|
+
SIMSIMD_DECLARATION_CURVED(mahalanobis, f16, f16)
|
|
199
|
+
SIMSIMD_DECLARATION_CURVED(bilinear, bf16, bf16)
|
|
200
|
+
SIMSIMD_DECLARATION_CURVED(mahalanobis, bf16, bf16)
|
|
201
|
+
|
|
202
|
+
// Element-wise operations
|
|
203
|
+
SIMSIMD_DECLARATION_FMA(fma, f64, f64)
|
|
204
|
+
SIMSIMD_DECLARATION_FMA(fma, f32, f32)
|
|
205
|
+
SIMSIMD_DECLARATION_FMA(fma, f16, f16)
|
|
206
|
+
SIMSIMD_DECLARATION_FMA(fma, bf16, bf16)
|
|
207
|
+
SIMSIMD_DECLARATION_FMA(fma, i8, i8)
|
|
208
|
+
SIMSIMD_DECLARATION_FMA(fma, u8, u8)
|
|
209
|
+
SIMSIMD_DECLARATION_WSUM(wsum, f64, f64)
|
|
210
|
+
SIMSIMD_DECLARATION_WSUM(wsum, f32, f32)
|
|
211
|
+
SIMSIMD_DECLARATION_WSUM(wsum, f16, f16)
|
|
212
|
+
SIMSIMD_DECLARATION_WSUM(wsum, bf16, bf16)
|
|
213
|
+
SIMSIMD_DECLARATION_WSUM(wsum, i8, i8)
|
|
214
|
+
SIMSIMD_DECLARATION_WSUM(wsum, u8, u8)
|
|
111
215
|
|
|
112
216
|
SIMSIMD_DYNAMIC int simsimd_uses_neon(void) { return (simsimd_capabilities() & simsimd_cap_neon_k) != 0; }
|
|
113
217
|
SIMSIMD_DYNAMIC int simsimd_uses_neon_f16(void) { return (simsimd_capabilities() & simsimd_cap_neon_f16_k) != 0; }
|
|
@@ -122,6 +226,115 @@ SIMSIMD_DYNAMIC int simsimd_uses_skylake(void) { return (simsimd_capabilities()
|
|
|
122
226
|
SIMSIMD_DYNAMIC int simsimd_uses_ice(void) { return (simsimd_capabilities() & simsimd_cap_ice_k) != 0; }
|
|
123
227
|
SIMSIMD_DYNAMIC int simsimd_uses_genoa(void) { return (simsimd_capabilities() & simsimd_cap_genoa_k) != 0; }
|
|
124
228
|
SIMSIMD_DYNAMIC int simsimd_uses_sapphire(void) { return (simsimd_capabilities() & simsimd_cap_sapphire_k) != 0; }
|
|
229
|
+
SIMSIMD_DYNAMIC int simsimd_uses_turin(void) { return (simsimd_capabilities() & simsimd_cap_turin_k) != 0; }
|
|
230
|
+
SIMSIMD_DYNAMIC int simsimd_uses_sierra(void) { return (simsimd_capabilities() & simsimd_cap_sierra_k) != 0; }
|
|
231
|
+
SIMSIMD_DYNAMIC int simsimd_uses_dynamic_dispatch(void) { return 1; }
|
|
232
|
+
|
|
233
|
+
SIMSIMD_DYNAMIC simsimd_capability_t simsimd_capabilities(void) {
|
|
234
|
+
//! The latency of the CPUID instruction can be over 100 cycles, so we cache the result.
|
|
235
|
+
static simsimd_capability_t static_capabilities = simsimd_cap_any_k;
|
|
236
|
+
if (static_capabilities != simsimd_cap_any_k) return static_capabilities;
|
|
237
|
+
|
|
238
|
+
static_capabilities = _simsimd_capabilities_implementation();
|
|
239
|
+
|
|
240
|
+
// In multithreaded applications we need to ensure that the function pointers are pre-initialized,
|
|
241
|
+
// so the first time we are probing for capabilities, we should also probe all of our metrics
|
|
242
|
+
// with dummy inputs:
|
|
243
|
+
simsimd_distance_t dummy_results_buffer[2];
|
|
244
|
+
simsimd_distance_t *dummy_results = &dummy_results_buffer[0];
|
|
245
|
+
void *x = 0;
|
|
246
|
+
|
|
247
|
+
// Dense:
|
|
248
|
+
simsimd_dot_i8((simsimd_i8_t *)x, (simsimd_i8_t *)x, 0, dummy_results);
|
|
249
|
+
simsimd_dot_u8((simsimd_u8_t *)x, (simsimd_u8_t *)x, 0, dummy_results);
|
|
250
|
+
simsimd_dot_f16((simsimd_f16_t *)x, (simsimd_f16_t *)x, 0, dummy_results);
|
|
251
|
+
simsimd_dot_bf16((simsimd_bf16_t *)x, (simsimd_bf16_t *)x, 0, dummy_results);
|
|
252
|
+
simsimd_dot_f32((simsimd_f32_t *)x, (simsimd_f32_t *)x, 0, dummy_results);
|
|
253
|
+
simsimd_dot_f64((simsimd_f64_t *)x, (simsimd_f64_t *)x, 0, dummy_results);
|
|
254
|
+
|
|
255
|
+
simsimd_dot_f16c((simsimd_f16_t *)x, (simsimd_f16_t *)x, 0, dummy_results);
|
|
256
|
+
simsimd_dot_bf16c((simsimd_bf16_t *)x, (simsimd_bf16_t *)x, 0, dummy_results);
|
|
257
|
+
simsimd_dot_f32c((simsimd_f32_t *)x, (simsimd_f32_t *)x, 0, dummy_results);
|
|
258
|
+
simsimd_dot_f64c((simsimd_f64_t *)x, (simsimd_f64_t *)x, 0, dummy_results);
|
|
259
|
+
simsimd_vdot_f16c((simsimd_f16_t *)x, (simsimd_f16_t *)x, 0, dummy_results);
|
|
260
|
+
simsimd_vdot_bf16c((simsimd_bf16_t *)x, (simsimd_bf16_t *)x, 0, dummy_results);
|
|
261
|
+
simsimd_vdot_f32c((simsimd_f32_t *)x, (simsimd_f32_t *)x, 0, dummy_results);
|
|
262
|
+
simsimd_vdot_f64c((simsimd_f64_t *)x, (simsimd_f64_t *)x, 0, dummy_results);
|
|
263
|
+
|
|
264
|
+
simsimd_cos_i8((simsimd_i8_t *)x, (simsimd_i8_t *)x, 0, dummy_results);
|
|
265
|
+
simsimd_cos_u8((simsimd_u8_t *)x, (simsimd_u8_t *)x, 0, dummy_results);
|
|
266
|
+
simsimd_cos_f16((simsimd_f16_t *)x, (simsimd_f16_t *)x, 0, dummy_results);
|
|
267
|
+
simsimd_cos_bf16((simsimd_bf16_t *)x, (simsimd_bf16_t *)x, 0, dummy_results);
|
|
268
|
+
simsimd_cos_f32((simsimd_f32_t *)x, (simsimd_f32_t *)x, 0, dummy_results);
|
|
269
|
+
simsimd_cos_f64((simsimd_f64_t *)x, (simsimd_f64_t *)x, 0, dummy_results);
|
|
270
|
+
|
|
271
|
+
simsimd_l2sq_i8((simsimd_i8_t *)x, (simsimd_i8_t *)x, 0, dummy_results);
|
|
272
|
+
simsimd_l2sq_u8((simsimd_u8_t *)x, (simsimd_u8_t *)x, 0, dummy_results);
|
|
273
|
+
simsimd_l2sq_f16((simsimd_f16_t *)x, (simsimd_f16_t *)x, 0, dummy_results);
|
|
274
|
+
simsimd_l2sq_bf16((simsimd_bf16_t *)x, (simsimd_bf16_t *)x, 0, dummy_results);
|
|
275
|
+
simsimd_l2sq_f32((simsimd_f32_t *)x, (simsimd_f32_t *)x, 0, dummy_results);
|
|
276
|
+
simsimd_l2sq_f64((simsimd_f64_t *)x, (simsimd_f64_t *)x, 0, dummy_results);
|
|
277
|
+
|
|
278
|
+
simsimd_l2_i8((simsimd_i8_t *)x, (simsimd_i8_t *)x, 0, dummy_results);
|
|
279
|
+
simsimd_l2_i8((simsimd_i8_t *)x, (simsimd_i8_t *)x, 0, dummy_results);
|
|
280
|
+
simsimd_l2_u8((simsimd_u8_t *)x, (simsimd_u8_t *)x, 0, dummy_results);
|
|
281
|
+
simsimd_l2_f16((simsimd_f16_t *)x, (simsimd_f16_t *)x, 0, dummy_results);
|
|
282
|
+
simsimd_l2_bf16((simsimd_bf16_t *)x, (simsimd_bf16_t *)x, 0, dummy_results);
|
|
283
|
+
simsimd_l2_f32((simsimd_f32_t *)x, (simsimd_f32_t *)x, 0, dummy_results);
|
|
284
|
+
simsimd_l2_f64((simsimd_f64_t *)x, (simsimd_f64_t *)x, 0, dummy_results);
|
|
285
|
+
|
|
286
|
+
simsimd_hamming_b8((simsimd_b8_t *)x, (simsimd_b8_t *)x, 0, dummy_results);
|
|
287
|
+
simsimd_jaccard_b8((simsimd_b8_t *)x, (simsimd_b8_t *)x, 0, dummy_results);
|
|
288
|
+
|
|
289
|
+
simsimd_kl_f16((simsimd_f16_t *)x, (simsimd_f16_t *)x, 0, dummy_results);
|
|
290
|
+
simsimd_kl_bf16((simsimd_bf16_t *)x, (simsimd_bf16_t *)x, 0, dummy_results);
|
|
291
|
+
simsimd_kl_f32((simsimd_f32_t *)x, (simsimd_f32_t *)x, 0, dummy_results);
|
|
292
|
+
simsimd_kl_f64((simsimd_f64_t *)x, (simsimd_f64_t *)x, 0, dummy_results);
|
|
293
|
+
simsimd_js_f16((simsimd_f16_t *)x, (simsimd_f16_t *)x, 0, dummy_results);
|
|
294
|
+
simsimd_js_bf16((simsimd_bf16_t *)x, (simsimd_bf16_t *)x, 0, dummy_results);
|
|
295
|
+
simsimd_js_f32((simsimd_f32_t *)x, (simsimd_f32_t *)x, 0, dummy_results);
|
|
296
|
+
simsimd_js_f64((simsimd_f64_t *)x, (simsimd_f64_t *)x, 0, dummy_results);
|
|
297
|
+
|
|
298
|
+
// Sparse
|
|
299
|
+
simsimd_intersect_u16((simsimd_u16_t *)x, (simsimd_u16_t *)x, 0, 0, dummy_results);
|
|
300
|
+
simsimd_intersect_u32((simsimd_u32_t *)x, (simsimd_u32_t *)x, 0, 0, dummy_results);
|
|
301
|
+
|
|
302
|
+
// Curved:
|
|
303
|
+
simsimd_bilinear_f64((simsimd_f64_t *)x, (simsimd_f64_t *)x, (simsimd_f64_t *)x, 0, dummy_results);
|
|
304
|
+
simsimd_mahalanobis_f64((simsimd_f64_t *)x, (simsimd_f64_t *)x, (simsimd_f64_t *)x, 0, dummy_results);
|
|
305
|
+
simsimd_bilinear_f32((simsimd_f32_t *)x, (simsimd_f32_t *)x, (simsimd_f32_t *)x, 0, dummy_results);
|
|
306
|
+
simsimd_mahalanobis_f32((simsimd_f32_t *)x, (simsimd_f32_t *)x, (simsimd_f32_t *)x, 0, dummy_results);
|
|
307
|
+
simsimd_bilinear_f16((simsimd_f16_t *)x, (simsimd_f16_t *)x, (simsimd_f16_t *)x, 0, dummy_results);
|
|
308
|
+
simsimd_mahalanobis_f16((simsimd_f16_t *)x, (simsimd_f16_t *)x, (simsimd_f16_t *)x, 0, dummy_results);
|
|
309
|
+
simsimd_bilinear_bf16((simsimd_bf16_t *)x, (simsimd_bf16_t *)x, (simsimd_bf16_t *)x, 0, dummy_results);
|
|
310
|
+
simsimd_mahalanobis_bf16((simsimd_bf16_t *)x, (simsimd_bf16_t *)x, (simsimd_bf16_t *)x, 0, dummy_results);
|
|
311
|
+
|
|
312
|
+
// Elementwise
|
|
313
|
+
simsimd_wsum_f64((simsimd_f64_t *)x, (simsimd_f64_t *)x, 0, 0, 0, (simsimd_f64_t *)x);
|
|
314
|
+
simsimd_wsum_f32((simsimd_f32_t *)x, (simsimd_f32_t *)x, 0, 0, 0, (simsimd_f32_t *)x);
|
|
315
|
+
simsimd_wsum_f16((simsimd_f16_t *)x, (simsimd_f16_t *)x, 0, 0, 0, (simsimd_f16_t *)x);
|
|
316
|
+
simsimd_wsum_bf16((simsimd_bf16_t *)x, (simsimd_bf16_t *)x, 0, 0, 0, (simsimd_bf16_t *)x);
|
|
317
|
+
simsimd_wsum_i8((simsimd_i8_t *)x, (simsimd_i8_t *)x, 0, 0, 0, (simsimd_i8_t *)x);
|
|
318
|
+
simsimd_wsum_u8((simsimd_u8_t *)x, (simsimd_u8_t *)x, 0, 0, 0, (simsimd_u8_t *)x);
|
|
319
|
+
simsimd_fma_f64((simsimd_f64_t *)x, (simsimd_f64_t *)x, (simsimd_f64_t *)x, 0, 0, 0, (simsimd_f64_t *)x);
|
|
320
|
+
simsimd_fma_f32((simsimd_f32_t *)x, (simsimd_f32_t *)x, (simsimd_f32_t *)x, 0, 0, 0, (simsimd_f32_t *)x);
|
|
321
|
+
simsimd_fma_f16((simsimd_f16_t *)x, (simsimd_f16_t *)x, (simsimd_f16_t *)x, 0, 0, 0, (simsimd_f16_t *)x);
|
|
322
|
+
simsimd_fma_bf16((simsimd_bf16_t *)x, (simsimd_bf16_t *)x, (simsimd_bf16_t *)x, 0, 0, 0, (simsimd_bf16_t *)x);
|
|
323
|
+
simsimd_fma_i8((simsimd_i8_t *)x, (simsimd_i8_t *)x, (simsimd_i8_t *)x, 0, 0, 0, (simsimd_i8_t *)x);
|
|
324
|
+
simsimd_fma_u8((simsimd_u8_t *)x, (simsimd_u8_t *)x, (simsimd_u8_t *)x, 0, 0, 0, (simsimd_u8_t *)x);
|
|
325
|
+
|
|
326
|
+
return static_capabilities;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
SIMSIMD_DYNAMIC void simsimd_find_metric_punned( //
|
|
330
|
+
simsimd_metric_kind_t kind, //
|
|
331
|
+
simsimd_datatype_t datatype, //
|
|
332
|
+
simsimd_capability_t supported, //
|
|
333
|
+
simsimd_capability_t allowed, //
|
|
334
|
+
simsimd_metric_punned_t *metric_output, //
|
|
335
|
+
simsimd_capability_t *capability_output) {
|
|
336
|
+
_simsimd_find_metric_punned_implementation(kind, datatype, supported, allowed, metric_output, capability_output);
|
|
337
|
+
}
|
|
125
338
|
|
|
126
339
|
#ifdef __cplusplus
|
|
127
340
|
}
|