usearch 2.25.0 → 2.25.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +43 -47
  2. package/c/README.md +1 -1
  3. package/c/lib.cpp +28 -13
  4. package/c/test.c +41 -0
  5. package/cpp/test.cpp +99 -0
  6. package/include/usearch/index.hpp +338 -57
  7. package/include/usearch/index_dense.hpp +155 -50
  8. package/include/usearch/index_plugins.hpp +94 -35
  9. package/javascript/README.md +1 -1
  10. package/javascript/lib.cpp +4 -2
  11. package/javascript/usearch.test.js +117 -94
  12. package/numkong/CITATION.cff +1 -1
  13. package/numkong/Cargo.toml +1 -1
  14. package/numkong/bench/bench_cross_amx.cpp +12 -0
  15. package/numkong/bench/bench_mesh.cpp +12 -0
  16. package/numkong/bench/bench_spatial.cpp +0 -3
  17. package/numkong/binding.gyp +18 -0
  18. package/numkong/build.rs +1 -0
  19. package/numkong/c/dispatch_e5m2.c +23 -3
  20. package/numkong/include/numkong/capabilities.h +1 -1
  21. package/numkong/include/numkong/cast/README.md +3 -0
  22. package/numkong/include/numkong/cast/haswell.h +28 -64
  23. package/numkong/include/numkong/cast/serial.h +17 -0
  24. package/numkong/include/numkong/cast/skylake.h +67 -52
  25. package/numkong/include/numkong/cast.h +1 -0
  26. package/numkong/include/numkong/dot/README.md +1 -0
  27. package/numkong/include/numkong/dot/haswell.h +92 -13
  28. package/numkong/include/numkong/dot/serial.h +15 -0
  29. package/numkong/include/numkong/dot/skylake.h +61 -14
  30. package/numkong/include/numkong/dots/README.md +2 -0
  31. package/numkong/include/numkong/dots/graniteamx.h +434 -0
  32. package/numkong/include/numkong/dots/haswell.h +28 -28
  33. package/numkong/include/numkong/dots/sapphireamx.h +1 -1
  34. package/numkong/include/numkong/dots/serial.h +23 -8
  35. package/numkong/include/numkong/dots/skylake.h +28 -23
  36. package/numkong/include/numkong/dots.h +12 -0
  37. package/numkong/include/numkong/each/serial.h +18 -1
  38. package/numkong/include/numkong/geospatial/serial.h +14 -3
  39. package/numkong/include/numkong/maxsim/serial.h +15 -0
  40. package/numkong/include/numkong/mesh/README.md +50 -44
  41. package/numkong/include/numkong/mesh/genoa.h +462 -0
  42. package/numkong/include/numkong/mesh/haswell.h +806 -933
  43. package/numkong/include/numkong/mesh/neon.h +871 -943
  44. package/numkong/include/numkong/mesh/neonbfdot.h +382 -522
  45. package/numkong/include/numkong/mesh/neonfhm.h +676 -0
  46. package/numkong/include/numkong/mesh/rvv.h +404 -319
  47. package/numkong/include/numkong/mesh/serial.h +204 -162
  48. package/numkong/include/numkong/mesh/skylake.h +1029 -1585
  49. package/numkong/include/numkong/mesh/v128relaxed.h +403 -377
  50. package/numkong/include/numkong/mesh.h +38 -0
  51. package/numkong/include/numkong/reduce/serial.h +15 -1
  52. package/numkong/include/numkong/sparse/serial.h +17 -2
  53. package/numkong/include/numkong/spatial/genoa.h +0 -68
  54. package/numkong/include/numkong/spatial/haswell.h +98 -56
  55. package/numkong/include/numkong/spatial/serial.h +15 -0
  56. package/numkong/include/numkong/spatial/skylake.h +114 -54
  57. package/numkong/include/numkong/spatial.h +0 -12
  58. package/numkong/include/numkong/spatials/graniteamx.h +128 -0
  59. package/numkong/include/numkong/spatials/serial.h +18 -1
  60. package/numkong/include/numkong/spatials/skylake.h +2 -2
  61. package/numkong/include/numkong/spatials.h +17 -0
  62. package/numkong/include/numkong/tensor.hpp +107 -23
  63. package/numkong/javascript/@numkong-darwin-arm64/package.json +1 -1
  64. package/numkong/javascript/@numkong-darwin-x64/package.json +1 -1
  65. package/numkong/javascript/@numkong-linux-arm64/package.json +1 -1
  66. package/numkong/javascript/@numkong-linux-x64/package.json +1 -1
  67. package/numkong/javascript/@numkong-win32-arm64/package.json +1 -1
  68. package/numkong/javascript/@numkong-win32-x64/package.json +1 -1
  69. package/numkong/javascript/numkong.c +3 -2
  70. package/numkong/package.json +7 -7
  71. package/numkong/test/test.cu +841 -0
  72. package/numkong/test/test_cross_amx.cpp +13 -0
  73. package/numkong/test/test_dlpack.py +492 -0
  74. package/numkong/test/test_mesh.cpp +12 -0
  75. package/numkong/test/test_spatial.cpp +0 -3
  76. package/numkong/test/test_tensor.cpp +87 -27
  77. package/package.json +1 -1
  78. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  79. package/prebuilds/linux-arm64/usearch.node +0 -0
  80. package/prebuilds/linux-x64/usearch.node +0 -0
