usearch 0.11.0 → 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/client.py +8 -9
- package/python/usearch/index.py +143 -60
- package/python/usearch/server.py +6 -16
- 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
package/src/test.cpp
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @brief A trivial test.
|
|
3
3
|
*/
|
|
4
4
|
#include <algorithm>
|
|
5
|
-
#include <
|
|
5
|
+
#include <stdexcept>
|
|
6
6
|
|
|
7
7
|
#include "punned.hpp"
|
|
8
8
|
|
|
@@ -11,13 +11,20 @@ using namespace unum;
|
|
|
11
11
|
|
|
12
12
|
using point_id_t = std::int64_t;
|
|
13
13
|
|
|
14
|
+
void expect(bool must_be_true) {
|
|
15
|
+
if (!must_be_true)
|
|
16
|
+
throw std::runtime_error("Failed!");
|
|
17
|
+
}
|
|
18
|
+
|
|
14
19
|
template <typename scalar_at, typename index_at> void test3d(index_at&& index) {
|
|
15
|
-
|
|
20
|
+
|
|
21
|
+
using scalar_t = scalar_at;
|
|
22
|
+
using view_t = span_gt<scalar_t const>;
|
|
16
23
|
using distance_t = typename index_at::distance_t;
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
25
|
+
scalar_t vec[3] = {10, 20, 15};
|
|
26
|
+
scalar_t vec_a[3] = {15, 16, 17};
|
|
27
|
+
scalar_t vec_b[3] = {16, 17, 18};
|
|
21
28
|
|
|
22
29
|
index.reserve(10);
|
|
23
30
|
index.add(42, view_t{&vec[0], 3ul});
|
|
@@ -27,16 +34,16 @@ template <typename scalar_at, typename index_at> void test3d(index_at&& index) {
|
|
|
27
34
|
distance_t matched_distances[10] = {0};
|
|
28
35
|
std::size_t matched_count = index.search(view_t{&vec[0], 3ul}, 5).dump_to(matched_labels, matched_distances);
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
expect(matched_count == 1);
|
|
38
|
+
expect(matched_labels[0] == 42);
|
|
39
|
+
expect(std::abs(matched_distances[0]) < 0.01);
|
|
33
40
|
|
|
34
41
|
// Add more entries
|
|
35
42
|
search_config_t search_config;
|
|
36
43
|
search_config.exact = true;
|
|
37
44
|
index.add(43, view_t{&vec_a[0], 3ul});
|
|
38
45
|
index.add(44, view_t{&vec_b[0], 3ul});
|
|
39
|
-
|
|
46
|
+
expect(index.size() == 3);
|
|
40
47
|
|
|
41
48
|
// Perform exact search
|
|
42
49
|
matched_count = index.search(view_t{&vec[0], 3ul}, 5, search_config).dump_to(matched_labels, matched_distances);
|
|
@@ -45,47 +52,84 @@ template <typename scalar_at, typename index_at> void test3d(index_at&& index) {
|
|
|
45
52
|
std::size_t count = 0;
|
|
46
53
|
for (auto member : index) {
|
|
47
54
|
point_id_t id = member.label;
|
|
48
|
-
|
|
55
|
+
expect(id >= 42 && id <= 44);
|
|
49
56
|
count++;
|
|
50
57
|
}
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
expect((count == 3));
|
|
59
|
+
expect((index.stats(0).nodes == 3));
|
|
53
60
|
|
|
54
61
|
// Search again over reconstructed index
|
|
55
62
|
index.save("tmp.usearch");
|
|
56
63
|
index.load("tmp.usearch");
|
|
57
64
|
matched_count = index.search(view_t{&vec[0], 3ul}, 5).dump_to(matched_labels, matched_distances);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
expect(matched_count == 3);
|
|
66
|
+
expect(matched_labels[0] == 42);
|
|
67
|
+
expect(std::abs(matched_distances[0]) < 0.01);
|
|
61
68
|
|
|
62
69
|
// Search again over mapped index
|
|
63
70
|
index.view("tmp.usearch");
|
|
64
71
|
matched_count = index.search(view_t{&vec[0], 3ul}, 5).dump_to(matched_labels, matched_distances);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
expect(matched_count == 3);
|
|
73
|
+
expect(matched_labels[0] == 42);
|
|
74
|
+
expect(std::abs(matched_distances[0]) < 0.01);
|
|
68
75
|
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
expect(index.memory_usage() > 0);
|
|
77
|
+
expect(index.stats().max_edges > 0);
|
|
71
78
|
}
|
|
72
79
|
|
|
73
80
|
template <typename scalar_at, typename index_at> void test3d_punned(index_at&& index) {
|
|
74
|
-
|
|
81
|
+
|
|
82
|
+
using scalar_t = scalar_at;
|
|
83
|
+
using view_t = span_gt<scalar_t const>;
|
|
75
84
|
using span_t = span_gt<scalar_at>;
|
|
76
|
-
using distance_t = typename index_at::distance_t;
|
|
77
85
|
|
|
78
|
-
|
|
86
|
+
scalar_t vec[3] = {10, 20, 15};
|
|
79
87
|
|
|
80
88
|
index.reserve(10);
|
|
81
89
|
index.add(42, view_t{&vec[0], 3ul});
|
|
82
90
|
|
|
83
91
|
// Reconstruct
|
|
84
|
-
|
|
92
|
+
scalar_t vec_reconstructed[3] = {0, 0, 0};
|
|
85
93
|
index.reconstruct(42, span_t{&vec_reconstructed[0], 3ul});
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
94
|
+
expect(vec_reconstructed[0] == vec[0]);
|
|
95
|
+
expect(vec_reconstructed[1] == vec[1]);
|
|
96
|
+
expect(vec_reconstructed[2] == vec[2]);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
template <typename index_at> void test_sets(index_at&& index) {
|
|
100
|
+
|
|
101
|
+
using index_t = typename std::remove_reference<index_at>::type;
|
|
102
|
+
using scalar_t = typename index_t::scalar_t;
|
|
103
|
+
using view_t = span_gt<scalar_t const>;
|
|
104
|
+
|
|
105
|
+
scalar_t vec0[] = {10, 20};
|
|
106
|
+
scalar_t vec1[] = {10, 15, 20};
|
|
107
|
+
scalar_t vec2[] = {10, 20, 30, 35};
|
|
108
|
+
|
|
109
|
+
index.reserve(10);
|
|
110
|
+
index.add(42, view_t{&vec0[0], 2ul});
|
|
111
|
+
index.add(43, view_t{&vec1[0], 3ul});
|
|
112
|
+
index.add(44, view_t{&vec2[0], 4ul});
|
|
113
|
+
|
|
114
|
+
expect(index.size() == 3);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
template <typename index_at> void test_sets_moved() {
|
|
118
|
+
{
|
|
119
|
+
index_at index;
|
|
120
|
+
test_sets(index);
|
|
121
|
+
}
|
|
122
|
+
{
|
|
123
|
+
index_at index;
|
|
124
|
+
index.reserve(1);
|
|
125
|
+
test_sets(index_at(std::move(index)));
|
|
126
|
+
}
|
|
127
|
+
{
|
|
128
|
+
index_at index;
|
|
129
|
+
index.reserve(1);
|
|
130
|
+
index_at index_moved = std::move(index);
|
|
131
|
+
test_sets(index_moved);
|
|
132
|
+
}
|
|
89
133
|
}
|
|
90
134
|
|
|
91
135
|
int main(int, char**) {
|
|
@@ -105,5 +149,11 @@ int main(int, char**) {
|
|
|
105
149
|
test3d_punned<float>(punned_small_t::cos(3));
|
|
106
150
|
test3d_punned<float>(punned_small_t::l2sq(3));
|
|
107
151
|
|
|
152
|
+
test_sets(index_gt<jaccard_gt<std::int32_t, float>, point_id_t, std::uint32_t, std::int32_t>{});
|
|
153
|
+
test_sets(index_gt<jaccard_gt<std::int64_t, float>, point_id_t, std::uint32_t, std::int64_t>{});
|
|
154
|
+
|
|
155
|
+
test_sets_moved<index_gt<jaccard_gt<std::int32_t, float>, point_id_t, std::uint32_t, std::int32_t>>();
|
|
156
|
+
test_sets_moved<index_gt<jaccard_gt<std::int64_t, float>, point_id_t, std::uint32_t, std::int64_t>>();
|
|
157
|
+
|
|
108
158
|
return 0;
|
|
109
159
|
}
|
package/wolfram/lib.cpp
CHANGED
|
@@ -10,23 +10,22 @@ EXTERN_C DLLEXPORT int WolframLibrary_initialize(WolframLibraryData libData) { r
|
|
|
10
10
|
EXTERN_C DLLEXPORT void WolframLibrary_uninitialize(WolframLibraryData libData) { return; }
|
|
11
11
|
|
|
12
12
|
EXTERN_C DLLEXPORT int IndexCreate(WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res) {
|
|
13
|
-
|
|
13
|
+
index_config_t config;
|
|
14
14
|
char* accuracy_cstr = nullptr;
|
|
15
15
|
char* metric_cstr = nullptr;
|
|
16
16
|
try {
|
|
17
17
|
accuracy_cstr = MArgument_getUTF8String(Args[1]);
|
|
18
18
|
metric_cstr = MArgument_getUTF8String(Args[0]);
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
std::size_t dimensions = static_cast<std::size_t>(MArgument_getInteger(Args[2]));
|
|
20
|
+
std::size_t capacity = static_cast<std::size_t>(MArgument_getInteger(Args[3]));
|
|
21
21
|
config.connectivity = static_cast<std::size_t>(MArgument_getInteger(Args[4]));
|
|
22
22
|
config.expansion_add = static_cast<std::size_t>(MArgument_getInteger(Args[5]));
|
|
23
23
|
config.expansion_search = static_cast<std::size_t>(MArgument_getInteger(Args[6]));
|
|
24
|
-
config.max_threads_add = 4;
|
|
25
|
-
config.max_threads_search = 4;
|
|
26
24
|
|
|
27
|
-
accuracy_t accuracy = accuracy_from_name(accuracy_cstr, strlen(accuracy_cstr));
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
accuracy_t accuracy = accuracy_from_name(accuracy_cstr, std::strlen(accuracy_cstr));
|
|
26
|
+
common_metric_kind_t metric_kind = common_metric_from_name(metric_cstr, std::strlen(metric_cstr));
|
|
27
|
+
punned_t index = make_punned<punned_t>(metric_kind, dimensions, accuracy, config);
|
|
28
|
+
index.reserve(capacity);
|
|
30
29
|
|
|
31
30
|
punned_t* result_ptr = new punned_t(std::move(index));
|
|
32
31
|
MArgument_setInteger(Res, (long)result_ptr);
|
package/Dockerfile
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# syntax=docker/dockerfile:1
|
|
2
|
-
|
|
3
|
-
FROM ubuntu:23.04
|
|
4
|
-
ENV DEBIAN_FRONTEND=noninteractive
|
|
5
|
-
|
|
6
|
-
RUN apt-get update && \
|
|
7
|
-
apt-get install -y --no-install-recommends python3.11 python3-pip && \
|
|
8
|
-
apt-get clean && \
|
|
9
|
-
rm -rf /var/lib/apt/lists/*
|
|
10
|
-
RUN pip3 install --no-cache-dir --break-system-packages ucall usearch
|
|
11
|
-
|
|
12
|
-
WORKDIR /usearch
|
|
13
|
-
COPY python/usearch/server.py server.py
|
|
14
|
-
|
|
15
|
-
ENTRYPOINT ["python3", "./server.py"]
|
|
16
|
-
EXPOSE 8545
|
package/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.11.0
|