Commit Graph
15 Commits
Author SHA1 Message Date
Alexandr Guzhva 799bf3aaec Introduce early stop facilities for IVF, attempt 2 (#5160)
Summary:
# Introduce early-stop controls for IVF search

This PR adds optional early-stop controls to IVF search through `SearchParametersIVF`.

IVF search looks in a sequence of buckets. Normally it keeps looking until it has checked all requested buckets. This PR adds a few ways to stop earlier:

- stop after enough candidate vectors have been checked,
- stop FastScan after enough buckets have been checked,
- stop range search after several nearby buckets produce no results.

All new fields default to disabled, so existing searches keep their current behavior unless callers opt in.

## New SearchParametersIVF fields

Default values:

| Field | Default | Effect |
|---|---:|---|
| `ensure_topk_full` | `false` | disabled; keep the existing hard `max_codes` behavior |
| `max_lists_num` | `0` | disabled; FastScan is bounded only by `nprobe` |
| `max_empty_result_buckets` | `0` | disabled; range search scans all requested probes |

`ensure_topk_full`

For k-NN search, `max_codes` limits how many candidate vectors are scanned. With `ensure_topk_full=false`, the search stops when the budget is reached.

With `ensure_topk_full=true`, very small budgets become less aggressive: `max_codes` is treated as at least `k` post-filter scans. This helps when `max_codes < k`, or when an `IDSelector` filters out many candidates before a distance is computed.

In the generic IVF path this is supported for `parallel_mode` 0 and 3. In FastScan k-NN it is supported by the per-query implementations 10 and 11.

`max_lists_num`

FastScan k-NN can also stop after visiting a limited number of inverted lists. `0` means disabled. With `ensure_topk_full`, this list budget is treated as at least `k` lists. This is only used by the FastScan per-query path (`search_implem_10`, also used for implementation 11).

When FastScan is left on `implem = 0`, setting an early-stop k-NN option makes the dispatcher choose the per-query implementation automatically. If an incompatible FastScan implementation is selected explicitly, Faiss throws instead of ignoring the option.

`max_empty_result_buckets`

This is for range search. It stops probing a query after that many consecutive probed lists add no in-radius results. The counter resets as soon as a list adds at least one result.

`0` means disabled. Setting this trades recall for less work: once nearby buckets repeatedly produce no hits, farther buckets are less likely to help.

The generic IVF range path supports this in `parallel_mode == 0`. FastScan range search also supports it through implementation 10. With `implem = 0`, FastScan selects implementation 10 automatically when this option is set; explicit incompatible implementations throw.

## Selector-aware scan accounting

This PR adds `InvertedListScannerStats`, returned by inverted-list scanner methods. It currently reports:

- `scan_cnt`: number of distances actually computed,
- `nheap_updates`: number of result updates.

The important behavior change is that `IndexIVFStats::ndis` now uses `scan_cnt`. With an `IDSelector`, candidates rejected by the selector are not counted as computed distances. Without a selector, this matches the previous count because every scanned code reaches distance computation.

This same post-filter count is used by `ensure_topk_full`, so a restrictive selector no longer consumes the search budget with candidates that were never eligible for the result heap.

## FastScan behavior

FastScan k-NN now applies `max_codes`, `max_lists_num`, and `ensure_topk_full` in the per-query implementation. The code keeps separate counters per query, so multi-query batches have independent budgets.

For `max_codes`, FastScan uses the result handler's scanned-row count. This means filtered-out rows do not consume the code budget.

FastScan range search rejects k-NN-only options (`max_codes`, `max_lists_num`, and `ensure_topk_full`). It accepts `max_empty_result_buckets` when the selected implementation can preserve per-query probe order.

## API exposure

The new fields are exposed through:

- C++ `SearchParametersIVF`,
- Python bindings,
- the C API.

The statistics is tracked via `InvertedListScanner::scan_codes(..., ResultHandler& handler)` call. In order to make it work inside `IndexIVF::search()`, it has been decided to transition it into this particular override of `InvertedListScanner::scan_codes()`. As a result, non-`ResultHandler` version of `scan_codes()` has been marked as non-virtual, so the custom `InvertedListScanner` implementations should override `ResultHandler`-based versions only. Another consequence is that `IndexIVFPQFastScanScanner` and `IndexIVFRaBitQFastScanScanner` accept only `HeapResultHandler` types of `ResultHandler`. These are the compromises that had to be made.

## Tests

The tests cover:

- default parameters preserving baseline k-NN and range-search results,
- `ensure_topk_full` filling more result slots under tight budgets,
- selector-aware `IndexIVFStats::ndis`,
- range-search early exit and counter reset behavior,
- unsupported parallel modes and FastScan implementations,
- FastScan k-NN and range-search early-stop behavior,
- Python and C API field exposure.

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5160

Reviewed By: limqiying

Differential Revision: D103044128

Pulled By: mnorris11

fbshipit-source-id: 80f1241c13ffc8173a3da0f2974fa9b6dd318890
2026-05-01 12:23:05 -07:00
Michael Norris eff0898a13 Enable linting: lint config changes plus arc lint command (#3966)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3966

This actually enables the linting.

Manual changes:
- tools/arcanist/lint/fbsource-licenselint-config.toml
- tools/arcanist/lint/fbsource-lint-engine.toml

Automated changes:
`arc lint --apply-patches --take LICENSELINT --paths-cmd 'hg files faiss'`

Reviewed By: asadoughi

Differential Revision: D64484165

fbshipit-source-id: 4f2f6e953c94ef6ebfea8a5ae035ccfbea65ed04
2024-10-22 09:46:48 -07:00
Michael Norris 56a383f253 Resolve "duplicate-license-header": Find and replace duplicate license headers (#3967)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3967

This diff just finds and replaces duplicate license headers.

See the errors for "duplicate-license-header" in D64429711 under "linter-coverage-verification" signal.

Reviewed By: asadoughi

Differential Revision: D64484123

fbshipit-source-id: 906e8baa3a11a3bbee174a03dcc27681f9fd78c2
2024-10-21 08:26:22 -07:00
Matthijs Douze fd09e51316 move by_residual to IndexIVF (#2870)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2870

Factor by_residual for all the IndexIVF inheritors.
Some training code can be put in IndexIVF and `train_residual` is replaced with `train_encoder`.

This will be used for the IndependentQuantizer work.

Reviewed By: alexanderguzhva

Differential Revision: D45987304

fbshipit-source-id: 7310a687b556b2faa15a76456b1d9000e21b58ce
2023-05-23 09:56:19 -07:00
Kaelen Haag 24758fb27d Search params c_api implementation (#2732)
Summary:
https://github.com/facebookresearch/faiss/issues/2727

Implements search_with_params function on c_api for index.

Implemented c_api equivalents of SearchParameters and SearchParametersIVF.

My C/C++ is pretty rusty so I imagine my arguments to the new functions for each search parameters could be refined. Happy to take suggestions :)

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2732

Reviewed By: alexanderguzhva

Differential Revision: D43917264

Pulled By: mdouze

fbshipit-source-id: c9eaf0d96ec0fad4862528aac9b5946294f5e444
2023-03-09 15:30:19 -08:00
Matthijs Douze cf15b89786 indicate default values in class declaration (#2676)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2676

This is a cosmetic diff where default values for scalar fields are moved to the .h file where the object is declared rather than in the object constructor. The advantage is that it is easier to read the default value of a parameter from just the class.

Reviewed By: alexanderguzhva

Differential Revision: D42722205

fbshipit-source-id: 9d9bc4641068f6d6233f60f0a3a16ab793c94bb8
2023-01-26 09:39:47 -08:00
Alexander Andreev f6d2efd1df Cover more types for C_API (#1917)
Summary:
Exported some global variables and statistics.
Supported downcast for IndexIDMap and IndexIDMap2 from faiss::Index
Fixes https://github.com/facebookresearch/faiss/issues/1863

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1917

Reviewed By: beauby

Differential Revision: D28834039

Pulled By: mdouze

fbshipit-source-id: c1f7739dcdc23055780ebc665082609641dff861
2021-06-08 15:34:05 -07:00
Alexander Andreev b209361f7b Add setters for IndexIVF* indexes (#1827)
Summary:
This PR gives users control over resources

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1827

Reviewed By: beauby

Differential Revision: D27904561

Pulled By: mdouze

fbshipit-source-id: 61352f776971d9f488917e39f8746d43614386d9
2021-04-22 05:22:40 -07:00
Lucas Hosseini e86bf8cae1 Enable clang-format + autofix.
Summary: Format whole codebase with clang-format.

Reviewed By: mdouze

Differential Revision: D22891341

fbshipit-source-id: 673032b2444d61026d1e2c3fa2c5659f178cf58b
2021-02-25 04:46:10 -08:00
Prabhat Roy 7a289d5418 Added C API to CMake and CircleCI (#1678)
Summary:
This supersedes https://github.com/facebookresearch/faiss/issues/1390 and https://github.com/facebookresearch/faiss/issues/1141.

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1678

Reviewed By: mdouze

Differential Revision: D26428986

Pulled By: beauby

fbshipit-source-id: 1e2718f457c1aca18c19edc2436d6baf9b627a60
2021-02-15 12:41:31 -08:00
Danil GuskovandEduardo Pinho 7e08db7cb7 c_api: faiss_IndexIVF_invlists_get_ids function (#1094)
If @Enet4 approves it's fine with me.

* c_api: faiss_IndexIVF_invlists_get_ids function

* Update c_api/IndexIVF_c.h

Co-Authored-By: Eduardo Pinho <[email protected]>

Co-authored-by: Eduardo Pinho <[email protected]>
2020-01-31 13:40:28 +01:00
Eduardo Pinho 828dcea400 [C API] June 2019 update (#869)
* [c_api] use all relevant flags in compilation

* [c_api] Remove redundant IndexIVFFlat declarations

- From IndexIVF_c.h, already declared in IndexIVFFlat_c.h

* [c_api] type changes

- replace `long` with a more suitable type
- provide definitions for `faiss_component_t` and `faiss_distance_t`

* [c_api] Define CFLAGS and CUDACFLAGS
2019-06-24 13:29:38 +02:00
Eduardo Pinho 2bfbead8f1 [C API] Update for compatibility with v1.5 (#858)
* [c_api] Update impl and interface for v1.5

- move IndexShards to dedicated module IndexShards_c.{h|cpp}
- remove getter/setters to unreachable fields
- reimplement faiss_IndexIVF_imbalance_factor (to use invlists)
- minor IndexIVF documentation tweaks
- Remove QueryResult, provide RangeQueryResult

* [c_api] Document FaissErrorCode

* [c_api] Update GPU impl and interface for v1.5

- Remove unavailable method setTempMemoryFraction

* [c_api] Relicense to MIT

In accordance to the rest of the project
2019-06-12 15:46:08 +02:00
Eduardo Pinho 9efdd8d427 [C API] Additional API coverage: IndexLSH, I/O, meta-indexes (#425)
* [c_api] leverage index downcast

- make index downcast declaration+definition possible with macros
- use macros on existing index types

* [c_api] Add IndexLSH to C API

* [c_api] Add Index IO interface

- new header index_io_c.h for access to the index_io.h API
- function`faiss_write_index` and overloads for dumping index to a file
- function`faiss_read_index` and overloads for reading index from a file
- function`faiss_clone_index` for cloning an index
- update C example to save index to a file

* [c_api] Add IndexIDMap and IndexShards API
2018-05-02 13:39:59 +02:00
Eduardo Pinho de0541c365 Add C API (#317)
* Add C API

* Add installation instructions for the C API
2018-02-26 11:23:17 +01:00