-
Notifications
You must be signed in to change notification settings - Fork 144
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding basic building blocks for MemoryOptimizedSearch. At the moment…
…, only FAISS is supporing this. Signed-off-by: Dooyong Kim <kdooyong@amazon.com>
- Loading branch information
Dooyong Kim
committed
Mar 6, 2025
1 parent
c7ac05c
commit 83cd071
Showing
8 changed files
with
258 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
src/main/java/org/opensearch/knn/memoryoptsearch/MemoryOptimizedSearcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.knn.memoryoptsearch; | ||
|
||
import org.apache.lucene.search.KnnCollector; | ||
import org.apache.lucene.util.Bits; | ||
|
||
import java.io.Closeable; | ||
import java.io.IOException; | ||
|
||
/** | ||
* Memory optimized searcher that performs vector search with the best efforts to minimize memory pressure. | ||
* Its implementation should only focus on optimizing memory allocations, and must not increase memory pressure in JVM. | ||
* The main focus of the pressure is limited to JVM, and it would be better if it could take a leverage of OS cache memory to improve | ||
* performance internally. | ||
* Although its main focus is on memory pressure, but it does not mean that we sacrifice performance over memory consumption. | ||
* If anything, this searcher must be balanced between two factors, seeking the best performance while minimizing memory pressure. | ||
* This is the goal of this searcher. | ||
*/ | ||
public interface MemoryOptimizedSearcher extends Closeable { | ||
|
||
/** | ||
* Return the k nearest neighbor documents as determined by comparison of their vector values for | ||
* this field, to the given vector, by the field's similarity function. The score of each document | ||
* is derived from the vector similarity in a way that ensures scores are positive and that a | ||
* larger score corresponds to a higher ranking. | ||
* | ||
* <p>The search is allowed to be approximate, meaning the results are not guaranteed to be the | ||
* true k closest neighbors. For large values of k (for example when k is close to the total | ||
* number of documents), the search may also retrieve fewer than k documents. | ||
* | ||
* @param target the vector-valued float vector query | ||
* @param knnCollector a KnnResults collector and relevant settings for gathering vector results | ||
* @param acceptDocs {@link Bits} that represents the allowed documents to match, or {@code null} | ||
* if they are all allowed to match. | ||
*/ | ||
void search(float[] target, KnnCollector knnCollector, Bits acceptDocs) throws IOException; | ||
|
||
/** | ||
* Return the k nearest neighbor documents as determined by comparison of their vector values for | ||
* this field, to the given vector, by the field's similarity function. The score of each document | ||
* is derived from the vector similarity in a way that ensures scores are positive and that a | ||
* larger score corresponds to a higher ranking. | ||
* | ||
* <p>The search is allowed to be approximate, meaning the results are not guaranteed to be the | ||
* true k closest neighbors. For large values of k (for example when k is close to the total | ||
* number of documents), the search may also retrieve fewer than k documents. | ||
* | ||
* @param target the vector-valued byte vector query | ||
* @param knnCollector a KnnResults collector and relevant settings for gathering vector results | ||
* @param acceptDocs {@link Bits} that represents the allowed documents to match, or {@code null} | ||
* if they are all allowed to match. | ||
*/ | ||
void search(byte[] target, KnnCollector knnCollector, Bits acceptDocs) throws IOException; | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/org/opensearch/knn/memoryoptsearch/MemoryOptimizedSearcherFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.knn.memoryoptsearch; | ||
|
||
import org.apache.lucene.store.Directory; | ||
|
||
import java.io.IOException; | ||
|
||
/** | ||
* Factory to create {@link MemoryOptimizedSearcher}. | ||
* Provided parameters will have {@link Directory} and a file name where implementation can rely on it to open an input stream. | ||
*/ | ||
public interface MemoryOptimizedSearcherFactory { | ||
/** | ||
* Create a non-null {@link MemoryOptimizedSearcher} with given Lucene's {@link Directory}. | ||
* | ||
* @param directory Lucene's Directory. | ||
* @param fileName Logical file name to load. | ||
* @return It must return a non-null {@link MemoryOptimizedSearcher} | ||
* @throws IOException | ||
*/ | ||
MemoryOptimizedSearcher createMemoryOptimizedSearcher(Directory directory, String fileName) throws IOException; | ||
} |
38 changes: 38 additions & 0 deletions
38
src/main/java/org/opensearch/knn/memoryoptsearch/faiss/FaissMemoryOptimizedSearcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.knn.memoryoptsearch.faiss; | ||
|
||
import org.apache.lucene.search.KnnCollector; | ||
import org.apache.lucene.store.IndexInput; | ||
import org.apache.lucene.util.Bits; | ||
import org.opensearch.knn.memoryoptsearch.MemoryOptimizedSearcher; | ||
|
||
import java.io.IOException; | ||
|
||
public class FaissMemoryOptimizedSearcher implements MemoryOptimizedSearcher { | ||
private final IndexInput indexInput; | ||
|
||
public FaissMemoryOptimizedSearcher(IndexInput indexInput) { | ||
this.indexInput = indexInput; | ||
} | ||
|
||
@Override | ||
public void search(float[] target, KnnCollector knnCollector, Bits acceptDocs) throws IOException { | ||
// TODO(KDY) : This will be covered in subsequent parts. | ||
throw new UnsupportedOperationException("Not implemented yet"); | ||
} | ||
|
||
@Override | ||
public void search(byte[] target, KnnCollector knnCollector, Bits acceptDocs) throws IOException { | ||
// TODO(KDY) : This will be covered in subsequent parts. | ||
throw new UnsupportedOperationException("Not implemented yet"); | ||
} | ||
|
||
@Override | ||
public void close() throws IOException { | ||
indexInput.close(); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
...in/java/org/opensearch/knn/memoryoptsearch/faiss/FaissMemoryOptimizedSearcherFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.knn.memoryoptsearch.faiss; | ||
|
||
import org.apache.lucene.store.Directory; | ||
import org.apache.lucene.store.IOContext; | ||
import org.apache.lucene.store.IndexInput; | ||
import org.apache.lucene.store.ReadAdvice; | ||
import org.opensearch.knn.memoryoptsearch.MemoryOptimizedSearcher; | ||
import org.opensearch.knn.memoryoptsearch.MemoryOptimizedSearcherFactory; | ||
|
||
import java.io.IOException; | ||
|
||
public class FaissMemoryOptimizedSearcherFactory implements MemoryOptimizedSearcherFactory { | ||
@Override | ||
public MemoryOptimizedSearcher createMemoryOptimizedSearcher(final Directory directory, final String fileName) throws IOException { | ||
// Why ReadAdvice.RANDOM? | ||
// We pass `RANDOM` as advice to prevent the underlying storage from performing read-ahead. Since vector search naturally accesses | ||
// random vector locations, read-ahead does not improve performance. By passing the `RANDOM` context, we explicitly indicate that | ||
// this searcher will access vectors randomly. | ||
final IndexInput indexInput = directory.openInput( | ||
fileName, | ||
new IOContext(IOContext.Context.DEFAULT, null, null, ReadAdvice.RANDOM) | ||
); | ||
return new FaissMemoryOptimizedSearcher(indexInput); | ||
} | ||
} |