usearch 2.15.3 → 2.16.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 (48) hide show
  1. package/README.md +1 -1
  2. package/cpp/test.cpp +16 -0
  3. package/include/usearch/index.hpp +21 -5
  4. package/include/usearch/index_dense.hpp +6 -1
  5. package/include/usearch/index_plugins.hpp +345 -8
  6. package/javascript/lib.cpp +17 -5
  7. package/javascript/usearch.test.js +190 -21
  8. package/package.json +1 -1
  9. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  10. package/prebuilds/linux-arm64/usearch.node +0 -0
  11. package/prebuilds/linux-x64/usearch.node +0 -0
  12. package/simsimd/.git-blame-ignore-revs +2 -0
  13. package/simsimd/CONTRIBUTING.md +71 -23
  14. package/simsimd/Cargo.lock +1 -1
  15. package/simsimd/Cargo.toml +4 -4
  16. package/simsimd/MANIFEST.in +2 -1
  17. package/simsimd/Package.swift +15 -3
  18. package/simsimd/README.md +104 -35
  19. package/simsimd/binding.gyp +6 -2
  20. package/simsimd/build.rs +2 -0
  21. package/simsimd/c/lib.c +180 -99
  22. package/simsimd/include/simsimd/binary.h +311 -102
  23. package/simsimd/include/simsimd/curved.h +134 -135
  24. package/simsimd/include/simsimd/dot.h +448 -274
  25. package/simsimd/include/simsimd/elementwise.h +1437 -0
  26. package/simsimd/include/simsimd/geospatial.h +2 -2
  27. package/simsimd/include/simsimd/mesh.h +2 -2
  28. package/simsimd/include/simsimd/probability.h +88 -88
  29. package/simsimd/include/simsimd/simsimd.h +1157 -772
  30. package/simsimd/include/simsimd/sparse.h +768 -147
  31. package/simsimd/include/simsimd/spatial.h +955 -376
  32. package/simsimd/include/simsimd/types.h +145 -71
  33. package/simsimd/javascript/lib.c +1 -2
  34. package/simsimd/package.json +4 -4
  35. package/simsimd/rust/lib.rs +14 -1
  36. package/simsimd/scripts/bench.cxx +1070 -0
  37. package/simsimd/scripts/bench.ipynb +187 -0
  38. package/simsimd/{javascript → scripts}/bench.js +1 -1
  39. package/simsimd/{rust/benches/sqeuclidean.rs → scripts/bench_sqeuclidean.rs} +6 -6
  40. package/simsimd/scripts/bench_vectors.py +700 -0
  41. package/simsimd/scripts/bench_vectors_live.py +213 -0
  42. package/simsimd/scripts/test.c +155 -0
  43. package/simsimd/{javascript → scripts}/test.mjs +2 -2
  44. package/simsimd/scripts/test.py +1410 -0
  45. package/simsimd/swift/{source/SimSIMD.swift → SimSIMD.swift} +6 -2
  46. package/simsimd/swift/{tests/SimSIMDTests.swift → Test.swift} +1 -1
  47. /package/simsimd/{rust/benches/cosine.rs → scripts/bench_cosine.rs} +0 -0
  48. /package/simsimd/{rust/benches/native.rs → scripts/bench_native.rs} +0 -0
@@ -6,18 +6,19 @@
6
6
  *
7
7
  * Defines:
8
8
  * - Sized aliases for numeric types, like: `simsimd_i32_t` and `simsimd_f64_t`.
9
- * - Macros for compiler/hardware checks, like: `SIMSIMD_TARGET_NEON`
9
+ * - Macros for internal compiler/hardware checks, like: `_SIMSIMD_TARGET_ARM`.
10
+ * - Macros for feature controls, like: `SIMSIMD_TARGET_NEON`
10
11
  */
11
12
  #ifndef SIMSIMD_TYPES_H
12
13
  #define SIMSIMD_TYPES_H
13
14
 
14
15
  // Inferring target OS: Windows, MacOS, or Linux
15
16
  #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
16
- #define SIMSIMD_DEFINED_WINDOWS
17
+ #define _SIMSIMD_DEFINED_WINDOWS 1
17
18
  #elif defined(__APPLE__) && defined(__MACH__)
18
- #define SIMSIMD_DEFINED_APPLE
19
+ #define _SIMSIMD_DEFINED_APPLE 1
19
20
  #elif defined(__linux__)
20
- #define SIMSIMD_DEFINED_LINUX
21
+ #define _SIMSIMD_DEFINED_LINUX 1
21
22
  #endif
22
23
 
23
24
  // Annotation for the public API symbols:
@@ -40,73 +41,113 @@
40
41
  #define SIMSIMD_INTERNAL inline static
41
42
  #endif
42
43
 
