usearch 2.8.7 → 2.8.9

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.
Files changed (113) hide show
  1. package/CITATION.cff +1 -1
  2. package/CMakeLists.txt +3 -3
  3. package/CONTRIBUTING.md +26 -3
  4. package/Cargo.toml +1 -1
  5. package/Dockerfile +16 -0
  6. package/README.md +41 -38
  7. package/VERSION +1 -0
  8. package/binding.gyp +57 -8
  9. package/conanfile.py +1 -1
  10. package/include/usearch/index.hpp +1 -1
  11. package/include/usearch/index_plugins.hpp +28 -24
  12. package/javascript/README.md +64 -12
  13. package/javascript/lib.cpp +11 -3
  14. package/javascript/usearch.js +4 -2
  15. package/javascript/usearch.test.js +15 -0
  16. package/package.json +1 -2
  17. package/setup.py +76 -15
  18. package/simsimd/README.md +14 -13
  19. package/simsimd/include/simsimd/probability.h +2 -2
  20. package/simsimd/package.json +1 -1
  21. package/wasmer.toml +1 -1
  22. package/. npmignore +0 -14
  23. package/.gitignore +0 -95
  24. package/.vscode/launch.json +0 -181
  25. package/.vscode/settings.json +0 -180
  26. package/.vscode/tasks.json +0 -71
  27. package/Package.swift +0 -41
  28. package/csharp/.editorconfig +0 -361
  29. package/csharp/Cloud.Unum.USearch.sln +0 -34
  30. package/csharp/DEV_SETUP.md +0 -51
  31. package/csharp/Directory.Build.props +0 -29
  32. package/csharp/README.md +0 -74
  33. package/csharp/build_and_test.cmd +0 -31
  34. package/csharp/build_and_test.sh +0 -30
  35. package/csharp/nuget/nuget-package.props +0 -33
  36. package/csharp/pack.sh +0 -56
  37. package/csharp/src/Cloud.Unum.USearch.Tests/Cloud.Unum.USearch.Tests.csproj +0 -39
  38. package/csharp/src/Cloud.Unum.USearch.Tests/USearchIndexTests.cs +0 -1013
  39. package/csharp/src/Cloud.Unum.USearch.Tests/Usings.cs +0 -1
  40. package/docs/_static/custom.css +0 -26
  41. package/docs/_static/custom.js +0 -7
  42. package/docs/benchmarks.md +0 -245
  43. package/docs/benchmarks.rst +0 -5
  44. package/docs/c/index.rst +0 -11
  45. package/docs/c/reference.rst +0 -7
  46. package/docs/conf.dox +0 -2668
  47. package/docs/conf.py +0 -53
  48. package/docs/contributing.rst +0 -5
  49. package/docs/cpp/index.rst +0 -11
  50. package/docs/cpp/reference.rst +0 -17
  51. package/docs/csharp/index.rst +0 -6
  52. package/docs/format.md +0 -86
  53. package/docs/format.rst +0 -5
  54. package/docs/golang/index.rst +0 -6
  55. package/docs/index.rst +0 -33
  56. package/docs/java/index.rst +0 -11
  57. package/docs/java/reference.rst +0 -7
  58. package/docs/javascript/index.rst +0 -11
  59. package/docs/javascript/reference.rst +0 -12
  60. package/docs/python/index.rst +0 -11
  61. package/docs/python/reference.rst +0 -42
  62. package/docs/rust/index.rst +0 -6
  63. package/docs/swift/index.rst +0 -6
  64. package/docs/wolfram/index.rst +0 -6
  65. package/golang/README.md +0 -95
  66. package/golang/go.mod +0 -3
  67. package/golang/lib.go +0 -379
  68. package/golang/lib_test.go +0 -108
  69. package/java/README.md +0 -22
  70. package/java/cloud/unum/usearch/Index.java +0 -337
  71. package/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp +0 -197
  72. package/java/cloud/unum/usearch/cloud_unum_usearch_Index.h +0 -125
  73. package/java/test/IndexTest.java +0 -30
  74. package/objc/USearchObjective.mm +0 -299
  75. package/objc/include/USearchObjective.h +0 -154
  76. package/python/README.md +0 -292
  77. package/python/lib.cpp +0 -1216
  78. package/python/scripts/bench.ipynb +0 -193
  79. package/python/scripts/bench.py +0 -137
  80. package/python/scripts/bench_exact.py +0 -44
  81. package/python/scripts/cluster.ipynb +0 -160
  82. package/python/scripts/index_faiss.py +0 -100
  83. package/python/scripts/join.py +0 -155
  84. package/python/scripts/test_index.py +0 -247
  85. package/python/scripts/test_jit.py +0 -231
  86. package/python/scripts/test_sparse.py +0 -32
  87. package/python/scripts/test_tooling.py +0 -133
  88. package/python/usearch/__init__.py +0 -0
  89. package/python/usearch/client.py +0 -124
  90. package/python/usearch/eval.py +0 -470
  91. package/python/usearch/index.py +0 -1401
  92. package/python/usearch/io.py +0 -113
  93. package/python/usearch/numba.py +0 -121
  94. package/python/usearch/server.py +0 -137
  95. package/rust/README.md +0 -66
  96. package/rust/lib.cpp +0 -136
  97. package/rust/lib.hpp +0 -69
  98. package/rust/lib.rs +0 -610
  99. package/simsimd/CMakeLists.txt +0 -67
  100. package/simsimd/cpp/bench.cxx +0 -206
  101. package/simsimd/package-ci.json +0 -10
  102. package/simsimd/setup.py +0 -86
  103. package/swift/Index+Sugar.swift +0 -153
  104. package/swift/README.md +0 -48
  105. package/swift/Test.swift +0 -37
  106. package/swift/USearch.swift +0 -8
  107. package/wasm/CMakeLists.txt +0 -7
  108. package/wasm/README.md +0 -13
  109. package/wasm/lib.cpp +0 -5
  110. package/wolfram/CMakeLists.txt +0 -18
  111. package/wolfram/README.md +0 -13
  112. package/wolfram/lib.cpp +0 -160
  113. package/wolfram/test.wls +0 -27
