usearch 0.14.0 → 0.15.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.
- package/.github/workflows/release.yml +56 -4
- package/.github/workflows/update_version.sh +6 -1
- package/.vscode/launch.json +21 -22
- package/.vscode/settings.json +7 -1
- package/CITATION.cff +4 -4
- package/CMakeLists.txt +1 -1
- package/Cargo.toml +1 -1
- package/Package.swift +0 -1
- package/README.md +100 -27
- package/binding.gyp +0 -1
- package/build.gradle +1 -1
- package/build.rs +3 -3
- package/c/lib.cpp +32 -9
- package/c/usearch.h +67 -36
- package/conanfile.py +1 -1
- package/{src → cpp}/bench.cpp +52 -36
- package/{src → cpp}/test.cpp +17 -7
- package/docs/benchmarks.md +33 -10
- package/docs/c/index.rst +11 -0
- package/docs/c/reference.rst +7 -0
- package/docs/compilation.md +24 -9
- package/docs/conf.dox +6 -6
- package/docs/conf.py +3 -1
- package/docs/cpp/index.rst +11 -0
- package/docs/cpp/reference.rst +7 -0
- package/docs/index.rst +10 -0
- package/docs/java/index.rst +11 -0
- package/docs/java/reference.rst +7 -0
- package/docs/javascript/index.rst +11 -0
- package/docs/javascript/reference.rst +9 -0
- package/docs/python/index.rst +11 -0
- package/docs/python/reference.rst +35 -0
- package/golang/lib.go +1 -1
- package/include/usearch/{usearch.hpp → index.hpp} +152 -148
- package/include/usearch/index_punned_dense.hpp +633 -0
- package/include/usearch/index_punned_helpers.hpp +528 -0
- package/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp +8 -7
- package/javascript/lib.cpp +26 -50
- package/javascript/usearch.js +117 -2
- package/objc/USearchObjective.mm +145 -49
- package/objc/include/USearchObjective.h +106 -30
- package/package.json +2 -2
- package/python/lib.cpp +134 -331
- package/python/scripts/bench.ipynb +170 -0
- package/python/scripts/bench.py +87 -175
- package/python/scripts/index_faiss.py +100 -0
- package/python/scripts/test.py +41 -37
- package/python/usearch/eval.py +353 -0
- package/python/usearch/index.py +117 -113
- package/python/usearch/io.py +7 -2
- package/python/usearch/join.py +100 -0
- package/python/usearch/numba.py +101 -0
- package/rust/lib.cpp +27 -14
- package/rust/lib.hpp +4 -10
- package/rust/lib.rs +50 -17
- package/setup.py +12 -2
- package/simsimd/include/simsimd/simsimd.h +32 -3
- package/swift/Index+Sugar.swift +55 -29
- package/swift/Test.swift +1 -1
- package/wolfram/lib.cpp +4 -4
- package/python/scripts/bench_params.py +0 -201
- package/python/usearch/synthetic.py +0 -31
- package/src/punned.hpp +0 -906
- /package/{src → cpp}/CMakeLists.txt +0 -0
package/conanfile.py
CHANGED
|
@@ -4,7 +4,7 @@ from conans import ConanFile
|
|
|
4
4
|
class USearchConan(ConanFile):
|
|
5
5
|
|
|
6
6
|
name = 'USearch'
|
|
7
|
-
version = '0.
|
|
7
|
+
version = '0.15.1'
|
|
8
8
|
license = 'Apache 2.0'
|
|
9
9
|
url = 'https://github.com/unum-cloud/usearch'
|
|
10
10
|
description = 'Smaller & Faster Single-File Vector Search Engine from Unum'
|
package/{src → cpp}/bench.cpp
RENAMED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
#include <simsimd/simsimd.h>
|
|
40
40
|
|
|
41
|
-
#include
|
|
41
|
+
#include <usearch/index_punned_dense.hpp>
|
|
42
42
|
|
|
43
43
|
using namespace unum::usearch;
|
|
44
44
|
using namespace unum;
|
|
@@ -432,46 +432,58 @@ struct args_t {
|
|
|
432
432
|
|
|
433
433
|
bool big = false;
|
|
434
434
|
bool native = false;
|
|
435
|
+
|
|
435
436
|
bool quantize_f16 = false;
|
|
436
437
|
bool quantize_f8 = false;
|
|
438
|
+
bool quantize_b1 = false;
|
|
437
439
|
|
|
438
440
|
bool metric_ip = false;
|
|
439
441
|
bool metric_l2 = false;
|
|
440
442
|
bool metric_cos = false;
|
|
441
443
|
bool metric_haversine = false;
|
|
442
|
-
|
|
444
|
+
bool metric_hamming = false;
|
|
445
|
+
bool metric_tanimoto = false;
|
|
446
|
+
bool metric_sorensen = false;
|
|
447
|
+
|
|
448
|
+
metric_kind_t metric() const noexcept {
|
|
449
|
+
if (metric_l2)
|
|
450
|
+
return metric_kind_t::l2sq_k;
|
|
451
|
+
if (metric_cos)
|
|
452
|
+
return metric_kind_t::cos_k;
|
|
453
|
+
if (metric_haversine)
|
|
454
|
+
return metric_kind_t::haversine_k;
|
|
455
|
+
if (metric_hamming)
|
|
456
|
+
return metric_kind_t::hamming_k;
|
|
457
|
+
if (metric_tanimoto)
|
|
458
|
+
return metric_kind_t::tanimoto_k;
|
|
459
|
+
if (metric_sorensen)
|
|
460
|
+
return metric_kind_t::sorensen_k;
|
|
461
|
+
return metric_kind_t::ip_k;
|
|
462
|
+
}
|
|
443
463
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
return
|
|
452
|
-
} else if (args.metric_haversine) {
|
|
453
|
-
std::printf("-- Metric: Haversine\n");
|
|
454
|
-
return index_at::haversine(accuracy, config);
|
|
455
|
-
} else {
|
|
456
|
-
std::printf("-- Metric: Inner Product\n");
|
|
457
|
-
return index_at::ip(dataset.dimensions(), accuracy, config);
|
|
464
|
+
scalar_kind_t accuracy() const noexcept {
|
|
465
|
+
if (quantize_f16)
|
|
466
|
+
return scalar_kind_t::f16_k;
|
|
467
|
+
if (quantize_f8)
|
|
468
|
+
return scalar_kind_t::f8_k;
|
|
469
|
+
if (quantize_b1)
|
|
470
|
+
return scalar_kind_t::b1x8_k;
|
|
471
|
+
return scalar_kind_t::f32_k;
|
|
458
472
|
}
|
|
459
|
-
}
|
|
473
|
+
};
|
|
460
474
|
|
|
461
475
|
template <typename index_at, typename dataset_at> //
|
|
462
476
|
void run_punned(dataset_at& dataset, args_t const& args, index_config_t config, index_limits_t limits) {
|
|
463
477
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
accuracy = accuracy_t::f16_k;
|
|
467
|
-
if (args.quantize_f8)
|
|
468
|
-
accuracy = accuracy_t::f8_k;
|
|
478
|
+
scalar_kind_t accuracy = args.accuracy();
|
|
479
|
+
std::printf("-- Accuracy: %s\n", scalar_kind_name(accuracy));
|
|
469
480
|
|
|
470
|
-
|
|
481
|
+
metric_kind_t kind = args.metric();
|
|
482
|
+
std::printf("-- Metric: %s\n", metric_kind_name(kind));
|
|
471
483
|
|
|
472
|
-
index_at index
|
|
484
|
+
index_at index = index_at::make(dataset.dimensions(), kind, config, accuracy);
|
|
473
485
|
index.reserve(limits);
|
|
474
|
-
std::printf("-- Hardware acceleration: %s\n", isa_name(index.
|
|
486
|
+
std::printf("-- Hardware acceleration: %s\n", isa_name(index.isa()));
|
|
475
487
|
std::printf("Will benchmark in-memory\n");
|
|
476
488
|
|
|
477
489
|
single_shot(dataset, index, true);
|
|
@@ -518,7 +530,7 @@ void run_big_or_small(dataset_at& dataset, args_t const& args, index_config_t co
|
|
|
518
530
|
run_typed<index_gt<ip_gt<float>, std::size_t, neighbor_id_at>>(dataset, args, config, limits);
|
|
519
531
|
}
|
|
520
532
|
} else
|
|
521
|
-
run_punned<
|
|
533
|
+
run_punned<index_punned_dense_gt<std::size_t, neighbor_id_at>>(dataset, args, config, limits);
|
|
522
534
|
}
|
|
523
535
|
|
|
524
536
|
void report_alternative_setups() {
|
|
@@ -537,8 +549,8 @@ void report_expected_losses(persisted_dataset_gt<float, vector_id_t> const& data
|
|
|
537
549
|
|
|
538
550
|
auto vec1 = dataset.vector(0);
|
|
539
551
|
auto vec2 = dataset.query(0);
|
|
540
|
-
std::vector<
|
|
541
|
-
std::vector<
|
|
552
|
+
std::vector<f16_t> vec1f16(dataset.dimensions());
|
|
553
|
+
std::vector<f16_t> vec2f16(dataset.dimensions());
|
|
542
554
|
std::transform(vec1, vec1 + dataset.dimensions(), vec1f16.data(), [](float v) { return v; });
|
|
543
555
|
std::transform(vec2, vec2 + dataset.dimensions(), vec2f16.data(), [](float v) { return v; });
|
|
544
556
|
std::vector<f8_bits_t> vec1f8(dataset.dimensions());
|
|
@@ -548,7 +560,7 @@ void report_expected_losses(persisted_dataset_gt<float, vector_id_t> const& data
|
|
|
548
560
|
|
|
549
561
|
#if 0
|
|
550
562
|
auto ip_default = ip_gt<float>{}(vec1, vec2, dataset.dimensions());
|
|
551
|
-
auto ip_f16 = ip_gt<
|
|
563
|
+
auto ip_f16 = ip_gt<f16_t, float>{}(vec1f16.data(), vec2f16.data(), dataset.dimensions());
|
|
552
564
|
auto ip_f8 = ip_gt<f8_bits_t, float>{}(vec1f8.data(), vec2f8.data(), dataset.dimensions());
|
|
553
565
|
|
|
554
566
|
#if defined(__AVX512F__)
|
|
@@ -591,12 +603,16 @@ int main(int argc, char** argv) {
|
|
|
591
603
|
(option("--rows-take") & value("integer", args.vectors_to_take)).doc("Number of vectors to take"),
|
|
592
604
|
( //
|
|
593
605
|
option("--native").set(args.native).doc("Use raw templates instead of type-punned classes") |
|
|
594
|
-
option("--f16quant").set(args.quantize_f16).doc("Enable `f16_t` quantization") |
|
|
595
|
-
option("--f8quant").set(args.quantize_f8).doc("Enable `f8_t` quantization")
|
|
606
|
+
option("-f16", "--f16quant").set(args.quantize_f16).doc("Enable `f16_t` quantization") |
|
|
607
|
+
option("-f8", "--f8quant").set(args.quantize_f8).doc("Enable `f8_t` quantization") |
|
|
608
|
+
option("-b1", "--b1quant").set(args.quantize_b1).doc("Enable `b1x8_t` quantization")),
|
|
596
609
|
( //
|
|
597
610
|
option("--ip").set(args.metric_ip).doc("Choose Inner Product metric") |
|
|
598
611
|
option("--l2sq").set(args.metric_l2).doc("Choose L2 Euclidean metric") |
|
|
599
612
|
option("--cos").set(args.metric_cos).doc("Choose Angular metric") |
|
|
613
|
+
option("--hamming").set(args.metric_hamming).doc("Choose Hamming metric") |
|
|
614
|
+
option("--tanimoto").set(args.metric_tanimoto).doc("Choose Tanimoto metric") |
|
|
615
|
+
option("--sorensen").set(args.metric_sorensen).doc("Choose Sorensen metric") |
|
|
600
616
|
option("--haversine").set(args.metric_haversine).doc("Choose Haversine metric")),
|
|
601
617
|
option("-h", "--help").set(args.help).doc("Print this help information on this tool and exit"));
|
|
602
618
|
|
|
@@ -609,7 +625,7 @@ int main(int argc, char** argv) {
|
|
|
609
625
|
exit(0);
|
|
610
626
|
}
|
|
611
627
|
|
|
612
|
-
// Instead of relying on `multithreaded` from "
|
|
628
|
+
// Instead of relying on `multithreaded` from "index_punned_dense.hpp" we will use OpenMP
|
|
613
629
|
// to better estimate statistics between tasks batches, without having to recreate
|
|
614
630
|
// the threads.
|
|
615
631
|
omp_set_dynamic(true);
|
|
@@ -638,16 +654,16 @@ int main(int argc, char** argv) {
|
|
|
638
654
|
|
|
639
655
|
index_config_t config;
|
|
640
656
|
config.connectivity = args.connectivity;
|
|
641
|
-
config.expansion_add = args.expansion_add;
|
|
642
|
-
config.expansion_search = args.expansion_search;
|
|
657
|
+
// config.expansion_add = args.expansion_add;
|
|
658
|
+
// config.expansion_search = args.expansion_search;
|
|
643
659
|
index_limits_t limits;
|
|
644
660
|
limits.threads_add = limits.threads_search = args.threads;
|
|
645
661
|
limits.elements = dataset.vectors_count();
|
|
646
662
|
|
|
647
663
|
std::printf("- Index: \n");
|
|
648
664
|
std::printf("-- Connectivity: %zu\n", config.connectivity);
|
|
649
|
-
std::printf("-- Expansion @ Add: %zu\n", config.expansion_add);
|
|
650
|
-
std::printf("-- Expansion @ Search: %zu\n", config.expansion_search);
|
|
665
|
+
// std::printf("-- Expansion @ Add: %zu\n", config.expansion_add);
|
|
666
|
+
// std::printf("-- Expansion @ Search: %zu\n", config.expansion_search);
|
|
651
667
|
|
|
652
668
|
if (args.big)
|
|
653
669
|
run_big_or_small<uint40_t>(dataset, args, config, limits);
|
package/{src → cpp}/test.cpp
RENAMED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
#include <algorithm>
|
|
5
5
|
#include <stdexcept>
|
|
6
6
|
|
|
7
|
-
#include
|
|
7
|
+
#include <usearch/index_punned_dense.hpp>
|
|
8
8
|
|
|
9
9
|
using namespace unum::usearch;
|
|
10
10
|
using namespace unum;
|
|
@@ -134,20 +134,30 @@ template <typename index_at> void test_sets_moved() {
|
|
|
134
134
|
|
|
135
135
|
int main(int, char**) {
|
|
136
136
|
|
|
137
|
+
static_assert(!std::is_same<index_gt<ip_gt<>>::value_type, std::true_type>());
|
|
138
|
+
static_assert(!std::is_same<index_gt<cos_gt<>>::value_type, std::true_type>());
|
|
139
|
+
static_assert(!std::is_same<index_gt<l2sq_gt<>>::value_type, std::true_type>());
|
|
140
|
+
// static_assert(!std::is_same<index_gt<hamming_gt<>>::value_type, std::true_type>());
|
|
141
|
+
// static_assert(!std::is_same<index_gt<tanimoto_gt<>>::value_type, std::true_type>());
|
|
142
|
+
// static_assert(!std::is_same<index_gt<sorensen_gt<>>::value_type, std::true_type>());
|
|
143
|
+
// static_assert(!std::is_same<index_gt<jaccard_gt<>>::value_type, std::true_type>());
|
|
144
|
+
// static_assert(!std::is_same<index_gt<pearson_correlation_gt<>>::value_type, std::true_type>());
|
|
145
|
+
// static_assert(!std::is_same<index_gt<haversine_gt<>>::value_type, std::true_type>());
|
|
146
|
+
|
|
137
147
|
test3d<float>(index_gt<cos_gt<float>, point_id_t, std::uint32_t, float>{});
|
|
138
148
|
test3d<float>(index_gt<l2sq_gt<float>, point_id_t, std::uint32_t, float>{});
|
|
139
149
|
|
|
140
150
|
test3d<double>(index_gt<cos_gt<double>, point_id_t, std::uint32_t, double>{});
|
|
141
151
|
test3d<double>(index_gt<l2sq_gt<double>, point_id_t, std::uint32_t, double>{});
|
|
142
152
|
|
|
143
|
-
test3d<float>(punned_small_t::
|
|
144
|
-
test3d<float>(punned_small_t::
|
|
153
|
+
test3d<float>(punned_small_t::make(3, metric_kind_t::cos_k));
|
|
154
|
+
test3d<float>(punned_small_t::make(3, metric_kind_t::l2sq_k));
|
|
145
155
|
|
|
146
|
-
test3d<double>(punned_small_t::
|
|
147
|
-
test3d<double>(punned_small_t::
|
|
156
|
+
test3d<double>(punned_small_t::make(3, metric_kind_t::cos_k));
|
|
157
|
+
test3d<double>(punned_small_t::make(3, metric_kind_t::l2sq_k));
|
|
148
158
|
|
|
149
|
-
test3d_punned<float>(punned_small_t::
|
|
150
|
-
test3d_punned<float>(punned_small_t::
|
|
159
|
+
test3d_punned<float>(punned_small_t::make(3, metric_kind_t::cos_k));
|
|
160
|
+
test3d_punned<float>(punned_small_t::make(3, metric_kind_t::l2sq_k));
|
|
151
161
|
|
|
152
162
|
test_sets(index_gt<jaccard_gt<std::int32_t, float>, point_id_t, std::uint32_t, std::int32_t>{});
|
|
153
163
|
test_sets(index_gt<jaccard_gt<std::int64_t, float>, point_id_t, std::uint32_t, std::int64_t>{});
|
package/docs/benchmarks.md
CHANGED
|
@@ -55,7 +55,7 @@ Also worth noting, 8-bit quantization results in almost no accuracy loss and may
|
|
|
55
55
|
|
|
56
56
|
Within this repository you will find two commonly used utilities:
|
|
57
57
|
|
|
58
|
-
- `
|
|
58
|
+
- `cpp/bench.cpp` the produces the `bench` binary for broad USearch benchmarks.
|
|
59
59
|
- `python/bench.py` for simple benchmarks against FAISS.
|
|
60
60
|
|
|
61
61
|
To achieve best highest results we suggest compiling locally for the target architecture.
|
|
@@ -170,15 +170,6 @@ mkdir -p datasets/deep_1B/ && \
|
|
|
170
170
|
|
|
171
171
|
## Profiling
|
|
172
172
|
|
|
173
|
-
Enabling Huge Pages:
|
|
174
|
-
|
|
175
|
-
```sh
|
|
176
|
-
sudo cat /proc/sys/vm/nr_hugepages
|
|
177
|
-
sudo sysctl -w vm.nr_hugepages=2048
|
|
178
|
-
sudo reboot
|
|
179
|
-
sudo cat /proc/sys/vm/nr_hugepages
|
|
180
|
-
```
|
|
181
|
-
|
|
182
173
|
With `perf`:
|
|
183
174
|
|
|
184
175
|
```sh
|
|
@@ -189,3 +180,35 @@ sudo -E perf mem -d ./build_release/bench ...
|
|
|
189
180
|
sudo -E perf record -F 1000 ./build_release/bench ...
|
|
190
181
|
perf record -d -e arm_spe// -- ./build_release/bench ..
|
|
191
182
|
```
|
|
183
|
+
|
|
184
|
+
### Caches
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
sudo perf stat -e 'faults,dTLB-loads,dTLB-load-misses,cache-misses,cache-references' ./build_release/bench ...
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Typical output on a 1M vectors dataset is:
|
|
191
|
+
|
|
192
|
+
```txt
|
|
193
|
+
255426 faults
|
|
194
|
+
305988813388 dTLB-loads
|
|
195
|
+
8845723783 dTLB-load-misses # 2.89% of all dTLB cache accesses
|
|
196
|
+
20094264206 cache-misses # 6.567 % of all cache refs
|
|
197
|
+
305988812745 cache-references
|
|
198
|
+
|
|
199
|
+
8.285148010 seconds time elapsed
|
|
200
|
+
|
|
201
|
+
500.705967000 seconds user
|
|
202
|
+
1.371118000 seconds sys
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
If you notice problems and the stalls are closer to 90%, it might be a good reason to consider enabling Huge Pages and tuning allocations alignment.
|
|
206
|
+
To enable Huge Pages:
|
|
207
|
+
|
|
208
|
+
```sh
|
|
209
|
+
sudo cat /proc/sys/vm/nr_hugepages
|
|
210
|
+
sudo sysctl -w vm.nr_hugepages=2048
|
|
211
|
+
sudo reboot
|
|
212
|
+
sudo cat /proc/sys/vm/nr_hugepages
|
|
213
|
+
```
|
|
214
|
+
|
package/docs/c/index.rst
ADDED
package/docs/compilation.md
CHANGED
|
@@ -41,7 +41,10 @@ cmake -B ./build_release \
|
|
|
41
41
|
Linting:
|
|
42
42
|
|
|
43
43
|
```sh
|
|
44
|
-
cppcheck --enable=all --suppress=cstyleCast --suppress=unusedFunction
|
|
44
|
+
cppcheck --enable=all --suppress=cstyleCast --suppress=unusedFunction \
|
|
45
|
+
include/usearch/index.hpp \
|
|
46
|
+
include/index_punned_dense.hpp \
|
|
47
|
+
include/index_punned_helpers.hpp
|
|
45
48
|
```
|
|
46
49
|
|
|
47
50
|
Benchmarking:
|
|
@@ -81,7 +84,7 @@ Benchmarking:
|
|
|
81
84
|
|
|
82
85
|
```sh
|
|
83
86
|
pip install faiss-cpu
|
|
84
|
-
python python/scripts/bench.py \
|
|
87
|
+
python python/scripts/bench.py speed \
|
|
85
88
|
--vectors datasets/wiki_1M/base.1M.fbin \
|
|
86
89
|
--queries datasets/wiki_1M/query.public.100K.fbin \
|
|
87
90
|
--neighbors datasets/wiki_1M/groundtruth.public.100K.ibin
|
|
@@ -92,9 +95,8 @@ python python/scripts/bench.py \
|
|
|
92
95
|
Checking the effect of different embedding dimensions on construction speed:
|
|
93
96
|
|
|
94
97
|
```sh
|
|
95
|
-
python python/scripts/
|
|
96
|
-
python python/scripts/
|
|
97
|
-
python python/scripts/bench_params.py robustness
|
|
98
|
+
python python/scripts/bench.py dimensions ...
|
|
99
|
+
python python/scripts/bench.py connectivity ...
|
|
98
100
|
```
|
|
99
101
|
|
|
100
102
|
## JavaScript
|
|
@@ -115,7 +117,7 @@ cargo publish
|
|
|
115
117
|
|
|
116
118
|
```sh
|
|
117
119
|
gradle clean build
|
|
118
|
-
java -cp . -Djava.library.path
|
|
120
|
+
java -cp . -Djava.library.path="$(pwd)/build/libs/usearch/shared" java/cloud/unum/usearch/Index.java
|
|
119
121
|
```
|
|
120
122
|
|
|
121
123
|
Or step by-step:
|
|
@@ -135,15 +137,14 @@ g++ -shared -o USearchJNI.dll cloud_unum_usearch_Index.o -Wl,--add-stdcall-alias
|
|
|
135
137
|
# MacOS
|
|
136
138
|
g++ -std=c++11 -c -fPIC \
|
|
137
139
|
-I../../../../include \
|
|
138
|
-
-I../../../../src \
|
|
139
140
|
-I../../../../fp16/include \
|
|
140
141
|
-I../../../../robin-map/include \
|
|
141
142
|
-I../../../../simsimd/include \
|
|
142
143
|
-I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin cloud_unum_usearch_Index.cpp -o cloud_unum_usearch_Index.o
|
|
143
144
|
g++ -dynamiclib -o libusearch.dylib cloud_unum_usearch_Index.o -lc
|
|
144
145
|
# Run linking to that directory
|
|
145
|
-
java -cp . -Djava.library.path
|
|
146
|
-
java -cp . -Djava.library.path
|
|
146
|
+
java -cp . -Djava.library.path="$(pwd)/java/cloud/unum/usearch/" Index.java
|
|
147
|
+
java -cp . -Djava.library.path="$(pwd)/java" cloud.unum.usearch.Index
|
|
147
148
|
```
|
|
148
149
|
|
|
149
150
|
## Wolfram
|
|
@@ -159,6 +160,12 @@ cd golang
|
|
|
159
160
|
go test -v
|
|
160
161
|
```
|
|
161
162
|
|
|
163
|
+
## Objective-C and Swift
|
|
164
|
+
|
|
165
|
+
```sh
|
|
166
|
+
swift build
|
|
167
|
+
```
|
|
168
|
+
|
|
162
169
|
## C
|
|
163
170
|
|
|
164
171
|
### Linux
|
|
@@ -186,4 +193,12 @@ docker buildx create --use &&
|
|
|
186
193
|
--tag unum/usearch:$version \
|
|
187
194
|
--tag unum/usearch:latest \
|
|
188
195
|
--push .
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
Extending metrics in SimSIMD:
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
git push --set-upstream https://github.com/ashvardanian/simsimd.git HEAD:main
|
|
189
204
|
```
|
package/docs/conf.dox
CHANGED
|
@@ -872,7 +872,7 @@ WARN_LOGFILE =
|
|
|
872
872
|
# - Testing
|
|
873
873
|
# - Benchmarks
|
|
874
874
|
|
|
875
|
-
INPUT = ../include/usearch
|
|
875
|
+
INPUT = ../include/usearch ../c/usearch.h ../java/cloud/unum/usearch/Index.java
|
|
876
876
|
|
|
877
877
|
# This tag can be used to specify the character encoding of the source files
|
|
878
878
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
|
@@ -1290,9 +1290,9 @@ HTML_STYLESHEET =
|
|
|
1290
1290
|
# list). For an example see the documentation.
|
|
1291
1291
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
|
1292
1292
|
|
|
1293
|
-
HTML_EXTRA_STYLESHEET =
|
|
1294
|
-
|
|
1295
|
-
|
|
1293
|
+
HTML_EXTRA_STYLESHEET =
|
|
1294
|
+
|
|
1295
|
+
|
|
1296
1296
|
|
|
1297
1297
|
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
|
|
1298
1298
|
# other source files which should be copied to the HTML output directory. Note
|
|
@@ -1302,8 +1302,8 @@ HTML_EXTRA_STYLESHEET = doxygen-awesome-css/doxygen-awesome.css \
|
|
|
1302
1302
|
# files will be copied as-is; there are no commands or markers available.
|
|
1303
1303
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
|
1304
1304
|
|
|
1305
|
-
HTML_EXTRA_FILES =
|
|
1306
|
-
|
|
1305
|
+
HTML_EXTRA_FILES =
|
|
1306
|
+
|
|
1307
1307
|
|
|
1308
1308
|
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
|
1309
1309
|
# will adjust the colors in the style sheet and background images according to
|
package/docs/conf.py
CHANGED
|
@@ -21,7 +21,7 @@ with open('_static/custom.js', 'r+') as js:
|
|
|
21
21
|
|
|
22
22
|
extensions = [
|
|
23
23
|
'breathe', 'm2r2',
|
|
24
|
-
'sphinx.ext.autodoc',
|
|
24
|
+
'sphinx.ext.autodoc', 'sphinx_js',
|
|
25
25
|
'sphinx.ext.autosummary',
|
|
26
26
|
'sphinx.ext.intersphinx',
|
|
27
27
|
'sphinx.ext.napoleon',
|
|
@@ -46,3 +46,5 @@ html_baseurl = '/docs/usearch/'
|
|
|
46
46
|
|
|
47
47
|
breathe_projects = {'USearch': '../build/xml'}
|
|
48
48
|
breathe_default_project = 'USearch'
|
|
49
|
+
|
|
50
|
+
js_source_path = '../javascript/usearch.js'
|
package/docs/index.rst
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
API Reference
|
|
2
|
+
===============
|
|
3
|
+
|
|
4
|
+
======
|
|
5
|
+
Index
|
|
6
|
+
======
|
|
7
|
+
|
|
8
|
+
.. automodule:: usearch.index
|
|
9
|
+
:members:
|
|
10
|
+
:undoc-members:
|
|
11
|
+
|
|
12
|
+
======
|
|
13
|
+
IO
|
|
14
|
+
======
|
|
15
|
+
|
|
16
|
+
.. automodule:: usearch.io
|
|
17
|
+
:members:
|
|
18
|
+
:undoc-members:
|
|
19
|
+
|
|
20
|
+
======
|
|
21
|
+
Client
|
|
22
|
+
======
|
|
23
|
+
|
|
24
|
+
.. automodule:: usearch.client
|
|
25
|
+
:members:
|
|
26
|
+
:undoc-members:
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
======
|
|
30
|
+
Server
|
|
31
|
+
======
|
|
32
|
+
|
|
33
|
+
.. automodule:: usearch.server
|
|
34
|
+
:members:
|
|
35
|
+
:undoc-members:
|
package/golang/lib.go
CHANGED
|
@@ -118,7 +118,7 @@ func (ind *Index) Destroy() {
|
|
|
118
118
|
if ind.opaque_handle == nil {
|
|
119
119
|
panic("index not initialized")
|
|
120
120
|
}
|
|
121
|
-
C.
|
|
121
|
+
C.usearch_free(unsafe.Pointer(ind.opaque_handle))
|
|
122
122
|
ind.opaque_handle = nil
|
|
123
123
|
ind.config = IndexConfig{}
|
|
124
124
|
}
|