43
- // Compiling for Arm: SIMSIMD_TARGET_ARM
44
- #if !defined(SIMSIMD_TARGET_ARM)
44
+ // Compiling for Arm: _SIMSIMD_TARGET_ARM
45
+ #if !defined(_SIMSIMD_TARGET_ARM)
45
46
  #if defined(__aarch64__) || defined(_M_ARM64)
46
- #define SIMSIMD_TARGET_ARM 1
47
+ #define _SIMSIMD_TARGET_ARM 1
47
48
  #else
48
- #define SIMSIMD_TARGET_ARM 0
49
+ #define _SIMSIMD_TARGET_ARM 0
49
50
  #endif // defined(__aarch64__) || defined(_M_ARM64)
50
- #endif // !defined(SIMSIMD_TARGET_ARM)
51
+ #endif // !defined(_SIMSIMD_TARGET_ARM)
51
52
 
52
- // Compiling for x86: SIMSIMD_TARGET_X86
53
- #if !defined(SIMSIMD_TARGET_X86)
53
+ // Compiling for x86: _SIMSIMD_TARGET_X86
54
+ #if !defined(_SIMSIMD_TARGET_X86)
54
55
  #if defined(__x86_64__) || defined(_M_X64)
55
- #define SIMSIMD_TARGET_X86 1
56
+ #define _SIMSIMD_TARGET_X86 1
56
57
  #else
57
- #define SIMSIMD_TARGET_X86 0
58
+ #define _SIMSIMD_TARGET_X86 0
58
59
  #endif // defined(__x86_64__) || defined(_M_X64)
59
- #endif // !defined(SIMSIMD_TARGET_X86)
60
+ #endif // !defined(_SIMSIMD_TARGET_X86)
60
61
 
61
62
  // Compiling for Arm: SIMSIMD_TARGET_NEON
62
- #if !defined(SIMSIMD_TARGET_NEON) || (SIMSIMD_TARGET_NEON && !SIMSIMD_TARGET_ARM)
63
+ #if !defined(SIMSIMD_TARGET_NEON) || (SIMSIMD_TARGET_NEON && !_SIMSIMD_TARGET_ARM)
63
64
  #if defined(__ARM_NEON)
64
- #define SIMSIMD_TARGET_NEON SIMSIMD_TARGET_ARM
65
+ #define SIMSIMD_TARGET_NEON _SIMSIMD_TARGET_ARM
65
66
  #else
66
67
  #undef SIMSIMD_TARGET_NEON
67
68
  #define SIMSIMD_TARGET_NEON 0
68
69
  #endif // defined(__ARM_NEON)
69
- #endif // !defined(SIMSIMD_TARGET_NEON)
70
-
71
- #if !defined(SIMSIMD_TARGET_NEON_I8)
72
- #define SIMSIMD_TARGET_NEON_I8 SIMSIMD_TARGET_NEON
73
- #endif // !defined(SIMSIMD_TARGET_NEON_I8)
74
- #if !defined(SIMSIMD_TARGET_NEON_F16)
75
- #define SIMSIMD_TARGET_NEON_F16 SIMSIMD_TARGET_NEON
76
- #endif // !defined(SIMSIMD_TARGET_NEON_F16)
77
- #if !defined(SIMSIMD_TARGET_NEON_BF16)
78
- #define SIMSIMD_TARGET_NEON_BF16 SIMSIMD_TARGET_NEON
79
- #endif // !defined(SIMSIMD_TARGET_NEON_BF16)
70
+ #endif // !defined(SIMSIMD_TARGET_NEON) || ...
71
+
72
+ // Compiling for Arm: SIMSIMD_TARGET_NEON_I8
73
+ #if !defined(SIMSIMD_TARGET_NEON_I8) || (SIMSIMD_TARGET_NEON_I8 && !_SIMSIMD_TARGET_ARM)
74
+ #if defined(__ARM_NEON)
75
+ #define SIMSIMD_TARGET_NEON_I8 _SIMSIMD_TARGET_ARM
76
+ #else
77
+ #undef SIMSIMD_TARGET_NEON_I8
78
+ #define SIMSIMD_TARGET_NEON_I8 0
79
+ #endif // defined(__ARM_NEON)
80
+ #endif // !defined(SIMSIMD_TARGET_NEON_I8) || ...
81
+
82
+ // Compiling for Arm: SIMSIMD_TARGET_NEON_F16
83
+ #if !defined(SIMSIMD_TARGET_NEON_F16) || (SIMSIMD_TARGET_NEON_F16 && !_SIMSIMD_TARGET_ARM)
84
+ #if defined(__ARM_NEON)
85
+ #define SIMSIMD_TARGET_NEON_F16 _SIMSIMD_TARGET_ARM
86
+ #else
87
+ #undef SIMSIMD_TARGET_NEON_F16
88
+ #define SIMSIMD_TARGET_NEON_F16 0
89
+ #endif // defined(__ARM_NEON)
90
+ #endif // !defined(SIMSIMD_TARGET_NEON_F16) || ...
91
+
92
+ // Compiling for Arm: SIMSIMD_TARGET_NEON_BF16
93
+ #if !defined(SIMSIMD_TARGET_NEON_BF16) || (SIMSIMD_TARGET_NEON_BF16 && !_SIMSIMD_TARGET_ARM)
94
+ #if defined(__ARM_NEON)
95
+ #define SIMSIMD_TARGET_NEON_BF16 _SIMSIMD_TARGET_ARM
96
+ #else
97
+ #undef SIMSIMD_TARGET_NEON_BF16
98
+ #define SIMSIMD_TARGET_NEON_BF16 0
99
+ #endif // defined(__ARM_NEON)
100
+ #endif // !defined(SIMSIMD_TARGET_NEON_BF16) || ...
80
101
 
