Skip to content

Add optional persistent locks to IndexHNSW for incremental adds (#5031)#5031

Open
ddrcoder wants to merge 1 commit intofacebookresearch:mainfrom
ddrcoder:export-D98232750
Open

Add optional persistent locks to IndexHNSW for incremental adds (#5031)#5031
ddrcoder wants to merge 1 commit intofacebookresearch:mainfrom
ddrcoder:export-D98232750

Conversation

@ddrcoder
Copy link
Copy Markdown
Contributor

@ddrcoder ddrcoder commented Apr 2, 2026

Summary:

IndexHNSW allocates an initializes locks for ntotal+n nodes on every call to add(). This makes batched insertion very costly, and incremental insertion prohibitively so.

This diff introduces optional persistent locks for IndexHNSW to improve incremental add() performance. Previously, omp_lock_t arrays of size ntotal+n were created/destroyed on each add() call. Now locks can be retained via a new retain_locks flag (default: false), using a new HNSW::Lock RAII wrapper with geometric growth.

RFC: Instead of retain_locks being the only way to opt into this new behavior, this could be inferred on the first incremental add. That is, clear the locks after insertion iff n0 == 0. Workloads which call add() once would be unaffected, but workloads which call add() repeatedly would 1) forego the clearing of the lock vector after add() call #2, and reuse locks for all subsequent calls. The downside would be the lack of the ability to reclaim the locks after insertion without HNSW-specific behavior at the call site.

Differential Revision: D98232750

@meta-cla meta-cla bot added the CLA Signed label Apr 2, 2026
@meta-codesync
Copy link
Copy Markdown
Contributor

meta-codesync bot commented Apr 2, 2026

@ddrcoder has exported this pull request. If you are a Meta employee, you can view the originating Diff in D98232750.

…bookresearch#5031)

Summary:

`IndexHNSW` allocates an initializes locks for `ntotal+n` nodes on every call to `add()`. This makes batched insertion very costly, and incremental insertion prohibitively so.

This diff introduces optional persistent locks for `IndexHNSW` to improve incremental `add()` performance. Previously, `omp_lock_t` arrays of size `ntotal+n` were created/destroyed on each `add()` call. Now locks can be retained via a new `retain_locks` flag (default: false), using a new `HNSW::Lock` RAII wrapper with geometric growth.

RFC: Instead of `retain_locks` being the only way to opt into this new behavior, this could be inferred on the first incremental add. That is, clear the locks after insertion iff `n0 == 0`. Workloads which call `add()` once would be unaffected, but workloads which call `add()` repeatedly would 1) forego the clearing of the lock vector after `add()` call facebookresearch#2, and reuse locks for all subsequent calls. The downside would be the lack of the ability to reclaim the locks after insertion without HNSW-specific behavior at the call site.

Differential Revision: D98232750
@meta-codesync meta-codesync bot changed the title Add optional persistent locks to IndexHNSW for incremental adds Add optional persistent locks to IndexHNSW for incremental adds (#5031) Apr 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant