usearch 0.4.0 → 0.8.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/.clang-tidy +60 -0
- package/.github/workflows/release.yml +42 -16
- package/.github/workflows/update_version.sh +1 -0
- package/.vscode/launch.json +22 -0
- package/.vscode/settings.json +5 -0
- package/.vscode/tasks.json +4 -4
- package/CITATION.cff +11 -0
- package/CMakeLists.txt +108 -95
- package/Cargo.toml +1 -1
- package/Dockerfile +14 -0
- package/README.md +8 -7
- package/VERSION +1 -1
- package/binding.gyp +2 -2
- package/build.rs +2 -2
- package/cmake/config.cmake.in +15 -0
- package/cmake/pkg-config.pc.in +4 -0
- package/cmake/usearchConfigVersion.cmake.in +20 -0
- package/conanfile.py +1 -1
- package/docs/benchmarks.md +11 -2
- package/docs/{Compilation.md → compilation.md} +54 -27
- package/include/usearch/usearch.hpp +664 -390
- package/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp +17 -16
- package/javascript/lib.cpp +13 -13
- package/javascript/test.js +1 -1
- package/objc/USearchObjective.mm +46 -29
- package/objc/include/USearchObjective.h +18 -26
- package/package.json +1 -1
- package/pyproject.toml +3 -2
- package/python/lib.cpp +179 -120
- package/python/{bench.py → scripts/bench.py} +6 -1
- package/python/scripts/bench_params.py +112 -0
- package/python/{test.py → scripts/test.py} +32 -13
- package/python/usearch/client.py +100 -14
- package/python/usearch/server.py +104 -23
- package/rust/lib.cpp +15 -14
- package/rust/lib.hpp +5 -5
- package/rust/lib.rs +3 -3
- package/setup.py +7 -0
- package/src/CMakeLists.txt +107 -0
- package/src/bench.cpp +45 -15
- package/src/{advanced.hpp → punned.hpp} +227 -199
- package/src/test.cpp +62 -0
- package/swift/Test.swift +1 -1
- package/wolfram/lib.cpp +14 -14
package/src/test.cpp
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @brief A trivial test.
|
|
3
|
+
*/
|
|
4
|
+
#include <cassert>
|
|
5
|
+
|
|
6
|
+
#include "punned.hpp"
|
|
7
|
+
|
|
8
|
+
using namespace unum::usearch;
|
|
9
|
+
using namespace unum;
|
|
10
|
+
|
|
11
|
+
using point_id_t = std::int64_t;
|
|
12
|
+
|
|
13
|
+
template <typename scalar_at, typename index_at> void test3d(index_at&& index) {
|
|
14
|
+
using span_t = span_gt<scalar_at const>;
|
|
15
|
+
using distance_t = typename index_at::distance_t;
|
|
16
|
+
|
|
17
|
+
scalar_at vec[3] = {10, 20, 15};
|
|
18
|
+
|
|
19
|
+
index.reserve(10);
|
|
20
|
+
index.add(42, span_t{&vec[0], 3ul});
|
|
21
|
+
|
|
22
|
+
point_id_t matched_labels[10] = {0};
|
|
23
|
+
distance_t matched_distances[10] = {0};
|
|
24
|
+
std::size_t matched_count = index.search(span_t{&vec[0], 3ul}, 5).dump_to(matched_labels, matched_distances);
|
|
25
|
+
|
|
26
|
+
assert(matched_count == 1);
|
|
27
|
+
assert(matched_labels[0] == 42);
|
|
28
|
+
assert(std::abs(matched_distances[0]) < 0.01);
|
|
29
|
+
|
|
30
|
+
index.save("tmp.usearch");
|
|
31
|
+
|
|
32
|
+
// Search again over reconstructed index
|
|
33
|
+
index.load("tmp.usearch");
|
|
34
|
+
matched_count = index.search(span_t{&vec[0], 3ul}, 5).dump_to(matched_labels, matched_distances);
|
|
35
|
+
assert(matched_count == 1);
|
|
36
|
+
assert(matched_labels[0] == 42);
|
|
37
|
+
assert(std::abs(matched_distances[0]) < 0.01);
|
|
38
|
+
|
|
39
|
+
// Search again over mapped index
|
|
40
|
+
index.view("tmp.usearch");
|
|
41
|
+
matched_count = index.search(span_t{&vec[0], 3ul}, 5).dump_to(matched_labels, matched_distances);
|
|
42
|
+
assert(matched_count == 1);
|
|
43
|
+
assert(matched_labels[0] == 42);
|
|
44
|
+
assert(std::abs(matched_distances[0]) < 0.01);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
int main(int, char**) {
|
|
48
|
+
|
|
49
|
+
test3d<float>(index_gt<cos_gt<float>, point_id_t, std::uint32_t, float>{});
|
|
50
|
+
test3d<float>(index_gt<l2sq_gt<float>, point_id_t, std::uint32_t, float>{});
|
|
51
|
+
|
|
52
|
+
test3d<double>(index_gt<cos_gt<double>, point_id_t, std::uint32_t, double>{});
|
|
53
|
+
test3d<double>(index_gt<l2sq_gt<double>, point_id_t, std::uint32_t, double>{});
|
|
54
|
+
|
|
55
|
+
test3d<float>(punned_small_t::cos(3));
|
|
56
|
+
test3d<float>(punned_small_t::l2sq(3));
|
|
57
|
+
|
|
58
|
+
test3d<double>(punned_small_t::cos(3));
|
|
59
|
+
test3d<double>(punned_small_t::l2sq(3));
|
|
60
|
+
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
package/swift/Test.swift
CHANGED
|
@@ -10,7 +10,7 @@ import USearch
|
|
|
10
10
|
|
|
11
11
|
@available(iOS 13, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
|
|
12
12
|
func testUnit() throws {
|
|
13
|
-
let index = Index.
|
|
13
|
+
let index = Index.l2sq(dimensions: 4, connectivity: 8)
|
|
14
14
|
let vectorA: [Float32] = [0.3, 0.5, 1.2, 1.4]
|
|
15
15
|
let vectorB: [Float32] = [0.4, 0.2, 1.2, 1.1]
|
|
16
16
|
index.add(label: 42, vector: vectorA[...])
|
package/wolfram/lib.cpp
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#include "WolframLibrary.h"
|
|
2
|
-
#include "
|
|
2
|
+
#include "punned.hpp"
|
|
3
3
|
|
|
4
4
|
using namespace unum::usearch;
|
|
5
5
|
using distance_t = punned_distance_t;
|
|
6
|
-
using
|
|
6
|
+
using punned_t = punned_gt<int>;
|
|
7
7
|
using span_t = span_gt<float>;
|
|
8
8
|
|
|
9
9
|
EXTERN_C DLLEXPORT int WolframLibrary_initialize(WolframLibraryData libData) { return LIBRARY_NO_ERROR; }
|
|
@@ -25,10 +25,10 @@ EXTERN_C DLLEXPORT int IndexCreate(WolframLibraryData libData, mint Argc, MArgum
|
|
|
25
25
|
config.max_threads_search = 4;
|
|
26
26
|
|
|
27
27
|
accuracy_t accuracy = accuracy_from_name(accuracy_cstr, strlen(accuracy_cstr));
|
|
28
|
-
|
|
28
|
+
punned_t index = index_from_name<punned_t>( //
|
|
29
29
|
metric_cstr, strlen(metric_cstr), dimensions, accuracy, config);
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
punned_t* result_ptr = new punned_t(std::move(index));
|
|
32
32
|
MArgument_setInteger(Res, (long)result_ptr);
|
|
33
33
|
|
|
34
34
|
} catch (...) {
|
|
@@ -42,7 +42,7 @@ EXTERN_C DLLEXPORT int IndexCreate(WolframLibraryData libData, mint Argc, MArgum
|
|
|
42
42
|
|
|
43
43
|
EXTERN_C DLLEXPORT int IndexSave(WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res) {
|
|
44
44
|
char* path_cstr = nullptr;
|
|
45
|
-
|
|
45
|
+
punned_t* c_ptr = (punned_t*)MArgument_getUTF8String(Args[0]);
|
|
46
46
|
try {
|
|
47
47
|
path_cstr = MArgument_getUTF8String(Args[1]);
|
|
48
48
|
c_ptr->save(path_cstr);
|
|
@@ -55,7 +55,7 @@ EXTERN_C DLLEXPORT int IndexSave(WolframLibraryData libData, mint Argc, MArgumen
|
|
|
55
55
|
|
|
56
56
|
EXTERN_C DLLEXPORT int IndexLoad(WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res) {
|
|
57
57
|
char* path_cstr = nullptr;
|
|
58
|
-
|
|
58
|
+
punned_t* c_ptr = (punned_t*)MArgument_getUTF8String(Args[0]);
|
|
59
59
|
try {
|
|
60
60
|
path_cstr = MArgument_getUTF8String(Args[1]);
|
|
61
61
|
c_ptr->load(path_cstr);
|
|
@@ -68,7 +68,7 @@ EXTERN_C DLLEXPORT int IndexLoad(WolframLibraryData libData, mint Argc, MArgumen
|
|
|
68
68
|
|
|
69
69
|
EXTERN_C DLLEXPORT int IndexView(WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res) {
|
|
70
70
|
char* path_cstr = nullptr;
|
|
71
|
-
|
|
71
|
+
punned_t* c_ptr = (punned_t*)MArgument_getUTF8String(Args[0]);
|
|
72
72
|
try {
|
|
73
73
|
path_cstr = MArgument_getUTF8String(Args[1]);
|
|
74
74
|
c_ptr->view(path_cstr);
|
|
@@ -80,37 +80,37 @@ EXTERN_C DLLEXPORT int IndexView(WolframLibraryData libData, mint Argc, MArgumen
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
EXTERN_C DLLEXPORT int IndexDestroy(WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res) {
|
|
83
|
-
delete (
|
|
83
|
+
delete (punned_t*)MArgument_getUTF8String(Args[0]);
|
|
84
84
|
return LIBRARY_NO_ERROR;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
EXTERN_C DLLEXPORT int IndexSize(WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res) {
|
|
88
|
-
size_t res = ((
|
|
88
|
+
size_t res = ((punned_t*)MArgument_getUTF8String(Args[0]))->size();
|
|
89
89
|
MArgument_setInteger(Res, res);
|
|
90
90
|
return LIBRARY_NO_ERROR;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
EXTERN_C DLLEXPORT int IndexConnectivity(WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res) {
|
|
94
|
-
size_t res = ((
|
|
94
|
+
size_t res = ((punned_t*)MArgument_getUTF8String(Args[0]))->connectivity();
|
|
95
95
|
MArgument_setInteger(Res, res);
|
|
96
96
|
return LIBRARY_NO_ERROR;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
EXTERN_C DLLEXPORT int IndexDimensions(WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res) {
|
|
100
|
-
size_t res = ((
|
|
100
|
+
size_t res = ((punned_t*)MArgument_getUTF8String(Args[0]))->dimensions();
|
|
101
101
|
MArgument_setInteger(Res, res);
|
|
102
102
|
return LIBRARY_NO_ERROR;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
EXTERN_C DLLEXPORT int IndexCapacity(WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res) {
|
|
106
|
-
size_t res = ((
|
|
106
|
+
size_t res = ((punned_t*)MArgument_getUTF8String(Args[0]))->capacity();
|
|
107
107
|
MArgument_setInteger(Res, res);
|
|
108
108
|
return LIBRARY_NO_ERROR;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
EXTERN_C DLLEXPORT int IndexAdd(WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res) {
|
|
112
112
|
char* path_cstr = nullptr;
|
|
113
|
-
|
|
113
|
+
punned_t* c_ptr = (punned_t*)MArgument_getUTF8String(Args[0]);
|
|
114
114
|
float* vector_data = nullptr;
|
|
115
115
|
try {
|
|
116
116
|
int label = MArgument_getInteger(Args[1]);
|
|
@@ -126,7 +126,7 @@ EXTERN_C DLLEXPORT int IndexAdd(WolframLibraryData libData, mint Argc, MArgument
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
EXTERN_C DLLEXPORT int IndexSearch(WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res) {
|
|
129
|
-
|
|
129
|
+
punned_t* c_ptr = (punned_t*)MArgument_getUTF8String(Args[0]);
|
|
130
130
|
MTensor matches;
|
|
131
131
|
mint dims[] = {1};
|
|
132
132
|
int wanted = MArgument_getInteger(Args[2]);
|