usearch 2.0.2 → 2.1.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/Dockerfile.libs +34 -0
- package/.github/workflows/release.yml +56 -0
- package/Cargo.toml +1 -1
- package/conanfile.py +1 -1
- package/csharp/README.md +1 -1
- package/golang/README.md +58 -37
- package/golang/lib.go +16 -12
- package/package.json +1 -1
- package/wasmer.toml +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
FROM ubuntu:22.04
|
|
2
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
3
|
+
|
|
4
|
+
ENV user_name="runner"
|
|
5
|
+
ARG TARGETPLATFORM
|
|
6
|
+
ARG docker_ip
|
|
7
|
+
ARG user_pass
|
|
8
|
+
|
|
9
|
+
RUN apt-get update && \
|
|
10
|
+
apt-get install -y --no-install-recommends python3.11 python3-pip cmake g++-12 build-essential libjemalloc-dev golang openssh-client sshpass && \
|
|
11
|
+
apt-get clean && \
|
|
12
|
+
rm -rf /var/lib/apt/lists/*
|
|
13
|
+
|
|
14
|
+
COPY . .
|
|
15
|
+
|
|
16
|
+
RUN cd golang && make -C ../c libusearch_c.so && \
|
|
17
|
+
mv ../c/libusearch_c.so libusearch.a && cp ../c/usearch.h usearch.h && \
|
|
18
|
+
go test -v && cd ..
|
|
19
|
+
|
|
20
|
+
RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \
|
|
21
|
+
export arch="amd"; \
|
|
22
|
+
elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
|
|
23
|
+
export arch="arm"; \
|
|
24
|
+
fi && \
|
|
25
|
+
version=$(cat VERSION) && \
|
|
26
|
+
mkdir -p usearch_"$arch"_"$version"/DEBIAN && \
|
|
27
|
+
touch usearch_"$arch"_"$version"/DEBIAN/control && \
|
|
28
|
+
mkdir -p usearch_"$arch"_"$version"/usr/local/lib && \
|
|
29
|
+
mkdir usearch_"$arch"_"$version"/usr/local/include && \
|
|
30
|
+
cp c/usearch.h usearch_"$arch"_"$version"/usr/local/include/ && \
|
|
31
|
+
cp golang/libusearch.a usearch_"$arch"_"$version"/usr/local/lib/ && \
|
|
32
|
+
echo "Package: usearch\nVersion: $version\nMaintainer: Ashot Vardanian\nArchitecture: "$arch"\nDescription: Faster & Smaller Single-File Search Engine for Vectors & Texts" > usearch_"$arch"_"$version"/DEBIAN/control && \
|
|
33
|
+
dpkg-deb --build usearch_"$arch"_"$version" && \
|
|
34
|
+
sshpass -p "$user_pass" scp -o StrictHostKeyChecking=no usearch_"$arch"_"$version".deb "$user_name"@"$docker_ip":/home/$user_name/work/usearch/usearch/
|
|
@@ -96,6 +96,62 @@ jobs:
|
|
|
96
96
|
* Source code (tar.gz) : `${{ steps.hashes.outputs.tar_hash }}`
|
|
97
97
|
|
|
98
98
|
|
|
99
|
+
create_deb_packages_linux:
|
|
100
|
+
name: Create deb package for Linux on ${{ matrix.arch }}
|
|
101
|
+
needs: versioning
|
|
102
|
+
runs-on: ubuntu-latest
|
|
103
|
+
strategy:
|
|
104
|
+
matrix:
|
|
105
|
+
arch: ["linux/amd64", "linux/arm64"]
|
|
106
|
+
steps:
|
|
107
|
+
- uses: actions/checkout@v3
|
|
108
|
+
with:
|
|
109
|
+
persist-credentials: false
|
|
110
|
+
ref: 'main'
|
|
111
|
+
- run: git submodule update --init --recursive
|
|
112
|
+
|
|
113
|
+
- name: Set up QEMU
|
|
114
|
+
uses: docker/setup-qemu-action@v2
|
|
115
|
+
|
|
116
|
+
- name: Set up Docker Buildx
|
|
117
|
+
uses: docker/setup-buildx-action@v2
|
|
118
|
+
|
|
119
|
+
- name: Get docker daemon IP
|
|
120
|
+
id: dockerip
|
|
121
|
+
run: |
|
|
122
|
+
docker_ip=$(ip addr show docker0 | grep -Po 'inet \K[\d.]+') && \
|
|
123
|
+
echo "docker_ip=$docker_ip" >> "$GITHUB_OUTPUT"
|
|
124
|
+
|
|
125
|
+
- name: Set new password for runner user
|
|
126
|
+
id: userpass
|
|
127
|
+
run: |
|
|
128
|
+
user_pass="1122"
|
|
129
|
+
echo "runner:$user_pass" | sudo chpasswd
|
|
130
|
+
echo "user_pass=$user_pass" >> "$GITHUB_OUTPUT"
|
|
131
|
+
|
|
132
|
+
- name: Build Usearch lib
|
|
133
|
+
run: |
|
|
134
|
+
docker buildx create --use
|
|
135
|
+
docker buildx build \
|
|
136
|
+
--platform ${{ matrix.arch }} \
|
|
137
|
+
--build-arg docker_ip=${{ steps.dockerip.outputs.docker_ip }} \
|
|
138
|
+
--build-arg user_pass=${{ steps.userpass.outputs.user_pass }} \
|
|
139
|
+
--file .github/workflows/Dockerfile.libs \
|
|
140
|
+
--tag unum/ustore-deps:latest \
|
|
141
|
+
--load .
|
|
142
|
+
|
|
143
|
+
- name: Clear Docker buildx cache
|
|
144
|
+
run: docker buildx prune --all --force
|
|
145
|
+
|
|
146
|
+
- name: Upload archive to release Assets
|
|
147
|
+
uses: xresloader/upload-to-github-release@v1
|
|
148
|
+
env:
|
|
149
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
150
|
+
with:
|
|
151
|
+
file: "*.deb"
|
|
152
|
+
update_latest_release: true
|
|
153
|
+
|
|
154
|
+
|
|
99
155
|
build_wheels:
|
|
100
156
|
name: Build Wheels for ${{ matrix.os }}
|
|
101
157
|
needs: versioning
|
package/Cargo.toml
CHANGED
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 = '2.0
|
|
7
|
+
version = '2.1.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/csharp/README.md
CHANGED
|
@@ -40,7 +40,7 @@ index.Save("index.usearch")
|
|
|
40
40
|
using var indexLoaded = new USearchIndex("index.usearch");
|
|
41
41
|
|
|
42
42
|
// Or view from disk without loading in memory
|
|
43
|
-
// using var indexLoaded = new USearchIndex("index.usearch", view:
|
|
43
|
+
// using var indexLoaded = new USearchIndex("index.usearch", view: true);
|
|
44
44
|
|
|
45
45
|
Trace.Assert(indexLoaded.Size() == 1);
|
|
46
46
|
Trace.Assert(indexLoaded.Dimensions() == 3);
|
package/golang/README.md
CHANGED
|
@@ -2,51 +2,72 @@
|
|
|
2
2
|
|
|
3
3
|
## Installation
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
Download and install from the Debian package from the latest release.
|
|
6
|
+
Substitute `<release_tag>`, `<arch>`, and `<usearch_version>` with your settings.
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
wget https://github.com/unum-cloud/usearch/releases/download/<release_tag>/usearch_<arch>_<usearch_version>.deb
|
|
10
|
+
dpkg -i usearch_<arch>_<usearch_version>.deb
|
|
9
11
|
```
|
|
10
12
|
|
|
11
13
|
## Quickstart
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
package main
|
|
15
|
+
1. Create a `go.mod` file:
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"github.com/unum-cloud/usearch/golang-go"
|
|
19
|
-
)
|
|
17
|
+
```
|
|
18
|
+
module usearch_example
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
conf := DefaultConfig(dim)
|
|
24
|
-
ind, err := NewIndex(conf)
|
|
25
|
-
if err != nil {
|
|
26
|
-
panic("Failed to construct the index: %s", err)
|
|
27
|
-
}
|
|
28
|
-
defer ind.Destroy()
|
|
20
|
+
go <go_version>
|
|
21
|
+
```
|
|
29
22
|
|
|
30
|
-
|
|
31
|
-
if err != nil {
|
|
32
|
-
panic("Failed to reserve capacity: %s", err)
|
|
33
|
-
}
|
|
23
|
+
2. Create an `example.go`:
|
|
34
24
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
vec[1] = 2.0
|
|
25
|
+
```golang
|
|
26
|
+
package main
|
|
38
27
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
28
|
+
import (
|
|
29
|
+
"fmt"
|
|
30
|
+
usearch "github.com/unum-cloud/usearch/golang"
|
|
31
|
+
)
|
|
43
32
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
33
|
+
func main() {
|
|
34
|
+
|
|
35
|
+
// Create Index
|
|
36
|
+
vector_size := 3
|
|
37
|
+
vectors_count := 100
|
|
38
|
+
conf := usearch.DefaultConfig(uint(vector_size))
|
|
39
|
+
index,err := usearch.NewIndex(conf)
|
|
40
|
+
if err != nil {
|
|
41
|
+
panic("Failed to create Index")
|
|
42
|
+
}
|
|
43
|
+
defer index.Destroy()
|
|
44
|
+
|
|
45
|
+
// Add to Index
|
|
46
|
+
err = index.Reserve(uint(vectors_count))
|
|
47
|
+
for i := 0; i < vectors_count; i++ {
|
|
48
|
+
err = index.Add(usearch.Key(i), []float32{float32(i), float32(i+1), float32(i+2)})
|
|
49
|
+
if err != nil {
|
|
50
|
+
panic("Failed to add")
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Search
|
|
55
|
+
keys, distances, err := index.Search([]float32{0.0, 1.0, 2.0}, 3)
|
|
56
|
+
if err != nil {
|
|
57
|
+
panic("Failed to search")
|
|
58
|
+
}
|
|
59
|
+
fmt.Println(keys, distances)
|
|
50
60
|
}
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
3. Get USearch:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
go get github.com/unum-cloud/usearch/golang
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
4. Run:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
go run example.go
|
|
73
|
+
```
|
package/golang/lib.go
CHANGED
|
@@ -6,9 +6,8 @@ import (
|
|
|
6
6
|
)
|
|
7
7
|
|
|
8
8
|
/*
|
|
9
|
-
#cgo
|
|
10
|
-
#
|
|
11
|
-
#include <usearch.h>
|
|
9
|
+
#cgo LDFLAGS: -L. -lusearch
|
|
10
|
+
#include "usearch.h"
|
|
12
11
|
#include <stdlib.h>
|
|
13
12
|
*/
|
|
14
13
|
import "C"
|
|
@@ -91,6 +90,8 @@ type IndexConfig struct {
|
|
|
91
90
|
ExpansionAdd uint
|
|
92
91
|
// The @b optional expansion factor used for index construction during search operations.
|
|
93
92
|
ExpansionSearch uint
|
|
93
|
+
// The @b optional multi flag.
|
|
94
|
+
Multi bool
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
func DefaultConfig(dimensions uint) IndexConfig {
|
|
@@ -101,6 +102,7 @@ func DefaultConfig(dimensions uint) IndexConfig {
|
|
|
101
102
|
c.Connectivity = 0
|
|
102
103
|
c.ExpansionAdd = 0
|
|
103
104
|
c.ExpansionSearch = 0
|
|
105
|
+
c.Multi = false
|
|
104
106
|
return c
|
|
105
107
|
}
|
|
106
108
|
|
|
@@ -114,16 +116,18 @@ func NewIndex(conf IndexConfig) (index *Index, err error) {
|
|
|
114
116
|
index = &Index{config: conf}
|
|
115
117
|
|
|
116
118
|
conf = index.config
|
|
117
|
-
dimensions := C.
|
|
118
|
-
connectivity := C.
|
|
119
|
-
expansion_add := C.
|
|
120
|
-
expansion_search := C.
|
|
119
|
+
dimensions := C.size_t(conf.Dimensions)
|
|
120
|
+
connectivity := C.size_t(conf.Connectivity)
|
|
121
|
+
expansion_add := C.size_t(conf.ExpansionAdd)
|
|
122
|
+
expansion_search := C.size_t(conf.ExpansionSearch)
|
|
123
|
+
multi := C.bool(conf.Multi)
|
|
121
124
|
|
|
122
125
|
options := C.struct_usearch_init_options_t{}
|
|
123
126
|
options.dimensions = dimensions
|
|
124
127
|
options.connectivity = connectivity
|
|
125
128
|
options.expansion_add = expansion_add
|
|
126
129
|
options.expansion_search = expansion_search
|
|
130
|
+
options.multi = multi
|
|
127
131
|
|
|
128
132
|
// Map the metric kind to a C enum
|
|
129
133
|
switch conf.Metric {
|
|
@@ -281,21 +285,21 @@ func (index *Index) Contains(key Key) (found bool, err error) {
|
|
|
281
285
|
return found, nil
|
|
282
286
|
}
|
|
283
287
|
|
|
284
|
-
func (index *Index) Get(key Key) (
|
|
288
|
+
func (index *Index) Get(key Key, count uint) (vectors []float32, err error) {
|
|
285
289
|
if index.opaque_handle == nil {
|
|
286
290
|
panic("Index is uninitialized")
|
|
287
291
|
}
|
|
288
292
|
|
|
289
|
-
|
|
293
|
+
vectors = make([]float32, index.config.Dimensions * count)
|
|
290
294
|
var errorMessage *C.char
|
|
291
|
-
found :=
|
|
295
|
+
found := uint(C.usearch_get((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), (C.usearch_key_t)(key), (C.size_t)(count), unsafe.Pointer(&vectors[0]), C.usearch_scalar_f32_k, (*C.usearch_error_t)(&errorMessage)))
|
|
292
296
|
if errorMessage != nil {
|
|
293
297
|
return nil, errors.New(C.GoString(errorMessage))
|
|
294
298
|
}
|
|
295
|
-
if
|
|
299
|
+
if found == 0 {
|
|
296
300
|
return nil, nil
|
|
297
301
|
}
|
|
298
|
-
return
|
|
302
|
+
return vectors, nil
|
|
299
303
|
}
|
|
300
304
|
|
|
301
305
|
// Performs k-Approximate Nearest Neighbors Search for closest vectors to query.
|
package/package.json
CHANGED