reduce the index file size of IndexRHNSWFlat ()

* reduce the index file size of IndexRHNSWFlat

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

* refactor meta info read and write

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

* update unittest of index rhnswflat since Serialize and Load changed

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

* fix Load

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

Co-authored-by: cmli <chengming.li@zilliz.com>
Co-authored-by: shengjun.li <shengjun.li@zilliz.com>
pull/4522/head
op-hunter 2020-12-26 09:51:34 +08:00 committed by GitHub
parent 934c90bf26
commit f9bec87c39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 26 deletions
core/src
index
knowhere/knowhere/index/vector_index

View File

@ -278,7 +278,7 @@ SplitChunk(const DataChunkPtr& chunk, int64_t segment_row_limit, std::vector<Dat
bool
RequireRawFile(const std::string& index_type) {
return index_type == knowhere::IndexEnum::INDEX_FAISS_IVFFLAT || index_type == knowhere::IndexEnum::INDEX_NSG ||
index_type == knowhere::IndexEnum::INDEX_HNSW;
index_type == knowhere::IndexEnum::INDEX_RHNSWFlat;
}
bool

View File

@ -41,17 +41,17 @@ IndexRHNSWFlat::Serialize(const Config& config) {
try {
auto res_set = IndexRHNSW::Serialize(config);
MemoryIOWriter writer;
writer.name = this->index_type() + "_Data";
auto real_idx = dynamic_cast<faiss::IndexRHNSWFlat*>(index_.get());
if (real_idx == nullptr) {
KNOWHERE_THROW_MSG("dynamic_cast<faiss::IndexRHNSWFlat*>(index_) failed during Serialize!");
KNOWHERE_THROW_MSG("index is not a faiss::IndexRHNSWFlat");
}
auto storage_index = dynamic_cast<faiss::IndexFlat*>(real_idx->storage);
faiss::write_index(storage_index, &writer);
std::shared_ptr<uint8_t[]> data(writer.data_);
res_set.Append(writer.name, data, writer.rp);
int64_t meta_info[3] = {real_idx->storage->metric_type, real_idx->storage->d, real_idx->storage->ntotal};
auto meta_space = new uint8_t[sizeof(meta_info)];
memcpy(meta_space, meta_info, sizeof(meta_info));
std::shared_ptr<uint8_t[]> space_sp(meta_space, std::default_delete<uint8_t[]>());
res_set.Append("META", space_sp, sizeof(meta_info));
if (config.contains(INDEX_FILE_SLICE_SIZE_IN_MEGABYTE)) {
Disassemble(config[INDEX_FILE_SLICE_SIZE_IN_MEGABYTE].get<int64_t>() * 1024 * 1024, res_set);
}
@ -66,18 +66,16 @@ IndexRHNSWFlat::Load(const BinarySet& index_binary) {
try {
Assemble(const_cast<BinarySet&>(index_binary));
IndexRHNSW::Load(index_binary);
MemoryIOReader reader;
reader.name = this->index_type() + "_Data";
auto binary = index_binary.GetByName(reader.name);
reader.total = static_cast<size_t>(binary->size);
reader.data_ = binary->data.get();
int64_t meta_info[3]; // = {metric_type, dim, ntotal}
auto meta_data = index_binary.GetByName("META");
memcpy(meta_info, meta_data->data.get(), meta_data->size);
auto real_idx = dynamic_cast<faiss::IndexRHNSWFlat*>(index_.get());
if (real_idx == nullptr) {
KNOWHERE_THROW_MSG("dynamic_cast<faiss::IndexRHNSWFlat*>(index_) failed during Load!");
}
real_idx->storage = faiss::read_index(&reader);
real_idx->storage =
new faiss::IndexFlat(static_cast<faiss::idx_t>(meta_info[1]), static_cast<faiss::MetricType>(meta_info[0]));
auto binary_data = index_binary.GetByName(RAW_DATA);
real_idx->storage->add(meta_info[2], reinterpret_cast<const float*>(binary_data->data.get()));
real_idx->init_hnsw();
} catch (std::exception& e) {
KNOWHERE_THROW_MSG(e.what());

View File

@ -59,6 +59,13 @@ TEST_P(RHNSWFlatTest, HNSW_basic) {
// Serialize and Load before Query
milvus::knowhere::BinarySet bs = index_->Serialize(conf);
int64_t dim = base_dataset->Get<int64_t>(milvus::knowhere::meta::DIM);
int64_t rows = base_dataset->Get<int64_t>(milvus::knowhere::meta::ROWS);
auto raw_data = base_dataset->Get<const void*>(milvus::knowhere::meta::TENSOR);
milvus::knowhere::BinaryPtr bptr = std::make_shared<milvus::knowhere::Binary>();
bptr->data = std::shared_ptr<uint8_t[]>((uint8_t*)raw_data, [&](uint8_t*) {});
bptr->size = dim * rows * sizeof(float);
bs.Append(RAW_DATA, bptr);
auto tmp_index = std::make_shared<milvus::knowhere::IndexRHNSWFlat>();
tmp_index->Load(bs);
@ -125,30 +132,37 @@ TEST_P(RHNSWFlatTest, HNSW_serialize) {
auto binaryset = index_->Serialize(conf);
std::string index_type = index_->index_type();
std::string idx_name = index_type + "_Index";
std::string dat_name = index_type + "_Data";
std::string met_name = "META";
if (binaryset.binary_map_.find(idx_name) == binaryset.binary_map_.end()) {
std::cout << "no idx!" << std::endl;
}
if (binaryset.binary_map_.find(dat_name) == binaryset.binary_map_.end()) {
std::cout << "no dat!" << std::endl;
if (binaryset.binary_map_.find(met_name) == binaryset.binary_map_.end()) {
std::cout << "no met!" << std::endl;
}
auto bin_idx = binaryset.GetByName(idx_name);
auto bin_dat = binaryset.GetByName(dat_name);
auto bin_met = binaryset.GetByName(met_name);
std::string filename_idx = "/tmp/RHNSWFlat_test_serialize_idx.bin";
std::string filename_dat = "/tmp/RHNSWFlat_test_serialize_dat.bin";
std::string filename_met = "/tmp/RHNSWFlat_test_serialize_met.bin";
auto load_idx = new uint8_t[bin_idx->size];
auto load_dat = new uint8_t[bin_dat->size];
auto load_met = new uint8_t[bin_met->size];
serialize(filename_idx, bin_idx, load_idx);
serialize(filename_dat, bin_dat, load_dat);
serialize(filename_met, bin_met, load_met);
binaryset.clear();
auto new_idx = std::make_shared<milvus::knowhere::IndexRHNSWFlat>();
std::shared_ptr<uint8_t[]> dat(load_dat);
std::shared_ptr<uint8_t[]> met(load_met);
std::shared_ptr<uint8_t[]> idx(load_idx);
binaryset.Append(new_idx->index_type() + "_Index", idx, bin_idx->size);
binaryset.Append(new_idx->index_type() + "_Data", dat, bin_dat->size);
binaryset.Append("META", met, bin_met->size);
int64_t dim = base_dataset->Get<int64_t>(milvus::knowhere::meta::DIM);
int64_t rows = base_dataset->Get<int64_t>(milvus::knowhere::meta::ROWS);
auto raw_data = base_dataset->Get<const void*>(milvus::knowhere::meta::TENSOR);
milvus::knowhere::BinaryPtr bptr = std::make_shared<milvus::knowhere::Binary>();
bptr->data = std::shared_ptr<uint8_t[]>((uint8_t*)raw_data, [&](uint8_t*) {});
bptr->size = dim * rows * sizeof(float);
binaryset.Append(RAW_DATA, bptr);
new_idx->Load(binaryset);
EXPECT_EQ(new_idx->Count(), nb);
EXPECT_EQ(new_idx->Dim(), dim);
@ -164,6 +178,13 @@ TEST_P(RHNSWFlatTest, HNSW_slice) {
index_->AddWithoutIds(base_dataset, conf);
auto binaryset = index_->Serialize(conf);
auto new_idx = std::make_shared<milvus::knowhere::IndexRHNSWFlat>();
int64_t dim = base_dataset->Get<int64_t>(milvus::knowhere::meta::DIM);
int64_t rows = base_dataset->Get<int64_t>(milvus::knowhere::meta::ROWS);
auto raw_data = base_dataset->Get<const void*>(milvus::knowhere::meta::TENSOR);
milvus::knowhere::BinaryPtr bptr = std::make_shared<milvus::knowhere::Binary>();
bptr->data = std::shared_ptr<uint8_t[]>((uint8_t*)raw_data, [&](uint8_t*) {});
bptr->size = dim * rows * sizeof(float);
binaryset.Append(RAW_DATA, bptr);
new_idx->Load(binaryset);
EXPECT_EQ(new_idx->Count(), nb);
EXPECT_EQ(new_idx->Dim(), dim);