Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Adding support for FAISS JNI #285

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
1c3d373
1. New Branch Support Faiss
Dec 25, 2020
6066a65
1. add submmodule faiss
Dec 25, 2020
5165e70
1. External Submodule
Dec 25, 2020
fb10190
Update CMakeLists.txt
luyuncheng Dec 25, 2020
54cf6a5
Update CMakeLists.txt
luyuncheng Dec 25, 2020
0f4bdf0
1. add knnEngine as a Settings
Dec 25, 2020
ab8e950
1. Modified some FIXME
Dec 25, 2020
950e460
Merge pull request #1 from luyuncheng/faiss_withIT
luyuncheng Dec 25, 2020
22ce605
1. gradle build jni and jniFaiss
Dec 25, 2020
1a44194
Merge pull request #2 from luyuncheng/faiss_withIT
luyuncheng Dec 25, 2020
3d13a7b
Merge pull request #6 from opendistro-for-elasticsearch/master
luyuncheng Jan 11, 2021
6f7094b
1. FIXED SpaceType Get From IndexSettings may be EMPTY when a anonymo…
Jan 11, 2021
d94881c
Update CI.yml
luyuncheng Jan 11, 2021
3dfb714
1. Add CI branches for faiss
Jan 11, 2021
3834ea0
1. Update Cmake Files
Jan 11, 2021
a775a3d
OFF GPU
Jan 11, 2021
051a54b
OFF PYTHON
Jan 11, 2021
8cd57a7
delete COMPILER
Jan 11, 2021
ff99c4c
Update CMakeLists.txt
luyuncheng Jan 12, 2021
d3d9baa
Update CMakeLists.txt
luyuncheng Jan 12, 2021
afa1b5c
Update build.gradle
luyuncheng Jan 12, 2021
ce389f4
Update com_amazon_opendistroforelasticsearch_knn_index_faiss_KNNFInde…
luyuncheng Jan 12, 2021
7165574
Update CMakeLists.txt
luyuncheng Jan 12, 2021
3d1670d
Merge branch 'faiss' into faiss_dev
luyuncheng Jan 12, 2021
3d0a2de
Update KNNCircuitBreakerIT.java
luyuncheng Jan 12, 2021
698fbea
Update KNNCircuitBreakerIT.java
luyuncheng Jan 12, 2021
890d6f7
Update KNNCircuitBreakerIT.java
luyuncheng Jan 12, 2021
8b08b4e
Update KNNCodecTestCase.java
luyuncheng Jan 12, 2021
8fd1220
Merge pull request #7 from luyuncheng/faiss_dev
luyuncheng Jan 12, 2021
381dd58
Merge branch 'master' into faiss
luyuncheng Jan 12, 2021
20672df
Update test-workflow.yml
luyuncheng Jan 12, 2021
deeefeb
Merge pull request #8 from luyuncheng/faiss_dev
luyuncheng Jan 12, 2021
fdeca84
Merge branch 'master' into faiss_dev
Jan 12, 2021
0423466
Merge Master Into Faiss
Jan 12, 2021
4d2960d
Merge Master Into Faiss
Jan 12, 2021
654cb52
Merge Master Into Faiss
Jan 12, 2021
f549e3e
Merge branch 'faiss' into faiss_dev
luyuncheng Jan 12, 2021
98d44d1
Merge pull request #10 from luyuncheng/faiss_dev
luyuncheng Jan 12, 2021
243eb81
move IndexClass check inside the AccessController.doPrivileged
Jan 13, 2021
3c2e397
Add Tests for Circuit breaker test with different engine
Jan 18, 2021
f231965
1. Add NmsLib Version And Faiss Version into KNN Plugin
Jan 20, 2021
3bdbc43
Update CMakeLists.txt
luyuncheng Jan 20, 2021
ce141a3
Update CMakeLists.txt
luyuncheng Jan 20, 2021
652c329
Update CMakeLists.txt
luyuncheng Jan 20, 2021
6672814
Update KNNWeight.java
luyuncheng Jan 20, 2021
b08d2d9
Update CMakeLists.txt
luyuncheng Jan 20, 2021
f4ebd79
1. Add NmsLib Version And Faiss Version into KNN Plugin
Jan 20, 2021
df4c218
Merge remote-tracking branch 'origin/faiss_dev_libversion' into faiss…
Jan 20, 2021
1777bd1
1. Add NmsLib Version And Faiss Version into KNN Plugin
Jan 20, 2021
576a8eb
Merge pull request #11 from luyuncheng/faiss_dev_libversion
luyuncheng Jan 20, 2021
d37a523
Add NmsLib Version And Faiss Version into KNN Plugin
luyuncheng Jan 20, 2021
7c83e70
Merge pull request #13 from opendistro-for-elasticsearch/master
luyuncheng Jan 22, 2021
dd179b5
1. Add NmsLib Version And Faiss Version into KNN Plugin
Jan 22, 2021
cd7e3e8
1. Merge remote-tracking branch 'origin/master' into faiss_dev
Jan 22, 2021
9056b85
1. Update Submodule FAISS to new version
Jan 24, 2021
a33625c
1. Update Submodule FAISS to new version V1.6.5(HASH:88eabe9)
Jan 24, 2021
ee0a3fe
1. Update Submodule FAISS to new version V1.6.5(HASH:88eabe9)
Jan 24, 2021
d613095
1. Remove nouse CI branches
Jan 24, 2021
7715563
Merge pull request #14 from luyuncheng/faiss_dev
luyuncheng Jan 24, 2021
82671ad
1. Fixed Indentation
Jan 25, 2021
bea16d6
1. Make KNNIndex as abstract class
Jan 25, 2021
3dc4f1f
1. Make KNNIndex as abstract class
Jan 25, 2021
1207bac
Merge pull request #15 from luyuncheng/opendistro-faiss_dev
luyuncheng Jan 25, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
branches:
- master
- opendistro-*
- faiss*
jmazanec15 marked this conversation as resolved.
Show resolved Hide resolved
jobs:
build:
strategy:
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "jni/external/nmslib"]
path = jni/external/nmslib
url = https://github.com/nmslib/nmslib.git
[submodule "jniFaiss/external/faiss"]
path = jniFaiss/external/faiss
url = https://github.com/facebookresearch/faiss
31 changes: 21 additions & 10 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -137,31 +137,41 @@ loggerUsageCheck.enabled = false
def es_tmp_dir = rootProject.file('build/private/es_tmp').absoluteFile
es_tmp_dir.mkdirs()

