From 1e72267a65d6bbbd43d11aa0d95aec678b2b6f77 Mon Sep 17 00:00:00 2001 From: Heisenberg-Y <35055583+Heisenberg-Y@users.noreply.github.com> Date: Sat, 28 Dec 2019 17:28:11 +0800 Subject: [PATCH] add cpu mode for built-in Faiss (#841) * add cpu mode for built-in Faiss * delete customization options on build stage * delete faiss version * delete customization options on build stage * fix unittest problem in cpu mode * fix unittest problem in cpu mode Co-authored-by: quicksilver Co-authored-by: Jin Hai --- CHANGELOG.md | 1 + ci/jenkins/step/build.groovy | 2 +- ci/scripts/build.sh | 10 ++----- core/CMakeLists.txt | 1 - core/build.sh | 7 +---- core/cmake/DefineOptions.cmake | 2 +- core/src/db/engine/ExecutionEngineImpl.cpp | 2 ++ core/src/index/CMakeLists.txt | 1 - core/src/index/cmake/DefineOptionsCore.cmake | 2 +- .../index/cmake/ThirdPartyPackagesCore.cmake | 24 ++++++++-------- .../index/thirdparty/faiss/InvertedLists.cpp | 28 +++++++++++++++++++ .../index/thirdparty/faiss/InvertedLists.h | 11 ++++++-- .../thirdparty/faiss/impl/index_read.cpp | 9 ++++-- .../thirdparty/faiss/impl/index_write.cpp | 9 ++++-- core/src/index/thirdparty/versions.txt | 1 - core/src/wrapper/VecIndex.cpp | 2 ++ core/unittest/db/test_db.cpp | 2 ++ 17 files changed, 75 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2410465470..38615bbeff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ Please mark all change in change log and use the issue from GitHub - \#738 - Use Openblas / lapack from apt install - \#758 - Enhance config description - \#791 - Remove Arrow +- \#834 - add cpu mode for built-in Faiss - \#848 - Add ready-to-use config files to the Milvus repo for enhanced user experince ## Task diff --git a/ci/jenkins/step/build.groovy b/ci/jenkins/step/build.groovy index aff5908900..b3a8a49278 100644 --- a/ci/jenkins/step/build.groovy +++ b/ci/jenkins/step/build.groovy @@ -4,7 +4,7 @@ timeout(time: 75, unit: 'MINUTES') { def checkResult = sh(script: "./check_ccache.sh -l ${params.JFROG_ARTFACTORY_URL}/ccache", returnStatus: true) if ("${BINARY_VERSION}" == "gpu") { - sh "/bin/bash --login -c \". ./before-install.sh && ./build.sh -t ${params.BUILD_TYPE} -o ${env.MILVUS_INSTALL_PREFIX} -l -g -x -u -c\"" + sh "/bin/bash --login -c \". ./before-install.sh && ./build.sh -t ${params.BUILD_TYPE} -o ${env.MILVUS_INSTALL_PREFIX} -l -g -u -c\"" } else { sh "/bin/bash --login -c \". ./before-install.sh && ./build.sh -t ${params.BUILD_TYPE} -o ${env.MILVUS_INSTALL_PREFIX} -l -u -c\"" } diff --git a/ci/scripts/build.sh b/ci/scripts/build.sh index 125677355b..f30644a3f2 100755 --- a/ci/scripts/build.sh +++ b/ci/scripts/build.sh @@ -17,14 +17,13 @@ BUILD_UNITTEST="OFF" INSTALL_PREFIX="/var/lib/milvus" FAISS_ROOT="" PRIVILEGES="OFF" -CUSTOMIZATION="OFF" # default use origin faiss BUILD_COVERAGE="OFF" RUN_CPPLINT="OFF" GPU_VERSION="OFF" WITH_MKL="OFF" CUDA_COMPILER=/usr/local/cuda/bin/nvcc -while getopts "o:t:b:f:pgxulcmh" arg +while getopts "o:t:b:f:pgulcmh" arg do case $arg in o) @@ -49,9 +48,6 @@ do echo "Build and run unittest cases" ; BUILD_UNITTEST="ON"; ;; - x) - CUSTOMIZATION="ON"; - ;; l) RUN_CPPLINT="ON" ;; @@ -71,7 +67,6 @@ parameter: -f: faiss root path -p: install command with elevated privileges -g: gpu version --x: milvus customization (default: OFF) -u: building unit test options(default: OFF) -l: run cpplint, clang-format and clang-tidy(default: OFF) -c: code coverage(default: OFF) @@ -79,7 +74,7 @@ parameter: -h: help usage: -./build.sh -o \${INSTALL_PREFIX} -t \${BUILD_TYPE} -b \${CORE_BUILD_DIR} -f \${FAISS_ROOT} [-p] [-g] [-x] [-u] [-l] [-c] [-m] [-h] +./build.sh -o \${INSTALL_PREFIX} -t \${BUILD_TYPE} -b \${CORE_BUILD_DIR} -f \${FAISS_ROOT} [-p] [-g] [-u] [-l] [-c] [-m] [-h] " exit 0 ;; @@ -104,7 +99,6 @@ CMAKE_CMD="cmake \ -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ -DCMAKE_CUDA_COMPILER=${CUDA_COMPILER} \ -DMILVUS_GPU_VERSION=${GPU_VERSION} \ --DCUSTOMIZATION=${CUSTOMIZATION} \ -DBUILD_UNIT_TEST=${BUILD_UNITTEST} \ -DBUILD_COVERAGE=${BUILD_COVERAGE} \ -DFAISS_ROOT=${FAISS_ROOT} \ diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 4290bc74fd..b4b221a74b 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -160,7 +160,6 @@ if (MILVUS_USE_CCACHE) endif () if (CUSTOMIZATION) - set(MILVUS_GPU_VERSION ON) add_compile_definitions(CUSTOMIZATION) endif () diff --git a/core/build.sh b/core/build.sh index 5239e7060c..126fcc224a 100755 --- a/core/build.sh +++ b/core/build.sh @@ -9,7 +9,6 @@ BUILD_COVERAGE="OFF" DB_PATH="/tmp/milvus" PROFILING="OFF" RUN_CPPLINT="OFF" -CUSTOMIZATION="OFF" # default use ori faiss CUDA_COMPILER=/usr/local/cuda/bin/nvcc GPU_VERSION="OFF" #defaults to CPU version WITH_MKL="OFF" @@ -18,7 +17,7 @@ FAISS_SOURCE="BUNDLED" WITH_PROMETHEUS="ON" FIU_ENABLE="OFF" -while getopts "p:d:t:f:ulrcghxzmei" arg; do +while getopts "p:d:t:f:ulrcghzmei" arg; do case $arg in p) INSTALL_PREFIX=$OPTARG @@ -52,9 +51,6 @@ while getopts "p:d:t:f:ulrcghxzmei" arg; do z) PROFILING="ON" ;; - x) - CUSTOMIZATION="ON" - ;; g) GPU_VERSION="ON" ;; @@ -120,7 +116,6 @@ CMAKE_CMD="cmake \ -DBUILD_COVERAGE=${BUILD_COVERAGE} \ -DMILVUS_DB_PATH=${DB_PATH} \ -DMILVUS_ENABLE_PROFILING=${PROFILING} \ --DCUSTOMIZATION=${CUSTOMIZATION} \ -DMILVUS_GPU_VERSION=${GPU_VERSION} \ -DFAISS_WITH_MKL=${WITH_MKL} \ -DMILVUS_WITH_PROMETHEUS=${WITH_PROMETHEUS} \ diff --git a/core/cmake/DefineOptions.cmake b/core/cmake/DefineOptions.cmake index 8f5a42420a..164856866b 100644 --- a/core/cmake/DefineOptions.cmake +++ b/core/cmake/DefineOptions.cmake @@ -45,7 +45,7 @@ set_option_category("Milvus Build Option") define_option(MILVUS_GPU_VERSION "Build GPU version" OFF) -define_option(CUSTOMIZATION "Build with customized FAISS library" OFF) +define_option(CUSTOMIZATION "Build with customized FAISS library" ON) #---------------------------------------------------------------------- set_option_category("Thirdparty") diff --git a/core/src/db/engine/ExecutionEngineImpl.cpp b/core/src/db/engine/ExecutionEngineImpl.cpp index 838346695d..b9dbd327ac 100644 --- a/core/src/db/engine/ExecutionEngineImpl.cpp +++ b/core/src/db/engine/ExecutionEngineImpl.cpp @@ -120,6 +120,7 @@ ExecutionEngineImpl::CreatetVecIndex(EngineType type) { break; } #ifdef CUSTOMIZATION +#ifdef MILVUS_GPU_VERSION case EngineType::FAISS_IVFSQ8H: { if (gpu_resource_enable) { index = GetVecIndexFactory(IndexType::FAISS_IVFSQ8_HYBRID); @@ -128,6 +129,7 @@ ExecutionEngineImpl::CreatetVecIndex(EngineType type) { } break; } +#endif #endif case EngineType::FAISS_PQ: { #ifdef MILVUS_GPU_VERSION diff --git a/core/src/index/CMakeLists.txt b/core/src/index/CMakeLists.txt index 5664694155..d020104d6d 100644 --- a/core/src/index/CMakeLists.txt +++ b/core/src/index/CMakeLists.txt @@ -73,7 +73,6 @@ include(DefineOptionsCore) include(BuildUtilsCore) if (CUSTOMIZATION) - set(MILVUS_GPU_VERSION ON) add_compile_definitions(CUSTOMIZATION) endif () diff --git a/core/src/index/cmake/DefineOptionsCore.cmake b/core/src/index/cmake/DefineOptionsCore.cmake index 1777fdbe8e..3ada0e2a35 100644 --- a/core/src/index/cmake/DefineOptionsCore.cmake +++ b/core/src/index/cmake/DefineOptionsCore.cmake @@ -49,7 +49,7 @@ else () define_option(KNOWHERE_GPU_VERSION "Build GPU version" OFF) endif () -define_option(CUSTOMIZATION "Build with customized FAISS library" OFF) +define_option(CUSTOMIZATION "Build with customized FAISS library" ON) #---------------------------------------------------------------------- set_option_category("Thirdparty") diff --git a/core/src/index/cmake/ThirdPartyPackagesCore.cmake b/core/src/index/cmake/ThirdPartyPackagesCore.cmake index b905aed355..1bb042cd23 100644 --- a/core/src/index/cmake/ThirdPartyPackagesCore.cmake +++ b/core/src/index/cmake/ThirdPartyPackagesCore.cmake @@ -206,11 +206,6 @@ foreach (_VERSION_ENTRY ${TOOLCHAIN_VERSIONS_TXT}) endforeach () set(FAISS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/faiss) -if (DEFINED ENV{FAISS_SOURCE_URL}) - set(FAISS_SOURCE_URL "$ENV{FAISS_SOURCE_URL}") -else () - set(FAISS_SOURCE_URL "https://github.com/JinHai-CN/faiss/archive/${FAISS_VERSION}.tar.gz") -endif () if (DEFINED ENV{KNOWHERE_ARROW_URL}) set(ARROW_SOURCE_URL "$ENV{KNOWHERE_ARROW_URL}") @@ -467,15 +462,16 @@ macro(build_faiss) "--with-cuda-arch=-gencode=arch=compute_60,code=sm_60 -gencode=arch=compute_61,code=sm_61 -gencode=arch=compute_70,code=sm_70 -gencode=arch=compute_75,code=sm_75" ) else () - set(FAISS_CONFIGURE_ARGS ${FAISS_CONFIGURE_ARGS} --without-cuda) + set(FAISS_CONFIGURE_ARGS ${FAISS_CONFIGURE_ARGS} + "CPPFLAGS=-DUSE_CPU" + --without-cuda) endif () - if (CUSTOMIZATION) + if (DEFINED ENV{FAISS_SOURCE_URL}) + set(FAISS_SOURCE_URL "$ENV{FAISS_SOURCE_URL}") externalproject_add(faiss_ep - DOWNLOAD_COMMAND - "" - SOURCE_DIR - ${FAISS_SOURCE_DIR} + URL + ${FAISS_SOURCE_URL} ${EP_LOG_OPTIONS} CONFIGURE_COMMAND "./configure" @@ -490,8 +486,10 @@ macro(build_faiss) ${FAISS_STATIC_LIB}) else () externalproject_add(faiss_ep - URL - ${FAISS_SOURCE_URL} + DOWNLOAD_COMMAND + "" + SOURCE_DIR + ${FAISS_SOURCE_DIR} ${EP_LOG_OPTIONS} CONFIGURE_COMMAND "./configure" diff --git a/core/src/index/thirdparty/faiss/InvertedLists.cpp b/core/src/index/thirdparty/faiss/InvertedLists.cpp index 86a9d6c711..8636b89efd 100644 --- a/core/src/index/thirdparty/faiss/InvertedLists.cpp +++ b/core/src/index/thirdparty/faiss/InvertedLists.cpp @@ -14,6 +14,8 @@ #include #include + +#ifndef USE_CPU #include "gpu/utils/DeviceUtils.h" #include "cuda.h" #include "cuda_runtime.h" @@ -47,6 +49,7 @@ PageLockMemory::PageLockMemory(PageLockMemory &&other) { other.nbytes = 0; } } +#endif namespace faiss { @@ -257,6 +260,11 @@ ReadOnlyArrayInvertedLists::ReadOnlyArrayInvertedLists(size_t nlist, auto total_size = std::accumulate(readonly_length.begin(), readonly_length.end(), 0); readonly_offset.reserve(nlist); +#ifdef USE_CPU + readonly_codes.reserve(total_size * code_size); + readonly_ids.reserve(total_size); +#endif + size_t offset = 0; for (auto i=0; i readonly_codes; std::vector readonly_ids; +#endif readonly_length.reserve(nlist); size_t offset = 0; for (auto& list_ids : other.ids) { @@ -281,6 +291,7 @@ ReadOnlyArrayInvertedLists::ReadOnlyArrayInvertedLists(const ArrayInvertedLists& readonly_codes.insert(readonly_codes.end(), list_codes.begin(), list_codes.end()); } +#ifndef USE_CPU // convert to page-lock memory { size_t size = readonly_codes.size() * sizeof(uint8_t); @@ -292,6 +303,7 @@ ReadOnlyArrayInvertedLists::ReadOnlyArrayInvertedLists(const ArrayInvertedLists& pin_readonly_ids = std::make_shared(size); memcpy(pin_readonly_ids->data, readonly_ids.data(), size); } +#endif valid = true; } @@ -352,25 +364,41 @@ size_t ReadOnlyArrayInvertedLists::list_size(size_t list_no) const const uint8_t * ReadOnlyArrayInvertedLists::get_codes (size_t list_no) const { FAISS_ASSERT(list_no < nlist && valid); +#ifdef USE_CPU + return readonly_codes.data() + readonly_offset[list_no] * code_size; +#else uint8_t *pcodes = (uint8_t *)(pin_readonly_codes->data); return pcodes + readonly_offset[list_no] * code_size; +#endif } const InvertedLists::idx_t* ReadOnlyArrayInvertedLists::get_ids (size_t list_no) const { FAISS_ASSERT(list_no < nlist && valid); +#ifdef USE_CPU + return readonly_ids.data() + readonly_offset[list_no]; +#else idx_t *pids = (idx_t *)pin_readonly_ids->data; return pids + readonly_offset[list_no]; +#endif } const InvertedLists::idx_t* ReadOnlyArrayInvertedLists::get_all_ids() const { FAISS_ASSERT(valid); +#ifdef USE_CPU + return readonly_ids.data(); +#else return (idx_t *)(pin_readonly_ids->data); +#endif } const uint8_t* ReadOnlyArrayInvertedLists::get_all_codes() const { FAISS_ASSERT(valid); +#ifdef USE_CPU + return readonly_codes.data(); +#else return (uint8_t *)(pin_readonly_codes->data); +#endif } const std::vector& ReadOnlyArrayInvertedLists::get_list_length() const { diff --git a/core/src/index/thirdparty/faiss/InvertedLists.h b/core/src/index/thirdparty/faiss/InvertedLists.h index 1e0d84d5d0..9df0cb63dc 100644 --- a/core/src/index/thirdparty/faiss/InvertedLists.h +++ b/core/src/index/thirdparty/faiss/InvertedLists.h @@ -19,6 +19,8 @@ #include #include + +#ifndef USE_CPU namespace faiss { struct PageLockMemory { @@ -42,6 +44,7 @@ public: }; using PageLockMemoryPtr = std::shared_ptr; } +#endif namespace faiss { @@ -232,10 +235,14 @@ struct ArrayInvertedLists: InvertedLists { }; struct ReadOnlyArrayInvertedLists: InvertedLists { +#ifdef USE_CPU + std::vector readonly_codes; + std::vector readonly_ids; +#else PageLockMemoryPtr pin_readonly_codes; PageLockMemoryPtr pin_readonly_ids; -// std::vector readonly_codes; -// std::vector readonly_ids; +#endif + std::vector readonly_length; std::vector readonly_offset; bool valid; diff --git a/core/src/index/thirdparty/faiss/impl/index_read.cpp b/core/src/index/thirdparty/faiss/impl/index_read.cpp index 8e977a323c..c092aa89dc 100644 --- a/core/src/index/thirdparty/faiss/impl/index_read.cpp +++ b/core/src/index/thirdparty/faiss/impl/index_read.cpp @@ -211,12 +211,17 @@ InvertedLists *read_InvertedLists (IOReader *f, int io_flags) { auto ails = new ReadOnlyArrayInvertedLists(nlist, code_size, list_length); size_t n; READ1(n); -// ails->readonly_ids.resize(n); -// ails->readonly_codes.resize(n*code_size); +#ifdef USE_CPU + ails->readonly_ids.resize(n); + ails->readonly_codes.resize(n*code_size); + READANDCHECK(ails->readonly_ids.data(), n); + READANDCHECK(ails->readonly_codes.data(), n * code_size); +#else ails->pin_readonly_ids = std::make_shared(n * sizeof(InvertedLists::idx_t)); ails->pin_readonly_codes = std::make_shared(n * code_size * sizeof(uint8_t)); READANDCHECK((InvertedLists::idx_t *) ails->pin_readonly_ids->data, n); READANDCHECK((uint8_t *) ails->pin_readonly_codes->data, n * code_size); +#endif return ails; } else if (h == fourcc ("ilar") && !(io_flags & IO_FLAG_MMAP)) { auto ails = new ArrayInvertedLists (0, 0); diff --git a/core/src/index/thirdparty/faiss/impl/index_write.cpp b/core/src/index/thirdparty/faiss/impl/index_write.cpp index 10b1d07c33..c18f8021e0 100644 --- a/core/src/index/thirdparty/faiss/impl/index_write.cpp +++ b/core/src/index/thirdparty/faiss/impl/index_write.cpp @@ -245,12 +245,17 @@ void write_InvertedLists (const InvertedLists *ils, IOWriter *f) { WRITE1 (oa->nlist); WRITE1 (oa->code_size); WRITEVECTOR(oa->readonly_length); +#ifdef USE_CPU + size_t n = oa->readonly_ids.size(); + WRITE1(n); + WRITEANDCHECK(oa->readonly_ids.data(), n); + WRITEANDCHECK(oa->readonly_codes.data(), n * oa->code_size); +#else size_t n = oa->pin_readonly_ids->size() / sizeof(InvertedLists::idx_t); WRITE1(n); -// WRITEANDCHECK(oa->readonly_ids.data(), n); -// WRITEANDCHECK(oa->readonly_codes.data(), n * oa->code_size); WRITEANDCHECK((InvertedLists::idx_t *) oa->pin_readonly_ids->data, n); WRITEANDCHECK((uint8_t *) oa->pin_readonly_codes->data, n * oa->code_size); +#endif } else if (const auto & od = dynamic_cast(ils)) { uint32_t h = fourcc ("ilod"); diff --git a/core/src/index/thirdparty/versions.txt b/core/src/index/thirdparty/versions.txt index efcef26fa9..97bd625bc6 100644 --- a/core/src/index/thirdparty/versions.txt +++ b/core/src/index/thirdparty/versions.txt @@ -3,5 +3,4 @@ BOOST_VERSION=1.70.0 GTEST_VERSION=1.8.1 LAPACK_VERSION=v3.8.0 OPENBLAS_VERSION=v0.3.6 -FAISS_VERSION=1.6.0 MKL_VERSION=2019.5.281 diff --git a/core/src/wrapper/VecIndex.cpp b/core/src/wrapper/VecIndex.cpp index 824e5be13d..e6eb06d75b 100644 --- a/core/src/wrapper/VecIndex.cpp +++ b/core/src/wrapper/VecIndex.cpp @@ -170,6 +170,7 @@ GetVecIndexFactory(const IndexType& type, const Config& cfg) { #endif #ifdef CUSTOMIZATION +#ifdef MILVUS_GPU_VERSION case IndexType::FAISS_IVFSQ8_HYBRID: { server::Config& config = server::Config::GetInstance(); bool gpu_resource_enable = true; @@ -181,6 +182,7 @@ GetVecIndexFactory(const IndexType& type, const Config& cfg) { throw Exception(DB_ERROR, "No GPU resources for IndexType::FAISS_IVFSQ8_HYBRID"); } } +#endif #endif case IndexType::NSG_MIX: { // TODO(linxj): bug. index = std::make_shared(gpu_device); diff --git a/core/unittest/db/test_db.cpp b/core/unittest/db/test_db.cpp index 16d2d42db8..6262bda7d6 100644 --- a/core/unittest/db/test_db.cpp +++ b/core/unittest/db/test_db.cpp @@ -510,9 +510,11 @@ TEST_F(DBTest, INDEX_TEST) { ASSERT_TRUE(stat.ok()); #ifdef CUSTOMIZATION +#ifdef MILVUS_GPU_VERSION index.engine_type_ = (int)milvus::engine::EngineType::FAISS_IVFSQ8H; stat = db_->CreateIndex(table_info.table_id_, index); ASSERT_TRUE(stat.ok()); +#endif #endif milvus::engine::TableIndex index_out;