usearch 2.15.2 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/binding.gyp +1 -1
- package/c/CMakeLists.txt +10 -3
- package/cpp/README.md +1 -1
- package/cpp/bench.cpp +2 -2
- package/cpp/test.cpp +16 -0
- package/include/usearch/index.hpp +44 -17
- package/include/usearch/index_dense.hpp +51 -89
- package/include/usearch/index_plugins.hpp +468 -43
- package/javascript/lib.cpp +17 -5
- package/javascript/usearch.test.js +205 -34
- package/package.json +1 -1
- package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
- package/prebuilds/linux-arm64/usearch.node +0 -0
- package/prebuilds/linux-x64/usearch.node +0 -0
- package/simsimd/.git-blame-ignore-revs +2 -0
- package/simsimd/CODE_OF_CONDUCT.md +128 -0
- package/simsimd/CONTRIBUTING.md +84 -26
- package/simsimd/Cargo.lock +1 -1
- package/simsimd/Cargo.toml +4 -4
- package/simsimd/MANIFEST.in +3 -0
- package/simsimd/Package.swift +15 -3
- package/simsimd/README.md +534 -177
- package/simsimd/binding.gyp +6 -2
- package/simsimd/build.rs +13 -1
- package/simsimd/c/lib.c +266 -53
- package/simsimd/include/simsimd/binary.h +321 -112
- package/simsimd/include/simsimd/curved.h +803 -0
- package/simsimd/include/simsimd/dot.h +694 -521
- package/simsimd/include/simsimd/elementwise.h +1437 -0
- package/simsimd/include/simsimd/geospatial.h +9 -3
- package/simsimd/include/simsimd/mesh.h +69 -0
- package/simsimd/include/simsimd/probability.h +234 -206
- package/simsimd/include/simsimd/simsimd.h +1476 -617
- package/simsimd/include/simsimd/sparse.h +1428 -0
- package/simsimd/include/simsimd/spatial.h +1556 -742
- package/simsimd/include/simsimd/types.h +276 -132
- package/simsimd/javascript/lib.c +1 -2
- package/simsimd/javascript/simsimd.ts +4 -4
- package/simsimd/package.json +4 -4
- package/simsimd/rust/lib.rs +179 -1
- package/simsimd/scripts/bench.cxx +1070 -0
- package/simsimd/scripts/bench.ipynb +187 -0
- package/simsimd/{javascript → scripts}/bench.js +1 -1
- package/simsimd/{rust/benches/sqeuclidean.rs → scripts/bench_sqeuclidean.rs} +6 -6
- package/simsimd/scripts/bench_vectors.py +700 -0
- package/simsimd/scripts/bench_vectors_live.py +213 -0
- package/simsimd/scripts/test.c +155 -0
- package/simsimd/{javascript → scripts}/test.mjs +2 -2
- package/simsimd/scripts/test.py +1410 -0
- package/simsimd/swift/{source/SimSIMD.swift → SimSIMD.swift} +6 -2
- package/simsimd/swift/{tests/SimSIMDTests.swift → Test.swift} +1 -1
- /package/simsimd/{rust/benches/cosine.rs → scripts/bench_cosine.rs} +0 -0
- /package/simsimd/{rust/benches/native.rs → scripts/bench_native.rs} +0 -0
|
@@ -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: `
|
|
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
|
|
17
|
+
#define _SIMSIMD_DEFINED_WINDOWS 1
|
|
17
18
|
#elif defined(__APPLE__) && defined(__MACH__)
|
|
18
|
-
#define
|
|
19
|
+
#define _SIMSIMD_DEFINED_APPLE 1
|
|
19
20
|
#elif defined(__linux__)
|
|
20
|
-
#define
|
|
21
|
+
#define _SIMSIMD_DEFINED_LINUX 1
|
|
21
22
|
#endif
|
|
22
23
|
|
|
23
24
|
// Annotation for the public API symbols:
|
|
@@ -35,68 +36,118 @@
|
|
|
35
36
|
#define SIMSIMD_PUBLIC __attribute__((unused)) inline static
|
|
36
37
|
#define SIMSIMD_INTERNAL __attribute__((always_inline)) inline static
|
|
37
38
|
#else
|
|
38
|
-
#define SIMSIMD_DYNAMIC
|
|
39
|
+
#define SIMSIMD_DYNAMIC
|
|
39
40
|
#define SIMSIMD_PUBLIC inline static
|
|
40
41
|
#define SIMSIMD_INTERNAL inline static
|
|
41
42
|
#endif
|
|
42
43
|
|
|
43
|
-
// Compiling for Arm:
|
|
44
|
-
#if !defined(
|
|
44
|
+
// Compiling for Arm: _SIMSIMD_TARGET_ARM
|
|
45
|
+
#if !defined(_SIMSIMD_TARGET_ARM)
|
|
45
46
|
#if defined(__aarch64__) || defined(_M_ARM64)
|
|
46
|
-
#define
|
|
47
|
+
#define _SIMSIMD_TARGET_ARM 1
|
|
47
48
|
#else
|
|
48
|
-
#define
|
|
49
|
+
#define _SIMSIMD_TARGET_ARM 0
|
|
49
50
|
#endif // defined(__aarch64__) || defined(_M_ARM64)
|
|
50
|
-
#endif // !defined(
|
|
51
|
+
#endif // !defined(_SIMSIMD_TARGET_ARM)
|
|
51
52
|
|
|
52
|
-
// Compiling for x86:
|
|
53
|
-
#if !defined(
|
|
53
|
+
// Compiling for x86: _SIMSIMD_TARGET_X86
|
|
54
|
+
#if !defined(_SIMSIMD_TARGET_X86)
|
|
54
55
|
#if defined(__x86_64__) || defined(_M_X64)
|
|
55
|
-
#define
|
|
56
|
+
#define _SIMSIMD_TARGET_X86 1
|
|
56
57
|
#else
|
|
57
|
-
#define
|
|
58
|
+
#define _SIMSIMD_TARGET_X86 0
|
|
58
59
|
#endif // defined(__x86_64__) || defined(_M_X64)
|
|
59
|
-
#endif // !defined(
|
|
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 && !
|
|
63
|
+
#if !defined(SIMSIMD_TARGET_NEON) || (SIMSIMD_TARGET_NEON && !_SIMSIMD_TARGET_ARM)
|
|
63
64
|
#if defined(__ARM_NEON)
|
|
64
|
-
#define SIMSIMD_TARGET_NEON
|
|
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
|
-
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
#endif // !defined(
|
|
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 && !
|
|
103
|
+
#if !defined(SIMSIMD_TARGET_SVE) || (SIMSIMD_TARGET_SVE && !_SIMSIMD_TARGET_ARM)
|
|
83
104
|
#if defined(__ARM_FEATURE_SVE)
|
|
84
|
-
#define SIMSIMD_TARGET_SVE
|
|
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
|
-
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
#endif // !defined(
|
|
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) || ...
|
|
141
|
+
|
|
142
|
+
// Compiling for Arm: SIMSIMD_TARGET_SVE2
|
|
143
|
+
#if !defined(SIMSIMD_TARGET_SVE2) || (SIMSIMD_TARGET_SVE2 && !_SIMSIMD_TARGET_ARM)
|
|
144
|
+
#if defined(__ARM_FEATURE_SVE)
|
|
145
|
+
#define SIMSIMD_TARGET_SVE2 _SIMSIMD_TARGET_ARM
|
|
146
|
+
#else
|
|
147
|
+
#undef SIMSIMD_TARGET_SVE2
|
|
148
|
+
#define SIMSIMD_TARGET_SVE2 0
|
|
149
|
+
#endif // defined(__ARM_FEATURE_SVE)
|
|
150
|
+
#endif // !defined(SIMSIMD_TARGET_SVE2) || ...
|
|
100
151
|
|
|
101
152
|
// Compiling for x86: SIMSIMD_TARGET_HASWELL
|
|
102
153
|
//
|
|
@@ -105,55 +156,72 @@
|
|
|
105
156
|
// are supported on all CPUs starting with Jaguar 2009.
|
|
106
157
|
// Starting with Sandy Bridge, Intel adds basic AVX support in their CPUs and in 2013
|
|
107
158
|
// extends it with AVX2 in the Haswell generation. Moreover, Haswell adds FMA support.
|
|
108
|
-
#if !defined(SIMSIMD_TARGET_HASWELL) || (SIMSIMD_TARGET_HASWELL && !
|
|
159
|
+
#if !defined(SIMSIMD_TARGET_HASWELL) || (SIMSIMD_TARGET_HASWELL && !_SIMSIMD_TARGET_X86)
|
|
109
160
|
#if defined(__AVX2__) && defined(__FMA__) && defined(__F16C__)
|
|
110
161
|
#define SIMSIMD_TARGET_HASWELL 1
|
|
111
162
|
#else
|
|
112
163
|
#undef SIMSIMD_TARGET_HASWELL
|
|
113
164
|
#define SIMSIMD_TARGET_HASWELL 0
|
|
114
165
|
#endif // defined(__AVX2__)
|
|
115
|
-
#endif // !defined(SIMSIMD_TARGET_HASWELL)
|
|
166
|
+
#endif // !defined(SIMSIMD_TARGET_HASWELL) || ...
|
|
116
167
|
|
|
117
|
-
// Compiling for x86: SIMSIMD_TARGET_SKYLAKE, SIMSIMD_TARGET_ICE,
|
|
168
|
+
// Compiling for x86: SIMSIMD_TARGET_SKYLAKE, SIMSIMD_TARGET_ICE, SIMSIMD_TARGET_GENOA,
|
|
169
|
+
// SIMSIMD_TARGET_SAPPHIRE, SIMSIMD_TARGET_TURIN, SIMSIMD_TARGET_SIERRA
|
|
118
170
|
//
|
|
119
171
|
// To list all available macros for x86, take a recent compiler, like GCC 12 and run:
|
|
120
172
|
// gcc-12 -march=sapphirerapids -dM -E - < /dev/null | egrep "SSE|AVX" | sort
|
|
121
173
|
// On Arm machines you may want to check for other flags:
|
|
122
174
|
// gcc-12 -march=native -dM -E - < /dev/null | egrep "NEON|SVE|FP16|FMA" | sort
|
|
123
|
-
#if !defined(SIMSIMD_TARGET_SKYLAKE) || (SIMSIMD_TARGET_SKYLAKE && !
|
|
124
|
-
#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__) && \
|
|
125
177
|
defined(__AVX512BW__)
|
|
126
178
|
#define SIMSIMD_TARGET_SKYLAKE 1
|
|
127
179
|
#else
|
|
128
180
|
#undef SIMSIMD_TARGET_SKYLAKE
|
|
129
181
|
#define SIMSIMD_TARGET_SKYLAKE 0
|
|
130
182
|
#endif
|
|
131
|
-
#endif // !defined(SIMSIMD_TARGET_SKYLAKE)
|
|
132
|
-
#if !defined(SIMSIMD_TARGET_ICE) || (SIMSIMD_TARGET_ICE && !
|
|
133
|
-
#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__) && \
|
|
134
186
|
defined(__AVX512VPOPCNTDQ__)
|
|
135
187
|
#define SIMSIMD_TARGET_ICE 1
|
|
136
188
|
#else
|
|
137
189
|
#undef SIMSIMD_TARGET_ICE
|
|
138
190
|
#define SIMSIMD_TARGET_ICE 0
|
|
139
191
|
#endif
|
|
140
|
-
#endif // !defined(SIMSIMD_TARGET_ICE)
|
|
141
|
-
#if !defined(SIMSIMD_TARGET_GENOA) || (SIMSIMD_TARGET_GENOA && !
|
|
192
|
+
#endif // !defined(SIMSIMD_TARGET_ICE) || ...
|
|
193
|
+
#if !defined(SIMSIMD_TARGET_GENOA) || (SIMSIMD_TARGET_GENOA && !_SIMSIMD_TARGET_X86)
|
|
142
194
|
#if defined(__AVX512BF16__)
|
|
143
195
|
#define SIMSIMD_TARGET_GENOA 1
|
|
144
196
|
#else
|
|
145
197
|
#undef SIMSIMD_TARGET_GENOA
|
|
146
198
|
#define SIMSIMD_TARGET_GENOA 0
|
|
147
199
|
#endif
|
|
148
|
-
#endif // !defined(SIMSIMD_TARGET_GENOA)
|
|
149
|
-
#if !defined(SIMSIMD_TARGET_SAPPHIRE) || (SIMSIMD_TARGET_SAPPHIRE && !
|
|
200
|
+
#endif // !defined(SIMSIMD_TARGET_GENOA) || ...
|
|
201
|
+
#if !defined(SIMSIMD_TARGET_SAPPHIRE) || (SIMSIMD_TARGET_SAPPHIRE && !_SIMSIMD_TARGET_X86)
|
|
150
202
|
#if defined(__AVX512FP16__)
|
|
151
203
|
#define SIMSIMD_TARGET_SAPPHIRE 1
|
|
152
204
|
#else
|
|
153
205
|
#undef SIMSIMD_TARGET_SAPPHIRE
|
|
154
206
|
#define SIMSIMD_TARGET_SAPPHIRE 0
|
|
155
207
|
#endif
|
|
156
|
-
#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) || ...
|
|
157
225
|
|
|
158
226
|
#ifdef _MSC_VER
|
|
159
227
|
#include <intrin.h>
|
|
@@ -163,31 +231,37 @@
|
|
|
163
231
|
#include <arm_neon.h>
|
|
164
232
|
#endif
|
|
165
233
|
|
|
166
|
-
#if SIMSIMD_TARGET_SVE
|
|
234
|
+
#if SIMSIMD_TARGET_SVE || SIMSIMD_TARGET_SVE2
|
|
167
235
|
#include <arm_sve.h>
|
|
168
236
|
#endif
|
|
169
237
|
|
|
170
|
-
#if SIMSIMD_TARGET_HASWELL || SIMSIMD_TARGET_SKYLAKE
|
|
238
|
+
#if SIMSIMD_TARGET_HASWELL || SIMSIMD_TARGET_SKYLAKE || SIMSIMD_TARGET_ICE || SIMSIMD_TARGET_GENOA || \
|
|
239
|
+
SIMSIMD_TARGET_SAPPHIRE || SIMSIMD_TARGET_TURIN
|
|
171
240
|
#include <immintrin.h>
|
|
172
241
|
#endif
|
|
173
242
|
|
|
174
243
|
#endif
|
|
175
244
|
|
|
176
|
-
#
|
|
245
|
+
#if !defined(SIMSIMD_SQRT)
|
|
177
246
|
#include <math.h>
|
|
178
|
-
#define
|
|
247
|
+
#define SIMSIMD_SQRT(x) (sqrt(x))
|
|
179
248
|
#endif
|
|
180
249
|
|
|
181
|
-
#
|
|
250
|
+
#if !defined(SIMSIMD_RSQRT)
|
|
182
251
|
#include <math.h>
|
|
183
|
-
#define
|
|
252
|
+
#define SIMSIMD_RSQRT(x) (1 / SIMSIMD_SQRT(x))
|
|
184
253
|
#endif
|
|
185
254
|
|
|
186
|
-
#
|
|
255
|
+
#if !defined(SIMSIMD_LOG)
|
|
256
|
+
#include <math.h>
|
|
257
|
+
#define SIMSIMD_LOG(x) (log(x))
|
|
258
|
+
#endif
|
|
259
|
+
|
|
260
|
+
#if !defined(SIMSIMD_F32_DIVISION_EPSILON)
|
|
187
261
|
#define SIMSIMD_F32_DIVISION_EPSILON (1e-7)
|
|
188
262
|
#endif
|
|
189
263
|
|
|
190
|
-
#
|
|
264
|
+
#if !defined(SIMSIMD_F16_DIVISION_EPSILON)
|
|
191
265
|
#define SIMSIMD_F16_DIVISION_EPSILON (1e-3)
|
|
192
266
|
#endif
|
|
193
267
|
|
|
@@ -195,14 +269,21 @@
|
|
|
195
269
|
extern "C" {
|
|
196
270
|
#endif
|
|
197
271
|
|
|
198
|
-
typedef int simsimd_i32_t;
|
|
199
|
-
typedef float simsimd_f32_t;
|
|
200
|
-
typedef double simsimd_f64_t;
|
|
201
|
-
typedef signed char simsimd_i8_t;
|
|
202
272
|
typedef unsigned char simsimd_b8_t;
|
|
203
|
-
typedef
|
|
273
|
+
typedef unsigned char simsimd_i4x2_t;
|
|
274
|
+
|
|
275
|
+
typedef signed char simsimd_i8_t;
|
|
276
|
+
typedef unsigned char simsimd_u8_t;
|
|
277
|
+
typedef signed short simsimd_i16_t;
|
|
278
|
+
typedef unsigned short simsimd_u16_t;
|
|
279
|
+
typedef signed int simsimd_i32_t;
|
|
280
|
+
typedef unsigned int simsimd_u32_t;
|
|
281
|
+
typedef signed long long simsimd_i64_t;
|
|
204
282
|
typedef unsigned long long simsimd_u64_t;
|
|
205
283
|
|
|
284
|
+
typedef float simsimd_f32_t;
|
|
285
|
+
typedef double simsimd_f64_t;
|
|
286
|
+
|
|
206
287
|
typedef simsimd_u64_t simsimd_size_t;
|
|
207
288
|
typedef simsimd_f64_t simsimd_distance_t;
|
|
208
289
|
|
|
@@ -213,19 +294,21 @@ typedef simsimd_f64_t simsimd_distance_t;
|
|
|
213
294
|
* - Default: `unsigned short`.
|
|
214
295
|
*/
|
|
215
296
|
#if !defined(SIMSIMD_NATIVE_F16) || SIMSIMD_NATIVE_F16
|
|
216
|
-
#if (defined(__GNUC__) || defined(__clang__)) && (defined(__ARM_ARCH) || defined(__aarch64__)) &&
|
|
297
|
+
#if (defined(__GNUC__) || defined(__clang__)) && (defined(__ARM_ARCH) || defined(__aarch64__)) && \
|
|
217
298
|
(defined(__ARM_FP16_FORMAT_IEEE))
|
|
218
|
-
#
|
|
299
|
+
#undef SIMSIMD_NATIVE_F16
|
|
219
300
|
#define SIMSIMD_NATIVE_F16 1
|
|
220
|
-
#endif
|
|
221
301
|
typedef __fp16 simsimd_f16_t;
|
|
222
|
-
#elif ((defined(__GNUC__) || defined(__clang__)) && (defined(__x86_64__) || defined(__i386__)) &&
|
|
223
|
-
(defined(
|
|
302
|
+
#elif ((defined(__GNUC__) || defined(__clang__)) && (defined(__x86_64__) || defined(__i386__)) && \
|
|
303
|
+
(defined(__AVX512FP16__)))
|
|
224
304
|
typedef _Float16 simsimd_f16_t;
|
|
225
|
-
#
|
|
305
|
+
#undef SIMSIMD_NATIVE_F16
|
|
226
306
|
#define SIMSIMD_NATIVE_F16 1
|
|
307
|
+
#else // Unknown compiler or architecture
|
|
308
|
+
#if defined(__GNUC__) || defined(__clang__) // Some compilers don't support warning pragmas
|
|
309
|
+
#warning "Unknown compiler or architecture for float16."
|
|
227
310
|
#endif
|
|
228
|
-
#
|
|
311
|
+
#undef SIMSIMD_NATIVE_F16
|
|
229
312
|
#define SIMSIMD_NATIVE_F16 0
|
|
230
313
|
#endif // Unknown compiler or architecture
|
|
231
314
|
#endif // !SIMSIMD_NATIVE_F16
|
|
@@ -242,23 +325,38 @@ typedef unsigned short simsimd_f16_t;
|
|
|
242
325
|
* - GCC or Clang on 64-bit x86: `_BFloat16`.
|
|
243
326
|
* - Default: `unsigned short`.
|
|
244
327
|
*
|
|
328
|
+
* The compilers have added `__bf16` support in compliance with the x86-64 psABI spec.
|
|
329
|
+
* The motivation for this new special type is summed up as:
|
|
330
|
+
*
|
|
331
|
+
* Currently `__bfloat16` is a typedef of short, which creates a problem where the
|
|
332
|
+
* compiler does not raise any alarms if it is used to add, subtract, multiply or
|
|
333
|
+
* divide, but the result of the calculation is actually meaningless.
|
|
334
|
+
* To solve this problem, a real scalar type `__Bfloat16` needs to be introduced.
|
|
335
|
+
* It is mainly used for intrinsics, not available for C standard operators.
|
|
336
|
+
* `__Bfloat16` will also be used for movement like passing parameter, load and store,
|
|
337
|
+
* vector initialization, vector shuffle, and etc. It creates a need for a
|
|
338
|
+
* corresponding psABI.
|
|
339
|
+
*
|
|
245
340
|
* @warning Apple Clang has hard time with bf16.
|
|
246
341
|
* https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms
|
|
247
342
|
* https://forums.developer.apple.com/forums/thread/726201
|
|
343
|
+
* https://www.phoronix.com/news/GCC-LLVM-bf16-BFloat16-Type
|
|
248
344
|
*/
|
|
249
|
-
#if (defined(__GNUC__) || defined(__clang__)) && (defined(__ARM_ARCH) || defined(__aarch64__)) &&
|
|
345
|
+
#if (defined(__GNUC__) || defined(__clang__)) && (defined(__ARM_ARCH) || defined(__aarch64__)) && \
|
|
250
346
|
(defined(__ARM_BF16_FORMAT_ALTERNATIVE))
|
|
251
|
-
#
|
|
347
|
+
#undef SIMSIMD_NATIVE_BF16
|
|
252
348
|
#define SIMSIMD_NATIVE_BF16 1
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
#if !defined(SIMSIMD_NATIVE_BF16)
|
|
349
|
+
typedef __bf16 simsimd_bf16_t;
|
|
350
|
+
#elif ((defined(__GNUC__) || defined(__clang__)) && (defined(__x86_64__) || defined(__i386__)) && \
|
|
351
|
+
(defined(__AVX512BF16__)))
|
|
352
|
+
typedef __bfloat16 simsimd_bf16_t;
|
|
353
|
+
#undef SIMSIMD_NATIVE_BF16
|
|
259
354
|
#define SIMSIMD_NATIVE_BF16 1
|
|
355
|
+
#else // Unknown compiler or architecture
|
|
356
|
+
#if defined(__GNUC__) || defined(__clang__) // Some compilers don't support warning pragmas
|
|
357
|
+
#warning "Unknown compiler or architecture for bfloat16."
|
|
260
358
|
#endif
|
|
261
|
-
#
|
|
359
|
+
#undef SIMSIMD_NATIVE_BF16
|
|
262
360
|
#define SIMSIMD_NATIVE_BF16 0
|
|
263
361
|
#endif // Unknown compiler or architecture
|
|
264
362
|
#endif // !SIMSIMD_NATIVE_BF16
|
|
@@ -276,7 +374,7 @@ typedef unsigned short simsimd_bf16_t;
|
|
|
276
374
|
* Some of those are defined as aliases, so we use `#define` preprocessor
|
|
277
375
|
* directives instead of `typedef` to avoid errors.
|
|
278
376
|
*/
|
|
279
|
-
#if
|
|
377
|
+
#if _SIMSIMD_TARGET_ARM
|
|
280
378
|
#if defined(_MSC_VER)
|
|
281
379
|
#define simsimd_f16_for_arm_simd_t simsimd_f16_t
|
|
282
380
|
#define simsimd_bf16_for_arm_simd_t simsimd_bf16_t
|
|
@@ -286,17 +384,40 @@ typedef unsigned short simsimd_bf16_t;
|
|
|
286
384
|
#endif
|
|
287
385
|
#endif
|
|
288
386
|
|
|
289
|
-
|
|
387
|
+
/*
|
|
388
|
+
* Let's make sure the sizes of the types are as expected.
|
|
389
|
+
* In C the `_Static_assert` is only available with C 11 and later.
|
|
390
|
+
*/
|
|
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);
|
|
394
|
+
SIMSIMD_STATIC_ASSERT(sizeof(simsimd_i8_t) == 1, simsimd_i8_t_must_be_1_byte);
|
|
395
|
+
SIMSIMD_STATIC_ASSERT(sizeof(simsimd_u8_t) == 1, simsimd_u8_t_must_be_1_byte);
|
|
396
|
+
SIMSIMD_STATIC_ASSERT(sizeof(simsimd_i16_t) == 2, simsimd_i16_t_must_be_2_bytes);
|
|
397
|
+
SIMSIMD_STATIC_ASSERT(sizeof(simsimd_u16_t) == 2, simsimd_u16_t_must_be_2_bytes);
|
|
398
|
+
SIMSIMD_STATIC_ASSERT(sizeof(simsimd_i32_t) == 4, simsimd_i32_t_must_be_4_bytes);
|
|
399
|
+
SIMSIMD_STATIC_ASSERT(sizeof(simsimd_u32_t) == 4, simsimd_u32_t_must_be_4_bytes);
|
|
400
|
+
SIMSIMD_STATIC_ASSERT(sizeof(simsimd_i64_t) == 8, simsimd_i64_t_must_be_8_bytes);
|
|
401
|
+
SIMSIMD_STATIC_ASSERT(sizeof(simsimd_u64_t) == 8, simsimd_u64_t_must_be_8_bytes);
|
|
402
|
+
SIMSIMD_STATIC_ASSERT(sizeof(simsimd_f32_t) == 4, simsimd_f32_t_must_be_4_bytes);
|
|
403
|
+
SIMSIMD_STATIC_ASSERT(sizeof(simsimd_f64_t) == 8, simsimd_f64_t_must_be_8_bytes);
|
|
404
|
+
SIMSIMD_STATIC_ASSERT(sizeof(simsimd_f16_t) == 2, simsimd_f16_t_must_be_2_bytes);
|
|
405
|
+
SIMSIMD_STATIC_ASSERT(sizeof(simsimd_bf16_t) == 2, simsimd_bf16_t_must_be_2_bytes);
|
|
406
|
+
|
|
407
|
+
#define SIMSIMD_DEREFERENCE(x) (*(x))
|
|
408
|
+
#define SIMSIMD_EXPORT(x, y) *(y) = x
|
|
290
409
|
|
|
291
410
|
/**
|
|
292
411
|
* @brief Returns the value of the half-precision floating-point number,
|
|
293
412
|
* potentially decompressed into single-precision.
|
|
294
413
|
*/
|
|
295
|
-
#
|
|
414
|
+
#if !defined(SIMSIMD_F16_TO_F32)
|
|
296
415
|
#if SIMSIMD_NATIVE_F16
|
|
297
|
-
#define
|
|
416
|
+
#define SIMSIMD_F16_TO_F32(x) (SIMSIMD_DEREFERENCE(x))
|
|
417
|
+
#define SIMSIMD_F32_TO_F16(x, y) (SIMSIMD_EXPORT(x, y))
|
|
298
418
|
#else
|
|
299
|
-
#define
|
|
419
|
+
#define SIMSIMD_F16_TO_F32(x) (simsimd_f16_to_f32(x))
|
|
420
|
+
#define SIMSIMD_F32_TO_F16(x, y) (simsimd_f32_to_f16(x, y))
|
|
300
421
|
#endif
|
|
301
422
|
#endif
|
|
302
423
|
|
|
@@ -304,22 +425,47 @@ typedef unsigned short simsimd_bf16_t;
|
|
|
304
425
|
* @brief Returns the value of the half-precision brain floating-point number,
|
|
305
426
|
* potentially decompressed into single-precision.
|
|
306
427
|
*/
|
|
307
|
-
#
|
|
428
|
+
#if !defined(SIMSIMD_BF16_TO_F32)
|
|
308
429
|
#if SIMSIMD_NATIVE_BF16
|
|
309
|
-
#define
|
|
430
|
+
#define SIMSIMD_BF16_TO_F32(x) (SIMSIMD_DEREFERENCE(x))
|
|
431
|
+
#define SIMSIMD_F32_TO_BF16(x, y) (SIMSIMD_EXPORT(x, y))
|
|
310
432
|
#else
|
|
311
|
-
#define
|
|
433
|
+
#define SIMSIMD_BF16_TO_F32(x) (simsimd_bf16_to_f32(x))
|
|
434
|
+
#define SIMSIMD_F32_TO_BF16(x, y) (simsimd_f32_to_bf16(x, y))
|
|
435
|
+
#endif
|
|
312
436
|
#endif
|
|
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)
|
|
313
449
|
#endif
|
|
314
450
|
|
|
451
|
+
/** @brief Convenience type for half-precision floating-point type conversions. */
|
|
315
452
|
typedef union {
|
|
316
453
|
unsigned i;
|
|
317
454
|
float f;
|
|
318
455
|
} simsimd_f32i32_t;
|
|
319
456
|
|
|
320
457
|
/**
|
|
321
|
-
* @brief Computes `1/sqrt(x)` using the trick from Quake 3,
|
|
322
|
-
* magic numbers with the ones suggested by Jan Kadlec.
|
|
458
|
+
* @brief Computes `1/sqrt(x)` using the trick from Quake 3,
|
|
459
|
+
* replacing the magic numbers with the ones suggested by Jan Kadlec.
|
|
460
|
+
*
|
|
461
|
+
* Subsequent additions by hardware manufacturers have made this algorithm redundant for the most part.
|
|
462
|
+
* For example, on x86, Intel introduced the SSE instruction `rsqrtss` in 1999. In a 2009 benchmark on
|
|
463
|
+
* the Intel Core 2, this instruction took 0.85ns per float compared to 3.54ns for the fast inverse
|
|
464
|
+
* square root algorithm, and had less error. Carmack's Magic Number `rsqrt` had an average error
|
|
465
|
+
* of 0.0990%, while SSE `rsqrtss` had 0.0094%, a 10x improvement.
|
|
466
|
+
*
|
|
467
|
+
* https://web.archive.org/web/20210208132927/http://assemblyrequired.crashworks.org/timing-square-root/
|
|
468
|
+
* https://stackoverflow.com/a/41460625/2766161
|
|
323
469
|
*/
|
|
324
470
|
SIMSIMD_PUBLIC simsimd_f32_t simsimd_approximate_inverse_square_root(simsimd_f32_t number) {
|
|
325
471
|
simsimd_f32i32_t conv;
|
|
@@ -351,20 +497,17 @@ SIMSIMD_PUBLIC simsimd_f32_t simsimd_approximate_log(simsimd_f32_t number) {
|
|
|
351
497
|
* https://gist.github.com/milhidaka/95863906fe828198f47991c813dbe233
|
|
352
498
|
* https://github.com/OpenCyphal/libcanard/blob/636795f4bc395f56af8d2c61d3757b5e762bb9e5/canard.c#L811-L834
|
|
353
499
|
*/
|
|
354
|
-
SIMSIMD_PUBLIC simsimd_f32_t
|
|
355
|
-
|
|
356
|
-
float f;
|
|
357
|
-
unsigned int i;
|
|
358
|
-
};
|
|
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;
|
|
359
502
|
unsigned int exponent = (x & 0x7C00) >> 10;
|
|
360
503
|
unsigned int mantissa = (x & 0x03FF) << 13;
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
unsigned int v = (
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
return
|
|
504
|
+
simsimd_f32i32_t mantissa_conv;
|
|
505
|
+
mantissa_conv.f = (float)mantissa;
|
|
506
|
+
unsigned int v = (mantissa_conv.i) >> 23;
|
|
507
|
+
simsimd_f32i32_t conv;
|
|
508
|
+
conv.i = (x & 0x8000) << 16 | (exponent != 0) * ((exponent + 112) << 23 | mantissa) |
|
|
509
|
+
((exponent == 0) & (mantissa != 0)) * ((v - 37) << 23 | ((mantissa << (150 - v)) & 0x007FE000));
|
|
510
|
+
return conv.f;
|
|
368
511
|
}
|
|
369
512
|
|
|
370
513
|
/**
|
|
@@ -376,20 +519,16 @@ SIMSIMD_PUBLIC simsimd_f32_t simsimd_uncompress_f16(unsigned short x) {
|
|
|
376
519
|
* https://gist.github.com/milhidaka/95863906fe828198f47991c813dbe233
|
|
377
520
|
* https://github.com/OpenCyphal/libcanard/blob/636795f4bc395f56af8d2c61d3757b5e762bb9e5/canard.c#L811-L834
|
|
378
521
|
*/
|
|
379
|
-
SIMSIMD_PUBLIC
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
} x_union;
|
|
384
|
-
x_union.f = x;
|
|
385
|
-
|
|
386
|
-
unsigned int b = x_union.i + 0x00001000;
|
|
522
|
+
SIMSIMD_PUBLIC void simsimd_f32_to_f16(simsimd_f32_t x, simsimd_f16_t *result_ptr) {
|
|
523
|
+
simsimd_f32i32_t conv;
|
|
524
|
+
conv.f = x;
|
|
525
|
+
unsigned int b = conv.i + 0x00001000;
|
|
387
526
|
unsigned int e = (b & 0x7F800000) >> 23;
|
|
388
527
|
unsigned int m = b & 0x007FFFFF;
|
|
389
528
|
unsigned short result = ((b & 0x80000000) >> 16) | (e > 112) * ((((e - 112) << 10) & 0x7C00) | (m >> 13)) |
|
|
390
529
|
((e < 113) & (e > 101)) * ((((0x007FF000 + m) >> (125 - e)) + 1) >> 1) |
|
|
391
530
|
((e > 143) * 0x7FFF);
|
|
392
|
-
|
|
531
|
+
*(unsigned short *)result_ptr = result;
|
|
393
532
|
}
|
|
394
533
|
|
|
395
534
|
/**
|
|
@@ -399,31 +538,36 @@ SIMSIMD_PUBLIC unsigned short simsimd_compress_f16(simsimd_f32_t x) {
|
|
|
399
538
|
* https://stackoverflow.com/questions/55253233/convert-fp32-to-bfloat16-in-c/55254307#55254307
|
|
400
539
|
* https://cloud.google.com/blog/products/ai-machine-learning/bfloat16-the-secret-to-high-performance-on-cloud-tpus
|
|
401
540
|
*/
|
|
402
|
-
SIMSIMD_PUBLIC simsimd_f32_t
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
union float_or_unsigned_int_t result_union;
|
|
408
|
-
result_union.i = x << 16; // Zero extends the mantissa
|
|
409
|
-
return result_union.f;
|
|
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;
|
|
543
|
+
simsimd_f32i32_t conv;
|
|
544
|
+
conv.i = x << 16; // Zero extends the mantissa
|
|
545
|
+
return conv.f;
|
|
410
546
|
}
|
|
411
547
|
|
|
412
548
|
/**
|
|
413
549
|
* @brief Compresses a `float` to a `bf16` representation.
|
|
550
|
+
*
|
|
551
|
+
* https://stackoverflow.com/questions/55253233/convert-fp32-to-bfloat16-in-c/55254307#55254307
|
|
552
|
+
* https://cloud.google.com/blog/products/ai-machine-learning/bfloat16-the-secret-to-high-performance-on-cloud-tpus
|
|
414
553
|
*/
|
|
415
|
-
SIMSIMD_PUBLIC
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
value.i &= 0xFFFF;
|
|
424
|
-
return (unsigned short)value.i;
|
|
554
|
+
SIMSIMD_PUBLIC void simsimd_f32_to_bf16(simsimd_f32_t x, simsimd_bf16_t *result_ptr) {
|
|
555
|
+
simsimd_f32i32_t conv;
|
|
556
|
+
conv.f = x;
|
|
557
|
+
conv.i += 0x8000; // Rounding is optional
|
|
558
|
+
conv.i >>= 16;
|
|
559
|
+
// The top 16 bits will be zeroed out anyways
|
|
560
|
+
// conv.i &= 0xFFFF;
|
|
561
|
+
*(unsigned short *)result_ptr = (unsigned short)conv.i;
|
|
425
562
|
}
|
|
426
563
|
|
|
564
|
+
SIMSIMD_PUBLIC simsimd_u32_t simsimd_u32_rol(simsimd_u32_t x, int n) { return (x << n) | (x >> (32 - n)); }
|
|
565
|
+
SIMSIMD_PUBLIC simsimd_u16_t simsimd_u16_rol(simsimd_u16_t x, int n) { return (x << n) | (x >> (16 - n)); }
|
|
566
|
+
SIMSIMD_PUBLIC simsimd_u8_t simsimd_u8_rol(simsimd_u8_t x, int n) { return (x << n) | (x >> (8 - n)); }
|
|
567
|
+
SIMSIMD_PUBLIC simsimd_u32_t simsimd_u32_ror(simsimd_u32_t x, int n) { return (x >> n) | (x << (32 - n)); }
|
|
568
|
+
SIMSIMD_PUBLIC simsimd_u16_t simsimd_u16_ror(simsimd_u16_t x, int n) { return (x >> n) | (x << (16 - n)); }
|
|
569
|
+
SIMSIMD_PUBLIC simsimd_u8_t simsimd_u8_ror(simsimd_u8_t x, int n) { return (x >> n) | (x << (8 - n)); }
|
|
570
|
+
|
|
427
571
|
#ifdef __cplusplus
|
|
428
572
|
} // extern "C"
|
|
429
573
|
#endif
|
package/simsimd/javascript/lib.c
CHANGED
|
@@ -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
|
}
|
|
@@ -83,20 +83,20 @@ export const jaccard = (a: Uint8Array, b: Uint8Array): number => {
|
|
|
83
83
|
};
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
|
-
* @brief Computes the
|
|
86
|
+
* @brief Computes the Kullback-Leibler divergence between two vectors.
|
|
87
87
|
* @param {Float64Array|Float32Array} a - The first vector.
|
|
88
88
|
* @param {Float64Array|Float32Array} b - The second vector.
|
|
89
|
-
* @returns {number} The
|
|
89
|
+
* @returns {number} The Kullback-Leibler divergence between vectors a and b.
|
|
90
90
|
*/
|
|
91
91
|
export const kullbackleibler = (a: Float64Array | Float32Array, b: Float64Array | Float32Array): number => {
|
|
92
92
|
return compiled.kullbackleibler(a, b);
|
|
93
93
|
};
|
|
94
94
|
|
|
95
95
|
/**
|
|
96
|
-
* @brief Computes the
|
|
96
|
+
* @brief Computes the Jensen-Shannon divergence between two vectors.
|
|
97
97
|
* @param {Float64Array|Float32Array} a - The first vector.
|
|
98
98
|
* @param {Float64Array|Float32Array} b - The second vector.
|
|
99
|
-
* @returns {number} The
|
|
99
|
+
* @returns {number} The Jensen-Shannon divergence between vectors a and b.
|
|
100
100
|
*/
|
|
101
101
|
export const jensenshannon = (a: Float64Array | Float32Array, b: Float64Array | Float32Array): number => {
|
|
102
102
|
return compiled.jensenshannon(a, b);
|