usearch 0.4.0 → 0.8.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.
Files changed (45) hide show
  1. package/.clang-tidy +60 -0
  2. package/.github/workflows/release.yml +42 -16
  3. package/.github/workflows/update_version.sh +1 -0
  4. package/.vscode/launch.json +22 -0
  5. package/.vscode/settings.json +5 -0
  6. package/.vscode/tasks.json +4 -4
  7. package/CITATION.cff +11 -0
  8. package/CMakeLists.txt +108 -95
  9. package/Cargo.toml +1 -1
  10. package/Dockerfile +14 -0
  11. package/README.md +8 -7
  12. package/VERSION +1 -1
  13. package/binding.gyp +2 -2
  14. package/build.rs +2 -2
  15. package/cmake/config.cmake.in +15 -0
  16. package/cmake/pkg-config.pc.in +4 -0
  17. package/cmake/usearchConfigVersion.cmake.in +20 -0
  18. package/conanfile.py +1 -1
  19. package/docs/benchmarks.md +11 -2
  20. package/docs/{Compilation.md → compilation.md} +54 -27
  21. package/include/usearch/usearch.hpp +664 -390
  22. package/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp +17 -16
  23. package/javascript/lib.cpp +13 -13
  24. package/javascript/test.js +1 -1
  25. package/objc/USearchObjective.mm +46 -29
  26. package/objc/include/USearchObjective.h +18 -26
  27. package/package.json +1 -1
  28. package/pyproject.toml +3 -2
  29. package/python/lib.cpp +179 -120
  30. package/python/scripts/bench.py +188 -0
  31. package/python/scripts/bench_params.py +113 -0
  32. package/python/{test.py → scripts/test.py} +32 -13
  33. package/python/usearch/client.py +100 -14
  34. package/python/usearch/server.py +104 -23
  35. package/rust/lib.cpp +15 -14
  36. package/rust/lib.hpp +5 -5
  37. package/rust/lib.rs +3 -3
  38. package/setup.py +7 -0
  39. package/src/CMakeLists.txt +107 -0
  40. package/src/bench.cpp +45 -15
  41. package/src/{advanced.hpp → punned.hpp} +227 -199
  42. package/src/test.cpp +62 -0
  43. package/swift/Test.swift +1 -1
  44. package/wolfram/lib.cpp +14 -14
  45. package/python/bench.py +0 -146
package/rust/lib.cpp CHANGED
@@ -4,9 +4,9 @@
4
4
  using namespace unum::usearch;
5
5
  using namespace unum;
6
6
 
7
- using native_index_t = typename Index::native_index_t;
7
+ using punned_t = typename Index::punned_t;
8
8
 
9
- Index::Index(std::shared_ptr<native_index_t> index) : index_(index) {}
9
+ Index::Index(std::shared_ptr<punned_t> index) : index_(index) {}
10
10
 
