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