81
102
  // Compiling for Arm: SIMSIMD_TARGET_SVE
82
- #if !defined(SIMSIMD_TARGET_SVE) || (SIMSIMD_TARGET_SVE && !SIMSIMD_TARGET_ARM)
103
+ #if !defined(SIMSIMD_TARGET_SVE) || (SIMSIMD_TARGET_SVE && !_SIMSIMD_TARGET_ARM)
83
104
  #if defined(__ARM_FEATURE_SVE)
84
- #define SIMSIMD_TARGET_SVE SIMSIMD_TARGET_ARM
105
+ #define SIMSIMD_TARGET_SVE _SIMSIMD_TARGET_ARM
85
106
  #else
86
107
  #undef SIMSIMD_TARGET_SVE
87
108
  #define SIMSIMD_TARGET_SVE 0
88
109
  #endif // defined(__ARM_FEATURE_SVE)
89
- #endif // !defined(SIMSIMD_TARGET_SVE)
90
-
91
- #if !defined(SIMSIMD_TARGET_SVE_I8)
92
- #define SIMSIMD_TARGET_SVE_I8 SIMSIMD_TARGET_SVE
93
- #endif // !defined(SIMSIMD_TARGET_SVE_I8)
94
- #if !defined(SIMSIMD_TARGET_SVE_F16)
95
- #define SIMSIMD_TARGET_SVE_F16 SIMSIMD_TARGET_SVE
96
- #endif // !defined(SIMSIMD_TARGET_SVE_F16)
97
- #if !defined(SIMSIMD_TARGET_SVE_BF16)
98
- #define SIMSIMD_TARGET_SVE_BF16 SIMSIMD_TARGET_SVE
99
- #endif // !defined(SIMSIMD_TARGET_SVE_BF16)
110
+ #endif // !defined(SIMSIMD_TARGET_SVE) || ...
111
+
112
+ // Compiling for Arm: SIMSIMD_TARGET_SVE_I8
113
+ #if !defined(SIMSIMD_TARGET_SVE_I8) || (SIMSIMD_TARGET_SVE_I8 && !_SIMSIMD_TARGET_ARM)
114
+ #if defined(__ARM_FEATURE_SVE)
115
+ #define SIMSIMD_TARGET_SVE_I8 _SIMSIMD_TARGET_ARM
116
+ #else
117
+ #undef SIMSIMD_TARGET_SVE_I8
118
+ #define SIMSIMD_TARGET_SVE_I8 0
119
+ #endif // defined(__ARM_FEATURE_SVE)
120
+ #endif // !defined(SIMSIMD_TARGET_SVE_I8) || ...
121
+
122
+ // Compiling for Arm: SIMSIMD_TARGET_SVE_F16
123
+ #if !defined(SIMSIMD_TARGET_SVE_F16) || (SIMSIMD_TARGET_SVE_F16 && !_SIMSIMD_TARGET_ARM)
124
+ #if defined(__ARM_FEATURE_SVE)
125
+ #define SIMSIMD_TARGET_SVE_F16 _SIMSIMD_TARGET_ARM
126
+ #else
127
+ #undef SIMSIMD_TARGET_SVE_F16
128
+ #define SIMSIMD_TARGET_SVE_F16 0
129
+ #endif // defined(__ARM_FEATURE_SVE)
130
+ #endif // !defined(SIMSIMD_TARGET_SVE_F16) || ...
131
+
132
+ // Compiling for Arm: SIMSIMD_TARGET_SVE_BF16
133
+ #if !defined(SIMSIMD_TARGET_SVE_BF16) || (SIMSIMD_TARGET_SVE_BF16 && !_SIMSIMD_TARGET_ARM)
134
+ #if defined(__ARM_FEATURE_SVE)
135
+ #define SIMSIMD_TARGET_SVE_BF16 _SIMSIMD_TARGET_ARM
136
+ #else
137
+ #undef SIMSIMD_TARGET_SVE_BF16
138
+ #define SIMSIMD_TARGET_SVE_BF16 0
139
+ #endif // defined(__ARM_FEATURE_SVE)
140
+ #endif // !defined(SIMSIMD_TARGET_SVE_BF16) || ...
100
141
 