task cmakeJniLib(type:Exec) {
task cmakeJniNmsLib(type:Exec) {
workingDir 'jni'
commandLine 'cmake', '.'
}

task buildJniLib(type:Exec) {
dependsOn cmakeJniLib
task cmakeJniFaissLib(type:Exec) {
workingDir 'jniFaiss'
commandLine 'cmake', '.'
}
task buildJniNmsLib(type:Exec) {
dependsOn cmakeJniNmsLib
workingDir 'jni'
commandLine 'make'
}
task buildJniFaissLib(type:Exec) {
dependsOn cmakeJniFaissLib
workingDir 'jniFaiss'
commandLine 'make'
}

test {
dependsOn buildJniLib
dependsOn buildJniNmsLib
dependsOn buildJniFaissLib
systemProperty 'tests.security.manager', 'false'
systemProperty "java.library.path", "$rootDir/jni/release"
systemProperty "java.library.path", "$rootDir/jniFaiss/release:$rootDir/jni/release"
}

def _numNodes = findProperty('numNodes') as Integer ?: 1
integTest {
if (integTestDependOnJniLib) {
dependsOn buildJniLib
dependsOn buildJniNmsLib
dependsOn buildJniFaissLib
}
systemProperty 'tests.security.manager', 'false'
systemProperty 'java.io.tmpdir', es_tmp_dir.absolutePath
systemProperty "java.library.path", "$rootDir/jni/release"
systemProperty "java.library.path", "$rootDir/jniFaiss/release:$rootDir/jni/release"
// allows integration test classes to access test resource from project root path
systemProperty('project.root', project.rootDir.absolutePath)

Expand Down Expand Up @@ -204,12 +214,13 @@ testClusters.integTest {
debugPort += 1
}
}
systemProperty("java.library.path", "$rootDir/jni/release")
systemProperty("java.library.path", "$rootDir/jniFaiss/release:$rootDir/jni/release")
}

run {
useCluster project.testClusters.integTest
dependsOn buildJniLib
dependsOn buildJniNmsLib
dependsOn buildJniFaissLib
doFirst {
// There seems to be an issue when running multi node run or integ tasks with unicast_hosts
// not being written, the waitForAllConditions ensures it's written
Expand Down
6 changes: 3 additions & 3 deletions jni/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

cmake_minimum_required(VERSION 2.8)

project(KNNIndexV2_0_11)
project(KNNIndex_NMSLIB)

# Corner case. For CMake 2.8, there is no option to specify set(CMAKE_CXX_STANDARD 11). Instead, the flag manually needs
# to be set.
Expand All @@ -27,7 +27,7 @@ else()
endif()

# Target Library to be built
set(KNN_INDEX KNNIndexV2_0_11)
set(KNN_INDEX KNNIndex_NMSLIB_V2_0_11)
set(KNN_PACKAGE_NAME opendistro-knnlib)

# Check if similarity search exists
Expand Down Expand Up @@ -55,7 +55,7 @@ else()
endif()

# Compile the library
add_library(${KNN_INDEX} SHARED ${CMAKE_CURRENT_SOURCE_DIR}/src/com_amazon_opendistroforelasticsearch_knn_index_v2011_KNNIndex.cpp)
add_library(${KNN_INDEX} SHARED ${CMAKE_CURRENT_SOURCE_DIR}/src/com_amazon_opendistroforelasticsearch_knn_index_nmslib_v2011_KNNNmsLibIndex.cpp)
target_link_libraries(${KNN_INDEX} NonMetricSpaceLib)
target_include_directories(${KNN_INDEX} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include $ENV{JAVA_HOME}/include $ENV{JAVA_HOME}/include/${JVM_OS_TYPE} ${CMAKE_CURRENT_SOURCE_DIR}/external/nmslib/similarity_search/include)

Expand Down
2 changes: 1 addition & 1 deletion jni/external/nmslib

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* permissions and limitations under the License.
*/

#include "com_amazon_opendistroforelasticsearch_knn_index_v2011_KNNIndex.h"
#include "com_amazon_opendistroforelasticsearch_knn_index_nmslib_v2011_KNNNmsLibIndex.h"

#include "init.h"
#include "index.h"
Expand Down Expand Up @@ -85,7 +85,7 @@ void catch_cpp_exception_and_throw_java(JNIEnv* env)
}
}

JNIEXPORT void JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_v2011_KNNIndex_saveIndex(JNIEnv* env, jclass cls, jintArray ids, jobjectArray vectors, jstring indexPath, jobjectArray algoParams, jstring spaceType)
JNIEXPORT void JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_nmslib_v2011_KNNNmsLibIndex_saveIndex(JNIEnv* env, jclass cls, jintArray ids, jobjectArray vectors, jstring indexPath, jobjectArray algoParams, jstring spaceType)
{
Space<float>* space = NULL;
ObjectVector dataset;
Expand Down Expand Up @@ -144,7 +144,7 @@ JNIEXPORT void JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_v201
}
}

