usearch 2.10.3 → 2.10.5
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 +101 -0
- package/c/CMakeLists.txt +27 -0
- package/c/README.md +34 -0
- package/c/lib.cpp +362 -0
- package/c/test.c +382 -0
- package/c/usearch.h +356 -0
- package/cmake/clipp.cmake +7 -0
- package/cmake/config.cmake.in +15 -0
- package/cmake/emscripten.cmake +8 -0
- package/cmake/jemalloc.cmake +62 -0
- package/cmake/pkg-config.pc.in +4 -0
- package/cmake/usearchConfigVersion.cmake.in +20 -0
- package/cpp/CMakeLists.txt +14 -0
- package/cpp/README.md +161 -0
- package/cpp/bench.cpp +616 -0
- package/cpp/test.cpp +324 -0
- package/fp16/CMakeLists.txt +176 -0
- package/fp16/LICENSE +11 -0
- package/fp16/README.md +20 -0
- package/fp16/bench/alt-element.cc +89 -0
- package/fp16/bench/from-alt-array.cc +175 -0
- package/fp16/bench/from-ieee-array.cc +399 -0
- package/fp16/bench/ieee-element.cc +272 -0
- package/fp16/bench/to-alt-array.cc +91 -0
- package/fp16/bench/to-ieee-array.cc +303 -0
- package/fp16/cmake/DownloadGoogleBenchmark.cmake +15 -0
- package/fp16/cmake/DownloadGoogleTest.cmake +15 -0
- package/fp16/cmake/DownloadPSimd.cmake +15 -0
- package/fp16/configure.py +65 -0
- package/fp16/confu.yaml +8 -0
- package/fp16/include/fp16/__init__.py +0 -0
- package/fp16/include/fp16/avx.py +50 -0
- package/fp16/include/fp16/avx2.py +53 -0
- package/fp16/include/fp16/bitcasts.h +92 -0
- package/fp16/include/fp16/fp16.h +451 -0
- package/fp16/include/fp16/psimd.h +131 -0
- package/fp16/include/fp16.h +11 -0
- package/fp16/jni/Android.mk +6 -0
- package/fp16/jni/Application.mk +4 -0
- package/fp16/test/alt-from-fp32-value.cc +498 -0
- package/fp16/test/alt-to-fp32-bits.cc +263 -0
- package/fp16/test/alt-to-fp32-psimd.cc +145 -0
- package/fp16/test/alt-to-fp32-value.cc +348 -0
- package/fp16/test/alt-to-fp32x2-psimd.cc +245 -0
- package/fp16/test/bitcasts.cc +56 -0
- package/fp16/test/ieee-from-fp32-value.cc +523 -0
- package/fp16/test/ieee-to-fp32-bits.cc +333 -0
- package/fp16/test/ieee-to-fp32-psimd.cc +312 -0
- package/fp16/test/ieee-to-fp32-value.cc +420 -0
- package/fp16/test/ieee-to-fp32x2-psimd.cc +541 -0
- package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +96 -0
- package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +96 -0
- package/fp16/test/peachpy/stubs.py +38 -0
- package/fp16/test/tables.cc +530 -0
- package/fp16/test/tables.h +13 -0
- package/fp16/third-party/THHalf.h +92 -0
- package/fp16/third-party/eigen-half.h +170 -0
- package/fp16/third-party/float16-compressor.h +80 -0
- package/fp16/third-party/half.hpp +2916 -0
- package/fp16/third-party/npy-halffloat.h +328 -0
- package/include/usearch/index.hpp +3838 -0
- package/include/usearch/index_dense.hpp +2004 -0
- package/include/usearch/index_plugins.hpp +2255 -0
- package/javascript/dist-package-cjs.json +3 -0
- package/javascript/dist-package-esm.json +3 -0
- package/javascript/lib.cpp +350 -0
- package/javascript/node-gyp-build.d.ts +1 -0
- package/javascript/tsconfig-base.json +25 -0
- package/javascript/tsconfig-cjs.json +8 -0
- package/javascript/tsconfig-esm.json +8 -0
- package/javascript/usearch.test.js +84 -0
- package/javascript/usearch.ts +640 -0
- package/package.json +10 -3
- 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/simsimd/.releaserc +87 -0
- package/simsimd/CONTRIBUTING.md +114 -0
- package/simsimd/Cargo.lock +709 -0
- package/simsimd/Cargo.toml +44 -0
- package/simsimd/LICENSE +201 -0
- package/simsimd/README.md +708 -0
- package/simsimd/binding.gyp +36 -0
- package/simsimd/build.rs +51 -0
- package/simsimd/c/lib.c +110 -0
- package/simsimd/include/simsimd/binary.h +258 -0
- package/simsimd/include/simsimd/dot.h +1237 -0
- package/simsimd/include/simsimd/geospatial.h +37 -0
- package/simsimd/include/simsimd/probability.h +563 -0
- package/simsimd/include/simsimd/simsimd.h +1129 -0
- package/simsimd/include/simsimd/spatial.h +1019 -0
- package/simsimd/include/simsimd/types.h +309 -0
- package/simsimd/javascript/bench.js +127 -0
- package/simsimd/javascript/dist-package-cjs.json +3 -0
- package/simsimd/javascript/dist-package-esm.json +3 -0
- package/simsimd/javascript/fallback.ts +203 -0
- package/simsimd/javascript/lib.c +107 -0
- package/simsimd/javascript/node-gyp-build.d.ts +1 -0
- package/simsimd/javascript/simsimd.ts +135 -0
- package/simsimd/javascript/test.mjs +179 -0
- package/simsimd/javascript/tsconfig-base.json +37 -0
- package/simsimd/javascript/tsconfig-cjs.json +8 -0
- package/simsimd/javascript/tsconfig-esm.json +8 -0
- package/simsimd/package-lock.json +1709 -0
- package/simsimd/package.json +61 -0
- package/simsimd/rust/benches/cosine.rs +27 -0
- package/simsimd/rust/benches/native.rs +30 -0
- package/simsimd/rust/benches/sqeuclidean.rs +27 -0
- package/simsimd/rust/lib.rs +778 -0
package/c/test.c
ADDED
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
#include <errno.h>
|
|
2
|
+
#include <stdio.h> // `remove`
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
#include <sys/stat.h>
|
|
5
|
+
|
|
6
|
+
#include "usearch.h"
|
|
7
|
+
|
|
8
|
+
#define ASSERT(must_be_true, message) \
|
|
9
|
+
if (!(must_be_true)) { \
|
|
10
|
+
printf("Assert: %s\n", message); \
|
|
11
|
+
exit(-1); \
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @brief Creates and initializes vectors with random float values.
|
|
16
|
+
*
|
|
17
|
+
* @param count The number of vectors.
|
|
18
|
+
* @param dimensions The number of dimensions per vector.
|
|
19
|
+
* @return A pointer to the first element of the vectors, that must be @b free-ed afterwards.
|
|
20
|
+
*/
|
|
21
|
+
float* create_vectors(size_t const count, size_t const dimensions) {
|
|
22
|
+
float* data = (float*)malloc(count * dimensions * sizeof(float));
|
|
23
|
+
ASSERT(data, "Failed to allocate memory");
|
|
24
|
+
for (size_t index = 0; index < count * dimensions; ++index)
|
|
25
|
+
data[index] = (float)rand() / (float)RAND_MAX;
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
usearch_init_options_t create_options(size_t const dimensions) {
|
|
30
|
+
usearch_init_options_t opts;
|
|
31
|
+
opts.connectivity = 3; // 32 in faiss
|
|
32
|
+
opts.dimensions = dimensions;
|
|
33
|
+
opts.expansion_add = 40; // 40 in faiss
|
|
34
|
+
opts.expansion_search = 16; // 10 in faiss
|
|
35
|
+
opts.metric_kind = usearch_metric_ip_k;
|
|
36
|
+
opts.metric = NULL;
|
|
37
|
+
opts.quantization = usearch_scalar_f32_k;
|
|
38
|
+
opts.multi = false;
|
|
39
|
+
return opts;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* This test is designed to verify the initialization of the index with specific dimensions and ensures that the
|
|
44
|
+
* associated properties are set correctly. It initializes the index twice, checking for errors at each step, and
|
|
45
|
+
* performs a reserve operation to pre-allocate space in the index, verifying the correct settings of size, capacity,
|
|
46
|
+
* dimensions, and connectivity after each operation.
|
|
47
|
+
*/
|
|
48
|
+
void test_init(size_t const collection_size, size_t const dimensions) {
|
|
49
|
+
printf("Test: Index Initialization... %zu vectors, %zu dimensions \n", collection_size, dimensions);
|
|
50
|
+
|
|
51
|
+
// Init index
|
|
52
|
+
usearch_error_t error = NULL;
|
|
53
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
54
|
+
usearch_index_t index = usearch_init(&opts, &error);
|
|
55
|
+
ASSERT(!error, error);
|
|
56
|
+
usearch_free(index, &error);
|
|
57
|
+
ASSERT(!error, error);
|
|
58
|
+
|
|
59
|
+
// Init second time
|
|
60
|
+
index = usearch_init(&opts, &error);
|
|
61
|
+
ASSERT(!error, error);
|
|
62
|
+
|
|
63
|
+
ASSERT(usearch_size(index, &error) == 0, error);
|
|
64
|
+
ASSERT(usearch_capacity(index, &error) == 0, error);
|
|
65
|
+
ASSERT(usearch_dimensions(index, &error) == dimensions, error);
|
|
66
|
+
ASSERT(usearch_connectivity(index, &error) == opts.connectivity, error);
|
|
67
|
+
|
|
68
|
+
// Reserve
|
|
69
|
+
usearch_reserve(index, collection_size, &error);
|
|
70
|
+
ASSERT(!error, error);
|
|
71
|
+
ASSERT(usearch_size(index, &error) == 0, error);
|
|
72
|
+
ASSERT(usearch_capacity(index, &error) == collection_size, error);
|
|
73
|
+
ASSERT(usearch_dimensions(index, &error) == dimensions, error);
|
|
74
|
+
ASSERT(usearch_connectivity(index, &error) == opts.connectivity, error);
|
|
75
|
+
|
|
76
|
+
usearch_free(index, &error);
|
|
77
|
+
ASSERT(!error, error);
|
|
78
|
+
|
|
79
|
+
printf("Test: Index Initialization - PASSED\n");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* This test validates the addition of vectors to the index. It initializes the index and reserves space for vectors.
|
|
84
|
+
* It then iteratively adds vectors to the index and checks if the index contains the added vectors by verifying the
|
|
85
|
+
* size, capacity, and presence of each vector in the index.
|
|
86
|
+
*/
|
|
87
|
+
void test_add_vector(size_t const collection_size, size_t const dimensions) {
|
|
88
|
+
printf("Test: Add Vector... %zu vectors, %zu dimensions \n", collection_size, dimensions);
|
|
89
|
+
|
|
90
|
+
usearch_error_t error = NULL;
|
|
91
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
92
|
+
usearch_index_t index = usearch_init(&opts, &error);
|
|
93
|
+
usearch_reserve(index, collection_size, &error);
|
|
94
|
+
|
|
95
|
+
// Add vectors
|
|
96
|
+
float* data = create_vectors(collection_size, dimensions);
|
|
97
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
98
|
+
usearch_key_t key = i;
|
|
99
|
+
usearch_add(index, key, data + i * dimensions, usearch_scalar_f32_k, &error);
|
|
100
|
+
ASSERT(!error, error);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
ASSERT(usearch_size(index, &error) == collection_size, error);
|
|
104
|
+
ASSERT(usearch_capacity(index, &error) == collection_size, error);
|
|
105
|
+
|
|
106
|
+
// Check vectors in the index
|
|
107
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
108
|
+
usearch_key_t key = i;
|
|
109
|
+
ASSERT(usearch_contains(index, key, &error), error);
|
|
110
|
+
}
|
|
111
|
+
ASSERT(!usearch_contains(index, -1, &error), error); // Non existing key
|
|
112
|
+
|
|
113
|
+
free(data);
|
|
114
|
+
usearch_free(index, &error);
|
|
115
|
+
printf("Test: Add Vector - PASSED\n");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* This test ensures that vectors added to the index can be correctly found. It initializes the index, reserves space,
|
|
120
|
+
* and adds vectors. It then performs a search query for each added vector to ensure that the vectors are correctly
|
|
121
|
+
* found in the index, validating the count of found vectors.
|
|
122
|
+
*/
|
|
123
|
+
void test_find_vector(size_t const collection_size, size_t const dimensions) {
|
|
124
|
+
printf("Test: Find Vector... %zu vectors, %zu dimensions \n", collection_size, dimensions);
|
|
125
|
+
|
|
126
|
+
usearch_error_t error = NULL;
|
|
127
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
128
|
+
usearch_index_t index = usearch_init(&opts, &error);
|
|
129
|
+
usearch_reserve(index, collection_size, &error);
|
|
130
|
+
|
|
131
|
+
// Create result buffers
|
|
132
|
+
usearch_key_t* keys = (usearch_key_t*)malloc(collection_size * sizeof(usearch_key_t));
|
|
133
|
+
float* distances = (float*)malloc(collection_size * sizeof(float));
|
|
134
|
+
ASSERT(keys && distances, "Failed to allocate memory");
|
|
135
|
+
|
|
136
|
+
// Add vectors
|
|
137
|
+
float* data = create_vectors(collection_size, dimensions);
|
|
138
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
139
|
+
usearch_key_t key = i;
|
|
140
|
+
usearch_add(index, key, data + i * dimensions, usearch_scalar_f32_k, &error);
|
|
141
|
+
ASSERT(!error, error);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Find the vectors
|
|
145
|
+
for (size_t i = 0; i < collection_size; i++) {
|
|
146
|
+
size_t found_count = usearch_search(index, data + i * dimensions, usearch_scalar_f32_k, collection_size, keys,
|
|
147
|
+
distances, &error);
|
|
148
|
+
ASSERT(!error, error);
|
|
149
|
+
ASSERT(found_count >= 1 && found_count <= collection_size, "Vector is missing");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
free(data);
|
|
153
|
+
free(keys);
|
|
154
|
+
free(distances);
|
|
155
|
+
usearch_free(index, &error);
|
|
156
|
+
printf("Test: Find Vector - PASSED\n");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* This test checks the ability of the index to handle multiple vectors associated with the same key. It initializes
|
|
161
|
+
* the index with the multi-option enabled, reserves space, and adds multiple vectors with the same key. The test then
|
|
162
|
+
* retrieves vectors associated with the key from the index and checks the count of retrieved vectors.
|
|
163
|
+
*/
|
|
164
|
+
void test_get_vector(size_t const collection_size, size_t const dimensions) {
|
|
165
|
+
printf("Test: Get Vector... %zu vectors, %zu dimensions \n", collection_size, dimensions);
|
|
166
|
+
|
|
167
|
+
usearch_error_t error = NULL;
|
|
168
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
169
|
+
opts.multi = true;
|
|
170
|
+
usearch_index_t index = usearch_init(&opts, &error);
|
|
171
|
+
usearch_reserve(index, collection_size, &error);
|
|
172
|
+
|
|
173
|
+
// Create result buffers
|
|
174
|
+
float* vectors = (float*)malloc(collection_size * dimensions * sizeof(float));
|
|
175
|
+
ASSERT(vectors, "Failed to allocate memory");
|
|
176
|
+
|
|
177
|
+
// Add multiple vectors with SAME key
|
|
178
|
+
usearch_key_t const key = 1;
|
|
179
|
+
float* data = create_vectors(collection_size, dimensions);
|
|
180
|
+
for (size_t i = 0; i < collection_size; i++) {
|
|
181
|
+
usearch_add(index, key, data + i * dimensions, usearch_scalar_f32_k, &error);
|
|
182
|
+
ASSERT(!error, error);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Retrieve vectors from index
|
|
186
|
+
size_t found_count = usearch_get(index, key, collection_size, vectors, usearch_scalar_f32_k, &error);
|
|
187
|
+
ASSERT(found_count == collection_size, "Vector is missing");
|
|
188
|
+
|
|
189
|
+
free(vectors);
|
|
190
|
+
free(data);
|
|
191
|
+
usearch_free(index, &error);
|
|
192
|
+
|
|
193
|
+
printf("Test: Get Vector - PASSED\n");
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* This test ensures that vectors can be successfully removed from the index. It initializes the index, reserves space,
|
|
198
|
+
* and adds vectors. It then iteratively removes each vector from the index and checks for errors. However, note that
|
|
199
|
+
* the assert in this test expects an error, indicating that the remove functionality is not currently supported.
|
|
200
|
+
*/
|
|
201
|
+
void test_remove_vector(size_t const collection_size, size_t const dimensions) {
|
|
202
|
+
printf("Test: Remove Vector... %zu vectors, %zu dimensions \n", collection_size, dimensions);
|
|
203
|
+
|
|
204
|
+
usearch_error_t error = NULL;
|
|
205
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
206
|
+
usearch_index_t index = usearch_init(&opts, &error);
|
|
207
|
+
usearch_reserve(index, collection_size, &error);
|
|
208
|
+
|
|
209
|
+
// Add vectors
|
|
210
|
+
float* data = create_vectors(collection_size, dimensions);
|
|
211
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
212
|
+
usearch_key_t key = i;
|
|
213
|
+
usearch_add(index, key, data + i * dimensions, usearch_scalar_f32_k, &error);
|
|
214
|
+
ASSERT(!error, error);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Remove the vectors
|
|
218
|
+
for (size_t i = 0; i < collection_size; i++) {
|
|
219
|
+
usearch_key_t key = i;
|
|
220
|
+
usearch_remove(index, key, &error);
|
|
221
|
+
ASSERT(!error, "Currently, Remove is not supported");
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
free(data);
|
|
225
|
+
usearch_free(index, &error);
|
|
226
|
+
printf("Test: Remove Vector - PASSED\n");
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* This test validates the save and load functionality of the index. It initializes the index, reserves space, and adds
|
|
231
|
+
* vectors. The index is then saved to a file and freed. A new index is initialized, and the previously saved index is
|
|
232
|
+
* loaded into it. The test then validates the loaded index properties and ensures that it contains all the vectors
|
|
233
|
+
* from the saved index.
|
|
234
|
+
*/
|
|
235
|
+
void test_save_load(size_t const collection_size, size_t const dimensions) {
|
|
236
|
+
printf("Test: Save/Load... %zu vectors, %zu dimensions \n", collection_size, dimensions);
|
|
237
|
+
float* data = create_vectors(collection_size, dimensions);
|
|
238
|
+
|
|
239
|
+
usearch_error_t error = NULL;
|
|
240
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
241
|
+
usearch_init_options_t weird_ops = opts;
|
|
242
|
+
weird_ops.connectivity = 11;
|
|
243
|
+
weird_ops.expansion_add = 15;
|
|
244
|
+
weird_ops.expansion_search = 19;
|
|
245
|
+
weird_ops.metric_kind = usearch_metric_pearson_k;
|
|
246
|
+
weird_ops.quantization = usearch_scalar_f64_k;
|
|
247
|
+
|
|
248
|
+
{
|
|
249
|
+
|
|
250
|
+
usearch_index_t index = usearch_init(&weird_ops, &error);
|
|
251
|
+
usearch_reserve(index, collection_size, &error);
|
|
252
|
+
|
|
253
|
+
// Add vectors
|
|
254
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
255
|
+
usearch_key_t key = i;
|
|
256
|
+
usearch_add(index, key, data + i * dimensions, usearch_scalar_f32_k, &error);
|
|
257
|
+
ASSERT(!error, error);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Save and free the index
|
|
261
|
+
usearch_save(index, "tmp.usearch", &error);
|
|
262
|
+
ASSERT(!error, error);
|
|
263
|
+
usearch_free(index, &error);
|
|
264
|
+
ASSERT(!error, error);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Reset the options
|
|
268
|
+
opts.connectivity = 0;
|
|
269
|
+
opts.dimensions = 0;
|
|
270
|
+
opts.expansion_add = 0;
|
|
271
|
+
opts.expansion_search = 0;
|
|
272
|
+
opts.metric = NULL;
|
|
273
|
+
opts.quantization = usearch_scalar_unknown_k;
|
|
274
|
+
opts.metric_kind = usearch_metric_unknown_k;
|
|
275
|
+
|
|
276
|
+
// Reinit
|
|
277
|
+
{
|
|
278
|
+
|
|
279
|
+
usearch_index_t index = usearch_init(&opts, &error);
|
|
280
|
+
ASSERT(!error, error);
|
|
281
|
+
ASSERT(usearch_size(index, &error) == 0, error);
|
|
282
|
+
|
|
283
|
+
// Load
|
|
284
|
+
usearch_load(index, "tmp.usearch", &error);
|
|
285
|
+
ASSERT(!error, error);
|
|
286
|
+
ASSERT(usearch_size(index, &error) == collection_size, error);
|
|
287
|
+
ASSERT(usearch_capacity(index, &error) == collection_size, error);
|
|
288
|
+
ASSERT(usearch_dimensions(index, &error) == dimensions, error);
|
|
289
|
+
ASSERT(usearch_connectivity(index, &error) == weird_ops.connectivity, error);
|
|
290
|
+
|
|
291
|
+
// Check vectors in the index
|
|
292
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
293
|
+
usearch_key_t key = i;
|
|
294
|
+
ASSERT(usearch_contains(index, key, &error), error);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Create result buffers
|
|
298
|
+
usearch_key_t* keys = (usearch_key_t*)malloc(collection_size * sizeof(usearch_key_t));
|
|
299
|
+
float* distances = (float*)malloc(collection_size * sizeof(float));
|
|
300
|
+
ASSERT(keys && distances, "Failed to allocate memory");
|
|
301
|
+
|
|
302
|
+
// Find the vectors
|
|
303
|
+
for (size_t i = 0; i < collection_size; i++) {
|
|
304
|
+
size_t found_count = usearch_search(index, data + i * dimensions, usearch_scalar_f32_k, collection_size,
|
|
305
|
+
keys, distances, &error);
|
|
306
|
+
ASSERT(!error, error);
|
|
307
|
+
ASSERT(found_count >= 1 && found_count <= collection_size, "Vector is missing");
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
free(keys);
|
|
311
|
+
free(distances);
|
|
312
|
+
usearch_free(index, &error);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
free(data);
|
|
316
|
+
|
|
317
|
+
// Remove the file from disk
|
|
318
|
+
remove("tmp.usearch");
|
|
319
|
+
printf("Test: Save/Load - PASSED\n");
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* This test is designed to validate the view functionality of the index. It initializes the index, reserves space, and
|
|
324
|
+
* adds vectors. The index is then saved to a file and freed. A new index is initialized and a view is created from the
|
|
325
|
+
* saved index file. The test is mainly focused on ensuring that no errors occur during these operations, but it does
|
|
326
|
+
* not verify the properties or contents of the viewed index.
|
|
327
|
+
*/
|
|
328
|
+
void test_view(size_t const collection_size, size_t const dimensions) {
|
|
329
|
+
printf("Test: View... %zu vectors, %zu dimensions \n", collection_size, dimensions);
|
|
330
|
+
|
|
331
|
+
usearch_error_t error = NULL;
|
|
332
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
333
|
+
usearch_index_t index = usearch_init(&opts, &error);
|
|
334
|
+
usearch_reserve(index, collection_size, &error);
|
|
335
|
+
|
|
336
|
+
// Add vectors
|
|
337
|
+
float* data = create_vectors(collection_size, dimensions);
|
|
338
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
339
|
+
usearch_key_t key = i;
|
|
340
|
+
usearch_add(index, key, data + i * dimensions, usearch_scalar_f32_k, &error);
|
|
341
|
+
ASSERT(!error, error);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Save and free the index
|
|
345
|
+
usearch_save(index, "tmp.usearch", &error);
|
|
346
|
+
ASSERT(!error, error);
|
|
347
|
+
usearch_free(index, &error);
|
|
348
|
+
ASSERT(!error, error);
|
|
349
|
+
|
|
350
|
+
// Reinit
|
|
351
|
+
index = usearch_init(&opts, &error);
|
|
352
|
+
ASSERT(!error, error);
|
|
353
|
+
|
|
354
|
+
// View
|
|
355
|
+
usearch_view(index, "tmp.usearch", &error);
|
|
356
|
+
ASSERT(!error, error);
|
|
357
|
+
|
|
358
|
+
free(data);
|
|
359
|
+
usearch_free(index, &error);
|
|
360
|
+
printf("Test: View - PASSED\n");
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
int main(int argc, char const* argv[]) {
|
|
364
|
+
|
|
365
|
+
size_t collection_sizes[] = {11, 512};
|
|
366
|
+
size_t dimensions[] = {83, 2}; // Not all distance functions make sense for 1 dimensional data
|
|
367
|
+
for (size_t index = 0; index < sizeof(collection_sizes) / sizeof(collection_sizes[0]); ++index) {
|
|
368
|
+
for (size_t jdx = 0; jdx < sizeof(dimensions) / sizeof(dimensions[0]); ++jdx) {
|
|
369
|
+
test_init(collection_sizes[index], dimensions[jdx]);
|
|
370
|
+
test_add_vector(collection_sizes[index], dimensions[jdx]);
|
|
371
|
+
test_find_vector(collection_sizes[index], dimensions[jdx]);
|
|
372
|
+
test_get_vector(collection_sizes[index], dimensions[jdx]);
|
|
373
|
+
test_remove_vector(collection_sizes[index], dimensions[jdx]);
|
|
374
|
+
test_save_load(collection_sizes[index], dimensions[jdx]);
|
|
375
|
+
test_view(collection_sizes[index], dimensions[jdx]);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
(void)argc;
|
|
380
|
+
(void)argv;
|
|
381
|
+
return 0;
|
|
382
|
+
}
|