mirror of https://github.com/milvus-io/milvus.git
Flat binary search over APU (#6676)
Signed-off-by: ezeharia <ezeharia@gsitechnology.com> solve issue Support search over APU board #5202 support Tanimoto/Hamming Flat binary search over APU device . Search over APU can be done for FAISS_BIN_IDMAP engaine type only. Dependencies : build with FPGA (- a ) and APU (-w ) . build must contain FPGA flag . example : ./build.sh -a -w *** search is not possible without APU device conneted to a server .** Resolves: #5202pull/7307/head
parent
91af6ced97
commit
12f1d3c23c
|
@ -158,6 +158,12 @@ if (MILVUS_FPGA_VERSION)
|
|||
else ()
|
||||
message(STATUS "Building Milvus CPU version")
|
||||
endif ()
|
||||
if (MILVUS_APU_VERSION)
|
||||
message(STATUS "Building Milvus APU version")
|
||||
add_compile_definitions("MILVUS_APU_VERSION")
|
||||
else ()
|
||||
message(STATUS "Building Milvus CPU version")
|
||||
endif ()
|
||||
if (MILVUS_GPU_VERSION)
|
||||
message(STATUS "Building Milvus GPU version")
|
||||
add_compile_definitions("MILVUS_GPU_VERSION")
|
||||
|
@ -215,6 +221,11 @@ if (MILVUS_FPGA_VERSION)
|
|||
else ()
|
||||
set(FPGA_ENABLE "false")
|
||||
endif ()
|
||||
if (MILVUS_APU_VERSION)
|
||||
set(APU_ENABLE "true")
|
||||
else ()
|
||||
set(APU_ENABLE "false")
|
||||
endif ()
|
||||
if (MILVUS_GPU_VERSION)
|
||||
set(GPU_ENABLE "true")
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/conf/server_config.template
|
||||
|
|
|
@ -12,12 +12,13 @@ RUN_CPPLINT="OFF"
|
|||
CUDA_COMPILER=/usr/local/cuda/bin/nvcc
|
||||
GPU_VERSION="OFF" #defaults to CPU version
|
||||
FPGA_VERSION="OFF"
|
||||
APU_VERSION="OFF"
|
||||
WITH_MKL="OFF"
|
||||
WITH_PROMETHEUS="ON"
|
||||
FIU_ENABLE="OFF"
|
||||
BUILD_OPENBLAS="ON"
|
||||
|
||||
while getopts "p:d:t:f:ulrcgahzmei" arg; do
|
||||
while getopts "p:d:t:f:ulrcgahzmeiw" arg; do
|
||||
case $arg in
|
||||
p)
|
||||
INSTALL_PREFIX=$OPTARG
|
||||
|
@ -62,6 +63,9 @@ while getopts "p:d:t:f:ulrcgahzmei" arg; do
|
|||
a)
|
||||
FPGA_VERSION="ON"
|
||||
;;
|
||||
w)
|
||||
APU_VERSION="ON"
|
||||
;;
|
||||
h) # help
|
||||
echo "
|
||||
|
||||
|
@ -79,6 +83,7 @@ parameter:
|
|||
-e: build without prometheus(default: OFF)
|
||||
-i: build FIU_ENABLE(default: OFF)
|
||||
-a: build FPGA(default: OFF)
|
||||
-w: build APU(default: OFF )
|
||||
-h: help
|
||||
|
||||
usage:
|
||||
|
@ -114,6 +119,7 @@ CMAKE_CMD="cmake \
|
|||
-DENABLE_CPU_PROFILING=${PROFILING} \
|
||||
-DMILVUS_GPU_VERSION=${GPU_VERSION} \
|
||||
-DMILVUS_FPGA_VERSION=${FPGA_VERSION} \
|
||||
-DMILVUS_APU_VERSION=${APU_VERSION} \
|
||||
-DFAISS_WITH_MKL=${WITH_MKL} \
|
||||
-DMILVUS_WITH_PROMETHEUS=${WITH_PROMETHEUS} \
|
||||
-DMILVUS_WITH_FIU=${FIU_ENABLE} \
|
||||
|
|
|
@ -46,6 +46,9 @@ set_option_category("Milvus Build Option")
|
|||
define_option(MILVUS_GPU_VERSION "Build GPU version" OFF)
|
||||
|
||||
define_option(MILVUS_FPGA_VERSION "Build FPGA version" OFF)
|
||||
|
||||
define_option(MILVUS_APU_VERSION "Build APU version" OFF)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
set_option_category("Thirdparty")
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@ set(MILVUS_THIRDPARTY_DEPENDENCIES
|
|||
fiu
|
||||
AWS
|
||||
oatpp
|
||||
armadillo)
|
||||
armadillo
|
||||
apu)
|
||||
|
||||
message(STATUS "Using ${MILVUS_DEPENDENCY_SOURCE} approach to find dependencies")
|
||||
|
||||
|
@ -64,6 +65,8 @@ macro(build_dependency DEPENDENCY_NAME)
|
|||
build_aws()
|
||||
elseif("${DEPENDENCY_NAME}" STREQUAL "armadillo")
|
||||
build_armadillo()
|
||||
elseif("${DEPENDENCY_NAME}" STREQUAL "apu")
|
||||
build_apu()
|
||||
else ()
|
||||
message(FATAL_ERROR "Unknown thirdparty dependency to build: ${DEPENDENCY_NAME}")
|
||||
endif ()
|
||||
|
@ -339,6 +342,12 @@ else ()
|
|||
set(ARMADILLO_SOURCE_URL "https://gitlab.com/conradsnicta/armadillo-code/-/archive/9.900.x/armadillo-code-9.900.x.tar.gz")
|
||||
endif ()
|
||||
|
||||
if (DEFINED ENV{MILVUS_APU_URL})
|
||||
set(APU_SOURCE_URL "$ENV{MILVUS_APU_URL}")
|
||||
else ()
|
||||
set(APU_SOURCE_URL "${PROJECT_SOURCE_DIR}/thirdparty/gsi/gsl_sources_milvus/2.8.0/gsi_release_2_8_0.tar.gz")
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Google gtest
|
||||
|
||||
|
@ -1148,3 +1157,47 @@ if(MILVUS_FPGA_VERSION)
|
|||
${INSTALL_DIR}/lib/libarmadillo.so
|
||||
DESTINATION lib)
|
||||
endif()
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# APU-GSI
|
||||
|
||||
macro(build_apu)
|
||||
message(STATUS "Building APU from source")
|
||||
set(APU_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/apu_ep-prefix/src/apu_ep")
|
||||
set(APU_SHARED_LIB "${APU_PREFIX}/lib/libgsl.so")
|
||||
set (APU_LIBS "${APU_PREFIX}/lib")
|
||||
set(APU_INCLUDE_DIR "${APU_PREFIX}/include")
|
||||
|
||||
externalproject_add(apu_ep
|
||||
URL
|
||||
${APU_SOURCE_URL}
|
||||
${EP_LOG_OPTIONS}
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
|
||||
file(MAKE_DIRECTORY ${APU_INCLUDE_DIR})
|
||||
add_library(apu SHARED IMPORTED)
|
||||
|
||||
set_target_properties(apu
|
||||
PROPERTIES
|
||||
IMPORTED_GLOBAL TRUE
|
||||
IMPORTED_LOCATION "${APU_SHARED_LIB}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${APU_INCLUDE_DIR}")
|
||||
|
||||
add_dependencies(apu apu_ep)
|
||||
endmacro()
|
||||
|
||||
if (MILVUS_APU_VERSION)
|
||||
|
||||
resolve_dependency(apu)
|
||||
|
||||
get_target_property(APU_INCLUDE_DIR apu INTERFACE_INCLUDE_DIRECTORIES)
|
||||
include_directories(SYSTEM ${APU_INCLUDE_DIR})
|
||||
install(FILES
|
||||
${APU_PREFIX}/lib/libgsl.so
|
||||
DESTINATION lib)
|
||||
|
||||
|
||||
endif ()
|
||||
|
||||
|
|
|
@ -178,6 +178,19 @@ fpga:
|
|||
search_devices:
|
||||
- fpga0
|
||||
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# APU Config | Description | Type | Default |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# enable | Use APU devices or not. | Boolean | false |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# apu_devices | The number of APU devices exist for computation. | DeviceList | 1 |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
apu:
|
||||
enable: @APU_ENABLE@
|
||||
search_devices: 1
|
||||
|
||||
|
||||
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# Logs Config | Description | Type | Default |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <faiss/utils/ConcurrentBitset.h>
|
||||
//#include <scheduler/job/SearchJob.h>
|
||||
|
||||
#include "query/GeneralQuery.h"
|
||||
#include "utils/Json.h"
|
||||
|
@ -100,6 +101,9 @@ class ExecutionEngine {
|
|||
virtual Status
|
||||
CopyToCpu() = 0;
|
||||
|
||||
virtual Status
|
||||
CopyToApu(uint32_t i) = 0;
|
||||
|
||||
// virtual std::shared_ptr<ExecutionEngine>
|
||||
// Clone() = 0;
|
||||
|
||||
|
|
|
@ -38,6 +38,11 @@
|
|||
#include "knowhere/index/vector_index/fpga/IndexFPGAIVFPQ.h"
|
||||
#include "knowhere/index/vector_index/fpga/utils.h"
|
||||
#endif
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
#include <knowhere/index/vector_index/fpga/ApuInst.h>
|
||||
#include <knowhere/index/vector_index/fpga/GsiHammingIndex.h>
|
||||
#include <knowhere/index/vector_index/fpga/GsiTanimotoIndex.h>
|
||||
#endif
|
||||
#ifdef MILVUS_GPU_VERSION
|
||||
#include "knowhere/index/vector_index/gpu/GPUIndex.h"
|
||||
#include "knowhere/index/vector_index/gpu/IndexIVFSQHybrid.h"
|
||||
|
@ -59,7 +64,6 @@
|
|||
|
||||
namespace milvus {
|
||||
namespace engine {
|
||||
|
||||
namespace {
|
||||
|
||||
Status
|
||||
|
@ -636,6 +640,34 @@ ExecutionEngineImpl::CopyToFpga() {
|
|||
return Status::OK();
|
||||
}
|
||||
|
||||
Status
|
||||
ExecutionEngineImpl::CopyToApu(uint32_t row_count) {
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
|
||||
auto cache_index_ =
|
||||
std::static_pointer_cast<knowhere::VecIndex>(cache::FpgaCacheMgr::GetInstance()->GetItem(location_));
|
||||
bool already_in_cache = (cache_index_ != nullptr);
|
||||
|
||||
if (!already_in_cache) {
|
||||
cache::FpgaCacheMgr::GetInstance()->ClearCache(); // clear cache to support cache switch .
|
||||
std::shared_ptr<knowhere::GsiBaseIndex> gsi_index;
|
||||
// factory is needed here
|
||||
if (metric_type_ == MetricType::HAMMING)
|
||||
gsi_index = std::make_shared<knowhere::GsiHammingIndex>(dim_);
|
||||
else
|
||||
gsi_index = std::make_shared<knowhere::GsiTanimotoIndex>(dim_);
|
||||
|
||||
gsi_index->SetUids(index_->GetUids());
|
||||
gsi_index->CopyIndexToFpga(row_count, location_);
|
||||
index_ = gsi_index;
|
||||
FpgaCache();
|
||||
} else {
|
||||
index_ = cache_index_;
|
||||
}
|
||||
#endif
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
ExecutionEnginePtr
|
||||
ExecutionEngineImpl::BuildIndex(const std::string& location, EngineType engine_type) {
|
||||
LOG_ENGINE_DEBUG_ << "Build index file: " << location << " from: " << location_;
|
||||
|
@ -838,6 +870,5 @@ ExecutionEngineImpl::Init() {
|
|||
return Status::OK();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace engine
|
||||
} // namespace milvus
|
||||
|
|
|
@ -60,6 +60,9 @@ class ExecutionEngineImpl : public ExecutionEngine {
|
|||
Status
|
||||
CopyToFpga() override;
|
||||
|
||||
Status
|
||||
CopyToApu(uint32_t row_count) override;
|
||||
|
||||
#if 0
|
||||
Status
|
||||
GetVectorByID(const int64_t id, float* vector, bool hybrid) override;
|
||||
|
|
|
@ -70,6 +70,11 @@ if (MILVUS_FPGA_VERSION OR KNOWHERE_FPGA_VERSION)
|
|||
else ()
|
||||
message(STATUS "Building Knowhere CPU version")
|
||||
endif ()
|
||||
if (MILVUS_APU_VERSION OR KNOWHERE_APU_VERSION)
|
||||
add_compile_definitions("MILVUS_APU_VERSION")
|
||||
else ()
|
||||
message(STATUS "Building Knowhere CPU version")
|
||||
endif ()
|
||||
if (MILVUS_GPU_VERSION OR KNOWHERE_GPU_VERSION)
|
||||
message(STATUS "Building Knowhere GPU version")
|
||||
add_compile_definitions("MILVUS_GPU_VERSION")
|
||||
|
|
|
@ -47,6 +47,14 @@ if (MILVUS_FPGA_VERSION)
|
|||
else ()
|
||||
define_option(KNOWHERE_FPGA_VERSION "Build FPGA version" OFF)
|
||||
endif ()
|
||||
#-------------------------------------------------
|
||||
set_option_category("APU version")
|
||||
|
||||
if (MILVUS_APU_VERSION)
|
||||
define_option(KNOWHERE_APU_VERSION "Build APU version" ON)
|
||||
else ()
|
||||
define_option(KNOWHERE_APU_VERSION "Build APU version" OFF)
|
||||
endif ()
|
||||
#----------------------------------------------------------------------
|
||||
set_option_category("GPU version")
|
||||
|
||||
|
|
|
@ -80,16 +80,35 @@ if (MILVUS_FPGA_VERSION)
|
|||
armadillo
|
||||
${depend_libs}
|
||||
)
|
||||
|
||||
set(index_srcs ${index_srcs}
|
||||
knowhere/index/vector_index/fpga/Fpga.cpp
|
||||
knowhere/index/vector_index/fpga/IndexFPGAIVFPQ.cpp
|
||||
knowhere/index/vector_index/fpga/xilinx_c.cpp
|
||||
knowhere/index/vector_index/fpga/utils.cpp
|
||||
knowhere/index/vector_index/fpga/FpgaInst.cpp
|
||||
)
|
||||
)
|
||||
|
||||
endif ()
|
||||
|
||||
if (MILVUS_APU_VERSION)
|
||||
|
||||
set(depend_libs
|
||||
apu
|
||||
${depend_libs}
|
||||
)
|
||||
|
||||
set(index_srcs ${index_srcs}
|
||||
knowhere/index/vector_index/fpga/GsiBaseIndex.cpp
|
||||
knowhere/index/vector_index/fpga/GsiHammingIndex.cpp
|
||||
knowhere/index/vector_index/fpga/GsiTanimotoIndex.cpp
|
||||
knowhere/index/vector_index/fpga/Apu.cpp
|
||||
knowhere/index/vector_index/fpga/ApuInst.cpp
|
||||
)
|
||||
|
||||
endif ()
|
||||
|
||||
|
||||
if (KNOWHERE_GPU_VERSION)
|
||||
include_directories(${CUDA_INCLUDE_DIRS})
|
||||
link_directories("${CUDA_TOOLKIT_ROOT_DIR}/lib64")
|
||||
|
@ -109,7 +128,7 @@ if (KNOWHERE_GPU_VERSION)
|
|||
knowhere/index/vector_index/gpu/IndexIVFSQHybrid.cpp
|
||||
knowhere/index/vector_index/helpers/Cloner.cpp
|
||||
knowhere/index/vector_index/helpers/FaissGpuResourceMgr.cpp
|
||||
)
|
||||
)
|
||||
|
||||
endif ()
|
||||
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
#include "knowhere/index/vector_index/fpga/Apu.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include "knowhere/common/Exception.h"
|
||||
#include "utils/Log.h"
|
||||
|
||||
using milvus::GetThreadName;
|
||||
using milvus::LogOut;
|
||||
using milvus::knowhere::KnowhereException;
|
||||
|
||||
namespace Fpga {
|
||||
|
||||
ApuInterface::ApuInterface() {
|
||||
InitApu();
|
||||
}
|
||||
|
||||
void
|
||||
ApuInterface::InitApu() {
|
||||
unsigned int num_existing_cards = 0;
|
||||
unsigned int num_req_cards = 8;
|
||||
|
||||
gsi_prod_status_t status = gdl_init();
|
||||
if (status != GSI_SUCCESS) {
|
||||
KNOWHERE_THROW_MSG("Apu init failed. error code : " + std::to_string(status));
|
||||
}
|
||||
|
||||
status = gdl_context_count_get(&num_existing_cards);
|
||||
if (status != GSI_SUCCESS) {
|
||||
KNOWHERE_THROW_MSG("Apu failed to get number of cards. error code : " + std::to_string(status));
|
||||
}
|
||||
|
||||
struct gdl_context_desc cards_desc[GDL_MAX_NUM_CONTEXTS] = {0};
|
||||
status = gdl_context_desc_get(cards_desc, num_req_cards);
|
||||
if (status != GSI_SUCCESS) {
|
||||
KNOWHERE_THROW_MSG("Apu failed to get cards description. error code : " + std::to_string(status));
|
||||
}
|
||||
|
||||
unsigned int num_ready_cards = 0;
|
||||
gdl_context_handle_t cards_ids[GDL_MAX_NUM_CONTEXTS] = {0};
|
||||
for (unsigned int i = 0; i < num_existing_cards; ++i) {
|
||||
if (cards_desc[i].status == GDL_CONTEXT_READY) {
|
||||
cards_ids[num_ready_cards] = cards_desc[i].ctx_id;
|
||||
++num_ready_cards;
|
||||
}
|
||||
}
|
||||
num_req_cards = (num_req_cards > num_ready_cards) ? num_ready_cards : num_req_cards;
|
||||
LOG_ENGINE_DEBUG_ << "Apu available cards: " << num_req_cards;
|
||||
|
||||
gsl_ctx_ = NULL;
|
||||
unsigned int idx_first_occupied_card = 0;
|
||||
uint32_t max_num_threads = 0;
|
||||
while ((idx_first_occupied_card + num_req_cards) <= num_ready_cards) {
|
||||
status = gsl_create_context(&gsl_ctx_, &cards_ids[idx_first_occupied_card], num_req_cards, max_num_threads);
|
||||
if (0 == status) {
|
||||
break;
|
||||
} else if (ENOSYS == status) {
|
||||
break;
|
||||
}
|
||||
++idx_first_occupied_card;
|
||||
}
|
||||
|
||||
if (status != GSI_SUCCESS && status != ENOSYS) {
|
||||
KNOWHERE_THROW_MSG("Apu failed to create context. error code : " + std::to_string(status));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ApuInterface::PopulateApuParams(uint32_t dimention, uint32_t row_count, const std::string location) {
|
||||
num_bfeatures_ = dimention;
|
||||
num_records_ = row_count;
|
||||
location_ = location;
|
||||
num_bytes_in_rec_ = num_bfeatures_ / CHAR_BITS;
|
||||
}
|
||||
|
||||
void
|
||||
ApuInterface::createBdb() {
|
||||
size_t db_size = num_bytes_in_rec_ * num_records_;
|
||||
bdb_ = {.row_size = num_bfeatures_,
|
||||
.row_stride = num_bytes_in_rec_,
|
||||
.num_rows = num_records_,
|
||||
.rows_u1 = malloc(db_size)};
|
||||
|
||||
std::string records_file_name = location_ + ".rv";
|
||||
char* rec_file_name = &records_file_name[0];
|
||||
char* records_file_c = &(rec_file_name)[0];
|
||||
|
||||
size_t file_size = 0;
|
||||
std::ifstream fin(records_file_c, std::ifstream::in | std::ifstream::binary);
|
||||
if (fin.is_open()) {
|
||||
fin.seekg(8, std::ios::beg);
|
||||
file_size = fin.tellg();
|
||||
fin.read((char*)bdb_.rows_u1, db_size);
|
||||
fin.close();
|
||||
}
|
||||
|
||||
int status = 0;
|
||||
bdbh_ = 0;
|
||||
status = gsl_create_bdb(gsl_ctx_, &bdbh_, &bdb_);
|
||||
if (status != GSI_SUCCESS) {
|
||||
KNOWHERE_THROW_MSG("Apu failed create Bdb. error code : " + std::to_string(status));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ApuInterface::loadHammingSessionToApu() {
|
||||
session_hdl_ = NULL;
|
||||
int status = 0;
|
||||
|
||||
status = gsl_flat_hamming_create_search_session(gsl_ctx_, &session_hdl_, &hamming_desc_);
|
||||
if (status != GSI_SUCCESS) {
|
||||
KNOWHERE_THROW_MSG("Apu failed to create search session. error code : " + std::to_string(status));
|
||||
}
|
||||
|
||||
status = gsl_search_in_focus(session_hdl_);
|
||||
if (status != GSI_SUCCESS) {
|
||||
KNOWHERE_THROW_MSG("Apu failed to focus search session. error code : " + std::to_string(status));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ApuInterface::loadTanimotoSessionToApu() {
|
||||
session_hdl_ = NULL;
|
||||
int status = 0;
|
||||
|
||||
status = gsl_flat_tanimoto_create_search_session(gsl_ctx_, &session_hdl_, &tanimoto_desc_);
|
||||
if (status != GSI_SUCCESS) {
|
||||
KNOWHERE_THROW_MSG("Apu failed to create search session. error code : " + std::to_string(status));
|
||||
}
|
||||
status = gsl_search_in_focus(session_hdl_);
|
||||
if (status != GSI_SUCCESS) {
|
||||
KNOWHERE_THROW_MSG("Apu failed to focus search session. error code : " + std::to_string(status));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ApuInterface::Query(gsl_matrix_u32& indices, gsl_matrix_f32& distances, gsl_matrix_u1& queries, APU_METRIC_TYPE type) {
|
||||
int status;
|
||||
switch (type) {
|
||||
case APU_METRIC_TYPE::TANIMOTO: {
|
||||
auto start_t = std::chrono::steady_clock::now();
|
||||
status = gsl_flat_tanimoto_search_u1(session_hdl_, &indices, &distances, &queries);
|
||||
auto end_t = std::chrono::steady_clock::now();
|
||||
LOG_ENGINE_DEBUG_ << "Apu search time in microseconds: "
|
||||
<< std::chrono::duration_cast<std::chrono::microseconds>(end_t - start_t).count()
|
||||
<< " µs";
|
||||
break;
|
||||
}
|
||||
case APU_METRIC_TYPE::HAMMING:
|
||||
auto start_h = std::chrono::steady_clock::now();
|
||||
status = gsl_flat_hamming_search_u1(session_hdl_, &indices, &distances, &queries);
|
||||
auto end_h = std::chrono::steady_clock::now();
|
||||
LOG_ENGINE_DEBUG_ << "Apu search time in microseconds: "
|
||||
<< std::chrono::duration_cast<std::chrono::microseconds>(end_h - start_h).count()
|
||||
<< " µs";
|
||||
break;
|
||||
}
|
||||
if (status != GSI_SUCCESS) {
|
||||
KNOWHERE_THROW_MSG("Apu query Failed. error code : " + std::to_string(status));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ApuInterface::isLoadNeeded(std::string cur_location) {
|
||||
if (location_ == "") {
|
||||
return true;
|
||||
} else if (cur_location != location_) {
|
||||
cleanApuResources(APU_CLEAN_TYPE::NEW_DB);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ApuInterface::~ApuInterface() {
|
||||
cleanApuResources(APU_CLEAN_TYPE::FULL);
|
||||
}
|
||||
|
||||
void
|
||||
ApuInterface::cleanApuResources(APU_CLEAN_TYPE type) {
|
||||
switch (type) {
|
||||
case APU_CLEAN_TYPE::FULL:
|
||||
if (session_hdl_)
|
||||
gsl_search_session_destroy(session_hdl_);
|
||||
if (bdbh_)
|
||||
gsl_destroy_bdb(bdbh_);
|
||||
gdl_exit();
|
||||
break;
|
||||
case APU_CLEAN_TYPE::SESSION_HDL:
|
||||
if (session_hdl_)
|
||||
gsl_search_session_destroy(session_hdl_);
|
||||
break;
|
||||
case APU_CLEAN_TYPE::BDBH:
|
||||
gsl_destroy_bdb(bdbh_);
|
||||
break;
|
||||
case APU_CLEAN_TYPE::NEW_DB:
|
||||
if (session_hdl_)
|
||||
gsl_search_session_destroy(session_hdl_);
|
||||
if (bdbh_)
|
||||
gsl_destroy_bdb(bdbh_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ApuInterface::loadSeesionToApu(APU_METRIC_TYPE type) {
|
||||
switch (type) {
|
||||
case APU_METRIC_TYPE::TANIMOTO: {
|
||||
tanimoto_desc_ = {.typical_num_queries = NUM_QUERIES,
|
||||
.max_num_queries = NUM_QUERIES,
|
||||
.tanimoto_bdbh = bdbh_,
|
||||
.max_k = topK_};
|
||||
loadTanimotoSessionToApu();
|
||||
}
|
||||
case APU_METRIC_TYPE::HAMMING: {
|
||||
hamming_desc_ = {.typical_num_queries = NUM_QUERIES,
|
||||
.max_num_queries = NUM_QUERIES,
|
||||
.encoding = NULL,
|
||||
.hamming_bdbh = bdbh_,
|
||||
.max_k = topK_,
|
||||
.rerank = NULL};
|
||||
loadHammingSessionToApu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ApuInterface::getTopK() const {
|
||||
return topK_;
|
||||
}
|
||||
|
||||
void
|
||||
ApuInterface::setTopK(uint32_t topK) {
|
||||
topK_ = topK;
|
||||
}
|
||||
} // namespace Fpga
|
|
@ -0,0 +1,113 @@
|
|||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
#ifndef APU_H
|
||||
#define APU_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
extern "C" {
|
||||
#include <gsi/libgdl.h>
|
||||
#include <gsi/libgsl.h>
|
||||
#include <gsi/libgsl_flat_tanimoto.h>
|
||||
#include <gsi/libgsl_matrix.h>
|
||||
}
|
||||
|
||||
#define NUM_QUERIES (100)
|
||||
#define CHAR_BITS (8)
|
||||
#define INIT_K (50)
|
||||
#define GSI_SUCCESS (0)
|
||||
|
||||
namespace Fpga {
|
||||
|
||||
enum class APU_CLEAN_TYPE {
|
||||
SESSION_HDL = 0,
|
||||
BDBH = 1,
|
||||
FULL,
|
||||
NEW_DB,
|
||||
};
|
||||
|
||||
enum class APU_METRIC_TYPE {
|
||||
HAMMING = 0,
|
||||
TANIMOTO = 1,
|
||||
};
|
||||
|
||||
class ApuInterface {
|
||||
public:
|
||||
ApuInterface();
|
||||
|
||||
~ApuInterface();
|
||||
|
||||
void
|
||||
PopulateApuParams(uint32_t dimention, uint32_t row_count, const std::string location);
|
||||
|
||||
void
|
||||
createBdb();
|
||||
|
||||
void
|
||||
loadSeesionToApu(APU_METRIC_TYPE type);
|
||||
|
||||
void
|
||||
Query(gsl_matrix_u32& indices, gsl_matrix_f32& distances, gsl_matrix_u1& queries, APU_METRIC_TYPE type);
|
||||
|
||||
bool
|
||||
isLoadNeeded(std::string location_);
|
||||
|
||||
void
|
||||
cleanApuResources(APU_CLEAN_TYPE type);
|
||||
|
||||
uint32_t
|
||||
getTopK() const;
|
||||
|
||||
void
|
||||
setTopK(uint32_t topK);
|
||||
|
||||
private:
|
||||
gsl_bdb_hdl bdbh_ = NULL;
|
||||
|
||||
void
|
||||
InitApu();
|
||||
|
||||
void
|
||||
loadHammingSessionToApu();
|
||||
|
||||
void
|
||||
loadTanimotoSessionToApu();
|
||||
|
||||
std::string location_ = "";
|
||||
|
||||
uint32_t num_records_ = 0;
|
||||
|
||||
uint32_t num_bfeatures_ = 0;
|
||||
|
||||
uint32_t num_bytes_in_rec_ = 0;
|
||||
|
||||
gsl_context gsl_ctx_;
|
||||
|
||||
struct gsl_matrix_u1 bdb_;
|
||||
|
||||
gsl_search_session_hdl session_hdl_;
|
||||
|
||||
gsl_flat_hamming_desc hamming_desc_;
|
||||
|
||||
gsl_flat_tanimoto_desc tanimoto_desc_;
|
||||
|
||||
uint32_t topK_ = INIT_K;
|
||||
}; // namespace ApuInterface
|
||||
using ApuInterfacePtr = std::shared_ptr<ApuInterface>;
|
||||
} // namespace Fpga
|
||||
#endif // MILVUS_ENGINE_APU_H
|
||||
#endif
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
|
||||
#include "knowhere/index/vector_index/fpga/ApuInst.h"
|
||||
|
||||
namespace Fpga {
|
||||
ApuInterfacePtr ApuInst::instance = nullptr;
|
||||
|
||||
std::mutex ApuInst::mutex_;
|
||||
} // namespace Fpga
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include "Apu.h"
|
||||
|
||||
namespace Fpga {
|
||||
class ApuInst {
|
||||
public:
|
||||
static ApuInterfacePtr
|
||||
getInstance() {
|
||||
if (instance == nullptr) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (instance == nullptr) {
|
||||
instance = std::make_shared<ApuInterface>();
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private:
|
||||
static ApuInterfacePtr instance;
|
||||
|
||||
static std::mutex mutex_;
|
||||
};
|
||||
} // namespace Fpga
|
||||
#endif
|
|
@ -0,0 +1,130 @@
|
|||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
#include "knowhere/index/vector_index/fpga/GsiBaseIndex.h"
|
||||
#include <scheduler/job/SearchJob.h>
|
||||
#include <scheduler/task/SearchTask.h>
|
||||
#include <fstream>
|
||||
|
||||
namespace milvus {
|
||||
namespace knowhere {
|
||||
|
||||
GsiBaseIndex::GsiBaseIndex(uint32_t dim) {
|
||||
num_bfeatures_ = dim;
|
||||
}
|
||||
|
||||
GsiBaseIndex::~GsiBaseIndex() {
|
||||
// freeAllocatedMem();
|
||||
}
|
||||
|
||||
void
|
||||
GsiBaseIndex::AllocateMemory(const DatasetPtr& dataset, const Config& config) {
|
||||
// allocating memory for search queries
|
||||
setQueriesInfo(dataset, config);
|
||||
|
||||
// allocating memory for result indices
|
||||
setResultIndicesStruct();
|
||||
|
||||
// allocating memory for result distances
|
||||
setResultDistancesStruct();
|
||||
}
|
||||
|
||||
void
|
||||
GsiBaseIndex::setResultDistancesStruct() {
|
||||
distances_ = {.row_size = topK_,
|
||||
.row_stride = topK_ * sizeof(float),
|
||||
.num_rows = num_queries_,
|
||||
.rows_f32 = (float*)calloc(topK_ * num_queries_, sizeof(float))};
|
||||
if (NULL == distances_.rows_f32) {
|
||||
// ERROR("no memory to allocate.");
|
||||
}
|
||||
// heap_allocations[counter_heap_allocations++] = (void*)distances_.rows_f32;
|
||||
}
|
||||
|
||||
void
|
||||
GsiBaseIndex::setResultIndicesStruct() {
|
||||
indices_ = {.row_size = topK_,
|
||||
.row_stride = topK_ * sizeof(uint32_t),
|
||||
.num_rows = num_queries_,
|
||||
.rows_u32 = (uint32_t*)calloc(topK_ * num_queries_, sizeof(uint32_t))};
|
||||
if (NULL == indices_.rows_u32) {
|
||||
// ERROR("no memory to allocate.");
|
||||
}
|
||||
// heap_allocations[counter_heap_allocations++] = (void*)indices_.rows_u32;
|
||||
}
|
||||
|
||||
void
|
||||
GsiBaseIndex::setQueriesInfo(const DatasetPtr& dataset, const Config& config) {
|
||||
queries_ = {.row_size = num_bfeatures_,
|
||||
.row_stride = num_bytes_in_rec_,
|
||||
.num_rows = num_queries_,
|
||||
.rows_u1 = queries_.rows_u1 = (void*)dataset->Get<const void*>(meta::TENSOR)};
|
||||
// if (NULL == queries_.rows_u1){}
|
||||
}
|
||||
|
||||
void
|
||||
GsiBaseIndex::freeAllocatedMem() {
|
||||
std::cout << "cleaning APU allocation" << std::endl;
|
||||
// free((void*)indices_.rows_u32);
|
||||
// free((void*)distances_.rows_f32);
|
||||
|
||||
for (size_t i = 0; i < counter_heap_allocations; i++) free(heap_allocations[i]);
|
||||
}
|
||||
|
||||
int64_t*
|
||||
GsiBaseIndex::convertToInt64_t(gsl_matrix_u32* indices, int64_t* ids_int64) {
|
||||
uint32_t* indices_buff = NULL;
|
||||
int64_t* indices_buff_int64 = NULL;
|
||||
uint32_t stride_64 = topK_ * sizeof(int64_t);
|
||||
|
||||
for (unsigned int i = 0; i < num_queries_; ++i) {
|
||||
indices_buff = (uint32_t*)((char*)indices->rows_u32 + indices->row_stride * i);
|
||||
indices_buff_int64 = (int64_t*)((char*)ids_int64 + stride_64 * i);
|
||||
|
||||
for (unsigned int j = 0; j < topK_; ++j) indices_buff_int64[j] = (int64_t)indices_buff[j];
|
||||
}
|
||||
return ids_int64;
|
||||
}
|
||||
|
||||
BinarySet
|
||||
GsiBaseIndex::Serialize(const Config& config) {
|
||||
return BinarySet();
|
||||
}
|
||||
|
||||
void
|
||||
GsiBaseIndex::Load(const BinarySet& set) {
|
||||
}
|
||||
|
||||
void
|
||||
GsiBaseIndex::Train(const DatasetPtr& dataset, const Config& config) {
|
||||
}
|
||||
|
||||
void
|
||||
GsiBaseIndex::AddWithoutIds(const DatasetPtr& dataset, const Config& config) {
|
||||
}
|
||||
|
||||
int64_t
|
||||
GsiBaseIndex::Dim() {
|
||||
return num_bfeatures_;
|
||||
}
|
||||
|
||||
int64_t
|
||||
GsiBaseIndex::Count() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t
|
||||
GsiBaseIndex::Size() {
|
||||
return index_size_;
|
||||
}
|
||||
|
||||
} // namespace knowhere
|
||||
} // namespace milvus
|
|
@ -0,0 +1,110 @@
|
|||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
#pragma once
|
||||
|
||||
#include "index/knowhere/knowhere/index/vector_index/VecIndex.h"
|
||||
#include "knowhere/index/vector_index/helpers/IndexParameter.h"
|
||||
#include "scheduler/task/Task.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
extern "C" {
|
||||
#include <gsi/libgdl.h>
|
||||
#include <gsi/libgsl.h>
|
||||
#include <gsi/libgsl_flat_tanimoto.h>
|
||||
#include <gsi/libgsl_matrix.h>
|
||||
}
|
||||
|
||||
#define NUM_QUERIES (100)
|
||||
#define INIT_K (50)
|
||||
#define MAX_HEAP_ALLOCATIONS (4)
|
||||
#define O_RDONLY 00
|
||||
|
||||
namespace milvus {
|
||||
namespace knowhere {
|
||||
|
||||
class GsiBaseIndex : public VecIndex {
|
||||
public:
|
||||
uint32_t topK_ = INIT_K;
|
||||
|
||||
uint32_t num_queries_;
|
||||
|
||||
uint32_t num_bfeatures_;
|
||||
|
||||
uint32_t num_bytes_in_rec_;
|
||||
|
||||
int64_t index_size_;
|
||||
|
||||
void* heap_allocations[MAX_HEAP_ALLOCATIONS] = {0};
|
||||
|
||||
unsigned int counter_heap_allocations;
|
||||
|
||||
virtual int64_t
|
||||
Size();
|
||||
|
||||
BinarySet
|
||||
Serialize(const Config& config) override;
|
||||
|
||||
void
|
||||
Load(const BinarySet& set) override;
|
||||
|
||||
void
|
||||
Train(const DatasetPtr& dataset, const Config& config) override;
|
||||
|
||||
void
|
||||
AddWithoutIds(const DatasetPtr& dataset, const Config& config) override;
|
||||
|
||||
int64_t
|
||||
Dim() override;
|
||||
|
||||
int64_t
|
||||
Count() override;
|
||||
|
||||
explicit GsiBaseIndex(uint32_t dim);
|
||||
|
||||
~GsiBaseIndex();
|
||||
|
||||
virtual void
|
||||
CopyIndexToFpga(uint32_t row_count, const std::string& location) = 0;
|
||||
|
||||
virtual DatasetPtr
|
||||
Query(const DatasetPtr& dataset, const Config& config, faiss::ConcurrentBitsetPtr blacklist) = 0;
|
||||
|
||||
protected:
|
||||
void
|
||||
setResultDistancesStruct();
|
||||
|
||||
struct gsl_matrix_u32 indices_;
|
||||
|
||||
struct gsl_matrix_f32 distances_;
|
||||
|
||||
struct gsl_matrix_u1 queries_;
|
||||
|
||||
void
|
||||
AllocateMemory(const DatasetPtr& dataset, const Config& config);
|
||||
|
||||
void
|
||||
setQueriesInfo(const DatasetPtr& dataset, const Config& config);
|
||||
|
||||
void
|
||||
setResultIndicesStruct();
|
||||
|
||||
int64_t*
|
||||
convertToInt64_t(gsl_matrix_u32* indices, int64_t* ids_int64);
|
||||
|
||||
void
|
||||
freeAllocatedMem();
|
||||
};
|
||||
} // namespace knowhere
|
||||
} // namespace milvus
|
||||
#endif
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
|
||||
#include "knowhere/index/vector_index/fpga/GsiHammingIndex.h"
|
||||
#include "ApuInst.h"
|
||||
#include "scheduler/task/SearchTask.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace milvus {
|
||||
namespace knowhere {
|
||||
|
||||
void
|
||||
GsiHammingIndex::CopyIndexToFpga(uint32_t row_count, const std::string& location) {
|
||||
num_bfeatures_ = Dim();
|
||||
num_bytes_in_rec_ = num_bfeatures_ / CHAR_BITS;
|
||||
index_size_ = row_count * num_bytes_in_rec_;
|
||||
|
||||
auto apu = Fpga::ApuInst::getInstance();
|
||||
apu->cleanApuResources(Fpga::APU_CLEAN_TYPE::NEW_DB);
|
||||
apu->PopulateApuParams(num_bfeatures_, row_count, location);
|
||||
apu->createBdb();
|
||||
apu->loadSeesionToApu(Fpga::APU_METRIC_TYPE::HAMMING);
|
||||
}
|
||||
|
||||
DatasetPtr
|
||||
GsiHammingIndex::Query(const DatasetPtr& dataset, const Config& config, faiss::ConcurrentBitsetPtr blacklist) {
|
||||
auto apu = Fpga::ApuInst::getInstance();
|
||||
|
||||
num_bfeatures_ = Dim();
|
||||
num_queries_ = static_cast<uint32_t>(dataset.get()->Get<int64_t>(meta::ROWS));
|
||||
num_bytes_in_rec_ = num_bfeatures_ / CHAR_BITS;
|
||||
topK_ = config[meta::TOPK];
|
||||
|
||||
apu->setTopK(topK_);
|
||||
AllocateMemory(dataset, config);
|
||||
|
||||
apu->Query(indices_, distances_, queries_, Fpga::APU_METRIC_TYPE::HAMMING);
|
||||
|
||||
auto ret_ds = std::make_shared<Dataset>();
|
||||
int64_t* ids_int64 = (int64_t*)calloc(topK_ * num_queries_, sizeof(int64_t));
|
||||
convertToInt64_t(&indices_, ids_int64);
|
||||
|
||||
ret_ds->Set(meta::IDS, ids_int64);
|
||||
ret_ds->Set(meta::DISTANCE, distances_.rows_f32);
|
||||
free((void*)indices_.rows_u32);
|
||||
return ret_ds;
|
||||
}
|
||||
#endif
|
||||
} // namespace knowhere
|
||||
} // namespace milvus
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
#pragma once
|
||||
|
||||
#include "Apu.h"
|
||||
#include "GsiBaseIndex.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace milvus {
|
||||
namespace knowhere {
|
||||
|
||||
class GsiHammingIndex : public GsiBaseIndex {
|
||||
public:
|
||||
explicit GsiHammingIndex(uint32_t dim) : GsiBaseIndex(dim) {
|
||||
index_type_ = IndexEnum::INDEX_FAISS_BIN_IDMAP;
|
||||
}
|
||||
|
||||
void
|
||||
CopyIndexToFpga(uint32_t row_count, const std::string& location) override;
|
||||
|
||||
DatasetPtr
|
||||
Query(const DatasetPtr& dataset, const Config& config, faiss::ConcurrentBitsetPtr blacklist) override;
|
||||
};
|
||||
} // namespace knowhere
|
||||
} // namespace milvus
|
||||
#endif
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
#include "knowhere/index/vector_index/fpga/GsiTanimotoIndex.h"
|
||||
#include "ApuInst.h"
|
||||
#include "scheduler/task/SearchTask.h"
|
||||
|
||||
namespace milvus {
|
||||
namespace knowhere {
|
||||
|
||||
void
|
||||
GsiTanimotoIndex::CopyIndexToFpga(uint32_t row_count, const std::string& location) {
|
||||
num_bfeatures_ = Dim();
|
||||
num_bytes_in_rec_ = num_bfeatures_ / CHAR_BITS;
|
||||
index_size_ = row_count * num_bytes_in_rec_;
|
||||
|
||||
auto apu = Fpga::ApuInst::getInstance();
|
||||
apu->cleanApuResources(Fpga::APU_CLEAN_TYPE::NEW_DB);
|
||||
apu->PopulateApuParams(num_bfeatures_, row_count, location);
|
||||
apu->createBdb();
|
||||
apu->loadSeesionToApu(Fpga::APU_METRIC_TYPE::TANIMOTO);
|
||||
}
|
||||
|
||||
DatasetPtr
|
||||
GsiTanimotoIndex::Query(const DatasetPtr& dataset, const Config& config, faiss::ConcurrentBitsetPtr blacklist) {
|
||||
auto apu = Fpga::ApuInst::getInstance();
|
||||
|
||||
num_bfeatures_ = Dim();
|
||||
num_queries_ = static_cast<uint32_t>(dataset.get()->Get<int64_t>(meta::ROWS));
|
||||
num_bytes_in_rec_ = num_bfeatures_ / CHAR_BITS;
|
||||
topK_ = config[meta::TOPK];
|
||||
|
||||
apu->setTopK(topK_);
|
||||
AllocateMemory(dataset, config);
|
||||
|
||||
apu->Query(indices_, distances_, queries_, Fpga::APU_METRIC_TYPE::TANIMOTO);
|
||||
|
||||
auto ret_ds = std::make_shared<Dataset>();
|
||||
int64_t* ids_int64 = (int64_t*)calloc(topK_ * num_queries_, sizeof(int64_t));
|
||||
convertToInt64_t(&indices_, ids_int64);
|
||||
|
||||
ret_ds->Set(meta::IDS, ids_int64);
|
||||
ret_ds->Set(meta::DISTANCE, distances_.rows_f32);
|
||||
free((void*)indices_.rows_u32);
|
||||
return ret_ds;
|
||||
}
|
||||
|
||||
} // namespace knowhere
|
||||
} // namespace milvus
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
#pragma once
|
||||
|
||||
#include "Apu.h"
|
||||
#include "GsiBaseIndex.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace milvus {
|
||||
namespace knowhere {
|
||||
|
||||
class GsiTanimotoIndex : public GsiBaseIndex {
|
||||
public:
|
||||
explicit GsiTanimotoIndex(uint32_t dim) : GsiBaseIndex(dim) {
|
||||
index_type_ = IndexEnum::INDEX_FAISS_BIN_IDMAP;
|
||||
}
|
||||
|
||||
void
|
||||
CopyIndexToFpga(uint32_t row_count, const std::string& location) override;
|
||||
|
||||
DatasetPtr
|
||||
Query(const DatasetPtr& dataset, const Config& config, faiss::ConcurrentBitsetPtr blacklist) override;
|
||||
};
|
||||
} // namespace knowhere
|
||||
} // namespace milvus
|
||||
#endif
|
|
@ -29,7 +29,9 @@
|
|||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
#include "selector/ApuPass.h"
|
||||
#endif
|
||||
namespace milvus {
|
||||
namespace scheduler {
|
||||
|
||||
|
@ -95,10 +97,15 @@ class OptimizerInst {
|
|||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (instance == nullptr) {
|
||||
std::vector<PassPtr> pass_list;
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
pass_list.push_back(std::make_shared<ApuPass>());
|
||||
#endif
|
||||
|
||||
#ifdef MILVUS_GPU_VERSION
|
||||
bool enable_gpu = false;
|
||||
server::Config& config = server::Config::GetInstance();
|
||||
config.GetGpuResourceConfigEnable(enable_gpu);
|
||||
|
||||
if (enable_gpu) {
|
||||
std::vector<int64_t> build_gpus;
|
||||
std::vector<int64_t> search_gpus;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <utility>
|
||||
#include "utils/Log.h"
|
||||
|
||||
namespace milvus {
|
||||
namespace scheduler {
|
||||
|
||||
|
@ -29,7 +30,11 @@ FpgaResource::FpgaResource(std::string name, uint64_t device_id, bool enable_exe
|
|||
void
|
||||
FpgaResource::LoadFile(TaskPtr task) {
|
||||
LOG_ENGINE_DEBUG_ << "jack: LoadFile loadType cpu2fpga";
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
task->Load(LoadType::CPU2APU, 0);
|
||||
#else
|
||||
task->Load(LoadType::CPU2FPGA, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License
|
||||
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
|
||||
#include "scheduler/selector/ApuPass.h"
|
||||
#include "scheduler/SchedInst.h"
|
||||
#include "scheduler/tasklabel/SpecResLabel.h"
|
||||
|
||||
namespace milvus {
|
||||
namespace scheduler {
|
||||
|
||||
void
|
||||
ApuPass::Init() {
|
||||
}
|
||||
|
||||
bool
|
||||
ApuPass::Run(const TaskPtr& task) {
|
||||
auto task_type = task->Type();
|
||||
auto search_task = std::static_pointer_cast<XSearchTask>(task);
|
||||
|
||||
if (task_type != TaskType::SearchTask ||
|
||||
search_task->file_->engine_type_ != (int)engine::EngineType::FAISS_BIN_IDMAP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto apu = ResMgrInst::GetInstance()->GetResource(ResourceType::FPGA, 0);
|
||||
auto lable = std::make_shared<SpecResLabel>(apu);
|
||||
task->label() = lable;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace scheduler
|
||||
} // namespace milvus
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License
|
||||
|
||||
#ifdef MILVUS_APU_VERSION
|
||||
#pragma once
|
||||
|
||||
#include "Pass.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace milvus {
|
||||
namespace scheduler {
|
||||
|
||||
class ApuPass : public Pass {
|
||||
public:
|
||||
ApuPass() = default;
|
||||
|
||||
void
|
||||
Init() override;
|
||||
|
||||
bool
|
||||
Run(const TaskPtr& task) override;
|
||||
};
|
||||
|
||||
} // namespace scheduler
|
||||
} // namespace milvus
|
||||
#endif
|
|
@ -158,6 +158,9 @@ XSearchTask::Load(LoadType type, uint8_t device_id) {
|
|||
} else if (type == LoadType::CPU2FPGA) {
|
||||
stat = index_engine_->CopyToFpga();
|
||||
type_str = "CPU2FPGA";
|
||||
} else if (type == LoadType::CPU2APU) {
|
||||
stat = index_engine_->CopyToApu(file_->row_count_);
|
||||
type_str = "CPU2APU";
|
||||
} else {
|
||||
error_msg = "Wrong load type";
|
||||
stat = Status(SERVER_UNEXPECTED_ERROR, error_msg);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
namespace milvus {
|
||||
namespace scheduler {
|
||||
|
||||
enum class LoadType { DISK2CPU, CPU2GPU, GPU2CPU, TEST, CPU2FPGA };
|
||||
enum class LoadType { DISK2CPU, CPU2GPU, GPU2CPU, TEST, CPU2FPGA, CPU2APU };
|
||||
|
||||
enum class TaskType {
|
||||
SearchTask,
|
||||
|
|
BIN
core/thirdparty/gsi/gdl_sources_milvus/gsi-sys-full-libs-120.11.300.9.deb
vendored
Executable file
BIN
core/thirdparty/gsi/gdl_sources_milvus/gsi-sys-full-libs-120.11.300.9.deb
vendored
Executable file
Binary file not shown.
Binary file not shown.
|
@ -12,3 +12,5 @@ libboost-filesystem-dev libboost-serialization-dev libboost-regex-dev liblapack3
|
|||
if [ ! -f "/usr/lib/x86_64-linux-gnu/libmysqlclient_r.so" ]; then
|
||||
sudo ln -s /usr/lib/x86_64-linux-gnu/libmysqlclient.so /usr/lib/x86_64-linux-gnu/libmysqlclient_r.so
|
||||
fi
|
||||
|
||||
sudo dpkg -i ./thirdparty/gsi/gdl_sources_milvus/gsi-sys-full-libs-120.11.300.9.deb
|
||||
|
|
Loading…
Reference in New Issue