@@ -1,15 +1,16 @@
1
1
  # USearch for JavaScript
2
2
 
3
+ USearch is a high-performance library for building and querying vector search indexes, optimized for Node.js and WASM environments.
4
+
3
5
  ## Installation
4
6
 
5
- USearch is available both for Node.js backend runtime and WASM frontend runtime.
6
- For the first option, use the conventional `npm install`:
7
+ For Node.js environments, install USearch using `npm`:
7
8
 
8
9
  ```sh
9
10
  npm install usearch
10
11
  ```
11
12
 
12
- For latter:
13
+ For front-end applications using WASM, use the Wasmer package manager:
13
14
 
14
15
  ```sh
15
16
  wasmer install unum/usearch
@@ -17,20 +18,71 @@ wasmer install unum/usearch
17
18
 
18
19
  ## Quickstart
19
20
 
21
+ Create an index, add vectors, and perform searches with ease:
22
+
20
23
  ```js
21
- var index = new usearch.Index({ metric: 'cos', connectivity: 16n, dimensions: 3n })
22
- index.add(42n, new Float32Array([0.2, 0.6, 0.4]))
23
- var results = index.search(new Float32Array([0.2, 0.6, 0.4]), 10n)
24
+ const usearch = require('usearch');
25
+ const index = new usearch.Index({ metric: 'cos', connectivity: 16, dimensions: 3 });
26
+ index.add(42n, new Float32Array([0.2, 0.6, 0.4]));
27
+ const results = index.search(new Float32Array([0.2, 0.6, 0.4]), 10);
28
+
29
+ assert(index.size() === 1);
30
+ assert.deepEqual(results.keys, new BigUint64Array([42n]));
31
+ assert.deepEqual(results.distances, new Float32Array([0]));
24
32
 