@@ -96,62 +96,100 @@ void test_tensor_operator_indexing() {
96
96
 
97
97
  assert(t[0] == 1.0f && "flat tensor lookup failed");
98
98
  assert(t[-1] == 6.0f && "negative flat tensor lookup failed");
99
- assert((t[0, 0] == 1.0f) && "exact tensor lookup failed");
100
- assert((t[1, -1] == 6.0f) && "negative exact tensor lookup failed");
99
+ assert((t(0, 0) == 1.0f) && "exact tensor lookup failed");
100
+ assert((t(1, -1) == 6.0f) && "negative exact tensor lookup failed");
101
+ #if NK_HAS_MULTIDIMENSIONAL_SUBSCRIPT_
102
+ assert((t[0, 0] == 1.0f) && "exact tensor lookup via operator[] failed");
103
+ assert((t[1, -1] == 6.0f) && "negative exact tensor lookup via operator[] failed");
104
+ #endif
101
105
 
102
106
  auto whole = t[nk::slice];
103
107
  assert(whole.rank() == 2 && "slice identity rank mismatch");
104
108
  assert(whole.extent(0) == 2 && whole.extent(1) == 3 && "slice identity extents mismatch");
105
109
 
106
- auto row1 = t[1, nk::slice];
110
+ auto row1 = t(1, nk::slice);
107
111
  assert(row1.rank() == 1 && "row slice rank mismatch");
108
112
  assert(row1.extent(0) == 3 && "row slice extent mismatch");
109
113
  assert(row1[0] == 4.0f && row1[-1] == 6.0f && "row slice values mismatch");
110
114
  row1[1] = 42.0f;
111
- assert((t[1, 1] == 42.0f) && "row slice write-through failed");
115
+ assert((t(1, 1) == 42.0f) && "row slice write-through failed");
116
+ #if NK_HAS_MULTIDIMENSIONAL_SUBSCRIPT_
117
+ assert((t[1, 1] == 42.0f) && "operator[] row slice write-through failed");
118
+ auto row1_subscript = t[1, nk::slice];
119
+ assert(row1_subscript.extent(0) == row1.extent(0) && "operator[] row slice mismatch");
120
+ #endif
112
121
 
113
- auto cell = t[1, 1, nk::slice];
122
+ auto cell = t(1, 1, nk::slice);
114
123
  assert(cell.rank() == 0 && "scalar slice rank mismatch");
115
124
  assert(cell.scalar() == 42.0f && "scalar slice value mismatch");
116
125
  cell.scalar_ref() = 24.0f;
117
- assert((t[1, 1] == 24.0f) && "scalar slice write-through failed");
126
+ assert((t(1, 1) == 24.0f) && "scalar slice write-through failed");
127
+ #if NK_HAS_MULTIDIMENSIONAL_SUBSCRIPT_
128
+ assert((t[1, 1] == 24.0f) && "operator[] scalar slice write-through failed");
129
+ auto cell_subscript = t[1, 1, nk::slice];
130
+ assert(cell_subscript.rank() == 0 && "operator[] scalar slice rank mismatch");
131
+ #endif
118
132
 
119
133
  auto const &ct = t;
120
- auto const last_row = ct[-1, nk::slice];
134
+ auto const last_row = ct(-1, nk::slice);
121
135
  assert(last_row.rank() == 1 && "const row slice rank mismatch");
122
136
  assert(last_row[0] == 4.0f && "const row slice mismatch");
137
+ #if NK_HAS_MULTIDIMENSIONAL_SUBSCRIPT_
138
+ auto const last_row_subscript = ct[-1, nk::slice];
139
+ assert(last_row_subscript.rank() == 1 && "operator[] const row slice mismatch");
140
+ #endif
123
141
 
124
142
  auto cube = nk::tensor<float>::try_zeros({2, 3, 4});
125
143
  assert(!cube.empty() && "cube allocation failed");
126
144
  for (int i = 0; i < 24; ++i) cube[i] = static_cast<float>(i);
127
145
 
128
- auto plane = cube[1, nk::slice];
146
+ auto plane = cube(1, nk::slice);
129
147
  assert(plane.rank() == 2 && plane.extent(0) == 3 && plane.extent(1) == 4 && "plane slice mismatch");
130
- auto line = cube[1, 2, nk::slice];
148
+ auto line = cube(1, 2, nk::slice);
131
149
  assert(line.rank() == 1 && line.extent(0) == 4 && "line slice mismatch");
132
- assert((line[3] == cube[1, 2, 3]) && "line slice element mismatch");
133
- auto point = cube[1, 2, 3, nk::slice];
134
- assert((point.rank() == 0 && point.scalar() == cube[1, 2, 3]) && "point slice mismatch");
150
+ assert((line[3] == cube(1, 2, 3)) && "line slice element mismatch");
151
+ auto point = cube(1, 2, 3, nk::slice);
152
+ assert((point.rank() == 0 && point.scalar() == cube(1, 2, 3)) && "point slice mismatch");
153
+ #if NK_HAS_MULTIDIMENSIONAL_SUBSCRIPT_
154
+ auto plane_subscript = cube[1, nk::slice];
155
+ auto line_subscript = cube[1, 2, nk::slice];
156
+ auto point_subscript = cube[1, 2, 3, nk::slice];
157
+ assert((line_subscript[3] == cube[1, 2, 3]) && "operator[] line slice element mismatch");
158
+ assert((point_subscript.scalar() == cube[1, 2, 3]) && "operator[] point slice mismatch");
159
+ assert(plane_subscript.rank() == 2 && "operator[] plane slice rank mismatch");
160
+ #endif
135
161
 
136
162
  // all_t slicing: extract a column
137
- auto second_column = t[nk::all, 1, nk::slice];
163
+ auto second_column = t(nk::all, 1, nk::slice);
138
164
  assert(second_column.rank() == 1 && "all_t column rank mismatch");
139
165
  assert(second_column.numel() == 2 && "all_t column numel mismatch");
140
166
 
141
167
  // range slicing: extract a sub-range of rows
142
- auto first_two_planes = cube[nk::range(0, 2), nk::slice];
168
+ auto first_two_planes = cube(nk::range(0, 2), nk::slice);
143
169
  assert(first_two_planes.rank() == 3 && "range slice rank mismatch");
144
170
  assert(first_two_planes.extent(0) == 2 && "range slice extent mismatch");
145
171
 
146
172
  // combined: range + all_t + slice on a 3D tensor
147
- auto sub = cube[nk::range(0, 2), nk::all, nk::slice];
173
+ auto sub = cube(nk::range(0, 2), nk::all, nk::slice);
148
174
  assert(sub.rank() == 3 && sub.extent(0) == 2 && sub.extent(1) == 3 && "range+all slice mismatch");
175
+ #if NK_HAS_MULTIDIMENSIONAL_SUBSCRIPT_
176
+ auto second_column_subscript = t[nk::all, 1, nk::slice];
177
+ auto first_two_planes_subscript = cube[nk::range(0, 2), nk::slice];
178
+ auto sub_subscript = cube[nk::range(0, 2), nk::all, nk::slice];
179
+ assert(second_column_subscript.numel() == 2 && "operator[] all_t column mismatch");
180
+ assert(first_two_planes_subscript.extent(0) == 2 && "operator[] range slice mismatch");
181
+ assert(sub_subscript.extent(1) == 3 && "operator[] range+all slice mismatch");
182
+ #endif
149
183
 
150
184
  // row() access
151
185
  auto row0 = t.row(0);
152
186
  assert(row0.rank() == 1 && row0.extent(0) == 3 && "row() rank/extent mismatch");
153
- auto row0_via_slice = t[0, nk::slice];
154
- assert(row0[0] == row0_via_slice[0] && "row() should match t[0, slice]");
187
+ auto row0_via_slice = t(0, nk::slice);
188
+ assert(row0[0] == row0_via_slice[0] && "row() should match t(0, slice)");
189
+ #if NK_HAS_MULTIDIMENSIONAL_SUBSCRIPT_
190
+ auto row0_via_subscript = t[0, nk::slice];
191
+ assert(row0[0] == row0_via_subscript[0] && "row() should match t[0, slice]");
192
+ #endif
155
193
  }
