usearch 0.9.2 → 0.9.4

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/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "usearch"
3
- version = "0.9.2"
3
+ version = "0.9.4"
4
4
  authors = ["Ashot Vardanian <1983160+ashvardanian@users.noreply.github.com>"]
5
5
  description = "Smaller & Faster Single-File Vector Search Engine from Unum"
6
6
  edition = "2021"
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.2
1
+ 0.9.4
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 = '0.9.2'
7
+ version = '0.9.4'
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'
@@ -410,71 +410,75 @@ template <typename allocator_at = std::allocator<char>> class visits_bitset_gt {
410
410
 
411
411
  #if defined(USEARCH_IS_WINDOWS)
412
412
  using slot_t = LONG volatile;
413
- static_assert(sizeof(slot_t) == 8);
414
413
  #else
415
414
  using slot_t = std::uint64_t;
416
415
  #endif
417
416
 
418
- std::uint64_t* u64s_{};
419
- std::size_t slots_{};
417
+ static constexpr std::size_t bits_per_slot() { return sizeof(slot_t) * CHAR_BIT; }
418
+ static constexpr slot_t bits_mask() { return sizeof(slot_t) * CHAR_BIT - 1; }
419
+
420
+ slot_t* slots_{};
421
+ std::size_t slots_count_{};
420
422
 
421
423
  public:
422
424
  visits_bitset_gt() noexcept {}
423
425
  visits_bitset_gt(std::size_t capacity) noexcept {
424
- slots_ = divide_round_up<64>(capacity);
425
- u64s_ = (slot_t*)allocator_t{}.allocate(slots_ * sizeof(slot_t));
426
+ slots_count_ = divide_round_up<bits_per_slot()>(capacity);
427
+ slots_ = (slot_t*)allocator_t{}.allocate(slots_count_ * sizeof(slot_t));
426
428
  clear();
427
429
  }
428
- ~visits_bitset_gt() noexcept { allocator_t{}.deallocate((byte_t*)u64s_, slots_ * sizeof(slot_t)), u64s_ = nullptr; }
429
- void clear() noexcept { std::memset(u64s_, 0, slots_ * sizeof(slot_t)); }
430
- inline bool test(std::size_t i) const noexcept { return u64s_[i / 64] & (1ul << (i & 63ul)); }
431
- inline void set(std::size_t i) noexcept { u64s_[i / 64] |= (1ul << (i & 63ul)); }
430
+ ~visits_bitset_gt() noexcept {
431
+ allocator_t{}.deallocate((byte_t*)slots_, slots_count_ * sizeof(slot_t)), slots_ = nullptr;
432
+ }
433
+ void clear() noexcept { std::memset(slots_, 0, slots_count_ * sizeof(slot_t)); }
434
+ inline bool test(std::size_t i) const noexcept { return slots_[i / bits_per_slot()] & (1ul << (i & bits_mask())); }
435
+ inline void set(std::size_t i) noexcept { slots_[i / bits_per_slot()] |= (1ul << (i & bits_mask())); }
432
436
 
433
437
  visits_bitset_gt(visits_bitset_gt&& other) noexcept {
434
- u64s_ = other.u64s_;
435
438
  slots_ = other.slots_;
436
- other.u64s_ = nullptr;
437
- other.slots_ = 0;
439
+ slots_count_ = other.slots_count_;
440
+ other.slots_ = nullptr;
441
+ other.slots_count_ = 0;
438
442
  }
439
443
 
440
444
  visits_bitset_gt& operator=(visits_bitset_gt&& other) noexcept {
441
- std::swap(u64s_, other.u64s_);
442
445
  std::swap(slots_, other.slots_);
446
+ std::swap(slots_count_, other.slots_count_);
443
447
  return *this;
444
448
  }
445
449
 
446
450
  #if defined(USEARCH_IS_WINDOWS)
447
451
 
448
452
  inline bool atomic_test(std::size_t i) noexcept {
449
- slot_t mask{1ul << (i & 63ul)};
450
- return InterlockedOr(&u64s_[i / 64], 0) & mask;
453
+ slot_t mask{1ul << (i & bits_mask())};
454
+ return InterlockedOr(&slots_[i / bits_per_slot()], 0) & mask;
451
455
  }
452
456
 
453
457
  inline bool atomic_set(std::size_t i) noexcept {
454
- slot_t mask{1ul << (i & 63ul)};
455
- return InterLockedOr(&u64s_[i / 64], mask) & mask;
458
+ slot_t mask{1ul << (i & bits_mask())};
459
+ return InterLockedOr(&slots_[i / bits_per_slot()], mask) & mask;
456
460
  }
457
461
 
458
462
  inline void atomic_reset(std::size_t i) noexcept {
459
- slot_t mask{1ul << (i & 63ul)};
460
- InterLockedAnd((LONG volatile*)&u64s_[i / 64], ~mask);
463
+ slot_t mask{1ul << (i & bits_mask())};
464
+ InterLockedAnd((LONG volatile*)&slots_[i / bits_per_slot()], ~mask);
461
465
  }
462
466
 
463
467
  #else
464
468
 
465
469
  inline bool atomic_test(std::size_t i) noexcept {
466
- slot_t mask{1ul << (i & 63ul)};
467
- return __atomic_load_n(&u64s_[i / 64], __ATOMIC_RELAXED) & mask;
470
+ slot_t mask{1ul << (i & bits_mask())};
471
+ return __atomic_load_n(&slots_[i / bits_per_slot()], __ATOMIC_RELAXED) & mask;
468
472
  }
469
473
 
470
474
  inline bool atomic_set(std::size_t i) noexcept {
471
- slot_t mask{1ul << (i & 63ul)};
472
- return __atomic_fetch_or(&u64s_[i / 64], mask, __ATOMIC_ACQUIRE) & mask;
475
+ slot_t mask{1ul << (i & bits_mask())};
476
+ return __atomic_fetch_or(&slots_[i / bits_per_slot()], mask, __ATOMIC_ACQUIRE) & mask;
473
477
  }
474
478
 
475
479
  inline void atomic_reset(std::size_t i) noexcept {
476
- slot_t mask{1ul << (i & 63ul)};
477
- __atomic_fetch_and(&u64s_[i / 64], ~mask, __ATOMIC_RELEASE);
480
+ slot_t mask{1ul << (i & bits_mask())};
481
+ __atomic_fetch_and(&slots_[i / bits_per_slot()], ~mask, __ATOMIC_RELEASE);
478
482
  }
479
483
 
480
484
  #endif
@@ -732,7 +736,7 @@ class usearch_pack_m uint40_t {
732
736
  inline uint40_t() noexcept { std::memset(octets, 0, 5); }
733
737
  inline uint40_t(std::uint32_t n) noexcept { std::memcpy(octets + 1, (char*)&n, 4), octets[0] = 0; }
734
738
  inline uint40_t(std::uint64_t n) noexcept { std::memcpy(octets, (char*)&n + 3, 5); }
735
- #if defined(USEARCH_IS_CLANG)
739
+ #if defined(USEARCH_IS_CLANG) && defined(USEARCH_IS_APPLE)
736
740
  inline uint40_t(std::size_t n) noexcept { std::memcpy(octets, (char*)&n + 3, 5); }
737
741
  #endif
738
742
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "usearch",
3
- "version": "0.9.2",
3
+ "version": "0.9.4",
4
4
  "description": "Smaller & Faster Single-File Vector Search Engine from Unum",
5
5
  "author": "Ashot Vardanian",
6
6
  "license": "Apache 2.0",
package/pyproject.toml CHANGED
@@ -46,3 +46,4 @@ before-build = [
46
46
  "git submodule update --init --recursive"
47
47
  ]
48
48
  archs = ["x86", "AMD64"]
49
+ skip = ["*win32*"]
package/setup.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import os
2
2
  import sys
3
- import platform
4
3
  from setuptools import setup
4
+
5
5
  from pybind11.setup_helpers import Pybind11Extension
6
6
 
7
7
 
@@ -22,11 +22,6 @@ if sys.platform == 'darwin':
22
22
  if sys.platform == 'win32':
23
23
  compile_args = ['/std:c++14', '/O2']
24
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')
29
-
30
25
  ext_modules = [
31
26
  Pybind11Extension(
32
27
  'usearch.index',
@@ -58,16 +53,21 @@ setup(
58
53
  license='Apache-2.0',
59
54
 
60
55
  classifiers=[
61
- 'Development Status :: 4 - Beta',
56
+ 'Development Status :: 5 - Production/Stable',
62
57
 
63
58
  'Natural Language :: English',
64
59
  'Intended Audience :: Developers',
65
60
  'Intended Audience :: Information Technology',
66
61
  'License :: OSI Approved :: Apache Software License',
67
62
 
63
+ 'Programming Language :: C++',
68
64
  'Programming Language :: Python :: 3 :: Only',
69
65
  'Programming Language :: Python :: Implementation :: CPython',
70
- 'Programming Language :: C++',
66
+ 'Programming Language :: Java',
67
+ 'Programming Language :: JavaScript',
68
+ 'Programming Language :: Objective C',
69
+ 'Programming Language :: Rust',
70
+ 'Programming Language :: Other',
71
71
 
72
72
  'Operating System :: MacOS',
73
73
  'Operating System :: Unix',
package/src/punned.hpp CHANGED
@@ -595,7 +595,7 @@ class punned_gt {
595
595
  if (casted)
596
596
  vector_data = casted_data, vector_bytes = casted_vector_bytes_;
597
597
 
598
- return index_->search_around(hint, {vector_data, vector_bytes}, wanted, config);
598
+ return index_->search_around(static_cast<id_t>(hint), {vector_data, vector_bytes}, wanted, config);
599
599
  }
600
600
 
601
601
  template <typename scalar_at> add_result_t add_(label_t label, scalar_at const* vector, cast_t const& cast) {