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