JNIEXPORT jobjectArray JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_v2011_KNNIndex_queryIndex(JNIEnv* env, jclass cls, jlong indexPointer, jfloatArray queryVector, jint k)
JNIEXPORT jobjectArray JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_nmslib_v2011_KNNNmsLibIndex_queryIndex(JNIEnv* env, jclass cls, jlong indexPointer, jfloatArray queryVector, jint k)
{
try {
IndexWrapper *indexWrapper = reinterpret_cast<IndexWrapper*>(indexPointer);
Expand Down Expand Up @@ -175,7 +175,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_amazon_opendistroforelasticsearch_knn_in
return NULL;
}

JNIEXPORT jlong JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_v2011_KNNIndex_init(JNIEnv* env, jclass cls, jstring indexPath, jobjectArray algoParams, jstring spaceType)
JNIEXPORT jlong JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_nmslib_v2011_KNNNmsLibIndex_init(JNIEnv* env, jclass cls, jstring indexPath, jobjectArray algoParams, jstring spaceType)
{
IndexWrapper *indexWrapper = NULL;
try {
Expand Down Expand Up @@ -215,7 +215,7 @@ JNIEXPORT jlong JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_v20
return NULL;
}

JNIEXPORT void JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_v2011_KNNIndex_gc(JNIEnv* env, jclass cls, jlong indexPointer)
JNIEXPORT void JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_nmslib_v2011_KNNNmsLibIndex_gc(JNIEnv* env, jclass cls, jlong indexPointer)
{
try {
IndexWrapper *indexWrapper = reinterpret_cast<IndexWrapper*>(indexPointer);
Expand All @@ -228,7 +228,7 @@ JNIEXPORT void JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_v201
}
}

JNIEXPORT void JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_v2011_KNNIndex_initLibrary(JNIEnv *, jclass)
JNIEXPORT void JNICALL Java_com_amazon_opendistroforelasticsearch_knn_index_nmslib_v2011_KNNNmsLibIndex_initLibrary(JNIEnv *, jclass)
{
initLibrary();

Expand Down
108 changes: 108 additions & 0 deletions jniFaiss/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
cmake_minimum_required(VERSION 2.8)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design question: Should we have separate JNI libraries for FAISS and nmslib, or should they be contained in one?

Copy link
Author

@luyuncheng luyuncheng Jan 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am not sure which is better.
At this, i separate libraries just to elaborate this faiss engine can work with knn-plugin.
may be one jni interface can make jni code more simple to maintain

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel having seperate JNI would be more cleaner and easy to abstract out the underlying business logic to dedicated files. I like the current approach.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having 2 separate libraries is okay.


project(KNNIndex_FAISS)
jmazanec15 marked this conversation as resolved.
Show resolved Hide resolved

# Corner case. For CMake 2.8, there is no option to specify set(CMAKE_CXX_STANDARD 11). Instead, the flag manually needs
# to be set.
if (CMAKE_VERSION VERSION_LESS "3.1")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
endif()

# Target Library to be built
set(KNN_INDEX KNNIndex_FAISS_V1_6_5)
set(KNN_PACKAGE_NAME opendistro-knnlib)

# --- FAISS BEGIN ---
if (${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
if(CMAKE_C_COMPILER_ID MATCHES "Clang\$")
set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp")
set(OpenMP_C_LIB_NAMES "omp")
set(OpenMP_omp_LIBRARY /usr/local/opt/libomp/lib/libomp.dylib)
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang\$")
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I/usr/local/opt/libomp/include")
set(OpenMP_CXX_LIB_NAMES "omp")
set(OpenMP_omp_LIBRARY /usr/local/opt/libomp/lib/libomp.dylib)
endif()
endif()

find_package(OpenMP REQUIRED)
find_package(ZLIB REQUIRED)
find_package(BLAS REQUIRED)
find_package(LAPACK REQUIRED)

# Check if faiss search exists
find_path(FAISS_REPO_DIR NAMES faiss PATHS ${CMAKE_CURRENT_SOURCE_DIR}/external/faiss)

# If not, pull the updated submodule
if (NOT EXISTS ${FAISS_REPO_DIR})
message(STATUS "Could not find faiss. Pulling updated submodule.")
execute_process(COMMAND git submodule update --init -- external/faiss WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endif ()

# Add the subdirectory so it is possible to use its targets
set(FAISS_ENABLE_GPU OFF)
set(FAISS_ENABLE_PYTHON OFF)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/faiss EXCLUDE_FROM_ALL)
# --- FAISS END

# Set OS specific variables
if (${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
set(CMAKE_MACOSX_RPATH 1)
set(JVM_OS_TYPE darwin)
set(LIB_EXT .jnilib)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
set(JVM_OS_TYPE linux)
set(LIB_EXT .so)
else()
message( FATAL_ERROR "Unable to run on system: ${CMAKE_SYSTEM_NAME}")
endif()

# Compile the library
include_directories($ENV{JAVA_HOME}/include )
add_library(${KNN_INDEX} SHARED ${CMAKE_CURRENT_SOURCE_DIR}/src/com_amazon_opendistroforelasticsearch_knn_index_faiss_v165_KNNFaissIndex.cpp)
target_link_libraries(${KNN_INDEX} faiss ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES} OpenMP::OpenMP_CXX)
target_include_directories(${KNN_INDEX} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include $ENV{JAVA_HOME}/include $ENV{JAVA_HOME}/include/${JVM_OS_TYPE} ${CMAKE_CURRENT_SOURCE_DIR}/external/faiss/faiss )

set_target_properties(${KNN_INDEX} PROPERTIES SUFFIX ${LIB_EXT})
set_target_properties(${KNN_INDEX} PROPERTIES POSITION_INDEPENDENT_CODE ON)
set_target_properties(${KNN_INDEX} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/release)

# Installation rules for shared library
install(TARGETS ${KNN_INDEX}
LIBRARY DESTINATION lib
COMPONENT library)

# CPack section to build artifacts
set(KNN_MAINTAINER "OpenDistro for Elasticsearch Team <[email protected]>")
set(ODFE_DOWNLOAD_URL "https://opendistro.github.io/elasticsearch/downloads")
set(CPACK_PACKAGE_NAME ${KNN_PACKAGE_NAME})
set(CPACK_PACKAGE_VERSION 1.12.0.0)
set(CMAKE_INSTALL_PREFIX /usr)
set(CPACK_GENERATOR "RPM;DEB")
SET(CPACK_OUTPUT_FILE_PREFIX packages)
set(CPACK_PACKAGE_RELEASE 1)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "KNN JNI library built off of Faiss for OpenDistro for Elasticsearch. Reference documentation can be found at https://opendistro.github.io/for-elasticsearch-docs/.")
set(CPACK_PACKAGE_VENDOR "Amazon")
set(CPACK_PACKAGE_CONTACT "Maintainer: ${KNN_MAINTAINER}")
set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_PACKAGE_RELEASE}_${JVM_OS_TYPE}.${CMAKE_SYSTEM_PROCESSOR}")

# RPM Specific variables
set(CPACK_RPM_PACKAGE_RELEASE ${CPACK_PACKAGE_RELEASE})
set(CPACK_RPM_PACKAGE_URL ${ODFE_DOWNLOAD_URL})
set(CPACK_RPM_PACKAGE_DESCRIPTION "Open Distro for Elasticsearch KNN Faiss JNI Library")
set(CPACK_RPM_PACKAGE_LICENSE "ASL-2.0")

# DEB Specific variables
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE ${ODFE_DOWNLOAD_URL})
set(CPACK_DEBIAN_PACKAGE_MAINTAINER ${KNN_MAINTAINER})
set(CPACK_DEBIAN_PACKAGE_SOURCE ${CPACK_PACKAGE_NAME})
set(CPACK_DEBIAN_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
set(CPACK_DEBIAN_PACKAGE_SECTION "libs")

include(CPack)
1 change: 1 addition & 0 deletions jniFaiss/external/faiss
Submodule faiss added at 88eabe

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading