usearch 0.2.3 → 0.4.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/binding.gyp CHANGED
@@ -15,15 +15,19 @@
15
15
  "dependencies": [
16
16
  "<!(node -p \"require('node-addon-api').gyp\")"
17
17
  ],
18
- "cflags!": ["-fno-exceptions", "-Wunknown-pragmas"],
19
- "cflags_cc!": ["-fno-exceptions", "-Wunknown-pragmas"],
20
- "conditions": [
21
- ["OS==\"mac\"", {
22
- "xcode_settings": {
23
- "GCC_ENABLE_CPP_EXCEPTIONS": "YES"
24
- }
25
- }]
26
- ]
18
+ "cflags": ["-fexceptions", "-Wunknown-pragmas", "-std=c99"],
19
+ "cflags_cc": ["-fexceptions", "-Wunknown-pragmas", "-std=c++11"],
20
+ "xcode_settings": {
21
+ "GCC_ENABLE_CPP_EXCEPTIONS": "YES",
22
+ "CLANG_CXX_LIBRARY": "libc++",
23
+ "MACOSX_DEPLOYMENT_TARGET": "10.15"
24
+ },
25
+ "msvs_settings": {
26
+ "VCCLCompilerTool": {
27
+ "ExceptionHandling": 1,
28
+ "AdditionalOptions": [ "-std:c++11" ]
29
+ }
30
+ }
27
31
  }
28
32
  ]
29
33
  }
package/build.rs CHANGED
@@ -2,6 +2,7 @@ fn main() {
2
2
  cxx_build::bridge("rust/lib.rs")
3
3
  .file("rust/lib.cpp")
4
4
  .flag_if_supported("-std=c++11")
5
+ .flag_if_supported("-Wunknown-pragmas")
5
6
  .include("include")
6
7
  .include("rust")
7
8
  .include("src")
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.2.3'
7
+ version = '0.4.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'
@@ -0,0 +1,112 @@
1
+ # Compiling USearch
2
+
3
+ ## Build
4
+
5
+ Before building the first time, please pull submodules.
6
+
7
+ ```sh
8
+ git submodule update --init --recursive
9
+ ```
10
+
11
+ ### Linux
12
+
13
+ ```sh
14
+ cmake -B ./build_release \
15
+ -DCMAKE_CXX_COMPILER="g++-12" \
16
+ -DCMAKE_BUILD_TYPE=Release \
17
+ -DUSEARCH_USE_OPENMP=1 \
18
+ -DUSEARCH_USE_JEMALLOC=1 && \
19
+ make -C ./build_release -j
20
+
21
+ # To benchmark in C++:
22
+ ./build_release/bench \
23
+ --vectors datasets/wiki_1M/base.1M.fbin \
24
+ --queries datasets/wiki_1M/query.public.100K.fbin \
25
+ --neighbors datasets/wiki_1M/groundtruth.public.100K.ibin
26
+
27
+ # Large benchmark on a 1TB dataset:
28
+ ./build_release/bench \
29
+ --vectors datasets/t2i_1B/base.1B.fbin \
30
+ --queries datasets/t2i_1B/query.public.100K.fbin \
31
+ --neighbors datasets/t2i_1B/groundtruth.public.100K.ibin \
32
+ --output datasets/t2i_1B/index.usearch \
33
+ --cos
34
+
35
+ # To benchmark in Python:
36
+ python python/bench.py \
37
+ --vectors datasets/wiki_1M/base.1M.fbin \
38
+ --queries datasets/wiki_1M/query.public.100K.fbin \
39
+ --neighbors datasets/wiki_1M/groundtruth.public.100K.ibin
40
+ ```
41
+
42
+ ### MacOS
43
+
44
+ ```sh
45
+ brew install libomp llvm
46
+ cmake \
47
+ -DCMAKE_C_COMPILER="/opt/homebrew/opt/llvm/bin/clang" \
48
+ -DCMAKE_CXX_COMPILER="/opt/homebrew/opt/llvm/bin/clang++" \
49
+ -DUSEARCH_USE_SIMD=1 \
50
+ -DUSEARCH_USE_OPENMP=1 \
51
+ -B ./build_release && \
52
+ make -C ./build_release -j
53
+ ```
54
+
55
+ ### Python
56
+
57
+ ```sh
58
+ pip install -e .
59
+ pytest python/test.py
60
+ ```
61
+
62
+ ### JavaScript
63
+
64
+ ```sh
65
+ npm install
66
+ node javascript/test.js
67
+ npm publish
68
+ ```
69
+
70
+ ### Rust
71
+
72
+ ```sh
73
+ cargo test -p usearch
74
+ cargo publish
75
+ ```
76
+
77
+ ### Java
78
+
79
+ ```sh
80
+ gradle clean build
81
+ java -cp . -Djava.library.path=/Users/av/github/usearch/build/libs/usearch/shared java/cloud/unum/usearch/Index.java
82
+ ```
83
+
84
+ Or step by-step:
85
+
86
+ ```sh
87
+ cs java/unum/cloud/usearch
88
+ javac -h . Index.java
89
+
90
+ # Ubuntu:
91
+ g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux cloud_unum_usearch_Index.cpp -o cloud_unum_usearch_Index.o
92
+ g++ -shared -fPIC -o libusearch.so cloud_unum_usearch_Index.o -lc
93
+
94
+ # Windows
95
+ g++ -c -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 cloud_unum_usearch_Index.cpp -o cloud_unum_usearch_Index.o
96
+ g++ -shared -o USearchJNI.dll cloud_unum_usearch_Index.o -Wl,--add-stdcall-alias
97
+
98
+ # MacOS
99
+ g++ -std=c++11 -c -fPIC \
100
+ -I../../../../include -I../../../../src -I../../../../fp16/include -I../../../../simsimd/include \
101
+ -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin cloud_unum_usearch_Index.cpp -o cloud_unum_usearch_Index.o
102
+ g++ -dynamiclib -o libusearch.dylib cloud_unum_usearch_Index.o -lc
103
+ # Run linking to that directory
104
+ java -cp . -Djava.library.path=/Users/av/github/usearch/java/cloud/unum/usearch/ Index.java
105
+ java -cp . -Djava.library.path=/Users/av/github/usearch/java cloud.unum.usearch.Index
106
+ ```
107
+
108
+ ### Wolfram
109
+
110
+ ```sh
111
+ brew install --cask wolfram-engine
112
+ ```
@@ -0,0 +1,182 @@
1
+ # Benchmarking USearch
2
+
3
+ ## Hyper-parameters
4
+
5
+ All major HNSW implementation share an identical list of hyper-parameters:
6
+
7
+ - connectivity (often called `M`),
8
+ - expansion on additions (often called `efConstruction`),
9
+ - expansion on search (often called `ef`).
10
+
11
+ The default values vary drastically.
12
+
13
+ | Library | Connectivity | EF @ A | EF @ S |
14
+ | :-------: | :----------: | :----: | :----: |
15
+ | `hnswlib` | 16 | 200 | 10 |
16
+ | `FAISS` | 32 | 40 | 16 |
17
+ | `USearch` | 16 | 128 | 64 |
18
+
19
+ Below are the performance numbers for a benchmark running on the 64 cores of AWS `c7g.metal` "Graviton 3"-based instances.
20
+ The main columns are:
21
+
22
+ - **Add**: Number of insertion Queries Per Second.
23
+ - **Search**: Number search Queries Per Second.
24
+ - **Recall @1**: How often does approximate search yield the exact best match?
25
+
26
+ ### Different "connectivity"
27
+
28
+ | Vectors | Connectivity | EF @ A | EF @ S | **Add**, QPS | **Search**, QPS | **Recall @1** |
29
+ | :--------- | :----------: | :----: | :----: | :----------: | :-------------: | ------------: |
30
+ | `f32` x256 | 16 | 128 | 64 | 75'640 | 131'654 | 99.3% |
31
+ | `f32` x256 | 12 | 128 | 64 | 81'747 | 149'728 | 99.0% |
32
+ | `f32` x256 | 32 | 128 | 64 | 64'368 | 104'050 | 99.4% |
33
+
34
+ ### Different "expansion factors"
35
+
36
+ | Vectors | Connectivity | EF @ A | EF @ S | **Add**, QPS | **Search**, QPS | **Recall @1** |
37
+ | :--------- | :----------: | :----: | :----: | :----------: | :-------------: | ------------: |
38
+ | `f32` x256 | 16 | 128 | 64 | 75'640 | 131'654 | 99.3% |
39
+ | `f32` x256 | 16 | 64 | 32 | 128'644 | 228'422 | 97.2% |
40
+ | `f32` x256 | 16 | 256 | 128 | 39'981 | 69'065 | 99.2% |
41
+
42
+ ### Different vectors "accuracy"
43
+
44
+ | Vectors | Connectivity | EF @ A | EF @ S | **Add**, QPS | **Search**, QPS | **Recall @1** |
45
+ | :----------- | :----------: | :----: | :----: | :----------: | :-------------: | ------------: |
46
+ | `f32` x256 | 16 | 128 | 64 | 87'995 | 171'856 | 99.1% |
47
+ | `f16` x256 | 16 | 128 | 64 | 87'270 | 153'788 | 98.4% |
48
+ | `f16` x256 ✳️ | 16 | 128 | 64 | 71'454 | 132'673 | 98.4% |
49
+ | `f8` x256 | 16 | 128 | 64 | 115'923 | 274'653 | 98.9% |
50
+
51
+ As seen on the chart, for `f16` accuracy, performance may differ depending on native hardware support for that numeric type.
52
+ Also worth noting, 8-bit quantization results in almost no accuracy loss and may perform better than `f16`.
53
+
54
+ ## Utilities
55
+
56
+ Within this repository you will find two commonly used utilities:
57
+
58
+ - `src/bench.cpp` the produces the `bench` binary for broad USearch benchmarks.
59
+ - `python/bench.py` for simple benchmarks against FAISS.
60
+
61
+ To achieve best highest results we suggest compiling locally for the target architecture.
62
+
63
+ ```sh
64
+ cmake -B ./build_release \
65
+ -DCMAKE_BUILD_TYPE=Release \
66
+ -DUSEARCH_USE_OPENMP=1 \
67
+ -DUSEARCH_USE_JEMALLOC=1 && \
68
+ make -C ./build_release -j
69
+
70
+ ./build_release/bench --help
71
+ ```
72
+
73
+ Which would print the following instructions.
74
+
75
+ ```txt
76
+ SYNOPSIS
77
+ ./build_release/bench [--vectors <path>] [--queries <path>] [--neighbors <path>] [-b] [-j
78
+ <integer>] [-c <integer>] [--expansion-add <integer>]
79
+ [--expansion-search <integer>] [--native|--f16quant|--i8quant]
80
+ [--ip|--l2|--cos|--haversine] [-h]
81
+
82
+ OPTIONS
83
+ --vectors <path>
84
+ .fbin file path to construct the index
85
+
86
+ --queries <path>
87
+ .fbin file path to query the index
88
+
89
+ --neighbors <path>
90
+ .ibin file path with ground truth
91
+
92
+ -b, --big Will switch to uint40_t for neighbors lists with over 4B entries
93
+ -j, --threads <integer>
94
+ Uses all available cores by default
95
+
96
+ -c, --connectivity <integer>
97
+ Index granularity
98
+
99
+ --expansion-add <integer>
100
+ Affects indexing depth
101
+
102
+ --expansion-search <integer>
103
+ Affects search depth
104
+
105
+ --native Use raw templates instead of type-punned classes
106
+ --f16quant Enable `f16_t` quantization
107
+ --i8quant Enable `int8_t` quantization
108
+ --ip Choose Inner Product metric
109
+ --l2 Choose L2 Euclidean metric
110
+ --cos Choose Angular metric
111
+ --haversine Choose Haversine metric
112
+ -h, --help Print this help information on this tool and exit
113
+ ```
114
+
115
+ ## Datasets
116
+
117
+ BigANN benchmark is a good starting point, if you are searching for large collections of high-dimensional vectors.
118
+ Those often come with precomputed ground-truth neighbors, which is handy for recall evaluation.
119
+
120
+ | Dataset | Scalar Type | Dimensions | Metric | Size |
121
+ | :-------------------------------------- | :---------: | :--------: | :----: | :-------: |
122
+ | [Unum UForm Wiki][unum-wiki] | float32 | 256 | IP | 1 GB |
123
+ | [Yandex Text-to-Image Sample][unum-t2i] | float32 | 200 | Cos | 1 GB |
124
+ | | | | | |
125
+ | [Microsoft SPACEV][spacev] | int8 | 100 | L2 | 93 GB |
126
+ | [Microsoft Turing-ANNS][turing] | float32 | 100 | L2 | 373 GB |
127
+ | [Yandex Deep1B][deep] | float32 | 96 | L2 | 358 GB |
128
+ | [Yandex Text-to-Image][t2i] | float32 | 200 | Cos | 750 GB |
129
+ | | | | | |
130
+ | [ViT-L/12 LAION][laion] | float32 | 2048 | Cos | 2 - 10 TB |
131
+
132
+ Luckily, smaller samples of those datasets are available.
133
+
134
+ [unum-wiki]: https://huggingface.co/datasets/unum-cloud/ann-wiki-1m
135
+ [unum-t2i]: https://huggingface.co/datasets/unum-cloud/ann-t2i-1m
136
+ [spacev]: https://github.com/microsoft/SPTAG/tree/main/datasets/SPACEV1B
137
+ [turing]: https://learning2hash.github.io/publications/microsoftturinganns1B/
138
+ [t2i]: https://research.yandex.com/blog/benchmarks-for-billion-scale-similarity-search
139
+ [deep]: https://research.yandex.com/blog/benchmarks-for-billion-scale-similarity-search
140
+ [laion]: https://laion.ai/blog/laion-5b/#download-the-data
141
+
142
+ ### Unum UForm Wiki
143
+
144
+ ```sh
145
+ mkdir -p datasets/wiki_1M/ && \
146
+ wget -nc https://huggingface.co/datasets/unum-cloud/ann-wiki-1m/resolve/main/base.1M.fbin -P datasets/wiki_1M/ &&
147
+ wget -nc https://huggingface.co/datasets/unum-cloud/ann-wiki-1m/resolve/main/query.public.100K.fbin -P datasets/wiki_1M/ &&
148
+ wget -nc https://huggingface.co/datasets/unum-cloud/ann-wiki-1m/resolve/main/groundtruth.public.100K.ibin -P datasets/wiki_1M/
149
+ ```
150
+
151
+ ### Yandex Text-to-Image
152
+
153
+ ```sh
154
+ mkdir -p datasets/t2i_1B/ && \
155
+ wget -nc https://storage.yandexcloud.net/yandex-research/ann-datasets/T2I/base.1B.fbin -P datasets/t2i_1B/ &&
156
+ wget -nc https://storage.yandexcloud.net/yandex-research/ann-datasets/T2I/base.1M.fbin -P datasets/t2i_1B/ &&
157
+ wget -nc https://storage.yandexcloud.net/yandex-research/ann-datasets/T2I/query.public.100K.fbin -P datasets/t2i_1B/ &&
158
+ wget -nc https://storage.yandexcloud.net/yandex-research/ann-datasets/T2I/groundtruth.public.100K.ibin -P datasets/t2i_1B/
159
+ ```
160
+
161
+ ### Yandex Deep1B
162
+
163
+ ```sh
164
+ mkdir -p datasets/deep_1B/ && \
165
+ wget -nc https://storage.yandexcloud.net/yandex-research/ann-datasets/DEEP/base.1B.fbin -P datasets/deep_1B/ &&
166
+ wget -nc https://storage.yandexcloud.net/yandex-research/ann-datasets/DEEP/base.10M.fbin -P datasets/deep_1B/ &&
167
+ wget -nc https://storage.yandexcloud.net/yandex-research/ann-datasets/DEEP/query.public.10K.fbin -P datasets/deep_1B/ &&
168
+ wget -nc https://storage.yandexcloud.net/yandex-research/ann-datasets/DEEP/groundtruth.public.10K.ibin -P datasets/deep_1B/
169
+ ```
170
+
171
+ ## Profiling
172
+
173
+ With `perf`:
174
+
175
+ ```sh
176
+ # Pass environment variables with `-E`, and `-d` for details
177
+ sudo -E perf stat -d ./build_release/bench ...
178
+ sudo -E perf mem -d ./build_release/bench ...
179
+ # Sample on-CPU functions for the specified command, at 1 Kilo Hertz:
180
+ sudo -E perf record -F 1000 ./build_release/bench ...
181
+ perf record -d -e arm_spe// -- ./build_release/bench ..
182
+ ```
@@ -0,0 +1,5 @@
1
+ ========================
2
+ Benchmarks
3
+ ========================
4
+
5
+ .. mdinclude:: benchmarks.md
@@ -0,0 +1,5 @@
1
+ ========================
2
+ Compilation
3
+ ========================
4
+
5
+ .. mdinclude:: compilation.md