Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Google tests for unit testing jni #36

Merged
merged 41 commits into from
Jun 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
8845b9d
Initial commit to add faiss to jni
jmazanec15 May 24, 2021
e6690a5
add faiss submodule
jmazanec15 May 24, 2021
d8c299a
Minor changes to get library working
jmazanec15 May 24, 2021
ddc331c
Minor style improvements
jmazanec15 May 25, 2021
498b47d
Fix parameter null checks
jmazanec15 May 25, 2021
276cc32
Add util to get object from map or throw
jmazanec15 May 25, 2021
a5d1a19
Simplify faiss result parsing logic
jmazanec15 May 25, 2021
92d70c3
Improve memory safety
jmazanec15 May 25, 2021
9d1e958
Remove parameters parameter from query index
jmazanec15 May 25, 2021
22836c4
Initial gtest commit
jmazanec15 May 25, 2021
4013600
Add algorithm to fix build failure
jmazanec15 May 25, 2021
e5a1cb5
Minor cleanup to address comments
jmazanec15 May 26, 2021
2041807
fix flaky test
jmazanec15 May 26, 2021
9ffc046
Free vector after call completes
jmazanec15 May 26, 2021
f5a350c
Initial test commit
jmazanec15 May 27, 2021
9caeb0c
Add faiss create index test
jmazanec15 May 27, 2021
0800b83
Some refactoring
jmazanec15 May 27, 2021
199d5f2
Refactor jni utils into interface
jmazanec15 May 28, 2021
cc9a266
Merge branch 'faiss-initial' into google-tests
jmazanec15 May 31, 2021
8caa717
Use gmock for mocking jnienv
jmazanec15 May 31, 2021
e4ae199
add google test
jmazanec15 May 31, 2021
efc0aa3
Finalize faiss create index
jmazanec15 Jun 1, 2021
3e6c5fd
Merge branch 'faiss-develop' of github.com:opensearch-project/k-NN in…
jmazanec15 Jun 1, 2021
6f228a4
Fix includes
jmazanec15 Jun 2, 2021
86081d6
Enhance utils
jmazanec15 Jun 2, 2021
a54d8c3
Fix faiss tests
jmazanec15 Jun 2, 2021
6c4dcf5
Minor fix for faiss tests
jmazanec15 Jun 2, 2021
d1a004a
Make parameters variables
jmazanec15 Jun 2, 2021
c462af5
Minor clean up for faiss tests
jmazanec15 Jun 2, 2021
ee3a983
Put index wrapper struct in header
jmazanec15 Jun 2, 2021
c3f2e02
Add nmslib tests
jmazanec15 Jun 2, 2021
4d757b2
Add gitignore to tmp dir
jmazanec15 Jun 2, 2021
9006a83
Ignore googletest
jmazanec15 Jun 2, 2021
7c6983c
Remove test file
jmazanec15 Jun 2, 2021
e6bc46e
Add additional comments
jmazanec15 Jun 2, 2021
c736ac2
Use clang-form style=Google for formatting
jmazanec15 Jun 2, 2021
cee9356
Fix some leaks
jmazanec15 Jun 3, 2021
517f7d3
Remove faiss deny list file as it is redundant
jmazanec15 Jun 3, 2021
f1f5d5a
Remove comment
jmazanec15 Jun 3, 2021
888925d
Fix comment style caused by clang format
jmazanec15 Jun 3, 2021
a60d429
Add license to .gitignore
jmazanec15 Jun 3, 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
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,11 @@ jni/CPack*
jni/_CPack*
jni/release
jni/packages
jni/CTestTestfile.cmake
jni/KNNPlugin_JNI.cbp
jni/Testing/
jni/_deps/
jni/bin/
jni/lib/
jni/jni_test*
jni/googletest*
50 changes: 50 additions & 0 deletions jni/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/nmslib/similarity_search)
# ---------------------------------------------------------------------------

# ---------------------------------- FAISS ----------------------------------
# Avoid building faiss tests
set(BUILD_TESTING OFF)

