usearch 1.3.0 → 2.0.1

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.
@@ -54,8 +54,8 @@ struct uuid_t {
54
54
  std::uint8_t octets[16];
55
55
  };
56
56
 
57
- class i8_bits_t;
58
57
  class f16_bits_t;
58
+ class i8_converted_t;
59
59
 
60
60
  #if USEARCH_USE_NATIVE_F16
61
61
  #if defined(USEARCH_DEFINED_ARM)
@@ -149,7 +149,7 @@ template <typename scalar_at> scalar_kind_t scalar_kind() noexcept {
149
149
  return scalar_kind_t::f32_k;
150
150
  if (std::is_same<scalar_at, f16_t>())
151
151
  return scalar_kind_t::f16_k;
152
- if (std::is_same<scalar_at, i8_bits_t>())
152
+ if (std::is_same<scalar_at, i8_t>())
153
153
  return scalar_kind_t::i8_k;
154
154
  if (std::is_same<scalar_at, u64_t>())
155
155
  return scalar_kind_t::u64_k;
@@ -364,7 +364,7 @@ class f16_bits_t {
364
364
  inline operator float() const noexcept { return f16_to_f32(uint16_); }
365
365
  inline explicit operator bool() const noexcept { return f16_to_f32(uint16_) > 0.5f; }
366
366
 
367
- inline f16_bits_t(i8_bits_t) noexcept;
367
+ inline f16_bits_t(i8_converted_t) noexcept;
368
368
  inline f16_bits_t(bool v) noexcept : uint16_(f32_to_f16(v)) {}
369
369
  inline f16_bits_t(float v) noexcept : uint16_(f32_to_f16(v)) {}
370
370
  inline f16_bits_t(double v) noexcept : uint16_(f32_to_f16(v)) {}
@@ -403,45 +403,6 @@ class f16_bits_t {
403
403
  }
404
404
  };
405
405
 
406
- /**
407
- * @brief Numeric type for uniformly-distributed floating point
408
- * values within [-1,1] range, quantized to integers [-100,100].
409
- */
410
- class i8_bits_t {
411
- std::int8_t int8_{};
412
-
413
- public:
414
- constexpr static float divisor_k = 100.f;
415
- constexpr static std::int8_t min_k = -100;
416
- constexpr static std::int8_t max_k = 100;
417
-
418
- inline i8_bits_t() noexcept : int8_(0) {}
419
- inline i8_bits_t(bool v) noexcept : int8_(v ? max_k : 0) {}
420
-
421
- inline i8_bits_t(i8_bits_t&&) = default;
422
- inline i8_bits_t& operator=(i8_bits_t&&) = default;
423
- inline i8_bits_t(i8_bits_t const&) = default;
424
- inline i8_bits_t& operator=(i8_bits_t const&) = default;
425
-
426
- inline operator float() const noexcept { return float(int8_) / divisor_k; }
427
- inline operator f16_t() const noexcept { return float(int8_) / divisor_k; }
428
- inline operator double() const noexcept { return double(int8_) / divisor_k; }
429
- inline explicit operator bool() const noexcept { return int8_ > (max_k / 2); }
430
- inline explicit operator std::int8_t() const noexcept { return int8_; }
431
- inline explicit operator std::int16_t() const noexcept { return int8_; }
432
- inline explicit operator std::int32_t() const noexcept { return int8_; }
433
- inline explicit operator std::int64_t() const noexcept { return int8_; }
434
-
435
- inline i8_bits_t(f16_t v)
436
- : int8_(usearch::clamp<std::int8_t>(static_cast<std::int8_t>(v * divisor_k), min_k, max_k)) {}
437
- inline i8_bits_t(float v)
438
- : int8_(usearch::clamp<std::int8_t>(static_cast<std::int8_t>(v * divisor_k), min_k, max_k)) {}
439
- inline i8_bits_t(double v)
440
- : int8_(usearch::clamp<std::int8_t>(static_cast<std::int8_t>(v * divisor_k), min_k, max_k)) {}
441
- };
442
-
443
- inline f16_bits_t::f16_bits_t(i8_bits_t v) noexcept : f16_bits_t(float(v)) {}
444
-
445
406
  /**
446
407
  * @brief An STL-based executor or a "thread-pool" for parallel execution.
447
408
  * Isn't efficient for small batches, as it recreates the threads on every call.
@@ -953,7 +914,7 @@ template <> struct cast_gt<f16_bits_t, f16_bits_t> {
953
914
  bool operator()(byte_t const*, std::size_t, byte_t*) const { return false; }
954
915
  };
955
916
 
956
- template <> struct cast_gt<i8_bits_t, i8_bits_t> {
917
+ template <> struct cast_gt<i8_t, i8_t> {
957
918
  bool operator()(byte_t const*, std::size_t, byte_t*) const { return false; }
958
919
  };
959
920
 
@@ -981,6 +942,53 @@ template <typename to_scalar_at> struct cast_gt<b1x8_t, to_scalar_at> {
981
942
  }
982
943
  };
983
944
 
945
+ /**
946
+ * @brief Numeric type for uniformly-distributed floating point
947
+ * values within [-1,1] range, quantized to integers [-100,100].
948
+ */
949
+ class i8_converted_t {
950
+ std::int8_t int8_{};
951
+
952
+ public:
953
+ constexpr static float divisor_k = 100.f;
954
+ constexpr static std::int8_t min_k = -100;
955
+ constexpr static std::int8_t max_k = 100;
956
+
957
+ inline i8_converted_t() noexcept : int8_(0) {}
958
+ inline i8_converted_t(bool v) noexcept : int8_(v ? max_k : 0) {}
959
+
960
+ inline i8_converted_t(i8_converted_t&&) = default;
961
+ inline i8_converted_t& operator=(i8_converted_t&&) = default;
962
+ inline i8_converted_t(i8_converted_t const&) = default;
963
+ inline i8_converted_t& operator=(i8_converted_t const&) = default;
964
+
965
+ inline operator float() const noexcept { return float(int8_) / divisor_k; }
966
+ inline operator f16_t() const noexcept { return float(int8_) / divisor_k; }
967
+ inline operator double() const noexcept { return double(int8_) / divisor_k; }
968
+ inline explicit operator bool() const noexcept { return int8_ > (max_k / 2); }
969
+ inline explicit operator std::int8_t() const noexcept { return int8_; }
970
+ inline explicit operator std::int16_t() const noexcept { return int8_; }
971
+ inline explicit operator std::int32_t() const noexcept { return int8_; }
972
+ inline explicit operator std::int64_t() const noexcept { return int8_; }
973
+
974
+ inline i8_converted_t(f16_t v)
975
+ : int8_(usearch::clamp<std::int8_t>(static_cast<std::int8_t>(v * divisor_k), min_k, max_k)) {}
976
+ inline i8_converted_t(float v)
977
+ : int8_(usearch::clamp<std::int8_t>(static_cast<std::int8_t>(v * divisor_k), min_k, max_k)) {}
978
+ inline i8_converted_t(double v)
979
+ : int8_(usearch::clamp<std::int8_t>(static_cast<std::int8_t>(v * divisor_k), min_k, max_k)) {}
980
+ };
981
+
982
+ f16_bits_t::f16_bits_t(i8_converted_t v) noexcept : uint16_(f32_to_f16(v)) {}
983
+
984
+ template <> struct cast_gt<i8_t, f16_t> : public cast_gt<i8_converted_t, f16_t> {};
985
+ template <> struct cast_gt<i8_t, f32_t> : public cast_gt<i8_converted_t, f32_t> {};
986
+ template <> struct cast_gt<i8_t, f64_t> : public cast_gt<i8_converted_t, f64_t> {};
987
+
988
+ template <> struct cast_gt<f16_t, i8_t> : public cast_gt<f16_t, i8_converted_t> {};
989
+ template <> struct cast_gt<f32_t, i8_t> : public cast_gt<f32_t, i8_converted_t> {};
990
+ template <> struct cast_gt<f64_t, i8_t> : public cast_gt<f64_t, i8_converted_t> {};
991
+
984
992
  /**
985
993
  * @brief Inner (Dot) Product distance.
986
994
  */
@@ -1205,10 +1213,10 @@ template <typename scalar_at = float, typename result_at = float> struct metric_
1205
1213
  };