25
- assert.equal(index.size(), 1n)
26
- assert.deepEqual(results.keys, new BigUint64Array([42n]))
27
- assert.deepEqual(results.distances, new Float32Array([0]))
33
+ index.remove(42n);
28
34
  ```
29
35
 
30
36
  ## Serialization
31
37
 
38
+ Persist and restore your index with serialization methods:
39
+
40
+ ```js
41
+ index.save('index.usearch'); // Save the index to a file
42
+ index.load('index.usearch'); // Load the index from a file
43
+ index.view('index.usearch'); // View the index from a file without loading into memory
44
+ ```
45
+
46
+ ## Advanced Index Configuration
47
+
48
+ Customize your index with additional configuration options:
49
+
50
+ ```js
51
+ const index = new usearch.Index({
52
+ dimensions: 128,
53
+ metric: 'ip',
54
+ quantization: 'f32',
55
+ connectivity: 10,
56
+ expansion_add: 5,
57
+ expansion_search: 3,
58
+ multi: true
59
+ });
60
+ ```
61
+
62
+ ## Batch Operations
63
+
64
+ Process multiple vectors at once for efficiency.
65
+ For performance reasons we prefer a flattened `TypedArray` over an Array of Arrays:
66
+
67
+ ```js
68
+ const keys = new BigUint64Array([15n, 16n]);
69
+ const vectors = new Float32Array([10, 20, 10, 25]);
70
+ index.add(keys, vectors);
71
+ ```
72
+
73
+ Retrieve batch search results:
74
+
75
+ ```js
76
+ const batchResults = index.search(vectors, 2);
77
+ const firstMatch = batchResults.get(0);
78
+ ```
79
+
80
+ ## Index Introspection
81
+
82
+ Inspect and interact with the index:
83
+
32
84
  ```js
33
- index.save('index.usearch')
34
- index.load('index.usearch')
35
- index.view('index.usearch')
85
+ const dimensions = index.dimensions(); // Get the number of dimensions
86
+ const containsKey = index.contains(42n); // Check if a key is in the index
87
+ const count = index.count(42n); // Get the count of vectors for a key
36
88
  ```
@@ -181,7 +181,7 @@ Napi::Value CompiledIndex::Search(Napi::CallbackInfo const& ctx) {
181
181
  std::size_t tasks = queries.ElementLength() / native_->dimensions();
182
182
  std::size_t wanted = napi_argument_to_size(ctx[1]);
183
183
 
184
- auto run_parallel = [&](auto vectors) {
184
+ auto run_parallel = [&](auto vectors) -> Napi::Value {
185
185
  Napi::Array result_js = Napi::Array::New(env, 3);
186
186
  Napi::BigUint64Array matches_js = Napi::BigUint64Array::New(env, tasks * wanted);
187
187
  Napi::Float32Array distances_js = Napi::Float32Array::New(env, tasks * wanted);
@@ -192,21 +192,29 @@ Napi::Value CompiledIndex::Search(Napi::CallbackInfo const& ctx) {
192
192
  auto counts_data = counts_js.Data();
193
193
 
194
194
  try {
195
+ bool failed = false;
195
196
  executor_stl_t executor;
196
197
  executor.fixed(tasks, [&](std::size_t /*thread_idx*/, std::size_t task_idx) {
197
198
  auto result = native_->search(vectors + task_idx * native_->dimensions(), wanted);
198
199
  if (!result) {
199
- // Handle the error appropriately
200
- // For example, log the error or set some flag in the result_js object
200
+ failed = true;
201
+ Napi::TypeError::New(env, result.error.release()).ThrowAsJavaScriptException();
201
202
  } else {
202
203
  counts_data[task_idx] = result.dump_to(matches_data + task_idx * native_->dimensions(),
203
204
  distances_data + task_idx * native_->dimensions());
204
205
  }
205
206
  });
207
+
208
+ if (failed)
209
+ return env.Null();
210
+
206
211
  } catch (std::bad_alloc const&) {
207
212
  Napi::TypeError::New(env, "Out of memory").ThrowAsJavaScriptException();
213
+ return env.Null();
214
+
208
215
  } catch (...) {
209
216
  Napi::TypeError::New(env, "Search failed").ThrowAsJavaScriptException();
217
+ return env.Null();
210
218
  }
211
219
 
212
220
  result_js.Set(0u, matches_js);
@@ -247,10 +247,12 @@ class Index {
247
247
  // Call the compiled method and create Matches or BatchMatches object with the result
248
248
  const result = this._compiledIndex.search(normalizedVectors, k);
249
249
  const countInQueries = normalizedVectors.length / Number(this._compiledIndex.dimensions());
250
+ const batchMatches = new BatchMatches(result[0], result[1], result[2], k);
251
+
250
252
  if (countInQueries === 1) {
251
- return new Matches(result[0], result[1]);
253
+ return batchMatches.get(0);
252
254
  } else {
253
- return new BatchMatches(result[0], result[1], result[2], k);
255
+ return batchMatches;
254
256
  }
255
257
  }
256
258
 
@@ -36,6 +36,21 @@ test('Batch operations', () => {
36
36
  assert.deepEqual(results.distances, new Float32Array([45, 130]), 'distances should be 45 and 130');
37
37
  });
38
38
 
39
+ test("Expected results", () => {
40
+ var index = new usearch.Index({
41
+ metric: "cos",
42
+ connectivity: 16,
43
+ dimensions: 3,
44
+ });
45
+ index.add(42n, new Float32Array([0.2, 0.6, 0.4]));
46
+ var results = index.search(new Float32Array([0.2, 0.6, 0.4]), 10);
47
+
48
+ assert.equal(index.size(), 1);
49
+ assert.deepEqual(results.keys, new BigUint64Array([42n]));
50
+ assert.deepEqual(results.distances, new Float32Array([0]));
51
+ });
52
+
53
+
39
54
 
40
55
  test('Operations with invalid values', () => {
41
56
  const indexBatch = new usearch.Index(2, 'l2sq');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "usearch",
3
- "version": "2.8.7",
3
+ "version": "2.8.9",
4
4
  "description": "Smaller & Faster Single-File Vector Search Engine from Unum",
5
5
  "author": "Ash Vardanian (https://ashvardanian.com/)",
6
6
  "license": "Apache 2.0",
@@ -24,7 +24,6 @@
24
24
  "node-addon-api": "^3.0.0"
25
25
  },
26
26
  "scripts": {
27
- "preinstall": "git submodule update --init --recursive",
28
27
  "test": "node --test ./javascript/usearch.test.js",
29
28
  "install": "node-gyp rebuild"
30
29
  },
package/setup.py CHANGED
@@ -5,19 +5,49 @@ from setuptools import setup
5
5
 
6
6
  from pybind11.setup_helpers import Pybind11Extension
7
7
 
8
-
9
8
  compile_args = []
10
9
  link_args = []
11
10
  macros_args = []
12
11
 
13
- def is_gcc():
12
+
13
+ def get_bool_env(name: str, preference: bool) -> bool:
14
+ return os.environ.get(name, "1" if preference else "0") == "1"
15
+
16
+
17
+ def get_bool_env_w_name(name: str, preference: bool) -> bool:
18
+ return name, get_bool_env(name, preference)
19
+
20
+
21
+ def get_is_gcc():
14
22
  try:
15
- compiler_version = subprocess.check_output(["c++", "--version"], universal_newlines=True)
23
+ compiler_version = subprocess.check_output(
24
+ ["c++", "--version"], universal_newlines=True
25
+ )
16
26
  return "gcc" in compiler_version.lower()
17
27
  except Exception:
18
28
  return False
19
29
 
20
- if sys.platform == "linux":
30
+
31
+ # Check the environment variables
32
+ is_linux: bool = sys.platform == "linux"
33
+ is_macos: bool = sys.platform == "darwin"
34
+ is_windows: bool = sys.platform == "win32"
35
+
36
+ prefer_simsimd: bool = is_linux or is_macos
37
+ prefer_fp16lib: bool = True
38
+ prefer_openmp: bool = is_linux and get_is_gcc()
39
+
40
+ use_simsimd: bool = get_bool_env("USEARCH_USE_SIMSIMD", prefer_simsimd)
41
+ use_fp16lib: bool = get_bool_env("USEARCH_USE_FP16LIB", prefer_fp16lib)
42
+ use_openmp: bool = get_bool_env("USEARCH_USE_OPENMP", prefer_openmp)
43
+
44
+
45
+ # Common arguments for all platforms
46
+ macros_args.append(("USEARCH_USE_OPENMP", "1" if use_openmp else "0"))
47
+ macros_args.append(("USEARCH_USE_SIMSIMD", "1" if use_simsimd else "0"))
48
+ macros_args.append(("USEARCH_USE_FP16LIB", "1" if use_fp16lib else "0"))
49
+
50
+ if is_linux:
21
51
  compile_args.append("-std=c++17")
22
52
  compile_args.append("-O3") # Maximize performance
23
53
  compile_args.append("-ffast-math") # Maximize floating-point performance
@@ -27,17 +57,21 @@ if sys.platform == "linux":
27
57
  # Simplify debugging, but the normal `-g` may make builds much longer!
28
58
  compile_args.append("-g1")
29
59
 
30
- macros_args.append(("USEARCH_USE_NATIVE_F16", "0"))
31
- macros_args.append(("USEARCH_USE_SIMSIMD", "1"))
32
-
33
- if is_gcc():
34
- macros_args.append(("USEARCH_USE_OPENMP", "1"))
60
+ if use_openmp:
35
61
  compile_args.append("-fopenmp")
36
62
  link_args.append("-lgomp")
37
- else:
38
- macros_args.append(("USEARCH_USE_OPENMP", "0"))
39
63
 
40
- if sys.platform == "darwin":
64
+ if use_simsimd:
65
+ macros_args.extend(
66
+ [
67
+ get_bool_env_w_name("SIMSIMD_TARGET_X86_AVX512", True),
68
+ get_bool_env_w_name("SIMSIMD_TARGET_ARM_SVE", True),
69
+ get_bool_env_w_name("SIMSIMD_TARGET_X86_AVX2", True),
70
+ get_bool_env_w_name("SIMSIMD_TARGET_ARM_NEON", True),
71
+ ]
72
+ )
73
+
74
+ if is_macos:
41
75
  # MacOS 10.15 or higher is needed for `aligned_alloc` support.
42
76
  # https://github.com/unum-cloud/usearch/actions/runs/4975434891/jobs/8902603392
43
77
  compile_args.append("-mmacosx-version-min=10.15")
@@ -61,12 +95,34 @@ if sys.platform == "darwin":
61
95
  # link_args.append("-lomp")
62
96
  # macros_args.append(("USEARCH_USE_OPENMP", "1"))
63
97
 
64
- if sys.platform == "win32":
98
+ if use_simsimd:
99
+ macros_args.extend(
100
+ [
101
+ get_bool_env_w_name("SIMSIMD_TARGET_X86_AVX512", False),
102
+ get_bool_env_w_name("SIMSIMD_TARGET_ARM_SVE", False),
103
+ get_bool_env_w_name("SIMSIMD_TARGET_X86_AVX2", True),
104
+ get_bool_env_w_name("SIMSIMD_TARGET_ARM_NEON", True),
105
+ ]
106
+ )
107
+
108
+ if is_windows:
65
109
  compile_args.append("/std:c++17")
66
110
  compile_args.append("/O2")
67
111
  compile_args.append("/fp:fast") # Enable fast math for MSVC
68
112
  compile_args.append("/W1") # Reduce warnings verbosity
69
113
 
114
+ # We don't actually want to use any SimSIMD stuff,
115
+ # as GCC attributes aren't compatible with MSVC
116
+ if use_simsimd:
117
+ macros_args.extend(
118
+ [
119
+ get_bool_env_w_name("SIMSIMD_TARGET_X86_AVX512", False),
120
+ get_bool_env_w_name("SIMSIMD_TARGET_ARM_SVE", False),
121
+ get_bool_env_w_name("SIMSIMD_TARGET_X86_AVX2", False),
122
+ get_bool_env_w_name("SIMSIMD_TARGET_ARM_NEON", False),
123
+ ]
124
+ )
125
+
70
126
  ext_modules = [
71
127
  Pybind11Extension(
72
128
  "usearch.compiled",
@@ -80,11 +136,16 @@ ext_modules = [
80
136
  __version__ = open("VERSION", "r").read().strip()
81
137
  __lib_name__ = "usearch"
82
138
 
83
-
84
139
  this_directory = os.path.abspath(os.path.dirname(__file__))
85
140
  with open(os.path.join(this_directory, "README.md")) as f:
86
141
  long_description = f.read()
87
142
 
143
+ # Depending on the macros, adjust the include directories
144
+ include_dirs = ["include"]
145
+ if use_simsimd:
146
+ include_dirs.append("simsimd/include")
147
+ if use_fp16lib:
148
+ include_dirs.append("fp16/include")
88
149
 
89
150
  setup(
90
151
  name=__lib_name__,
@@ -118,7 +179,7 @@ setup(
118
179
  "Topic :: Database :: Database Engines/Servers",
119
180
  "Topic :: Scientific/Engineering :: Artificial Intelligence",
120
181
  ],
121
- include_dirs=["include", "fp16/include", "simsimd/include"],
182
+ include_dirs=include_dirs,
122
183
  ext_modules=ext_modules,
123
184
  install_requires=[
124
185
  "numpy",
package/simsimd/README.md CHANGED
@@ -30,24 +30,23 @@ SimSIMD leverages SIMD intrinsics, capabilities that only select compilers effec
30
30
 
31
31
  Given 1000 embeddings from OpenAI Ada API with 1536 dimensions, running on the Apple M2 Pro Arm CPU with NEON support, here's how SimSIMD performs against conventional methods:
32
32
 
33
- | Conventional | SimSIMD | `f32` improvement | `f16` improvement | `i8` improvement |
34
- | :------------------------------------- | :---------------- | ----------------: | ----------------: | ---------------: |
35
- | `numpy.inner` | `inner` | __2 x__ | __9 x__ | __18 x__ |
36
- | `scipy.spatial.distance.cosine` | `cosine` | __32 x__ | __79 x__ | __133 x__ |
37
- | `scipy.spatial.distance.sqeuclidean` | `sqeuclidean` | __5 x__ | __26 x__ | __17 x__ |
38
- | `scipy.spatial.distance.jensenshannon` | `jensenshannon` | __31 x__ | __53 x__ | |
39
- | `scipy.special.kl_div` | `kullbackleibler` | __21 x__ | __18 x__ | |
33
+ | Kind | `f32` improvement | `f16` improvement | `i8` improvement | Conventional method | SimSIMD |
34
+ | :------------- | ----------------: | ----------------: | ---------------: | :------------------------------------- | :-------------- |
35
+ | Cosine | __32 x__ | __79 x__ | __133 x__ | `scipy.spatial.distance.cosine` | `cosine` |
36
+ | Euclidean ² | __5 x__ | __26 x__ | __17 x__ | `scipy.spatial.distance.sqeuclidean` | `sqeuclidean` |
37
+ | Inner Product | __2 x__ | __9 x__ | __18 x__ | `numpy.inner` | `inner` |
38
+ | Jensen Shannon | __31 x__ | __53 x__ | | `scipy.spatial.distance.jensenshannon` | `jensenshannon` |
40
39
 
41
40
  ### Intel Sapphire Rapids
42
41
 
43
42
  On the Intel Sapphire Rapids platform, SimSIMD was benchmarked against auto-vectorized code using GCC 12. GCC handles single-precision `float`, but might not be the best choice for `int8` and `_Float16` arrays, which has been part of the C language since 2011.
44
43
 
45
- | | GCC 12 `f32` | GCC 12 `f16` | SimSIMD `f16` | `f16` improvement |
46
- | :-------------- | -----------: | -----------: | ------------: | ----------------: |
47
- | `cosine` | 3.28 M/s | _336.29 k/s_ | _6.88 M/s_ | __20 x__ |
48
- | `sqeuclidean` | 4.62 M/s | _147.25 k/s_ | _5.32 M/s_ | __36 x__ |
49
- | `inner` | 3.81 M/s | _192.02 k/s_ | _5.99 M/s_ | __31 x__ |
50
- | `jensenshannon` | 1.18 M/s | _18.13 k/s_ | _2.14 M/s_ | __118 x__ |
44
+ | Kind | GCC 12 `f32` | GCC 12 `f16` | SimSIMD `f16` | `f16` improvement |
45
+ | :------------- | -----------: | -----------: | ------------: | ----------------: |
46
+ | Cosine | 3.28 M/s | _336.29 k/s_ | _6.88 M/s_ | __20 x__ |
47
+ | Euclidean ² | 4.62 M/s | _147.25 k/s_ | _5.32 M/s_ | __36 x__ |
48
+ | Inner Product | 3.81 M/s | _192.02 k/s_ | _5.99 M/s_ | __31 x__ |
49
+ | Jensen Shannon | 1.18 M/s | _18.13 k/s_ | _2.14 M/s_ | __118 x__ |
51
50
 
52
51
  __Technical Insights__:
53
52
 
@@ -173,6 +172,8 @@ Stay updated with the latest advancements by always using the most recent compil
173
172
 
174
173
  Should you wish to integrate SimSIMD within USearch, simply compile USearch with the flag `USEARCH_USE_SIMSIMD=1`. Notably, this is the default setting on the majority of platforms.
175
174
 
175
+ ## Benchmarking and Contributing
176
+
176
177
  __To rerun experiments__ utilize the following command:
177
178
 
178
179
  ```sh
