Refactor Faiss-based vector format for easier backport#14934
Refactor Faiss-based vector format for easier backport#14934mikemccand merged 4 commits intoapache:mainfrom
Conversation
|
This PR does not have an entry in lucene/CHANGES.txt. Consider adding one. If the PR doesn't need a changelog entry, then add the skip-changelog label to it and you will stop receiving this reminder on future updates to the PR. |
|
This PR does not have an entry in lucene/CHANGES.txt. Consider adding one. If the PR doesn't need a changelog entry, then add the skip-changelog label to it and you will stop receiving this reminder on future updates to the PR. |
|
Also ran benchmarks to ensure these changes don't adversely affect performance..
This PR: |
mikemccand
left a comment
There was a problem hiding this comment.
Thank you @kaivalnp -- this looks clean to me -- but @uschindler probably has suggestions still ;)
| interface FaissLibrary { | ||
| FaissLibrary INSTANCE = lookup(); | ||
|
|
||
| // TODO: Use vectorized version where available |
There was a problem hiding this comment.
Hmm what does this TODO mean again? Is "vectorized" meaning "SIMD instructions"? This term (vector) is overloaded! https://youtu.be/fVq4_HhBK8Y
Maybe clarify to // TODO: use SIMD Faiss API versions where available or so (if that's what it really means)? I think this is necessary because the Faiss build process will produce specific dynamic library for specific SIMD targets (AVX-512 vs AVX-128 etc.)?
There was a problem hiding this comment.
Yes sorry, I meant using SIMD instructions wherever available..
Today, the shared library of Faiss' C API (libfaiss_c.so) is linked to the non-SIMD version of the base library (libfaiss.so) by default, but a user can still "point" to the correct SIMD version by changing its dependencies using:
# patchelf --replace-needed OLD_DEPENDENCY NEW_DEPENDENCY SHARED_LIBRARY
patchelf --replace-needed libfaiss.so libfaiss_{avx2,avx512,sve}.so libfaiss_c.soHowever, we'd ideally want to do this automatically (either propose a change to upstream Faiss, or something else from Lucene) -- but I wasn't sure how to do it right now..
I'll update the comment soon!
|
Give me some time to check this. In general I agree with those refactorings, it is much cleaner and exception handling is correct. Also everything which touches native code is encapsulated. This is all strongly needed and should be done without any backporting in mind. It is rwquired to have good code. I don't think we should backport this to our stable 10.x branch as this won't work with Java 21 and still theres complex work to be used to make this compile with Java 21 using APIJARs duplication and so on. My proposal is to release Lucene 11 this autumn with Java 25 (see mailing list thread) where we have no limitations with preview APIs anymore. |
Hi @uschindler, wanted to ask if you have any feedback for these changes? |
There was a problem hiding this comment.
To me the whole thing looks fine. I have not checked the internals and only looked at the native code. It looks fine to have everything which calls native code into two classes.
The try/catch code looks correct. The redundancy here is needed, thanks for adding it, using a wrapper method for catching exceptions as before was not a good idea, because it required to use slow/inexact method handles and varargs.
But please remove the lookup of the native implementation in FaiddLibrary.java. In Lucene's main branch this is useless. Just return the instance directly (see code of MMapDir in main branch, there are no such indirections anymore).
Like Robert, I don't agree with backporting this to 10.x branch. This should be a new feature for Lucene 11.
| String NAME = "faiss_c"; | ||
| String VERSION = "1.11.0"; | ||
|
|
||
| private static FaissLibrary lookup() { |
There was a problem hiding this comment.
Why do we have that dynamic code in main branch? Please replace by a simple return new FaissLibraryNativeImpl().
There was a problem hiding this comment.
Makes sense, updated
- Avoid dynamic lookup for FaissLibraryNativeImpl on the main branch - Explain the SIMD situation in more detail
|
This PR does not have an entry in lucene/CHANGES.txt. Consider adding one. If the PR doesn't need a changelog entry, then add the skip-changelog label to it and you will stop receiving this reminder on future updates to the PR. |
|
Thanks a lot @uschindler!
Personally, I feel that the main blocker here was some differences in function names that allocated / read strings and arrays from native memory (which I think could be worked around using method handles to point to the correct function) -- but I agree, it could become messy due to the incompatibility. I'll hold off on trying to backport this change unless someone feels otherwise. |
mikemccand
left a comment
There was a problem hiding this comment.
Thanks @kaivalnp -- this looks cleaner!
It sounds like consensus is to not backport this to 10.x, and rather release 11.0 soon (end of year ish?).
|
I think this is ready to merge? I'll merge in a day or so ... |
uschindler
left a comment
There was a problem hiding this comment.
Latest changes look OK.
|
Thank you @kaivalnp! |
* Refactor Faiss-based vector format for easier backport * Fix errorprone * Address comments - Avoid dynamic lookup for FaissLibraryNativeImpl on the main branch - Explain the SIMD situation in more detail --------- Co-authored-by: Kaival Parikh <kaivalp2000@gmail.com>
Description
Refactor classes of the Faiss-based vector format to simplify backport to 10.x
FaissLibraryinterfaceFaissNativeWrapper(and useinvokeExactfor faster calls!)FaissLibraryNativeImplclass implementingFaissLibrarywithFaissNativeWrapperunder the hoodFaissLibraryNativeImplfromFaissLibraryat runtimeFaissNativeWrapperandFaissLibraryNativeImpl(as marked by TODOs in build: enable more of javac 24's lints, fix some issues #14907), which can independently be moved into thejava21/directory for an easier backport (see comments in Backport Faiss-based vector format to 10.x #14843), while theFaissKnnVectors{Format/Reader/Writer}can stay as-is!