101
142
  // Compiling for Arm: SIMSIMD_TARGET_SVE2
102
- #if !defined(SIMSIMD_TARGET_SVE2) || (SIMSIMD_TARGET_SVE2 && !SIMSIMD_TARGET_ARM)
143
+ #if !defined(SIMSIMD_TARGET_SVE2) || (SIMSIMD_TARGET_SVE2 && !_SIMSIMD_TARGET_ARM)
103
144
  #if defined(__ARM_FEATURE_SVE)
104
- #define SIMSIMD_TARGET_SVE2 SIMSIMD_TARGET_ARM
145
+ #define SIMSIMD_TARGET_SVE2 _SIMSIMD_TARGET_ARM
105
146
  #else
106
147
  #undef SIMSIMD_TARGET_SVE2
107
148
  #define SIMSIMD_TARGET_SVE2 0
108
149
  #endif // defined(__ARM_FEATURE_SVE)
109
- #endif // !defined(SIMSIMD_TARGET_SVE2)
150
+ #endif // !defined(SIMSIMD_TARGET_SVE2) || ...
110
151
 
111
152
  // Compiling for x86: SIMSIMD_TARGET_HASWELL
112
153
  //
@@ -115,55 +156,72 @@
115
156
  // are supported on all CPUs starting with Jaguar 2009.
116
157
  // Starting with Sandy Bridge, Intel adds basic AVX support in their CPUs and in 2013
117
158
  // extends it with AVX2 in the Haswell generation. Moreover, Haswell adds FMA support.
118
- #if !defined(SIMSIMD_TARGET_HASWELL) || (SIMSIMD_TARGET_HASWELL && !SIMSIMD_TARGET_X86)
159
+ #if !defined(SIMSIMD_TARGET_HASWELL) || (SIMSIMD_TARGET_HASWELL && !_SIMSIMD_TARGET_X86)
119
160
  #if defined(__AVX2__) && defined(__FMA__) && defined(__F16C__)
120
161
  #define SIMSIMD_TARGET_HASWELL 1
121
162
  #else
122
163
  #undef SIMSIMD_TARGET_HASWELL
123
164
  #define SIMSIMD_TARGET_HASWELL 0
124
165
  #endif // defined(__AVX2__)
125
- #endif // !defined(SIMSIMD_TARGET_HASWELL)
166
+ #endif // !defined(SIMSIMD_TARGET_HASWELL) || ...
126
167
 
127
- // Compiling for x86: SIMSIMD_TARGET_SKYLAKE, SIMSIMD_TARGET_ICE, SIMSIMD_TARGET_GENOA, SIMSIMD_TARGET_SAPPHIRE
168
+ // Compiling for x86: SIMSIMD_TARGET_SKYLAKE, SIMSIMD_TARGET_ICE, SIMSIMD_TARGET_GENOA,
169
+ // SIMSIMD_TARGET_SAPPHIRE, SIMSIMD_TARGET_TURIN, SIMSIMD_TARGET_SIERRA
128
170
  //
129
171
  // To list all available macros for x86, take a recent compiler, like GCC 12 and run:
130
172
  // gcc-12 -march=sapphirerapids -dM -E - < /dev/null | egrep "SSE|AVX" | sort
131
173
  // On Arm machines you may want to check for other flags:
132
174
  // gcc-12 -march=native -dM -E - < /dev/null | egrep "NEON|SVE|FP16|FMA" | sort
133
- #if !defined(SIMSIMD_TARGET_SKYLAKE) || (SIMSIMD_TARGET_SKYLAKE && !SIMSIMD_TARGET_X86)
134
- #if defined(__AVX512F__) && defined(__AVX512CD__) && defined(__AVX512VL__) && defined(__AVX512DQ__) && \
175
+ #if !defined(SIMSIMD_TARGET_SKYLAKE) || (SIMSIMD_TARGET_SKYLAKE && !_SIMSIMD_TARGET_X86)
176
+ #if defined(__AVX512F__) && defined(__AVX512CD__) && defined(__AVX512VL__) && defined(__AVX512DQ__) && \
135
177
  defined(__AVX512BW__)
136
178
  #define SIMSIMD_TARGET_SKYLAKE 1
137
179
  #else
138
180
  #undef SIMSIMD_TARGET_SKYLAKE
139
181
  #define SIMSIMD_TARGET_SKYLAKE 0
140
182
  #endif
141
- #endif // !defined(SIMSIMD_TARGET_SKYLAKE)
142
- #if !defined(SIMSIMD_TARGET_ICE) || (SIMSIMD_TARGET_ICE && !SIMSIMD_TARGET_X86)
143
- #if defined(__AVX512VNNI__) && defined(__AVX512IFMA__) && defined(__AVX512BITALG__) && defined(__AVX512VBMI2__) && \
183
+ #endif // !defined(SIMSIMD_TARGET_SKYLAKE) || ...
184
+ #if !defined(SIMSIMD_TARGET_ICE) || (SIMSIMD_TARGET_ICE && !_SIMSIMD_TARGET_X86)
185
+ #if defined(__AVX512VNNI__) && defined(__AVX512IFMA__) && defined(__AVX512BITALG__) && defined(__AVX512VBMI2__) && \
144
186
  defined(__AVX512VPOPCNTDQ__)
