File IndexBinaryIVF.h
-
namespace faiss
Implementation of k-means clustering with many variants.
Copyright (c) Facebook, Inc. and its affiliates.
This source code is licensed under the MIT license found in the LICENSE file in the root directory of this source tree.
IDSelector is intended to define a subset of vectors to handle (for removal or as subset to search)
PQ4 SIMD packing and accumulation functions
The basic kernel accumulates nq query vectors with bbs = nb * 2 * 16 vectors and produces an output matrix for that. It is interesting for nq * nb <= 4, otherwise register spilling becomes too large.
The implementation of these functions is spread over 3 cpp files to reduce parallel compile times. Templates are instantiated explicitly.
This file contains callbacks for kernels that compute distances.
Throughout the library, vectors are provided as float * pointers. Most algorithms can be optimized when several vectors are processed (added/searched) together in a batch. In this case, they are passed in as a matrix. When n vectors of size d are provided as float * x, component j of vector i is
x[ i * d + j ]
where 0 <= i < n and 0 <= j < d. In other words, matrices are always compact. When specifying the size of the matrix, we call it an n*d matrix, which implies a row-major storage.
I/O functions can read/write to a filename, a file handle or to an object that abstracts the medium.
The read functions return objects that should be deallocated with delete. All references within these objectes are owned by the object.
Definition of inverted lists + a few common classes that implement the interface.
Since IVF (inverted file) indexes are of so much use for large-scale use cases, we group a few functions related to them in this small library. Most functions work both on IndexIVFs and IndexIVFs embedded within an IndexPreTransform.
In this file are the implementations of extra metrics beyond L2 and inner product
Implements a few neural net layers, mainly to support QINCo
Defines a few objects that apply transformations to a set of vectors Often these are pre-processing steps.
-
struct IndexBinaryIVF : public faiss::IndexBinary
- #include <IndexBinaryIVF.h>
Index based on a inverted file (IVF)
In the inverted file, the quantizer (an IndexBinary instance) provides a quantization index for each vector to be added. The quantization index maps to a list (aka inverted list or posting list), where the id of the vector is stored.
Otherwise the object is similar to the IndexIVF
Public Functions
-
IndexBinaryIVF(IndexBinary *quantizer, size_t d, size_t nlist)
The Inverted file takes a quantizer (an IndexBinary) on input, which implements the function mapping a vector to a list identifier. The pointer is borrowed: the quantizer should not be deleted while the IndexBinaryIVF is in use.
-
IndexBinaryIVF()
-
~IndexBinaryIVF() override
-
virtual void reset() override
Removes all elements from the database.
-
virtual void add(idx_t n, const uint8_t *x) override
Add n vectors of dimension d to the index.
Vectors are implicitly assigned labels ntotal .. ntotal + n - 1
- Parameters:
x – input matrix, size n * d / 8
-
virtual void add_with_ids(idx_t n, const uint8_t *x, const idx_t *xids) override
Same as add, but stores xids instead of sequential ids.
The default implementation fails with an assertion, as it is not supported by all indexes.
- Parameters:
xids – if non-null, ids to store for the vectors (size n)
-
void add_core(idx_t n, const uint8_t *x, const idx_t *xids, const idx_t *precomputed_idx)
Implementation of vector addition where the vector assignments are predefined.
- Parameters:
precomputed_idx – quantization indices for the input vectors (size n)
-
void search_preassigned(idx_t n, const uint8_t *x, idx_t k, const idx_t *assign, const int32_t *centroid_dis, int32_t *distances, idx_t *labels, bool store_pairs, const IVFSearchParameters *params = nullptr) const
Search a set of vectors, that are pre-quantized by the IVF quantizer. Fill in the corresponding heaps with the query results. search() calls this.
- Parameters:
n – nb of vectors to query
x – query vectors, size nx * d
assign – coarse quantization indices, size nx * nprobe
centroid_dis – distances to coarse centroids, size nx * nprobe
distance – output distances, size n * k
labels – output labels, size n * k
store_pairs – store inv list index + inv list offset instead in upper/lower 32 bit of result, instead of ids (used for reranking).
params – used to override the object’s search parameters
-
virtual BinaryInvertedListScanner *get_InvertedListScanner(bool store_pairs = false) const
-
virtual void search(idx_t n, const uint8_t *x, idx_t k, int32_t *distances, idx_t *labels, const SearchParameters *params = nullptr) const override
assign the vectors, then call search_preassign
-
virtual void range_search(idx_t n, const uint8_t *x, int radius, RangeSearchResult *result, const SearchParameters *params = nullptr) const override
Query n vectors of dimension d to the index.
return all vectors with distance < radius. Note that many indexes do not implement the range_search (only the k-NN search is mandatory). The distances are converted to float to reuse the RangeSearchResult structure, but they are integer. By convention, only distances < radius (strict comparison) are returned, ie. radius = 0 does not return any result and 1 returns only exact same vectors.
- Parameters:
x – input vectors to search, size n * d / 8
radius – search radius
result – result table
-
void range_search_preassigned(idx_t n, const uint8_t *x, int radius, const idx_t *assign, const int32_t *centroid_dis, RangeSearchResult *result) const
-
virtual void reconstruct(idx_t key, uint8_t *recons) const override
Reconstruct a stored vector.
This function may not be defined for some indexes.
- Parameters:
key – id of the vector to reconstruct
recons – reconstucted vector (size d / 8)
-
virtual void reconstruct_n(idx_t i0, idx_t ni, uint8_t *recons) const override
Reconstruct a subset of the indexed vectors.
Overrides default implementation to bypass reconstruct() which requires direct_map to be maintained.
- Parameters:
i0 – first vector to reconstruct
ni – nb of vectors to reconstruct
recons – output array of reconstructed vectors, size ni * d / 8
-
virtual void search_and_reconstruct(idx_t n, const uint8_t *x, idx_t k, int32_t *distances, idx_t *labels, uint8_t *recons, const SearchParameters *params = nullptr) const override
Similar to search, but also reconstructs the stored vectors (or an approximation in the case of lossy coding) for the search results.
Overrides default implementation to avoid having to maintain direct_map and instead fetch the code offsets through the
store_pairs
flag in search_preassigned().- Parameters:
recons – reconstructed vectors size (n, k, d / 8)
-
virtual void reconstruct_from_offset(idx_t list_no, idx_t offset, uint8_t *recons) const
Reconstruct a vector given the location in terms of (inv list index + inv list offset) instead of the id.
Useful for reconstructing when the direct_map is not maintained and the inv list offset is computed by search_preassigned() with
store_pairs
set.
-
virtual size_t remove_ids(const IDSelector &sel) override
Dataset manipulation functions.
-
virtual void merge_from(IndexBinary &other, idx_t add_id) override
moves the entries from another dataset to self. On output, other is empty. add_id is added to all moved ids (for sequential ids, this would be this->ntotal)
-
virtual void check_compatible_for_merge(const IndexBinary &otherIndex) const override
check that the two indexes are compatible (ie, they are trained in the same way and have the same parameters). Otherwise throw.
-
inline size_t get_list_size(size_t list_no) const
-
void make_direct_map(bool new_maintain_direct_map = true)
initialize a direct map
- Parameters:
new_maintain_direct_map – if true, create a direct map, else clear it
-
void replace_invlists(InvertedLists *il, bool own = false)
Public Members
-
InvertedLists *invlists = nullptr
Access to the actual data.
-
bool own_invlists = true
-
size_t nprobe = 1
number of probes at query time
-
size_t max_codes = 0
max nb of codes to visit to do a query
-
bool use_heap = true
Select between using a heap or counting to select the k smallest values when scanning inverted lists.
-
bool per_invlist_search = false
collect computations per batch
-
DirectMap direct_map
map for direct access to the elements. Enables reconstruct().
-
IndexBinary *quantizer = nullptr
quantizer that maps vectors to inverted lists
-
size_t nlist = 0
number of possible key values
-
bool own_fields = false
whether object owns the quantizer
-
ClusteringParameters cp
to override default clustering params
-
IndexBinaryIVF(IndexBinary *quantizer, size_t d, size_t nlist)
-
struct BinaryInvertedListScanner
Public Functions
-
virtual void set_query(const uint8_t *query_vector) = 0
from now on we handle this query.
-
virtual void set_list(idx_t list_no, uint8_t coarse_dis) = 0
following codes come from this inverted list
-
virtual uint32_t distance_to_code(const uint8_t *code) const = 0
compute a single query-to-code distance
-
virtual size_t scan_codes(size_t n, const uint8_t *codes, const idx_t *ids, int32_t *distances, idx_t *labels, size_t k) const = 0
compute the distances to codes. (distances, labels) should be organized as a min- or max-heap
- Parameters:
n – number of codes to scan
codes – codes to scan (n * code_size)
ids – corresponding ids (ignored if store_pairs)
distances – heap distances (size k)
labels – heap labels (size k)
k – heap size
-
virtual void scan_codes_range(size_t n, const uint8_t *codes, const idx_t *ids, int radius, RangeQueryResult &result) const = 0
-
inline virtual ~BinaryInvertedListScanner()
-
virtual void set_query(const uint8_t *query_vector) = 0
-
struct IndexBinaryIVF : public faiss::IndexBinary