Code Refactoring (#4702)

* remove useless code

Signed-off-by: shengjun.li <shengjun.li@zilliz.com>

* Code Refactoring

Signed-off-by: shengjun.li <shengjun.li@zilliz.com>

* fix ut

Signed-off-by: shengjun.li <shengjun.li@zilliz.com>
pull/4713/head
shengjun.li 2021-02-09 17:25:15 +08:00 committed by GitHub
parent 97a5d9055e
commit 09f0730f8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 187 additions and 258 deletions

View File

@ -43,6 +43,7 @@
#include "knowhere/index/vector_index/gpu/IndexIVFSQHybrid.h"
#include "knowhere/index/vector_index/helpers/Cloner.h"
#endif
#include "knowhere/index/vector_index/IndexType.h"
#include "knowhere/index/vector_index/helpers/IndexParameter.h"
#include "metrics/Metrics.h"
#include "scheduler/Utils.h"
@ -92,9 +93,40 @@ MappingMetricType(MetricType metric_type, milvus::json& conf) {
return Status::OK();
}
bool
IsBinaryIndexType(knowhere::IndexType type) {
return type == knowhere::IndexEnum::INDEX_FAISS_BIN_IDMAP || type == knowhere::IndexEnum::INDEX_FAISS_BIN_IVFFLAT;
knowhere::IndexType
MappingIndexType(EngineType type) {
switch (type) {
case EngineType::FAISS_IDMAP:
return knowhere::IndexEnum::INDEX_FAISS_IDMAP;
case EngineType::FAISS_IVFFLAT:
return knowhere::IndexEnum::INDEX_FAISS_IVFFLAT;
case EngineType::FAISS_PQ:
return knowhere::IndexEnum::INDEX_FAISS_IVFPQ;
case EngineType::FAISS_IVFSQ8:
return knowhere::IndexEnum::INDEX_FAISS_IVFSQ8;
#ifdef MILVUS_GPU_VERSION
case EngineType::FAISS_IVFSQ8H:
return knowhere::IndexEnum::INDEX_FAISS_IVFSQ8H;
#endif
case EngineType::FAISS_BIN_IDMAP:
return knowhere::IndexEnum::INDEX_FAISS_BIN_IDMAP;
case EngineType::FAISS_BIN_IVFFLAT:
return knowhere::IndexEnum::INDEX_FAISS_BIN_IVFFLAT;
case EngineType::NSG_MIX:
return knowhere::IndexEnum::INDEX_NSG;
case EngineType::SPTAG_KDT:
return knowhere::IndexEnum::INDEX_SPTAG_KDT_RNT;
case EngineType::SPTAG_BKT:
return knowhere::IndexEnum::INDEX_SPTAG_BKT_RNT;
case EngineType::HNSW:
return knowhere::IndexEnum::INDEX_HNSW;
case EngineType::ANNOY:
return knowhere::IndexEnum::INDEX_ANNOY;
default:
break;
}
return knowhere::IndexEnum::INVALID;
}
} // namespace
@ -127,29 +159,6 @@ ExecutionEngineImpl::ExecutionEngineImpl(uint16_t dimension, const std::string&
index_type_(index_type),
metric_type_(metric_type),
index_params_(index_params) {
EngineType tmp_index_type =
utils::IsBinaryMetricType((int32_t)metric_type) ? EngineType::FAISS_BIN_IDMAP : EngineType::FAISS_IDMAP;
index_ = CreatetVecIndex(tmp_index_type);
if (!index_) {
throw Exception(DB_ERROR, "Unsupported index type");
}
milvus::json conf = index_params;
conf[knowhere::meta::DEVICEID] = gpu_num_;
conf[knowhere::meta::DIM] = dimension;
MappingMetricType(metric_type, conf);
LOG_ENGINE_DEBUG_ << "Index params: " << conf.dump();
auto adapter = knowhere::AdapterMgr::GetInstance().GetAdapter(index_->index_type());
if (!adapter->CheckTrain(conf, index_->index_mode())) {
throw Exception(DB_ERROR, "Illegal index params");
}
fiu_do_on("ExecutionEngineImpl.throw_exception", throw Exception(DB_ERROR, ""));
if (auto bf_index = std::dynamic_pointer_cast<knowhere::IDMAP>(index_)) {
bf_index->Train(knowhere::DatasetPtr(), conf);
} else if (auto bf_bin_index = std::dynamic_pointer_cast<knowhere::BinaryIDMAP>(index_)) {
bf_bin_index->Train(knowhere::DatasetPtr(), conf);
}
}
ExecutionEngineImpl::ExecutionEngineImpl(knowhere::VecIndexPtr index, const std::string& location,
@ -162,20 +171,23 @@ ExecutionEngineImpl::ExecutionEngineImpl(knowhere::VecIndexPtr index, const std:
index_params_(index_params) {
}
knowhere::VecIndexPtr
ExecutionEngineImpl::CreatetVecIndex(EngineType type) {
knowhere::VecIndexFactory& vec_index_factory = knowhere::VecIndexFactory::GetInstance();
knowhere::IndexMode mode = knowhere::IndexMode::MODE_CPU;
knowhere::IndexMode
ExecutionEngineImpl::GetModeFromConfig() {
#ifdef MILVUS_GPU_VERSION
server::Config& config = server::Config::GetInstance();
bool gpu_resource_enable = true;
config.GetGpuResourceConfigEnable(gpu_resource_enable);
fiu_do_on("ExecutionEngineImpl.CreatetVecIndex.gpu_res_disabled", gpu_resource_enable = false);
fiu_do_on("ExecutionEngineImpl.GetModeFromConfig.gpu_res_disabled", gpu_resource_enable = false);
if (gpu_resource_enable) {
mode = knowhere::IndexMode::MODE_GPU;
return knowhere::IndexMode::MODE_GPU;
}
#endif
fiu_do_on("ExecutionEngineImpl.CreateVecIndex.invalid_type", type = EngineType::INVALID);
return knowhere::IndexMode::MODE_CPU;
}
knowhere::VecIndexPtr
ExecutionEngineImpl::CreatetVecIndex(EngineType type, knowhere::IndexMode mode) {
knowhere::VecIndexFactory& vec_index_factory = knowhere::VecIndexFactory::GetInstance();
knowhere::VecIndexPtr index = nullptr;
switch (type) {
case EngineType::FAISS_IDMAP: {
@ -187,13 +199,6 @@ ExecutionEngineImpl::CreatetVecIndex(EngineType type) {
break;
}
case EngineType::FAISS_PQ: {
auto m = index_params_[knowhere::IndexParams::m];
if (!m.is_null() && !milvus::knowhere::IVFPQConfAdapter::GetValidM(dim_, m.get<int64_t>(), mode)) {
std::string err_msg = "dimension " + std::to_string(dim_) + " can't not be divided by m " +
std::to_string(m.get<int64_t>());
LOG_ENGINE_ERROR_ << err_msg;
break;
}
index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_FAISS_IVFPQ, mode);
break;
}
@ -235,10 +240,8 @@ ExecutionEngineImpl::CreatetVecIndex(EngineType type) {
index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_ANNOY, mode);
break;
}
default: {
LOG_ENGINE_ERROR_ << "Unsupported index type " << (int)type;
return nullptr;
}
default:
break;
}
if (index == nullptr) {
std::string err_msg = "Invalid index type " + std::to_string((int)type) + " mod " + std::to_string((int)mode);
@ -380,8 +383,8 @@ ExecutionEngineImpl::Serialize() {
Status
ExecutionEngineImpl::Load(bool to_cache) {
index_ = std::static_pointer_cast<knowhere::VecIndex>(cache::CpuCacheMgr::GetInstance()->GetIndex(location_));
bool already_in_cache = (index_ != nullptr);
if (!already_in_cache) {
if (!index_) {
// not in the cache
std::string segment_dir;
utils::GetParentPath(location_, segment_dir);
auto segment_reader_ptr = std::make_shared<segment::SegmentReader>(segment_dir);
@ -397,7 +400,8 @@ ExecutionEngineImpl::Load(bool to_cache) {
MappingMetricType(metric_type_, conf);
auto adapter = knowhere::AdapterMgr::GetInstance().GetAdapter(index_->index_type());
LOG_ENGINE_DEBUG_ << "Index params: " << conf.dump();
if (!adapter->CheckTrain(conf, index_->index_mode())) {
auto mode = index_->index_mode();
if (!adapter->CheckTrain(conf, mode)) {
throw Exception(DB_ERROR, "Illegal index params");
}
@ -497,68 +501,17 @@ ExecutionEngineImpl::Load(bool to_cache) {
return Status(DB_ERROR, e.what());
}
}
if (to_cache) {
Cache();
}
}
if (!already_in_cache && to_cache) {
Cache();
}
return Status::OK();
} // namespace engine
Status
ExecutionEngineImpl::CopyToGpu(uint64_t device_id, bool hybrid) {
#if 0
if (hybrid) {
const std::string key = location_ + ".quantizer";
std::vector<uint64_t> gpus{device_id};
const int64_t NOT_FOUND = -1;
int64_t device_id = NOT_FOUND;
// cache hit
{
knowhere::QuantizerPtr quantizer = nullptr;
for (auto& gpu : gpus) {
auto cache = cache::GpuCacheMgr::GetInstance(gpu);
if (auto cached_quantizer = cache->GetIndex(key)) {
device_id = gpu;
quantizer = std::static_pointer_cast<CachedQuantizer>(cached_quantizer)->Data();
}
}
if (device_id != NOT_FOUND) {
// cache hit
milvus::json quantizer_conf{{knowhere::meta::DEVICEID : device_id}, {"mode" : 2}};
auto new_index = index_->LoadData(quantizer, config);
index_ = new_index;
}
}
if (device_id == NOT_FOUND) {
// cache miss
std::vector<int64_t> all_free_mem;
for (auto& gpu : gpus) {
auto cache = cache::GpuCacheMgr::GetInstance(gpu);
auto free_mem = cache->CacheCapacity() - cache->CacheUsage();
all_free_mem.push_back(free_mem);
}
auto max_e = std::max_element(all_free_mem.begin(), all_free_mem.end());
auto best_index = std::distance(all_free_mem.begin(), max_e);
device_id = gpus[best_index];
auto pair = index_->CopyToGpuWithQuantizer(device_id);
index_ = pair.first;
// cache
auto cached_quantizer = std::make_shared<CachedQuantizer>(pair.second);
cache::GpuCacheMgr::GetInstance(device_id)->InsertItem(key, cached_quantizer);
}
return Status::OK();
}
#endif
#ifdef MILVUS_GPU_VERSION
auto data_obj_ptr = cache::GpuCacheMgr::GetInstance(device_id)->GetIndex(location_);
auto index = std::static_pointer_cast<knowhere::VecIndex>(data_obj_ptr);
@ -592,7 +545,7 @@ ExecutionEngineImpl::CopyToGpu(uint64_t device_id, bool hybrid) {
}
index_ = knowhere::cloner::CopyCpuToGpu(index_, device_id, knowhere::Config());
if (index_ == nullptr) {
LOG_ENGINE_DEBUG_ << "copy to GPU faied, search on CPU";
LOG_ENGINE_DEBUG_ << "copy to GPU failed, search on CPU";
index_ = index_reserve_;
} else {
if (gpu_cache_enable) {
@ -679,6 +632,7 @@ ExecutionEngineImpl::CopyToFpga() {
#endif
return Status::OK();
}
ExecutionEnginePtr
ExecutionEngineImpl::BuildIndex(const std::string& location, EngineType engine_type) {
LOG_ENGINE_DEBUG_ << "Build index file: " << location << " from: " << location_;
@ -690,22 +644,20 @@ ExecutionEngineImpl::BuildIndex(const std::string& location, EngineType engine_t
return nullptr;
}
auto to_index = CreatetVecIndex(engine_type);
if (!to_index) {
throw Exception(DB_ERROR, "Unsupported index type");
}
milvus::json conf = index_params_;
conf[knowhere::meta::DIM] = Dimension();
conf[knowhere::meta::ROWS] = Count();
conf[knowhere::meta::DEVICEID] = gpu_num_;
MappingMetricType(metric_type_, conf);
LOG_ENGINE_DEBUG_ << "Index params: " << conf.dump();
auto adapter = knowhere::AdapterMgr::GetInstance().GetAdapter(to_index->index_type());
if (!adapter->CheckTrain(conf, to_index->index_mode())) {
auto adapter = knowhere::AdapterMgr::GetInstance().GetAdapter(MappingIndexType(engine_type));
auto mode = GetModeFromConfig();
if (!adapter->CheckTrain(conf, mode)) {
throw Exception(DB_ERROR, "Illegal index params");
}
LOG_ENGINE_DEBUG_ << "Index config: " << conf.dump();
auto to_index = CreatetVecIndex(engine_type, mode);
std::shared_ptr<std::vector<segment::doc_id_t>> uids;
faiss::ConcurrentBitsetPtr blacklist;
if (from_index) {
@ -727,6 +679,7 @@ ExecutionEngineImpl::BuildIndex(const std::string& location, EngineType engine_t
to_index = device_index->CopyGpuToCpu(conf);
}
#endif
to_index->SetUids(uids);
LOG_ENGINE_DEBUG_ << "Set " << to_index->UidsSize() << "uids for " << location;
if (blacklist != nullptr) {

View File

@ -109,11 +109,11 @@ class ExecutionEngineImpl : public ExecutionEngine {
}
private:
knowhere::VecIndexPtr
CreatetVecIndex(EngineType type);
knowhere::IndexMode
GetModeFromConfig();
knowhere::VecIndexPtr
Load(const std::string& location);
CreatetVecIndex(EngineType type, knowhere::IndexMode mode);
void
HybridLoad() const;

View File

@ -14,6 +14,7 @@
#include <memory>
#include <string>
#include <vector>
#include "knowhere/common/Log.h"
#include "knowhere/index/vector_index/helpers/IndexParameter.h"
#ifdef MILVUS_GPU_VERSION
@ -60,51 +61,69 @@ namespace knowhere {
}
bool
ConfAdapter::CheckTrain(Config& oricfg, const IndexMode mode) {
static std::vector<std::string> METRICS{knowhere::Metric::L2, knowhere::Metric::IP};
CheckIntByRange(knowhere::meta::DIM, DEFAULT_MIN_DIM, DEFAULT_MAX_DIM);
CheckStrByValues(knowhere::Metric::TYPE, METRICS);
ConfAdapter::CheckTrain(Config& oricfg, IndexMode& mode) {
static std::vector<std::string> METRICS{Metric::L2, Metric::IP};
CheckIntByRange(meta::DIM, DEFAULT_MIN_DIM, DEFAULT_MAX_DIM);
CheckStrByValues(Metric::TYPE, METRICS);
return true;
}
bool
ConfAdapter::CheckSearch(Config& oricfg, const IndexType type, const IndexMode mode) {
CheckIntByRange(knowhere::meta::TOPK, DEFAULT_MIN_K - 1, DEFAULT_MAX_K);
CheckIntByRange(meta::TOPK, DEFAULT_MIN_K - 1, DEFAULT_MAX_K);
return true;
}
int64_t
MatchNlist(int64_t size, int64_t nlist) {
const int64_t TYPICAL_COUNT = 1000000;
const int64_t PER_NLIST = 16384;
const int64_t MIN_POINTS_PER_CENTROID = 40;
if (nlist * TYPICAL_COUNT > size * PER_NLIST) {
if (nlist * MIN_POINTS_PER_CENTROID > size) {
// nlist is too large, adjust to a proper value
nlist = std::max(1L, size * PER_NLIST / TYPICAL_COUNT);
nlist = std::max(1L, size / MIN_POINTS_PER_CENTROID);
LOG_KNOWHERE_WARNING_ << "Row num " << size << " match nlist " << nlist;
}
return nlist;
}
int64_t
MatchNbits(int64_t size, int64_t nbits) {
if (size < (1 << nbits)) {
// nbits is too large, adjust to a proper value
if (size >= (1 << 8)) {
nbits = 8;
} else if (size >= (1 << 4)) {
nbits = 4;
} else if (size >= (1 << 2)) {
nbits = 2;
} else {
nbits = 1;
}
LOG_KNOWHERE_WARNING_ << "Row num " << size << " match nbits " << nbits;
}
return nbits;
}
bool
IVFConfAdapter::CheckTrain(Config& oricfg, const IndexMode mode) {
IVFConfAdapter::CheckTrain(Config& oricfg, IndexMode& mode) {
static int64_t MAX_NLIST = 65536;
static int64_t MIN_NLIST = 1;
CheckIntByRange(knowhere::IndexParams::nlist, MIN_NLIST, MAX_NLIST);
CheckIntByRange(knowhere::meta::ROWS, DEFAULT_MIN_ROWS, DEFAULT_MAX_ROWS);
CheckIntByRange(IndexParams::nlist, MIN_NLIST, MAX_NLIST);
CheckIntByRange(meta::ROWS, DEFAULT_MIN_ROWS, DEFAULT_MAX_ROWS);
// int64_t nlist = oricfg[knowhere::IndexParams::nlist];
// CheckIntByRange(knowhere::meta::ROWS, nlist, DEFAULT_MAX_ROWS);
// int64_t nlist = oricfg[IndexParams::nlist];
// CheckIntByRange(meta::ROWS, nlist, DEFAULT_MAX_ROWS);
// auto tune params
int64_t nq = oricfg[knowhere::meta::ROWS].get<int64_t>();
int64_t nlist = oricfg[knowhere::IndexParams::nlist].get<int64_t>();
oricfg[knowhere::IndexParams::nlist] = MatchNlist(nq, nlist);
int64_t nq = oricfg[meta::ROWS].get<int64_t>();
int64_t nlist = oricfg[IndexParams::nlist].get<int64_t>();
oricfg[IndexParams::nlist] = MatchNlist(nq, nlist);
// Best Practice
// static int64_t MIN_POINTS_PER_CENTROID = 40;
// static int64_t MAX_POINTS_PER_CENTROID = 256;
// CheckIntByRange(knowhere::meta::ROWS, MIN_POINTS_PER_CENTROID * nlist, MAX_POINTS_PER_CENTROID * nlist);
// CheckIntByRange(meta::ROWS, MIN_POINTS_PER_CENTROID * nlist, MAX_POINTS_PER_CENTROID * nlist);
return ConfAdapter::CheckTrain(oricfg, mode);
}
@ -116,71 +135,57 @@ IVFConfAdapter::CheckSearch(Config& oricfg, const IndexType type, const IndexMod
if (mode == IndexMode::MODE_GPU) {
#ifdef MILVUS_GPU_VERSION
CheckIntByRange(knowhere::IndexParams::nprobe, MIN_NPROBE, faiss::gpu::getMaxKSelection());
CheckIntByRange(IndexParams::nprobe, MIN_NPROBE, faiss::gpu::getMaxKSelection());
#endif
} else {
CheckIntByRange(knowhere::IndexParams::nprobe, MIN_NPROBE, MAX_NPROBE);
CheckIntByRange(IndexParams::nprobe, MIN_NPROBE, MAX_NPROBE);
}
return ConfAdapter::CheckSearch(oricfg, type, mode);
}
bool
IVFSQConfAdapter::CheckTrain(Config& oricfg, const IndexMode mode) {
IVFSQConfAdapter::CheckTrain(Config& oricfg, IndexMode& mode) {
static int64_t DEFAULT_NBITS = 8;
oricfg[knowhere::IndexParams::nbits] = DEFAULT_NBITS;
oricfg[IndexParams::nbits] = DEFAULT_NBITS;
return IVFConfAdapter::CheckTrain(oricfg, mode);
}
bool
IVFPQConfAdapter::CheckTrain(Config& oricfg, const IndexMode mode) {
IVFPQConfAdapter::CheckTrain(Config& oricfg, IndexMode& mode) {
static int64_t DEFAULT_NBITS = 8;
static int64_t MAX_NLIST = 65536;
static int64_t MIN_NLIST = 1;
static std::vector<std::string> METRICS{knowhere::Metric::L2, knowhere::Metric::IP};
static std::vector<std::string> METRICS{Metric::L2, Metric::IP};
oricfg[knowhere::IndexParams::nbits] = DEFAULT_NBITS;
oricfg[IndexParams::nbits] = DEFAULT_NBITS;
CheckStrByValues(Metric::TYPE, METRICS);
CheckIntByRange(meta::DIM, DEFAULT_MIN_DIM, DEFAULT_MAX_DIM);
CheckIntByRange(meta::ROWS, DEFAULT_MIN_ROWS, DEFAULT_MAX_ROWS);
CheckIntByRange(IndexParams::nlist, MIN_NLIST, MAX_NLIST);
CheckStrByValues(knowhere::Metric::TYPE, METRICS);
CheckIntByRange(knowhere::meta::DIM, DEFAULT_MIN_DIM, DEFAULT_MAX_DIM);
CheckIntByRange(knowhere::meta::ROWS, DEFAULT_MIN_ROWS, DEFAULT_MAX_ROWS);
CheckIntByRange(knowhere::IndexParams::nlist, MIN_NLIST, MAX_NLIST);
// int64_t nlist = oricfg[knowhere::IndexParams::nlist];
// CheckIntByRange(knowhere::meta::ROWS, nlist, DEFAULT_MAX_ROWS);
auto rows = oricfg[meta::ROWS].get<int64_t>();
auto nlist = oricfg[IndexParams::nlist].get<int64_t>();
auto dimension = oricfg[meta::DIM].get<int64_t>();
auto m = oricfg[IndexParams::m].get<int64_t>();
// auto tune params
oricfg[knowhere::IndexParams::nlist] =
MatchNlist(oricfg[knowhere::meta::ROWS].get<int64_t>(), oricfg[knowhere::IndexParams::nlist].get<int64_t>());
// Best Practice
// static int64_t MIN_POINTS_PER_CENTROID = 40;
// static int64_t MAX_POINTS_PER_CENTROID = 256;
// CheckIntByRange(knowhere::meta::ROWS, MIN_POINTS_PER_CENTROID * nlist, MAX_POINTS_PER_CENTROID * nlist);
int64_t dimension = oricfg[knowhere::meta::DIM].get<int64_t>();
int64_t m = oricfg[knowhere::IndexParams::m].get<int64_t>();
IndexMode IVFPQ_mode = mode;
return GetValidM(dimension, m, IVFPQ_mode);
}
bool
IVFPQConfAdapter::GetValidM(int64_t dimension, int64_t m, IndexMode& mode) {
oricfg[IndexParams::nlist] = MatchNlist(rows, nlist);
#ifdef MILVUS_GPU_VERSION
if (mode == knowhere::IndexMode::MODE_GPU && !IVFPQConfAdapter::GetValidGPUM(dimension, m)) {
mode = knowhere::IndexMode::MODE_CPU;
if (mode == IndexMode::MODE_GPU) {
if (IsValidForGPU(dimension, m)) {
return true;
}
// else try CPU Mode
mode == IndexMode::MODE_CPU;
}
#endif
if (mode != knowhere::IndexMode::MODE_GPU && !IVFPQConfAdapter::GetValidCPUM(dimension, m)) {
return false;
}
return true;
return IsValidForCPU(dimension, m);
}
bool
IVFPQConfAdapter::GetValidGPUM(int64_t dimension, int64_t m) {
IVFPQConfAdapter::IsValidForGPU(int64_t dimension, int64_t m) {
/*
* Faiss 1.6
* Only 1, 2, 3, 4, 6, 8, 10, 12, 16, 20, 24, 28, 32 dims per sub-quantizer are currently supported with
@ -189,7 +194,7 @@ IVFPQConfAdapter::GetValidGPUM(int64_t dimension, int64_t m) {
static std::vector<int64_t> support_dim_per_subquantizer{32, 28, 24, 20, 16, 12, 10, 8, 6, 4, 3, 2, 1};
static std::vector<int64_t> support_subquantizer{96, 64, 56, 48, 40, 32, 28, 24, 20, 16, 12, 8, 4, 3, 2, 1};
if (!GetValidCPUM(dimension, m)) {
if (!IsValidForCPU(dimension, m)) {
return false;
}
@ -198,29 +203,15 @@ IVFPQConfAdapter::GetValidGPUM(int64_t dimension, int64_t m) {
support_subquantizer.end()) &&
(std::find(std::begin(support_dim_per_subquantizer), std::end(support_dim_per_subquantizer), sub_dim) !=
support_dim_per_subquantizer.end());
/*
std::vector<int64_t> resset;
resset.clear();
for (const auto& dimperquantizer : support_dim_per_subquantizer) {
if (!(dimension % dimperquantizer)) {
auto subquantzier_num = dimension / dimperquantizer;
auto finder = std::find(support_subquantizer.begin(), support_subquantizer.end(), subquantzier_num);
if (finder != support_subquantizer.end()) {
resset.push_back(subquantzier_num);
}
}
}
*/
}
bool
IVFPQConfAdapter::GetValidCPUM(int64_t dimension, int64_t m) {
IVFPQConfAdapter::IsValidForCPU(int64_t dimension, int64_t m) {
return (dimension % m == 0);
}
bool
NSGConfAdapter::CheckTrain(Config& oricfg, const IndexMode mode) {
NSGConfAdapter::CheckTrain(Config& oricfg, IndexMode& mode) {
static int64_t MIN_KNNG = 5;
static int64_t MAX_KNNG = 300;
static int64_t MIN_SEARCH_LENGTH = 10;
@ -229,20 +220,20 @@ NSGConfAdapter::CheckTrain(Config& oricfg, const IndexMode mode) {
static int64_t MAX_OUT_DEGREE = 300;
static int64_t MIN_CANDIDATE_POOL_SIZE = 50;
static int64_t MAX_CANDIDATE_POOL_SIZE = 1000;
static std::vector<std::string> METRICS{knowhere::Metric::L2, knowhere::Metric::IP};
static std::vector<std::string> METRICS{Metric::L2, Metric::IP};
CheckStrByValues(knowhere::Metric::TYPE, METRICS);
CheckIntByRange(knowhere::meta::ROWS, DEFAULT_MIN_ROWS, DEFAULT_MAX_ROWS);
CheckIntByRange(knowhere::IndexParams::knng, MIN_KNNG, MAX_KNNG);
CheckIntByRange(knowhere::IndexParams::search_length, MIN_SEARCH_LENGTH, MAX_SEARCH_LENGTH);
CheckIntByRange(knowhere::IndexParams::out_degree, MIN_OUT_DEGREE, MAX_OUT_DEGREE);
CheckIntByRange(knowhere::IndexParams::candidate, MIN_CANDIDATE_POOL_SIZE, MAX_CANDIDATE_POOL_SIZE);
CheckStrByValues(Metric::TYPE, METRICS);
CheckIntByRange(meta::ROWS, DEFAULT_MIN_ROWS, DEFAULT_MAX_ROWS);
CheckIntByRange(IndexParams::knng, MIN_KNNG, MAX_KNNG);
CheckIntByRange(IndexParams::search_length, MIN_SEARCH_LENGTH, MAX_SEARCH_LENGTH);
CheckIntByRange(IndexParams::out_degree, MIN_OUT_DEGREE, MAX_OUT_DEGREE);
CheckIntByRange(IndexParams::candidate, MIN_CANDIDATE_POOL_SIZE, MAX_CANDIDATE_POOL_SIZE);
// auto tune params
oricfg[knowhere::IndexParams::nlist] = MatchNlist(oricfg[knowhere::meta::ROWS].get<int64_t>(), 8192);
oricfg[IndexParams::nlist] = MatchNlist(oricfg[meta::ROWS].get<int64_t>(), 8192);
int64_t nprobe = int(oricfg[knowhere::IndexParams::nlist].get<int64_t>() * 0.1);
oricfg[knowhere::IndexParams::nprobe] = nprobe < 1 ? 1 : nprobe;
int64_t nprobe = int(oricfg[IndexParams::nlist].get<int64_t>() * 0.1);
oricfg[IndexParams::nprobe] = nprobe < 1 ? 1 : nprobe;
return true;
}
@ -252,21 +243,21 @@ NSGConfAdapter::CheckSearch(Config& oricfg, const IndexType type, const IndexMod
static int64_t MIN_SEARCH_LENGTH = 1;
static int64_t MAX_SEARCH_LENGTH = 300;
CheckIntByRange(knowhere::IndexParams::search_length, MIN_SEARCH_LENGTH, MAX_SEARCH_LENGTH);
CheckIntByRange(IndexParams::search_length, MIN_SEARCH_LENGTH, MAX_SEARCH_LENGTH);
return ConfAdapter::CheckSearch(oricfg, type, mode);
}
bool
HNSWConfAdapter::CheckTrain(Config& oricfg, const IndexMode mode) {
HNSWConfAdapter::CheckTrain(Config& oricfg, IndexMode& mode) {
static int64_t MIN_EFCONSTRUCTION = 8;
static int64_t MAX_EFCONSTRUCTION = 512;
static int64_t MIN_M = 4;
static int64_t MAX_M = 64;
CheckIntByRange(knowhere::meta::ROWS, DEFAULT_MIN_ROWS, DEFAULT_MAX_ROWS);
CheckIntByRange(knowhere::IndexParams::efConstruction, MIN_EFCONSTRUCTION, MAX_EFCONSTRUCTION);
CheckIntByRange(knowhere::IndexParams::M, MIN_M, MAX_M);
CheckIntByRange(meta::ROWS, DEFAULT_MIN_ROWS, DEFAULT_MAX_ROWS);
CheckIntByRange(IndexParams::efConstruction, MIN_EFCONSTRUCTION, MAX_EFCONSTRUCTION);
CheckIntByRange(IndexParams::M, MIN_M, MAX_M);
return ConfAdapter::CheckTrain(oricfg, mode);
}
@ -275,53 +266,51 @@ bool
HNSWConfAdapter::CheckSearch(Config& oricfg, const IndexType type, const IndexMode mode) {
static int64_t MAX_EF = 32768;
CheckIntByRange(knowhere::IndexParams::ef, oricfg[knowhere::meta::TOPK], MAX_EF);
CheckIntByRange(IndexParams::ef, oricfg[meta::TOPK], MAX_EF);
return ConfAdapter::CheckSearch(oricfg, type, mode);
}
bool
BinIDMAPConfAdapter::CheckTrain(Config& oricfg, const IndexMode mode) {
static std::vector<std::string> METRICS{knowhere::Metric::HAMMING, knowhere::Metric::JACCARD,
knowhere::Metric::TANIMOTO, knowhere::Metric::SUBSTRUCTURE,
knowhere::Metric::SUPERSTRUCTURE};
BinIDMAPConfAdapter::CheckTrain(Config& oricfg, IndexMode& mode) {
static std::vector<std::string> METRICS{Metric::HAMMING, Metric::JACCARD, Metric::TANIMOTO, Metric::SUBSTRUCTURE,
Metric::SUPERSTRUCTURE};
CheckIntByRange(knowhere::meta::DIM, DEFAULT_MIN_DIM, DEFAULT_MAX_DIM);
CheckStrByValues(knowhere::Metric::TYPE, METRICS);
CheckIntByRange(meta::DIM, DEFAULT_MIN_DIM, DEFAULT_MAX_DIM);
CheckStrByValues(Metric::TYPE, METRICS);
return true;
}
bool
BinIVFConfAdapter::CheckTrain(Config& oricfg, const IndexMode mode) {
static std::vector<std::string> METRICS{knowhere::Metric::HAMMING, knowhere::Metric::JACCARD,
knowhere::Metric::TANIMOTO};
static int64_t MAX_NLIST = 999999;
BinIVFConfAdapter::CheckTrain(Config& oricfg, IndexMode& mode) {
static std::vector<std::string> METRICS{Metric::HAMMING, Metric::JACCARD, Metric::TANIMOTO};
static int64_t MAX_NLIST = 65536;
static int64_t MIN_NLIST = 1;
CheckIntByRange(knowhere::meta::ROWS, DEFAULT_MIN_ROWS, DEFAULT_MAX_ROWS);
CheckIntByRange(knowhere::meta::DIM, DEFAULT_MIN_DIM, DEFAULT_MAX_DIM);
CheckIntByRange(knowhere::IndexParams::nlist, MIN_NLIST, MAX_NLIST);
CheckStrByValues(knowhere::Metric::TYPE, METRICS);
CheckIntByRange(meta::ROWS, DEFAULT_MIN_ROWS, DEFAULT_MAX_ROWS);
CheckIntByRange(meta::DIM, DEFAULT_MIN_DIM, DEFAULT_MAX_DIM);
CheckIntByRange(IndexParams::nlist, MIN_NLIST, MAX_NLIST);
CheckStrByValues(Metric::TYPE, METRICS);
int64_t nlist = oricfg[knowhere::IndexParams::nlist];
CheckIntByRange(knowhere::meta::ROWS, nlist, DEFAULT_MAX_ROWS);
int64_t nlist = oricfg[IndexParams::nlist];
CheckIntByRange(meta::ROWS, nlist, DEFAULT_MAX_ROWS);
// Best Practice
// static int64_t MIN_POINTS_PER_CENTROID = 40;
// static int64_t MAX_POINTS_PER_CENTROID = 256;
// CheckIntByRange(knowhere::meta::ROWS, MIN_POINTS_PER_CENTROID * nlist, MAX_POINTS_PER_CENTROID * nlist);
// CheckIntByRange(meta::ROWS, MIN_POINTS_PER_CENTROID * nlist, MAX_POINTS_PER_CENTROID * nlist);
return true;
}
bool
ANNOYConfAdapter::CheckTrain(Config& oricfg, const IndexMode mode) {
ANNOYConfAdapter::CheckTrain(Config& oricfg, IndexMode& mode) {
static int64_t MIN_NTREES = 1;
// too large of n_trees takes much time, if there is real requirement, change this threshold.
static int64_t MAX_NTREES = 1024;
CheckIntByRange(knowhere::IndexParams::n_trees, MIN_NTREES, MAX_NTREES);
CheckIntByRange(IndexParams::n_trees, MIN_NTREES, MAX_NTREES);
return ConfAdapter::CheckTrain(oricfg, mode);
}

View File

@ -24,7 +24,7 @@ namespace knowhere {
class ConfAdapter {
public:
virtual bool
CheckTrain(Config& oricfg, const IndexMode mode);
CheckTrain(Config& oricfg, IndexMode& mode);
virtual bool
CheckSearch(Config& oricfg, const IndexType type, const IndexMode mode);
@ -34,7 +34,7 @@ using ConfAdapterPtr = std::shared_ptr<ConfAdapter>;
class IVFConfAdapter : public ConfAdapter {
public:
bool
CheckTrain(Config& oricfg, const IndexMode mode) override;
CheckTrain(Config& oricfg, IndexMode& mode) override;
bool
CheckSearch(Config& oricfg, const IndexType type, const IndexMode mode) override;
@ -43,28 +43,25 @@ class IVFConfAdapter : public ConfAdapter {
class IVFSQConfAdapter : public IVFConfAdapter {
public:
bool
CheckTrain(Config& oricfg, const IndexMode mode) override;
CheckTrain(Config& oricfg, IndexMode& mode) override;
};
class IVFPQConfAdapter : public IVFConfAdapter {
public:
bool
CheckTrain(Config& oricfg, const IndexMode mode) override;
CheckTrain(Config& oricfg, IndexMode& mode) override;
static bool
GetValidM(int64_t dimension, int64_t m, IndexMode& mode);
IsValidForGPU(int64_t dimension, int64_t m);
static bool
GetValidGPUM(int64_t dimension, int64_t m);
static bool
GetValidCPUM(int64_t dimension, int64_t m);
IsValidForCPU(int64_t dimension, int64_t m);
};
class NSGConfAdapter : public IVFConfAdapter {
public:
bool
CheckTrain(Config& oricfg, const IndexMode mode) override;
CheckTrain(Config& oricfg, IndexMode& mode) override;
bool
CheckSearch(Config& oricfg, const IndexType type, const IndexMode mode) override;
@ -73,19 +70,19 @@ class NSGConfAdapter : public IVFConfAdapter {
class BinIDMAPConfAdapter : public ConfAdapter {
public:
bool
CheckTrain(Config& oricfg, const IndexMode mode) override;
CheckTrain(Config& oricfg, IndexMode& mode) override;
};
class BinIVFConfAdapter : public IVFConfAdapter {
public:
bool
CheckTrain(Config& oricfg, const IndexMode mode) override;
CheckTrain(Config& oricfg, IndexMode& mode) override;
};
class HNSWConfAdapter : public ConfAdapter {
public:
bool
CheckTrain(Config& oricfg, const IndexMode mode) override;
CheckTrain(Config& oricfg, IndexMode& mode) override;
bool
CheckSearch(Config& oricfg, const IndexType type, const IndexMode mode) override;
@ -94,7 +91,7 @@ class HNSWConfAdapter : public ConfAdapter {
class ANNOYConfAdapter : public ConfAdapter {
public:
bool
CheckTrain(Config& oricfg, const IndexMode mode) override;
CheckTrain(Config& oricfg, IndexMode& mode) override;
bool
CheckSearch(Config& oricfg, const IndexType type, const IndexMode mode) override;

View File

@ -52,7 +52,7 @@ IVFPQ::CopyCpuToGpu(const int64_t device_id, const Config& config) {
auto ivfpq_index = dynamic_cast<faiss::IndexIVFPQ*>(index_.get());
int64_t dim = ivfpq_index->d;
int64_t m = ivfpq_index->pq.M;
if (!IVFPQConfAdapter::GetValidGPUM(dim, m)) {
if (!IVFPQConfAdapter::IsValidForGPU(dim, m)) {
return nullptr;
}

View File

@ -220,7 +220,7 @@ ValidationUtil::ValidateIndexParams(const milvus::json& index_params,
// special check for 'm' parameter
int64_t m_value = index_params[knowhere::IndexParams::m];
if (!milvus::knowhere::IVFPQConfAdapter::GetValidCPUM(collection_schema.dimension_, m_value)) {
if (!milvus::knowhere::IVFPQConfAdapter::IsValidForCPU(collection_schema.dimension_, m_value)) {
std::string msg = "Invalid collection dimension, dimension can not be divided by m";
LOG_SERVER_ERROR_ << msg;
return Status(SERVER_INVALID_COLLECTION_DIMENSION, msg);

View File

@ -19,6 +19,7 @@
#include "db/engine/ExecutionEngineImpl.h"
#include "db/utils.h"
#include "knowhere/index/vector_index/adapter/VectorAdapter.h"
#include "knowhere/index/vector_index/VecIndexFactory.h"
#include <fiu-local.h>
#include <fiu-control.h>
@ -50,7 +51,15 @@ CreateExecEngine(const milvus::json& json_params, milvus::engine::MetricType met
auto engine_impl = (std::static_pointer_cast<milvus::engine::ExecutionEngineImpl>(engine_ptr));
auto& vec_index_factory = milvus::knowhere::VecIndexFactory::GetInstance();
engine_impl->index_ = vec_index_factory.CreateVecIndex(milvus::knowhere::IndexEnum::INDEX_FAISS_IDMAP,
milvus::knowhere::IndexMode::MODE_CPU);
auto conf = json_params;
conf[milvus::knowhere::meta::DIM] = DIMENSION;
conf[milvus::knowhere::Metric::TYPE] = milvus::knowhere::Metric::L2;
auto dataset = milvus::knowhere::GenDataset(ROW_COUNT, DIMENSION, data.data());
engine_impl->index_->Train(milvus::knowhere::DatasetPtr(), conf);
engine_impl->index_->AddWithoutIds(dataset, milvus::knowhere::Config());
engine_impl->index_->SetUids(ids);
return engine_ptr;
@ -138,25 +147,6 @@ TEST_F(EngineTest, FACTORY_TEST) {
ASSERT_TRUE(engine_ptr != nullptr);
}
{
fiu_init(0);
// test ExecutionEngineImpl constructor when create VecIndex failed
FIU_ENABLE_FIU("ExecutionEngineImpl.CreateVecIndex.invalid_type");
ASSERT_ANY_THROW(milvus::engine::EngineFactory::Build(
512, "/tmp/milvus_index_1", milvus::engine::EngineType::SPTAG_KDT,
milvus::engine::MetricType::L2, index_params));
fiu_disable("ExecutionEngineImpl.CreateVecIndex.invalid_type");
}
{
// test ExecutionEngineImpl constructor when build failed
FIU_ENABLE_FIU("ExecutionEngineImpl.throw_exception");
ASSERT_ANY_THROW(milvus::engine::EngineFactory::Build(
512, "/tmp/milvus_index_1", milvus::engine::EngineType::SPTAG_KDT,
milvus::engine::MetricType::L2, index_params));
fiu_disable("ExecutionEngineImpl.throw_exception");
}
}
TEST_F(EngineTest, ENGINE_IMPL_TEST) {
@ -201,12 +191,12 @@ TEST_F(EngineTest, ENGINE_IMPL_TEST) {
#ifdef MILVUS_GPU_VERSION
{
FIU_ENABLE_FIU("ExecutionEngineImpl.CreatetVecIndex.gpu_res_disabled");
FIU_ENABLE_FIU("ExecutionEngineImpl.GetModeFromConfig.gpu_res_disabled");
milvus::json index_params = {{"search_length", 100}, {"out_degree", 40}, {"pool_size", 100}, {"knng", 200},
{"candidate_pool_size", 500}};
auto engine_ptr = CreateExecEngine(index_params, milvus::engine::MetricType::L2);
engine_ptr->BuildIndex("/tmp/milvus_index_NSG_MIX", milvus::engine::EngineType::NSG_MIX);
fiu_disable("ExecutionEngineImpl.CreatetVecIndex.gpu_res_disabled");
fiu_disable("ExecutionEngineImpl.GetModeFromConfig.gpu_res_disabled");
auto status = engine_ptr->CopyToGpu(0, false);
ASSERT_TRUE(status.ok());