if (${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
if(CMAKE_C_COMPILER_ID MATCHES "Clang\$")
set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp")
Expand Down Expand Up @@ -117,6 +120,53 @@ set_target_properties(${TARGET_LIB} PROPERTIES POSITION_INDEPENDENT_CODE ON)
set_target_properties(${TARGET_LIB} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/release)
# ---------------------------------------------------------------------------

# --------------------------------- TESTS -----------------------------------
# Reference - https://crascit.com/2015/07/25/cmake-gtest/
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/googletest-download"
)
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/googletest-download"
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

add_subdirectory("${CMAKE_BINARY_DIR}/googletest-src"
"${CMAKE_BINARY_DIR}/googletest-build"
)
add_executable(
jni_test
tests/faiss_wrapper_test.cpp
tests/nmslib_wrapper_test.cpp
tests/test_util.cpp)

target_link_libraries(
jni_test
gtest_main
gmock_main
faiss
NonMetricSpaceLib
${BLAS_LIBRARIES}
${LAPACK_LIBRARIES}
OpenMP::OpenMP_CXX
${TARGET_LIB}
)

target_include_directories(jni_test PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/tests
${CMAKE_CURRENT_SOURCE_DIR}/include
$ENV{JAVA_HOME}/include
$ENV{JAVA_HOME}/include/${JVM_OS_TYPE}
${CMAKE_CURRENT_SOURCE_DIR}/external/faiss
${CMAKE_CURRENT_SOURCE_DIR}/external/nmslib/similarity_search/include
${gtest_SOURCE_DIR}/include
${gmock_SOURCE_DIR}/include)


set_target_properties(jni_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)

# ---------------------------------------------------------------------------

# -------------------------------- INSTALL ----------------------------------
# Installation rules for shared library
install(TARGETS ${TARGET_LIB}
Expand Down
14 changes: 14 additions & 0 deletions jni/CMakeLists.txt.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 2.8.2)
project(googletest-download NONE)

include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
2 changes: 2 additions & 0 deletions jni/include/faiss_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#ifndef OPENSEARCH_KNN_FAISS_WRAPPER_H
#define OPENSEARCH_KNN_FAISS_WRAPPER_H

#include "jni_util.h"

#include <jni.h>

namespace knn_jni {
Expand Down
3 changes: 3 additions & 0 deletions jni/include/jni_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,10 @@ namespace knn_jni {

extern const std::string NPROBES;
extern const std::string COARSE_QUANTIZER;
extern const std::string M;
extern const std::string M_NMSLIB;
extern const std::string EF_CONSTRUCTION;
extern const std::string EF_CONSTRUCTION_NMSLIB;
extern const std::string EF_SEARCH;

// --------------------------------------------------------------------------
Expand Down
19 changes: 18 additions & 1 deletion jni/include/nmslib_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,15 @@
#ifndef OPENSEARCH_KNN_NMSLIB_WRAPPER_H
#define OPENSEARCH_KNN_NMSLIB_WRAPPER_H

#include <jni.h>
#include "jni_util.h"

#include "methodfactory.h"
#include "space.h"
#include "spacefactory.h"

#include <jni.h>
#include <string>

namespace knn_jni {
namespace nmslib_wrapper {
// Create an index with ids and vectors. The configuration is defined by values in the Java map, parametersJ.
Expand All @@ -38,6 +44,17 @@ namespace knn_jni {

// Perform required initialization operations for the library
void InitLibrary();

struct IndexWrapper {
explicit IndexWrapper(const std::string& spaceType) {
// Index gets constructed with a reference to data (see above) but is otherwise unused
similarity::ObjectVector data;
space.reset(similarity::SpaceFactoryRegistry<float>::Instance().CreateSpace(spaceType, similarity::AnyParams()));
index.reset(similarity::MethodFactoryRegistry<float>::Instance().CreateMethod(false, "hnsw", spaceType, *space, data));
}
std::unique_ptr<similarity::Space<float>> space;
std::unique_ptr<similarity::Index<float>> index;
};
}
}

Expand Down
6 changes: 3 additions & 3 deletions jni/src/faiss_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@
#include "jni_util.h"
#include "faiss_wrapper.h"

#include "faiss/impl/io.h"
#include "faiss/index_factory.h"
#include "faiss/MetaIndexes.h"
#include "faiss/index_io.h"
#include "faiss/IndexHNSW.h"
#include "faiss/IndexIVFFlat.h"
#include "faiss/MetaIndexes.h"

#include <algorithm>
#include <jni.h>
#include <vector>
#include <string>
#include <faiss/impl/io.h>
#include <vector>


// Translate space type to faiss metric
Expand Down
4 changes: 4 additions & 0 deletions jni/src/jni_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,5 +413,9 @@ const std::string knn_jni::NEG_DOT_PRODUCT = "negdotprod";

const std::string knn_jni::NPROBES = "nprobes";
const std::string knn_jni::COARSE_QUANTIZER = "coarse_quantizer";
const std::string knn_jni::M = "m";
const std::string knn_jni::M_NMSLIB = "M";
const std::string knn_jni::EF_CONSTRUCTION = "ef_construction";
const std::string knn_jni::EF_CONSTRUCTION_NMSLIB = "efConstruction";
const std::string knn_jni::EF_SEARCH = "ef_search";

35 changes: 12 additions & 23 deletions jni/src/nmslib_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
#include "jni_util.h"
#include "nmslib_wrapper.h"

#include <jni.h>
#include <string>

#include "init.h"
#include "index.h"
#include "params.h"
Expand All @@ -24,17 +21,9 @@
#include "spacefactory.h"
#include "space.h"

#include <jni.h>
#include <string>

struct IndexWrapper {
explicit IndexWrapper(const string& spaceType) {
// Index gets constructed with a reference to data (see above) but is otherwise unused
similarity::ObjectVector data;
space.reset(similarity::SpaceFactoryRegistry<float>::Instance().CreateSpace(spaceType, similarity::AnyParams()));
index.reset(similarity::MethodFactoryRegistry<float>::Instance().CreateMethod(false, "hnsw", spaceType, *space, data));
}
std::unique_ptr<similarity::Space<float>> space;
std::unique_ptr<similarity::Index<float>> index;
};

std::string TranslateSpaceType(const std::string& spaceType);

Expand All @@ -60,14 +49,14 @@ void knn_jni::nmslib_wrapper::CreateIndex(knn_jni::JNIUtilInterface * jniUtil, J
// Handle parameters
auto parametersCpp = jniUtil->ConvertJavaMapToCppMap(env, parametersJ);
std::vector<std::string> indexParameters;
if(parametersCpp.find("ef_construction") != parametersCpp.end()) {
auto efConstruction = jniUtil->ConvertJavaObjectToCppInteger(env, parametersCpp["ef_construction"]);
indexParameters.push_back("efConstruction=" + std::to_string(efConstruction));
if(parametersCpp.find(knn_jni::EF_CONSTRUCTION) != parametersCpp.end()) {
auto efConstruction = jniUtil->ConvertJavaObjectToCppInteger(env, parametersCpp[knn_jni::EF_CONSTRUCTION]);
indexParameters.push_back(knn_jni::EF_CONSTRUCTION_NMSLIB + "=" + std::to_string(efConstruction));
}

if(parametersCpp.find("m") != parametersCpp.end()) {
auto m = jniUtil->ConvertJavaObjectToCppInteger(env, parametersCpp["m"]);
indexParameters.push_back("M=" + std::to_string(m));
if(parametersCpp.find(knn_jni::M) != parametersCpp.end()) {
auto m = jniUtil->ConvertJavaObjectToCppInteger(env, parametersCpp[knn_jni::M]);
indexParameters.push_back(knn_jni::M_NMSLIB + "=" + std::to_string(m));
}
jniUtil->DeleteLocalRef(env, parametersJ);

Expand Down Expand Up @@ -160,9 +149,9 @@ jlong knn_jni::nmslib_wrapper::LoadIndex(knn_jni::JNIUtilInterface * jniUtil, JN
}

// Load index
IndexWrapper * indexWrapper;
knn_jni::nmslib_wrapper::IndexWrapper * indexWrapper;
try {
indexWrapper = new IndexWrapper(spaceTypeCpp);
indexWrapper = new knn_jni::nmslib_wrapper::IndexWrapper(spaceTypeCpp);
indexWrapper->index->LoadIndex(indexPathCpp);
indexWrapper->index->SetQueryTimeParams(similarity::AnyParams(queryParams));
} catch (...) {
Expand All @@ -184,7 +173,7 @@ jobjectArray knn_jni::nmslib_wrapper::QueryIndex(knn_jni::JNIUtilInterface * jni
throw std::runtime_error("Invalid pointer to index");
}

auto *indexWrapper = reinterpret_cast<IndexWrapper*>(indexPointerJ);
auto *indexWrapper = reinterpret_cast<knn_jni::nmslib_wrapper::IndexWrapper*>(indexPointerJ);

int dim = jniUtil->GetJavaFloatArrayLength(env, queryVectorJ);

Expand Down Expand Up @@ -223,7 +212,7 @@ jobjectArray knn_jni::nmslib_wrapper::QueryIndex(knn_jni::JNIUtilInterface * jni
}

void knn_jni::nmslib_wrapper::Free(jlong indexPointerJ) {
auto *indexWrapper = reinterpret_cast<IndexWrapper*>(indexPointerJ);
auto *indexWrapper = reinterpret_cast<knn_jni::nmslib_wrapper::IndexWrapper*>(indexPointerJ);
delete indexWrapper;
}

Expand Down
Loading