usearch 2.9.2 → 2.10.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.
Files changed (172) hide show
  1. package/README.md +39 -38
  2. package/javascript/{types → dist/cjs}/usearch.d.ts +90 -115
  3. package/javascript/dist/cjs/usearch.js +531 -0
  4. package/javascript/dist/esm/usearch.d.ts +212 -0
  5. package/javascript/{usearch.js → dist/esm/usearch.js} +199 -153
  6. package/package.json +25 -23
  7. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  8. package/prebuilds/linux-arm64/usearch.node +0 -0
  9. package/prebuilds/linux-x64/usearch.node +0 -0
  10. package/prebuilds/win32-ia32/usearch.node +0 -0
  11. package/prebuilds/win32-x64/usearch.node +0 -0
  12. package/.clang-format +0 -10
  13. package/.clang-tidy +0 -60
  14. package/.cmake-format.py +0 -19
  15. package/.dockerignore +0 -93
  16. package/.gitattributes +0 -9
  17. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -90
  18. package/.github/ISSUE_TEMPLATE/config.yml +0 -5
  19. package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -64
  20. package/.github/workflows/Dockerfile.libs +0 -36
  21. package/.github/workflows/prerelease.yml +0 -331
  22. package/.github/workflows/release.yml +0 -722
  23. package/.github/workflows/update_version.sh +0 -15
  24. package/.gitmodules +0 -9
  25. package/.releaserc +0 -90
  26. package/CITATION.cff +0 -11
  27. package/CMakeLists.txt +0 -324
  28. package/CODE_OF_CONDUCT.md +0 -128
  29. package/CONTRIBUTING.md +0 -361
  30. package/Cargo.toml +0 -19
  31. package/Dockerfile +0 -16
  32. package/VERSION +0 -1
  33. package/assets/unum.png +0 -0
  34. package/assets/usearch-approaches-transparent.png +0 -0
  35. package/assets/usearch-approaches-white.png +0 -0
  36. package/assets/usearch-neighbor-types.png +0 -0
  37. package/binding.gyp +0 -87
  38. package/build.gradle +0 -204
  39. package/build.rs +0 -18
  40. package/c/CMakeLists.txt +0 -25
  41. package/c/README.md +0 -34
  42. package/c/lib.cpp +0 -358
  43. package/c/test.c +0 -382
  44. package/c/usearch.h +0 -311
  45. package/cmake/clipp.cmake +0 -7
  46. package/cmake/config.cmake.in +0 -15
  47. package/cmake/emscripten.cmake +0 -8
  48. package/cmake/jemalloc.cmake +0 -62
  49. package/cmake/pkg-config.pc.in +0 -4
  50. package/cmake/usearchConfigVersion.cmake.in +0 -20
  51. package/conanfile.py +0 -26
  52. package/cpp/CMakeLists.txt +0 -14
  53. package/cpp/README.md +0 -161
  54. package/cpp/bench.cpp +0 -618
  55. package/cpp/test.cpp +0 -323
  56. package/fp16/CMakeLists.txt +0 -176
  57. package/fp16/LICENSE +0 -11
  58. package/fp16/README.md +0 -20
  59. package/fp16/bench/alt-element.cc +0 -89
  60. package/fp16/bench/from-alt-array.cc +0 -175
  61. package/fp16/bench/from-ieee-array.cc +0 -399
  62. package/fp16/bench/ieee-element.cc +0 -272
  63. package/fp16/bench/to-alt-array.cc +0 -91
  64. package/fp16/bench/to-ieee-array.cc +0 -303
  65. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  66. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  67. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  68. package/fp16/configure.py +0 -65
  69. package/fp16/confu.yaml +0 -8
  70. package/fp16/include/fp16/__init__.py +0 -0
  71. package/fp16/include/fp16/avx.py +0 -50
  72. package/fp16/include/fp16/avx2.py +0 -53
  73. package/fp16/include/fp16/bitcasts.h +0 -92
  74. package/fp16/include/fp16/fp16.h +0 -451
  75. package/fp16/include/fp16/psimd.h +0 -131
  76. package/fp16/include/fp16.h +0 -11
  77. package/fp16/jni/Android.mk +0 -6
  78. package/fp16/jni/Application.mk +0 -4
  79. package/fp16/test/alt-from-fp32-value.cc +0 -498
  80. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  81. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  82. package/fp16/test/alt-to-fp32-value.cc +0 -348
  83. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  84. package/fp16/test/bitcasts.cc +0 -56
  85. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  86. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  87. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  88. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  89. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  90. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  91. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  92. package/fp16/test/peachpy/stubs.py +0 -38
  93. package/fp16/test/tables.cc +0 -530
  94. package/fp16/test/tables.h +0 -13
  95. package/fp16/third-party/THHalf.h +0 -92
  96. package/fp16/third-party/eigen-half.h +0 -170
  97. package/fp16/third-party/float16-compressor.h +0 -80
  98. package/fp16/third-party/half.hpp +0 -2916
  99. package/fp16/third-party/npy-halffloat.h +0 -328
  100. package/include/usearch/index.hpp +0 -3836
  101. package/include/usearch/index_dense.hpp +0 -2004
  102. package/include/usearch/index_plugins.hpp +0 -2213
  103. package/javascript/lib.cpp +0 -341
  104. package/javascript/types/usearch.d.ts.map +0 -1
  105. package/javascript/usearch.test.js +0 -74
  106. package/package-ci.json +0 -10
  107. package/pyproject.toml +0 -51
  108. package/setup.py +0 -201
  109. package/simsimd/.releaserc +0 -86
  110. package/simsimd/CONTRIBUTING.md +0 -88
  111. package/simsimd/Cargo.lock +0 -709
  112. package/simsimd/Cargo.toml +0 -44
  113. package/simsimd/LICENSE +0 -201
  114. package/simsimd/README.md +0 -317
  115. package/simsimd/binding.gyp +0 -36
  116. package/simsimd/build.rs +0 -20
  117. package/simsimd/include/simsimd/binary.h +0 -245
  118. package/simsimd/include/simsimd/complex.h +0 -174
  119. package/simsimd/include/simsimd/probability.h +0 -548
  120. package/simsimd/include/simsimd/simsimd.h +0 -465
  121. package/simsimd/include/simsimd/spatial.h +0 -1267
  122. package/simsimd/include/simsimd/types.h +0 -208
  123. package/simsimd/javascript/bench.js +0 -127
  124. package/simsimd/javascript/fallback.ts +0 -193
  125. package/simsimd/javascript/lib.c +0 -102
  126. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  127. package/simsimd/javascript/simsimd.ts +0 -124
  128. package/simsimd/javascript/test.mjs +0 -153
  129. package/simsimd/javascript/tsconfig-base.json +0 -25
  130. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  131. package/simsimd/javascript/tsconfig-esm.json +0 -8
  132. package/simsimd/package-lock.json +0 -1688
  133. package/simsimd/package.json +0 -61
  134. package/simsimd/rust/benches/cosine.rs +0 -27
  135. package/simsimd/rust/benches/native.rs +0 -30
  136. package/simsimd/rust/benches/sqeuclidean.rs +0 -27
  137. package/simsimd/rust/lib.c +0 -45
  138. package/simsimd/rust/lib.rs +0 -550
  139. package/sqlite/README.md +0 -178
  140. package/sqlite/lib.cpp +0 -325
  141. package/stringzilla/CONTRIBUTING.md +0 -446
  142. package/stringzilla/Cargo.lock +0 -25
  143. package/stringzilla/Cargo.toml +0 -26
  144. package/stringzilla/LICENSE +0 -201
  145. package/stringzilla/README.md +0 -1422
  146. package/stringzilla/VERSION +0 -1
  147. package/stringzilla/assets/cover-strinzilla.jpeg +0 -0
  148. package/stringzilla/assets/meme-stringzilla-v2.jpeg +0 -0
  149. package/stringzilla/assets/meme-stringzilla-v3.jpeg +0 -0
  150. package/stringzilla/binding.gyp +0 -16
  151. package/stringzilla/build.rs +0 -87
  152. package/stringzilla/c/lib.c +0 -337
  153. package/stringzilla/cli/README.md +0 -65
  154. package/stringzilla/cli/__init__.py +0 -0
  155. package/stringzilla/cli/split.py +0 -105
  156. package/stringzilla/cli/wc.py +0 -117
  157. package/stringzilla/include/stringzilla/experimental.h +0 -845
  158. package/stringzilla/include/stringzilla/module.modulemap +0 -9
  159. package/stringzilla/include/stringzilla/stringzilla.h +0 -5370
  160. package/stringzilla/include/stringzilla/stringzilla.hpp +0 -3838
  161. package/stringzilla/javascript/lib.c +0 -125
  162. package/stringzilla/javascript/stringzilla.js +0 -22
  163. package/stringzilla/package-ci.json +0 -10
  164. package/stringzilla/package.json +0 -32
  165. package/stringzilla/rust/lib.rs +0 -873
  166. package/stringzilla/swift/StringProtocol+StringZilla.swift +0 -280
  167. package/stringzilla/swift/Test.swift +0 -60
  168. package/tsconfig.json +0 -21
  169. package/wasmer.toml +0 -12
  170. package/winlibinstaller.bat +0 -42
  171. /package/{simsimd/javascript/dist-package-cjs.json → javascript/dist/cjs/package.json} +0 -0
  172. /package/{simsimd/javascript/dist-package-esm.json → javascript/dist/esm/package.json} +0 -0