145
187
  #define SIMSIMD_TARGET_ICE 1
146
188
  #else
147
189
  #undef SIMSIMD_TARGET_ICE
148
190
  #define SIMSIMD_TARGET_ICE 0
149
191
  #endif
150
- #endif // !defined(SIMSIMD_TARGET_ICE)
151
- #if !defined(SIMSIMD_TARGET_GENOA) || (SIMSIMD_TARGET_GENOA && !SIMSIMD_TARGET_X86)
192
+ #endif // !defined(SIMSIMD_TARGET_ICE) || ...
193
+ #if !defined(SIMSIMD_TARGET_GENOA) || (SIMSIMD_TARGET_GENOA && !_SIMSIMD_TARGET_X86)
152
194
  #if defined(__AVX512BF16__)
153
195
  #define SIMSIMD_TARGET_GENOA 1
154
196
  #else
155
197
  #undef SIMSIMD_TARGET_GENOA
156
198
  #define SIMSIMD_TARGET_GENOA 0
157
199
  #endif
158
- #endif // !defined(SIMSIMD_TARGET_GENOA)
159
- #if !defined(SIMSIMD_TARGET_SAPPHIRE) || (SIMSIMD_TARGET_SAPPHIRE && !SIMSIMD_TARGET_X86)
200
+ #endif // !defined(SIMSIMD_TARGET_GENOA) || ...
201
+ #if !defined(SIMSIMD_TARGET_SAPPHIRE) || (SIMSIMD_TARGET_SAPPHIRE && !_SIMSIMD_TARGET_X86)
160
202
  #if defined(__AVX512FP16__)
161
203
  #define SIMSIMD_TARGET_SAPPHIRE 1
162
204
  #else
163
205
  #undef SIMSIMD_TARGET_SAPPHIRE
164
206
  #define SIMSIMD_TARGET_SAPPHIRE 0
165
207
  #endif
166
- #endif // !defined(SIMSIMD_TARGET_SAPPHIRE)
208
+ #endif // !defined(SIMSIMD_TARGET_SAPPHIRE) || ...
209
+ #if !defined(SIMSIMD_TARGET_TURIN) || (SIMSIMD_TARGET_TURIN && !_SIMSIMD_TARGET_X86)
210
+ #if defined(__AVX512VP2INTERSECT__)
211
+ #define SIMSIMD_TARGET_TURIN 1
212
+ #else
213
+ #undef SIMSIMD_TARGET_TURIN
214
+ #define SIMSIMD_TARGET_TURIN 0
215
+ #endif
216
+ #endif // !defined(SIMSIMD_TARGET_TURIN) || ...
217
+ #if !defined(SIMSIMD_TARGET_SIERRA) || (SIMSIMD_TARGET_SIERRA && !_SIMSIMD_TARGET_X86)
218
+ #if defined(__AVX2_VNNI__)
219
+ #define SIMSIMD_TARGET_SIERRA 1
220
+ #else
221
+ #undef SIMSIMD_TARGET_SIERRA
222
+ #define SIMSIMD_TARGET_SIERRA 0
223
+ #endif
224
+ #endif // !defined(SIMSIMD_TARGET_SIERRA) || ...
167
225
 
168
226
  #ifdef _MSC_VER
169
227
  #include <intrin.h>
@@ -177,8 +235,8 @@
177
235
  #include <arm_sve.h>
178
236
  #endif
179
237
 
180
- #if SIMSIMD_TARGET_HASWELL || SIMSIMD_TARGET_SKYLAKE || SIMSIMD_TARGET_ICE || SIMSIMD_TARGET_GENOA || \
181
- SIMSIMD_TARGET_SAPPHIRE
238
+ #if SIMSIMD_TARGET_HASWELL || SIMSIMD_TARGET_SKYLAKE || SIMSIMD_TARGET_ICE || SIMSIMD_TARGET_GENOA || \
239
+ SIMSIMD_TARGET_SAPPHIRE || SIMSIMD_TARGET_TURIN
182
240
  #include <immintrin.h>
183
241
  #endif
184
242
 
