Skip to main content

Smaller & Faster Single-File Vector Search Engine from Unum

Project description

USearch

Smaller & Faster Single-File
Vector Search Engine


Discord     LinkedIn     Twitter     Blog     GitHub

Euclidean • Angular • Jaccard • Hamming • Haversine • User-Defined Metrics
C++11PythonJavaScriptJavaRustObjective-CSwiftGoLangWolfram
Linux • MacOS • Windows • Docker • WebAssembly 🔜



FAISS USearch
Implementation 84 K SLOC in faiss/ 1 K SLOC in usearch/
Supported metrics 9 fixed metrics Any User-Defined metrics
Supported ID types uint32_t, uint64_t uint32_t, uint40_t, uint64_t
Dependencies BLAS, OpenMP None
Bindings SWIG Native
Acceleration Learned Quantization Downcasting

FAISS is the industry standard for a high-performance batteries-included vector search engine. Both USearch and FAISS implement the same HNSW algorithm. But they differ in a lot of design decisions. USearch is designed to be compact and broadly compatible without sacrificing performance.

FAISS, f32 USearch, f32 USearch, f16 USearch, f8
Batch Insert 16 K/s 73 K/s 100 K/s 104 K/s
Batch Search 82 K/s 103 K/s 113 K/s 134 K/s
Bulk Insert 76 K/s 105 K/s 115 K/s 202 K/s
Bulk Search 118 K/s 174 K/s 173 K/s 304 K/s
Recall @1 99% 99.2% 99.1% 99.2%

Dataset: 1M vectors sample of the Deep1B dataset. Hardware: c7g.metal AWS instance with 64 cores and DDR5 memory. HNSW was configured with identical hyper-parameters: connectivity M=16, expansion @ construction efConstruction=128, and expansion @ search ef=64. Batch size is 256. Both libraries were compiled for the target architecture. Jump to the Performance Tuning section to read about the effects of those hyper-parameters.

User-Defined Functions

Most vector-search packages focus on just 2 metrics - "Inner Product distance" and "Euclidean distance". That only partially exhausts the list of possible metrics. A good example would be the rare Haversine distance, used to compute the distance between geo-spatial coordinates, extending Vector Search into the GIS domain. Another example would be designing a custom metric for composite embeddings concatenated from multiple AI models in real-world applications. USearch supports that: Python and C++ examples.

USearch: Vector Search Approaches

Unlike older approaches indexing high-dimensional spaces, like KD-Trees and Locality Sensitive Hashing, HNSW doesn't require vectors to be identical in length. They only have to be comparable. So you can apply it in obscure applications, like searching for similar sets or fuzzy text matching.

Memory Efficiency, Downcasting, and Quantization

Training a quantization model and dimension-reduction is a common approach to accelerate vector search. Those, however, are only sometimes reliable, can significantly affect the statistical properties of your data, and require regular adjustments if your distribution shifts.

USearch uint40_t support

Instead, we have focused on high-precision arithmetic over low-precision downcasted vectors. The same index, and add and search operations will automatically down-cast or up-cast between f32_t, f16_t, f64_t, and f8_t representations, even if the hardware doesn't natively support it. Continuing the topic of memory-efficiency, we provide a uint40_t to allow collection with over 4B+ vectors without allocating 8 bytes for every neighbor reference in the proximity graph.

View Larger Indexes from Disk

Modern search systems often suggest using different servers to maximize indexing speed and minimize serving costs. Memory-optimized for the first task, and storage-optimized for the second, if the index can be served from external memory, which USearch can.

To Build To Serve
Instance u-24tb1.metal is4gen.8xlarge
Price ~ $200/h ~$4.5/h
Memory 24 TB RAM + EBS 192 GB RAM + 30 TB SSD

There is a 50x difference between the cost of such instances for identical capacity. Of course, the latency of external memory access will be higher, but it is in part compensated with an excellent prefetching mechanism.

Usage

There are two usage patters:

  1. Bare-bones with usearch/index.hpp, only available in C++.
  2. Full-fat version with it's own threads, mutexes, type-punning, quantization, that is available both in C++ and is wrapped for higher-level bindings.

C++

Installation

To use in a C++ project simply copy the include/usearch/index.hpp header into your project. Alternatively fetch it with CMake:

