diff --git a/faiss-sys/build.rs b/faiss-sys/build.rs index aee4b76..b51a6b3 100644 --- a/faiss-sys/build.rs +++ b/faiss-sys/build.rs @@ -11,11 +11,10 @@ fn static_link_faiss() { cfg.define("FAISS_ENABLE_C_API", "ON") .define("BUILD_SHARED_LIBS", "OFF") .define("CMAKE_BUILD_TYPE", "Release") - .define("FAISS_ENABLE_GPU", if cfg!(feature = "gpu") { - "ON" - } else { - "OFF" - }) + .define( + "FAISS_ENABLE_GPU", + if cfg!(feature = "gpu") { "ON" } else { "OFF" }, + ) .define("FAISS_ENABLE_PYTHON", "OFF") .define("BUILD_TESTING", "OFF") .very_verbose(true); diff --git a/faiss-sys/faiss b/faiss-sys/faiss index 943d08b..77e2e79 160000 --- a/faiss-sys/faiss +++ b/faiss-sys/faiss @@ -1 +1 @@ -Subproject commit 943d08bdad7946b22f56d040756669ee444dd681 +Subproject commit 77e2e79cd0a680adc343b9840dd865da724c579e diff --git a/faiss-sys/src/bindings.rs b/faiss-sys/src/bindings.rs index 6676a76..6ee7406 100644 --- a/faiss-sys/src/bindings.rs +++ b/faiss-sys/src/bindings.rs @@ -297,14 +297,6 @@ extern "C" { arg3: *mut *mut FaissParameterRange, ) -> ::std::os::raw::c_int; } -pub type FILE = [u64; 27usize]; -extern "C" { - #[doc = " Clone an index. This is equivalent to `faiss::clone_index`"] - pub fn faiss_clone_index( - arg1: *const FaissIndex, - p_out: *mut *mut FaissIndex, - ) -> ::std::os::raw::c_int; -} #[doc = " Class for the clustering parameters. Can be passed to the\n constructor of the Clustering object."] #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -593,638 +585,630 @@ extern "C" { q_error: *mut f32, ) -> ::std::os::raw::c_int; } -#[doc = " No error"] -pub const FaissErrorCode_OK: FaissErrorCode = 0; -#[doc = " Any exception other than Faiss or standard C++ library exceptions"] -pub const FaissErrorCode_UNKNOWN_EXCEPT: FaissErrorCode = -1; -#[doc = " Faiss library exception"] -pub const FaissErrorCode_FAISS_EXCEPT: FaissErrorCode = -2; -#[doc = " Standard C++ library exception"] -pub const FaissErrorCode_STD_EXCEPT: FaissErrorCode = -4; -#[doc = " An error code which depends on the exception thrown from the previous\n operation. See `faiss_get_last_error` to retrieve the error message."] -pub type FaissErrorCode = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIndexBinary_H { + _unused: [u8; 0], +} +pub type FaissIndexBinary = FaissIndexBinary_H; extern "C" { - #[doc = " Get the error message of the last failed operation performed by Faiss.\n The given pointer is only invalid until another Faiss function is\n called."] - pub fn faiss_get_last_error() -> *const ::std::os::raw::c_char; + pub fn faiss_IndexBinary_free(obj: *mut FaissIndexBinary); } extern "C" { - pub fn faiss_RangeSearchResult_nq(arg1: *const FaissRangeSearchResult) -> usize; + pub fn faiss_IndexBinary_d(arg1: *const FaissIndexBinary) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_RangeSearchResult_new( - p_rsr: *mut *mut FaissRangeSearchResult, - nq: idx_t, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexBinary_is_trained(arg1: *const FaissIndexBinary) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_RangeSearchResult_new_with( - p_rsr: *mut *mut FaissRangeSearchResult, - nq: idx_t, - alloc_lims: ::std::os::raw::c_int, + pub fn faiss_IndexBinary_ntotal(arg1: *const FaissIndexBinary) -> idx_t; +} +extern "C" { + pub fn faiss_IndexBinary_metric_type(arg1: *const FaissIndexBinary) -> FaissMetricType; +} +extern "C" { + pub fn faiss_IndexBinary_verbose(arg1: *const FaissIndexBinary) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn faiss_IndexBinary_set_verbose(arg1: *mut FaissIndexBinary, arg2: ::std::os::raw::c_int); +} +extern "C" { + #[doc = " Perform training on a representative set of vectors\n\n @param index opaque pointer to index object\n @param n nb of training vectors\n @param x training vectors, size n * d"] + pub fn faiss_IndexBinary_train( + index: *mut FaissIndexBinary, + n: idx_t, + x: *const u8, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " called when lims contains the nb of elements result entries\n for each query"] - pub fn faiss_RangeSearchResult_do_allocation( - rsr: *mut FaissRangeSearchResult, + #[doc = " Add n vectors of dimension d to the index.\n\n Vectors are implicitly assigned labels ntotal .. ntotal + n - 1\n This function slices the input vectors in chunks smaller than\n blocksize_add and calls add_core.\n @param index opaque pointer to index object\n @param x input matrix, size n * d"] + pub fn faiss_IndexBinary_add( + index: *mut FaissIndexBinary, + n: idx_t, + x: *const u8, ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_RangeSearchResult_free(obj: *mut FaissRangeSearchResult); + #[doc = " Same as add, but stores xids instead of sequential ids.\n\n The default implementation fails with an assertion, as it is\n not supported by all indexes.\n\n @param index opaque pointer to index object\n @param xids if non-null, ids to store for the vectors (size n)"] + pub fn faiss_IndexBinary_add_with_ids( + index: *mut FaissIndexBinary, + n: idx_t, + x: *const u8, + xids: *const idx_t, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_RangeSearchResult_buffer_size(arg1: *const FaissRangeSearchResult) -> usize; + #[doc = " query n vectors of dimension d to the index.\n\n return at most k vectors. If there are not enough results for a\n query, the result array is padded with -1s.\n\n @param index opaque pointer to index object\n @param x input vectors to search, size n * d\n @param labels output labels of the NNs, size n*k\n @param distances output pairwise distances, size n*k"] + pub fn faiss_IndexBinary_search( + index: *const FaissIndexBinary, + n: idx_t, + x: *const u8, + k: idx_t, + distances: *mut i32, + labels: *mut idx_t, + ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " getter for lims: size (nq + 1)"] - pub fn faiss_RangeSearchResult_lims(rsr: *mut FaissRangeSearchResult, lims: *mut *mut usize); + #[doc = " query n vectors of dimension d to the index.\n\n return all vectors with distance < radius. Note that many\n indexes do not implement the range_search (only the k-NN search\n is mandatory).\n\n @param index opaque pointer to index object\n @param x input vectors to search, size n * d\n @param radius search radius\n @param result result table"] + pub fn faiss_IndexBinary_range_search( + index: *const FaissIndexBinary, + n: idx_t, + x: *const u8, + radius: ::std::os::raw::c_int, + result: *mut FaissRangeSearchResult, + ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " getter for labels and respective distances (not sorted):\n result for query i is labels[lims[i]:lims[i+1]]"] - pub fn faiss_RangeSearchResult_labels( - rsr: *mut FaissRangeSearchResult, - labels: *mut *mut idx_t, - distances: *mut *mut f32, - ); + #[doc = " return the indexes of the k vectors closest to the query x.\n\n This function is identical as search but only return labels of neighbors.\n @param index opaque pointer to index object\n @param x input vectors to search, size n * d\n @param labels output labels of the NNs, size n*k"] + pub fn faiss_IndexBinary_assign( + index: *mut FaissIndexBinary, + n: idx_t, + x: *const u8, + labels: *mut idx_t, + k: idx_t, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IDSelector_free(obj: *mut FaissIDSelector); + #[doc = " removes all elements from the database.\n @param index opaque pointer to index object"] + pub fn faiss_IndexBinary_reset(index: *mut FaissIndexBinary) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Encapsulates a set of ids to remove."] - pub fn faiss_IDSelector_is_member( + #[doc = " removes IDs from the index. Not supported by all indexes\n @param index opaque pointer to index object\n @param nremove output for the number of IDs removed"] + pub fn faiss_IndexBinary_remove_ids( + index: *mut FaissIndexBinary, sel: *const FaissIDSelector, - id: idx_t, + n_removed: *mut usize, ) -> ::std::os::raw::c_int; } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIDSelectorRange_H { - _unused: [u8; 0], -} -pub type FaissIDSelectorRange = FaissIDSelectorRange_H; extern "C" { - pub fn faiss_IDSelectorRange_free(obj: *mut FaissIDSelectorRange); + #[doc = " Reconstruct a stored vector (or an approximation if lossy coding)\n\n this function may not be defined for some indexes\n @param index opaque pointer to index object\n @param key id of the vector to reconstruct\n @param recons reconstructed vector (size d)"] + pub fn faiss_IndexBinary_reconstruct( + index: *const FaissIndexBinary, + key: idx_t, + recons: *mut u8, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IDSelectorRange_imin(arg1: *const FaissIDSelectorRange) -> idx_t; + #[doc = " Reconstruct vectors i0 to i0 + ni - 1\n\n this function may not be defined for some indexes\n @param index opaque pointer to index object\n @param recons reconstructed vector (size ni * d)"] + pub fn faiss_IndexBinary_reconstruct_n( + index: *const FaissIndexBinary, + i0: idx_t, + ni: idx_t, + recons: *mut u8, + ) -> ::std::os::raw::c_int; } +pub type FaissIndexFlat = FaissIndex_H; extern "C" { - pub fn faiss_IDSelectorRange_imax(arg1: *const FaissIDSelectorRange) -> idx_t; + #[doc = " Opaque type for IndexFlat"] + pub fn faiss_IndexFlat_new(p_index: *mut *mut FaissIndexFlat) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " remove ids between [imni, imax)"] - pub fn faiss_IDSelectorRange_new( - p_sel: *mut *mut FaissIDSelectorRange, - imin: idx_t, - imax: idx_t, + pub fn faiss_IndexFlat_new_with( + p_index: *mut *mut FaissIndexFlat, + d: idx_t, + metric: FaissMetricType, ) -> ::std::os::raw::c_int; } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIDSelectorBatch_H { - _unused: [u8; 0], +extern "C" { + #[doc = " get a pointer to the index's internal data (the `xb` field). The outputs\n become invalid after any data addition or removal operation.\n\n @param index opaque pointer to index object\n @param p_xb output, the pointer to the beginning of `xb`.\n @param p_size output, the current size of `sb` in number of float values."] + pub fn faiss_IndexFlat_xb(index: *mut FaissIndexFlat, p_xb: *mut *mut f32, p_size: *mut usize); } -pub type FaissIDSelectorBatch = FaissIDSelectorBatch_H; extern "C" { - pub fn faiss_IDSelectorBatch_nbits(arg1: *const FaissIDSelectorBatch) -> ::std::os::raw::c_int; + pub fn faiss_IndexFlat_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlat; } extern "C" { - pub fn faiss_IDSelectorBatch_mask(arg1: *const FaissIDSelectorBatch) -> idx_t; + pub fn faiss_IndexFlat_free(obj: *mut FaissIndexFlat); } extern "C" { - #[doc = " Remove ids from a set. Repetitions of ids in the indices set\n passed to the constructor does not hurt performance. The hash\n function used for the bloom filter and GCC's implementation of\n unordered_set are just the least significant bits of the id. This\n works fine for random ids or ids in sequences but will produce many\n hash collisions if lsb's are always the same"] - pub fn faiss_IDSelectorBatch_new( - p_sel: *mut *mut FaissIDSelectorBatch, - n: usize, - indices: *const idx_t, + #[doc = " compute distance with a subset of vectors\n\n @param index opaque pointer to index object\n @param x query vectors, size n * d\n @param labels indices of the vectors that should be compared\n for each query vector, size n * k\n @param distances\n corresponding output distances, size n * k"] + pub fn faiss_IndexFlat_compute_distance_subset( + index: *mut FaissIndex, + n: idx_t, + x: *const f32, + k: idx_t, + distances: *mut f32, + labels: *const idx_t, ) -> ::std::os::raw::c_int; } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIDSelectorNot_H { - _unused: [u8; 0], +pub type FaissIndexFlatIP = FaissIndex_H; +extern "C" { + pub fn faiss_IndexFlatIP_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlatIP; } -pub type FaissIDSelectorNot = FaissIDSelectorNot_H; extern "C" { - pub fn faiss_IDSelectorNot_new( - p_sel: *mut *mut FaissIDSelectorNot, - sel: *const FaissIDSelector, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexFlatIP_free(obj: *mut FaissIndexFlatIP); } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIDSelectorAnd_H { - _unused: [u8; 0], +extern "C" { + #[doc = " Opaque type for IndexFlatIP"] + pub fn faiss_IndexFlatIP_new(p_index: *mut *mut FaissIndexFlatIP) -> ::std::os::raw::c_int; } -pub type FaissIDSelectorAnd = FaissIDSelectorAnd_H; extern "C" { - pub fn faiss_IDSelectorAnd_new( - p_sel: *mut *mut FaissIDSelectorAnd, - lhs_sel: *const FaissIDSelector, - rhs_sel: *const FaissIDSelector, + pub fn faiss_IndexFlatIP_new_with( + p_index: *mut *mut FaissIndexFlatIP, + d: idx_t, ) -> ::std::os::raw::c_int; } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIDSelectorOr_H { - _unused: [u8; 0], +pub type FaissIndexFlatL2 = FaissIndex_H; +extern "C" { + pub fn faiss_IndexFlatL2_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlatL2; } -pub type FaissIDSelectorOr = FaissIDSelectorOr_H; extern "C" { - pub fn faiss_IDSelectorOr_new( - p_sel: *mut *mut FaissIDSelectorOr, - lhs_sel: *const FaissIDSelector, - rhs_sel: *const FaissIDSelector, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexFlatL2_free(obj: *mut FaissIndexFlatL2); } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIDSelectorXOr_H { - _unused: [u8; 0], +extern "C" { + #[doc = " Opaque type for IndexFlatL2"] + pub fn faiss_IndexFlatL2_new(p_index: *mut *mut FaissIndexFlatL2) -> ::std::os::raw::c_int; } -pub type FaissIDSelectorXOr = FaissIDSelectorXOr_H; extern "C" { - pub fn faiss_IDSelectorXOr_new( - p_sel: *mut *mut FaissIDSelectorXOr, - lhs_sel: *const FaissIDSelector, - rhs_sel: *const FaissIDSelector, + pub fn faiss_IndexFlatL2_new_with( + p_index: *mut *mut FaissIndexFlatL2, + d: idx_t, ) -> ::std::os::raw::c_int; } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissBufferList_H { - _unused: [u8; 0], +pub type FaissIndexRefineFlat = FaissIndex_H; +extern "C" { + #[doc = " Opaque type for IndexRefineFlat\n\n Index that queries in a base_index (a fast one) and refines the\n results with an exact search, hopefully improving the results."] + pub fn faiss_IndexRefineFlat_new( + p_index: *mut *mut FaissIndexRefineFlat, + base_index: *mut FaissIndex, + ) -> ::std::os::raw::c_int; } -pub type FaissBufferList = FaissBufferList_H; extern "C" { - pub fn faiss_BufferList_free(obj: *mut FaissBufferList); + pub fn faiss_IndexRefineFlat_free(obj: *mut FaissIndexRefineFlat); } extern "C" { - pub fn faiss_BufferList_buffer_size(arg1: *const FaissBufferList) -> usize; + pub fn faiss_IndexRefineFlat_cast(arg1: *mut FaissIndex) -> *mut FaissIndexRefineFlat; } extern "C" { - pub fn faiss_BufferList_wp(arg1: *const FaissBufferList) -> usize; -} -#[doc = " List of temporary buffers used to store results before they are\n copied to the RangeSearchResult object."] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissBuffer { - pub ids: *mut idx_t, - pub dis: *mut f32, -} -#[test] -fn bindgen_test_layout_FaissBuffer() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(FaissBuffer)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(FaissBuffer)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ids) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(FaissBuffer), - "::", - stringify!(ids) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dis) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(FaissBuffer), - "::", - stringify!(dis) - ) - ); + pub fn faiss_IndexRefineFlat_own_fields( + arg1: *const FaissIndexRefineFlat, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_BufferList_append_buffer(bl: *mut FaissBufferList) -> ::std::os::raw::c_int; + pub fn faiss_IndexRefineFlat_set_own_fields( + arg1: *mut FaissIndexRefineFlat, + arg2: ::std::os::raw::c_int, + ); } extern "C" { - pub fn faiss_BufferList_new( - p_bl: *mut *mut FaissBufferList, - buffer_size: usize, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexRefineFlat_k_factor(arg1: *const FaissIndexRefineFlat) -> f32; } extern "C" { - pub fn faiss_BufferList_add( - bl: *mut FaissBufferList, - id: idx_t, - dis: f32, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexRefineFlat_set_k_factor(arg1: *mut FaissIndexRefineFlat, arg2: f32); } +pub type FaissIndexFlat1D = FaissIndex_H; extern "C" { - #[doc = " copy elemnts ofs:ofs+n-1 seen as linear data in the buffers to\n tables dest_ids, dest_dis"] - pub fn faiss_BufferList_copy_range( - bl: *mut FaissBufferList, - ofs: usize, - n: usize, - dest_ids: *mut idx_t, - dest_dis: *mut f32, - ) -> ::std::os::raw::c_int; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissRangeSearchPartialResult_H { - _unused: [u8; 0], -} -pub type FaissRangeSearchPartialResult = FaissRangeSearchPartialResult_H; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissRangeQueryResult_H { - _unused: [u8; 0], + pub fn faiss_IndexFlat1D_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlat1D; } -pub type FaissRangeQueryResult = FaissRangeQueryResult_H; extern "C" { - pub fn faiss_RangeQueryResult_qno(arg1: *const FaissRangeQueryResult) -> idx_t; + pub fn faiss_IndexFlat1D_free(obj: *mut FaissIndexFlat1D); } extern "C" { - pub fn faiss_RangeQueryResult_nres(arg1: *const FaissRangeQueryResult) -> usize; + #[doc = " Opaque type for IndexFlat1D\n\n optimized version for 1D \"vectors\""] + pub fn faiss_IndexFlat1D_new(p_index: *mut *mut FaissIndexFlat1D) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_RangeQueryResult_pres( - arg1: *const FaissRangeQueryResult, - ) -> *mut FaissRangeSearchPartialResult; + pub fn faiss_IndexFlat1D_new_with( + p_index: *mut *mut FaissIndexFlat1D, + continuous_update: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " result structure for a single query"] - pub fn faiss_RangeQueryResult_add( - qr: *mut FaissRangeQueryResult, - dis: f32, - id: idx_t, + pub fn faiss_IndexFlat1D_update_permutation( + index: *mut FaissIndexFlat1D, ) -> ::std::os::raw::c_int; } +pub type FaissIndexIVFFlat = FaissIndex_H; extern "C" { - pub fn faiss_RangeSearchPartialResult_res( - arg1: *const FaissRangeSearchPartialResult, - ) -> *mut FaissRangeSearchResult; + pub fn faiss_IndexIVFFlat_free(obj: *mut FaissIndexIVFFlat); } extern "C" { - pub fn faiss_RangeSearchPartialResult_new( - p_res: *mut *mut FaissRangeSearchPartialResult, - res_in: *mut FaissRangeSearchResult, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_cast(arg1: *mut FaissIndex) -> *mut FaissIndexIVFFlat; } extern "C" { - pub fn faiss_RangeSearchPartialResult_finalize( - res: *mut FaissRangeSearchPartialResult, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_nlist(arg1: *const FaissIndexIVFFlat) -> usize; } extern "C" { - #[doc = " called by range_search before do_allocation"] - pub fn faiss_RangeSearchPartialResult_set_lims( - res: *mut FaissRangeSearchPartialResult, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_nprobe(arg1: *const FaissIndexIVFFlat) -> usize; } extern "C" { - pub fn faiss_RangeSearchPartialResult_new_result( - res: *mut FaissRangeSearchPartialResult, - qno: idx_t, - qr: *mut *mut FaissRangeQueryResult, - ) -> ::std::os::raw::c_int; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissDistanceComputer_H { - _unused: [u8; 0], + pub fn faiss_IndexIVFFlat_set_nprobe(arg1: *mut FaissIndexIVFFlat, arg2: usize); } -pub type FaissDistanceComputer = FaissDistanceComputer_H; extern "C" { - #[doc = " called before computing distances"] - pub fn faiss_DistanceComputer_set_query( - dc: *mut FaissDistanceComputer, - x: *const f32, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_quantizer(arg1: *const FaissIndexIVFFlat) -> *mut FaissIndex; } extern "C" { - #[doc = " Compute distance of vector i to current query.\n This function corresponds to the function call operator:\n DistanceComputer::operator()"] - pub fn faiss_DistanceComputer_vector_to_query_dis( - dc: *mut FaissDistanceComputer, - i: idx_t, - qd: *mut f32, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_quantizer_trains_alone( + arg1: *const FaissIndexIVFFlat, + ) -> ::std::os::raw::c_char; } extern "C" { - #[doc = " compute distance between two stored vectors"] - pub fn faiss_DistanceComputer_symmetric_dis( - dc: *mut FaissDistanceComputer, - i: idx_t, - j: idx_t, - vd: *mut f32, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_own_fields(arg1: *const FaissIndexIVFFlat) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_DistanceComputer_free(obj: *mut FaissDistanceComputer); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIndexBinary_H { - _unused: [u8; 0], + pub fn faiss_IndexIVFFlat_set_own_fields( + arg1: *mut FaissIndexIVFFlat, + arg2: ::std::os::raw::c_int, + ); } -pub type FaissIndexBinary = FaissIndexBinary_H; extern "C" { - pub fn faiss_IndexBinary_free(obj: *mut FaissIndexBinary); + #[doc = " whether object owns the quantizer"] + pub fn faiss_IndexIVFFlat_new(p_index: *mut *mut FaissIndexIVFFlat) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexBinary_d(arg1: *const FaissIndexBinary) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_new_with( + p_index: *mut *mut FaissIndexIVFFlat, + quantizer: *mut FaissIndex, + d: usize, + nlist: usize, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexBinary_is_trained(arg1: *const FaissIndexBinary) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_new_with_metric( + p_index: *mut *mut FaissIndexIVFFlat, + quantizer: *mut FaissIndex, + d: usize, + nlist: usize, + metric: FaissMetricType, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexBinary_ntotal(arg1: *const FaissIndexBinary) -> idx_t; + pub fn faiss_IndexIVFFlat_add_core( + index: *mut FaissIndexIVFFlat, + n: idx_t, + x: *const f32, + xids: *const idx_t, + precomputed_idx: *const i64, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexBinary_metric_type(arg1: *const FaissIndexBinary) -> FaissMetricType; + #[doc = " Update a subset of vectors.\n\n The index must have a direct_map\n\n @param nv nb of vectors to update\n @param idx vector indices to update, size nv\n @param v vectors of new values, size nv*d"] + pub fn faiss_IndexIVFFlat_update_vectors( + index: *mut FaissIndexIVFFlat, + nv: ::std::os::raw::c_int, + idx: *mut idx_t, + v: *const f32, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexBinary_verbose(arg1: *const FaissIndexBinary) -> ::std::os::raw::c_int; + pub fn faiss_RangeSearchResult_nq(arg1: *const FaissRangeSearchResult) -> usize; } extern "C" { - pub fn faiss_IndexBinary_set_verbose(arg1: *mut FaissIndexBinary, arg2: ::std::os::raw::c_int); + pub fn faiss_RangeSearchResult_new( + p_rsr: *mut *mut FaissRangeSearchResult, + nq: idx_t, + ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Perform training on a representative set of vectors\n\n @param index opaque pointer to index object\n @param n nb of training vectors\n @param x training vectors, size n * d"] - pub fn faiss_IndexBinary_train( - index: *mut FaissIndexBinary, - n: idx_t, - x: *const u8, + pub fn faiss_RangeSearchResult_new_with( + p_rsr: *mut *mut FaissRangeSearchResult, + nq: idx_t, + alloc_lims: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Add n vectors of dimension d to the index.\n\n Vectors are implicitly assigned labels ntotal .. ntotal + n - 1\n This function slices the input vectors in chunks smaller than\n blocksize_add and calls add_core.\n @param index opaque pointer to index object\n @param x input matrix, size n * d"] - pub fn faiss_IndexBinary_add( - index: *mut FaissIndexBinary, - n: idx_t, - x: *const u8, + #[doc = " called when lims contains the nb of elements result entries\n for each query"] + pub fn faiss_RangeSearchResult_do_allocation( + rsr: *mut FaissRangeSearchResult, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Same as add, but stores xids instead of sequential ids.\n\n The default implementation fails with an assertion, as it is\n not supported by all indexes.\n\n @param index opaque pointer to index object\n @param xids if non-null, ids to store for the vectors (size n)"] - pub fn faiss_IndexBinary_add_with_ids( - index: *mut FaissIndexBinary, - n: idx_t, - x: *const u8, - xids: *const idx_t, - ) -> ::std::os::raw::c_int; + pub fn faiss_RangeSearchResult_free(obj: *mut FaissRangeSearchResult); } extern "C" { - #[doc = " query n vectors of dimension d to the index.\n\n return at most k vectors. If there are not enough results for a\n query, the result array is padded with -1s.\n\n @param index opaque pointer to index object\n @param x input vectors to search, size n * d\n @param labels output labels of the NNs, size n*k\n @param distances output pairwise distances, size n*k"] - pub fn faiss_IndexBinary_search( - index: *const FaissIndexBinary, - n: idx_t, - x: *const u8, - k: idx_t, - distances: *mut i32, - labels: *mut idx_t, - ) -> ::std::os::raw::c_int; + pub fn faiss_RangeSearchResult_buffer_size(arg1: *const FaissRangeSearchResult) -> usize; } extern "C" { - #[doc = " query n vectors of dimension d to the index.\n\n return all vectors with distance < radius. Note that many\n indexes do not implement the range_search (only the k-NN search\n is mandatory).\n\n @param index opaque pointer to index object\n @param x input vectors to search, size n * d\n @param radius search radius\n @param result result table"] - pub fn faiss_IndexBinary_range_search( - index: *const FaissIndexBinary, - n: idx_t, - x: *const u8, - radius: ::std::os::raw::c_int, - result: *mut FaissRangeSearchResult, - ) -> ::std::os::raw::c_int; + #[doc = " getter for lims: size (nq + 1)"] + pub fn faiss_RangeSearchResult_lims(rsr: *mut FaissRangeSearchResult, lims: *mut *mut usize); } extern "C" { - #[doc = " return the indexes of the k vectors closest to the query x.\n\n This function is identical as search but only return labels of neighbors.\n @param index opaque pointer to index object\n @param x input vectors to search, size n * d\n @param labels output labels of the NNs, size n*k"] - pub fn faiss_IndexBinary_assign( - index: *mut FaissIndexBinary, - n: idx_t, - x: *const u8, - labels: *mut idx_t, - k: idx_t, - ) -> ::std::os::raw::c_int; + #[doc = " getter for labels and respective distances (not sorted):\n result for query i is labels[lims[i]:lims[i+1]]"] + pub fn faiss_RangeSearchResult_labels( + rsr: *mut FaissRangeSearchResult, + labels: *mut *mut idx_t, + distances: *mut *mut f32, + ); } extern "C" { - #[doc = " removes all elements from the database.\n @param index opaque pointer to index object"] - pub fn faiss_IndexBinary_reset(index: *mut FaissIndexBinary) -> ::std::os::raw::c_int; + pub fn faiss_IDSelector_free(obj: *mut FaissIDSelector); } extern "C" { - #[doc = " removes IDs from the index. Not supported by all indexes\n @param index opaque pointer to index object\n @param nremove output for the number of IDs removed"] - pub fn faiss_IndexBinary_remove_ids( - index: *mut FaissIndexBinary, + #[doc = " Encapsulates a set of ids to remove."] + pub fn faiss_IDSelector_is_member( sel: *const FaissIDSelector, - n_removed: *mut usize, + id: idx_t, ) -> ::std::os::raw::c_int; } -extern "C" { - #[doc = " Reconstruct a stored vector (or an approximation if lossy coding)\n\n this function may not be defined for some indexes\n @param index opaque pointer to index object\n @param key id of the vector to reconstruct\n @param recons reconstructed vector (size d)"] - pub fn faiss_IndexBinary_reconstruct( - index: *const FaissIndexBinary, - key: idx_t, - recons: *mut u8, - ) -> ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIDSelectorRange_H { + _unused: [u8; 0], } +pub type FaissIDSelectorRange = FaissIDSelectorRange_H; extern "C" { - #[doc = " Reconstruct vectors i0 to i0 + ni - 1\n\n this function may not be defined for some indexes\n @param index opaque pointer to index object\n @param recons reconstructed vector (size ni * d)"] - pub fn faiss_IndexBinary_reconstruct_n( - index: *const FaissIndexBinary, - i0: idx_t, - ni: idx_t, - recons: *mut u8, - ) -> ::std::os::raw::c_int; + pub fn faiss_IDSelectorRange_free(obj: *mut FaissIDSelectorRange); } extern "C" { - #[doc = " Build and index with the sequence of processing steps described in\n the string."] - pub fn faiss_index_factory( - p_index: *mut *mut FaissIndex, - d: ::std::os::raw::c_int, - description: *const ::std::os::raw::c_char, - metric: FaissMetricType, - ) -> ::std::os::raw::c_int; + pub fn faiss_IDSelectorRange_imin(arg1: *const FaissIDSelectorRange) -> idx_t; } -pub type FaissIndexFlat = FaissIndex_H; extern "C" { - #[doc = " Opaque type for IndexFlat"] - pub fn faiss_IndexFlat_new(p_index: *mut *mut FaissIndexFlat) -> ::std::os::raw::c_int; + pub fn faiss_IDSelectorRange_imax(arg1: *const FaissIDSelectorRange) -> idx_t; } extern "C" { - pub fn faiss_IndexFlat_new_with( - p_index: *mut *mut FaissIndexFlat, - d: idx_t, - metric: FaissMetricType, + #[doc = " remove ids between [imni, imax)"] + pub fn faiss_IDSelectorRange_new( + p_sel: *mut *mut FaissIDSelectorRange, + imin: idx_t, + imax: idx_t, ) -> ::std::os::raw::c_int; } -extern "C" { - #[doc = " get a pointer to the index's internal data (the `xb` field). The outputs\n become invalid after any data addition or removal operation.\n\n @param index opaque pointer to index object\n @param p_xb output, the pointer to the beginning of `xb`.\n @param p_size output, the current size of `sb` in number of float values."] - pub fn faiss_IndexFlat_xb(index: *mut FaissIndexFlat, p_xb: *mut *mut f32, p_size: *mut usize); +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIDSelectorBatch_H { + _unused: [u8; 0], } +pub type FaissIDSelectorBatch = FaissIDSelectorBatch_H; extern "C" { - pub fn faiss_IndexFlat_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlat; + pub fn faiss_IDSelectorBatch_nbits(arg1: *const FaissIDSelectorBatch) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexFlat_free(obj: *mut FaissIndexFlat); + pub fn faiss_IDSelectorBatch_mask(arg1: *const FaissIDSelectorBatch) -> idx_t; } extern "C" { - #[doc = " compute distance with a subset of vectors\n\n @param index opaque pointer to index object\n @param x query vectors, size n * d\n @param labels indices of the vectors that should be compared\n for each query vector, size n * k\n @param distances\n corresponding output distances, size n * k"] - pub fn faiss_IndexFlat_compute_distance_subset( - index: *mut FaissIndex, - n: idx_t, - x: *const f32, - k: idx_t, - distances: *mut f32, - labels: *const idx_t, + #[doc = " Remove ids from a set. Repetitions of ids in the indices set\n passed to the constructor does not hurt performance. The hash\n function used for the bloom filter and GCC's implementation of\n unordered_set are just the least significant bits of the id. This\n works fine for random ids or ids in sequences but will produce many\n hash collisions if lsb's are always the same"] + pub fn faiss_IDSelectorBatch_new( + p_sel: *mut *mut FaissIDSelectorBatch, + n: usize, + indices: *const idx_t, ) -> ::std::os::raw::c_int; } -pub type FaissIndexFlatIP = FaissIndex_H; -extern "C" { - pub fn faiss_IndexFlatIP_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlatIP; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIDSelectorNot_H { + _unused: [u8; 0], } +pub type FaissIDSelectorNot = FaissIDSelectorNot_H; extern "C" { - pub fn faiss_IndexFlatIP_free(obj: *mut FaissIndexFlatIP); + pub fn faiss_IDSelectorNot_new( + p_sel: *mut *mut FaissIDSelectorNot, + sel: *const FaissIDSelector, + ) -> ::std::os::raw::c_int; } -extern "C" { - #[doc = " Opaque type for IndexFlatIP"] - pub fn faiss_IndexFlatIP_new(p_index: *mut *mut FaissIndexFlatIP) -> ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIDSelectorAnd_H { + _unused: [u8; 0], } +pub type FaissIDSelectorAnd = FaissIDSelectorAnd_H; extern "C" { - pub fn faiss_IndexFlatIP_new_with( - p_index: *mut *mut FaissIndexFlatIP, - d: idx_t, + pub fn faiss_IDSelectorAnd_new( + p_sel: *mut *mut FaissIDSelectorAnd, + lhs_sel: *const FaissIDSelector, + rhs_sel: *const FaissIDSelector, ) -> ::std::os::raw::c_int; } -pub type FaissIndexFlatL2 = FaissIndex_H; -extern "C" { - pub fn faiss_IndexFlatL2_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlatL2; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIDSelectorOr_H { + _unused: [u8; 0], } +pub type FaissIDSelectorOr = FaissIDSelectorOr_H; extern "C" { - pub fn faiss_IndexFlatL2_free(obj: *mut FaissIndexFlatL2); + pub fn faiss_IDSelectorOr_new( + p_sel: *mut *mut FaissIDSelectorOr, + lhs_sel: *const FaissIDSelector, + rhs_sel: *const FaissIDSelector, + ) -> ::std::os::raw::c_int; } -extern "C" { - #[doc = " Opaque type for IndexFlatL2"] - pub fn faiss_IndexFlatL2_new(p_index: *mut *mut FaissIndexFlatL2) -> ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIDSelectorXOr_H { + _unused: [u8; 0], } +pub type FaissIDSelectorXOr = FaissIDSelectorXOr_H; extern "C" { - pub fn faiss_IndexFlatL2_new_with( - p_index: *mut *mut FaissIndexFlatL2, - d: idx_t, + pub fn faiss_IDSelectorXOr_new( + p_sel: *mut *mut FaissIDSelectorXOr, + lhs_sel: *const FaissIDSelector, + rhs_sel: *const FaissIDSelector, ) -> ::std::os::raw::c_int; } -pub type FaissIndexRefineFlat = FaissIndex_H; -extern "C" { - #[doc = " Opaque type for IndexRefineFlat\n\n Index that queries in a base_index (a fast one) and refines the\n results with an exact search, hopefully improving the results."] - pub fn faiss_IndexRefineFlat_new( - p_index: *mut *mut FaissIndexRefineFlat, - base_index: *mut FaissIndex, - ) -> ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissBufferList_H { + _unused: [u8; 0], } +pub type FaissBufferList = FaissBufferList_H; extern "C" { - pub fn faiss_IndexRefineFlat_free(obj: *mut FaissIndexRefineFlat); + pub fn faiss_BufferList_free(obj: *mut FaissBufferList); } extern "C" { - pub fn faiss_IndexRefineFlat_cast(arg1: *mut FaissIndex) -> *mut FaissIndexRefineFlat; + pub fn faiss_BufferList_buffer_size(arg1: *const FaissBufferList) -> usize; } extern "C" { - pub fn faiss_IndexRefineFlat_own_fields( - arg1: *const FaissIndexRefineFlat, - ) -> ::std::os::raw::c_int; + pub fn faiss_BufferList_wp(arg1: *const FaissBufferList) -> usize; } -extern "C" { - pub fn faiss_IndexRefineFlat_set_own_fields( - arg1: *mut FaissIndexRefineFlat, - arg2: ::std::os::raw::c_int, +#[doc = " List of temporary buffers used to store results before they are\n copied to the RangeSearchResult object."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissBuffer { + pub ids: *mut idx_t, + pub dis: *mut f32, +} +#[test] +fn bindgen_test_layout_FaissBuffer() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(FaissBuffer)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(FaissBuffer)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).ids) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(FaissBuffer), + "::", + stringify!(ids) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).dis) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(FaissBuffer), + "::", + stringify!(dis) + ) ); } extern "C" { - pub fn faiss_IndexRefineFlat_k_factor(arg1: *const FaissIndexRefineFlat) -> f32; + pub fn faiss_BufferList_append_buffer(bl: *mut FaissBufferList) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexRefineFlat_set_k_factor(arg1: *mut FaissIndexRefineFlat, arg2: f32); + pub fn faiss_BufferList_new( + p_bl: *mut *mut FaissBufferList, + buffer_size: usize, + ) -> ::std::os::raw::c_int; } -pub type FaissIndexFlat1D = FaissIndex_H; extern "C" { - pub fn faiss_IndexFlat1D_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlat1D; + pub fn faiss_BufferList_add( + bl: *mut FaissBufferList, + id: idx_t, + dis: f32, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexFlat1D_free(obj: *mut FaissIndexFlat1D); + #[doc = " copy elemnts ofs:ofs+n-1 seen as linear data in the buffers to\n tables dest_ids, dest_dis"] + pub fn faiss_BufferList_copy_range( + bl: *mut FaissBufferList, + ofs: usize, + n: usize, + dest_ids: *mut idx_t, + dest_dis: *mut f32, + ) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissRangeSearchPartialResult_H { + _unused: [u8; 0], } +pub type FaissRangeSearchPartialResult = FaissRangeSearchPartialResult_H; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissRangeQueryResult_H { + _unused: [u8; 0], +} +pub type FaissRangeQueryResult = FaissRangeQueryResult_H; extern "C" { - #[doc = " Opaque type for IndexFlat1D\n\n optimized version for 1D \"vectors\""] - pub fn faiss_IndexFlat1D_new(p_index: *mut *mut FaissIndexFlat1D) -> ::std::os::raw::c_int; + pub fn faiss_RangeQueryResult_qno(arg1: *const FaissRangeQueryResult) -> idx_t; +} +extern "C" { + pub fn faiss_RangeQueryResult_nres(arg1: *const FaissRangeQueryResult) -> usize; } extern "C" { - pub fn faiss_IndexFlat1D_new_with( - p_index: *mut *mut FaissIndexFlat1D, - continuous_update: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; + pub fn faiss_RangeQueryResult_pres( + arg1: *const FaissRangeQueryResult, + ) -> *mut FaissRangeSearchPartialResult; } extern "C" { - pub fn faiss_IndexFlat1D_update_permutation( - index: *mut FaissIndexFlat1D, + #[doc = " result structure for a single query"] + pub fn faiss_RangeQueryResult_add( + qr: *mut FaissRangeQueryResult, + dis: f32, + id: idx_t, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index` when a file descriptor is\n provided."] - pub fn faiss_write_index(idx: *const FaissIndex, f: *mut FILE) -> ::std::os::raw::c_int; + pub fn faiss_RangeSearchPartialResult_res( + arg1: *const FaissRangeSearchPartialResult, + ) -> *mut FaissRangeSearchResult; } extern "C" { - #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index` when a file path is provided."] - pub fn faiss_write_index_fname( - idx: *const FaissIndex, - fname: *const ::std::os::raw::c_char, + pub fn faiss_RangeSearchPartialResult_new( + p_res: *mut *mut FaissRangeSearchPartialResult, + res_in: *mut FaissRangeSearchResult, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index` when a file descriptor is given."] - pub fn faiss_read_index( - f: *mut FILE, - io_flags: ::std::os::raw::c_int, - p_out: *mut *mut FaissIndex, + pub fn faiss_RangeSearchPartialResult_finalize( + res: *mut FaissRangeSearchPartialResult, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index` when a file path is given."] - pub fn faiss_read_index_fname( - fname: *const ::std::os::raw::c_char, - io_flags: ::std::os::raw::c_int, - p_out: *mut *mut FaissIndex, + #[doc = " called by range_search before do_allocation"] + pub fn faiss_RangeSearchPartialResult_set_lims( + res: *mut FaissRangeSearchPartialResult, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index_binary` when a file descriptor is\n provided."] - pub fn faiss_write_index_binary( - idx: *const FaissIndexBinary, - f: *mut FILE, + pub fn faiss_RangeSearchPartialResult_new_result( + res: *mut FaissRangeSearchPartialResult, + qno: idx_t, + qr: *mut *mut FaissRangeQueryResult, ) -> ::std::os::raw::c_int; } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissDistanceComputer_H { + _unused: [u8; 0], +} +pub type FaissDistanceComputer = FaissDistanceComputer_H; extern "C" { - #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index_binary` when a file path is\n provided."] - pub fn faiss_write_index_binary_fname( - idx: *const FaissIndexBinary, - fname: *const ::std::os::raw::c_char, + #[doc = " called before computing distances"] + pub fn faiss_DistanceComputer_set_query( + dc: *mut FaissDistanceComputer, + x: *const f32, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index_binary` when a file descriptor is\n given."] - pub fn faiss_read_index_binary( - f: *mut FILE, - io_flags: ::std::os::raw::c_int, - p_out: *mut *mut FaissIndexBinary, + #[doc = " Compute distance of vector i to current query.\n This function corresponds to the function call operator:\n DistanceComputer::operator()"] + pub fn faiss_DistanceComputer_vector_to_query_dis( + dc: *mut FaissDistanceComputer, + i: idx_t, + qd: *mut f32, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index_binary` when a file path is given."] - pub fn faiss_read_index_binary_fname( - fname: *const ::std::os::raw::c_char, - io_flags: ::std::os::raw::c_int, - p_out: *mut *mut FaissIndexBinary, + #[doc = " compute distance between two stored vectors"] + pub fn faiss_DistanceComputer_symmetric_dis( + dc: *mut FaissDistanceComputer, + i: idx_t, + j: idx_t, + vd: *mut f32, ) -> ::std::os::raw::c_int; } +extern "C" { + pub fn faiss_DistanceComputer_free(obj: *mut FaissDistanceComputer); +} pub type FaissSearchParametersIVF = FaissSearchParameters_H; extern "C" { pub fn faiss_SearchParametersIVF_free(obj: *mut FaissSearchParametersIVF); @@ -1455,78 +1439,6 @@ extern "C" { #[doc = " global var that collects all statists"] pub fn faiss_get_indexIVF_stats() -> *mut FaissIndexIVFStats; } -pub type FaissIndexIVFFlat = FaissIndex_H; -extern "C" { - pub fn faiss_IndexIVFFlat_free(obj: *mut FaissIndexIVFFlat); -} -extern "C" { - pub fn faiss_IndexIVFFlat_cast(arg1: *mut FaissIndex) -> *mut FaissIndexIVFFlat; -} -extern "C" { - pub fn faiss_IndexIVFFlat_nlist(arg1: *const FaissIndexIVFFlat) -> usize; -} -extern "C" { - pub fn faiss_IndexIVFFlat_nprobe(arg1: *const FaissIndexIVFFlat) -> usize; -} -extern "C" { - pub fn faiss_IndexIVFFlat_set_nprobe(arg1: *mut FaissIndexIVFFlat, arg2: usize); -} -extern "C" { - pub fn faiss_IndexIVFFlat_quantizer(arg1: *const FaissIndexIVFFlat) -> *mut FaissIndex; -} -extern "C" { - pub fn faiss_IndexIVFFlat_quantizer_trains_alone( - arg1: *const FaissIndexIVFFlat, - ) -> ::std::os::raw::c_char; -} -extern "C" { - pub fn faiss_IndexIVFFlat_own_fields(arg1: *const FaissIndexIVFFlat) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn faiss_IndexIVFFlat_set_own_fields( - arg1: *mut FaissIndexIVFFlat, - arg2: ::std::os::raw::c_int, - ); -} -extern "C" { - #[doc = " whether object owns the quantizer"] - pub fn faiss_IndexIVFFlat_new(p_index: *mut *mut FaissIndexIVFFlat) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn faiss_IndexIVFFlat_new_with( - p_index: *mut *mut FaissIndexIVFFlat, - quantizer: *mut FaissIndex, - d: usize, - nlist: usize, - ) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn faiss_IndexIVFFlat_new_with_metric( - p_index: *mut *mut FaissIndexIVFFlat, - quantizer: *mut FaissIndex, - d: usize, - nlist: usize, - metric: FaissMetricType, - ) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn faiss_IndexIVFFlat_add_core( - index: *mut FaissIndexIVFFlat, - n: idx_t, - x: *const f32, - xids: *const idx_t, - precomputed_idx: *const i64, - ) -> ::std::os::raw::c_int; -} -extern "C" { - #[doc = " Update a subset of vectors.\n\n The index must have a direct_map\n\n @param nv nb of vectors to update\n @param idx vector indices to update, size nv\n @param v vectors of new values, size nv*d"] - pub fn faiss_IndexIVFFlat_update_vectors( - index: *mut FaissIndexIVFFlat, - nv: ::std::os::raw::c_int, - idx: *mut idx_t, - v: *const f32, - ) -> ::std::os::raw::c_int; -} pub type FaissIndexLSH = FaissIndex_H; extern "C" { pub fn faiss_IndexLSH_free(obj: *mut FaissIndexLSH); @@ -2092,6 +2004,109 @@ extern "C" { #[doc = " get a pointer to the sub-index (the `index` field).\n The outputs of this function become invalid after any operation that can\n modify the index.\n\n @param index opaque pointer to index object"] pub fn faiss_IndexIDMap2_sub_index(index: *mut FaissIndexIDMap2) -> *mut FaissIndex; } +pub type FILE = [u64; 27usize]; +extern "C" { + #[doc = " Clone an index. This is equivalent to `faiss::clone_index`"] + pub fn faiss_clone_index( + arg1: *const FaissIndex, + p_out: *mut *mut FaissIndex, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Clone a binary index. This is equivalent to `faiss::clone_index_binary`"] + pub fn faiss_clone_index_binary( + arg1: *const FaissIndexBinary, + p_out: *mut *mut FaissIndexBinary, + ) -> ::std::os::raw::c_int; +} +#[doc = " No error"] +pub const FaissErrorCode_OK: FaissErrorCode = 0; +#[doc = " Any exception other than Faiss or standard C++ library exceptions"] +pub const FaissErrorCode_UNKNOWN_EXCEPT: FaissErrorCode = -1; +#[doc = " Faiss library exception"] +pub const FaissErrorCode_FAISS_EXCEPT: FaissErrorCode = -2; +#[doc = " Standard C++ library exception"] +pub const FaissErrorCode_STD_EXCEPT: FaissErrorCode = -4; +#[doc = " An error code which depends on the exception thrown from the previous\n operation. See `faiss_get_last_error` to retrieve the error message."] +pub type FaissErrorCode = ::std::os::raw::c_int; +extern "C" { + #[doc = " Get the error message of the last failed operation performed by Faiss.\n The given pointer is only invalid until another Faiss function is\n called."] + pub fn faiss_get_last_error() -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = " Build an index with the sequence of processing steps described in\n the string."] + pub fn faiss_index_factory( + p_index: *mut *mut FaissIndex, + d: ::std::os::raw::c_int, + description: *const ::std::os::raw::c_char, + metric: FaissMetricType, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Build a binary index with the sequence of processing steps described in\n the string."] + pub fn faiss_index_binary_factory( + p_index: *mut *mut FaissIndexBinary, + d: ::std::os::raw::c_int, + description: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index` when a file descriptor is\n provided."] + pub fn faiss_write_index(idx: *const FaissIndex, f: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index` when a file path is provided."] + pub fn faiss_write_index_fname( + idx: *const FaissIndex, + fname: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index` when a file descriptor is given."] + pub fn faiss_read_index( + f: *mut FILE, + io_flags: ::std::os::raw::c_int, + p_out: *mut *mut FaissIndex, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index` when a file path is given."] + pub fn faiss_read_index_fname( + fname: *const ::std::os::raw::c_char, + io_flags: ::std::os::raw::c_int, + p_out: *mut *mut FaissIndex, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index_binary` when a file descriptor is\n provided."] + pub fn faiss_write_index_binary( + idx: *const FaissIndexBinary, + f: *mut FILE, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index_binary` when a file path is\n provided."] + pub fn faiss_write_index_binary_fname( + idx: *const FaissIndexBinary, + fname: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index_binary` when a file descriptor is\n given."] + pub fn faiss_read_index_binary( + f: *mut FILE, + io_flags: ::std::os::raw::c_int, + p_out: *mut *mut FaissIndexBinary, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index_binary` when a file path is given."] + pub fn faiss_read_index_binary_fname( + fname: *const ::std::os::raw::c_char, + io_flags: ::std::os::raw::c_int, + p_out: *mut *mut FaissIndexBinary, + ) -> ::std::os::raw::c_int; +} extern "C" { #[doc = " Compute pairwise distances between sets of vectors"] pub fn faiss_pairwise_L2sqr( diff --git a/faiss-sys/src/bindings_gpu.rs b/faiss-sys/src/bindings_gpu.rs index 996ad28..84202a3 100644 --- a/faiss-sys/src/bindings_gpu.rs +++ b/faiss-sys/src/bindings_gpu.rs @@ -297,14 +297,6 @@ extern "C" { arg3: *mut *mut FaissParameterRange, ) -> ::std::os::raw::c_int; } -pub type FILE = [u64; 27usize]; -extern "C" { - #[doc = " Clone an index. This is equivalent to `faiss::clone_index`"] - pub fn faiss_clone_index( - arg1: *const FaissIndex, - p_out: *mut *mut FaissIndex, - ) -> ::std::os::raw::c_int; -} #[doc = " Class for the clustering parameters. Can be passed to the\n constructor of the Clustering object."] #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -593,638 +585,630 @@ extern "C" { q_error: *mut f32, ) -> ::std::os::raw::c_int; } -#[doc = " No error"] -pub const FaissErrorCode_OK: FaissErrorCode = 0; -#[doc = " Any exception other than Faiss or standard C++ library exceptions"] -pub const FaissErrorCode_UNKNOWN_EXCEPT: FaissErrorCode = -1; -#[doc = " Faiss library exception"] -pub const FaissErrorCode_FAISS_EXCEPT: FaissErrorCode = -2; -#[doc = " Standard C++ library exception"] -pub const FaissErrorCode_STD_EXCEPT: FaissErrorCode = -4; -#[doc = " An error code which depends on the exception thrown from the previous\n operation. See `faiss_get_last_error` to retrieve the error message."] -pub type FaissErrorCode = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIndexBinary_H { + _unused: [u8; 0], +} +pub type FaissIndexBinary = FaissIndexBinary_H; extern "C" { - #[doc = " Get the error message of the last failed operation performed by Faiss.\n The given pointer is only invalid until another Faiss function is\n called."] - pub fn faiss_get_last_error() -> *const ::std::os::raw::c_char; + pub fn faiss_IndexBinary_free(obj: *mut FaissIndexBinary); } extern "C" { - pub fn faiss_RangeSearchResult_nq(arg1: *const FaissRangeSearchResult) -> usize; + pub fn faiss_IndexBinary_d(arg1: *const FaissIndexBinary) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_RangeSearchResult_new( - p_rsr: *mut *mut FaissRangeSearchResult, - nq: idx_t, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexBinary_is_trained(arg1: *const FaissIndexBinary) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_RangeSearchResult_new_with( - p_rsr: *mut *mut FaissRangeSearchResult, - nq: idx_t, - alloc_lims: ::std::os::raw::c_int, + pub fn faiss_IndexBinary_ntotal(arg1: *const FaissIndexBinary) -> idx_t; +} +extern "C" { + pub fn faiss_IndexBinary_metric_type(arg1: *const FaissIndexBinary) -> FaissMetricType; +} +extern "C" { + pub fn faiss_IndexBinary_verbose(arg1: *const FaissIndexBinary) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn faiss_IndexBinary_set_verbose(arg1: *mut FaissIndexBinary, arg2: ::std::os::raw::c_int); +} +extern "C" { + #[doc = " Perform training on a representative set of vectors\n\n @param index opaque pointer to index object\n @param n nb of training vectors\n @param x training vectors, size n * d"] + pub fn faiss_IndexBinary_train( + index: *mut FaissIndexBinary, + n: idx_t, + x: *const u8, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " called when lims contains the nb of elements result entries\n for each query"] - pub fn faiss_RangeSearchResult_do_allocation( - rsr: *mut FaissRangeSearchResult, + #[doc = " Add n vectors of dimension d to the index.\n\n Vectors are implicitly assigned labels ntotal .. ntotal + n - 1\n This function slices the input vectors in chunks smaller than\n blocksize_add and calls add_core.\n @param index opaque pointer to index object\n @param x input matrix, size n * d"] + pub fn faiss_IndexBinary_add( + index: *mut FaissIndexBinary, + n: idx_t, + x: *const u8, ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_RangeSearchResult_free(obj: *mut FaissRangeSearchResult); + #[doc = " Same as add, but stores xids instead of sequential ids.\n\n The default implementation fails with an assertion, as it is\n not supported by all indexes.\n\n @param index opaque pointer to index object\n @param xids if non-null, ids to store for the vectors (size n)"] + pub fn faiss_IndexBinary_add_with_ids( + index: *mut FaissIndexBinary, + n: idx_t, + x: *const u8, + xids: *const idx_t, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_RangeSearchResult_buffer_size(arg1: *const FaissRangeSearchResult) -> usize; + #[doc = " query n vectors of dimension d to the index.\n\n return at most k vectors. If there are not enough results for a\n query, the result array is padded with -1s.\n\n @param index opaque pointer to index object\n @param x input vectors to search, size n * d\n @param labels output labels of the NNs, size n*k\n @param distances output pairwise distances, size n*k"] + pub fn faiss_IndexBinary_search( + index: *const FaissIndexBinary, + n: idx_t, + x: *const u8, + k: idx_t, + distances: *mut i32, + labels: *mut idx_t, + ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " getter for lims: size (nq + 1)"] - pub fn faiss_RangeSearchResult_lims(rsr: *mut FaissRangeSearchResult, lims: *mut *mut usize); + #[doc = " query n vectors of dimension d to the index.\n\n return all vectors with distance < radius. Note that many\n indexes do not implement the range_search (only the k-NN search\n is mandatory).\n\n @param index opaque pointer to index object\n @param x input vectors to search, size n * d\n @param radius search radius\n @param result result table"] + pub fn faiss_IndexBinary_range_search( + index: *const FaissIndexBinary, + n: idx_t, + x: *const u8, + radius: ::std::os::raw::c_int, + result: *mut FaissRangeSearchResult, + ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " getter for labels and respective distances (not sorted):\n result for query i is labels[lims[i]:lims[i+1]]"] - pub fn faiss_RangeSearchResult_labels( - rsr: *mut FaissRangeSearchResult, - labels: *mut *mut idx_t, - distances: *mut *mut f32, - ); + #[doc = " return the indexes of the k vectors closest to the query x.\n\n This function is identical as search but only return labels of neighbors.\n @param index opaque pointer to index object\n @param x input vectors to search, size n * d\n @param labels output labels of the NNs, size n*k"] + pub fn faiss_IndexBinary_assign( + index: *mut FaissIndexBinary, + n: idx_t, + x: *const u8, + labels: *mut idx_t, + k: idx_t, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IDSelector_free(obj: *mut FaissIDSelector); + #[doc = " removes all elements from the database.\n @param index opaque pointer to index object"] + pub fn faiss_IndexBinary_reset(index: *mut FaissIndexBinary) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Encapsulates a set of ids to remove."] - pub fn faiss_IDSelector_is_member( + #[doc = " removes IDs from the index. Not supported by all indexes\n @param index opaque pointer to index object\n @param nremove output for the number of IDs removed"] + pub fn faiss_IndexBinary_remove_ids( + index: *mut FaissIndexBinary, sel: *const FaissIDSelector, - id: idx_t, + n_removed: *mut usize, ) -> ::std::os::raw::c_int; } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIDSelectorRange_H { - _unused: [u8; 0], -} -pub type FaissIDSelectorRange = FaissIDSelectorRange_H; extern "C" { - pub fn faiss_IDSelectorRange_free(obj: *mut FaissIDSelectorRange); + #[doc = " Reconstruct a stored vector (or an approximation if lossy coding)\n\n this function may not be defined for some indexes\n @param index opaque pointer to index object\n @param key id of the vector to reconstruct\n @param recons reconstructed vector (size d)"] + pub fn faiss_IndexBinary_reconstruct( + index: *const FaissIndexBinary, + key: idx_t, + recons: *mut u8, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IDSelectorRange_imin(arg1: *const FaissIDSelectorRange) -> idx_t; + #[doc = " Reconstruct vectors i0 to i0 + ni - 1\n\n this function may not be defined for some indexes\n @param index opaque pointer to index object\n @param recons reconstructed vector (size ni * d)"] + pub fn faiss_IndexBinary_reconstruct_n( + index: *const FaissIndexBinary, + i0: idx_t, + ni: idx_t, + recons: *mut u8, + ) -> ::std::os::raw::c_int; } +pub type FaissIndexFlat = FaissIndex_H; extern "C" { - pub fn faiss_IDSelectorRange_imax(arg1: *const FaissIDSelectorRange) -> idx_t; + #[doc = " Opaque type for IndexFlat"] + pub fn faiss_IndexFlat_new(p_index: *mut *mut FaissIndexFlat) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " remove ids between [imni, imax)"] - pub fn faiss_IDSelectorRange_new( - p_sel: *mut *mut FaissIDSelectorRange, - imin: idx_t, - imax: idx_t, + pub fn faiss_IndexFlat_new_with( + p_index: *mut *mut FaissIndexFlat, + d: idx_t, + metric: FaissMetricType, ) -> ::std::os::raw::c_int; } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIDSelectorBatch_H { - _unused: [u8; 0], +extern "C" { + #[doc = " get a pointer to the index's internal data (the `xb` field). The outputs\n become invalid after any data addition or removal operation.\n\n @param index opaque pointer to index object\n @param p_xb output, the pointer to the beginning of `xb`.\n @param p_size output, the current size of `sb` in number of float values."] + pub fn faiss_IndexFlat_xb(index: *mut FaissIndexFlat, p_xb: *mut *mut f32, p_size: *mut usize); } -pub type FaissIDSelectorBatch = FaissIDSelectorBatch_H; extern "C" { - pub fn faiss_IDSelectorBatch_nbits(arg1: *const FaissIDSelectorBatch) -> ::std::os::raw::c_int; + pub fn faiss_IndexFlat_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlat; } extern "C" { - pub fn faiss_IDSelectorBatch_mask(arg1: *const FaissIDSelectorBatch) -> idx_t; + pub fn faiss_IndexFlat_free(obj: *mut FaissIndexFlat); } extern "C" { - #[doc = " Remove ids from a set. Repetitions of ids in the indices set\n passed to the constructor does not hurt performance. The hash\n function used for the bloom filter and GCC's implementation of\n unordered_set are just the least significant bits of the id. This\n works fine for random ids or ids in sequences but will produce many\n hash collisions if lsb's are always the same"] - pub fn faiss_IDSelectorBatch_new( - p_sel: *mut *mut FaissIDSelectorBatch, - n: usize, - indices: *const idx_t, + #[doc = " compute distance with a subset of vectors\n\n @param index opaque pointer to index object\n @param x query vectors, size n * d\n @param labels indices of the vectors that should be compared\n for each query vector, size n * k\n @param distances\n corresponding output distances, size n * k"] + pub fn faiss_IndexFlat_compute_distance_subset( + index: *mut FaissIndex, + n: idx_t, + x: *const f32, + k: idx_t, + distances: *mut f32, + labels: *const idx_t, ) -> ::std::os::raw::c_int; } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIDSelectorNot_H { - _unused: [u8; 0], +pub type FaissIndexFlatIP = FaissIndex_H; +extern "C" { + pub fn faiss_IndexFlatIP_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlatIP; } -pub type FaissIDSelectorNot = FaissIDSelectorNot_H; extern "C" { - pub fn faiss_IDSelectorNot_new( - p_sel: *mut *mut FaissIDSelectorNot, - sel: *const FaissIDSelector, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexFlatIP_free(obj: *mut FaissIndexFlatIP); } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIDSelectorAnd_H { - _unused: [u8; 0], +extern "C" { + #[doc = " Opaque type for IndexFlatIP"] + pub fn faiss_IndexFlatIP_new(p_index: *mut *mut FaissIndexFlatIP) -> ::std::os::raw::c_int; } -pub type FaissIDSelectorAnd = FaissIDSelectorAnd_H; extern "C" { - pub fn faiss_IDSelectorAnd_new( - p_sel: *mut *mut FaissIDSelectorAnd, - lhs_sel: *const FaissIDSelector, - rhs_sel: *const FaissIDSelector, + pub fn faiss_IndexFlatIP_new_with( + p_index: *mut *mut FaissIndexFlatIP, + d: idx_t, ) -> ::std::os::raw::c_int; } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIDSelectorOr_H { - _unused: [u8; 0], +pub type FaissIndexFlatL2 = FaissIndex_H; +extern "C" { + pub fn faiss_IndexFlatL2_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlatL2; } -pub type FaissIDSelectorOr = FaissIDSelectorOr_H; extern "C" { - pub fn faiss_IDSelectorOr_new( - p_sel: *mut *mut FaissIDSelectorOr, - lhs_sel: *const FaissIDSelector, - rhs_sel: *const FaissIDSelector, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexFlatL2_free(obj: *mut FaissIndexFlatL2); } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIDSelectorXOr_H { - _unused: [u8; 0], +extern "C" { + #[doc = " Opaque type for IndexFlatL2"] + pub fn faiss_IndexFlatL2_new(p_index: *mut *mut FaissIndexFlatL2) -> ::std::os::raw::c_int; } -pub type FaissIDSelectorXOr = FaissIDSelectorXOr_H; extern "C" { - pub fn faiss_IDSelectorXOr_new( - p_sel: *mut *mut FaissIDSelectorXOr, - lhs_sel: *const FaissIDSelector, - rhs_sel: *const FaissIDSelector, + pub fn faiss_IndexFlatL2_new_with( + p_index: *mut *mut FaissIndexFlatL2, + d: idx_t, ) -> ::std::os::raw::c_int; } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissBufferList_H { - _unused: [u8; 0], +pub type FaissIndexRefineFlat = FaissIndex_H; +extern "C" { + #[doc = " Opaque type for IndexRefineFlat\n\n Index that queries in a base_index (a fast one) and refines the\n results with an exact search, hopefully improving the results."] + pub fn faiss_IndexRefineFlat_new( + p_index: *mut *mut FaissIndexRefineFlat, + base_index: *mut FaissIndex, + ) -> ::std::os::raw::c_int; } -pub type FaissBufferList = FaissBufferList_H; extern "C" { - pub fn faiss_BufferList_free(obj: *mut FaissBufferList); + pub fn faiss_IndexRefineFlat_free(obj: *mut FaissIndexRefineFlat); } extern "C" { - pub fn faiss_BufferList_buffer_size(arg1: *const FaissBufferList) -> usize; + pub fn faiss_IndexRefineFlat_cast(arg1: *mut FaissIndex) -> *mut FaissIndexRefineFlat; } extern "C" { - pub fn faiss_BufferList_wp(arg1: *const FaissBufferList) -> usize; -} -#[doc = " List of temporary buffers used to store results before they are\n copied to the RangeSearchResult object."] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissBuffer { - pub ids: *mut idx_t, - pub dis: *mut f32, -} -#[test] -fn bindgen_test_layout_FaissBuffer() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(FaissBuffer)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(FaissBuffer)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ids) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(FaissBuffer), - "::", - stringify!(ids) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dis) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(FaissBuffer), - "::", - stringify!(dis) - ) - ); + pub fn faiss_IndexRefineFlat_own_fields( + arg1: *const FaissIndexRefineFlat, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_BufferList_append_buffer(bl: *mut FaissBufferList) -> ::std::os::raw::c_int; + pub fn faiss_IndexRefineFlat_set_own_fields( + arg1: *mut FaissIndexRefineFlat, + arg2: ::std::os::raw::c_int, + ); } extern "C" { - pub fn faiss_BufferList_new( - p_bl: *mut *mut FaissBufferList, - buffer_size: usize, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexRefineFlat_k_factor(arg1: *const FaissIndexRefineFlat) -> f32; } extern "C" { - pub fn faiss_BufferList_add( - bl: *mut FaissBufferList, - id: idx_t, - dis: f32, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexRefineFlat_set_k_factor(arg1: *mut FaissIndexRefineFlat, arg2: f32); } +pub type FaissIndexFlat1D = FaissIndex_H; extern "C" { - #[doc = " copy elemnts ofs:ofs+n-1 seen as linear data in the buffers to\n tables dest_ids, dest_dis"] - pub fn faiss_BufferList_copy_range( - bl: *mut FaissBufferList, - ofs: usize, - n: usize, - dest_ids: *mut idx_t, - dest_dis: *mut f32, - ) -> ::std::os::raw::c_int; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissRangeSearchPartialResult_H { - _unused: [u8; 0], -} -pub type FaissRangeSearchPartialResult = FaissRangeSearchPartialResult_H; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissRangeQueryResult_H { - _unused: [u8; 0], + pub fn faiss_IndexFlat1D_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlat1D; } -pub type FaissRangeQueryResult = FaissRangeQueryResult_H; extern "C" { - pub fn faiss_RangeQueryResult_qno(arg1: *const FaissRangeQueryResult) -> idx_t; + pub fn faiss_IndexFlat1D_free(obj: *mut FaissIndexFlat1D); } extern "C" { - pub fn faiss_RangeQueryResult_nres(arg1: *const FaissRangeQueryResult) -> usize; + #[doc = " Opaque type for IndexFlat1D\n\n optimized version for 1D \"vectors\""] + pub fn faiss_IndexFlat1D_new(p_index: *mut *mut FaissIndexFlat1D) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_RangeQueryResult_pres( - arg1: *const FaissRangeQueryResult, - ) -> *mut FaissRangeSearchPartialResult; + pub fn faiss_IndexFlat1D_new_with( + p_index: *mut *mut FaissIndexFlat1D, + continuous_update: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " result structure for a single query"] - pub fn faiss_RangeQueryResult_add( - qr: *mut FaissRangeQueryResult, - dis: f32, - id: idx_t, + pub fn faiss_IndexFlat1D_update_permutation( + index: *mut FaissIndexFlat1D, ) -> ::std::os::raw::c_int; } +pub type FaissIndexIVFFlat = FaissIndex_H; extern "C" { - pub fn faiss_RangeSearchPartialResult_res( - arg1: *const FaissRangeSearchPartialResult, - ) -> *mut FaissRangeSearchResult; + pub fn faiss_IndexIVFFlat_free(obj: *mut FaissIndexIVFFlat); } extern "C" { - pub fn faiss_RangeSearchPartialResult_new( - p_res: *mut *mut FaissRangeSearchPartialResult, - res_in: *mut FaissRangeSearchResult, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_cast(arg1: *mut FaissIndex) -> *mut FaissIndexIVFFlat; } extern "C" { - pub fn faiss_RangeSearchPartialResult_finalize( - res: *mut FaissRangeSearchPartialResult, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_nlist(arg1: *const FaissIndexIVFFlat) -> usize; } extern "C" { - #[doc = " called by range_search before do_allocation"] - pub fn faiss_RangeSearchPartialResult_set_lims( - res: *mut FaissRangeSearchPartialResult, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_nprobe(arg1: *const FaissIndexIVFFlat) -> usize; } extern "C" { - pub fn faiss_RangeSearchPartialResult_new_result( - res: *mut FaissRangeSearchPartialResult, - qno: idx_t, - qr: *mut *mut FaissRangeQueryResult, - ) -> ::std::os::raw::c_int; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissDistanceComputer_H { - _unused: [u8; 0], + pub fn faiss_IndexIVFFlat_set_nprobe(arg1: *mut FaissIndexIVFFlat, arg2: usize); } -pub type FaissDistanceComputer = FaissDistanceComputer_H; extern "C" { - #[doc = " called before computing distances"] - pub fn faiss_DistanceComputer_set_query( - dc: *mut FaissDistanceComputer, - x: *const f32, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_quantizer(arg1: *const FaissIndexIVFFlat) -> *mut FaissIndex; } extern "C" { - #[doc = " Compute distance of vector i to current query.\n This function corresponds to the function call operator:\n DistanceComputer::operator()"] - pub fn faiss_DistanceComputer_vector_to_query_dis( - dc: *mut FaissDistanceComputer, - i: idx_t, - qd: *mut f32, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_quantizer_trains_alone( + arg1: *const FaissIndexIVFFlat, + ) -> ::std::os::raw::c_char; } extern "C" { - #[doc = " compute distance between two stored vectors"] - pub fn faiss_DistanceComputer_symmetric_dis( - dc: *mut FaissDistanceComputer, - i: idx_t, - j: idx_t, - vd: *mut f32, - ) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_own_fields(arg1: *const FaissIndexIVFFlat) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_DistanceComputer_free(obj: *mut FaissDistanceComputer); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct FaissIndexBinary_H { - _unused: [u8; 0], + pub fn faiss_IndexIVFFlat_set_own_fields( + arg1: *mut FaissIndexIVFFlat, + arg2: ::std::os::raw::c_int, + ); } -pub type FaissIndexBinary = FaissIndexBinary_H; extern "C" { - pub fn faiss_IndexBinary_free(obj: *mut FaissIndexBinary); + #[doc = " whether object owns the quantizer"] + pub fn faiss_IndexIVFFlat_new(p_index: *mut *mut FaissIndexIVFFlat) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexBinary_d(arg1: *const FaissIndexBinary) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_new_with( + p_index: *mut *mut FaissIndexIVFFlat, + quantizer: *mut FaissIndex, + d: usize, + nlist: usize, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexBinary_is_trained(arg1: *const FaissIndexBinary) -> ::std::os::raw::c_int; + pub fn faiss_IndexIVFFlat_new_with_metric( + p_index: *mut *mut FaissIndexIVFFlat, + quantizer: *mut FaissIndex, + d: usize, + nlist: usize, + metric: FaissMetricType, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexBinary_ntotal(arg1: *const FaissIndexBinary) -> idx_t; + pub fn faiss_IndexIVFFlat_add_core( + index: *mut FaissIndexIVFFlat, + n: idx_t, + x: *const f32, + xids: *const idx_t, + precomputed_idx: *const i64, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexBinary_metric_type(arg1: *const FaissIndexBinary) -> FaissMetricType; + #[doc = " Update a subset of vectors.\n\n The index must have a direct_map\n\n @param nv nb of vectors to update\n @param idx vector indices to update, size nv\n @param v vectors of new values, size nv*d"] + pub fn faiss_IndexIVFFlat_update_vectors( + index: *mut FaissIndexIVFFlat, + nv: ::std::os::raw::c_int, + idx: *mut idx_t, + v: *const f32, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexBinary_verbose(arg1: *const FaissIndexBinary) -> ::std::os::raw::c_int; + pub fn faiss_RangeSearchResult_nq(arg1: *const FaissRangeSearchResult) -> usize; } extern "C" { - pub fn faiss_IndexBinary_set_verbose(arg1: *mut FaissIndexBinary, arg2: ::std::os::raw::c_int); + pub fn faiss_RangeSearchResult_new( + p_rsr: *mut *mut FaissRangeSearchResult, + nq: idx_t, + ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Perform training on a representative set of vectors\n\n @param index opaque pointer to index object\n @param n nb of training vectors\n @param x training vectors, size n * d"] - pub fn faiss_IndexBinary_train( - index: *mut FaissIndexBinary, - n: idx_t, - x: *const u8, + pub fn faiss_RangeSearchResult_new_with( + p_rsr: *mut *mut FaissRangeSearchResult, + nq: idx_t, + alloc_lims: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Add n vectors of dimension d to the index.\n\n Vectors are implicitly assigned labels ntotal .. ntotal + n - 1\n This function slices the input vectors in chunks smaller than\n blocksize_add and calls add_core.\n @param index opaque pointer to index object\n @param x input matrix, size n * d"] - pub fn faiss_IndexBinary_add( - index: *mut FaissIndexBinary, - n: idx_t, - x: *const u8, + #[doc = " called when lims contains the nb of elements result entries\n for each query"] + pub fn faiss_RangeSearchResult_do_allocation( + rsr: *mut FaissRangeSearchResult, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Same as add, but stores xids instead of sequential ids.\n\n The default implementation fails with an assertion, as it is\n not supported by all indexes.\n\n @param index opaque pointer to index object\n @param xids if non-null, ids to store for the vectors (size n)"] - pub fn faiss_IndexBinary_add_with_ids( - index: *mut FaissIndexBinary, - n: idx_t, - x: *const u8, - xids: *const idx_t, - ) -> ::std::os::raw::c_int; + pub fn faiss_RangeSearchResult_free(obj: *mut FaissRangeSearchResult); } extern "C" { - #[doc = " query n vectors of dimension d to the index.\n\n return at most k vectors. If there are not enough results for a\n query, the result array is padded with -1s.\n\n @param index opaque pointer to index object\n @param x input vectors to search, size n * d\n @param labels output labels of the NNs, size n*k\n @param distances output pairwise distances, size n*k"] - pub fn faiss_IndexBinary_search( - index: *const FaissIndexBinary, - n: idx_t, - x: *const u8, - k: idx_t, - distances: *mut i32, - labels: *mut idx_t, - ) -> ::std::os::raw::c_int; + pub fn faiss_RangeSearchResult_buffer_size(arg1: *const FaissRangeSearchResult) -> usize; } extern "C" { - #[doc = " query n vectors of dimension d to the index.\n\n return all vectors with distance < radius. Note that many\n indexes do not implement the range_search (only the k-NN search\n is mandatory).\n\n @param index opaque pointer to index object\n @param x input vectors to search, size n * d\n @param radius search radius\n @param result result table"] - pub fn faiss_IndexBinary_range_search( - index: *const FaissIndexBinary, - n: idx_t, - x: *const u8, - radius: ::std::os::raw::c_int, - result: *mut FaissRangeSearchResult, - ) -> ::std::os::raw::c_int; + #[doc = " getter for lims: size (nq + 1)"] + pub fn faiss_RangeSearchResult_lims(rsr: *mut FaissRangeSearchResult, lims: *mut *mut usize); } extern "C" { - #[doc = " return the indexes of the k vectors closest to the query x.\n\n This function is identical as search but only return labels of neighbors.\n @param index opaque pointer to index object\n @param x input vectors to search, size n * d\n @param labels output labels of the NNs, size n*k"] - pub fn faiss_IndexBinary_assign( - index: *mut FaissIndexBinary, - n: idx_t, - x: *const u8, - labels: *mut idx_t, - k: idx_t, - ) -> ::std::os::raw::c_int; + #[doc = " getter for labels and respective distances (not sorted):\n result for query i is labels[lims[i]:lims[i+1]]"] + pub fn faiss_RangeSearchResult_labels( + rsr: *mut FaissRangeSearchResult, + labels: *mut *mut idx_t, + distances: *mut *mut f32, + ); } extern "C" { - #[doc = " removes all elements from the database.\n @param index opaque pointer to index object"] - pub fn faiss_IndexBinary_reset(index: *mut FaissIndexBinary) -> ::std::os::raw::c_int; + pub fn faiss_IDSelector_free(obj: *mut FaissIDSelector); } extern "C" { - #[doc = " removes IDs from the index. Not supported by all indexes\n @param index opaque pointer to index object\n @param nremove output for the number of IDs removed"] - pub fn faiss_IndexBinary_remove_ids( - index: *mut FaissIndexBinary, + #[doc = " Encapsulates a set of ids to remove."] + pub fn faiss_IDSelector_is_member( sel: *const FaissIDSelector, - n_removed: *mut usize, + id: idx_t, ) -> ::std::os::raw::c_int; } -extern "C" { - #[doc = " Reconstruct a stored vector (or an approximation if lossy coding)\n\n this function may not be defined for some indexes\n @param index opaque pointer to index object\n @param key id of the vector to reconstruct\n @param recons reconstructed vector (size d)"] - pub fn faiss_IndexBinary_reconstruct( - index: *const FaissIndexBinary, - key: idx_t, - recons: *mut u8, - ) -> ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIDSelectorRange_H { + _unused: [u8; 0], } +pub type FaissIDSelectorRange = FaissIDSelectorRange_H; extern "C" { - #[doc = " Reconstruct vectors i0 to i0 + ni - 1\n\n this function may not be defined for some indexes\n @param index opaque pointer to index object\n @param recons reconstructed vector (size ni * d)"] - pub fn faiss_IndexBinary_reconstruct_n( - index: *const FaissIndexBinary, - i0: idx_t, - ni: idx_t, - recons: *mut u8, - ) -> ::std::os::raw::c_int; + pub fn faiss_IDSelectorRange_free(obj: *mut FaissIDSelectorRange); } extern "C" { - #[doc = " Build and index with the sequence of processing steps described in\n the string."] - pub fn faiss_index_factory( - p_index: *mut *mut FaissIndex, - d: ::std::os::raw::c_int, - description: *const ::std::os::raw::c_char, - metric: FaissMetricType, - ) -> ::std::os::raw::c_int; + pub fn faiss_IDSelectorRange_imin(arg1: *const FaissIDSelectorRange) -> idx_t; } -pub type FaissIndexFlat = FaissIndex_H; extern "C" { - #[doc = " Opaque type for IndexFlat"] - pub fn faiss_IndexFlat_new(p_index: *mut *mut FaissIndexFlat) -> ::std::os::raw::c_int; + pub fn faiss_IDSelectorRange_imax(arg1: *const FaissIDSelectorRange) -> idx_t; } extern "C" { - pub fn faiss_IndexFlat_new_with( - p_index: *mut *mut FaissIndexFlat, - d: idx_t, - metric: FaissMetricType, + #[doc = " remove ids between [imni, imax)"] + pub fn faiss_IDSelectorRange_new( + p_sel: *mut *mut FaissIDSelectorRange, + imin: idx_t, + imax: idx_t, ) -> ::std::os::raw::c_int; } -extern "C" { - #[doc = " get a pointer to the index's internal data (the `xb` field). The outputs\n become invalid after any data addition or removal operation.\n\n @param index opaque pointer to index object\n @param p_xb output, the pointer to the beginning of `xb`.\n @param p_size output, the current size of `sb` in number of float values."] - pub fn faiss_IndexFlat_xb(index: *mut FaissIndexFlat, p_xb: *mut *mut f32, p_size: *mut usize); +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIDSelectorBatch_H { + _unused: [u8; 0], } +pub type FaissIDSelectorBatch = FaissIDSelectorBatch_H; extern "C" { - pub fn faiss_IndexFlat_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlat; + pub fn faiss_IDSelectorBatch_nbits(arg1: *const FaissIDSelectorBatch) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexFlat_free(obj: *mut FaissIndexFlat); + pub fn faiss_IDSelectorBatch_mask(arg1: *const FaissIDSelectorBatch) -> idx_t; } extern "C" { - #[doc = " compute distance with a subset of vectors\n\n @param index opaque pointer to index object\n @param x query vectors, size n * d\n @param labels indices of the vectors that should be compared\n for each query vector, size n * k\n @param distances\n corresponding output distances, size n * k"] - pub fn faiss_IndexFlat_compute_distance_subset( - index: *mut FaissIndex, - n: idx_t, - x: *const f32, - k: idx_t, - distances: *mut f32, - labels: *const idx_t, + #[doc = " Remove ids from a set. Repetitions of ids in the indices set\n passed to the constructor does not hurt performance. The hash\n function used for the bloom filter and GCC's implementation of\n unordered_set are just the least significant bits of the id. This\n works fine for random ids or ids in sequences but will produce many\n hash collisions if lsb's are always the same"] + pub fn faiss_IDSelectorBatch_new( + p_sel: *mut *mut FaissIDSelectorBatch, + n: usize, + indices: *const idx_t, ) -> ::std::os::raw::c_int; } -pub type FaissIndexFlatIP = FaissIndex_H; -extern "C" { - pub fn faiss_IndexFlatIP_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlatIP; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIDSelectorNot_H { + _unused: [u8; 0], } +pub type FaissIDSelectorNot = FaissIDSelectorNot_H; extern "C" { - pub fn faiss_IndexFlatIP_free(obj: *mut FaissIndexFlatIP); + pub fn faiss_IDSelectorNot_new( + p_sel: *mut *mut FaissIDSelectorNot, + sel: *const FaissIDSelector, + ) -> ::std::os::raw::c_int; } -extern "C" { - #[doc = " Opaque type for IndexFlatIP"] - pub fn faiss_IndexFlatIP_new(p_index: *mut *mut FaissIndexFlatIP) -> ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIDSelectorAnd_H { + _unused: [u8; 0], } +pub type FaissIDSelectorAnd = FaissIDSelectorAnd_H; extern "C" { - pub fn faiss_IndexFlatIP_new_with( - p_index: *mut *mut FaissIndexFlatIP, - d: idx_t, + pub fn faiss_IDSelectorAnd_new( + p_sel: *mut *mut FaissIDSelectorAnd, + lhs_sel: *const FaissIDSelector, + rhs_sel: *const FaissIDSelector, ) -> ::std::os::raw::c_int; } -pub type FaissIndexFlatL2 = FaissIndex_H; -extern "C" { - pub fn faiss_IndexFlatL2_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlatL2; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIDSelectorOr_H { + _unused: [u8; 0], } +pub type FaissIDSelectorOr = FaissIDSelectorOr_H; extern "C" { - pub fn faiss_IndexFlatL2_free(obj: *mut FaissIndexFlatL2); + pub fn faiss_IDSelectorOr_new( + p_sel: *mut *mut FaissIDSelectorOr, + lhs_sel: *const FaissIDSelector, + rhs_sel: *const FaissIDSelector, + ) -> ::std::os::raw::c_int; } -extern "C" { - #[doc = " Opaque type for IndexFlatL2"] - pub fn faiss_IndexFlatL2_new(p_index: *mut *mut FaissIndexFlatL2) -> ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissIDSelectorXOr_H { + _unused: [u8; 0], } +pub type FaissIDSelectorXOr = FaissIDSelectorXOr_H; extern "C" { - pub fn faiss_IndexFlatL2_new_with( - p_index: *mut *mut FaissIndexFlatL2, - d: idx_t, + pub fn faiss_IDSelectorXOr_new( + p_sel: *mut *mut FaissIDSelectorXOr, + lhs_sel: *const FaissIDSelector, + rhs_sel: *const FaissIDSelector, ) -> ::std::os::raw::c_int; } -pub type FaissIndexRefineFlat = FaissIndex_H; -extern "C" { - #[doc = " Opaque type for IndexRefineFlat\n\n Index that queries in a base_index (a fast one) and refines the\n results with an exact search, hopefully improving the results."] - pub fn faiss_IndexRefineFlat_new( - p_index: *mut *mut FaissIndexRefineFlat, - base_index: *mut FaissIndex, - ) -> ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissBufferList_H { + _unused: [u8; 0], } +pub type FaissBufferList = FaissBufferList_H; extern "C" { - pub fn faiss_IndexRefineFlat_free(obj: *mut FaissIndexRefineFlat); + pub fn faiss_BufferList_free(obj: *mut FaissBufferList); } extern "C" { - pub fn faiss_IndexRefineFlat_cast(arg1: *mut FaissIndex) -> *mut FaissIndexRefineFlat; + pub fn faiss_BufferList_buffer_size(arg1: *const FaissBufferList) -> usize; } extern "C" { - pub fn faiss_IndexRefineFlat_own_fields( - arg1: *const FaissIndexRefineFlat, - ) -> ::std::os::raw::c_int; + pub fn faiss_BufferList_wp(arg1: *const FaissBufferList) -> usize; } -extern "C" { - pub fn faiss_IndexRefineFlat_set_own_fields( - arg1: *mut FaissIndexRefineFlat, - arg2: ::std::os::raw::c_int, +#[doc = " List of temporary buffers used to store results before they are\n copied to the RangeSearchResult object."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissBuffer { + pub ids: *mut idx_t, + pub dis: *mut f32, +} +#[test] +fn bindgen_test_layout_FaissBuffer() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(FaissBuffer)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(FaissBuffer)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).ids) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(FaissBuffer), + "::", + stringify!(ids) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).dis) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(FaissBuffer), + "::", + stringify!(dis) + ) ); } extern "C" { - pub fn faiss_IndexRefineFlat_k_factor(arg1: *const FaissIndexRefineFlat) -> f32; + pub fn faiss_BufferList_append_buffer(bl: *mut FaissBufferList) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexRefineFlat_set_k_factor(arg1: *mut FaissIndexRefineFlat, arg2: f32); + pub fn faiss_BufferList_new( + p_bl: *mut *mut FaissBufferList, + buffer_size: usize, + ) -> ::std::os::raw::c_int; } -pub type FaissIndexFlat1D = FaissIndex_H; extern "C" { - pub fn faiss_IndexFlat1D_cast(arg1: *mut FaissIndex) -> *mut FaissIndexFlat1D; + pub fn faiss_BufferList_add( + bl: *mut FaissBufferList, + id: idx_t, + dis: f32, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn faiss_IndexFlat1D_free(obj: *mut FaissIndexFlat1D); + #[doc = " copy elemnts ofs:ofs+n-1 seen as linear data in the buffers to\n tables dest_ids, dest_dis"] + pub fn faiss_BufferList_copy_range( + bl: *mut FaissBufferList, + ofs: usize, + n: usize, + dest_ids: *mut idx_t, + dest_dis: *mut f32, + ) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissRangeSearchPartialResult_H { + _unused: [u8; 0], } +pub type FaissRangeSearchPartialResult = FaissRangeSearchPartialResult_H; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissRangeQueryResult_H { + _unused: [u8; 0], +} +pub type FaissRangeQueryResult = FaissRangeQueryResult_H; extern "C" { - #[doc = " Opaque type for IndexFlat1D\n\n optimized version for 1D \"vectors\""] - pub fn faiss_IndexFlat1D_new(p_index: *mut *mut FaissIndexFlat1D) -> ::std::os::raw::c_int; + pub fn faiss_RangeQueryResult_qno(arg1: *const FaissRangeQueryResult) -> idx_t; +} +extern "C" { + pub fn faiss_RangeQueryResult_nres(arg1: *const FaissRangeQueryResult) -> usize; } extern "C" { - pub fn faiss_IndexFlat1D_new_with( - p_index: *mut *mut FaissIndexFlat1D, - continuous_update: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; + pub fn faiss_RangeQueryResult_pres( + arg1: *const FaissRangeQueryResult, + ) -> *mut FaissRangeSearchPartialResult; } extern "C" { - pub fn faiss_IndexFlat1D_update_permutation( - index: *mut FaissIndexFlat1D, + #[doc = " result structure for a single query"] + pub fn faiss_RangeQueryResult_add( + qr: *mut FaissRangeQueryResult, + dis: f32, + id: idx_t, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index` when a file descriptor is\n provided."] - pub fn faiss_write_index(idx: *const FaissIndex, f: *mut FILE) -> ::std::os::raw::c_int; + pub fn faiss_RangeSearchPartialResult_res( + arg1: *const FaissRangeSearchPartialResult, + ) -> *mut FaissRangeSearchResult; } extern "C" { - #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index` when a file path is provided."] - pub fn faiss_write_index_fname( - idx: *const FaissIndex, - fname: *const ::std::os::raw::c_char, + pub fn faiss_RangeSearchPartialResult_new( + p_res: *mut *mut FaissRangeSearchPartialResult, + res_in: *mut FaissRangeSearchResult, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index` when a file descriptor is given."] - pub fn faiss_read_index( - f: *mut FILE, - io_flags: ::std::os::raw::c_int, - p_out: *mut *mut FaissIndex, + pub fn faiss_RangeSearchPartialResult_finalize( + res: *mut FaissRangeSearchPartialResult, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index` when a file path is given."] - pub fn faiss_read_index_fname( - fname: *const ::std::os::raw::c_char, - io_flags: ::std::os::raw::c_int, - p_out: *mut *mut FaissIndex, + #[doc = " called by range_search before do_allocation"] + pub fn faiss_RangeSearchPartialResult_set_lims( + res: *mut FaissRangeSearchPartialResult, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index_binary` when a file descriptor is\n provided."] - pub fn faiss_write_index_binary( - idx: *const FaissIndexBinary, - f: *mut FILE, + pub fn faiss_RangeSearchPartialResult_new_result( + res: *mut FaissRangeSearchPartialResult, + qno: idx_t, + qr: *mut *mut FaissRangeQueryResult, ) -> ::std::os::raw::c_int; } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FaissDistanceComputer_H { + _unused: [u8; 0], +} +pub type FaissDistanceComputer = FaissDistanceComputer_H; extern "C" { - #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index_binary` when a file path is\n provided."] - pub fn faiss_write_index_binary_fname( - idx: *const FaissIndexBinary, - fname: *const ::std::os::raw::c_char, + #[doc = " called before computing distances"] + pub fn faiss_DistanceComputer_set_query( + dc: *mut FaissDistanceComputer, + x: *const f32, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index_binary` when a file descriptor is\n given."] - pub fn faiss_read_index_binary( - f: *mut FILE, - io_flags: ::std::os::raw::c_int, - p_out: *mut *mut FaissIndexBinary, + #[doc = " Compute distance of vector i to current query.\n This function corresponds to the function call operator:\n DistanceComputer::operator()"] + pub fn faiss_DistanceComputer_vector_to_query_dis( + dc: *mut FaissDistanceComputer, + i: idx_t, + qd: *mut f32, ) -> ::std::os::raw::c_int; } extern "C" { - #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index_binary` when a file path is given."] - pub fn faiss_read_index_binary_fname( - fname: *const ::std::os::raw::c_char, - io_flags: ::std::os::raw::c_int, - p_out: *mut *mut FaissIndexBinary, + #[doc = " compute distance between two stored vectors"] + pub fn faiss_DistanceComputer_symmetric_dis( + dc: *mut FaissDistanceComputer, + i: idx_t, + j: idx_t, + vd: *mut f32, ) -> ::std::os::raw::c_int; } +extern "C" { + pub fn faiss_DistanceComputer_free(obj: *mut FaissDistanceComputer); +} pub type FaissSearchParametersIVF = FaissSearchParameters_H; extern "C" { pub fn faiss_SearchParametersIVF_free(obj: *mut FaissSearchParametersIVF); @@ -1455,78 +1439,6 @@ extern "C" { #[doc = " global var that collects all statists"] pub fn faiss_get_indexIVF_stats() -> *mut FaissIndexIVFStats; } -pub type FaissIndexIVFFlat = FaissIndex_H; -extern "C" { - pub fn faiss_IndexIVFFlat_free(obj: *mut FaissIndexIVFFlat); -} -extern "C" { - pub fn faiss_IndexIVFFlat_cast(arg1: *mut FaissIndex) -> *mut FaissIndexIVFFlat; -} -extern "C" { - pub fn faiss_IndexIVFFlat_nlist(arg1: *const FaissIndexIVFFlat) -> usize; -} -extern "C" { - pub fn faiss_IndexIVFFlat_nprobe(arg1: *const FaissIndexIVFFlat) -> usize; -} -extern "C" { - pub fn faiss_IndexIVFFlat_set_nprobe(arg1: *mut FaissIndexIVFFlat, arg2: usize); -} -extern "C" { - pub fn faiss_IndexIVFFlat_quantizer(arg1: *const FaissIndexIVFFlat) -> *mut FaissIndex; -} -extern "C" { - pub fn faiss_IndexIVFFlat_quantizer_trains_alone( - arg1: *const FaissIndexIVFFlat, - ) -> ::std::os::raw::c_char; -} -extern "C" { - pub fn faiss_IndexIVFFlat_own_fields(arg1: *const FaissIndexIVFFlat) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn faiss_IndexIVFFlat_set_own_fields( - arg1: *mut FaissIndexIVFFlat, - arg2: ::std::os::raw::c_int, - ); -} -extern "C" { - #[doc = " whether object owns the quantizer"] - pub fn faiss_IndexIVFFlat_new(p_index: *mut *mut FaissIndexIVFFlat) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn faiss_IndexIVFFlat_new_with( - p_index: *mut *mut FaissIndexIVFFlat, - quantizer: *mut FaissIndex, - d: usize, - nlist: usize, - ) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn faiss_IndexIVFFlat_new_with_metric( - p_index: *mut *mut FaissIndexIVFFlat, - quantizer: *mut FaissIndex, - d: usize, - nlist: usize, - metric: FaissMetricType, - ) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn faiss_IndexIVFFlat_add_core( - index: *mut FaissIndexIVFFlat, - n: idx_t, - x: *const f32, - xids: *const idx_t, - precomputed_idx: *const i64, - ) -> ::std::os::raw::c_int; -} -extern "C" { - #[doc = " Update a subset of vectors.\n\n The index must have a direct_map\n\n @param nv nb of vectors to update\n @param idx vector indices to update, size nv\n @param v vectors of new values, size nv*d"] - pub fn faiss_IndexIVFFlat_update_vectors( - index: *mut FaissIndexIVFFlat, - nv: ::std::os::raw::c_int, - idx: *mut idx_t, - v: *const f32, - ) -> ::std::os::raw::c_int; -} pub type FaissIndexLSH = FaissIndex_H; extern "C" { pub fn faiss_IndexLSH_free(obj: *mut FaissIndexLSH); @@ -2092,6 +2004,109 @@ extern "C" { #[doc = " get a pointer to the sub-index (the `index` field).\n The outputs of this function become invalid after any operation that can\n modify the index.\n\n @param index opaque pointer to index object"] pub fn faiss_IndexIDMap2_sub_index(index: *mut FaissIndexIDMap2) -> *mut FaissIndex; } +pub type FILE = [u64; 27usize]; +extern "C" { + #[doc = " Clone an index. This is equivalent to `faiss::clone_index`"] + pub fn faiss_clone_index( + arg1: *const FaissIndex, + p_out: *mut *mut FaissIndex, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Clone a binary index. This is equivalent to `faiss::clone_index_binary`"] + pub fn faiss_clone_index_binary( + arg1: *const FaissIndexBinary, + p_out: *mut *mut FaissIndexBinary, + ) -> ::std::os::raw::c_int; +} +#[doc = " No error"] +pub const FaissErrorCode_OK: FaissErrorCode = 0; +#[doc = " Any exception other than Faiss or standard C++ library exceptions"] +pub const FaissErrorCode_UNKNOWN_EXCEPT: FaissErrorCode = -1; +#[doc = " Faiss library exception"] +pub const FaissErrorCode_FAISS_EXCEPT: FaissErrorCode = -2; +#[doc = " Standard C++ library exception"] +pub const FaissErrorCode_STD_EXCEPT: FaissErrorCode = -4; +#[doc = " An error code which depends on the exception thrown from the previous\n operation. See `faiss_get_last_error` to retrieve the error message."] +pub type FaissErrorCode = ::std::os::raw::c_int; +extern "C" { + #[doc = " Get the error message of the last failed operation performed by Faiss.\n The given pointer is only invalid until another Faiss function is\n called."] + pub fn faiss_get_last_error() -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = " Build an index with the sequence of processing steps described in\n the string."] + pub fn faiss_index_factory( + p_index: *mut *mut FaissIndex, + d: ::std::os::raw::c_int, + description: *const ::std::os::raw::c_char, + metric: FaissMetricType, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Build a binary index with the sequence of processing steps described in\n the string."] + pub fn faiss_index_binary_factory( + p_index: *mut *mut FaissIndexBinary, + d: ::std::os::raw::c_int, + description: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index` when a file descriptor is\n provided."] + pub fn faiss_write_index(idx: *const FaissIndex, f: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index` when a file path is provided."] + pub fn faiss_write_index_fname( + idx: *const FaissIndex, + fname: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index` when a file descriptor is given."] + pub fn faiss_read_index( + f: *mut FILE, + io_flags: ::std::os::raw::c_int, + p_out: *mut *mut FaissIndex, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index` when a file path is given."] + pub fn faiss_read_index_fname( + fname: *const ::std::os::raw::c_char, + io_flags: ::std::os::raw::c_int, + p_out: *mut *mut FaissIndex, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index_binary` when a file descriptor is\n provided."] + pub fn faiss_write_index_binary( + idx: *const FaissIndexBinary, + f: *mut FILE, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Write index to a file.\n This is equivalent to `faiss::write_index_binary` when a file path is\n provided."] + pub fn faiss_write_index_binary_fname( + idx: *const FaissIndexBinary, + fname: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index_binary` when a file descriptor is\n given."] + pub fn faiss_read_index_binary( + f: *mut FILE, + io_flags: ::std::os::raw::c_int, + p_out: *mut *mut FaissIndexBinary, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " Read index from a file.\n This is equivalent to `faiss:read_index_binary` when a file path is given."] + pub fn faiss_read_index_binary_fname( + fname: *const ::std::os::raw::c_char, + io_flags: ::std::os::raw::c_int, + p_out: *mut *mut FaissIndexBinary, + ) -> ::std::os::raw::c_int; +} extern "C" { #[doc = " Compute pairwise distances between sets of vectors"] pub fn faiss_pairwise_L2sqr( diff --git a/faiss-sys/src/lib.rs b/faiss-sys/src/lib.rs index c0505fd..a5c3e0e 100644 --- a/faiss-sys/src/lib.rs +++ b/faiss-sys/src/lib.rs @@ -31,6 +31,20 @@ mod tests { assert!(!last_error.is_null()); } } + #[test] + fn flat_index_binary() { + const D: usize = 8; + unsafe { + let description = CString::new::<&str>("BFlat".as_ref()).unwrap(); + let mut index_ptr = ::std::ptr::null_mut(); + let code = faiss_index_binary_factory( + &mut index_ptr, + (D & 0x7FFF_FFFF) as i32, + description.as_ptr(), + ); + assert_eq!(code, 0); + } + } #[test] fn flat_index() { diff --git a/src/index/io.rs b/src/index/io.rs index f32ea4c..bf4628a 100644 --- a/src/index/io.rs +++ b/src/index/io.rs @@ -2,7 +2,10 @@ use crate::error::{Error, Result}; use crate::faiss_try; -use crate::index::{CpuIndex, FromInnerPtr, IndexImpl, NativeIndex}; +use crate::index::{ + BinaryIndexImpl, CpuIndex, CpuIndexBinary, FromInnerPtr, FromInnerPtrBinary, IndexImpl, + NativeIndex, NativeIndexBinary, +}; use faiss_sys::*; use std::ffi::CString; use std::os::raw::c_int; @@ -31,6 +34,30 @@ where } } +/// Write a binary index to a file. +/// +/// # Error +/// +/// This function returns an error if the description contains any byte with the value `\0` (since +/// it cannot be converted to a C string), or if the internal index writing operation fails. +pub fn write_index_binary(index: &I, file_name: P) -> Result<()> +where + I: NativeIndexBinary, + I: CpuIndexBinary, + P: AsRef, +{ + unsafe { + let f = file_name.as_ref(); + let f = CString::new(f).map_err(|_| Error::BadFilePath)?; + + faiss_try(faiss_write_index_binary_fname( + index.inner_ptr(), + f.as_ptr(), + ))?; + Ok(()) + } +} + /// Read an index from a file. /// /// # Error @@ -54,6 +81,29 @@ where } } +/// Read a binary index from a file. +/// +/// # Error +/// +/// This function returns an error if the description contains any byte with the value `\0` (since +/// it cannot be converted to a C string), or if the internal index reading operation fails. +pub fn read_index_binary

(file_name: P) -> Result +where + P: AsRef, +{ + unsafe { + let f = file_name.as_ref(); + let f = CString::new(f).map_err(|_| Error::BadFilePath)?; + let mut inner = ptr::null_mut(); + faiss_try(faiss_read_index_binary_fname( + f.as_ptr(), + IoFlags::MEM_RESIDENT.into(), + &mut inner, + ))?; + Ok(BinaryIndexImpl::from_inner_ptr(inner)) + } +} + /// Read an index from a file with I/O flags. /// /// You can memory map some index types with this. @@ -79,6 +129,31 @@ where } } +/// Read a binary index from a file with I/O flags. +/// +/// You can memory map some index types with this. +/// +/// # Error +/// +/// This function returns an error if the description contains any byte with the value `\0` (since +/// it cannot be converted to a C string), or if the internal index reading operation fails. +pub fn read_index_binary_with_flags

(file_name: P, io_flags: IoFlags) -> Result +where + P: AsRef, +{ + unsafe { + let f = file_name.as_ref(); + let f = CString::new(f).map_err(|_| Error::BadFilePath)?; + let mut inner = ptr::null_mut(); + faiss_try(faiss_read_index_binary_fname( + f.as_ptr(), + io_flags.0 as c_int, + &mut inner, + ))?; + Ok(BinaryIndexImpl::from_inner_ptr(inner)) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/index/mod.rs b/src/index/mod.rs index a427d34..0729e5f 100644 --- a/src/index/mod.rs +++ b/src/index/mod.rs @@ -126,6 +126,67 @@ impl PartialOrd for Idx { } } +/// Interface for a Faiss binary index. Most methods in this trait match the ones in +/// the native library, whereas some others serve as getters to the index' +/// parameters. +/// +/// Although all methods appear to be available for all binary index implementations, +/// some methods may not be supported. For instance, a [`BinaryFlatIndex`] stores +/// vectors sequentially, and so does not support `add_with_ids` nor +/// `remove_ids`. Users are advised to read the Faiss wiki pages in order +/// to understand which index algorithms support which operations. +/// +/// [`BinaryFlatIndex`]: flat/struct.BinaryFlatIndex.html +pub trait IndexBinary { + /// Whether the BinaryIndex does not require training, or if training is done already + fn is_trained(&self) -> bool; + + /// The total number of vectors indexed + fn ntotal(&self) -> u64; + + /// The dimensionality of the indexed vectors + fn d(&self) -> u32; + + /// The metric type assumed by the index + fn metric_type(&self) -> MetricType; + + /// Add new data vectors to the index. + /// This assumes a C-contiguous memory slice of vectors, where the total + /// number of vectors is `x.len() / d`. + fn add(&mut self, x: &[u8]) -> Result<()>; + + /// Add new data vectors to the index with IDs. + /// This assumes a C-contiguous memory slice of vectors, where the total + /// number of vectors is `x.len() / d`. + /// Not all index types may support this operation. + fn add_with_ids(&mut self, x: &[u8], xids: &[Idx]) -> Result<()>; + + /// Train the underlying index with the given data. + fn train(&mut self, x: &[u8]) -> Result<()>; + + /// Similar to `search`, but only provides the labels. + fn assign(&mut self, q: &[u8], k: usize) -> Result; + + /// Perform a search for the `k` closest vectors to the given query vectors. + fn search(&mut self, q: &[u8], k: usize) -> Result; + + /// Perform a ranged search for the vectors closest to the given query vectors + /// by the given radius. + fn range_search(&mut self, q: &[u8], radius: i32) -> Result; + + /// Clear the entire index. + fn reset(&mut self) -> Result<()>; + + /// Remove data vectors represented by IDs. + fn remove_ids(&mut self, sel: &IdSelector) -> Result; + + /// Index verbosity level + fn verbose(&self) -> bool; + + /// Set Index verbosity level + fn set_verbose(&mut self, value: bool); +} + /// Interface for a Faiss index. Most methods in this trait match the ones in /// the native library, whereas some others serve as getters to the index' /// parameters. @@ -187,6 +248,67 @@ pub trait Index { fn set_verbose(&mut self, value: bool); } +impl IndexBinary for Box +where + BI: IndexBinary, +{ + fn is_trained(&self) -> bool { + (**self).is_trained() + } + + fn ntotal(&self) -> u64 { + (**self).ntotal() + } + + fn d(&self) -> u32 { + (**self).d() + } + + fn metric_type(&self) -> MetricType { + (**self).metric_type() + } + + fn add(&mut self, x: &[u8]) -> Result<()> { + (**self).add(x) + } + + fn add_with_ids(&mut self, x: &[u8], xids: &[Idx]) -> Result<()> { + (**self).add_with_ids(x, xids) + } + + fn train(&mut self, x: &[u8]) -> Result<()> { + (**self).train(x) + } + + fn assign(&mut self, q: &[u8], k: usize) -> Result { + (**self).assign(q, k) + } + + fn search(&mut self, q: &[u8], k: usize) -> Result { + (**self).search(q, k) + } + + fn range_search(&mut self, q: &[u8], radius: i32) -> Result { + (**self).range_search(q, radius) + } + + fn reset(&mut self) -> Result<()> { + (**self).reset() + } + + fn remove_ids(&mut self, sel: &IdSelector) -> Result { + (**self).remove_ids(sel) + } + + fn verbose(&self) -> bool { + (**self).verbose() + } + + fn set_verbose(&mut self, value: bool) { + (**self).set_verbose(value) + } +} + impl Index for Box where I: Index, @@ -248,6 +370,93 @@ where } } +/// Sub-trait for native implementations of a Faiss binary index. +pub trait NativeIndexBinary: IndexBinary { + /// Retrieve a pointer to the native index object. + fn inner_ptr(&self) -> *mut FaissIndexBinary; +} + +impl NativeIndexBinary for Box { + fn inner_ptr(&self) -> *mut FaissIndexBinary { + (**self).inner_ptr() + } +} + +/// Trait for a Faiss binary index that can be safely searched over multiple threads. +/// Operations which do not modify the index are given a method taking an +/// immutable reference. This is not the default for every index type because +/// some implementations (such as the ones running on the GPU) do not allow +/// concurrent searches. +/// +/// Users of these methods should still note that batched querying is +/// considerably faster than running queries one by one, even in parallel. +pub trait ConcurrentIndexBinary: IndexBinary { + /// Similar to `search`, but only provides the labels. + fn assign(&self, q: &[u8], k: usize) -> Result; + + /// Perform a search for the `k` closest vectors to the given query vectors. + fn search(&self, q: &[u8], k: usize) -> Result; + + /// Perform a ranged search for the vectors closest to the given query vectors + /// by the given radius. + fn range_search(&self, q: &[u8], radius: i32) -> Result; +} + +impl ConcurrentIndexBinary for Box { + fn assign(&self, q: &[u8], k: usize) -> Result { + (**self).assign(q, k) + } + + fn search(&self, q: &[u8], k: usize) -> Result { + (**self).search(q, k) + } + + fn range_search(&self, q: &[u8], radius: i32) -> Result { + (**self).range_search(q, radius) + } +} + +/// Trait for Faiss index types known to be running on the CPU. +pub trait CpuIndexBinary: IndexBinary {} + +impl CpuIndexBinary for Box {} + +/// Trait for Faiss binary index types which can be built from a pointer +/// to a native implementation. +pub trait FromInnerPtrBinary: NativeIndexBinary { + /// Create a binary index using the given pointer to a native object. + /// + /// # Safety + /// + /// `inner_ptr` must point to a valid, non-freed CPU binary index, and cannot be + /// shared across multiple instances. The inner binary index must also be + /// compatible with the target `NativeIndexBinary` type according to the native + /// class hierarchy. For example, creating an `BinaryIndexImpl` out of a pointer + /// to `FaissIndexBinaryFlat` is valid, but creating a `FlatIndexBinary` out of a + /// plain `FaissIndexBinary` can cause undefined behavior. + unsafe fn from_inner_ptr(inner_ptr: *mut FaissIndexBinary) -> Self; +} + +/// Trait for Faiss binary index types which can be built from a pointer +/// to a native implementation. +pub trait TryFromInnerPtrBinary: NativeIndexBinary { + /// Create a binary index using the given pointer to a native object, + /// checking that the binary index behind the given pointer + /// is compatible with the target index type. + /// If the inner index is not compatible with the intended target type + /// (e.g. creating a `FlatIndexBinary` out of a `FaissIndexBinaryHNSW`), + /// an error is returned. + /// + /// # Safety + /// + /// This function is unable to check that + /// `inner_ptr` points to a valid, non-freed CPU binary index. + /// Moreover, `inner_ptr` must not be shared across multiple instances. + unsafe fn try_from_inner_ptr(inner_ptr: *mut FaissIndexBinary) -> Result + where + Self: Sized; +} + /// Sub-trait for native implementations of a Faiss index. pub trait NativeIndex: Index { /// Retrieve a pointer to the native index object. @@ -359,6 +568,22 @@ where } } +pub fn try_clone_from_inner_ptr_binary(val: &T) -> Result +where + T: FromInnerPtrBinary, +{ + unsafe { + let mut new_index_ptr = ::std::ptr::null_mut(); + faiss_try(faiss_clone_index_binary( + val.inner_ptr(), + &mut new_index_ptr, + ))?; + Ok(crate::index::FromInnerPtrBinary::from_inner_ptr( + new_index_ptr, + )) + } +} + /// The outcome of an index assign operation. #[derive(Debug, Clone, PartialEq)] pub struct AssignSearchResult { @@ -372,6 +597,13 @@ pub struct SearchResult { pub labels: Vec, } +/// The outcome of an index search operation. +#[derive(Debug, Clone, PartialEq)] +pub struct SearchResultBinary { + pub distances: Vec, + pub labels: Vec, +} + /// The outcome of an index range search operation. #[derive(Debug, Clone, PartialEq)] pub struct RangeSearchResult { @@ -460,10 +692,21 @@ pub struct IndexImpl { inner: *mut FaissIndex, } +/// Native implementation of a Faiss binary index +/// running on the CPU. +#[derive(Debug)] +pub struct BinaryIndexImpl { + inner: *mut FaissIndexBinary, +} + unsafe impl Send for IndexImpl {} unsafe impl Sync for IndexImpl {} +unsafe impl Send for BinaryIndexImpl {} +unsafe impl Sync for BinaryIndexImpl {} + impl CpuIndex for IndexImpl {} +impl CpuIndexBinary for BinaryIndexImpl {} impl Drop for IndexImpl { fn drop(&mut self) { @@ -473,18 +716,44 @@ impl Drop for IndexImpl { } } +impl Drop for BinaryIndexImpl { + fn drop(&mut self) { + unsafe { + faiss_IndexBinary_free(self.inner); + } + } +} + +impl BinaryIndexImpl { + pub fn inner_ptr(&self) -> *mut FaissIndexBinary { + self.inner + } +} + impl IndexImpl { pub fn inner_ptr(&self) -> *mut FaissIndex { self.inner } } +impl NativeIndexBinary for BinaryIndexImpl { + fn inner_ptr(&self) -> *mut FaissIndexBinary { + self.inner + } +} + impl NativeIndex for IndexImpl { fn inner_ptr(&self) -> *mut FaissIndex { self.inner } } +impl FromInnerPtrBinary for BinaryIndexImpl { + unsafe fn from_inner_ptr(inner_ptr: *mut FaissIndexBinary) -> Self { + BinaryIndexImpl { inner: inner_ptr } + } +} + impl FromInnerPtr for IndexImpl { unsafe fn from_inner_ptr(inner_ptr: *mut FaissIndex) -> Self { IndexImpl { inner: inner_ptr } @@ -504,6 +773,19 @@ impl TryFromInnerPtr for IndexImpl { } } +impl TryFromInnerPtrBinary for BinaryIndexImpl { + unsafe fn try_from_inner_ptr(inner_ptr: *mut FaissIndexBinary) -> Result + where + Self: Sized, + { + if inner_ptr.is_null() { + Err(Error::BadCast) + } else { + Ok(BinaryIndexImpl { inner: inner_ptr }) + } + } +} + /// Index upcast trait. /// /// If you need to store several different types of indexes in one collection, @@ -525,6 +807,15 @@ pub trait UpcastIndex: NativeIndex { fn upcast(self) -> IndexImpl; } +/// BinaryIndex upcast trait. +/// +/// If you need to store several different types of binary indexes in one collection, +/// you can cast all binary indexes to the common type `BinaryIndexImpl`. +pub trait UpcastIndexBinary: NativeIndexBinary { + /// Convert an index to the base `BinaryIndexImpl` type + fn upcast(self) -> BinaryIndexImpl; +} + impl UpcastIndex for NI { fn upcast(self) -> IndexImpl { let inner_ptr = self.inner_ptr(); @@ -534,7 +825,17 @@ impl UpcastIndex for NI { } } +impl UpcastIndexBinary for NIB { + fn upcast(self) -> BinaryIndexImpl { + let inner_ptr = self.inner_ptr(); + mem::forget(self); + + unsafe { BinaryIndexImpl::from_inner_ptr(inner_ptr) } + } +} + impl_native_index!(IndexImpl); +impl_native_binary_index!(BinaryIndexImpl); impl TryClone for IndexImpl { fn try_clone(&self) -> Result @@ -545,6 +846,15 @@ impl TryClone for IndexImpl { } } +impl TryClone for BinaryIndexImpl { + fn try_clone(&self) -> Result + where + Self: Sized, + { + try_clone_from_inner_ptr_binary(self) + } +} + /// Use the index factory to create a native instance of a Faiss index, for `d`-dimensional /// vectors. `description` should follow the exact guidelines as the native Faiss interface /// (see the [Faiss wiki](https://github.com/facebookresearch/faiss/wiki/Faiss-indexes) for examples). @@ -572,9 +882,34 @@ where } } +/// Use the index binary factory to create a native instance of a Faiss binary index, for `d`-dimensional +/// vectors. `description` should follow the exact guidelines as the native Faiss interface +/// (see the [Faiss wiki](https://github.com/facebookresearch/faiss/wiki/Binary-indexes) for examples). +/// +/// # Error +/// +/// This function returns an error if the description contains any byte with the value `\0` (since +/// it cannot be converted to a C string), or if the internal index factory operation fails. +pub fn index_binary_factory(d: u32, description: D) -> Result +where + D: AsRef, +{ + unsafe { + let description = + CString::new(description.as_ref()).map_err(|_| Error::IndexDescription)?; + let mut index_ptr = ::std::ptr::null_mut(); + faiss_try(faiss_index_binary_factory( + &mut index_ptr, + (d & 0x7FFF_FFFF) as i32, + description.as_ptr(), + ))?; + Ok(BinaryIndexImpl { inner: index_ptr }) + } +} + #[cfg(test)] mod tests { - use super::{index_factory, Idx, Index, TryClone}; + use super::{index_binary_factory, index_factory, Idx, Index, IndexBinary, TryClone}; use crate::metric::MetricType; #[test] @@ -584,6 +919,13 @@ mod tests { assert_eq!(index.ntotal(), 0); } + #[test] + fn index_binary_factory_flat() { + let index = index_binary_factory(64, "BFlat").unwrap(); + assert_eq!(index.is_trained(), true); // BFlat index does not need training + assert_eq!(index.ntotal(), 0); + } + #[test] fn index_factory_flat_boxed() { let index = index_factory(64, "Flat", MetricType::L2).unwrap(); @@ -638,7 +980,26 @@ mod tests { let r = index_factory(64, "Flat\0Flat", MetricType::L2); assert!(r.is_err()); } + #[test] + fn index_binary_clone() { + let mut index = index_binary_factory(16, "BFlat").unwrap(); + + let some_data = &[ + 0, 1, 2, 3 + ]; + index.add(some_data).unwrap(); + assert_eq!(index.ntotal(), 2); + + let mut index2 = index.try_clone().unwrap(); + assert_eq!(index2.ntotal(), 2); + let some_more_data = &[ + 4, 5, 6, 7 + ]; + index2.add(some_more_data).unwrap(); + assert_eq!(index.ntotal(), 2); + assert_eq!(index2.ntotal(), 4); + } #[test] fn index_clone() { let mut index = index_factory(4, "Flat", MetricType::L2).unwrap(); @@ -663,6 +1024,20 @@ mod tests { assert_eq!(index2.ntotal(), 10); } + #[test] + fn search_index_binary() { + let mut index = index_binary_factory(256, "BFlat").unwrap(); + let some_data = &[ + 255u8; 32 + ]; + index.add(some_data).unwrap(); + assert_eq!(index.ntotal(), 1); + let my_query = [254u8; 32]; + let result = index.search(&my_query, 1).unwrap(); + assert_eq!(result.labels, vec![Idx(0)]); + assert_eq!(result.distances.len(), 1); + assert!(result.distances.iter().all(|x| *x == 32)); + } #[test] fn flat_index_search() { let mut index = index_factory(8, "Flat", MetricType::L2).unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 299a4ce..50a68a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -92,17 +92,20 @@ pub mod error; pub mod index; pub mod metric; pub mod selector; -pub mod vector_transform; pub mod utils; +pub mod vector_transform; #[cfg(feature = "gpu")] pub mod gpu; pub use index::flat::FlatIndex; pub use index::id_map::IdMap; -pub use index::io::{read_index, write_index}; +pub use index::io::{read_index, read_index_binary, write_index, write_index_binary}; pub use index::lsh::LshIndex; -pub use index::{index_factory, ConcurrentIndex, Idx, Index}; +pub use index::{ + index_binary_factory, index_factory, ConcurrentIndex, ConcurrentIndexBinary, Idx, Index, + IndexBinary, +}; pub use metric::MetricType; #[cfg(feature = "gpu")] diff --git a/src/macros.rs b/src/macros.rs index 049e5a2..b8f3af1 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -176,7 +176,220 @@ macro_rules! impl_native_index { }; } -/// A macro which provides a concurrent index implementation to the given type. +/// A macro which provides a native binary index implementation to the given type. +macro_rules! impl_native_binary_index { + ($t:ty) => { + impl crate::index::IndexBinary for $t { + fn is_trained(&self) -> bool { + unsafe { faiss_IndexBinary_is_trained(self.inner_ptr()) != 0 } + } + + fn ntotal(&self) -> u64 { + unsafe { faiss_IndexBinary_ntotal(self.inner_ptr()) as u64 } + } + + fn d(&self) -> u32 { + unsafe { faiss_IndexBinary_d(self.inner_ptr()) as u32 } + } + + fn metric_type(&self) -> crate::metric::MetricType { + unsafe { + crate::metric::MetricType::from_code(faiss_IndexBinary_metric_type( + self.inner_ptr(), + ) as u32) + .unwrap() + } + } + + fn add(&mut self, x: &[u8]) -> Result<()> { + unsafe { + let n = (x.len() * 8) / self.d() as usize; + faiss_try(faiss_IndexBinary_add( + self.inner_ptr(), + n as i64, + x.as_ptr(), + ))?; + Ok(()) + } + } + + fn add_with_ids(&mut self, x: &[u8], xids: &[crate::index::Idx]) -> Result<()> { + unsafe { + let n = (x.len() * 8) / self.d() as usize; + faiss_try(faiss_IndexBinary_add_with_ids( + self.inner_ptr(), + n as i64, + x.as_ptr(), + xids.as_ptr() as *const _, + ))?; + Ok(()) + } + } + fn train(&mut self, x: &[u8]) -> Result<()> { + unsafe { + let n = (x.len() * 8) / self.d() as usize; + faiss_try(faiss_IndexBinary_train( + self.inner_ptr(), + n as i64, + x.as_ptr(), + ))?; + Ok(()) + } + } + fn assign( + &mut self, + query: &[u8], + k: usize, + ) -> Result { + unsafe { + let nq = (query.len() * 8) / self.d() as usize; + let mut out_labels = vec![Idx::none(); k * nq]; + faiss_try(faiss_IndexBinary_assign( + self.inner_ptr(), + nq as idx_t, + query.as_ptr(), + out_labels.as_mut_ptr() as *mut _, + k as i64, + ))?; + Ok(crate::index::AssignSearchResult { labels: out_labels }) + } + } + fn search( + &mut self, + query: &[u8], + k: usize, + ) -> Result { + unsafe { + let nq = (query.len() * 8) / self.d() as usize; + let mut distances = vec![0_i32; k * nq]; + let mut labels = vec![Idx::none(); k * nq]; + faiss_try(faiss_IndexBinary_search( + self.inner_ptr(), + nq as idx_t, + query.as_ptr(), + k as idx_t, + distances.as_mut_ptr(), + labels.as_mut_ptr() as *mut _, + ))?; + Ok(crate::index::SearchResultBinary { distances, labels }) + } + } + fn range_search( + &mut self, + query: &[u8], + radius: i32, + ) -> Result { + unsafe { + let nq = ((query.len() * 8) / self.d() as usize) as idx_t; + let mut p_res: *mut FaissRangeSearchResult = ::std::ptr::null_mut(); + faiss_try(faiss_RangeSearchResult_new(&mut p_res, nq))?; + faiss_try(faiss_IndexBinary_range_search( + self.inner_ptr(), + nq, + query.as_ptr(), + radius, + p_res, + ))?; + Ok(crate::index::RangeSearchResult { inner: p_res }) + } + } + + fn reset(&mut self) -> Result<()> { + unsafe { + faiss_try(faiss_IndexBinary_reset(self.inner_ptr()))?; + Ok(()) + } + } + + fn remove_ids(&mut self, sel: &IdSelector) -> Result { + unsafe { + let mut n_removed = 0; + faiss_try(faiss_IndexBinary_remove_ids( + self.inner_ptr(), + sel.inner_ptr(), + &mut n_removed, + ))?; + Ok(n_removed) + } + } + + fn verbose(&self) -> bool { + unsafe { faiss_IndexBinary_verbose(self.inner_ptr()) != 0 } + } + + fn set_verbose(&mut self, value: bool) { + unsafe { + faiss_IndexBinary_set_verbose( + self.inner_ptr(), + std::os::raw::c_int::from(value), + ); + } + } + } + }; +} + +// FIXME: Reinstate this once there are other concrete implementations for Binary Indexes. +// For now, this is just a red herring for CI since we have `-D unused-macros` +// /// A macro which provides a concurrent index implementation to the given type. +// macro_rules! impl_concurrent_binary_index { +// ($t:ty) => { +// impl crate::index::ConcurrentIndexBinary for $t +// where +// Self: crate::index::IndexBinary + crate::index::NativeIndexBinary, +// { +// fn assign(&self, query: &[u8], k: usize) -> Result { +// unsafe { +// let nq = query.len() / self.d() as usize; +// let mut out_labels = vec![Idx::none(); k * nq]; +// faiss_try(faiss_IndexBinary_assign( +// self.inner_ptr(), +// nq as idx_t, +// query.as_ptr(), +// out_labels.as_mut_ptr() as *mut _, +// k as i64, +// ))?; +// Ok(AssignSearchResult { labels: out_labels }) +// } +// } + +// fn search(&self, query: &[u8], k: usize) -> Result { +// unsafe { +// let nq = query.len() / self.d() as usize; +// let mut distances = vec![0_i32; k * nq]; +// let mut labels = vec![Idx::none(); k * nq]; +// faiss_try(faiss_IndexBinary_search( +// self.inner_ptr(), +// nq as idx_t, +// query.as_ptr(), +// k as idx_t, +// distances.as_mut_ptr(), +// labels.as_mut_ptr() as *mut _, +// ))?; +// Ok(SearchResultBinary { distances, labels }) +// } +// } + +// fn range_search(&self, query: &[u8], radius: i32) -> Result { +// unsafe { +// let nq = (query.len() / self.d() as usize) as idx_t; +// let mut p_res: *mut FaissRangeSearchResult = ptr::null_mut(); +// faiss_try(faiss_RangeSearchResult_new(&mut p_res, nq))?; +// faiss_try(faiss_IndexBinary_range_search( +// self.inner_ptr(), +// nq, +// query.as_ptr(), +// radius, +// p_res, +// ))?; +// Ok(RangeSearchResult { inner: p_res }) +// } +// } +// } +// }; +// } + +/// A macro which provides a concurrent binary index implementation to the given type. macro_rules! impl_concurrent_index { ($t:ty) => { impl crate::index::ConcurrentIndex for $t