@@ -212,6 +270,7 @@ extern "C" {
212
270
  #endif
213
271
 
214
272
  typedef unsigned char simsimd_b8_t;
273
+ typedef unsigned char simsimd_i4x2_t;
215
274
 
216
275
  typedef signed char simsimd_i8_t;
217
276
  typedef unsigned char simsimd_u8_t;
@@ -235,12 +294,12 @@ typedef simsimd_f64_t simsimd_distance_t;
235
294
  * - Default: `unsigned short`.
236
295
  */
237
296
  #if !defined(SIMSIMD_NATIVE_F16) || SIMSIMD_NATIVE_F16
238
- #if (defined(__GNUC__) || defined(__clang__)) && (defined(__ARM_ARCH) || defined(__aarch64__)) && \
297
+ #if (defined(__GNUC__) || defined(__clang__)) && (defined(__ARM_ARCH) || defined(__aarch64__)) && \
239
298
  (defined(__ARM_FP16_FORMAT_IEEE))
240
299
  #undef SIMSIMD_NATIVE_F16
241
300
  #define SIMSIMD_NATIVE_F16 1
242
301
  typedef __fp16 simsimd_f16_t;
243
- #elif ((defined(__GNUC__) || defined(__clang__)) && (defined(__x86_64__) || defined(__i386__)) && \
302
+ #elif ((defined(__GNUC__) || defined(__clang__)) && (defined(__x86_64__) || defined(__i386__)) && \
244
303
  (defined(__AVX512FP16__)))
245
304
  typedef _Float16 simsimd_f16_t;
246
305
  #undef SIMSIMD_NATIVE_F16
@@ -283,12 +342,12 @@ typedef unsigned short simsimd_f16_t;
283
342
  * https://forums.developer.apple.com/forums/thread/726201
284
343
  * https://www.phoronix.com/news/GCC-LLVM-bf16-BFloat16-Type
285
344
  */
286
- #if (defined(__GNUC__) || defined(__clang__)) && (defined(__ARM_ARCH) || defined(__aarch64__)) && \
345
+ #if (defined(__GNUC__) || defined(__clang__)) && (defined(__ARM_ARCH) || defined(__aarch64__)) && \
287
346
  (defined(__ARM_BF16_FORMAT_ALTERNATIVE))
288
347
  #undef SIMSIMD_NATIVE_BF16
289
348
  #define SIMSIMD_NATIVE_BF16 1
290
349
  typedef __bf16 simsimd_bf16_t;
291
- #elif ((defined(__GNUC__) || defined(__clang__)) && (defined(__x86_64__) || defined(__i386__)) && \
350
+ #elif ((defined(__GNUC__) || defined(__clang__)) && (defined(__x86_64__) || defined(__i386__)) && \
292
351
  (defined(__AVX512BF16__)))
293
352
  typedef __bfloat16 simsimd_bf16_t;
294
353
  #undef SIMSIMD_NATIVE_BF16
@@ -315,7 +374,7 @@ typedef unsigned short simsimd_bf16_t;
315
374
  * Some of those are defined as aliases, so we use `#define` preprocessor
316
375
  * directives instead of `typedef` to avoid errors.
317
376
  */
318
- #if SIMSIMD_TARGET_ARM
377
+ #if _SIMSIMD_TARGET_ARM
319
378
  #if defined(_MSC_VER)
320
379
  #define simsimd_f16_for_arm_simd_t simsimd_f16_t
321
380
  #define simsimd_bf16_for_arm_simd_t simsimd_bf16_t
@@ -330,6 +389,8 @@ typedef unsigned short simsimd_bf16_t;
330
389
  * In C the `_Static_assert` is only available with C 11 and later.
331
390
  */
332
391
  #define SIMSIMD_STATIC_ASSERT(cond, msg) typedef char static_assertion_##msg[(cond) ? 1 : -1]
392
+ SIMSIMD_STATIC_ASSERT(sizeof(simsimd_b8_t) == 1, simsimd_b8_t_must_be_1_byte);
393
+ SIMSIMD_STATIC_ASSERT(sizeof(simsimd_i4x2_t) == 1, simsimd_i4x2_t_must_be_1_byte);
333
394
  SIMSIMD_STATIC_ASSERT(sizeof(simsimd_i8_t) == 1, simsimd_i8_t_must_be_1_byte);
334
395
  SIMSIMD_STATIC_ASSERT(sizeof(simsimd_u8_t) == 1, simsimd_u8_t_must_be_1_byte);
335
396
  SIMSIMD_STATIC_ASSERT(sizeof(simsimd_i16_t) == 2, simsimd_i16_t_must_be_2_bytes);