FetchContent_Declare(usearch GIT_REPOSITORY https://github.com/unum-cloud/usearch.git)
FetchContent_MakeAvailable(usearch)

Quickstart

Once included, the low-level C++11 interface is as simple as it gets: reserve(), add(), search(), size(), capacity(), save(), load(), view(). This covers 90% of use-cases.

using namespace unum::usearch;

index_gt<cos_gt<float>> index;
float vec[3] = {0.1, 0.3, 0.2};

index.reserve(10);
index.add(/* label: */ 42, /* vector: */ {&vec[0], 3});
auto results = index.search(/* query: */ {&vec[0], 3}, 5 /* neighbors */);

for (std::size_t i = 0; i != results.size(); ++i)
    results[i].element.label, results[i].element.vector, results[i].distance;

The add is thread-safe for concurrent index construction.

Serialization

index.save("index.usearch");
index.load("index.usearch"); // Copying from disk
index.view("index.usearch"); // Memory-mapping from disk

User-Defined Metrics in C++

For advanced users, more compile-time abstractions are available.

template <typename metric_at = ip_gt<float>,            //
          typename label_at = std::size_t,              // `uint32_t`, `uuid_t`...
          typename id_at = std::uint32_t,               // `uint40_t`, `uint64_t`...
          typename scalar_at = float,                   // `double`, `half`, `char`...
          typename allocator_at = std::allocator<char>> //
class index_gt;

You may want to use a custom memory allocator or a rare scalar type, but most often, you would start by defining a custom similarity measure. The function object should have the following signature to support different-length vectors.

struct custom_metric_t {
    T operator()(T const* a, T const* b, std::size_t a_length, std::size_t b_length) const;
};

The following distances are pre-packaged:

  • cos_gt<scalar_t> for "Cosine" or "Angular" distance.
  • ip_gt<scalar_t> for "Inner Product" or "Dot Product" distance.
  • l2sq_gt<scalar_t> for the squared "L2" or "Euclidean" distance.
  • jaccard_gt<scalar_t> for "Jaccard" distance between two ordered sets of unique elements.
  • hamming_gt<scalar_t> for "Hamming" distance, as the number of shared bits in hashes.
  • tanimoto_gt<scalar_t> for "Tanimoto" coefficient for bit-strings.
  • sorensen_gt<scalar_t> for "Dice-Sorensen" coefficient for bit-strings.
  • pearson_correlation_gt<scalar_t> for "Pearson" correlation between probability distributions.
  • haversine_gt<scalar_t> for "Haversine" or "Great Circle" distance between coordinates used in GIS applications.

Multi-Threading

Most AI, HPC, or Big Data packages use some form of a thread pool. Instead of spawning additional threads within USearch, we focus on the thread safety of add() function, simplifying resource management.

#pragma omp parallel for
    for (std::size_t i = 0; i < n; ++i)
        native.add(label, span_t{vector, dims}, add_config_t { .thread = omp_get_thread_num() });

During initialization, we allocate enough temporary memory for all the cores on the machine. On the call, the user can supply the identifier of the current thread, making this library easy to integrate with OpenMP and similar tools.

Python

Installation

pip install usearch

Quickstart

import numpy as np
from usearch.index import Index

index = Index(
    ndim=3, # Define the number of dimensions in input vectors
    metric='cos', # Choose 'l2sq', 'haversine' or other metric, default = 'ip'
    dtype='f32', # Quantize to 'f16' or 'f8' if needed, default = 'f32'
    connectivity=16, # How frequent should the connections in the graph be, optional
    expansion_add=128, # Control the recall of indexing, optional
    expansion_search=64, # Control the quality of search, optional
)

vector = np.array([0.2, 0.6, 0.4])
index.add(42, vector)
matches, distances, count = index.search(vector, 10)

assert len(index) == 1
assert count == 1
assert matches[0] == 42
assert distances[0] <= 0.001
assert np.allclose(index[42], vector)

Python bindings are implemented with pybind/pybind11. Assuming the presence of Global Interpreter Lock in Python, we spawn threads in the C++ layer on large insertions.

Serialization

index.save('index.usearch')
index.load('index.usearch') # Copy the whole index into memory
index.view('index.usearch') # View from disk without loading in memory

If you don't know anything about the index except its path, there are two more endpoints to know:

Index.metadata('index.usearch') -> IndexMetadata
Index.restore('index.usearch', view=False) -> Index

Batch Operations

Adding or querying a batch of entries is identical to adding a single vector. The difference would be in the shape of the tensors.

n = 100
labels = np.arange(n)
vectors = np.random.uniform(0, 0.3, (n, index.ndim)).astype(np.float32)

index.add(labels, vectors, threads=..., copy=...)
matches, distances, counts = index.search(vectors, 10, threads=...)

assert matches.shape[0] == vectors.shape[0]
assert counts[0] <= 10

You can also override the default threads and copy arguments in bulk workloads. The first controls the number of threads spawned for the task. The second controls whether the vector itself will be persisted inside the index. If you can preserve the lifetime of the vector somewhere else, you can avoid the copy.

User-Defined Metrics and JIT in Python

Numba

Assuming the language boundary exists between Python user code and C++ implementation, there are more efficient solutions than passing a Python callable to the engine. Luckily, with the help of Numba, we can JIT compile a function with a matching signature and pass it down to the engine.

from numba import cfunc, types, carray

ndim = 256
signature = types.float32(
    types.CPointer(types.float32),
    types.CPointer(types.float32))

@cfunc(signature)
def inner_product(a, b):
    a_array = carray(a, ndim)
    b_array = carray(b, ndim)
    c = 0.0
    for i in range(ndim):
        c += a_array[i] * b_array[i]
    return 1 - c

index = Index(ndim=ndim, metric=CompiledMetric(
    pointer=inner_product.address,
    kind=MetricKind.IP,
    signature=MetricSignature.ArrayArray,
))

Alternatively, you can avoid pre-defining the number of dimensions, and pass it separately:

signature = types.float32(
    types.CPointer(types.float32),
    types.CPointer(types.float32),
    types.uint64)

@cfunc(signature)
def inner_product(a, b, ndim):
    a_array = carray(a, ndim)
    b_array = carray(b, ndim)
    c = 0.0
    for i in range(ndim):
        c += a_array[i] * b_array[i]
    return 1 - c

index = Index(ndim=ndim, metric=CompiledMetric(
    pointer=inner_product.address,
    kind=MetricKind.IP,
    signature=MetricSignature.ArrayArraySize,
))
pip install numba
Cppyy

Similarly, you can use Cppyy with Cling to JIT-compile native C or C++ code and pass it to USearch, which may be a good idea, if you want to explicitly request loop-unrolling or other low-level optimizations!

import cppyy
import cppyy.ll

cppyy.cppdef("""
float inner_product(float *a, float *b) {
    float result = 0;
#pragma unroll
    for (size_t i = 0; i != ndim; ++i)
        result += a[i] * b[i];
    return 1 - result;
}
""".replace("ndim", str(ndim)))

function = cppyy.gbl.inner_product
index = Index(ndim=ndim, metric=CompiledMetric(
    pointer=cppyy.ll.addressof(function),
    kind=MetricKind.IP,
    signature=MetricSignature.ArrayArraySize,
))
conda install -c conda-forge cppyy
PeachPy

We have covered JIT-ing Python with Numba and C++ with Cppyy and Cling. How about writing Assembly directly? That is also possible. Below is an example of constructing the "Inner Product" distance for 8-dimensional f32 vectors for x86 using PeachPy.

from peachpy import (
    Argument,
    ptr,
    float_,
    const_float_,
)
from peachpy.x86_64 import (
    abi,
    Function,
    uarch,
    isa,
    GeneralPurposeRegister64,
    LOAD,
    YMMRegister,
    VSUBPS,
    VADDPS,
    VHADDPS,
    VMOVUPS,
    VFMADD231PS,
    VPERM2F128,
    VXORPS,
    RETURN,
)

a = Argument(ptr(const_float_), name="a")
b = Argument(ptr(const_float_), name="b")

with Function(
    "inner_product", (a, b), float_, target=uarch.default + isa.avx2
) as asm_function:
    
    # Request two 64-bit general-purpose registers for addresses
    reg_a, reg_b = GeneralPurposeRegister64(), GeneralPurposeRegister64()
    LOAD.ARGUMENT(reg_a, a)
    LOAD.ARGUMENT(reg_b, b)

    # Load the vectors
    ymm_a = YMMRegister()
    ymm_b = YMMRegister()
    VMOVUPS(ymm_a, [reg_a])
    VMOVUPS(ymm_b, [reg_b])

    # Prepare the accumulator
    ymm_c = YMMRegister()
    ymm_one = YMMRegister()
    VXORPS(ymm_c, ymm_c, ymm_c)
    VXORPS(ymm_one, ymm_one, ymm_one)

    # Accumulate A and B product into C
    VFMADD231PS(ymm_c, ymm_a, ymm_b)

    # Reduce the contents of a YMM register
    ymm_c_permuted = YMMRegister()
    VPERM2F128(ymm_c_permuted, ymm_c, ymm_c, 1)
    VADDPS(ymm_c, ymm_c, ymm_c_permuted)
    VHADDPS(ymm_c, ymm_c, ymm_c)
    VHADDPS(ymm_c, ymm_c, ymm_c)

    # Negate the values, to go from "similarity" to "distance"
    VSUBPS(ymm_c, ymm_one, ymm_c)

    # A common convention is to return floats in XMM registers
    RETURN(ymm_c.as_xmm)

python_function = asm_function.finalize(abi.detect()).encode().load()
metric = CompiledMetric(
    pointer=python_function.loader.code_address,
    kind=MetricKind.IP,
    signature=MetricSignature.ArrayArray,
)
index = Index(ndim=ndim, metric=metric)

Tooling

To work with bbin, fbin, ibin, hbin matrix files USearch provides load_matrix and save_matrix. Such files are standard in k-ANN tasks and represent a binary object with all the scalars, prepended by two 32-bit integers - the number of rows and columns in the matrix.

from usearch.index import Index
from usearch.io import load_matrix, save_matrix

vectors = load_matrix('deep1B.fbin')
index = Index(ndim=vectors.shape[1])
index.add(labels, vectors)

One may often want to evaluate the quality of the constructed index before running in production. The trivial way is to measure recall@1 on the entries already present in the index.

from usearch.eval import recall_members

assert recall_members(index, exact=True) == 1
print(recall_members(index, exact=False))

In case you have some ground-truth data for more than one entry, you compare search results against expected values:

from usearch.eval import relevance, dcg, ndcg, random_vectors

vectors = random_vectors(index=index)
matches_approximate = index.search(vectors)
matches_exact = index.search(vectors, exact=True)
relevance_scores = relevance(matches_exact, matches_approximate)
print(dcg(relevance_scores), ndcg(relevance_scores))

JavaScript

Installation

npm install usearch

Quickstart

var index = new usearch.Index({ metric: 'cos', connectivity: 16, dimensions: 3 })
index.add(42, new Float32Array([0.2, 0.6, 0.4]))
var results = index.search(new Float32Array([0.2, 0.6, 0.4]), 10)

assert.equal(index.size(), 1)
assert.deepEqual(results.labels, new Uint32Array([42]))
assert.deepEqual(results.distances, new Float32Array([0]))

Serialization

index.save('index.usearch')
index.load('index.usearch')
index.view('index.usearch')

Rust

Installation

cargo add usearch

Quickstart

let options = IndexOptions {
            dimensions: 5,
            metric: MetricKind::IP,
            quantization: ScalarKind::F16,
            connectivity: 0,
            expansion_add: 0,
            expansion_search: 0
        };

let index = new_index(&options).unwrap();

assert!(index.reserve(10).is_ok());
assert!(index.capacity() >= 10);
assert!(index.connectivity() != 0);
assert_eq!(index.dimensions(), 3);
assert_eq!(index.size(), 0);

let first: [f32; 3] = [0.2, 0.1, 0.2];
let second: [f32; 3] = [0.2, 0.1, 0.2];

assert!(index.add(42, &first).is_ok());
assert!(index.add(43, &second).is_ok());
assert_eq!(index.size(), 2);

// Read back the tags
let results = index.search(&first, 10).unwrap();
assert_eq!(results.count, 2);

Multi-Threading

assert!(index.add_in_thread(42, &first, 0).is_ok());
assert!(index.add_in_thread(43, &second, 0).is_ok());
let results = index.search_in_thread(&first, 10, 0).unwrap();

Being a systems-programming language, Rust has better control over memory management and concurrency but lacks function overloading. Aside from the add and search, USearch Rust binding also provides add_in_thread and search_in_thread, which let users identify the calling thread to use underlying temporary memory more efficiently.

Serialization

assert!(index.save("index.usearch").is_ok());
assert!(index.load("index.usearch").is_ok());
assert!(index.view("index.usearch").is_ok());

Metrics

assert!(new_l2sq(3, &quant, 0, 0, 0).is_ok());
assert!(new_cos(3, &quant, 0, 0, 0).is_ok());
assert!(new_haversine(&quant, 0, 0, 0).is_ok());

Java

Installation

<dependency>
  <groupId>cloud.unum</groupId>
  <artifactId>usearch</artifactId>
  <version>0.2.3</version>
</dependency>

Add that snippet to your pom.xml and hit mvn install.

Quickstart

Index index = new Index.Config().metric("cos").dimensions(2).build();
float vec[] = {10, 20};
index.add(42, vec);
int[] labels = index.search(vec, 5);

Swift

Installation

https://github.com/unum-cloud/usearch

Quickstart

let index = Index.l2sq(dimensions: 3, connectivity: 8)
let vectorA: [Float32] = [0.3, 0.5, 1.2]
let vectorB: [Float32] = [0.4, 0.2, 1.2]
index.reserve(2)
index.add(label: 42, vector: vectorA[...])
index.add(label: 43, vector: vectorB[...])

let results = index.search(vector: vectorA[...], count: 10)
assert(results.0[0] == 42)

GoLang

Installation

import (
	"github.com/unum-cloud/usearch/golang"
)

Quickstart

package main

import (
	"fmt"
	"github.com/unum-cloud/usearch/golang"
)

func main() {
	conf := usearch.DefaultConfig(128)
	index := usearch.NewIndex(conf)
	v := make([]float32, 128)
	index.Add(42, v)
	results := index.Search(v, 1)
}

Wolfram

Application Examples

USearch + AI = Multi-Modal Semantic Search

AI has a growing number of applications, but one of the coolest classic ideas is to use it for Semantic Search. One can take an encoder model, like the multi-modal UForm, and a web-programming framework, like UCall, and build a text-to-image search platform in just 20 lines of Python.

import ucall
import uform
import usearch

import numpy as np
import PIL as pil

server = ucall.Server()
model = uform.get_model('unum-cloud/uform-vl-multilingual')
index = usearch.index.Index(ndim=256)

@server
def add(label: int, photo: pil.Image.Image):
    image = model.preprocess_image(photo)
    vector = model.encode_image(image).detach().numpy()
    index.add(label, vector.flatten(), copy=True)

@server
def search(query: str) -> np.ndarray:
    tokens = model.preprocess_text(query)
    vector = model.encode_text(tokens).detach().numpy()
    matches = index.search(vector.flatten(), 3)
    return matches.labels

server.run()

We have pre-processed some commonly used datasets, cleaning the images, producing the vectors, and pre-building the index.

Dataset Size Images Preprocessed
Unsplash 25K - 25 K HF
Createve Captions 3M - 3 M HF

USearch + RDKit = Molecular Search

Comparing molecule graphs and searching for similar structures is expensive and slow. It can be seen as a special case of the NP-Complete Subgraph Isomorphism problem. Luckily, domain-specific approximate methods exists. The one commonly used in Chemistry, is to generate structures from SMILES, and later hash them into binary fingerprints. The later are searchable with bitwise similarity metrics, like the Tanimoto coefficient. Below is na example using the RDKit package.

from usearch.index import Index, MetricKind
from rdkit import Chem
from rdkit.Chem import AllChem

import numpy as np

molecules = [Chem.MolFromSmiles('CCOC'), Chem.MolFromSmiles('CCO')]
encoder = AllChem.GetRDKitFPGenerator()

fingerprints = np.vstack([encoder.GetFingerprint(x) for x in molecules])
fingerprints = np.packbits(fingerprints, axis=1)

index = Index(ndim=2048, metric=MetricKind.BitwiseTanimoto)
labels = np.arange(len(molecules))

index.add(labels, fingerprints)
matches = index.search(fingerprints, 10)

TODO

  • JavaScript: Allow calling from "worker threads".
  • Rust: Allow passing a custom thread ID.
  • C# .NET bindings.

Integrations

  • GPT-Cache.
  • Langchain.
  • Microsoft Semantic Kernel.
  • PyTorch.

Citations

@software{Vardanian_USearch_2022,
doi = {10.5281/zenodo.7949416},
author = {Vardanian, Ash},
title = {{USearch by Unum Cloud}},
url = {https://github.com/unum-cloud/usearch},
version = {0.13.0},
year = {2022}
month = jun,
}

Check that and other examples on our corporate GitHub 🤗

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

usearch-0.19.1-cp311-cp311-win_amd64.whl (176.4 kB view details)

Uploaded CPython 3.11 Windows x86-64

usearch-0.19.1-cp311-cp311-manylinux_2_28_x86_64.whl (334.1 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.28+ x86-64

usearch-0.19.1-cp311-cp311-manylinux_2_28_aarch64.whl (320.9 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.28+ ARM64

usearch-0.19.1-cp311-cp311-macosx_11_0_arm64.whl (226.3 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

usearch-0.19.1-cp311-cp311-macosx_10_9_x86_64.whl (232.2 kB view details)

Uploaded CPython 3.11 macOS 10.9+ x86-64

usearch-0.19.1-cp311-cp311-macosx_10_9_universal2.whl (428.4 kB view details)

Uploaded CPython 3.11 macOS 10.9+ universal2 (ARM64, x86-64)

usearch-0.19.1-cp310-cp310-win_amd64.whl (176.4 kB view details)

Uploaded CPython 3.10 Windows x86-64

usearch-0.19.1-cp310-cp310-manylinux_2_28_x86_64.whl (334.2 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.28+ x86-64

usearch-0.19.1-cp310-cp310-manylinux_2_28_aarch64.whl (321.2 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.28+ ARM64

usearch-0.19.1-cp310-cp310-macosx_11_0_arm64.whl (226.3 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

usearch-0.19.1-cp310-cp310-macosx_10_9_x86_64.whl (232.1 kB view details)

Uploaded CPython 3.10 macOS 10.9+ x86-64

usearch-0.19.1-cp310-cp310-macosx_10_9_universal2.whl (428.4 kB view details)

Uploaded CPython 3.10 macOS 10.9+ universal2 (ARM64, x86-64)

usearch-0.19.1-cp39-cp39-win_amd64.whl (176.4 kB view details)

Uploaded CPython 3.9 Windows x86-64

usearch-0.19.1-cp39-cp39-manylinux_2_28_x86_64.whl (334.7 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.28+ x86-64

usearch-0.19.1-cp39-cp39-manylinux_2_28_aarch64.whl (321.2 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.28+ ARM64

usearch-0.19.1-cp39-cp39-macosx_11_0_arm64.whl (226.5 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

usearch-0.19.1-cp39-cp39-macosx_10_9_x86_64.whl (232.3 kB view details)

Uploaded CPython 3.9 macOS 10.9+ x86-64

usearch-0.19.1-cp39-cp39-macosx_10_9_universal2.whl (428.9 kB view details)

Uploaded CPython 3.9 macOS 10.9+ universal2 (ARM64, x86-64)

usearch-0.19.1-cp38-cp38-win_amd64.whl (176.3 kB view details)

Uploaded CPython 3.8 Windows x86-64

usearch-0.19.1-cp38-cp38-manylinux_2_28_x86_64.whl (333.8 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.28+ x86-64

usearch-0.19.1-cp38-cp38-manylinux_2_28_aarch64.whl (321.0 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.28+ ARM64

usearch-0.19.1-cp38-cp38-macosx_11_0_arm64.whl (226.2 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

usearch-0.19.1-cp38-cp38-macosx_10_9_x86_64.whl (232.2 kB view details)

Uploaded CPython 3.8 macOS 10.9+ x86-64

usearch-0.19.1-cp38-cp38-macosx_10_9_universal2.whl (428.3 kB view details)

Uploaded CPython 3.8 macOS 10.9+ universal2 (ARM64, x86-64)

usearch-0.19.1-cp37-cp37m-win_amd64.whl (176.3 kB view details)

Uploaded CPython 3.7m Windows x86-64

usearch-0.19.1-cp37-cp37m-manylinux_2_28_x86_64.whl (339.6 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.28+ x86-64

usearch-0.19.1-cp37-cp37m-manylinux_2_28_aarch64.whl (325.6 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.28+ ARM64

usearch-0.19.1-cp37-cp37m-macosx_10_9_x86_64.whl (229.7 kB view details)

Uploaded CPython 3.7m macOS 10.9+ x86-64

File details

Details for the file usearch-0.19.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: usearch-0.19.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 176.4 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.1 CPython/3.11.4

File hashes

Hashes for usearch-0.19.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 3cafeba627a592f04b3bb425e9861ebe9eb7e0092a94c69b6697c8d4d960ddae
MD5 06dc80ca98a715999c96d78028961245
BLAKE2b-256 c9087fe61d4044d85790c1c12107aec7d9f9feb1360273165f1b10b015e743ac

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 620cc6d4e06c7570edebd8ab16e3d02bfed9168c8275b94c1162a5a11c98ac49
MD5 30615e6bc9f4beaa39a13ec06aa2a833
BLAKE2b-256 84b6023b18321b39c6dcd91b19ab77a17f817d9741045cf00c36a44aa6699f7f

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ec11e122e096e0a3aefbcbeb53c89d02bee4224f9c9a1c9ef7be89c4843da111
MD5 bf3289bc1f7b742dbf338c6af3ff6722
BLAKE2b-256 f58a7655b923beb153b3a7a8e4429cabc451c8f45a63375feb9220cab6c48e1c

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6dc32b844f0a57e43e930cc33b2687ca8c0df65da3704f06c823441797697b17
MD5 92aeafef9ad0425bc98dcb4e657e0eae
BLAKE2b-256 6b434cbcd06334d82667c847cd44ffb1d556eb31085517065045c5287bbde1a1

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 83e75581083a0644cbd43195a415a3174098f935cb6b58405766e3f2857c77d9
MD5 5efb6d68b9f2ab4730d98ff07e40fa3a
BLAKE2b-256 3d3d95d00ba34c456aa8371dcdcad6192559361695ff5adc105b8d3a95defcbe

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp311-cp311-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 25d9de99091e4b5029b2349834dc438333dfac65ce11e5ab2499fa2acf119f24
MD5 db8da756315e7ecdc7ae2b22044fa71a
BLAKE2b-256 38de713424b7ff3748311e2293d5a2fd19ac79db1808c9a0323b74589f95f9f3

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: usearch-0.19.1-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 176.4 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.1 CPython/3.11.4

File hashes

Hashes for usearch-0.19.1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 b185754b1ead9a9905dade67ca2c1d04f77603cf6a9c2a85866eeeff22a4544a
MD5 c65bccfc11f8512d6158a2ce59b76710
BLAKE2b-256 829fc34ee6ea810eaae56d60f8f74901eec131374e8e18f1edd21d04eefa1e68

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3884e12bd41dfd9cccced8e0e11f8383a49a6b72c4ccbb5825776eaceaf760fb
MD5 8074875dab554da6b9dfe5986a2414b3
BLAKE2b-256 39f31f7297335fc4e7469b44657c774a115e7271b401c37f3d49e4838e061139

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp310-cp310-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 69fd1b6489ac75f32e536162ac4a84ac5a9993787cd2d842d7035ead1d49a605
MD5 5b2c82b0352bc9f60f36466488361237
BLAKE2b-256 775ac42097c32379987ee6d5a767d7daba64cbe72123ad36c1faab28a47835b3

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 aa60960a3444add6a1fefbdfb75e884799f050e59347fa038cbb9705a12061b7
MD5 f3b74f81ddc982908fe15aa416f3806e
BLAKE2b-256 59c252f070f795457492535b45696d708956bf9b9fd550607d21f9a9cf3f7edb

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 6d092e45b627ad435753f1ba0c7a112bdf3ad4efb8e06930c11ec2afdeddafb3
MD5 5cdc3f6494ffa4b7ef0d40f858b4ac4d
BLAKE2b-256 397e6e6993d57c28888dbd9397da4704f08b1c0db7aa37bee67bf5d4aad6ebc6

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp310-cp310-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 6a7153057083b4fee9c6d4f5b5bfd37c226da33b6433e9ef8934bfa09e476811
MD5 d6187345bf35e1b929d52d3ea22dc9dc
BLAKE2b-256 0aa6038f1d4e15765582e4ea8a6cc47a46f3b89c203c879316a0f626c2a36317

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: usearch-0.19.1-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 176.4 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.1 CPython/3.11.4

File hashes

Hashes for usearch-0.19.1-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 3935bc37738757423918573b8e1f1e91d51f34f324c7682c9c3af62473040209
MD5 6f6684245225e53cc256900eaf306de7
BLAKE2b-256 b5fe58f412a6488a0eec73bd8ccde7f93b55550c1b3bc7f28203664c5c313e50

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp39-cp39-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e0e00cc3e2e193953dbfc053e326f5bbc72dd3ccbfa02ed9fc5eed9d9fd4223f
MD5 f1fbb46a3fb0c36aec231eb5f2cdf762
BLAKE2b-256 70f58e0cd9704a36bcc57ecb1ec92f18d051caed3eadcc447139a1da90b83cda

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp39-cp39-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp39-cp39-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 94537418fa0838feec2b877ea7cffcce93a75e290fcfd4de1f8b8891914ce660
MD5 dc7db2e58fc0cc2e619aa5b9cc9e57e0
BLAKE2b-256 280c8a8313e7a8e66901d360d24430e2d8b588d2a9c2c359677c580f292edd73

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 33f46c7802ceda26911585bc082c3ebd491a80abeac8bcf35faa807121c1efa0
MD5 bada8cfe099af77be537aa4380c44b20
BLAKE2b-256 ad42eba07f746bed299a3d9e44963481d990ade04d75419e24547e5b9b1fbdb1

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp39-cp39-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 bfaf53d3cddb55e5fdea56837187f29b391a697f1b527d30049cf720426fa88e
MD5 048a04cf0579d5a443bd794417c1271d
BLAKE2b-256 15456877fb7b57cc7068cc52a7a6b13b3eae941c9705061471260b753fee189b

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp39-cp39-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp39-cp39-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 9f52ff2c130e49623bec59d1e13d424f20a9fc246ff9741a973bc152f967ae7e
MD5 858d4c99eff335185e7f0c00dcdb78e9
BLAKE2b-256 0faf558c26d8d943672dab45535e3d19a8c2eec774500e4f77620fe5217f4e0a

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: usearch-0.19.1-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 176.3 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.1 CPython/3.11.4

File hashes

Hashes for usearch-0.19.1-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 3cb13118292e301959e00321ef8ca86b3be23094abfc430be70640d1a6836edb
MD5 1d4ea650d18d5c4303b70f881c7f6402
BLAKE2b-256 cb60cacb077ba46fb19e356b2c57ceeebf065d728380b129e7e167301a019278

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp38-cp38-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp38-cp38-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 649f61fa2a30bfeec3d4b37c2bc7f719e1e6735353f34d7e72882e9f2802576b
MD5 594b4943a89cb34451c409278bf971a0
BLAKE2b-256 f15826da231c358a691b109c933988331960281ebe187ef8b20a044164beb4ac

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp38-cp38-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp38-cp38-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 f072151c6d3210a00fe346af85aadc438579a63afaf09f55986c94b42403bacf
MD5 f631d078d7d81ac3e250270ca4ecec3e
BLAKE2b-256 3b8d9f9582f98d5497e11221769bc259c219b0d026ca4f1b0204954fe3d44151

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp38-cp38-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 403088776c4ed7e4f04e44764b0b271adb13f5a8072495aa2d7b800e821282c7
MD5 02e358bec6a315e9905dd408b8032bcd
BLAKE2b-256 738a7c35db855345983c3247540c92e2ffa7221d56029e9d24bcef377e607cfa

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp38-cp38-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 942cb700a995b64f8344d8fe306b87b91b1db1a3bcd0971342cdf7a36f48b35e
MD5 e4556a16237f2d38c8ebca9b7353cd0d
BLAKE2b-256 30aac94b16d195ed9bc4c2e956965fa9e784225b839faaf9d12ca2de3a8a476c

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp38-cp38-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp38-cp38-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 bb9fe22b378d5abfe395271a849152943b78dceb3b28d844edc92de67b1d8ff0
MD5 34531b3bd706a620e94b7745c313096d
BLAKE2b-256 fd4badf1126c688e1acb0cbd35eb3320c4369bf2829a981460339bdcd29a722e

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: usearch-0.19.1-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 176.3 kB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.1 CPython/3.11.4

File hashes

Hashes for usearch-0.19.1-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 39e48ef22cdb0937ac432287e8d88c7e04f532415891f843f7af06f8851ffda1
MD5 308774fe35c9ddc005cbfccf220f4a22
BLAKE2b-256 918a57f4c93c7bfc2dadc4945b2d6ce4c2d3adac1ae3320fd70db32bfdb32093

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp37-cp37m-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp37-cp37m-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fe96472c1a2cc6dad33383876b610d11ad2a8ddec463b13df60e494e4c015925
MD5 9a2257a8036c69bf2238ef40f5849d7a
BLAKE2b-256 082c4af4bab76d1fc0967ddd23ad02f9103f5bd65d958b4188005c6ee298eb74

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp37-cp37m-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp37-cp37m-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 d0e8a9dd94f29f34714c61ab1301f449fdab3f8fd293af74f580c9563271e643
MD5 4d254046536e32b1c594d59bf37b88cd
BLAKE2b-256 173a39e44b6c52ea5d638b8c670adc2da72aac0407c08f33e91333dcc9168903

See more details on using hashes here.

File details

Details for the file usearch-0.19.1-cp37-cp37m-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for usearch-0.19.1-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 03f0bccaa2065e7b792c139853af451ae8d2c158f6d6f7d956873f0433f5324a
MD5 b067822a67bcd7a557ad7aa1b02fb703
BLAKE2b-256 bb0fd878388628a7f7d481ad29209edf3dc8e2ca325beb3bb023c782364a8f5b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page