usearch 2.15.1 → 2.15.3
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 +2 -2
- package/binding.gyp +1 -1
- package/c/CMakeLists.txt +10 -3
- package/cpp/README.md +1 -1
- package/cpp/bench.cpp +2 -2
- package/include/usearch/index.hpp +27 -13
- package/include/usearch/index_dense.hpp +45 -88
- package/include/usearch/index_plugins.hpp +128 -40
- package/javascript/usearch.test.js +15 -13
- 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/CODE_OF_CONDUCT.md +128 -0
- package/simsimd/CONTRIBUTING.md +18 -8
- package/simsimd/Cargo.lock +1 -1
- package/simsimd/Cargo.toml +1 -1
- package/simsimd/MANIFEST.in +2 -0
- package/simsimd/README.md +446 -158
- package/simsimd/build.rs +11 -1
- package/simsimd/c/lib.c +172 -40
- package/simsimd/include/simsimd/binary.h +11 -11
- package/simsimd/include/simsimd/curved.h +804 -0
- package/simsimd/include/simsimd/dot.h +333 -334
- package/simsimd/include/simsimd/geospatial.h +9 -3
- package/simsimd/include/simsimd/mesh.h +69 -0
- package/simsimd/include/simsimd/probability.h +178 -150
- package/simsimd/include/simsimd/simsimd.h +581 -107
- package/simsimd/include/simsimd/sparse.h +807 -0
- package/simsimd/include/simsimd/spatial.h +737 -502
- package/simsimd/include/simsimd/types.h +145 -75
- package/simsimd/javascript/simsimd.ts +4 -4
- package/simsimd/package.json +1 -1
- package/simsimd/rust/lib.rs +165 -0
package/simsimd/build.rs
CHANGED
|
@@ -17,7 +17,17 @@ 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![
|
|
22
32
|
"SIMSIMD_TARGET_SAPPHIRE",
|
|
23
33
|
"SIMSIMD_TARGET_GENOA",
|
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
|
|
@@ -42,18 +45,11 @@
|
|
|
42
45
|
extern "C" {
|
|
43
46
|
#endif
|
|
44
47
|
|
|
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
48
|
// Every time a function is called, it checks if the metric is already loaded. If not, it fetches it.
|
|
53
49
|
// If no metric is found, it returns NaN. We can obtain NaN by dividing 0.0 by 0.0, but that annoys
|
|
54
50
|
// the MSVC compiler. Instead we can directly write-in the signaling NaN (0x7FF0000000000001)
|
|
55
51
|
// or the qNaN (0x7FF8000000000000).
|
|
56
|
-
#define
|
|
52
|
+
#define SIMSIMD_DECLARATION_DENSE(name, extension, type) \
|
|
57
53
|
SIMSIMD_DYNAMIC void simsimd_##name##_##extension(simsimd_##type##_t const* a, simsimd_##type##_t const* b, \
|
|
58
54
|
simsimd_size_t n, simsimd_distance_t* results) { \
|
|
59
55
|
static simsimd_metric_punned_t metric = 0; \
|
|
@@ -69,45 +65,100 @@ simsimd_capability_t simsimd_capabilities(void) {
|
|
|
69
65
|
metric(a, b, n, results); \
|
|
70
66
|
}
|
|
71
67
|
|
|
68
|
+
#define SIMSIMD_DECLARATION_SPARSE(name, extension, type) \
|
|
69
|
+
SIMSIMD_DYNAMIC void simsimd_##name##_##extension(simsimd_##type##_t const* a, simsimd_##type##_t const* b, \
|
|
70
|
+
simsimd_size_t a_length, simsimd_size_t b_length, \
|
|
71
|
+
simsimd_distance_t* result) { \
|
|
72
|
+
static simsimd_metric_sparse_punned_t metric = 0; \
|
|
73
|
+
if (metric == 0) { \
|
|
74
|
+
simsimd_capability_t used_capability; \
|
|
75
|
+
simsimd_find_metric_punned(simsimd_metric_##name##_k, simsimd_datatype_##extension##_k, \
|
|
76
|
+
simsimd_capabilities(), simsimd_cap_any_k, (simsimd_metric_punned_t*)(&metric), \
|
|
77
|
+
&used_capability); \
|
|
78
|
+
if (!metric) { \
|
|
79
|
+
*(simsimd_u64_t*)result = 0x7FF0000000000001ull; \
|
|
80
|
+
return; \
|
|
81
|
+
} \
|
|
82
|
+
} \
|
|
83
|
+
metric(a, b, a_length, b_length, result); \
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
#define SIMSIMD_DECLARATION_CURVED(name, extension, type) \
|
|
87
|
+
SIMSIMD_DYNAMIC void simsimd_##name##_##extension(simsimd_##type##_t const* a, simsimd_##type##_t const* b, \
|
|
88
|
+
simsimd_##type##_t const* c, simsimd_size_t n, \
|
|
89
|
+
simsimd_distance_t* result) { \
|
|
90
|
+
static simsimd_metric_curved_punned_t metric = 0; \
|
|
91
|
+
if (metric == 0) { \
|
|
92
|
+
simsimd_capability_t used_capability; \
|
|
93
|
+
simsimd_find_metric_punned(simsimd_metric_##name##_k, simsimd_datatype_##extension##_k, \
|
|
94
|
+
simsimd_capabilities(), simsimd_cap_any_k, (simsimd_metric_punned_t*)(&metric), \
|
|
95
|
+
&used_capability); \
|
|
96
|
+
if (!metric) { \
|
|
97
|
+
*(simsimd_u64_t*)result = 0x7FF0000000000001ull; \
|
|
98
|
+
return; \
|
|
99
|
+
} \
|
|
100
|
+
} \
|
|
101
|
+
metric(a, b, c, n, result); \
|
|
102
|
+
}
|
|
103
|
+
|
|
72
104
|
// Dot products
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
105
|
+
SIMSIMD_DECLARATION_DENSE(dot, f16, f16)
|
|
106
|
+
SIMSIMD_DECLARATION_DENSE(dot, bf16, bf16)
|
|
107
|
+
SIMSIMD_DECLARATION_DENSE(dot, f32, f32)
|
|
108
|
+
SIMSIMD_DECLARATION_DENSE(dot, f64, f64)
|
|
109
|
+
SIMSIMD_DECLARATION_DENSE(dot, f16c, f16)
|
|
110
|
+
SIMSIMD_DECLARATION_DENSE(dot, bf16c, bf16)
|
|
111
|
+
SIMSIMD_DECLARATION_DENSE(dot, f32c, f32)
|
|
112
|
+
SIMSIMD_DECLARATION_DENSE(dot, f64c, f64)
|
|
113
|
+
SIMSIMD_DECLARATION_DENSE(vdot, f16c, f16)
|
|
114
|
+
SIMSIMD_DECLARATION_DENSE(vdot, bf16c, bf16)
|
|
115
|
+
SIMSIMD_DECLARATION_DENSE(vdot, f32c, f32)
|
|
116
|
+
SIMSIMD_DECLARATION_DENSE(vdot, f64c, f64)
|
|
85
117
|
|
|
86
118
|
// Spatial distances
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
119
|
+
SIMSIMD_DECLARATION_DENSE(cos, i8, i8)
|
|
120
|
+
SIMSIMD_DECLARATION_DENSE(cos, f16, f16)
|
|
121
|
+
SIMSIMD_DECLARATION_DENSE(cos, bf16, bf16)
|
|
122
|
+
SIMSIMD_DECLARATION_DENSE(cos, f32, f32)
|
|
123
|
+
SIMSIMD_DECLARATION_DENSE(cos, f64, f64)
|
|
124
|
+
SIMSIMD_DECLARATION_DENSE(l2sq, i8, i8)
|
|
125
|
+
SIMSIMD_DECLARATION_DENSE(l2sq, f16, f16)
|
|
126
|
+
SIMSIMD_DECLARATION_DENSE(l2sq, bf16, bf16)
|
|
127
|
+
SIMSIMD_DECLARATION_DENSE(l2sq, f32, f32)
|
|
128
|
+
SIMSIMD_DECLARATION_DENSE(l2sq, f64, f64)
|
|
129
|
+
SIMSIMD_DECLARATION_DENSE(l2, i8, i8)
|
|
130
|
+
SIMSIMD_DECLARATION_DENSE(l2, f16, f16)
|
|
131
|
+
SIMSIMD_DECLARATION_DENSE(l2, bf16, bf16)
|
|
132
|
+
SIMSIMD_DECLARATION_DENSE(l2, f32, f32)
|
|
133
|
+
SIMSIMD_DECLARATION_DENSE(l2, f64, f64)
|
|
97
134
|
|
|
98
135
|
// Binary distances
|
|
99
|
-
|
|
100
|
-
|
|
136
|
+
SIMSIMD_DECLARATION_DENSE(hamming, b8, b8)
|
|
137
|
+
SIMSIMD_DECLARATION_DENSE(jaccard, b8, b8)
|
|
101
138
|
|
|
102
139
|
// Probability distributions
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
140
|
+
SIMSIMD_DECLARATION_DENSE(kl, f16, f16)
|
|
141
|
+
SIMSIMD_DECLARATION_DENSE(kl, bf16, bf16)
|
|
142
|
+
SIMSIMD_DECLARATION_DENSE(kl, f32, f32)
|
|
143
|
+
SIMSIMD_DECLARATION_DENSE(kl, f64, f64)
|
|
144
|
+
SIMSIMD_DECLARATION_DENSE(js, f16, f16)
|
|
145
|
+
SIMSIMD_DECLARATION_DENSE(js, bf16, bf16)
|
|
146
|
+
SIMSIMD_DECLARATION_DENSE(js, f32, f32)
|
|
147
|
+
SIMSIMD_DECLARATION_DENSE(js, f64, f64)
|
|
148
|
+
|
|
149
|
+
// Sparse sets
|
|
150
|
+
SIMSIMD_DECLARATION_SPARSE(intersect, u16, u16)
|
|
151
|
+
SIMSIMD_DECLARATION_SPARSE(intersect, u32, u32)
|
|
152
|
+
|
|
153
|
+
// Curved spaces
|
|
154
|
+
SIMSIMD_DECLARATION_CURVED(bilinear, f64, f64)
|
|
155
|
+
SIMSIMD_DECLARATION_CURVED(mahalanobis, f64, f64)
|
|
156
|
+
SIMSIMD_DECLARATION_CURVED(bilinear, f32, f32)
|
|
157
|
+
SIMSIMD_DECLARATION_CURVED(mahalanobis, f32, f32)
|
|
158
|
+
SIMSIMD_DECLARATION_CURVED(bilinear, f16, f16)
|
|
159
|
+
SIMSIMD_DECLARATION_CURVED(mahalanobis, f16, f16)
|
|
160
|
+
SIMSIMD_DECLARATION_CURVED(bilinear, bf16, bf16)
|
|
161
|
+
SIMSIMD_DECLARATION_CURVED(mahalanobis, bf16, bf16)
|
|
111
162
|
|
|
112
163
|
SIMSIMD_DYNAMIC int simsimd_uses_neon(void) { return (simsimd_capabilities() & simsimd_cap_neon_k) != 0; }
|
|
113
164
|
SIMSIMD_DYNAMIC int simsimd_uses_neon_f16(void) { return (simsimd_capabilities() & simsimd_cap_neon_f16_k) != 0; }
|
|
@@ -122,6 +173,87 @@ SIMSIMD_DYNAMIC int simsimd_uses_skylake(void) { return (simsimd_capabilities()
|
|
|
122
173
|
SIMSIMD_DYNAMIC int simsimd_uses_ice(void) { return (simsimd_capabilities() & simsimd_cap_ice_k) != 0; }
|
|
123
174
|
SIMSIMD_DYNAMIC int simsimd_uses_genoa(void) { return (simsimd_capabilities() & simsimd_cap_genoa_k) != 0; }
|
|
124
175
|
SIMSIMD_DYNAMIC int simsimd_uses_sapphire(void) { return (simsimd_capabilities() & simsimd_cap_sapphire_k) != 0; }
|
|
176
|
+
SIMSIMD_DYNAMIC int simsimd_uses_dynamic_dispatch(void) { return 1; }
|
|
177
|
+
|
|
178
|
+
SIMSIMD_DYNAMIC simsimd_capability_t simsimd_capabilities(void) {
|
|
179
|
+
static simsimd_capability_t static_capabilities = simsimd_cap_any_k;
|
|
180
|
+
if (static_capabilities != simsimd_cap_any_k)
|
|
181
|
+
return static_capabilities;
|
|
182
|
+
|
|
183
|
+
static_capabilities = _simsimd_capabilities_implementation();
|
|
184
|
+
|
|
185
|
+
// In multithreaded applications we need to ensure that the function pointers are pre-initialized,
|
|
186
|
+
// so the first time we are probing for capabilities, we should also probe all of our metrics
|
|
187
|
+
// with dummy inputs:
|
|
188
|
+
simsimd_distance_t dummy_results_buffer[2];
|
|
189
|
+
simsimd_distance_t* dummy_results = &dummy_results_buffer[0];
|
|
190
|
+
void* dummy = 0;
|
|
191
|
+
|
|
192
|
+
// Dense:
|
|
193
|
+
simsimd_dot_f16((simsimd_f16_t*)dummy, (simsimd_f16_t*)dummy, 0, dummy_results);
|
|
194
|
+
simsimd_dot_bf16((simsimd_bf16_t*)dummy, (simsimd_bf16_t*)dummy, 0, dummy_results);
|
|
195
|
+
simsimd_dot_f32((simsimd_f32_t*)dummy, (simsimd_f32_t*)dummy, 0, dummy_results);
|
|
196
|
+
simsimd_dot_f64((simsimd_f64_t*)dummy, (simsimd_f64_t*)dummy, 0, dummy_results);
|
|
197
|
+
simsimd_dot_f16c((simsimd_f16_t*)dummy, (simsimd_f16_t*)dummy, 0, dummy_results);
|
|
198
|
+
simsimd_dot_bf16c((simsimd_bf16_t*)dummy, (simsimd_bf16_t*)dummy, 0, dummy_results);
|
|
199
|
+
simsimd_dot_f32c((simsimd_f32_t*)dummy, (simsimd_f32_t*)dummy, 0, dummy_results);
|
|
200
|
+
simsimd_dot_f64c((simsimd_f64_t*)dummy, (simsimd_f64_t*)dummy, 0, dummy_results);
|
|
201
|
+
simsimd_vdot_f16c((simsimd_f16_t*)dummy, (simsimd_f16_t*)dummy, 0, dummy_results);
|
|
202
|
+
simsimd_vdot_bf16c((simsimd_bf16_t*)dummy, (simsimd_bf16_t*)dummy, 0, dummy_results);
|
|
203
|
+
simsimd_vdot_f32c((simsimd_f32_t*)dummy, (simsimd_f32_t*)dummy, 0, dummy_results);
|
|
204
|
+
simsimd_vdot_f64c((simsimd_f64_t*)dummy, (simsimd_f64_t*)dummy, 0, dummy_results);
|
|
205
|
+
simsimd_cos_i8((simsimd_i8_t*)dummy, (simsimd_i8_t*)dummy, 0, dummy_results);
|
|
206
|
+
simsimd_cos_f16((simsimd_f16_t*)dummy, (simsimd_f16_t*)dummy, 0, dummy_results);
|
|
207
|
+
simsimd_cos_bf16((simsimd_bf16_t*)dummy, (simsimd_bf16_t*)dummy, 0, dummy_results);
|
|
208
|
+
simsimd_cos_f32((simsimd_f32_t*)dummy, (simsimd_f32_t*)dummy, 0, dummy_results);
|
|
209
|
+
simsimd_cos_f64((simsimd_f64_t*)dummy, (simsimd_f64_t*)dummy, 0, dummy_results);
|
|
210
|
+
simsimd_l2sq_i8((simsimd_i8_t*)dummy, (simsimd_i8_t*)dummy, 0, dummy_results);
|
|
211
|
+
simsimd_l2sq_f16((simsimd_f16_t*)dummy, (simsimd_f16_t*)dummy, 0, dummy_results);
|
|
212
|
+
simsimd_l2sq_bf16((simsimd_bf16_t*)dummy, (simsimd_bf16_t*)dummy, 0, dummy_results);
|
|
213
|
+
simsimd_l2sq_f32((simsimd_f32_t*)dummy, (simsimd_f32_t*)dummy, 0, dummy_results);
|
|
214
|
+
simsimd_l2sq_f64((simsimd_f64_t*)dummy, (simsimd_f64_t*)dummy, 0, dummy_results);
|
|
215
|
+
simsimd_l2_i8((simsimd_i8_t*)dummy, (simsimd_i8_t*)dummy, 0, dummy_results);
|
|
216
|
+
simsimd_l2_f16((simsimd_f16_t*)dummy, (simsimd_f16_t*)dummy, 0, dummy_results);
|
|
217
|
+
simsimd_l2_bf16((simsimd_bf16_t*)dummy, (simsimd_bf16_t*)dummy, 0, dummy_results);
|
|
218
|
+
simsimd_l2_f32((simsimd_f32_t*)dummy, (simsimd_f32_t*)dummy, 0, dummy_results);
|
|
219
|
+
simsimd_l2_f64((simsimd_f64_t*)dummy, (simsimd_f64_t*)dummy, 0, dummy_results);
|
|
220
|
+
simsimd_hamming_b8((simsimd_b8_t*)dummy, (simsimd_b8_t*)dummy, 0, dummy_results);
|
|
221
|
+
simsimd_jaccard_b8((simsimd_b8_t*)dummy, (simsimd_b8_t*)dummy, 0, dummy_results);
|
|
222
|
+
simsimd_kl_f16((simsimd_f16_t*)dummy, (simsimd_f16_t*)dummy, 0, dummy_results);
|
|
223
|
+
simsimd_kl_bf16((simsimd_bf16_t*)dummy, (simsimd_bf16_t*)dummy, 0, dummy_results);
|
|
224
|
+
simsimd_kl_f32((simsimd_f32_t*)dummy, (simsimd_f32_t*)dummy, 0, dummy_results);
|
|
225
|
+
simsimd_kl_f64((simsimd_f64_t*)dummy, (simsimd_f64_t*)dummy, 0, dummy_results);
|
|
226
|
+
simsimd_js_f16((simsimd_f16_t*)dummy, (simsimd_f16_t*)dummy, 0, dummy_results);
|
|
227
|
+
simsimd_js_bf16((simsimd_bf16_t*)dummy, (simsimd_bf16_t*)dummy, 0, dummy_results);
|
|
228
|
+
simsimd_js_f32((simsimd_f32_t*)dummy, (simsimd_f32_t*)dummy, 0, dummy_results);
|
|
229
|
+
simsimd_js_f64((simsimd_f64_t*)dummy, (simsimd_f64_t*)dummy, 0, dummy_results);
|
|
230
|
+
|
|
231
|
+
// Sparse
|
|
232
|
+
simsimd_intersect_u16((simsimd_u16_t*)dummy, (simsimd_u16_t*)dummy, 0, 0, dummy_results);
|
|
233
|
+
simsimd_intersect_u32((simsimd_u32_t*)dummy, (simsimd_u32_t*)dummy, 0, 0, dummy_results);
|
|
234
|
+
|
|
235
|
+
// Curved:
|
|
236
|
+
simsimd_bilinear_f64((simsimd_f64_t*)dummy, (simsimd_f64_t*)dummy, (simsimd_f64_t*)dummy, 0, dummy_results);
|
|
237
|
+
simsimd_mahalanobis_f64((simsimd_f64_t*)dummy, (simsimd_f64_t*)dummy, (simsimd_f64_t*)dummy, 0, dummy_results);
|
|
238
|
+
simsimd_bilinear_f32((simsimd_f32_t*)dummy, (simsimd_f32_t*)dummy, (simsimd_f32_t*)dummy, 0, dummy_results);
|
|
239
|
+
simsimd_mahalanobis_f32((simsimd_f32_t*)dummy, (simsimd_f32_t*)dummy, (simsimd_f32_t*)dummy, 0, dummy_results);
|
|
240
|
+
simsimd_bilinear_f16((simsimd_f16_t*)dummy, (simsimd_f16_t*)dummy, (simsimd_f16_t*)dummy, 0, dummy_results);
|
|
241
|
+
simsimd_mahalanobis_f16((simsimd_f16_t*)dummy, (simsimd_f16_t*)dummy, (simsimd_f16_t*)dummy, 0, dummy_results);
|
|
242
|
+
simsimd_bilinear_bf16((simsimd_bf16_t*)dummy, (simsimd_bf16_t*)dummy, (simsimd_bf16_t*)dummy, 0, dummy_results);
|
|
243
|
+
simsimd_mahalanobis_bf16((simsimd_bf16_t*)dummy, (simsimd_bf16_t*)dummy, (simsimd_bf16_t*)dummy, 0, dummy_results);
|
|
244
|
+
|
|
245
|
+
return static_capabilities;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
SIMSIMD_DYNAMIC void simsimd_find_metric_punned( //
|
|
249
|
+
simsimd_metric_kind_t kind, //
|
|
250
|
+
simsimd_datatype_t datatype, //
|
|
251
|
+
simsimd_capability_t supported, //
|
|
252
|
+
simsimd_capability_t allowed, //
|
|
253
|
+
simsimd_metric_punned_t* metric_output, //
|
|
254
|
+
simsimd_capability_t* capability_output) {
|
|
255
|
+
_simsimd_find_metric_punned_implementation(kind, datatype, supported, allowed, metric_output, capability_output);
|
|
256
|
+
}
|
|
125
257
|
|
|
126
258
|
#ifdef __cplusplus
|
|
127
259
|
}
|
|
@@ -73,14 +73,14 @@ SIMSIMD_PUBLIC void simsimd_jaccard_b8_serial(simsimd_b8_t const* a, simsimd_b8_
|
|
|
73
73
|
simsimd_i32_t intersection = 0, union_ = 0;
|
|
74
74
|
for (simsimd_size_t i = 0; i != n_words; ++i)
|
|
75
75
|
intersection += simsimd_popcount_b8(a[i] & b[i]), union_ += simsimd_popcount_b8(a[i] | b[i]);
|
|
76
|
-
*result = (union_ != 0) ? 1 - (
|
|
76
|
+
*result = (union_ != 0) ? 1 - (simsimd_f64_t)intersection / (simsimd_f64_t)union_ : 1;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
#if SIMSIMD_TARGET_ARM
|
|
80
80
|
#if SIMSIMD_TARGET_NEON
|
|
81
81
|
#pragma GCC push_options
|
|
82
|
-
#pragma GCC target("+simd")
|
|
83
|
-
#pragma clang attribute push(__attribute__((target("+simd"))), apply_to = function)
|
|
82
|
+
#pragma GCC target("arch=armv8.2-a+simd")
|
|
83
|
+
#pragma clang attribute push(__attribute__((target("arch=armv8.2-a+simd"))), apply_to = function)
|
|
84
84
|
|
|
85
85
|
SIMSIMD_PUBLIC void simsimd_hamming_b8_neon(simsimd_b8_t const* a, simsimd_b8_t const* b, simsimd_size_t n_words,
|
|
86
86
|
simsimd_distance_t* result) {
|
|
@@ -110,7 +110,7 @@ SIMSIMD_PUBLIC void simsimd_jaccard_b8_neon(simsimd_b8_t const* a, simsimd_b8_t
|
|
|
110
110
|
// Handle the tail
|
|
111
111
|
for (; i != n_words; ++i)
|
|
112
112
|
intersection += simsimd_popcount_b8(a[i] & b[i]), union_ += simsimd_popcount_b8(a[i] | b[i]);
|
|
113
|
-
*result = (union_ != 0) ? 1 - (
|
|
113
|
+
*result = (union_ != 0) ? 1 - (simsimd_f64_t)intersection / (simsimd_f64_t)union_ : 1;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
#pragma clang attribute pop
|
|
@@ -119,8 +119,8 @@ SIMSIMD_PUBLIC void simsimd_jaccard_b8_neon(simsimd_b8_t const* a, simsimd_b8_t
|
|
|
119
119
|
|
|
120
120
|
#if SIMSIMD_TARGET_SVE
|
|
121
121
|
#pragma GCC push_options
|
|
122
|
-
#pragma GCC target("+sve")
|
|
123
|
-
#pragma clang attribute push(__attribute__((target("+sve"))), apply_to = function)
|
|
122
|
+
#pragma GCC target("arch=armv8.2-a+sve")
|
|
123
|
+
#pragma clang attribute push(__attribute__((target("arch=armv8.2-a+sve"))), apply_to = function)
|
|
124
124
|
|
|
125
125
|
SIMSIMD_PUBLIC void simsimd_hamming_b8_sve(simsimd_b8_t const* a, simsimd_b8_t const* b, simsimd_size_t n_words,
|
|
126
126
|
simsimd_distance_t* result) {
|
|
@@ -148,7 +148,7 @@ SIMSIMD_PUBLIC void simsimd_jaccard_b8_sve(simsimd_b8_t const* a, simsimd_b8_t c
|
|
|
148
148
|
union_ += svaddv_u8(svptrue_b8(), svcnt_u8_x(svptrue_b8(), svorr_u8_m(svptrue_b8(), a_vec, b_vec)));
|
|
149
149
|
i += svcntb();
|
|
150
150
|
} while (i < n_words);
|
|
151
|
-
*result = (union_ != 0) ? 1 - (
|
|
151
|
+
*result = (union_ != 0) ? 1 - (simsimd_f64_t)intersection / (simsimd_f64_t)union_ : 1;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
#pragma clang attribute pop
|
|
@@ -159,8 +159,8 @@ SIMSIMD_PUBLIC void simsimd_jaccard_b8_sve(simsimd_b8_t const* a, simsimd_b8_t c
|
|
|
159
159
|
#if SIMSIMD_TARGET_X86
|
|
160
160
|
#if SIMSIMD_TARGET_ICE
|
|
161
161
|
#pragma GCC push_options
|
|
162
|
-
#pragma GCC target("avx512f", "avx512vl", "bmi2", "avx512bw", "avx512vpopcntdq")
|
|
163
|
-
#pragma clang attribute push(__attribute__((target("avx512f,avx512vl,bmi2,avx512bw,avx512vpopcntdq"))),
|
|
162
|
+
#pragma GCC target("avx2", "avx512f", "avx512vl", "bmi2", "avx512bw", "avx512vpopcntdq")
|
|
163
|
+
#pragma clang attribute push(__attribute__((target("avx2,avx512f,avx512vl,bmi2,avx512bw,avx512vpopcntdq"))), \
|
|
164
164
|
apply_to = function)
|
|
165
165
|
|
|
166
166
|
SIMSIMD_PUBLIC void simsimd_hamming_b8_ice(simsimd_b8_t const* a, simsimd_b8_t const* b, simsimd_size_t n_words,
|
|
@@ -213,7 +213,7 @@ simsimd_jaccard_b8_ice_cycle:
|
|
|
213
213
|
|
|
214
214
|
simsimd_size_t intersection = _mm512_reduce_add_epi64(intersection_vec),
|
|
215
215
|
union_ = _mm512_reduce_add_epi64(union_vec);
|
|
216
|
-
*result = (union_ != 0) ? 1 - (
|
|
216
|
+
*result = (union_ != 0) ? 1 - (simsimd_f64_t)intersection / (simsimd_f64_t)union_ : 1;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
#pragma clang attribute pop
|
|
@@ -245,7 +245,7 @@ SIMSIMD_PUBLIC void simsimd_jaccard_b8_haswell(simsimd_b8_t const* a, simsimd_b8
|
|
|
245
245
|
union_ += _mm_popcnt_u64(*(simsimd_u64_t const*)a | *(simsimd_u64_t const*)b);
|
|
246
246
|
for (; n_words; --n_words, ++a, ++b)
|
|
247
247
|
intersection += _mm_popcnt_u32(*a & *b), union_ += _mm_popcnt_u32(*a | *b);
|
|
248
|
-
*result = (union_ != 0) ? 1 - (
|
|
248
|
+
*result = (union_ != 0) ? 1 - (simsimd_f64_t)intersection / (simsimd_f64_t)union_ : 1;
|
|
249
249
|
}
|
|
250
250
|
|
|
251
251
|
#pragma clang attribute pop
|