@@ -1,465 +0,0 @@
1
- /**
2
- * @brief SIMD-accelerated Similarity Measures and Distance Functions.
3
- * @file simsimd.h
4
- * @author Ash Vardanian
5
- * @date March 14, 2023
6
- * @copyright Copyright (c) 2023
7
- *
8
- * References:
9
- * x86 intrinsics: https://www.intel.com/content/www/us/en/docs/intrinsics-guide/
10
- * Arm intrinsics: https://developer.arm.com/architectures/instruction-sets/intrinsics/
11
- * Detecting target CPU features at compile time: https://stackoverflow.com/a/28939692/2766161
12
- */
13
-
14
- #ifndef SIMSIMD_H
15
- #define SIMSIMD_H
16
-
17
- #define SIMSIMD_VERSION_MAJOR 3
18
- #define SIMSIMD_VERSION_MINOR 9
19
- #define SIMSIMD_VERSION_PATCH 0
20
-
21
- #include "binary.h" // Hamming, Jaccard
22
- #include "complex.h" // Complex numbers
23
- #include "probability.h" // Kullback-Leibler, Jensen–Shannon
24
- #include "spatial.h" // L2, Inner Product, Cosine
25
-
26
- #if SIMSIMD_TARGET_ARM
27
- #ifdef __linux__
28
- #include <asm/hwcap.h>
29
- #include <sys/auxv.h>
30
- #endif
31
- #endif
32
-
33
- #ifdef __cplusplus
34
- extern "C" {
35
- #endif
36
-
37
- /**
38
- * @brief Enumeration of supported metric kinds.
39
- */
40
- typedef enum {
41
- simsimd_metric_unknown_k = 0, ///< Unknown metric kind
42
-
43
- // Classics:
44
- simsimd_metric_ip_k = 'i', ///< Inner product
45
- simsimd_metric_dot_k = 'i', ///< Inner product alias
46
- simsimd_metric_inner_k = 'i', ///< Inner product alias
47
-
48
- simsimd_metric_cos_k = 'c', ///< Cosine similarity
49
- simsimd_metric_cosine_k = 'c', ///< Cosine similarity alias
50
- simsimd_metric_angular_k = 'c', ///< Cosine similarity alias
51
-
52
- simsimd_metric_l2sq_k = 'e', ///< Squared Euclidean distance
53
- simsimd_metric_sqeuclidean_k = 'e', ///< Squared Euclidean distance alias
54
-
55
- // Binary:
56
- simsimd_metric_hamming_k = 'b', ///< Hamming distance
57
- simsimd_metric_jaccard_k = 'j', ///< Jaccard coefficient
58
-
59
- // Probability:
60
- simsimd_metric_kl_k = 'k', ///< Kullback-Leibler divergence
61
- simsimd_metric_kullback_leibler_k = 'k', ///< Kullback-Leibler divergence alias
62
-
63
- simsimd_metric_js_k = 's', ///< Jensen-Shannon divergence
64
- simsimd_metric_jensen_shannon_k = 's', ///< Jensen-Shannon divergence alias
65
-
66
- } simsimd_metric_kind_t;
67
-
68
- /**
69
- * @brief Enumeration of SIMD capabilities of the target architecture.
70
- */
71
- typedef enum {
72
- simsimd_cap_serial_k = 1, ///< Serial (non-SIMD) capability
73
- simsimd_cap_any_k = 0x7FFFFFFF, ///< Mask representing any capability with `INT_MAX`
74
-
75
- simsimd_cap_arm_neon_k = 1 << 10, ///< ARM NEON capability
76
- simsimd_cap_arm_sve_k = 1 << 11, ///< ARM SVE capability
77
- simsimd_cap_arm_sve2_k = 1 << 12, ///< ARM SVE2 capability
78
-
79
- simsimd_cap_x86_avx2_k = 1 << 20, ///< x86 AVX2 capability
80
- simsimd_cap_x86_avx512_k = 1 << 21, ///< x86 AVX512 capability
81
- simsimd_cap_x86_avx2fp16_k = 1 << 22, ///< x86 AVX2 with FP16 capability
82
- simsimd_cap_x86_avx512fp16_k = 1 << 23, ///< x86 AVX512 with FP16 capability
83
- simsimd_cap_x86_avx512vpopcntdq_k = 1 << 24, ///< x86 AVX512 VPOPCNTDQ instruction capability
84
- simsimd_cap_x86_avx512vnni_k = 1 << 25, ///< x86 AVX512 VNNI instruction capability
85
-
86
- } simsimd_capability_t;
87
-
88
- /**
89
- * @brief Enumeration of supported data types.
90
- */
91
- typedef enum {
92
- simsimd_datatype_unknown_k, ///< Unknown data type
93
- simsimd_datatype_f64_k, ///< Double precision floating point
94
- simsimd_datatype_f32_k, ///< Single precision floating point
95
- simsimd_datatype_f16_k, ///< Half precision floating point
96
- simsimd_datatype_i8_k, ///< 8-bit integer
97
- simsimd_datatype_b8_k, ///< Single-bit values packed into 8-bit words
98
- } simsimd_datatype_t;
99
-
100
- /**
101
- * @brief Type-punned function pointer accepting two vectors and outputting their similarity/distance.
102
- *
103
- * @param[in] a Pointer to the first data array.
104
- * @param[in] b Pointer to the second data array.
105
- * @param[in] size_a Size of the first data array.
106
- * @param[in] size_b Size of the second data array.
107
- * @return Computed metric as a single-precision floating-point value.
108
- */
109
- typedef simsimd_f32_t (*simsimd_metric_punned_t)(void const* a, void const* b, simsimd_size_t size_a,
110
- simsimd_size_t size_b);
111
-
112
- /**
113
- * @brief Function to determine the SIMD capabilities of the current machine at @b runtime.
114
- * @return A bitmask of the SIMD capabilities represented as a `simsimd_capability_t` enum value.
115
- */
116
- inline static simsimd_capability_t simsimd_capabilities(void) {
117
-
118
- #if SIMSIMD_TARGET_X86
119
-
120
- /// The states of 4 registers populated for a specific "cpuid" assembly call
121
- union four_registers_t {
122
- int array[4];
123
- struct separate_t {
124
- unsigned eax, ebx, ecx, edx;
125
- } named;
126
- } info1, info7;
127
-
128
- #ifdef _MSC_VER
129
- __cpuidex(info1.array, 1, 0);
130
- __cpuidex(info7.array, 7, 0);
131
- #else
132
- __asm__ __volatile__("cpuid"
133
- : "=a"(info1.named.eax), "=b"(info1.named.ebx), "=c"(info1.named.ecx), "=d"(info1.named.edx)
134
- : "a"(1), "c"(0));
135
- __asm__ __volatile__("cpuid"
136
- : "=a"(info7.named.eax), "=b"(info7.named.ebx), "=c"(info7.named.ecx), "=d"(info7.named.edx)
137
- : "a"(7), "c"(0));
138
- #endif
139
-
140
- // Check for AVX2 (Function ID 7, EBX register)
141
- // https://github.com/llvm/llvm-project/blob/50598f0ff44f3a4e75706f8c53f3380fe7faa896/clang/lib/Headers/cpuid.h#L148
142
- unsigned supports_avx2 = (info7.named.ebx & 0x00000020) != 0;
143
- // Check for F16C (Function ID 1, ECX register)
144
- // https://github.com/llvm/llvm-project/blob/50598f0ff44f3a4e75706f8c53f3380fe7faa896/clang/lib/Headers/cpuid.h#L107
145
- unsigned supports_f16c = (info1.named.ecx & 0x20000000) != 0;
146
- // Check for AVX512F (Function ID 7, EBX register)
147
- // https://github.com/llvm/llvm-project/blob/50598f0ff44f3a4e75706f8c53f3380fe7faa896/clang/lib/Headers/cpuid.h#L155
148
- unsigned supports_avx512f = (info7.named.ebx & 0x00010000) != 0;
149
- // Check for AVX512FP16 (Function ID 7, EDX register)
150
- // https://github.com/llvm/llvm-project/blob/50598f0ff44f3a4e75706f8c53f3380fe7faa896/clang/lib/Headers/cpuid.h#L198C9-L198C23
151
- unsigned supports_avx512fp16 = (info7.named.edx & 0x00800000) != 0;
152
- // Check for VPOPCNTDQ (Function ID 1, ECX register)
153
- // https://github.com/llvm/llvm-project/blob/50598f0ff44f3a4e75706f8c53f3380fe7faa896/clang/lib/Headers/cpuid.h#L182C30-L182C40
154
- unsigned supports_avx512vpopcntdq = (info1.named.ecx & 0x00004000) != 0;
155
- // Check for VNNI (Function ID 1, ECX register)
156
- // https://github.com/llvm/llvm-project/blob/50598f0ff44f3a4e75706f8c53f3380fe7faa896/clang/lib/Headers/cpuid.h#L180
157
- unsigned supports_avx512vnni = (info1.named.ecx & 0x00000800) != 0;
158
-
159
- return (simsimd_capability_t)( //
160
- (simsimd_cap_x86_avx2_k * supports_avx2) | //
161
- (simsimd_cap_x86_avx512_k * supports_avx512f) | //
162
- (simsimd_cap_x86_avx2fp16_k * (supports_avx2 && supports_f16c)) | //
163
- (simsimd_cap_x86_avx512fp16_k * (supports_avx512fp16 && supports_avx512f)) | //
164
- (simsimd_cap_x86_avx512vpopcntdq_k * (supports_avx512vpopcntdq)) | //
165
- (simsimd_cap_x86_avx512vnni_k * (supports_avx512vnni)) | //
166
- (simsimd_cap_serial_k));
167
-
168
- #endif // SIMSIMD_TARGET_X86
169
-
170
- #if SIMSIMD_TARGET_ARM
171
-
172
- // Every 64-bit Arm CPU supports NEON
173
- unsigned supports_neon = 1;
174
- unsigned supports_sve = 0;
175
- unsigned supports_sve2 = 0;
176
-
177
- #ifdef __linux__
178
- unsigned long hwcap = getauxval(AT_HWCAP);
179
- unsigned long hwcap2 = getauxval(AT_HWCAP2);
180
- supports_sve = (hwcap & HWCAP_SVE) != 0;
181
- supports_sve2 = (hwcap2 & HWCAP2_SVE2) != 0;
182
- #endif
183
-
184
- return (simsimd_capability_t)( //
185
- (simsimd_cap_arm_neon_k * supports_neon) | //
186
- (simsimd_cap_arm_sve_k * supports_sve) | //
187
- (simsimd_cap_arm_sve2_k * supports_sve2) | //
188
- (simsimd_cap_serial_k));
189
-
190
- #endif // SIMSIMD_TARGET_ARM
191
-
192
- return simsimd_cap_serial_k;
193
- }
194
-
195
- #pragma GCC diagnostic push
196
- #pragma GCC diagnostic ignored "-Wcast-function-type"
197
- #pragma clang diagnostic push
198
- #pragma clang diagnostic ignored "-Wcast-function-type"
199
-
200
- /**
201
- * @brief Determines the best suited metric implementation based on the given datatype,
202
- * supported and allowed by hardware capabilities.
203
- *
204
- * @param kind The kind of metric to be evaluated.
205
- * @param datatype The data type for which the metric needs to be evaluated.
206
- * @param supported The hardware capabilities supported by the CPU.
207
- * @param allowed The hardware capabilities allowed for use.
208
- * @param metric_output Output variable for the selected similarity function.
209
- * @param capability_output Output variable for the utilized hardware capabilities.
210
- */
211
- inline static void simsimd_find_metric_punned( //
212
- simsimd_metric_kind_t kind, //
213
- simsimd_datatype_t datatype, //
214
- simsimd_capability_t supported, //
215
- simsimd_capability_t allowed, //
216
- simsimd_metric_punned_t* metric_output, //
217
- simsimd_capability_t* capability_output) {
218
-
219
- simsimd_metric_punned_t* m = metric_output;
220
- simsimd_capability_t* c = capability_output;
221
- simsimd_capability_t viable = (simsimd_capability_t)(supported & allowed);
222
- *m = (simsimd_metric_punned_t)0;
223
- *c = (simsimd_capability_t)0;
224
-
225
- // clang-format off
226
- switch (datatype) {
227
-
228
- case simsimd_datatype_unknown_k: break;
229
-
230
- // Double-precision floating-point vectors
231
- case simsimd_datatype_f64_k:
232
-
233
- #if SIMSIMD_TARGET_X86_AVX512
234
- if (viable & simsimd_cap_x86_avx512_k)
235
- switch (kind) {
236
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f64_ip, *c = simsimd_cap_x86_avx512_k; return;
237
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f64_cos, *c = simsimd_cap_x86_avx512_k; return;
238
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f64_l2sq, *c = simsimd_cap_x86_avx512_k; return;
239
- default: break;
240
- }
241
- #endif
242
- if (viable & simsimd_cap_serial_k)
243
- switch (kind) {
244
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f64_ip, *c = simsimd_cap_serial_k; return;
245
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f64_cos, *c = simsimd_cap_serial_k; return;
246
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f64_l2sq, *c = simsimd_cap_serial_k; return;
247
- case simsimd_metric_js_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f64_js, *c = simsimd_cap_serial_k; return;
248
- case simsimd_metric_kl_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f64_kl, *c = simsimd_cap_serial_k; return;
249
- default: break;
250
- }
251
-
252
- break;
253
-
254
- // Single-precision floating-point vectors
255
- case simsimd_datatype_f32_k:
256
-
257
- #if SIMSIMD_TARGET_ARM_NEON
258
- if (viable & simsimd_cap_arm_neon_k)
259
- switch (kind) {
260
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_neon_f32_ip, *c = simsimd_cap_arm_neon_k; return;
261
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_neon_f32_cos, *c = simsimd_cap_arm_neon_k; return;
262
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_neon_f32_l2sq, *c = simsimd_cap_arm_neon_k; return;
263
- case simsimd_metric_js_k: *m = (simsimd_metric_punned_t)&simsimd_neon_f32_js, *c = simsimd_cap_arm_neon_k; return;
264
- case simsimd_metric_kl_k: *m = (simsimd_metric_punned_t)&simsimd_neon_f32_kl, *c = simsimd_cap_arm_neon_k; return;
265
- default: break;
266
- }
267
- #endif
268
- #if SIMSIMD_TARGET_X86_AVX512
269
- if (viable & simsimd_cap_x86_avx512_k)
270
- switch (kind) {
271
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f32_ip, *c = simsimd_cap_x86_avx512_k; return;
272
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f32_cos, *c = simsimd_cap_x86_avx512_k; return;
273
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f32_l2sq, *c = simsimd_cap_x86_avx512_k; return;
274
- case simsimd_metric_js_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f32_js, *c = simsimd_cap_x86_avx512_k; return;
275
- case simsimd_metric_kl_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f32_kl, *c = simsimd_cap_x86_avx512_k; return;
276
- default: break;
277
- }
278
- #endif
279
- if (viable & simsimd_cap_serial_k)
280
- switch (kind) {
281
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f32_ip, *c = simsimd_cap_serial_k; return;
282
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f32_cos, *c = simsimd_cap_serial_k; return;
283
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f32_l2sq, *c = simsimd_cap_serial_k; return;
284
- case simsimd_metric_js_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f32_js, *c = simsimd_cap_serial_k; return;
285
- case simsimd_metric_kl_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f32_kl, *c = simsimd_cap_serial_k; return;
286
- default: break;
287
- }
288
-
289
- break;
290
-
291
- // Half-precision floating-point vectors
292
- case simsimd_datatype_f16_k:
293
-
294
- #if SIMSIMD_TARGET_ARM_SVE
295
- if (viable & simsimd_cap_arm_sve_k)
296
- switch (kind) {
297
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_sve_f16_ip, *c = simsimd_cap_arm_sve_k; return;
298
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_sve_f16_cos, *c = simsimd_cap_arm_sve_k; return;
299
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_sve_f16_l2sq, *c = simsimd_cap_arm_sve_k; return;
300
- default: break;
301
- }
302
- #endif
303
- #if SIMSIMD_TARGET_ARM_NEON
304
- if (viable & simsimd_cap_arm_neon_k)
305
- switch (kind) {
306
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_neon_f16_ip, *c = simsimd_cap_arm_neon_k; return;
307
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_neon_f16_cos, *c = simsimd_cap_arm_neon_k; return;
308
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_neon_f16_l2sq, *c = simsimd_cap_arm_neon_k; return;
309
- case simsimd_metric_js_k: *m = (simsimd_metric_punned_t)&simsimd_neon_f16_js, *c = simsimd_cap_arm_neon_k; return;
310
- case simsimd_metric_kl_k: *m = (simsimd_metric_punned_t)&simsimd_neon_f16_kl, *c = simsimd_cap_arm_neon_k; return;
311
- default: break;
312
- }
313
- #endif
314
- #if SIMSIMD_TARGET_X86_AVX512
315
- if (viable & simsimd_cap_x86_avx512fp16_k)
316
- switch (kind) {
317
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f16_ip, *c = simsimd_cap_x86_avx512fp16_k; return;
318
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f16_cos, *c = simsimd_cap_x86_avx512fp16_k; return;
319
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f16_l2sq, *c = simsimd_cap_x86_avx512fp16_k; return;
320
- case simsimd_metric_js_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f16_js, *c = simsimd_cap_x86_avx512fp16_k; return;
321
- case simsimd_metric_kl_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_f16_kl, *c = simsimd_cap_x86_avx512fp16_k; return;
322
- default: break;
323
- }
324
- #endif
325
- #if SIMSIMD_TARGET_X86_AVX2
326
- if (viable & simsimd_cap_x86_avx2fp16_k)
327
- switch (kind) {
328
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_avx2_f16_ip, *c = simsimd_cap_x86_avx2fp16_k; return;
329
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_avx2_f16_cos, *c = simsimd_cap_x86_avx2fp16_k; return;
330
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_avx2_f16_l2sq, *c = simsimd_cap_x86_avx2fp16_k; return;
331
- case simsimd_metric_js_k: *m = (simsimd_metric_punned_t)&simsimd_avx2_f16_js, *c = simsimd_cap_x86_avx2fp16_k; return;
332
- case simsimd_metric_kl_k: *m = (simsimd_metric_punned_t)&simsimd_avx2_f16_kl, *c = simsimd_cap_x86_avx2fp16_k; return;
333
- default: break;
334
- }
335
- #endif
336
-
337
- if (viable & simsimd_cap_serial_k)
338
- switch (kind) {
339
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f16_ip, *c = simsimd_cap_serial_k; return;
340
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f16_cos, *c = simsimd_cap_serial_k; return;
341
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f16_l2sq, *c = simsimd_cap_serial_k; return;
342
- case simsimd_metric_js_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f16_js, *c = simsimd_cap_serial_k; return;
343
- case simsimd_metric_kl_k: *m = (simsimd_metric_punned_t)&simsimd_serial_f16_kl, *c = simsimd_cap_serial_k; return;
344
- default: break;
345
- }
346
-
347
- break;
348
-
349
- // Single-byte integer vectors
350
- case simsimd_datatype_i8_k:
351
- #if SIMSIMD_TARGET_ARM_NEON
352
- if (viable & simsimd_cap_arm_neon_k)
353
- switch (kind) {
354
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_neon_i8_ip, *c = simsimd_cap_arm_neon_k; return;
355
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_neon_i8_cos, *c = simsimd_cap_arm_neon_k; return;
356
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_neon_i8_l2sq, *c = simsimd_cap_arm_neon_k; return;
357
- default: break;
358
- }
359
- #endif
360
- #if SIMSIMD_TARGET_X86_AVX512
361
- if (viable & simsimd_cap_x86_avx512vnni_k)
362
- switch (kind) {
363
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_i8_ip, *c = simsimd_cap_x86_avx512vnni_k; return;
364
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_i8_cos, *c = simsimd_cap_x86_avx512vnni_k; return;
365
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_i8_l2sq, *c = simsimd_cap_x86_avx512vnni_k; return;
366
- default: break;
367
- }
368
- #endif
369
- #if SIMSIMD_TARGET_X86_AVX2
370
- if (viable & simsimd_cap_x86_avx2_k)
371
- switch (kind) {
372
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_avx2_i8_ip, *c = simsimd_cap_x86_avx2_k; return;
373
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_avx2_i8_cos, *c = simsimd_cap_x86_avx2_k; return;
374
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_avx2_i8_l2sq, *c = simsimd_cap_x86_avx2_k; return;
375
- default: break;
376
- }
377
- #endif
378
-
379
- if (viable & simsimd_cap_serial_k)
380
- switch (kind) {
381
- case simsimd_metric_ip_k: *m = (simsimd_metric_punned_t)&simsimd_serial_i8_ip, *c = simsimd_cap_serial_k; return;
382
- case simsimd_metric_cos_k: *m = (simsimd_metric_punned_t)&simsimd_serial_i8_cos, *c = simsimd_cap_serial_k; return;
383
- case simsimd_metric_l2sq_k: *m = (simsimd_metric_punned_t)&simsimd_serial_i8_l2sq, *c = simsimd_cap_serial_k; return;
384
- default: break;
385
- }
386
-
387
- break;
388
-
389
- // Binary vectors
390
- case simsimd_datatype_b8_k:
391
-
392
- #if SIMSIMD_TARGET_ARM_SVE
393
- if (viable & simsimd_cap_arm_sve_k)
394
- switch (kind) {
395
- case simsimd_metric_hamming_k: *m = (simsimd_metric_punned_t)&simsimd_sve_b8_hamming, *c = simsimd_cap_arm_sve_k; return;
396
- case simsimd_metric_jaccard_k: *m = (simsimd_metric_punned_t)&simsimd_sve_b8_jaccard, *c = simsimd_cap_arm_sve_k; return;
397
- default: break;
398
- }
399
- #endif
400
- #if SIMSIMD_TARGET_ARM_NEON
401
- if (viable & simsimd_cap_arm_neon_k)
402
- switch (kind) {
403
- case simsimd_metric_hamming_k: *m = (simsimd_metric_punned_t)&simsimd_neon_b8_hamming, *c = simsimd_cap_arm_neon_k; return;
404
- case simsimd_metric_jaccard_k: *m = (simsimd_metric_punned_t)&simsimd_neon_b8_jaccard, *c = simsimd_cap_arm_neon_k; return;
405
- default: break;
406
- }
407
- #endif
408
- #if SIMSIMD_TARGET_X86_AVX512
409
- if (viable & simsimd_cap_x86_avx512vpopcntdq_k)
410
- switch (kind) {
411
- case simsimd_metric_hamming_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_b8_hamming, *c = simsimd_cap_x86_avx512vpopcntdq_k; return;
412
- case simsimd_metric_jaccard_k: *m = (simsimd_metric_punned_t)&simsimd_avx512_b8_jaccard, *c = simsimd_cap_x86_avx512vpopcntdq_k; return;
413
- default: break;
414
- }
415
- #endif
416
- #if SIMSIMD_TARGET_X86_AVX2
417
- if (viable & simsimd_cap_x86_avx2_k)
418
- switch (kind) {
419
- case simsimd_metric_hamming_k: *m = (simsimd_metric_punned_t)&simsimd_avx2_b8_hamming, *c = simsimd_cap_x86_avx2_k; return;
420
- case simsimd_metric_jaccard_k: *m = (simsimd_metric_punned_t)&simsimd_avx2_b8_jaccard, *c = simsimd_cap_x86_avx2_k; return;
421
- default: break;
422
- }
423
- #endif
424
-
425
- if (viable & simsimd_cap_serial_k)
426
- switch (kind) {
427
- case simsimd_metric_hamming_k: *m = (simsimd_metric_punned_t)&simsimd_serial_b8_hamming, *c = simsimd_cap_serial_k; return;
428
- case simsimd_metric_jaccard_k: *m = (simsimd_metric_punned_t)&simsimd_serial_b8_jaccard, *c = simsimd_cap_serial_k; return;
429
- default: break;
430
- }
431
-
432
- break;
433
- }
434
- // clang-format on
435
- }
436
-
437
- #pragma clang diagnostic pop
438
- #pragma GCC diagnostic pop
439
-
440
- /**
441
- * @brief Selects the most suitable metric implementation based on the given metric kind, datatype,
442
- * and allowed capabilities. @b Don't call too often and prefer caching the `simsimd_capabilities()`.
443
- *
444
- * @param kind The kind of metric to be evaluated.
445
- * @param datatype The data type for which the metric needs to be evaluated.
446
- * @param allowed The hardware capabilities allowed for use.
447
- * @return A function pointer to the selected metric implementation.
448
- */
449
- inline static simsimd_metric_punned_t simsimd_metric_punned( //
450
- simsimd_metric_kind_t kind, //
451
- simsimd_datatype_t datatype, //
452
- simsimd_capability_t allowed) {
453
-
454
- simsimd_metric_punned_t result = 0;
455
- simsimd_capability_t c = simsimd_cap_serial_k;
456
- simsimd_capability_t supported = simsimd_capabilities();
457
- simsimd_find_metric_punned(kind, datatype, supported, allowed, &result, &c);
458
- return result;
459
- }
460
-
461
- #ifdef __cplusplus
462
- }
463
- #endif
464
-
465
- #endif