156
194
 
157
195
  void test_packed_tensor_operator_indexing() {
@@ -162,14 +200,23 @@ void test_packed_tensor_operator_indexing() {
162
200
 
163
201
  assert(int(t4[0]) == 1 && "packed flat lookup failed");
164
202
  assert(int(t4[-1]) == 8 && "packed negative flat lookup failed");
165
- assert((int(t4[0, 3]) == 4) && "packed exact lookup failed");
166
- assert((int(t4[1, -1]) == 8) && "packed negative exact lookup failed");
203
+ assert((int(t4(0, 3)) == 4) && "packed exact lookup failed");
204
+ assert((int(t4(1, -1)) == 8) && "packed negative exact lookup failed");
205
+ #if NK_HAS_MULTIDIMENSIONAL_SUBSCRIPT_
206
+ assert((int(t4[0, 3]) == 4) && "packed operator[] exact lookup failed");
207
+ assert((int(t4[1, -1]) == 8) && "packed operator[] negative exact lookup failed");
208
+ #endif
167
209
 
168
- auto second_row = t4[1, nk::slice];
210
+ auto second_row = t4(1, nk::slice);
169
211
  assert(second_row.rank() == 1 && second_row.extent(0) == 4 && "packed row slice rank mismatch");
170
212
  assert(int(second_row[0]) == 5 && int(second_row[-1]) == 8 && "packed row slice values mismatch");
171
213
  second_row[1] = 14;
172
- assert((int(t4[1, 1]) == 14) && "packed row slice write-through failed");
214
+ assert((int(t4(1, 1)) == 14) && "packed row slice write-through failed");
215
+ #if NK_HAS_MULTIDIMENSIONAL_SUBSCRIPT_
216
+ auto second_row_subscript = t4[1, nk::slice];
217
+ assert(second_row_subscript.extent(0) == 4 && "packed operator[] row slice rank mismatch");
218
+ assert((int(t4[1, 1]) == 14) && "packed operator[] row slice write-through failed");
219
+ #endif
173
220
 
174
221
  auto t1 = nk::tensor<nk::u1x8_t>::try_zeros({2, 8});
175
222
  assert(!t1.empty() && "packed u1 tensor allocation failed");
@@ -179,14 +226,23 @@ void test_packed_tensor_operator_indexing() {
179
226
  t1[-1] = true;
180
227
 
181
228
  assert(bool(t1[0]) && "packed bit flat lookup failed");
182
- assert((bool(t1[0, 7])) && "packed bit exact lookup failed");
183
- assert((bool(t1[1, 3])) && "packed bit second-row lookup failed");
229
+ assert((bool(t1(0, 7))) && "packed bit exact lookup failed");
230
+ assert((bool(t1(1, 3))) && "packed bit second-row lookup failed");
184
231
  assert(bool(t1[-1]) && "packed bit negative flat lookup failed");
232
+ #if NK_HAS_MULTIDIMENSIONAL_SUBSCRIPT_
233
+ assert((bool(t1[0, 7])) && "packed bit operator[] exact lookup failed");
234
+ assert((bool(t1[1, 3])) && "packed bit operator[] second-row lookup failed");
235
+ #endif
185
236
 
186
- auto bits = t1[1, nk::slice];
237
+ auto bits = t1(1, nk::slice);
187
238
  assert(bits.rank() == 1 && bits.extent(0) == 8 && "packed bit slice rank mismatch");
188
239
  bits[4] = true;
189
- assert((bool(t1[1, 4])) && "packed bit slice write-through failed");
240
+ assert((bool(t1(1, 4))) && "packed bit slice write-through failed");
241
+ #if NK_HAS_MULTIDIMENSIONAL_SUBSCRIPT_
242
+ auto bits_subscript = t1[1, nk::slice];
243
+ assert(bits_subscript.extent(0) == 8 && "packed bit operator[] slice rank mismatch");
244
+ assert((bool(t1[1, 4])) && "packed bit operator[] slice write-through failed");
245
+ #endif
190
246
  }
191
247
 
192
248
  void test_move_semantics() {
@@ -470,8 +526,12 @@ void test_packed_tensor_fail_closed_views() {
470
526
  auto packed = nk::tensor<nk::i4x2_t>::try_zeros({2, 4});
471
527
  assert(!packed.empty() && "packed tensor allocation failed");
472
528
  assert(packed.view().transpose().empty() && "packed transpose should fail closed");
473
- assert((!packed[1, nk::slice].empty()) && "packed row slice should remain supported");
474
- assert((packed[1, 2, nk::slice].empty()) && "packed scalar trailing slice should fail closed");
529
+ assert((!packed(1, nk::slice).empty()) && "packed row slice should remain supported");
530
+ assert((packed(1, 2, nk::slice).empty()) && "packed scalar trailing slice should fail closed");
531
+ #if NK_HAS_MULTIDIMENSIONAL_SUBSCRIPT_
532
+ assert((!packed[1, nk::slice].empty()) && "packed operator[] row slice should remain supported");
533
+ assert((packed[1, 2, nk::slice].empty()) && "packed operator[] scalar trailing slice should fail closed");
534
+ #endif
475
535
  }
476
536
 
477
537
  void test_vector_types() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "usearch",
3
- "version": "2.25.0",
3
+ "version": "2.25.3",
4
4
  "description": "Smaller & Faster Single-File Vector Search Engine from Unum",
5
5
  "author": "Ash Vardanian (https://ashvardanian.com/)",
6
6
  "license": "Apache 2.0",
Binary file
Binary file