usearch 0.11.1 → 0.12.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/.github/workflows/prerelease.yml +1 -5
- package/.github/workflows/release.yml +22 -2
- package/.gitignore +84 -0
- package/.vscode/launch.json +7 -1
- package/.vscode/settings.json +15 -1
- package/Cargo.toml +1 -1
- package/README.md +42 -7
- package/binding.gyp +2 -2
- package/c/lib.cpp +141 -0
- package/c/usearch.h +43 -0
- package/conanfile.py +1 -1
- package/docs/compilation.md +14 -3
- package/golang/go.mod +3 -0
- package/golang/lib.go +238 -0
- package/golang/usearch.h +9 -0
- package/golang/usearch_par_test.go +40 -0
- package/golang/usearch_test.go +82 -0
- package/include/usearch/usearch.hpp +595 -248
- package/java/cloud/unum/usearch/Index.java +1 -1
- package/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp +36 -44
- package/javascript/lib.cpp +10 -6
- package/javascript/usearch.js +3 -0
- package/objc/USearchObjective.mm +3 -3
- package/package.json +4 -3
- package/pyproject.toml +1 -1
- package/python/lib.cpp +354 -181
- package/python/scripts/test.py +87 -28
- package/python/usearch/index.py +131 -56
- package/rust/lib.cpp +33 -24
- package/rust/lib.hpp +2 -2
- package/setup.py +4 -1
- package/src/CMakeLists.txt +4 -4
- package/src/bench.cpp +22 -19
- package/src/punned.hpp +108 -79
- package/src/test.cpp +77 -27
- package/wolfram/lib.cpp +7 -8
- package/Dockerfile +0 -16
- package/VERSION +0 -1
|
@@ -37,12 +37,8 @@ jobs:
|
|
|
37
37
|
pip install pytest numpy
|
|
38
38
|
- name: Build locally
|
|
39
39
|
run: python -m pip install .
|
|
40
|
-
- name: Test with PyTest
|
|
41
|
-
if: matrix.os != 'windows-2022'
|
|
40
|
+
- name: Test with PyTest
|
|
42
41
|
run: pytest python/scripts/test.py
|
|
43
|
-
- name: Test with PyTest on Windows
|
|
44
|
-
if: matrix.os == 'windows-2022'
|
|
45
|
-
run: pytest python\scripts\test.py
|
|
46
42
|
|
|
47
43
|
test_javascript:
|
|
48
44
|
name: Test JavaScript
|
|
@@ -11,7 +11,7 @@ env:
|
|
|
11
11
|
|
|
12
12
|
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
|
13
13
|
permissions:
|
|
14
|
-
contents:
|
|
14
|
+
contents: write
|
|
15
15
|
pages: write
|
|
16
16
|
id-token: write
|
|
17
17
|
|
|
@@ -27,13 +27,33 @@ jobs:
|
|
|
27
27
|
- uses: actions/setup-node@v3
|
|
28
28
|
- run: npm install --save-dev @semantic-release/exec @semantic-release/git conventional-changelog-eslint semantic-release && npx semantic-release
|
|
29
29
|
|
|
30
|
+
rebase:
|
|
31
|
+
name: Rebase from main into main-dev
|
|
32
|
+
needs: versioning
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
- name: Checkout the latest code
|
|
36
|
+
uses: actions/checkout@v3
|
|
37
|
+
with:
|
|
38
|
+
fetch-depth: 0
|
|
39
|
+
|
|
40
|
+
- name: Perform Rebase
|
|
41
|
+
run: |
|
|
42
|
+
git checkout main-dev
|
|
43
|
+
git rebase main
|
|
44
|
+
- name: Push changes
|
|
45
|
+
uses: ad-m/github-push-action@master
|
|
46
|
+
with:
|
|
47
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
48
|
+
branch: main-dev
|
|
49
|
+
|
|
30
50
|
build_wheels:
|
|
31
51
|
name: Build Wheels for ${{ matrix.os }}
|
|
32
52
|
needs: versioning
|
|
33
53
|
runs-on: ${{ matrix.os }}
|
|
34
54
|
strategy:
|
|
35
55
|
matrix:
|
|
36
|
-
os: [ubuntu-20.04, macOS-11]
|
|
56
|
+
os: [ubuntu-20.04, macOS-11, windows-2022]
|
|
37
57
|
|
|
38
58
|
steps:
|
|
39
59
|
- uses: actions/checkout@v3
|
package/.gitignore
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Ignore all files without an extension
|
|
2
|
+
*
|
|
3
|
+
!/**/
|
|
4
|
+
!*.*
|
|
5
|
+
|
|
6
|
+
# Temporary files
|
|
7
|
+
.DS_Store
|
|
8
|
+
*.fbin
|
|
9
|
+
*.ibin
|
|
10
|
+
datasets
|
|
11
|
+
bin
|
|
12
|
+
*.usearch
|
|
13
|
+
|
|
14
|
+
# C++ builds
|
|
15
|
+
build
|
|
16
|
+
build_release
|
|
17
|
+
build_debug
|
|
18
|
+
_deps
|
|
19
|
+
CMakeCache.txt
|
|
20
|
+
CMakeFiles
|
|
21
|
+
Makefile
|
|
22
|
+
cmake_install.cmake
|
|
23
|
+
|
|
24
|
+
# Profiling with GProf and `perf` on Linux
|
|
25
|
+
gmon.out
|
|
26
|
+
perf.data
|
|
27
|
+
|
|
28
|
+
# Python wrappers
|
|
29
|
+
__pycache__
|
|
30
|
+
*.egg-info
|
|
31
|
+
dist/
|
|
32
|
+
wheelhouse/
|
|
33
|
+
|
|
34
|
+
# JS wrappers
|
|
35
|
+
package-lock.json
|
|
36
|
+
node_modules/
|
|
37
|
+
|
|
38
|
+
# Rust builds
|
|
39
|
+
Cargo.lock
|
|
40
|
+
target/
|
|
41
|
+
|
|
42
|
+
# Java binings
|
|
43
|
+
.gradle
|
|
44
|
+
*.class
|
|
45
|
+
|
|
46
|
+
# ObjC and Swift
|
|
47
|
+
.build
|
|
48
|
+
.swiftpm
|
|
49
|
+
|
|
50
|
+
# Prerequisites
|
|
51
|
+
*.d
|
|
52
|
+
|
|
53
|
+
# Compiled Object files
|
|
54
|
+
*.slo
|
|
55
|
+
*.lo
|
|
56
|
+
*.o
|
|
57
|
+
*.obj
|
|
58
|
+
|
|
59
|
+
# Precompiled Headers
|
|
60
|
+
*.gch
|
|
61
|
+
*.pch
|
|
62
|
+
|
|
63
|
+
# Compiled Dynamic libraries
|
|
64
|
+
*.so
|
|
65
|
+
*.dylib
|
|
66
|
+
*.dll
|
|
67
|
+
|
|
68
|
+
# Fortran module files
|
|
69
|
+
*.mod
|
|
70
|
+
*.smod
|
|
71
|
+
|
|
72
|
+
# Allow golang go.mod
|
|
73
|
+
!go.mod
|
|
74
|
+
|
|
75
|
+
# Compiled Static libraries
|
|
76
|
+
*.lai
|
|
77
|
+
*.la
|
|
78
|
+
*.a
|
|
79
|
+
*.lib
|
|
80
|
+
|
|
81
|
+
# Executables
|
|
82
|
+
*.exe
|
|
83
|
+
*.out
|
|
84
|
+
*.app
|
package/.vscode/launch.json
CHANGED
|
@@ -50,7 +50,13 @@
|
|
|
50
50
|
"stopAtEntry": false,
|
|
51
51
|
"linux": {
|
|
52
52
|
"preLaunchTask": "Linux Build C++ Bench Debug",
|
|
53
|
-
"MIMode": "gdb"
|
|
53
|
+
"MIMode": "gdb",
|
|
54
|
+
"environment": [
|
|
55
|
+
{
|
|
56
|
+
"name": "MALLOC_CHECK_",
|
|
57
|
+
"value": "2"
|
|
58
|
+
}
|
|
59
|
+
]
|
|
54
60
|
},
|
|
55
61
|
"osx": {
|
|
56
62
|
"preLaunchTask": "MacOS Build C++ Bench Debug",
|
package/.vscode/settings.json
CHANGED
|
@@ -99,9 +99,12 @@
|
|
|
99
99
|
"__availability": "cpp",
|
|
100
100
|
"version": "cpp",
|
|
101
101
|
"future": "cpp",
|
|
102
|
-
"__verbose_abort": "cpp"
|
|
102
|
+
"__verbose_abort": "cpp",
|
|
103
|
+
"shared_mutex": "cpp"
|
|
103
104
|
},
|
|
104
105
|
"cSpell.words": [
|
|
106
|
+
"allclose",
|
|
107
|
+
"arange",
|
|
105
108
|
"astype",
|
|
106
109
|
"Availible",
|
|
107
110
|
"BLAS",
|
|
@@ -110,11 +113,15 @@
|
|
|
110
113
|
"downcasted",
|
|
111
114
|
"Downcasting",
|
|
112
115
|
"dtype",
|
|
116
|
+
"equi",
|
|
113
117
|
"equidimensional",
|
|
114
118
|
"FAISS",
|
|
119
|
+
"fbin",
|
|
120
|
+
"groundtruth",
|
|
115
121
|
"hashable",
|
|
116
122
|
"HNSW",
|
|
117
123
|
"hnswlib",
|
|
124
|
+
"ibin",
|
|
118
125
|
"jaccard",
|
|
119
126
|
"longlong",
|
|
120
127
|
"memmap",
|
|
@@ -122,12 +129,19 @@
|
|
|
122
129
|
"ndarray",
|
|
123
130
|
"ndim",
|
|
124
131
|
"Numba",
|
|
132
|
+
"numpy",
|
|
125
133
|
"OPENMP",
|
|
126
134
|
"preprocess",
|
|
135
|
+
"Println",
|
|
136
|
+
"pytest",
|
|
127
137
|
"Quickstart",
|
|
128
138
|
"rtype",
|
|
129
139
|
"simsimd",
|
|
130
140
|
"SLOC",
|
|
141
|
+
"sorensen",
|
|
142
|
+
"tanimoto",
|
|
143
|
+
"uninitialize",
|
|
144
|
+
"unumusearch",
|
|
131
145
|
"usearch",
|
|
132
146
|
"usecases"
|
|
133
147
|
],
|
package/Cargo.toml
CHANGED
package/README.md
CHANGED
|
@@ -66,11 +66,11 @@ Both USearch and FAISS implement the same HNSW algorithm.
|
|
|
66
66
|
But they differ in a lot of design decisions.
|
|
67
67
|
USearch is designed to be compact and broadly compatible without sacrificing performance.
|
|
68
68
|
|
|
69
|
-
| | FAISS, `f32` | USearch, `f32` | USearch, `f16` | USearch, `f8` |
|
|
70
|
-
| :--------- | -----------: | -------------: | -------------: | ------------: |
|
|
71
|
-
| Insertions | 76 K/s |
|
|
72
|
-
| Queries | 118 K/s |
|
|
73
|
-
| Recall @1 | 99% | 99.2% |
|
|
69
|
+
| | FAISS, `f32` | USearch, `f32` | USearch, `f16` | USearch, `f8` |
|
|
70
|
+
| :--------- | -----------: | -------------: | -------------: | ------------: |
|
|
71
|
+
| Insertions | 76 K/s | 105 K/s | 115 K/s | **202 K/s** |
|
|
72
|
+
| Queries | 118 K/s | 174 K/s | 173 K/s | **304 K/s** |
|
|
73
|
+
| Recall @1 | 99% | 99.2% | 99.1% | **99.2%** |
|
|
74
74
|
|
|
75
75
|
> Dataset: 1M vectors sample of the Deep1B dataset.
|
|
76
76
|
> Hardware: `c7g.metal` AWS instance with 64 cores and DDR5 memory.
|
|
@@ -202,9 +202,11 @@ The following distances are pre-packaged:
|
|
|
202
202
|
- `ip_gt<scalar_t>` for "Inner Product" or "Dot Product" distance.
|
|
203
203
|
- `l2sq_gt<scalar_t>` for the squared "L2" or "Euclidean" distance.
|
|
204
204
|
- `jaccard_gt<scalar_t>` for "Jaccard" distance between two ordered sets of unique elements.
|
|
205
|
-
- `
|
|
205
|
+
- `bitwise_hamming_gt<scalar_t>` for "Hamming" distance, as the number of shared bits in hashes.
|
|
206
|
+
- `bitwise_tanimoto_gt<scalar_t>` for "Tanimoto" coefficient for bit-strings.
|
|
207
|
+
- `bitwise_sorensen_gt<scalar_t>` for "Dice-Sorensen" coefficient for bit-strings.
|
|
206
208
|
- `pearson_correlation_gt<scalar_t>` for "Pearson" correlation between probability distributions.
|
|
207
|
-
- `haversine_gt<scalar_t>` for "Haversine" or "Great Circle" distance between coordinates.
|
|
209
|
+
- `haversine_gt<scalar_t>` for "Haversine" or "Great Circle" distance between coordinates used in GIS applications.
|
|
208
210
|
|
|
209
211
|
#### Multi-Threading
|
|
210
212
|
|
|
@@ -311,6 +313,12 @@ def python_dot(a, b, n, m):
|
|
|
311
313
|
index = Index(ndim=ndim, metric=python_dot.address)
|
|
312
314
|
```
|
|
313
315
|
|
|
316
|
+
To use Numba JIT, install USearch with extras:
|
|
317
|
+
|
|
318
|
+
```sh
|
|
319
|
+
pip install usearch[jit]
|
|
320
|
+
```
|
|
321
|
+
|
|
314
322
|
[numba]: https://numba.readthedocs.io/en/stable/reference/jit-compilation.html#c-callbacks
|
|
315
323
|
|
|
316
324
|
#### Tooling
|
|
@@ -457,6 +465,33 @@ assert(results.0[0] == 42)
|
|
|
457
465
|
|
|
458
466
|
### GoLang
|
|
459
467
|
|
|
468
|
+
#### Installation
|
|
469
|
+
|
|
470
|
+
```golang
|
|
471
|
+
import (
|
|
472
|
+
"github.com/unum-cloud/usearch/golang"
|
|
473
|
+
)
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
#### Quickstart
|
|
477
|
+
|
|
478
|
+
```golang
|
|
479
|
+
package main
|
|
480
|
+
|
|
481
|
+
import (
|
|
482
|
+
"fmt"
|
|
483
|
+
"github.com/unum-cloud/usearch/golang"
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
func main() {
|
|
487
|
+
conf := usearch.DefaultConfig(128)
|
|
488
|
+
index := usearch.NewIndex(conf)
|
|
489
|
+
v := make([]float32, 128)
|
|
490
|
+
index.Add(42, v)
|
|
491
|
+
results := index.Search(v, 1)
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
460
495
|
### Wolfram
|
|
461
496
|
|
|
462
497
|
## TODO
|
package/binding.gyp
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"dependencies": [
|
|
17
17
|
"<!(node -p \"require('node-addon-api').gyp\")"
|
|
18
18
|
],
|
|
19
|
-
"cflags": ["-fexceptions", "-Wno-unknown-pragmas"],
|
|
20
|
-
"cflags_cc": ["-fexceptions", "-Wno-unknown-pragmas", "-std=c++11"],
|
|
19
|
+
"cflags": ["-fexceptions", "-Wno-unknown-pragmas", "-Wno-maybe-uninitialized"],
|
|
20
|
+
"cflags_cc": ["-fexceptions", "-Wno-unknown-pragmas", "-Wno-maybe-uninitialized", "-std=c++11"],
|
|
21
21
|
"xcode_settings": {
|
|
22
22
|
"GCC_ENABLE_CPP_EXCEPTIONS": "YES",
|
|
23
23
|
"CLANG_CXX_LIBRARY": "libc++",
|
package/c/lib.cpp
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#include "../src/punned.hpp"
|
|
2
|
+
|
|
3
|
+
extern "C" {
|
|
4
|
+
#include "usearch.h"
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
using namespace unum::usearch;
|
|
8
|
+
using namespace unum;
|
|
9
|
+
|
|
10
|
+
using label_t = int;
|
|
11
|
+
using distance_t = float;
|
|
12
|
+
using punned_index_t = punned_gt<label_t>;
|
|
13
|
+
using span_t = span_gt<float>;
|
|
14
|
+
|
|
15
|
+
void* usearch_new( //
|
|
16
|
+
usearch_metric_t metric, usearch_accuracy_t accuracy, //
|
|
17
|
+
int dimensions, int capacity, int connectivity, //
|
|
18
|
+
int expansion_add, int expansion_search) {
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
config_t config;
|
|
22
|
+
config.expansion_add = static_cast<std::size_t>(expansion_add);
|
|
23
|
+
config.expansion_search = static_cast<std::size_t>(expansion_search);
|
|
24
|
+
config.connectivity = static_cast<std::size_t>(connectivity);
|
|
25
|
+
config.max_elements = static_cast<std::size_t>(capacity);
|
|
26
|
+
config.max_threads_add = std::thread::hardware_concurrency();
|
|
27
|
+
config.max_threads_search = std::thread::hardware_concurrency();
|
|
28
|
+
|
|
29
|
+
// TODO: Implement safe buffers for error messages, either here on in
|
|
30
|
+
// the C++ type-punned implementation.
|
|
31
|
+
// static constexpr std::size_t error_limit_k = 128;
|
|
32
|
+
// struct safe_punned_index_t {
|
|
33
|
+
// punned_index_t punned_index;
|
|
34
|
+
// char error_buffers[1];
|
|
35
|
+
// };
|
|
36
|
+
// std::size_t bytes_for_error_messages = error_limit_k * config.max_threads();
|
|
37
|
+
// std::size_t bytes_to_alloc = sizeof(punned_index_t) + bytes_for_error_messages;
|
|
38
|
+
// safe_punned_index_t* result = (safe_punned_index_t*)std::malloc(bytes_to_alloc);
|
|
39
|
+
|
|
40
|
+
accuracy_t accuracy = accuracy_from_name(accuracy_str, accuracy_len);
|
|
41
|
+
common_metric_kind_t metric_kind = common_metric_from_name(metric_str, metric_len);
|
|
42
|
+
punned_index_t index = make_punned<punned_index_t>( //
|
|
43
|
+
metric_kind, static_cast<std::size_t>(dimensions), accuracy, config);
|
|
44
|
+
|
|
45
|
+
punned_index_t* result_ptr = new punned_index_t(std::move(index));
|
|
46
|
+
return result_ptr;
|
|
47
|
+
} catch (std::exception const&) {
|
|
48
|
+
}
|
|
49
|
+
return NULL;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
void usearch_destroy(punned_index_t* index) { delete index; }
|
|
53
|
+
|
|
54
|
+
char const* usearch_save(punned_index_t* index, char const* path) {
|
|
55
|
+
try {
|
|
56
|
+
index->save(path);
|
|
57
|
+
return NULL;
|
|
58
|
+
} catch (std::exception& e) {
|
|
59
|
+
// q:: added these to make sure I do not pass a potentially dangling e.what()
|
|
60
|
+
// though I realize allocation below may fail and I am not checking for it.
|
|
61
|
+
// what can I do there? Golang side tries to free whatever string is passed from
|
|
62
|
+
// so passing a compile time constant "double fault" string is not an option
|
|
63
|
+
char* res = new char[strlen(e.what()) + 1];
|
|
64
|
+
strcpy(res, e.what());
|
|
65
|
+
return res;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
char const* usearch_load(punned_index_t* index, char const* path) {
|
|
70
|
+
try {
|
|
71
|
+
index->load(path);
|
|
72
|
+
return NULL;
|
|
73
|
+
} catch (std::exception& e) {
|
|
74
|
+
char* res = new char[strlen(e.what()) + 1];
|
|
75
|
+
strcpy(res, e.what());
|
|
76
|
+
return res;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
char const* usearch_view(punned_index_t* index, char const* path) {
|
|
81
|
+
try {
|
|
82
|
+
index->view(path);
|
|
83
|
+
return NULL;
|
|
84
|
+
} catch (std::exception& e) {
|
|
85
|
+
char* res = new char[strlen(e.what()) + 1];
|
|
86
|
+
strcpy(res, e.what());
|
|
87
|
+
return res;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
int usearch_size(punned_index_t* index) { return index->size(); }
|
|
92
|
+
int usearch_connectivity(punned_index_t* index) { return index->connectivity(); }
|
|
93
|
+
int usearch_dimensions(punned_index_t* index) { return index->dimensions(); }
|
|
94
|
+
int usearch_capacity(punned_index_t* index) { return index->capacity(); }
|
|
95
|
+
|
|
96
|
+
char const* usearch_reserve(punned_index_t* index, int capacity) {
|
|
97
|
+
try {
|
|
98
|
+
index->reserve(capacity);
|
|
99
|
+
return NULL;
|
|
100
|
+
} catch (std::exception& e) {
|
|
101
|
+
char* res = new char[strlen(e.what()) + 1];
|
|
102
|
+
strcpy(res, e.what());
|
|
103
|
+
return res;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
char const* usearch_add(punned_index_t* index, int label, float* vector) {
|
|
108
|
+
// q:: I followed the java example to have try catches everywhere
|
|
109
|
+
// but they are kind of useless as most errors are outside of cpp so
|
|
110
|
+
// those translate into segfaults and are not caught by the runtime
|
|
111
|
+
try {
|
|
112
|
+
index->add(label, vector);
|
|
113
|
+
} catch (std::exception& e) {
|
|
114
|
+
char* res = new char[strlen(e.what()) + 1];
|
|
115
|
+
strcpy(res, e.what());
|
|
116
|
+
return res;
|
|
117
|
+
}
|
|
118
|
+
return NULL;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
SearchResults usearch_search(punned_index_t* index, float* query, int query_len, int limit) {
|
|
122
|
+
// todo:: this could be allocated as golang slice
|
|
123
|
+
// to avoid a copy. not sure how it interacts with gc
|
|
124
|
+
// that is why doing this now
|
|
125
|
+
label_t* matches_data = new label_t[limit];
|
|
126
|
+
|
|
127
|
+
// todo:: pass the distances to outside world
|
|
128
|
+
distance_t* dist_data = new distance_t[limit];
|
|
129
|
+
SearchResults res{0};
|
|
130
|
+
try {
|
|
131
|
+
span_t vector_span = span_t{query, static_cast<std::size_t>(query_len)};
|
|
132
|
+
res.Len = index->search(vector_span, static_cast<std::size_t>(limit)).dump_to(matches_data, dist_data);
|
|
133
|
+
} catch (std::exception& e) {
|
|
134
|
+
res.Error = new char[strlen(e.what()) + 1];
|
|
135
|
+
strcpy(res.Error, e.what());
|
|
136
|
+
// res.Error = res;
|
|
137
|
+
}
|
|
138
|
+
res.Labels = matches_data;
|
|
139
|
+
res.Distances = dist_data;
|
|
140
|
+
return res;
|
|
141
|
+
}
|
package/c/usearch.h
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#ifndef UNUM_USEARCH_H
|
|
2
|
+
#define UNUM_USEARCH_H
|
|
3
|
+
|
|
4
|
+
#include <stdlib.h>
|
|
5
|
+
|
|
6
|
+
typedef enum {
|
|
7
|
+
usearch_metric_ip_k = 0,
|
|
8
|
+
usearch_metric_l2sq_k = 1,
|
|
9
|
+
usearch_metric_cos_k = 2,
|
|
10
|
+
usearch_metric_haversine_k = 3
|
|
11
|
+
} usearch_metric_t;
|
|
12
|
+
|
|
13
|
+
typedef enum {
|
|
14
|
+
usearch_accuracy_f32_k = 0,
|
|
15
|
+
usearch_accuracy_f16_k = 1,
|
|
16
|
+
usearch_accuracy_f8_k = 2,
|
|
17
|
+
} usearch_accuracy_t;
|
|
18
|
+
|
|
19
|
+
void* usearch_new( //
|
|
20
|
+
usearch_metric_t metric, usearch_accuracy_t accuracy, //
|
|
21
|
+
int dimensions, int capacity, int connectivity, //
|
|
22
|
+
int expansion_add, int expansion_search);
|
|
23
|
+
|
|
24
|
+
void usearch_destroy(void* index);
|
|
25
|
+
|
|
26
|
+
char const* usearch_save(void* index, char const* path);
|
|
27
|
+
char const* usearch_load(void* index, char const* path);
|
|
28
|
+
char const* usearch_view(void* index, char const* path);
|
|
29
|
+
|
|
30
|
+
int usearch_size(void* index);
|
|
31
|
+
int usearch_connectivity(void* index);
|
|
32
|
+
int usearch_dimensions(void* index);
|
|
33
|
+
int usearch_capacity(void* index);
|
|
34
|
+
|
|
35
|
+
char const* usearch_reserve(void* index, int capacity);
|
|
36
|
+
char const* usearch_add(void* index, int label, float const* vec);
|
|
37
|
+
|
|
38
|
+
char const* usearch_search( //
|
|
39
|
+
void* index, //
|
|
40
|
+
float const* query, int limit, //
|
|
41
|
+
int* labels, float* distances, int* count);
|
|
42
|
+
|
|
43
|
+
#endif
|
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.12.0'
|
|
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/docs/compilation.md
CHANGED
|
@@ -62,8 +62,12 @@ Benchmarking:
|
|
|
62
62
|
|
|
63
63
|
## Python
|
|
64
64
|
|
|
65
|
+
Use PyTest to validate the build.
|
|
66
|
+
The `-s` option will disable capturing the logs.
|
|
67
|
+
The `-x` option will exit after first failure to simplify debugging.
|
|
68
|
+
|
|
65
69
|
```sh
|
|
66
|
-
pip install -e . && pytest python/scripts/test.py
|
|
70
|
+
pip install -e . && pytest python/scripts/test.py -s -x
|
|
67
71
|
```
|
|
68
72
|
|
|
69
73
|
Linting:
|
|
@@ -95,8 +99,7 @@ python python/scripts/bench_params.py connectivity
|
|
|
95
99
|
## JavaScript
|
|
96
100
|
|
|
97
101
|
```sh
|
|
98
|
-
npm install
|
|
99
|
-
node javascript/test.js
|
|
102
|
+
npm install && node javascript/test.js
|
|
100
103
|
npm publish
|
|
101
104
|
```
|
|
102
105
|
|
|
@@ -148,6 +151,14 @@ java -cp . -Djava.library.path=/Users/av/github/usearch/java cloud.unum.usearch.
|
|
|
148
151
|
brew install --cask wolfram-engine
|
|
149
152
|
```
|
|
150
153
|
|
|
154
|
+
## C
|
|
155
|
+
|
|
156
|
+
### Linux
|
|
157
|
+
|
|
158
|
+
```sh
|
|
159
|
+
g++ -shared -fPIC lib.cpp -I ../include/ -I ../fp16/include/ -o libusearch.so
|
|
160
|
+
```
|
|
161
|
+
|
|
151
162
|
## Docker
|
|
152
163
|
|
|
153
164
|
```sh
|
package/golang/go.mod
ADDED