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 10 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
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
32 changes: 24 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -120,21 +120,37 @@ 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 cmakeJniLib() {
dependsOn cmakeJniNmsLib
dependsOn cmakeJniFaissLib
}
task buildJniNmsLib(type:Exec) {
dependsOn cmakeJniNmsLib
workingDir 'jni'
commandLine 'make'
}

task buildJniFaissLib(type:Exec) {
dependsOn cmakeJniFaissLib
workingDir 'jniFaiss'
commandLine 'make'
}
task buildJniLib() {
dependsOn cmakeJniLib
dependsOn buildJniNmsLib
dependsOn buildJniFaissLib
}
Copy link
Member

Choose a reason for hiding this comment

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

You could remove dependsOn cmakeJniLib and just rely on dependsOn buildJniNmsLib dependsOn buildJniFaissLib as they internally depends on cmakeJniNmsLib and cmakeJniFaissLib

Copy link
Author

Choose a reason for hiding this comment

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

Thanks, I fixed it

test {
dependsOn buildJniLib
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
Expand All @@ -144,7 +160,7 @@ integTest {
}
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 @@ -183,7 +199,7 @@ testClusters.integTest {
debugPort += 1
}
}
systemProperty("java.library.path", "$rootDir/jni/release")
systemProperty("java.library.path", "$rootDir/jniFaiss/release:$rootDir/jni/release")
}

run {
Expand Down
144 changes: 144 additions & 0 deletions jniFaiss/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
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(KNNIndexVFaiss)

# 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 KNNIndexVFaiss)
set(KNN_PACKAGE_NAME opendistro-knnlib)

# --- NMSLIB BEGIN ---
# Check if similarity search exists
#find_path(NMS_REPO_DIR NAMES similarity_search PATHS ${CMAKE_CURRENT_SOURCE_DIR}/external/nmslib)

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

# Add the subdirectory so it is possible to use its targets
#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/nmslib/similarity_search EXCLUDE_FROM_ALL)
# --- NMSLIB END ---

# --- FAISS BEGIN ---
# Check if faiss search exists
find_path(NMS_REPO_DIR NAMES faiss PATHS ${CMAKE_CURRENT_SOURCE_DIR}/external/faiss)

# If not, pull the updated submodule
if (NOT EXISTS ${NMS_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 ()

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/external/faiss/)
set(FIASSLIB ${CMAKE_CURRENT_SOURCE_DIR}/external/libfaiss.a)

set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_COMPILER "/usr/bin/gcc")
set(CMAKE_CXX_COMPILER "/usr/bin/g++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_RELEASE} -fpermissive -std=c++11 -Wall -pthread -O3 -g")
find_package(ZLIB REQUIRED)
find_package(BLAS REQUIRED)
find_package(LAPACK REQUIRED)

# ---- OPENMP BEGIN ----
OPTION (USE_OpenMP "Use OpenMP to enamble <omp.h>" ON)

# Find OpenMP
if(APPLE AND USE_OpenMP)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(OpenMP_C "${CMAKE_C_COMPILER}")
set(OpenMP_C_FLAGS "-fopenmp=libomp -Wno-unused-command-line-argument")
set(OpenMP_C_LIB_NAMES "libomp" "libgomp" "libiomp5")
set(OpenMP_libomp_LIBRARY ${OpenMP_C_LIB_NAMES})
set(OpenMP_libgomp_LIBRARY ${OpenMP_C_LIB_NAMES})
set(OpenMP_libiomp5_LIBRARY ${OpenMP_C_LIB_NAMES})
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(OpenMP_CXX "${CMAKE_CXX_COMPILER}")
set(OpenMP_CXX_FLAGS "-fopenmp=libomp -Wno-unused-command-line-argument")
set(OpenMP_CXX_LIB_NAMES "libomp" "libgomp" "libiomp5")
set(OpenMP_libomp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
set(OpenMP_libgomp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
set(OpenMP_libiomp5_LIBRARY ${OpenMP_CXX_LIB_NAMES})
endif()
endif()

if(USE_OpenMP)
find_package(OpenMP REQUIRED)
endif(USE_OpenMP)

if (OPENMP_FOUND)
#include_directories("${OPENMP_INCLUDES}")
link_directories("${OPENMP_LIBRARIES}")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
# set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif(OPENMP_FOUND)
# ---- OPENMP END ----
# --- 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
add_library(${KNN_INDEX} SHARED ${CMAKE_CURRENT_SOURCE_DIR}/src/com_amazon_opendistroforelasticsearch_knn_index_faiss_KNNFIndex.cpp)
target_link_libraries(${KNN_INDEX} ${FIASSLIB} ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
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 )

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 NMSLIB 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 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 3dd7ba
Binary file added jniFaiss/external/libfaiss.a
Binary file not shown.

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

Loading