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.
- package/.github/workflows/prerelease.yml +45 -0
- package/.github/workflows/release.yml +79 -1
- package/.github/workflows/update_version.sh +1 -0
- package/.gitignore +11 -1
- package/.vscode/settings.json +5 -1
- package/Cargo.toml +1 -1
- package/README.md +15 -8
- package/c/lib.cpp +3 -3
- package/conanfile.py +1 -1
- package/csharp/.editorconfig +361 -0
- package/csharp/Cloud.Unum.USearch.sln +34 -0
- package/csharp/DEV_SETUP.md +51 -0
- package/csharp/Directory.Build.props +29 -0
- package/csharp/README.md +77 -0
- package/csharp/build_and_test.cmd +31 -0
- package/csharp/build_and_test.sh +30 -0
- package/csharp/eng/build_lib.sh +65 -0
- package/csharp/eng/clean.sh +12 -0
- package/csharp/nuget/NUGET.md +11 -0
- package/csharp/nuget/nuget-package.props +33 -0
- package/csharp/pack.sh +56 -0
- package/csharp/src/Cloud.Unum.USearch.Tests/Cloud.Unum.USearch.Tests.csproj +39 -0
- package/csharp/src/Cloud.Unum.USearch.Tests/InitTests.cs +306 -0
- package/csharp/src/Cloud.Unum.USearch.Tests/Usings.cs +1 -0
- package/include/usearch/index_dense.hpp +8 -8
- package/include/usearch/index_plugins.hpp +56 -49
- package/package.json +1 -1
- package/python/lib.cpp +6 -6
- package/rust/lib.cpp +27 -15
- package/rust/lib.hpp +9 -0
- package/rust/lib.rs +10 -0
- package/wasmer.toml +1 -1
|
@@ -174,6 +174,51 @@ jobs:
|
|
|
174
174
|
- name: Run tests
|
|
175
175
|
run: swift test
|
|
176
176
|
|
|
177
|
+
test_csharp:
|
|
178
|
+
name: Test C#
|
|
179
|
+
runs-on: ${{ matrix.os }}
|
|
180
|
+
strategy:
|
|
181
|
+
fail-fast: false
|
|
182
|
+
matrix:
|
|
183
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
184
|
+
dotnet-version: ['7.0.x']
|
|
185
|
+
steps:
|
|
186
|
+
- uses: actions/checkout@v3
|
|
187
|
+
- run: git submodule update --init --recursive
|
|
188
|
+
- name: Setup .NET ${{ matrix.dotnet-version }}
|
|
189
|
+
uses: actions/setup-dotnet@v3
|
|
190
|
+
with:
|
|
191
|
+
dotnet-version: ${{ matrix.dotnet-version }}
|
|
192
|
+
|
|
193
|
+
- name: Ubuntu/macOS build native lib
|
|
194
|
+
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
|
|
195
|
+
run: ./build_lib.sh
|
|
196
|
+
shell: bash
|
|
197
|
+
working-directory: ${{ github.workspace }}/csharp/eng/
|
|
198
|
+
|
|
199
|
+
# Use cl.exe https://www.appveyor.com/docs/lang/cpp/#visual-studio-2017
|
|
200
|
+
# There is no support for c++11
|
|
201
|
+
- name: Windows MSVC build
|
|
202
|
+
if: matrix.os == 'windows-latest'
|
|
203
|
+
run: |
|
|
204
|
+
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
|
205
|
+
where cl
|
|
206
|
+
cl /EHsc /std:c++14 /O2 /LD /Fe:libusearch_c.dll lib.cpp /I. /I../include/ /I../fp16/include/
|
|
207
|
+
working-directory: ${{ github.workspace }}/c
|
|
208
|
+
shell: cmd
|
|
209
|
+
|
|
210
|
+
- name: Windows move dll to lib dir
|
|
211
|
+
if: matrix.os == 'windows-latest'
|
|
212
|
+
run: |
|
|
213
|
+
mkdir -p "${GITHUB_WORKSPACE}/csharp/lib/runtimes/win-x64/native"
|
|
214
|
+
mv "${GITHUB_WORKSPACE}/c/libusearch_c.dll" "${GITHUB_WORKSPACE}/csharp/lib/runtimes/win-x64/native"
|
|
215
|
+
shell: bash
|
|
216
|
+
|
|
217
|
+
- name: Build and test
|
|
218
|
+
run: dotnet test -c Release
|
|
219
|
+
shell: bash
|
|
220
|
+
working-directory: ${{ github.workspace }}/csharp/
|
|
221
|
+
|
|
177
222
|
build_docker:
|
|
178
223
|
name: Test Docker Image
|
|
179
224
|
runs-on: ubuntu-latest
|
|
@@ -271,11 +271,89 @@ jobs:
|
|
|
271
271
|
tags: ${{ steps.meta.outputs.tags }}
|
|
272
272
|
labels: ${{ steps.meta.outputs.labels }}
|
|
273
273
|
|
|
274
|
+
build_csharp:
|
|
275
|
+
name: Build NuGet
|
|
276
|
+
needs: versioning
|
|
277
|
+
strategy:
|
|
278
|
+
matrix:
|
|
279
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
280
|
+
runs-on: ${{ matrix.os }}
|
|
281
|
+
defaults:
|
|
282
|
+
run:
|
|
283
|
+
shell: bash
|
|
284
|
+
steps:
|
|
285
|
+
- uses: actions/checkout@v3
|
|
286
|
+
with:
|
|
287
|
+
ref: 'main'
|
|
288
|
+
- run: git submodule update --init --recursive
|
|
289
|
+
|
|
290
|
+
- name: Ubuntu/macOS build usearch shared obj
|
|
291
|
+
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
|
|
292
|
+
run: ./build_lib.sh
|
|
293
|
+
working-directory: ${{ github.workspace }}/csharp/eng
|
|
294
|
+
|
|
295
|
+
- name: Windows MSVC build usearch dll
|
|
296
|
+
if: matrix.os == 'windows-latest'
|
|
297
|
+
run: |
|
|
298
|
+
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
|
299
|
+
where cl
|
|
300
|
+
cl /EHsc /std:c++14 /O2 /LD /Fe:libusearch_c.dll lib.cpp /I. /I../include/ /I../fp16/include/
|
|
301
|
+
working-directory: ${{ github.workspace }}/c
|
|
302
|
+
shell: cmd
|
|
303
|
+
|
|
304
|
+
- name: Windows copy dll
|
|
305
|
+
if: matrix.os == 'windows-latest'
|
|
306
|
+
run: |
|
|
307
|
+
mkdir -p "${GITHUB_WORKSPACE}/csharp/lib/runtimes/win-x64/native"
|
|
308
|
+
cp "${GITHUB_WORKSPACE}/c/libusearch_c.dll" "${GITHUB_WORKSPACE}/csharp/lib/runtimes/win-x64/native"
|
|
309
|
+
shell: bash
|
|
310
|
+
|
|
311
|
+
- name: Upload Artifacts
|
|
312
|
+
uses: actions/upload-artifact@v3
|
|
313
|
+
with:
|
|
314
|
+
name: usearch-libs
|
|
315
|
+
path: ${{ github.workspace }}/csharp/lib/**/*
|
|
316
|
+
|
|
317
|
+
publish_csharp:
|
|
318
|
+
name: Publish C#
|
|
319
|
+
runs-on: ubuntu-latest
|
|
320
|
+
needs: [build_csharp]
|
|
321
|
+
env:
|
|
322
|
+
USEARCH_LIBS: ${{ github.workspace }}/csharp/lib
|
|
323
|
+
NUGET_DIR: ${{ github.workspace }}/csharp/packages
|
|
324
|
+
# NUGET_SOURCE: https://apiint.nugettest.org/v3/index.json
|
|
325
|
+
NUGET_SOURCE: https://api.nuget.org/v3/index.json
|
|
326
|
+
SOLUTION_DIR: ${{ github.workspace }}/csharp
|
|
327
|
+
steps:
|
|
328
|
+
- uses: actions/checkout@v3
|
|
329
|
+
- run: git submodule update --init --recursive
|
|
330
|
+
|
|
331
|
+
- name: Download usearch libs artifact
|
|
332
|
+
uses: actions/download-artifact@v3
|
|
333
|
+
with:
|
|
334
|
+
name: usearch-libs
|
|
335
|
+
path: ${{ env.USEARCH_LIBS }}
|
|
336
|
+
|
|
337
|
+
- name: Setup .NET
|
|
338
|
+
uses: actions/setup-dotnet@v3
|
|
339
|
+
with:
|
|
340
|
+
dotnet-version: 7.0.x
|
|
341
|
+
|
|
342
|
+
- name: Pack project
|
|
343
|
+
run: |
|
|
344
|
+
VERSION_CONTENT=$(< VERSION)
|
|
345
|
+
dotnet pack "${{ env.SOLUTION_DIR }}" -c Release -p:Version="$VERSION_CONTENT" --output ${{ env.NUGET_DIR }}
|
|
346
|
+
working-directory: ${{ github.workspace }}
|
|
347
|
+
|
|
348
|
+
- name: Publish NuGet packages
|
|
349
|
+
run: |
|
|
350
|
+
dotnet nuget push "${{ env.NUGET_DIR }}/*.nupkg" --api-key "${{ secrets.NUGET_API }}" --source "${{ env.NUGET_SOURCE }}"
|
|
351
|
+
|
|
274
352
|
build_docs:
|
|
275
353
|
name: Build Docs
|
|
276
354
|
runs-on: ubuntu-22.04
|
|
277
355
|
if: ${{ always() }}
|
|
278
|
-
needs: [publish_python, publish_javascript, publish_rust, publish_java, publish_swift, publish_docker]
|
|
356
|
+
needs: [publish_python, publish_javascript, publish_rust, publish_java, publish_swift, publish_docker, publish_csharp]
|
|
279
357
|
permissions:
|
|
280
358
|
contents: write
|
|
281
359
|
steps:
|
|
@@ -10,4 +10,5 @@ echo $1 > VERSION &&
|
|
|
10
10
|
sed -i "s/^\(#define USEARCH_VERSION_PATCH \).*/\1$(echo "$1" | cut -d. -f3)/" ./include/usearch/index.hpp &&
|
|
11
11
|
sed -i "s/<version>[0-9]\+\.[0-9]\+\.[0-9]\+/<version>$1/" README.md &&
|
|
12
12
|
sed -i "s/version = {[0-9]\+\.[0-9]\+\.[0-9]\+}/version = {$1}/" README.md &&
|
|
13
|
+
sed -i "s/>[0-9]\+\.[0-9]\+\.[0-9]\+<\/Version>/>$1<\/Version>/" ./csharp/nuget/nuget-package.props &&
|
|
13
14
|
sed -i "s/version=\".*\"/version=\"$1\"/" wasmer.toml
|
package/.gitignore
CHANGED
|
@@ -31,6 +31,9 @@ __pycache__
|
|
|
31
31
|
dist/
|
|
32
32
|
wheelhouse/
|
|
33
33
|
|
|
34
|
+
# Python Environments
|
|
35
|
+
venv/
|
|
36
|
+
|
|
34
37
|
# JS wrappers
|
|
35
38
|
package-lock.json
|
|
36
39
|
node_modules/
|
|
@@ -39,7 +42,7 @@ node_modules/
|
|
|
39
42
|
Cargo.lock
|
|
40
43
|
target/
|
|
41
44
|
|
|
42
|
-
# Java
|
|
45
|
+
# Java bindings
|
|
43
46
|
.gradle
|
|
44
47
|
*.class
|
|
45
48
|
|
|
@@ -47,6 +50,12 @@ target/
|
|
|
47
50
|
.build
|
|
48
51
|
.swiftpm
|
|
49
52
|
|
|
53
|
+
# C# builds
|
|
54
|
+
csharp/**/[Bb]in/
|
|
55
|
+
csharp/**/[Oo]bj/
|
|
56
|
+
csharp/lib
|
|
57
|
+
csharp/packages
|
|
58
|
+
|
|
50
59
|
# Prerequisites
|
|
51
60
|
*.d
|
|
52
61
|
|
|
@@ -82,3 +91,4 @@ target/
|
|
|
82
91
|
*.exe
|
|
83
92
|
*.out
|
|
84
93
|
*.app
|
|
94
|
+
|
package/.vscode/settings.json
CHANGED
|
@@ -111,6 +111,7 @@
|
|
|
111
111
|
"Availible",
|
|
112
112
|
"bidict",
|
|
113
113
|
"BLAS",
|
|
114
|
+
"Cdecl",
|
|
114
115
|
"cflags",
|
|
115
116
|
"citerator",
|
|
116
117
|
"downcasted",
|
|
@@ -126,6 +127,7 @@
|
|
|
126
127
|
"hnswlib",
|
|
127
128
|
"ibin",
|
|
128
129
|
"jaccard",
|
|
130
|
+
"libusearch",
|
|
129
131
|
"longlong",
|
|
130
132
|
"memmap",
|
|
131
133
|
"Napi",
|
|
@@ -146,7 +148,8 @@
|
|
|
146
148
|
"uninitialize",
|
|
147
149
|
"unumusearch",
|
|
148
150
|
"usearch",
|
|
149
|
-
"usecases"
|
|
151
|
+
"usecases",
|
|
152
|
+
"Xunit"
|
|
150
153
|
],
|
|
151
154
|
"autoDocstring.docstringFormat": "sphinx",
|
|
152
155
|
"java.configuration.updateBuildConfiguration": "interactive",
|
|
@@ -163,4 +166,5 @@
|
|
|
163
166
|
"editor.formatOnSave": true,
|
|
164
167
|
"editor.defaultFormatter": "golang.go"
|
|
165
168
|
},
|
|
169
|
+
"dotnet.defaultSolution": "csharp/Cloud.Unum.USearch.sln",
|
|
166
170
|
}
|
package/Cargo.toml
CHANGED
package/README.md
CHANGED
|
@@ -283,8 +283,10 @@ Broader functionality is ported per request.
|
|
|
283
283
|
|
|
284
284
|
### USearch + AI = Multi-Modal Semantic Search
|
|
285
285
|
|
|
286
|
+
[](https://github.com/ashvardanian/usearch-images)
|
|
287
|
+
|
|
286
288
|
AI has a growing number of applications, but one of the coolest classic ideas is to use it for Semantic Search.
|
|
287
|
-
One can take an encoder model, like the multi-modal UForm, and a web-programming framework, like UCall, and build a text-to-image search platform in just 20 lines of Python.
|
|
289
|
+
One can take an encoder model, like the multi-modal [UForm](https://github.com/unum-cloud/uform), and a web-programming framework, like UCall, and build a text-to-image search platform in just 20 lines of Python.
|
|
288
290
|
|
|
289
291
|
```python
|
|
290
292
|
import ucall
|
|
@@ -314,13 +316,14 @@ def search(query: str) -> np.ndarray:
|
|
|
314
316
|
server.run()
|
|
315
317
|
```
|
|
316
318
|
|
|
319
|
+
A more complete [demo with Streamlit is available on GitHub](https://github.com/ashvardanian/usearch-images).
|
|
317
320
|
We have pre-processed some commonly used datasets, cleaned the images, produced the vectors, and pre-built the index.
|
|
318
321
|
|
|
319
|
-
| Dataset
|
|
320
|
-
|
|
|
321
|
-
| [Unsplash
|
|
322
|
-
| [Conceptual Captions
|
|
323
|
-
| [Arxiv
|
|
322
|
+
| Dataset | Modalities | Images | Download |
|
|
323
|
+
| :---------------------------------- | --------------------: | -----: | ------------------------------------: |
|
|
324
|
+
| [Unsplash][unsplash-25k-origin] | Images & Descriptions | 25 K | [HuggingFace / Unum][unsplash-25k-hf] |
|
|
325
|
+
| [Conceptual Captions][cc-3m-origin] | Images & Descriptions | 3 M | [HuggingFace / Unum][cc-3m-hf] |
|
|
326
|
+
| [Arxiv][arxiv-2m-origin] | Titles & Abstracts | 2 M | [HuggingFace / Unum][arxiv-2m-hf] |
|
|
324
327
|
|
|
325
328
|
[unsplash-25k-origin]: https://github.com/unsplash/datasets
|
|
326
329
|
[cc-3m-origin]: https://huggingface.co/datasets/conceptual_captions
|
|
@@ -364,15 +367,19 @@ matches = index.search(fingerprints, 10)
|
|
|
364
367
|
|
|
365
368
|
### USearch + POI Coordinates = GIS Applications... on iOS?
|
|
366
369
|
|
|
367
|
-
|
|
370
|
+
[](https://github.com/ashvardanian/SwiftVectorSearch)
|
|
368
371
|
|
|
372
|
+
With Objective-C and Swift iOS bindings, USearch can be easily used in mobile applications.
|
|
373
|
+
The [SwiftVectorSearch](https://github.com/ashvardanian/SwiftVectorSearch) project illustrates how to build a dynamic, real-time search system on iOS.
|
|
374
|
+
In this example, we use 2-dimensional vectors—encoded as latitude and longitude—to find the closest Points of Interest (POIs) on a map.
|
|
375
|
+
The search is based on the Haversine distance metric, but can easily be extended to support high-dimensional vectors.
|
|
369
376
|
|
|
370
377
|
## Integrations
|
|
371
378
|
|
|
372
379
|
- [x] GPTCache: [Python](https://github.com/zilliztech/GPTCache/releases/tag/0.1.29).
|
|
373
380
|
- [x] LangChain: [Python](https://github.com/langchain-ai/langchain/releases/tag/v0.0.257) and [JavaScipt](https://github.com/hwchase17/langchainjs/releases/tag/0.0.125).
|
|
374
381
|
- [x] ClickHouse: [C++](https://github.com/ClickHouse/ClickHouse/pull/53447).
|
|
375
|
-
- [
|
|
382
|
+
- [x] Microsoft Semantic Kernel: [Python](https://github.com/microsoft/semantic-kernel/releases/tag/python-0.3.9.dev) and C#.
|
|
376
383
|
|
|
377
384
|
## Citations
|
|
378
385
|
|
package/c/lib.cpp
CHANGED
|
@@ -48,7 +48,7 @@ add_result_t add_(index_dense_t* index, usearch_key_t key, void const* vector, s
|
|
|
48
48
|
case scalar_kind_t::f32_k: return index->add(key, (f32_t const*)vector);
|
|
49
49
|
case scalar_kind_t::f64_k: return index->add(key, (f64_t const*)vector);
|
|
50
50
|
case scalar_kind_t::f16_k: return index->add(key, (f16_t const*)vector);
|
|
51
|
-
case scalar_kind_t::i8_k: return index->add(key, (
|
|
51
|
+
case scalar_kind_t::i8_k: return index->add(key, (i8_t const*)vector);
|
|
52
52
|
case scalar_kind_t::b1x8_k: return index->add(key, (b1x8_t const*)vector);
|
|
53
53
|
default: return add_result_t{}.failed("Unknown scalar kind!");
|
|
54
54
|
}
|
|
@@ -59,7 +59,7 @@ std::size_t get_(index_dense_t* index, usearch_key_t key, size_t count, void* ve
|
|
|
59
59
|
case scalar_kind_t::f32_k: return index->get(key, (f32_t*)vector, count);
|
|
60
60
|
case scalar_kind_t::f64_k: return index->get(key, (f64_t*)vector, count);
|
|
61
61
|
case scalar_kind_t::f16_k: return index->get(key, (f16_t*)vector, count);
|
|
62
|
-
case scalar_kind_t::i8_k: return index->get(key, (
|
|
62
|
+
case scalar_kind_t::i8_k: return index->get(key, (i8_t*)vector, count);
|
|
63
63
|
case scalar_kind_t::b1x8_k: return index->get(key, (b1x8_t*)vector, count);
|
|
64
64
|
default: return search_result_t().failed("Unknown scalar kind!");
|
|
65
65
|
}
|
|
@@ -70,7 +70,7 @@ search_result_t search_(index_dense_t* index, void const* vector, scalar_kind_t
|
|
|
70
70
|
case scalar_kind_t::f32_k: return index->search((f32_t const*)vector, n);
|
|
71
71
|
case scalar_kind_t::f64_k: return index->search((f64_t const*)vector, n);
|
|
72
72
|
case scalar_kind_t::f16_k: return index->search((f16_t const*)vector, n);
|
|
73
|
-
case scalar_kind_t::i8_k: return index->search((
|
|
73
|
+
case scalar_kind_t::i8_k: return index->search((i8_t const*)vector, n);
|
|
74
74
|
case scalar_kind_t::b1x8_k: return index->search((b1x8_t const*)vector, n);
|
|
75
75
|
default: return search_result_t().failed("Unknown scalar kind!");
|
|
76
76
|
}
|
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 = '
|
|
7
|
+
version = '2.0.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'
|