@@ -425,8 +425,8 @@ simsimd_avx512_f32_js_cycle:
425
425
  __mmask16 nonzero_mask_b = _mm512_cmp_ps_mask(b_vec, epsilon_vec, _CMP_GE_OQ);
426
426
  __mmask16 nonzero_mask = nonzero_mask_a & nonzero_mask_b;
427
427
  __m512 m_recip_approx = _mm512_rcp14_ps(m_vec);
428
- __m512 ratio_a_vec = _mm512_div_ps(a_vec, m_vec);
429
- __m512 ratio_b_vec = _mm512_div_ps(b_vec, m_vec);
428
+ __m512 ratio_a_vec = _mm512_mul_ps(a_vec, m_recip_approx);
429
+ __m512 ratio_b_vec = _mm512_mul_ps(b_vec, m_recip_approx);
430
430
  __m512 log_ratio_a_vec = simsimd_avx512_f32_log2(ratio_a_vec);
431
431
  __m512 log_ratio_b_vec = simsimd_avx512_f32_log2(ratio_b_vec);
432
432
  sum_a_vec = _mm512_maskz_fmadd_ps(nonzero_mask, a_vec, log_ratio_a_vec, sum_a_vec);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simsimd",
3
- "version": "3.5.3",
3
+ "version": "3.5.4",
4
4
  "description": "Vector Similarity Functions 3x-200x Faster than SciPy and NumPy",