11
11
  void Index::add_in_thread(uint32_t label, rust::Slice<float const> vector, size_t thread) const {
12
12
  add_config_t config;
@@ -22,7 +22,8 @@ Matches Index::search_in_thread(rust::Slice<float const> vector, size_t count, s
22
22
  results.labels.push_back(0), results.distances.push_back(0);
23
23
  search_config_t config;
24
24
  config.thread = thread;
25
- results.count = index_->search(vector.data(), count, results.labels.data(), results.distances.data(), config);
25
+ results.count =
26
+ index_->search(vector.data(), count, config).dump_to(results.labels.data(), results.distances.data());
26
27
  results.labels.truncate(results.count);
27
28
  results.distances.truncate(results.count);
28
29
  return results;
@@ -38,7 +39,7 @@ Matches Index::search(rust::Slice<float const> vector, size_t count) const {
38
39
  results.distances.reserve(count);
39
40
  for (size_t i = 0; i != count; ++i)
40
41
  results.labels.push_back(0), results.distances.push_back(0);
41
- results.count = index_->search(vector.data(), count, results.labels.data(), results.distances.data());
42
+ results.count = index_->search(vector.data(), count).dump_to(results.labels.data(), results.distances.data());
42
43
  results.labels.truncate(results.count);
43
44
  results.distances.truncate(results.count);
44
45
  return results;
@@ -57,31 +58,31 @@ void Index::view(rust::Str path) const { index_->view(std::string(path).c_str())
57
58
 
58
59
  accuracy_t accuracy(rust::Str quant) { return accuracy_from_name(quant.data(), quant.size()); }
59
60
 
60
- std::unique_ptr<Index> wrap(native_index_t&& index) {
61
- std::shared_ptr<native_index_t> native = std::make_shared<native_index_t>(std::move(index));
61
+ std::unique_ptr<Index> wrap(punned_t&& index) {
62
+ std::shared_ptr<punned_t> native = std::make_shared<punned_t>(std::move(index));
62
63
  return std::unique_ptr<Index>(new Index(native));
63
64
  }
64
65
 
65
66
  config_t config(size_t connectivity, size_t exp_add, size_t exp_search) {
66
67
  config_t result;
67
- result.connectivity = connectivity ? connectivity : config_t::connectivity_default_k;
68
- result.expansion_add = exp_add ? exp_add : config_t::expansion_add_default_k;
69
- result.expansion_search = exp_search ? exp_search : config_t::expansion_search_default_k;
68
+ result.connectivity = connectivity ? connectivity : default_connectivity();
69
+ result.expansion_add = exp_add ? exp_add : default_expansion_add();
70
+ result.expansion_search = exp_search ? exp_search : default_expansion_search();
70
71
  return result;
71
72
  }
72
73
 
73
74
  std::unique_ptr<Index> new_ip(size_t dims, rust::Str quant, size_t connectivity, size_t exp_add, size_t exp_search) {
74
- return wrap(native_index_t::ip(dims, accuracy(quant), config(connectivity, exp_add, exp_search)));
75
+ return wrap(punned_t::ip(dims, accuracy(quant), config(connectivity, exp_add, exp_search)));
75
76
  }
76
77
 
77
- std::unique_ptr<Index> new_l2(size_t dims, rust::Str quant, size_t connectivity, size_t exp_add, size_t exp_search) {
78
- return wrap(native_index_t::l2(dims, accuracy(quant), config(connectivity, exp_add, exp_search)));
78
+ std::unique_ptr<Index> new_l2sq(size_t dims, rust::Str quant, size_t connectivity, size_t exp_add, size_t exp_search) {
79
+ return wrap(punned_t::l2sq(dims, accuracy(quant), config(connectivity, exp_add, exp_search)));
79
80
  }
80
81
 
81
82
  std::unique_ptr<Index> new_cos(size_t dims, rust::Str quant, size_t connectivity, size_t exp_add, size_t exp_search) {
82
- return wrap(native_index_t::cos(dims, accuracy(quant), config(connectivity, exp_add, exp_search)));
83
+ return wrap(punned_t::cos(dims, accuracy(quant), config(connectivity, exp_add, exp_search)));
83
84
  }
84
85
 
85
86
  std::unique_ptr<Index> new_haversine(rust::Str quant, size_t connectivity, size_t exp_add, size_t exp_search) {
86
- return wrap(native_index_t::haversine(accuracy(quant), config(connectivity, exp_add, exp_search)));
87
+ return wrap(punned_t::haversine(accuracy(quant), config(connectivity, exp_add, exp_search)));
87
88
  }
package/rust/lib.hpp CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  #include <memory> // `std::shared_ptr`
5
5
 
6
- #include "advanced.hpp"
6
+ #include "punned.hpp"
7
7
 
8
8
  struct Matches;
9
9
 
@@ -15,9 +15,9 @@ class Index {
15
15
  public:
16
16
  using label_t = std::uint32_t;
17
17
  using distance_t = unum::usearch::punned_distance_t;
18
- using native_index_t = unum::usearch::auto_index_gt<label_t>;
18
+ using punned_t = unum::usearch::punned_gt<label_t>;
19
19
 
20
- Index(std::shared_ptr<native_index_t> index);
20
+ Index(std::shared_ptr<punned_t> index);
21
21
 
22
22
  void reserve(size_t) const;
23
23
 
@@ -37,10 +37,10 @@ class Index {
37
37
  void view(rust::Str path) const;
38
38
 
39
39
  private:
40
- std::shared_ptr<native_index_t> index_;
40
+ std::shared_ptr<punned_t> index_;
41
41
  };
42
42
 
43
43
  std::unique_ptr<Index> new_ip(size_t dims, rust::Str quant, size_t connectivity, size_t exp_add, size_t exp_search);
44
- std::unique_ptr<Index> new_l2(size_t dims, rust::Str quant, size_t connectivity, size_t exp_add, size_t exp_search);
44
+ std::unique_ptr<Index> new_l2sq(size_t dims, rust::Str quant, size_t connectivity, size_t exp_add, size_t exp_search);
45
45
  std::unique_ptr<Index> new_cos(size_t dims, rust::Str quant, size_t connectivity, size_t exp_add, size_t exp_search);
46
46
  std::unique_ptr<Index> new_haversine(rust::Str quant, size_t connectivity, size_t exp_add, size_t exp_search);
package/rust/lib.rs CHANGED
@@ -15,7 +15,7 @@ pub mod ffi {
15
15
  type Index;
16
16
 
17
17
  fn new_ip(dimensions: usize, quantization: &str, connectivity: usize, expansion_add: usize, expansion_search: usize) -> Result<UniquePtr<Index>>;
18
- fn new_l2(dimensions: usize, quantization: &str, connectivity: usize, expansion_add: usize, expansion_search: usize) -> Result<UniquePtr<Index>>;
18
+ fn new_l2sq(dimensions: usize, quantization: &str, connectivity: usize, expansion_add: usize, expansion_search: usize) -> Result<UniquePtr<Index>>;
19
19
  fn new_cos(dimensions: usize, quantization: &str, connectivity: usize, expansion_add: usize, expansion_search: usize) -> Result<UniquePtr<Index>>;
20
20
  fn new_haversine(quantization: &str, connectivity: usize, expansion_add: usize, expansion_search: usize) -> Result<UniquePtr<Index>>;
21
21
 
@@ -42,7 +42,7 @@ pub mod ffi {
42
42
  #[cfg(test)]
43
43
  mod tests {
44
44
  use crate::ffi::new_ip;
45
- use crate::ffi::new_l2;
45
+ use crate::ffi::new_l2sq;
46
46
  use crate::ffi::new_cos;
47
47
  use crate::ffi::new_haversine;
48
48
 
@@ -76,7 +76,7 @@ mod tests {
76
76
 
77
77
  // Make sure every function is called at least once
78
78
  assert!(new_ip(5, &quant, 0, 0, 0).is_ok());
79
- assert!(new_l2(5, &quant, 0, 0, 0).is_ok());
79
+ assert!(new_l2sq(5, &quant, 0, 0, 0).is_ok());
80
80
  assert!(new_cos(5, &quant, 0, 0, 0).is_ok());
81
81
  assert!(new_haversine(&quant, 0, 0, 0).is_ok());
82
82
  }
package/setup.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import sys
3
+ import platform
3
4
  from setuptools import setup
4
5
  from pybind11.setup_helpers import Pybind11Extension
5
6
 
@@ -10,15 +11,21 @@ link_args = []
10
11
  if sys.platform == 'linux':
11
12
  compile_args.append('-fopenmp')
12
13
  link_args.append('-lgomp')
14
+ compile_args.append('-Wno-unknown-pragmas')
13
15
 
14
16
  if sys.platform == 'darwin':
15
17
  # MacOS 10.15 orhigher is needed for `aligned_alloc` support.
16
18
  # https://github.com/unum-cloud/usearch/actions/runs/4975434891/jobs/8902603392
17
19
  compile_args.append('-mmacosx-version-min=10.15')
20
+ compile_args.append('-Wno-unknown-pragmas')
18
21
 
19
22
  if sys.platform == 'win32':
20
23
  compile_args = ['/std:c++14', '/O2']
21
24
 
25
+ if platform.machine() == 'arm64':
26
+ compile_args.append('-march=armv8.2-a+simd+fp16+fp16fml+dotprod')
27
+ elif platform.machine() in ('i386', 'AMD64', 'x86_64'):
28
+ compile_args.append('-march=haswell')
22
29
 
23
30
  ext_modules = [
24
31
  Pybind11Extension(
@@ -0,0 +1,107 @@
1
+ cmake_minimum_required(VERSION 3.1)
2
+
3
+ option(USEARCH_USE_OPENMP "Use OpenMP for a thread pool" OFF)
4
+ option(USEARCH_USE_SIMSIMD "Use SimSIMD hardware-accelerated metrics" OFF)
5
+ option(USEARCH_USE_JEMALLOC "Use JeMalloc for faster memory allocations" OFF)
6
+
7
+ # Make "Release" by default
8
+ if(NOT CMAKE_BUILD_TYPE)
9
+ set(CMAKE_BUILD_TYPE Release)
10
+ endif()
11
+
12
+ # List of all possible compiler IDs:
13
+ # https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html
14
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
15
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address")
16
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra -Wno-conversion -Wno-unknown-pragmas")
17
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
18
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmax-errors=1")
19
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
20
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
21
+
22
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
23
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wfatal-errors")
24
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
25
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
26
+
27
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "NVIDIA" OR CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC")
28
+ set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --extended-lambda")
29
+ set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -gencode arch=compute_86,code=sm_86")
30
+ set_property(SOURCE bench.cpp PROPERTY LANGUAGE CUDA)
31
+ set_target_properties(bench PROPERTIES POSITION_INDEPENDENT_CODE ON)
32
+ set_target_properties(bench PROPERTIES CUDA_ARCHITECTURES "86")
33
+
34
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
35
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w")
36
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ferror-limit=1")
37
+
38
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
39
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /DEBUG")
40
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2")
41
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /O2 /DEBUG")
42
+ else()
43
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0")
44
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
45
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -pg -g")
46
+ endif()
47
+
48
+ if(APPLE)
49
+ set(CMAKE_THREAD_LIBS_INIT "-lpthread")
50
+ set(CMAKE_HAVE_THREADS_LIBRARY 1)
51
+ set(CMAKE_USE_WIN32_THREADS_INIT 0)
52
+ set(CMAKE_USE_PTHREADS_INIT 1)
53
+ set(THREADS_PREFER_PTHREAD_FLAG ON)
54
+ endif()
55
+
56
+ find_package(Threads REQUIRED)
57
+
58
+ if(${USEARCH_USE_OPENMP})
59
+ find_package(OpenMP REQUIRED)
60
+ include_directories(${OPENMP_INCLUDE_DIRS})
61
+ endif()
62
+
63
+ if(${USEARCH_USE_JEMALLOC})
64
+ include(jemalloc)
65
+ endif()
66
+
67
+ include(clipp)
68
+
69
+ set(USEARCH_PUNNED_INCLUDE_DIRS
70
+ "${CMAKE_CURRENT_SOURCE_DIR}/../include"
71
+ "${CMAKE_CURRENT_SOURCE_DIR}/../fp16/include"
72
+ "${CMAKE_CURRENT_SOURCE_DIR}/../simsimd/include"
73
+ "${CMAKE_CURRENT_SOURCE_DIR}/"
74
+ )
75
+
76
+ if(${USEARCH_BUILD_TEST})
77
+ add_executable(test test.cpp)
78
+ target_link_libraries(test PRIVATE Threads::Threads)
79
+ target_include_directories(test PRIVATE ${USEARCH_PUNNED_INCLUDE_DIRS})
80
+ set_target_properties(test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
81
+
82
+ if(${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13)
83
+ include(CTest)
84
+ enable_testing()
85
+ add_test(NAME test COMMAND test)
86
+ endif()
87
+ endif()
88
+
89
+ if(${USEARCH_BUILD_BENCHMARK})
90
+ add_executable(bench bench.cpp)
91
+ target_link_libraries(bench PRIVATE Threads::Threads)
92
+ target_include_directories(bench PRIVATE ${USEARCH_PUNNED_INCLUDE_DIRS})
93
+ set_target_properties(bench PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
94
+
95
+ if(${USEARCH_USE_SIMSIMD})
96
+ target_compile_definitions(bench PRIVATE USEARCH_USE_SIMSIMD=1)
97
+ endif()
98
+
99
+ if(${USEARCH_USE_OPENMP})
100
+ target_compile_definitions(bench PRIVATE USEARCH_USE_OPENMP=1)
101
+ target_link_libraries(bench PRIVATE ${OPENMP_LIBRARIES})
102
+ endif()
103
+
104
+ if(${USEARCH_USE_JEMALLOC})
105
+ target_link_libraries(bench PRIVATE ${JEMALLOC_LIBRARIES})
106
+ endif()
107
+ endif()
package/src/bench.cpp CHANGED
@@ -29,6 +29,7 @@
29
29
  #include <iostream> // `std::cerr`
30
30
  #include <numeric> // `std::iota`
31
31
  #include <stdexcept> // `std::invalid_argument`
32
+ #include <string> // `std::to_string`
32
33
  #include <thread> // `std::thread::hardware_concurrency()`
33
34
  #include <variant> // `std::monostate`
34
35
 
@@ -37,7 +38,7 @@
37
38
 
38
39
  #include <simsimd/simsimd.h>
39
40
 
40
- #include "advanced.hpp"
41
+ #include "punned.hpp"
41
42
 
42
43
  using namespace unum::usearch;
43
44
  using namespace unum;
@@ -227,7 +228,7 @@ struct running_stats_printer_t {
227
228
  running_stats_printer_t(std::size_t n, char const* msg) {
228
229
  std::printf("%s. %zu items\n", msg, n);
229
230
  total = n;
230
- start_time = std::chrono::high_resolution_clock::now();
231
+ last_printed_time = start_time = std::chrono::high_resolution_clock::now();
231
232
  }
232
233
 
233
234
  ~running_stats_printer_t() {
@@ -279,7 +280,8 @@ void index_many(index_at& native, std::size_t n, vector_id_at const* ids, real_a
279
280
  add_config_t config;
280
281
  config.thread = omp_get_thread_num();
281
282
  config.store_vector = true;
282
- native.add(ids[i], vector_view_t{vectors + dims * i, dims}, config);
283
+ vector_view_t vector{vectors + dims * i, dims};
284
+ native.add(ids[i], vector, config);
283
285
  printer.progress++;
284
286
  if (omp_get_thread_num() == 0)
285
287
  printer.refresh();
@@ -291,16 +293,35 @@ void search_many( //
291
293
  index_at& native, std::size_t n, real_at const* vectors, std::size_t dims, std::size_t wanted, vector_id_at* ids,
292
294
  real_at* distances) {
293
295
 
294
- running_stats_printer_t printer{n, "Search"};
296
+ std::string name = "Search " + std::to_string(wanted);
297
+ running_stats_printer_t printer{n, name.c_str()};
295
298
 
296
299
  #pragma omp parallel for schedule(static, 32)
297
300
  for (std::size_t i = 0; i < n; ++i) {
298
301
  search_config_t config;
299
302
  config.thread = omp_get_thread_num();
300
- native.search( //
301
- vector_view_t{vectors + dims * i, dims}, wanted, //
302
- ids + wanted * i, distances + wanted * i, //
303
- config);
303
+ vector_view_t vector{vectors + dims * i, dims};
304
+ native.search(vector, wanted, config).dump_to(ids + wanted * i, distances + wanted * i);
305
+ printer.progress++;
306
+ if (omp_get_thread_num() == 0)
307
+ printer.refresh();
308
+ }
309
+ }
310
+
311
+ template <typename index_at, typename vector_id_at, typename real_at>
312
+ void paginate_many( //
313
+ index_at& native, std::size_t n, real_at const* vectors, std::size_t dims, std::size_t wanted,
314
+ vector_id_at const* hints) {
315
+
316
+ std::string name = "Paginate " + std::to_string(wanted);
317
+ running_stats_printer_t printer{n, name.c_str()};
318
+
319
+ #pragma omp parallel for schedule(static, 32)
320
+ for (std::size_t i = 0; i < n; ++i) {
321
+ search_config_t config;
322
+ config.thread = omp_get_thread_num();
323
+ vector_view_t vector{vectors + dims * i, dims};
324
+ native.search_around(hints[i], vector, wanted, config);
304
325
  printer.progress++;
305
326
  if (omp_get_thread_num() == 0)
306
327
  printer.refresh();
@@ -338,6 +359,15 @@ static void single_shot(dataset_at& dataset, index_at& index, bool construct = t
338
359
 
339
360
  std::printf("Recall@1 %.2f %%\n", recall_at_1 * 100.f / dataset.queries_count());
340
361
  std::printf("Recall %.2f %%\n", recall_full * 100.f / dataset.queries_count());
362
+
363
+ // Paginate
364
+ std::vector<vector_id_t> hints(dataset.queries_count());
365
+ for (std::size_t i = 0; i != hints.size(); ++i)
366
+ hints[i] = dataset.neighborhood(i)[0];
367
+ paginate_many(index, dataset.queries_count(), dataset.query(0), dataset.dimensions(), 10, hints.data());
368
+ paginate_many(index, dataset.queries_count(), dataset.query(0), dataset.dimensions(), 100, hints.data());
369
+ paginate_many(index, dataset.queries_count(), dataset.query(0), dataset.dimensions(), 1000, hints.data());
370
+
341
371
  std::printf("------------\n");
342
372
  std::printf("\n");
343
373
  }
@@ -390,9 +420,9 @@ struct args_t {
390
420
  std::string path_neighbors;
391
421
  std::string path_output = "last.usearch";
392
422
 
393
- std::size_t connectivity = config_t::connectivity_default_k;
394
- std::size_t expansion_add = config_t::expansion_add_default_k;
395
- std::size_t expansion_search = config_t::expansion_search_default_k;
423
+ std::size_t connectivity = default_connectivity();
424
+ std::size_t expansion_add = default_expansion_add();
425
+ std::size_t expansion_search = default_expansion_search();
396
426
  std::size_t threads = std::thread::hardware_concurrency();
397
427
 
398
428
  std::size_t vectors_to_skip = 0;
@@ -415,7 +445,7 @@ template <typename index_at, typename dataset_at> //
415
445
  index_at type_punned_index_for_metric(dataset_at& dataset, args_t const& args, config_t config, accuracy_t accuracy) {
416
446
  if (args.metric_l2) {
417
447
  std::printf("-- Metric: Euclidean\n");
418
- return index_at::l2(dataset.dimensions(), accuracy, config);
448
+ return index_at::l2sq(dataset.dimensions(), accuracy, config);
419
449
  } else if (args.metric_cos) {
420
450
  std::printf("-- Metric: Angular\n");
421
451
  return index_at::cos(dataset.dimensions(), accuracy, config);
@@ -486,7 +516,7 @@ void run_big_or_small(dataset_at& dataset, args_t const& args, config_t config)
486
516
  run_typed<index_gt<ip_gt<float>, std::size_t, neighbor_id_at>>(dataset, args, config);
487
517
  }
488
518
  } else
489
- run_type_punned<auto_index_gt<std::size_t, neighbor_id_at>>(dataset, args, config);
519
+ run_type_punned<punned_gt<std::size_t, neighbor_id_at>>(dataset, args, config);
490
520
  }
491
521
 
492
522
  void report_alternative_setups() {
@@ -563,7 +593,7 @@ int main(int argc, char** argv) {
563
593
  option("--f8quant").set(args.quantize_f8).doc("Enable `f8_t` quantization")),
564
594
  ( //
565
595
  option("--ip").set(args.metric_ip).doc("Choose Inner Product metric") |
566
- option("--l2").set(args.metric_l2).doc("Choose L2 Euclidean metric") |
596
+ option("--l2sq").set(args.metric_l2).doc("Choose L2 Euclidean metric") |
567
597
  option("--cos").set(args.metric_cos).doc("Choose Angular metric") |
568
598
  option("--haversine").set(args.metric_haversine).doc("Choose Haversine metric")),
569
599
  option("-h", "--help").set(args.help).doc("Print this help information on this tool and exit"));
@@ -577,7 +607,7 @@ int main(int argc, char** argv) {
577
607
  exit(0);
578
608
  }
579
609
 
580
- // Instead of relying on `multithreaded` from "advanced.hpp" we will use OpenMP
610
+ // Instead of relying on `multithreaded` from "punned.hpp" we will use OpenMP
581
611
  // to better estimate statistics between tasks batches, without having to recreate
582
612
  // the threads.
583
613
  omp_set_dynamic(true);