1206
1214
 
1207
1215
  struct cos_i8_t {
1208
- using scalar_t = i8_bits_t;
1216
+ using scalar_t = i8_t;
1209
1217
  using result_t = f32_t;
1210
1218
 
1211
- inline result_t operator()(i8_bits_t const* a, i8_bits_t const* b, std::size_t dim) const noexcept {
1219
+ inline result_t operator()(i8_t const* a, i8_t const* b, std::size_t dim) const noexcept {
1212
1220
  std::int32_t ab{}, a2{}, b2{};
1213
1221
  #if USEARCH_USE_OPENMP
1214
1222
  #pragma omp simd reduction(+ : ab, a2, b2)
@@ -1229,10 +1237,10 @@ struct cos_i8_t {
1229
1237
  };
1230
1238
 
1231
1239
  struct l2sq_i8_t {
1232
- using scalar_t = i8_bits_t;
1240
+ using scalar_t = i8_t;
1233
1241
  using result_t = f32_t;
1234
1242
 
1235
- inline result_t operator()(i8_bits_t const* a, i8_bits_t const* b, std::size_t dim) const noexcept {
1243
+ inline result_t operator()(i8_t const* a, i8_t const* b, std::size_t dim) const noexcept {
1236
1244
  std::int32_t ab_deltas_sq{};
1237
1245
  #if USEARCH_USE_OPENMP
1238
1246
  #pragma omp simd reduction(+ : ab_deltas_sq)
@@ -1431,7 +1439,6 @@ class metric_punned_t {
1431
1439
  static metric_punned_t haversine_metric_(scalar_kind_t scalar_kind) {
1432
1440
  std::size_t bytes_per_vector = 2u * bits_per_scalar(scalar_kind) / CHAR_BIT;
1433
1441
  switch (scalar_kind) {
1434
- case scalar_kind_t::i8_k: return {to_stl_<metric_haversine_gt<i8_bits_t, f32_t>>(bytes_per_vector), bytes_per_vector, metric_kind_t::haversine_k, scalar_kind_t::i8_k, isa_kind_t::auto_k};
1435
1442
  case scalar_kind_t::f16_k: return {to_stl_<metric_haversine_gt<f16_t, f32_t>>(bytes_per_vector), bytes_per_vector, metric_kind_t::haversine_k, scalar_kind_t::f16_k, isa_kind_t::auto_k};
1436
1443
  case scalar_kind_t::f32_k: return {to_stl_<metric_haversine_gt<f32_t>>(bytes_per_vector), bytes_per_vector, metric_kind_t::haversine_k, scalar_kind_t::f32_k, isa_kind_t::auto_k};
1437
1444
  case scalar_kind_t::f64_k: return {to_stl_<metric_haversine_gt<f64_t>>(bytes_per_vector), bytes_per_vector, metric_kind_t::haversine_k, scalar_kind_t::f64_k, isa_kind_t::auto_k};
@@ -1441,7 +1448,7 @@ class metric_punned_t {
1441
1448
 
1442
1449
  static metric_punned_t pearson_metric_(std::size_t bytes_per_vector, scalar_kind_t scalar_kind) {
1443
1450
  switch (scalar_kind) {
1444
- case scalar_kind_t::i8_k: return {to_stl_<metric_pearson_gt<i8_bits_t, f32_t>>(bytes_per_vector), bytes_per_vector, metric_kind_t::pearson_k, scalar_kind_t::i8_k, isa_kind_t::auto_k};
1451
+ case scalar_kind_t::i8_k: return {to_stl_<metric_pearson_gt<i8_t, f32_t>>(bytes_per_vector), bytes_per_vector, metric_kind_t::pearson_k, scalar_kind_t::i8_k, isa_kind_t::auto_k};
1445
1452
  case scalar_kind_t::f16_k: return {to_stl_<metric_pearson_gt<f16_t, f32_t>>(bytes_per_vector), bytes_per_vector, metric_kind_t::pearson_k, scalar_kind_t::f16_k, isa_kind_t::auto_k};
1446
1453
  case scalar_kind_t::f32_k: return {to_stl_<metric_pearson_gt<f32_t>>(bytes_per_vector), bytes_per_vector, metric_kind_t::pearson_k, scalar_kind_t::f32_k, isa_kind_t::auto_k};
1447
1454
  case scalar_kind_t::f64_k: return {to_stl_<metric_pearson_gt<f64_t>>(bytes_per_vector), bytes_per_vector, metric_kind_t::pearson_k, scalar_kind_t::f64_k, isa_kind_t::auto_k};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "usearch",
3
- "version": "1.3.0",
3
+ "version": "2.0.1",
4
4
  "description": "Smaller & Faster Single-File Vector Search Engine from Unum",
5
5
  "author": "Ash Vardanian",
6
6
  "license": "Apache 2.0",
package/python/lib.cpp CHANGED
@@ -144,7 +144,7 @@ metric_t wrap_user_defined_metric(
144
144
  case scalar_kind_t::b1x8_k:
145
145
  return wrap_typed_user_defined_metric<b1x8_t>(kind, signature, metric_uintptr, scalar_kind, dimensions);
146
146
  case scalar_kind_t::i8_k:
147
- return wrap_typed_user_defined_metric<i8_bits_t>(kind, signature, metric_uintptr, scalar_kind, dimensions);
147
+ return wrap_typed_user_defined_metric<i8_t>(kind, signature, metric_uintptr, scalar_kind, dimensions);
148
148
  case scalar_kind_t::f16_k:
149
149
  return wrap_typed_user_defined_metric<f16_t>(kind, signature, metric_uintptr, scalar_kind, dimensions);
150
150
  case scalar_kind_t::f32_k:
@@ -273,7 +273,7 @@ static void add_many_to_index( //
273
273
  // clang-format off
274
274
  switch (numpy_string_to_kind(vectors_info.format)) {
275
275
  case scalar_kind_t::b1x8_k: add_typed_to_index<b1x8_t>(index, keys_info, vectors_info, force_copy, threads); break;
276
- case scalar_kind_t::i8_k: add_typed_to_index<i8_bits_t>(index, keys_info, vectors_info, force_copy, threads); break;
276
+ case scalar_kind_t::i8_k: add_typed_to_index<i8_t>(index, keys_info, vectors_info, force_copy, threads); break;
277
277
  case scalar_kind_t::f16_k: add_typed_to_index<f16_t>(index, keys_info, vectors_info, force_copy, threads); break;
278
278
  case scalar_kind_t::f32_k: add_typed_to_index<f32_t>(index, keys_info, vectors_info, force_copy, threads); break;
279
279
  case scalar_kind_t::f64_k: add_typed_to_index<f64_t>(index, keys_info, vectors_info, force_copy, threads); break;
@@ -442,7 +442,7 @@ static py::tuple search_many_in_index( //
442
442
  // clang-format off
443
443
  switch (numpy_string_to_kind(vectors_info.format)) {
444
444
  case scalar_kind_t::b1x8_k: search_typed<b1x8_t>(index, vectors_info, wanted, exact, threads, keys_py, distances_py, counts_py, stats_visited_members, stats_computed_distances); break;
445
- case scalar_kind_t::i8_k: search_typed<i8_bits_t>(index, vectors_info, wanted, exact, threads, keys_py, distances_py, counts_py, stats_visited_members, stats_computed_distances); break;
445
+ case scalar_kind_t::i8_k: search_typed<i8_t>(index, vectors_info, wanted, exact, threads, keys_py, distances_py, counts_py, stats_visited_members, stats_computed_distances); break;
446
446
  case scalar_kind_t::f16_k: search_typed<f16_t>(index, vectors_info, wanted, exact, threads, keys_py, distances_py, counts_py, stats_visited_members, stats_computed_distances); break;
447
447
  case scalar_kind_t::f32_k: search_typed<f32_t>(index, vectors_info, wanted, exact, threads, keys_py, distances_py, counts_py, stats_visited_members, stats_computed_distances); break;
448
448
  case scalar_kind_t::f64_k: search_typed<f64_t>(index, vectors_info, wanted, exact, threads, keys_py, distances_py, counts_py, stats_visited_members, stats_computed_distances); break;
@@ -561,7 +561,7 @@ static py::tuple search_many_brute_force( //
561
561
  // clang-format off
562
562
  switch (dataset_kind) {
563
563
  case scalar_kind_t::b1x8_k: search_typed_brute_force<b1x8_t>(dataset_info, queries_info, wanted, threads, metric, keys_py, distances_py, counts_py); break;
564
- case scalar_kind_t::i8_k: search_typed_brute_force<i8_bits_t>(dataset_info, queries_info, wanted, threads, metric, keys_py, distances_py, counts_py); break;
564
+ case scalar_kind_t::i8_k: search_typed_brute_force<i8_t>(dataset_info, queries_info, wanted, threads, metric, keys_py, distances_py, counts_py); break;
565
565
  case scalar_kind_t::f16_k: search_typed_brute_force<f16_t>(dataset_info, queries_info, wanted, threads, metric, keys_py, distances_py, counts_py); break;
566
566
  case scalar_kind_t::f32_k: search_typed_brute_force<f32_t>(dataset_info, queries_info, wanted, threads, metric, keys_py, distances_py, counts_py); break;
567
567
  case scalar_kind_t::f64_k: search_typed_brute_force<f64_t>(dataset_info, queries_info, wanted, threads, metric, keys_py, distances_py, counts_py); break;
@@ -638,7 +638,7 @@ static py::tuple cluster_vectors( //
638
638
  // clang-format off
639
639
  switch (numpy_string_to_kind(queries_info.format)) {
640
640
  case scalar_kind_t::b1x8_k: cluster_result = index.cluster(queries_begin.as<b1x8_t const>(), queries_end.as<b1x8_t const>(), config, keys_ptr, distances_ptr, executor); break;
641
- case scalar_kind_t::i8_k: cluster_result = index.cluster(queries_begin.as<i8_bits_t const>(), queries_end.as<i8_bits_t const>(), config, keys_ptr, distances_ptr, executor); break;
641
+ case scalar_kind_t::i8_k: cluster_result = index.cluster(queries_begin.as<i8_t const>(), queries_end.as<i8_t const>(), config, keys_ptr, distances_ptr, executor); break;
642
642
  case scalar_kind_t::f16_k: cluster_result = index.cluster(queries_begin.as<f16_t const>(), queries_end.as<f16_t const>(), config, keys_ptr, distances_ptr, executor); break;
643
643
  case scalar_kind_t::f32_k: cluster_result = index.cluster(queries_begin.as<f32_t const>(), queries_end.as<f32_t const>(), config, keys_ptr, distances_ptr, executor); break;
644
644
  case scalar_kind_t::f64_k: cluster_result = index.cluster(queries_begin.as<f64_t const>(), queries_end.as<f64_t const>(), config, keys_ptr, distances_ptr, executor); break;
@@ -876,7 +876,7 @@ template <typename index_at> py::tuple get_many(index_at const& index, py::buffe
876
876
  else if (scalar_kind == scalar_kind_t::f16_k)
877
877
  return get_typed_vectors_for_keys<f16_t, std::uint16_t>(index, keys);
878
878
  else if (scalar_kind == scalar_kind_t::i8_k)
879
- return get_typed_vectors_for_keys<i8_bits_t, std::int8_t>(index, keys);
879
+ return get_typed_vectors_for_keys<i8_t, std::int8_t>(index, keys);
880
880
  else if (scalar_kind == scalar_kind_t::b1x8_k)
881
881
  return get_typed_vectors_for_keys<b1x8_t, std::uint8_t>(index, keys);
882
882
  else
package/rust/lib.cpp CHANGED
@@ -9,9 +9,35 @@ using add_result_t = typename index_t::add_result_t;
9
9
  using search_result_t = typename index_t::search_result_t;
10
10
  using labeling_result_t = typename index_t::labeling_result_t;
11
11
 
12
+ template <typename scalar_at> Matches search_(index_dense_t& index, scalar_at const* vec, size_t count) {
13
+ Matches matches;
14
+ matches.keys.reserve(count);
15
+ matches.distances.reserve(count);
16
+ for (size_t i = 0; i != count; ++i)
17
+ matches.keys.push_back(0), matches.distances.push_back(0);
18
+ search_result_t result = index.search(vec, count);
19
+ result.error.raise();
20
+ count = result.dump_to(matches.keys.data(), matches.distances.data());
21
+ matches.keys.truncate(count);
22
+ matches.distances.truncate(count);
23
+ return matches;
24
+ }
25
+
12
26
  Index::Index(std::unique_ptr<index_t> index) : index_(std::move(index)) {}
13
27
 
14
- void Index::add(key_t key, rust::Slice<float const> vector) const { index_->add(key, vector.data()).error.raise(); }
28
+ // clang-format off
29
+ void Index::add(key_t key, rust::Slice<float const> vec) const { index_->add(key, vec.data()).error.raise(); }
30
+ void Index::add_i8(key_t key, rust::Slice<int8_t const> vec) const { index_->add(key, vec.data()).error.raise(); }
31
+ void Index::add_f16(key_t key, rust::Slice<uint16_t const> vec) const { index_->add(key, (f16_t const*)vec.data()).error.raise(); }
32
+ void Index::add_f32(key_t key, rust::Slice<float const> vec) const { index_->add(key, vec.data()).error.raise(); }
33
+ void Index::add_f64(key_t key, rust::Slice<double const> vec) const { index_->add(key, vec.data()).error.raise(); }
34
+
35
+ Matches Index::search(rust::Slice<float const> vec, size_t count) const { return search_(*index_, vec.data(), count); }
36
+ Matches Index::search_i8(rust::Slice<int8_t const> vec, size_t count) const { return search_(*index_, vec.data(), count); }
37
+ Matches Index::search_f16(rust::Slice<uint16_t const> vec, size_t count) const { return search_(*index_, (f16_t const*)vec.data(), count); }
38
+ Matches Index::search_f32(rust::Slice<float const> vec, size_t count) const { return search_(*index_, vec.data(), count); }
39
+ Matches Index::search_f64(rust::Slice<double const> vec, size_t count) const { return search_(*index_, vec.data(), count); }
40
+ // clang-format on
15
41
 
16
42
  bool Index::remove(key_t key) const {
17
43
  labeling_result_t result = index_->remove(key);
@@ -27,20 +53,6 @@ bool Index::rename(key_t from, key_t to) const {
27
53
 
28
54
  bool Index::contains(key_t key) const { return index_->contains(key); }
29
55
 
30
- Matches Index::search(rust::Slice<float const> vector, size_t count) const {
31
- Matches matches;
32
- matches.keys.reserve(count);
33
- matches.distances.reserve(count);
34
- for (size_t i = 0; i != count; ++i)
35
- matches.keys.push_back(0), matches.distances.push_back(0);
36
- search_result_t result = index_->search(vector.data(), count);
37
- result.error.raise();
38
- count = result.dump_to(matches.keys.data(), matches.distances.data());
39
- matches.keys.truncate(count);
40
- matches.distances.truncate(count);
41
- return matches;
42
- }
43
-
44
56
  void Index::reserve(size_t capacity) const { index_->reserve(capacity); }
45
57
 
46
58
  size_t Index::dimensions() const { return index_->dimensions(); }
package/rust/lib.hpp CHANGED
@@ -22,7 +22,16 @@ class Index {
22
22
  void reserve(size_t) const;
23
23
 
24
24
  void add(key_t key, rust::Slice<float const> vector) const;
25
+ void add_i8(key_t key, rust::Slice<int8_t const> vector) const;
26
+ void add_f16(key_t key, rust::Slice<uint16_t const> vector) const;
27
+ void add_f32(key_t key, rust::Slice<float const> vector) const;
28
+ void add_f64(key_t key, rust::Slice<double const> vector) const;
29
+
25
30
  Matches search(rust::Slice<float const> vector, size_t count) const;
31
+ Matches search_i8(rust::Slice<int8_t const> vector, size_t count) const;
32
+ Matches search_f16(rust::Slice<uint16_t const> vector, size_t count) const;
33
+ Matches search_f32(rust::Slice<float const> vector, size_t count) const;
34
+ Matches search_f64(rust::Slice<double const> vector, size_t count) const;
26
35
 
27
36
  bool remove(key_t key) const;
28
37
  bool contains(key_t key) const;
package/rust/lib.rs CHANGED
@@ -83,6 +83,11 @@ pub mod ffi {
83
83
  /// * `vector` - A slice containing the vector data.
84
84
  pub fn add(self: &Index, key: u64, vector: &[f32]) -> Result<()>;
85
85
 
86
+ pub fn add_i8(self: &Index, key: u64, vector: &[i8]) -> Result<()>;
87
+ pub fn add_f16(self: &Index, key: u64, vector: &[u16]) -> Result<()>;
88
+ pub fn add_f32(self: &Index, key: u64, vector: &[f32]) -> Result<()>;
89
+ pub fn add_f64(self: &Index, key: u64, vector: &[f64]) -> Result<()>;
90
+
86
91
  /// Performs k-Approximate Nearest Neighbors (kANN) Search for closest vectors to the provided query.
87
92
  ///
88
93
  /// # Arguments
@@ -95,6 +100,11 @@ pub mod ffi {
95
100
  /// A `Result` containing the matches found.
96
101
  pub fn search(self: &Index, query: &[f32], count: usize) -> Result<Matches>;
97
102
 
103
+ pub fn search_i8(self: &Index, query: &[i8], count: usize) -> Result<Matches>;
104
+ pub fn search_f16(self: &Index, query: &[u16], count: usize) -> Result<Matches>;
105
+ pub fn search_f32(self: &Index, query: &[f32], count: usize) -> Result<Matches>;
106
+ pub fn search_f64(self: &Index, query: &[f64], count: usize) -> Result<Matches>;
107
+
98
108
  /// Removes the vector associated with the given key from the index.
99
109
  ///
100
110
  /// # Arguments
package/wasmer.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name="unum/usearch"
3
- version="1.3.0"
3
+ version="2.0.1"
4
4
  description="Smaller & Faster Single-File Vector Search Engine from Unum"
5
5
  license="Apache-2.0"
6
6
  readme="README.md"