5
5
  "author": "Ash Vardanian",
6
6
  "license": "Apache 2.0",
package/wasmer.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name="unum/usearch"
3
- version="2.8.7"
3
+ version="2.8.9"
4
4
  description="Smaller & Faster Single-File Vector Search Engine from Unum"
5
5
  license="Apache-2.0"
6
6
  readme="README.md"
package/. npmignore DELETED
@@ -1,14 +0,0 @@
1
- node_modules/
2
- .vscode/
3
- build/
4
- csharp/
5
- golang/
6
- java/
7
- objc/
8
- rust/
9
- swift/
10
- wolfram/
11
- python/
12
- docs/
13
- wasm/
14
- Package.swift
package/.gitignore DELETED
@@ -1,95 +0,0 @@
1
- # Ignore all files without an extension
2
- *
3
- !/**/
4
- !*.*
5
-
6
- # Temporary files
7
- .DS_Store
8
- *.fbin
9
- *.ibin
10
- datasets
11
- bin
12
- *.usearch
13
- .cache
14
-
15
- # C++ builds
16
- build
17
- build_release
18
- build_debug
19
- build_artifacts
20
- _deps
21
- CMakeCache.txt
22
- CMakeFiles
23
- cmake_install.cmake
24
-
25
- # Profiling with GProf and `perf` on Linux
26
- gmon.out
27
- perf.data
28
-
29
- # Python wrappers
30
- __pycache__
31
- *.egg-info
32
- dist/
33
- wheelhouse/
34
-
35
- # Python Environments
36
- venv/
37
-
38
- # JS wrappers
39
- package-lock.json
40
- node_modules/
41
-
42
- # Rust builds
43
- Cargo.lock
44
- target/
45
-
46
- # Java bindings
47
- .gradle
48
- *.class
49
-
50
- # ObjC and Swift
51
- .build
52
- .swiftpm
53
-
54
- # C# builds
55
- csharp/**/[Bb]in/
56
- csharp/**/[Oo]bj/
57
- csharp/lib
58
- csharp/packages
59
-
60
- # Prerequisites
61
- *.d
62
-
63
- # Compiled Object files
64
- *.slo
65
- *.lo
66
- *.o
67
- *.obj
68
-
69
- # Precompiled Headers
70
- *.gch
71
- *.pch
72
-
73
- # Compiled Dynamic libraries
74
- *.so
75
- *.dylib
76
- *.dll
77
-
78
- # Fortran module files
79
- *.mod
80
- *.smod
81
-
82
- # Allow golang go.mod
83
- !go.mod
84
-
85
- # Compiled Static libraries
86
- *.lai
87
- *.la
88
- *.a
89
- *.lib
90
-
91
- # Executables
92
- *.exe
93
- *.out
94
- *.app
95
-