@@ -374,6 +435,19 @@ SIMSIMD_STATIC_ASSERT(sizeof(simsimd_bf16_t) == 2, simsimd_bf16_t_must_be_2_byte
374
435
  #endif
375
436
  #endif
376
437
 
438
+ #if !defined(SIMSIMD_F32_TO_I8)
439
+ #define SIMSIMD_F32_TO_I8(x, y) *(y) = (simsimd_i8_t)fminf(fmaxf(roundf(x), -128), 127)
440
+ #endif
441
+ #if !defined(SIMSIMD_F32_TO_U8)
442
+ #define SIMSIMD_F32_TO_U8(x, y) *(y) = (simsimd_u8_t)fminf(fmaxf(roundf(x), 0), 255)
443
+ #endif
444
+ #if !defined(SIMSIMD_F64_TO_I8)
445
+ #define SIMSIMD_F64_TO_I8(x, y) *(y) = (simsimd_i8_t)fmin(fmax(round(x), -128), 127)
446
+ #endif
447
+ #if !defined(SIMSIMD_F64_TO_U8)
448
+ #define SIMSIMD_F64_TO_U8(x, y) *(y) = (simsimd_u8_t)fmin(fmax(round(x), 0), 255)
449
+ #endif
450
+
377
451
  /** @brief Convenience type for half-precision floating-point type conversions. */
378
452
  typedef union {
379
453
  unsigned i;
@@ -423,8 +497,8 @@ SIMSIMD_PUBLIC simsimd_f32_t simsimd_approximate_log(simsimd_f32_t number) {
423
497
  * https://gist.github.com/milhidaka/95863906fe828198f47991c813dbe233
424
498
  * https://github.com/OpenCyphal/libcanard/blob/636795f4bc395f56af8d2c61d3757b5e762bb9e5/canard.c#L811-L834
425
499
  */
426
- SIMSIMD_PUBLIC simsimd_f32_t simsimd_f16_to_f32(simsimd_f16_t const* x_ptr) {
427
- unsigned short x = *(unsigned short const*)x_ptr;
500
+ SIMSIMD_PUBLIC simsimd_f32_t simsimd_f16_to_f32(simsimd_f16_t const *x_ptr) {
501
+ unsigned short x = *(unsigned short const *)x_ptr;
428
502
  unsigned int exponent = (x & 0x7C00) >> 10;
429
503
  unsigned int mantissa = (x & 0x03FF) << 13;
430
504
  simsimd_f32i32_t mantissa_conv;
@@ -445,7 +519,7 @@ SIMSIMD_PUBLIC simsimd_f32_t simsimd_f16_to_f32(simsimd_f16_t const* x_ptr) {
445
519
  * https://gist.github.com/milhidaka/95863906fe828198f47991c813dbe233
446
520
  * https://github.com/OpenCyphal/libcanard/blob/636795f4bc395f56af8d2c61d3757b5e762bb9e5/canard.c#L811-L834
447
521
  */
448
- SIMSIMD_PUBLIC void simsimd_f32_to_f16(simsimd_f32_t x, simsimd_f16_t* result_ptr) {
522
+ SIMSIMD_PUBLIC void simsimd_f32_to_f16(simsimd_f32_t x, simsimd_f16_t *result_ptr) {
449
523
  simsimd_f32i32_t conv;
450
524
  conv.f = x;
451
525
  unsigned int b = conv.i + 0x00001000;
@@ -454,7 +528,7 @@ SIMSIMD_PUBLIC void simsimd_f32_to_f16(simsimd_f32_t x, simsimd_f16_t* result_pt
454
528
  unsigned short result = ((b & 0x80000000) >> 16) | (e > 112) * ((((e - 112) << 10) & 0x7C00) | (m >> 13)) |
455
529
  ((e < 113) & (e > 101)) * ((((0x007FF000 + m) >> (125 - e)) + 1) >> 1) |
456
530
  ((e > 143) * 0x7FFF);
457
- *(unsigned short*)result_ptr = result;
531
+ *(unsigned short *)result_ptr = result;
458
532
  }
459
533
 
460
534
  /**
@@ -464,8 +538,8 @@ SIMSIMD_PUBLIC void simsimd_f32_to_f16(simsimd_f32_t x, simsimd_f16_t* result_pt
464
538
  * https://stackoverflow.com/questions/55253233/convert-fp32-to-bfloat16-in-c/55254307#55254307
465
539
  * https://cloud.google.com/blog/products/ai-machine-learning/bfloat16-the-secret-to-high-performance-on-cloud-tpus
466
540
  */
467
- SIMSIMD_PUBLIC simsimd_f32_t simsimd_bf16_to_f32(simsimd_bf16_t const* x_ptr) {
468
- unsigned short x = *(unsigned short const*)x_ptr;
541
+ SIMSIMD_PUBLIC simsimd_f32_t simsimd_bf16_to_f32(simsimd_bf16_t const *x_ptr) {
542
+ unsigned short x = *(unsigned short const *)x_ptr;
469
543
  simsimd_f32i32_t conv;
470
544
  conv.i = x << 16; // Zero extends the mantissa
471
545
  return conv.f;
@@ -477,14 +551,14 @@ SIMSIMD_PUBLIC simsimd_f32_t simsimd_bf16_to_f32(simsimd_bf16_t const* x_ptr) {
477
551
  * https://stackoverflow.com/questions/55253233/convert-fp32-to-bfloat16-in-c/55254307#55254307
478
552
  * https://cloud.google.com/blog/products/ai-machine-learning/bfloat16-the-secret-to-high-performance-on-cloud-tpus
479
553
  */
480
- SIMSIMD_PUBLIC void simsimd_f32_to_bf16(simsimd_f32_t x, simsimd_bf16_t* result_ptr) {
554
+ SIMSIMD_PUBLIC void simsimd_f32_to_bf16(simsimd_f32_t x, simsimd_bf16_t *result_ptr) {
481
555
  simsimd_f32i32_t conv;
482
556
  conv.f = x;
483
557
  conv.i += 0x8000; // Rounding is optional
484
558
  conv.i >>= 16;
485
559
  // The top 16 bits will be zeroed out anyways
486
560
  // conv.i &= 0xFFFF;
487
- *(unsigned short*)result_ptr = (unsigned short)conv.i;
561
+ *(unsigned short *)result_ptr = (unsigned short)conv.i;
488
562
  }
489
563
 
490
564
  SIMSIMD_PUBLIC simsimd_u32_t simsimd_u32_rol(simsimd_u32_t x, int n) { return (x << n) | (x >> (32 - n)); }
@@ -67,8 +67,7 @@ napi_value runAPI(napi_env env, napi_callback_info info, simsimd_metric_kind_t m
67
67
  // Convert the result to a JavaScript number
68
68
  napi_value js_result;
69
69
  status = napi_create_double(env, result, &js_result);
70
- if (status != napi_ok)
71
- return NULL;
70
+ if (status != napi_ok) return NULL;
72
71
 
73
72
  return js_result;
74
73
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "simsimd",
3
- "version": "5.6.4",
4
- "description": "Fastest SIMD-Accelerated Vector Similarity Functions for x86 and Arm",
3
+ "version": "5.9.6",
4
+ "description": "Portable mixed-precision BLAS-like vector math library for x86 and ARM",
5
5
  "homepage": "https://github.com/ashvardanian/simsimd",
6
6
  "author": "Ash Vardanian",
7
7
  "license": "Apache 2.0",
@@ -27,8 +27,8 @@
27
27
  "prebuild-arm64": "prebuildify --arch arm64 --napi --strip --target=10.4.0",
28
28
  "prebuild-darwin-x64+arm64": "prebuildify --arch arm64+x64 --napi --strip --target=10.4.0",
29
29
  "build-js": "rm -fr javascript/dist/* && tsc -p javascript/tsconfig-esm.json && tsc -p javascript/tsconfig-cjs.json && cp javascript/dist-package-esm.json javascript/dist/esm/package.json && cp javascript/dist-package-cjs.json javascript/dist/cjs/package.json",
30
- "test": "node --test ./javascript/test.mjs",
31
- "bench": "node ./javascript/bench.js"
30
+ "test": "node --test ./scripts/test.mjs",
31
+ "bench": "node ./scripts/bench.js"
32
32
  },
33
33
  "main": "javascript/dist/cjs/simsimd.js",
34
34
  "module": "javascript/dist/esm/simsimd.js",
@@ -106,6 +106,8 @@ extern "C" {
106
106
  fn simsimd_uses_ice() -> i32;
107
107
  fn simsimd_uses_genoa() -> i32;
108
108
  fn simsimd_uses_sapphire() -> i32;
109
+ fn simsimd_uses_turin() -> i32;
110
+ fn simsimd_uses_sierra() -> i32;
109
111
  }
110
112
 
111
113
  /// A half-precision floating point number.
@@ -175,6 +177,14 @@ pub mod capabilities {
175
177
  pub fn uses_sapphire() -> bool {
176
178
  unsafe { crate::simsimd_uses_sapphire() != 0 }
177
179
  }
180
+
181
+ pub fn uses_turin() -> bool {
182
+ unsafe { crate::simsimd_uses_turin() != 0 }
183
+ }
184
+
185
+ pub fn uses_sierra() -> bool {
186
+ unsafe { crate::simsimd_uses_sierra() != 0 }
187
+ }
178
188
  }
179
189
 
180
190
  /// `SpatialSimilarity` provides a set of trait methods for computing similarity
@@ -710,7 +720,8 @@ mod tests {
710
720
  || capabilities::uses_skylake()
711
721
  || capabilities::uses_ice()
712
722
  || capabilities::uses_genoa()
713
- || capabilities::uses_sapphire();
723
+ || capabilities::uses_sapphire()
724
+ || capabilities::uses_turin();
714
725
 
715
726
  // The CPU can't simultaneously support ARM and x86 SIMD extensions
716
727
  if uses_arm {
@@ -727,6 +738,8 @@ mod tests {
727
738
  println!("- uses_ice: {}", capabilities::uses_ice());
728
739
  println!("- uses_genoa: {}", capabilities::uses_genoa());
729
740
  println!("- uses_sapphire: {}", capabilities::uses_sapphire());
741
+ println!("- uses_turin: {}", capabilities::uses_turin());
742
+ println!("- uses_sierra: {}", capabilities::uses_sierra());
730
743
  }
731
744
 
732
745
  //