#2890 Fix wrong index size (#2930)

* fix update index size

Signed-off-by: sahuang <xiaohai.xu@zilliz.com>

* add GetSize() interface 4 SPTAG

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

* fix index size of index hnsw, annoy and nsg

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

* fix clang

Signed-off-by: sahuang <xiaohai.xu@zilliz.com>

* add sdk 4 non-ivf index test

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

* remove std::cout and make clang-format

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

* fix cout

Signed-off-by: sahuang <xiaohai.xu@zilliz.com>

* checkout sdk

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

* fix binary ivf

Signed-off-by: sahuang <xiaohai.xu@zilliz.com>

* fix hnsw

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/2946/head
Xiaohai Xu 2020-07-21 14:02:44 +08:00 committed by GitHub
parent 2bfc108f5a
commit 7ba30c7830
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 337 additions and 67 deletions

View File

@ -12,7 +12,7 @@ Please mark all changes in change log and use the issue from GitHub
- \#2557 Fix random crash of INSERT_DUPLICATE_ID case
- \#2578 Result count doesn't match target vectors count
- \#2582 CreateHybridIndex.cpp compile error
- \#2585 IVF_PQ on GPU with using metric_type IP
- \#2585 Support IVF_PQ IP on GPU
- \#2598 Fix Milvus docker image report illegal instruction
- \#2617 Fix HNSW and RNSG index files size
- \#2637 Suit the range of HNSW parameters
@ -23,9 +23,10 @@ Please mark all changes in change log and use the issue from GitHub
- \#2739 Fix mishards start failed
- \#2752 Milvus formats vectors data to double-precision and return to http client
- \#2767 Fix a bug of getting wrong nprobe limitation in knowhere on GPU version
- \#2768 After building the index,the number of vectors increases
- \#2768 After building the index, the number of vectors increases
- \#2776 Fix too many data copies during creating IVF index
- \#2813 To implemente RNSG IP
- \#2890 Fix wrong index size
## Feature
- \#2319 Redo metadata to support MVCC

View File

@ -100,7 +100,8 @@ DefaultVectorIndexFormat::read_internal(const storage::FSHandlerPtr& fs_ptr, con
}
index->Load(load_data_list);
index->SetIndexSize(length);
index->UpdateIndexSize();
LOG_ENGINE_DEBUG_ << "index file size " << length << " index size " << index->IndexSize();
} else {
LOG_ENGINE_ERROR_ << "Fail to create vector index: " << path;
}

View File

@ -150,7 +150,8 @@ SSVectorIndexFormat::construct_index(const std::string& index_name, knowhere::Bi
}
index->Load(index_data);
index->SetIndexSize(length);
index->UpdateIndexSize();
LOG_ENGINE_DEBUG_ << "index file size " << length << " index size " << index->IndexSize();
} else {
std::string err_msg = "Fail to create vector index";
LOG_ENGINE_ERROR_ << err_msg;

View File

@ -270,7 +270,7 @@ GetIndexName(int32_t index_type) {
#endif
{(int32_t)engine::EngineType::FAISS_BIN_IDMAP, "IDMAP"},
{(int32_t)engine::EngineType::FAISS_BIN_IVFFLAT, "IVFFLAT"},
{(int32_t)engine::EngineType::HNSW_SQ8NR, "HNSW_SQ8NR"},
{(int32_t)engine::EngineType::HNSW_SQ8NM, "HNSW_SQ8NM"},
{(int32_t)engine::EngineType::HNSW, "HNSW"},
{(int32_t)engine::EngineType::NSG_MIX, "NSG"},
{(int32_t)engine::EngineType::ANNOY, "ANNOY"}};

View File

@ -100,7 +100,7 @@ GetIndexDataType(EngineType type) {
case EngineType::NSG_MIX:
return codec::ExternalData::ExternalData_RawData;
case EngineType::HNSW_SQ8NR:
case EngineType::HNSW_SQ8NM:
case EngineType::FAISS_IVFSQ8NR:
return codec::ExternalData::ExternalData_SQ8;
@ -244,8 +244,8 @@ ExecutionEngineImpl::CreatetVecIndex(EngineType type) {
index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_HNSW, mode);
break;
}
case EngineType::HNSW_SQ8NR: {
index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_HNSW_SQ8NR, mode);
case EngineType::HNSW_SQ8NM: {
index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_HNSW_SQ8NM, mode);
break;
}
case EngineType::ANNOY: {
@ -396,7 +396,7 @@ ExecutionEngineImpl::Serialize() {
// here we reset index size by file size,
// since some index type(such as SQ8) data size become smaller after serialized
index_->SetIndexSize(CommonUtil::GetFileSize(location_));
index_->UpdateIndexSize();
LOG_ENGINE_DEBUG_ << "Finish serialize index file: " << location_ << " size: " << index_->Size();
if (index_->Size() == 0) {

View File

@ -41,8 +41,8 @@ enum class EngineType {
HNSW = 11,
ANNOY = 12,
FAISS_IVFSQ8NR = 13,
HNSW_SQ8NR = 14,
MAX_VALUE = HNSW_SQ8NR,
HNSW_SQ8NM = 14,
MAX_VALUE = HNSW_SQ8NM,
};
static std::map<std::string, EngineType> s_map_engine_type = {
@ -58,7 +58,7 @@ static std::map<std::string, EngineType> s_map_engine_type = {
{knowhere::IndexEnum::INDEX_SPTAG_BKT_RNT, EngineType::SPTAG_BKT},
#endif
{knowhere::IndexEnum::INDEX_HNSW, EngineType::HNSW},
{knowhere::IndexEnum::INDEX_HNSW_SQ8NR, EngineType::HNSW_SQ8NR},
{knowhere::IndexEnum::INDEX_HNSW_SQ8NM, EngineType::HNSW_SQ8NM},
{knowhere::IndexEnum::INDEX_ANNOY, EngineType::ANNOY}};
enum class MetricType {

View File

@ -71,7 +71,7 @@ set(vector_offset_index_srcs
knowhere/index/vector_offset_index/IndexIVFSQNR_NM.cpp
knowhere/index/vector_offset_index/IndexHNSW_NM.cpp
knowhere/index/vector_offset_index/IndexNSG_NM.cpp
knowhere/index/vector_offset_index/IndexHNSW_SQ8NR.cpp
knowhere/index/vector_offset_index/IndexHNSW_SQ8NM.cpp
)
if (MILVUS_SUPPORT_SPTAG)

View File

@ -38,7 +38,7 @@ static std::unordered_map<int32_t, std::string> old_index_type_str_map = {
#endif
{(int32_t)OldIndexType::HNSW, IndexEnum::INDEX_HNSW},
{(int32_t)OldIndexType::ANNOY, IndexEnum::INDEX_ANNOY},
{(int32_t)OldIndexType::HNSW_SQ8NR, IndexEnum::INDEX_HNSW_SQ8NR},
{(int32_t)OldIndexType::HNSW_SQ8NM, IndexEnum::INDEX_HNSW_SQ8NM},
{(int32_t)OldIndexType::FAISS_IVFSQ8NR, IndexEnum::INDEX_FAISS_IVFSQ8NR},
{(int32_t)OldIndexType::FAISS_BIN_IDMAP, IndexEnum::INDEX_FAISS_BIN_IDMAP},
{(int32_t)OldIndexType::FAISS_BIN_IVFLAT_CPU, IndexEnum::INDEX_FAISS_BIN_IVFFLAT},
@ -59,7 +59,7 @@ static std::unordered_map<std::string, int32_t> str_old_index_type_map = {
{IndexEnum::INDEX_HNSW, (int32_t)OldIndexType::HNSW},
{IndexEnum::INDEX_ANNOY, (int32_t)OldIndexType::ANNOY},
{IndexEnum::INDEX_FAISS_IVFSQ8NR, (int32_t)OldIndexType::FAISS_IVFSQ8NR},
{IndexEnum::INDEX_HNSW_SQ8NR, (int32_t)OldIndexType::HNSW_SQ8NR},
{IndexEnum::INDEX_HNSW_SQ8NM, (int32_t)OldIndexType::HNSW_SQ8NM},
{IndexEnum::INDEX_FAISS_BIN_IDMAP, (int32_t)OldIndexType::FAISS_BIN_IDMAP},
{IndexEnum::INDEX_FAISS_BIN_IVFFLAT, (int32_t)OldIndexType::FAISS_BIN_IVFLAT_CPU},
};
@ -82,7 +82,7 @@ const char* INDEX_SPTAG_BKT_RNT = "SPTAG_BKT_RNT";
#endif
const char* INDEX_HNSW = "HNSW";
const char* INDEX_ANNOY = "ANNOY";
const char* INDEX_HNSW_SQ8NR = "HNSW_SQ8NR";
const char* INDEX_HNSW_SQ8NM = "HNSW_SQ8NM";
} // namespace IndexEnum
std::string

View File

@ -36,7 +36,7 @@ enum class OldIndexType {
HNSW,
ANNOY,
FAISS_IVFSQ8NR,
HNSW_SQ8NR,
HNSW_SQ8NM,
FAISS_BIN_IDMAP = 100,
FAISS_BIN_IVFLAT_CPU = 101,
};
@ -61,7 +61,7 @@ extern const char* INDEX_SPTAG_BKT_RNT;
#endif
extern const char* INDEX_HNSW;
extern const char* INDEX_ANNOY;
extern const char* INDEX_HNSW_SQ8NR;
extern const char* INDEX_HNSW_SQ8NM;
} // namespace IndexEnum
enum class IndexMode { MODE_CPU = 0, MODE_GPU = 1 };

View File

@ -49,7 +49,7 @@ AdapterMgr::RegisterAdapter() {
#endif
REGISTER_CONF_ADAPTER(HNSWConfAdapter, IndexEnum::INDEX_HNSW, hnsw_adapter);
REGISTER_CONF_ADAPTER(ANNOYConfAdapter, IndexEnum::INDEX_ANNOY, annoy_adapter);
REGISTER_CONF_ADAPTER(HNSWSQ8NRConfAdapter, IndexEnum::INDEX_HNSW_SQ8NR, hnswsq8nr_adapter);
REGISTER_CONF_ADAPTER(HNSWSQ8NRConfAdapter, IndexEnum::INDEX_HNSW_SQ8NM, hnswsq8nr_adapter);
REGISTER_CONF_ADAPTER(IVFSQ8NRConfAdapter, IndexEnum::INDEX_FAISS_IVFSQ8NR, ivfsq8nr_adapter);
}

View File

@ -159,5 +159,13 @@ IndexAnnoy::Dim() {
return index_->get_dim();
}
void
IndexAnnoy::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
index_size_ = index_->cal_size();
}
} // namespace knowhere
} // namespace milvus

View File

@ -62,6 +62,9 @@ class IndexAnnoy : public VecIndex {
int64_t
Dim() override;
void
UpdateIndexSize() override;
private:
MetricType metric_type_;
std::shared_ptr<AnnoyIndexInterface<int64_t, float>> index_ = nullptr;

View File

@ -145,6 +145,20 @@ BinaryIVF::Dim() {
return index_->d;
}
void
BinaryIVF::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
auto bin_ivf_index = dynamic_cast<faiss::IndexBinaryIVF*>(index_.get());
auto nb = bin_ivf_index->invlists->compute_ntotal();
auto nlist = bin_ivf_index->nlist;
auto code_size = bin_ivf_index->code_size;
// binary ivf codes, ids and quantizer
index_size_ = nb * code_size + nb * sizeof(int64_t) + nlist * code_size;
}
void
BinaryIVF::Train(const DatasetPtr& dataset_ptr, const Config& config) {
GET_TENSOR(dataset_ptr)

View File

@ -73,6 +73,9 @@ class BinaryIVF : public VecIndex, public FaissBaseBinaryIndex {
int64_t
Dim() override;
void
UpdateIndexSize() override;
#if 0
DatasetPtr
GetVectorById(const DatasetPtr& dataset_ptr, const Config& config);

View File

@ -83,9 +83,9 @@ IndexHNSW::Train(const DatasetPtr& dataset_ptr, const Config& config) {
hnswlib::SpaceInterface<float>* space;
if (config[Metric::TYPE] == Metric::L2) {
space = new hnswlib::L2Space(dim);
space = new hnswlib_nm::L2Space(dim);
} else if (config[Metric::TYPE] == Metric::IP) {
space = new hnswlib::InnerProductSpace(dim);
space = new hnswlib_nm::InnerProductSpace(dim);
normalize = true;
}
index_ = std::make_shared<hnswlib::HierarchicalNSW<float>>(space, rows, config[IndexParams::M].get<int64_t>(),
@ -206,5 +206,13 @@ IndexHNSW::Dim() {
return (*(size_t*)index_->dist_func_param_);
}
void
IndexHNSW::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
index_size_ = index_->cal_size();
}
} // namespace knowhere
} // namespace milvus

View File

@ -54,6 +54,9 @@ class IndexHNSW : public VecIndex {
int64_t
Dim() override;
void
UpdateIndexSize() override;
private:
bool normalize = false;
std::mutex mutex_;

View File

@ -239,6 +239,19 @@ IVF::Seal() {
SealImpl();
}
void
IVF::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
auto ivf_index = dynamic_cast<faiss::IndexIVFFlat*>(index_.get());
auto nb = ivf_index->invlists->compute_ntotal();
auto nlist = ivf_index->nlist;
auto code_size = ivf_index->code_size;
// ivf codes, ivf ids and quantizer
index_size_ = nb * code_size + nb * sizeof(int64_t) + nlist * code_size;
}
VecIndexPtr
IVF::CopyCpuToGpu(const int64_t device_id, const Config& config) {
#ifdef MILVUS_GPU_VERSION

View File

@ -64,6 +64,9 @@ class IVF : public VecIndex, public FaissBaseIndex {
int64_t
Dim() override;
void
UpdateIndexSize() override;
#if 0
DatasetPtr
GetVectorById(const DatasetPtr& dataset, const Config& config) override;

View File

@ -73,5 +73,28 @@ IVFPQ::GenParams(const Config& config) {
return params;
}
void
IVFPQ::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
auto ivfpq_index = dynamic_cast<faiss::IndexIVFPQ*>(index_.get());
auto nb = ivfpq_index->invlists->compute_ntotal();
auto code_size = ivfpq_index->code_size;
auto pq = ivfpq_index->pq;
auto nlist = ivfpq_index->nlist;
auto d = ivfpq_index->d;
// ivf codes, ivf ids and quantizer
auto capacity = nb * code_size + nb * sizeof(int64_t) + nlist * d * sizeof(float);
auto centroid_table = pq.M * pq.ksub * pq.dsub * sizeof(float);
auto precomputed_table = nlist * pq.M * pq.ksub * sizeof(float);
if (precomputed_table > ivfpq_index->precomputed_table_max_bytes) {
// will not precompute table
precomputed_table = 0;
}
index_size_ = capacity + centroid_table + precomputed_table;
}
} // namespace knowhere
} // namespace milvus

View File

@ -35,6 +35,9 @@ class IVFPQ : public IVF {
VecIndexPtr
CopyCpuToGpu(const int64_t, const Config&) override;
void
UpdateIndexSize() override;
protected:
std::shared_ptr<faiss::IVFSearchParameters>
GenParams(const Config& config) override;

View File

@ -70,5 +70,19 @@ IVFSQ::CopyCpuToGpu(const int64_t device_id, const Config& config) {
#endif
}
void
IVFSQ::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
auto ivfsq_index = dynamic_cast<faiss::IndexIVFScalarQuantizer*>(index_.get());
auto nb = ivfsq_index->invlists->compute_ntotal();
auto code_size = ivfsq_index->code_size;
auto nlist = ivfsq_index->nlist;
auto d = ivfsq_index->d;
// ivf codes, ivf ids, sq trained vectors and quantizer
index_size_ = nb * code_size + nb * sizeof(int64_t) + 2 * d * sizeof(float) + nlist * d * sizeof(float);
}
} // namespace knowhere
} // namespace milvus

View File

@ -34,6 +34,9 @@ class IVFSQ : public IVF {
VecIndexPtr
CopyCpuToGpu(const int64_t, const Config&) override;
void
UpdateIndexSize() override;
};
using IVFSQPtr = std::shared_ptr<IVFSQ>;

View File

@ -172,5 +172,13 @@ NSG::Dim() {
return index_->dimension;
}
void
NSG::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
index_size_ = index_->GetSize();
}
} // namespace knowhere
} // namespace milvus

View File

@ -214,6 +214,14 @@ CPUSPTAGRNG::Dim() {
return index_ptr_->GetFeatureDim();
}
void
CPUSPTAGRNG::UpdateIndexSize() {
if (!index_ptr_) {
KNOWHERE_THROW_MSG("index not initialize");
}
index_size_ = index_ptr_->GetIndexSize();
}
// void
// CPUSPTAGRNG::Add(const DatasetPtr& origin, const Config& add_config) {
// SetParameters(add_config);

View File

@ -60,6 +60,9 @@ class CPUSPTAGRNG : public VecIndex {
int64_t
Dim() override;
void
UpdateIndexSize() override;
private:
void
SetParameters(const Config& config);

View File

@ -133,6 +133,10 @@ class VecIndex : public Index {
index_size_ = size;
}
virtual void
UpdateIndexSize() {
}
int64_t
Size() override {
return BlacklistSize() + UidsSize() + IndexSize();

View File

@ -21,7 +21,7 @@
#include "knowhere/index/vector_index/IndexIVFPQ.h"
#include "knowhere/index/vector_index/IndexIVFSQ.h"
#include "knowhere/index/vector_offset_index/IndexHNSW_NM.h"
#include "knowhere/index/vector_offset_index/IndexHNSW_SQ8NR.h"
#include "knowhere/index/vector_offset_index/IndexHNSW_SQ8NM.h"
#include "knowhere/index/vector_offset_index/IndexIVFSQNR_NM.h"
#include "knowhere/index/vector_offset_index/IndexIVF_NM.h"
#include "knowhere/index/vector_offset_index/IndexNSG_NM.h"
@ -92,8 +92,8 @@ VecIndexFactory::CreateVecIndex(const IndexType& type, const IndexMode mode) {
return std::make_shared<knowhere::IndexAnnoy>();
} else if (type == IndexEnum::INDEX_FAISS_IVFSQ8NR) {
return std::make_shared<knowhere::IVFSQNR_NM>();
} else if (type == IndexEnum::INDEX_HNSW_SQ8NR) {
return std::make_shared<knowhere::IndexHNSW_SQ8NR>();
} else if (type == IndexEnum::INDEX_HNSW_SQ8NM) {
return std::make_shared<knowhere::IndexHNSW_SQ8NM>();
} else {
return nullptr;
}

View File

@ -10,6 +10,7 @@
// 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 <faiss/IndexSQHybrid.h>
#include <faiss/gpu/GpuCloner.h>
#include <faiss/gpu/GpuIndexIVF.h>
#include <faiss/index_factory.h>
@ -261,6 +262,20 @@ IVFSQHybrid::QueryImpl(int64_t n, const float* data, int64_t k, float* distances
}
}
void
IVFSQHybrid::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
auto ivfsqh_index = dynamic_cast<faiss::IndexIVFSQHybrid*>(index_.get());
auto nb = ivfsqh_index->invlists->compute_ntotal();
auto code_size = ivfsqh_index->code_size;
auto nlist = ivfsqh_index->nlist;
auto d = ivfsqh_index->d;
// ivf codes, ivf ids, sq trained vectors and quantizer
index_size_ = nb * code_size + nb * sizeof(int64_t) + 2 * d * sizeof(float) + nlist * d * sizeof(float);
}
FaissIVFQuantizer::~FaissIVFQuantizer() {
if (quantizer != nullptr) {
delete quantizer;

View File

@ -77,6 +77,9 @@ class IVFSQHybrid : public GPUIVFSQ {
void
UnsetQuantizer();
void
UpdateIndexSize() override;
protected:
BinarySet
SerializeImpl(const IndexType&) override;

View File

@ -873,6 +873,22 @@ NsgIndex::SetKnnGraph(Graph& g) {
knng = std::move(g);
}
int64_t
NsgIndex::GetSize() {
int64_t ret = 0;
ret += sizeof(*this);
ret += ntotal * dimension * sizeof(float);
ret += ntotal * sizeof(int64_t);
ret += sizeof(*distance_);
for (auto i = 0; i < nsg.size(); ++i) {
ret += nsg[i].size() * sizeof(node_t);
}
for (auto i = 0; i < knng.size(); ++i) {
ret += knng[i].size() * sizeof(node_t);
}
return ret;
}
} // namespace impl
} // namespace knowhere
} // namespace milvus

View File

@ -86,6 +86,9 @@ class NsgIndex {
Search(const float* query, float* data, const unsigned& nq, const unsigned& dim, const unsigned& k, float* dist,
int64_t* ids, SearchParams& params, faiss::ConcurrentBitsetPtr bitset = nullptr);
int64_t
GetSize();
// Not support yet.
// virtual void Add() = 0;
// virtual void Add_with_ids() = 0;

View File

@ -187,5 +187,13 @@ IndexHNSW_NM::Dim() {
return (*(size_t*)index_->dist_func_param_);
}
void
IndexHNSW_NM::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
index_size_ = index_->cal_size();
}
} // namespace knowhere
} // namespace milvus

View File

@ -55,6 +55,9 @@ class IndexHNSW_NM : public VecIndex {
int64_t
Dim() override;
void
UpdateIndexSize() override;
private:
bool normalize = false;
std::mutex mutex_;

View File

@ -9,7 +9,7 @@
// 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_offset_index/IndexHNSW_SQ8NR.h"
#include "knowhere/index/vector_offset_index/IndexHNSW_SQ8NM.h"
#include <algorithm>
#include <cassert>
@ -29,7 +29,7 @@ namespace milvus {
namespace knowhere {
BinarySet
IndexHNSW_SQ8NR::Serialize(const Config& config) {
IndexHNSW_SQ8NM::Serialize(const Config& config) {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize or trained");
}
@ -49,7 +49,7 @@ IndexHNSW_SQ8NR::Serialize(const Config& config) {
}
void
IndexHNSW_SQ8NR::Load(const BinarySet& index_binary) {
IndexHNSW_SQ8NM::Load(const BinarySet& index_binary) {
try {
auto binary = index_binary.GetByName("HNSW_SQ8");
@ -71,7 +71,7 @@ IndexHNSW_SQ8NR::Load(const BinarySet& index_binary) {
}
void
IndexHNSW_SQ8NR::Train(const DatasetPtr& dataset_ptr, const Config& config) {
IndexHNSW_SQ8NM::Train(const DatasetPtr& dataset_ptr, const Config& config) {
try {
GET_TENSOR_DATA_DIM(dataset_ptr)
@ -93,7 +93,7 @@ IndexHNSW_SQ8NR::Train(const DatasetPtr& dataset_ptr, const Config& config) {
}
void
IndexHNSW_SQ8NR::Add(const DatasetPtr& dataset_ptr, const Config& config) {
IndexHNSW_SQ8NM::Add(const DatasetPtr& dataset_ptr, const Config& config) {
// It will not call Query() just after Add()
// So, not to set 'data_' is allowed.
@ -116,7 +116,7 @@ IndexHNSW_SQ8NR::Add(const DatasetPtr& dataset_ptr, const Config& config) {
}
DatasetPtr
IndexHNSW_SQ8NR::Query(const DatasetPtr& dataset_ptr, const Config& config) {
IndexHNSW_SQ8NM::Query(const DatasetPtr& dataset_ptr, const Config& config) {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize or trained");
}
@ -168,7 +168,7 @@ IndexHNSW_SQ8NR::Query(const DatasetPtr& dataset_ptr, const Config& config) {
}
int64_t
IndexHNSW_SQ8NR::Count() {
IndexHNSW_SQ8NM::Count() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
@ -176,12 +176,20 @@ IndexHNSW_SQ8NR::Count() {
}
int64_t
IndexHNSW_SQ8NR::Dim() {
IndexHNSW_SQ8NM::Dim() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
return (*(size_t*)index_->dist_func_param_);
}
void
IndexHNSW_SQ8NM::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
index_size_ = index_->cal_size() + Dim() * (2 * sizeof(float) + Count());
}
} // namespace knowhere
} // namespace milvus

View File

@ -22,10 +22,10 @@
namespace milvus {
namespace knowhere {
class IndexHNSW_SQ8NR : public VecIndex {
class IndexHNSW_SQ8NM : public VecIndex {
public:
IndexHNSW_SQ8NR() {
index_type_ = IndexEnum::INDEX_HNSW_SQ8NR;
IndexHNSW_SQ8NM() {
index_type_ = IndexEnum::INDEX_HNSW_SQ8NM;
}
BinarySet
@ -54,6 +54,9 @@ class IndexHNSW_SQ8NR : public VecIndex {
int64_t
Dim() override;
void
UpdateIndexSize() override;
private:
bool normalize = false;
std::mutex mutex_;

View File

@ -205,5 +205,18 @@ IVFSQNR_NM::ArrangeCodes(const DatasetPtr& dataset_ptr, const Config& config) {
data_ = std::shared_ptr<uint8_t[]>(arranged_data);
}
void
IVFSQNR_NM::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
auto ivfsq_index = dynamic_cast<faiss::IndexIVFScalarQuantizer*>(index_.get());
auto nb = ivfsq_index->invlists->compute_ntotal();
auto nlist = ivfsq_index->nlist;
auto d = ivfsq_index->d;
// ivf ids, sq trained vectors and quantizer
index_size_ = nb * sizeof(int64_t) + 2 * d * sizeof(float) + nlist * d * sizeof(float);
}
} // namespace knowhere
} // namespace milvus

View File

@ -54,6 +54,9 @@ class IVFSQNR_NM : public IVF_NM {
void
ArrangeCodes(const DatasetPtr&, const Config&);
void
UpdateIndexSize() override;
};
using IVFSQNRNMPtr = std::shared_ptr<IVFSQNR_NM>;

View File

@ -351,5 +351,18 @@ IVF_NM::Dim() {
return index_->d;
}
void
IVF_NM::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
auto ivf_index = dynamic_cast<faiss::IndexIVFFlat*>(index_.get());
auto nb = ivf_index->invlists->compute_ntotal();
auto nlist = ivf_index->nlist;
auto d = ivf_index->d;
// ivf ids and quantizer
index_size_ = nb * sizeof(int64_t) + nlist * d * sizeof(float);
}
} // namespace knowhere
} // namespace milvus

View File

@ -64,6 +64,9 @@ class IVF_NM : public VecIndex, public OffsetBaseIndex {
int64_t
Dim() override;
void
UpdateIndexSize() override;
#if 0
DatasetPtr
GetVectorById(const DatasetPtr& dataset, const Config& config) override;

View File

@ -173,5 +173,13 @@ NSG_NM::Dim() {
return index_->dimension;
}
void
NSG_NM::UpdateIndexSize() {
if (!index_) {
KNOWHERE_THROW_MSG("index not initialize");
}
index_size_ = index_->GetSize();
}
} // namespace knowhere
} // namespace milvus

View File

@ -67,6 +67,9 @@ class NSG_NM : public VecIndex {
int64_t
Dim() override;
void
UpdateIndexSize() override;
private:
std::mutex mutex_;
int64_t gpu_;

View File

@ -79,6 +79,7 @@ namespace SPTAG
~Index() {}
inline SizeType GetNumSamples() const { return m_pSamples.R(); }
inline SizeType GetIndexSize() const { return sizeof(*this); }
inline DimensionType GetFeatureDim() const { return m_pSamples.C(); }
inline int GetCurrMaxCheck() const { return m_iMaxCheck; }

View File

@ -79,6 +79,7 @@ namespace SPTAG
~Index() {}
inline SizeType GetNumSamples() const { return m_pSamples.R(); }
inline SizeType GetIndexSize() const { return sizeof(*this); }
inline DimensionType GetFeatureDim() const { return m_pSamples.C(); }
inline int GetCurrMaxCheck() const { return m_iMaxCheck; }

View File

@ -37,6 +37,7 @@ public:
virtual DimensionType GetFeatureDim() const = 0;
virtual SizeType GetNumSamples() const = 0;
virtual SizeType GetIndexSize() const = 0;
virtual DistCalcMethod GetDistCalcMethod() const = 0;
virtual IndexAlgoType GetIndexAlgoType() const = 0;

View File

@ -850,6 +850,7 @@ class AnnoyIndexInterface {
virtual void get_item(S item, T* v) const = 0;
virtual void set_seed(int q) = 0;
virtual bool on_disk_build(const char* filename, char** error=nullptr) = 0;
virtual int64_t cal_size() = 0;
};
template<typename S, typename T, typename Distance, typename Random>
@ -1396,6 +1397,14 @@ protected:
result->push_back(nns_dist[i].second);
}
}
int64_t cal_size() {
int64_t ret = 0;
ret += sizeof(*this);
ret += _roots.size() * sizeof(S);
ret += std::max(_n_nodes, _nodes_size) * _s;
return ret;
}
};
#endif

View File

@ -75,7 +75,6 @@ class HierarchicalNSW : public AlgorithmInterface<dist_t> {
throw std::runtime_error("Not enough memory: HierarchicalNSW failed to allocate linklists");
size_links_per_element_ = maxM_ * sizeof(tableint) + sizeof(linklistsizeint);
mult_ = 1 / log(1.0 * M_);
revSize_ = 1.0 / mult_;
}
struct CompareByFirst {
@ -113,7 +112,7 @@ class HierarchicalNSW : public AlgorithmInterface<dist_t> {
size_t maxM0_;
size_t ef_construction_;
double mult_, revSize_;
double mult_;
int maxlevel_;
@ -709,7 +708,6 @@ class HierarchicalNSW : public AlgorithmInterface<dist_t> {
if (linkLists_ == nullptr)
throw std::runtime_error("Not enough memory: loadIndex failed to allocate linklists");
element_levels_ = std::vector<int>(max_elements);
revSize_ = 1.0 / mult_;
ef_ = 10;
for (size_t i = 0; i < cur_element_count; i++) {
label_lookup_[getExternalLabel(i)]=i;
@ -846,7 +844,6 @@ class HierarchicalNSW : public AlgorithmInterface<dist_t> {
if (linkLists_ == nullptr)
throw std::runtime_error("Not enough memory: loadIndex failed to allocate linklists");
element_levels_ = std::vector<int>(max_elements);
revSize_ = 1.0 / mult_;
ef_ = 10;
for (size_t i = 0; i < cur_element_count; i++) {
label_lookup_[getExternalLabel(i)]=i;
@ -1139,6 +1136,21 @@ class HierarchicalNSW : public AlgorithmInterface<dist_t> {
std::priority_queue<std::pair<dist_t, labeltype >> ret;
return ret;
}
int64_t cal_size() {
int64_t ret = 0;
ret += sizeof(*this);
ret += sizeof(*space);
ret += visited_list_pool_->GetSize();
ret += link_list_locks_.size() * sizeof(std::mutex);
ret += element_levels_.size() * sizeof(int);
ret += max_elements_ * size_data_per_element_;
ret += max_elements_ * sizeof(void*);
for (auto i = 0; i < max_elements_; ++ i) {
ret += linkLists_[i] ? size_links_per_element_ * element_levels_[i] : 0;
}
return ret;
}
};
}

View File

@ -1208,6 +1208,20 @@ namespace hnswlib_nm {
return result;
}
int64_t cal_size() {
int64_t ret = 0;
ret += sizeof(*this);
ret += sizeof(*space);
ret += visited_list_pool_->GetSize();
ret += link_list_locks_.size() * sizeof(std::mutex);
ret += element_levels_.size() * sizeof(int);
ret += max_elements_ * size_data_per_element_;
ret += max_elements_ * sizeof(void*);
for (auto i = 0; i < max_elements_; ++ i) {
ret += linkLists_[i] ? size_links_per_element_ * element_levels_[i] : 0;
}
return ret;
}
};
}

View File

@ -27,6 +27,7 @@ class VisitedList {
}
};
~VisitedList() { delete[] mass; }
};
@ -75,6 +76,12 @@ class VisitedListPool {
delete rez;
}
};
int64_t GetSize() {
auto visit_list_size = sizeof(VisitedList) + numelements * sizeof(vl_type);
auto pool_size = pool.size() * (sizeof(VisitedList *) + visit_list_size);
return pool_size + sizeof(*this);
}
};
}

View File

@ -210,14 +210,14 @@ install(TARGETS test_hnsw DESTINATION unittest)
################################################################################
#<HNSWSQ8NR-TEST>
set(hnsw_sq8nr_srcs
${INDEX_SOURCE_DIR}/knowhere/knowhere/index/vector_offset_index/IndexHNSW_SQ8NR.cpp
set(hnsw_sq8nm_srcs
${INDEX_SOURCE_DIR}/knowhere/knowhere/index/vector_offset_index/IndexHNSW_SQ8NM.cpp
)
if (NOT TARGET test_hnsw_sq8nr)
add_executable(test_hnsw_sq8nr test_hnsw_sq8nr.cpp ${hnsw_sq8nr_srcs} ${util_srcs})
if (NOT TARGET test_hnsw_sq8nm)
add_executable(test_hnsw_sq8nm test_hnsw_sq8nm.cpp ${hnsw_sq8nm_srcs} ${util_srcs})
endif ()
target_link_libraries(test_hnsw_sq8nr ${depend_libs} ${unittest_libs} ${basic_libs})
install(TARGETS test_hnsw_sq8nr DESTINATION unittest)
target_link_libraries(test_hnsw_sq8nm ${depend_libs} ${unittest_libs} ${basic_libs})
install(TARGETS test_hnsw_sq8nm DESTINATION unittest)
################################################################################
#<SPTAG-TEST>

View File

@ -10,7 +10,7 @@
// or implied. See the License for the specific language governing permissions and limitations under the License.
#include <gtest/gtest.h>
#include <knowhere/index/vector_offset_index/IndexHNSW_SQ8NR.h>
#include <knowhere/index/vector_offset_index/IndexHNSW_SQ8NM.h>
#include <src/index/knowhere/knowhere/index/vector_index/helpers/IndexParameter.h>
#include <iostream>
#include <random>
@ -29,7 +29,7 @@ class HNSWSQ8NRTest : public DataGen, public TestWithParam<std::string> {
std::cout << "IndexType from GetParam() is: " << IndexType << std::endl;
Generate(64, 10000, 10); // dim = 64, nb = 10000, nq = 10
// Generate(2, 10, 2); // dim = 64, nb = 10000, nq = 10
index_ = std::make_shared<milvus::knowhere::IndexHNSW_SQ8NR>();
index_ = std::make_shared<milvus::knowhere::IndexHNSW_SQ8NM>();
conf = milvus::knowhere::Config{
{milvus::knowhere::meta::DIM, 64}, {milvus::knowhere::meta::TOPK, 10},
{milvus::knowhere::IndexParams::M, 16}, {milvus::knowhere::IndexParams::efConstruction, 200},
@ -46,7 +46,7 @@ class HNSWSQ8NRTest : public DataGen, public TestWithParam<std::string> {
protected:
milvus::knowhere::Config conf;
std::shared_ptr<milvus::knowhere::IndexHNSW_SQ8NR> index_ = nullptr;
std::shared_ptr<milvus::knowhere::IndexHNSW_SQ8NM> index_ = nullptr;
std::string IndexType;
};
@ -162,8 +162,8 @@ TEST_P(HNSWSQ8NRTest, HNSW_serialize) {
auto bin_index = binaryset.GetByName("HNSW_SQ8");
auto bin_sq8 = binaryset.GetByName(SQ8_DATA);
std::string filename = "/tmp/HNSW_SQ8NR_test_serialize_index.bin";
std::string filename2 = "/tmp/HNSW_SQ8NR_test_serialize_sq8.bin";
std::string filename = "/tmp/HNSW_SQ8NM_test_serialize_index.bin";
std::string filename2 = "/tmp/HNSW_SQ8NM_test_serialize_sq8.bin";
auto load_index_data = new uint8_t[bin_index->size];
serialize(filename, bin_index, load_index_data);
auto load_sq8_data = new uint8_t[bin_sq8->size];

View File

@ -330,11 +330,11 @@ TEST_P(IVFTest, invalid_gpu_source) {
auto invalid_conf = ParamGenerator::GetInstance().Gen(index_type_);
invalid_conf[milvus::knowhere::meta::DEVICEID] = -1;
if (index_type_ == milvus::knowhere::IndexEnum::INDEX_FAISS_IVFFLAT) {
// null faiss index
index_->SetIndexSize(0);
milvus::knowhere::cloner::CopyGpuToCpu(index_, milvus::knowhere::Config());
}
// if (index_type_ == milvus::knowhere::IndexEnum::INDEX_FAISS_IVFFLAT) {
// null faiss index
// index_->SetIndexSize(0);
// milvus::knowhere::cloner::CopyGpuToCpu(index_, milvus::knowhere::Config());
// }
index_->Train(base_dataset, conf_);

View File

@ -248,7 +248,7 @@ ValidateIndexParams(const milvus::json& index_params, const engine::meta::Collec
}
break;
}
case (int32_t)engine::EngineType::HNSW_SQ8NR:
case (int32_t)engine::EngineType::HNSW_SQ8NM:
case (int32_t)engine::EngineType::HNSW: {
auto status = CheckParameterRange(index_params, knowhere::IndexParams::M, 4, 64);
if (!status.ok()) {
@ -298,7 +298,7 @@ ValidateSearchParams(const milvus::json& search_params, const engine::meta::Coll
}
break;
}
case (int32_t)engine::EngineType::HNSW_SQ8NR:
case (int32_t)engine::EngineType::HNSW_SQ8NM:
case (int32_t)engine::EngineType::HNSW: {
auto status = CheckParameterRange(search_params, knowhere::IndexParams::ef, topk, 4096);
if (!status.ok()) {

View File

@ -24,7 +24,7 @@ const char* NAME_ENGINE_TYPE_IVFPQ = "IVFPQ";
const char* NAME_ENGINE_TYPE_HNSW = "HNSW";
const char* NAME_ENGINE_TYPE_ANNOY = "ANNOY";
const char* NAME_ENGINE_TYPE_IVFSQ8NR = "IVFSQ8NR";
const char* NAME_ENGINE_TYPE_HNSWSQ8NR = "HNSWSQ8NR";
const char* NAME_ENGINE_TYPE_HNSWSQ8NM = "HNSWSQ8NM";
const char* NAME_METRIC_TYPE_L2 = "L2";
const char* NAME_METRIC_TYPE_IP = "IP";
@ -57,7 +57,7 @@ const std::unordered_map<engine::EngineType, std::string> IndexMap = {
{engine::EngineType::HNSW, NAME_ENGINE_TYPE_HNSW},
{engine::EngineType::ANNOY, NAME_ENGINE_TYPE_ANNOY},
{engine::EngineType::FAISS_IVFSQ8NR, NAME_ENGINE_TYPE_IVFSQ8NR},
{engine::EngineType::HNSW_SQ8NR, NAME_ENGINE_TYPE_HNSWSQ8NR}};
{engine::EngineType::HNSW_SQ8NM, NAME_ENGINE_TYPE_HNSWSQ8NM}};
const std::unordered_map<std::string, engine::EngineType> IndexNameMap = {
{NAME_ENGINE_TYPE_FLAT, engine::EngineType::FAISS_IDMAP},
@ -69,7 +69,7 @@ const std::unordered_map<std::string, engine::EngineType> IndexNameMap = {
{NAME_ENGINE_TYPE_HNSW, engine::EngineType::HNSW},
{NAME_ENGINE_TYPE_ANNOY, engine::EngineType::ANNOY},
{NAME_ENGINE_TYPE_IVFSQ8NR, engine::EngineType::FAISS_IVFSQ8NR},
{NAME_ENGINE_TYPE_HNSWSQ8NR, engine::EngineType::HNSW_SQ8NR}};
{NAME_ENGINE_TYPE_HNSWSQ8NM, engine::EngineType::HNSW_SQ8NM}};
const std::unordered_map<engine::MetricType, std::string> MetricMap = {
{engine::MetricType::L2, NAME_METRIC_TYPE_L2},

View File

@ -28,7 +28,7 @@ extern const char* NAME_ENGINE_TYPE_IVFSQ8H;
extern const char* NAME_ENGINE_TYPE_RNSG;
extern const char* NAME_ENGINE_TYPE_IVFPQ;
extern const char* NAME_ENGINE_TYPE_HNSW;
extern const char* NAME_ENGINE_TYPE_HNSW_SQ8NR;
extern const char* NAME_ENGINE_TYPE_HNSW_SQ8NM;
extern const char* NAME_ENGINE_TYPE_ANNOY;
extern const char* NAME_METRIC_TYPE_L2;

View File

@ -38,8 +38,7 @@ class LessItemCacheMgr : public milvus::cache::CacheMgr<milvus::cache::DataObjPt
class MockVecIndex : public milvus::knowhere::VecIndex {
public:
MockVecIndex(int64_t dim, int64_t total) : dim_(dim), ntotal_(total) {
int64_t data_size = Dim() * Count() * sizeof(float);
SetIndexSize(data_size);
index_size_ = Dim() * Count() * sizeof(float);
}
virtual void

View File

@ -319,4 +319,4 @@ ClientTest::Test() {
DropIndex(collection_name);
DropCollection(collection_name);
}
}

View File

@ -113,8 +113,8 @@ Utils::IndexTypeName(const milvus::IndexType& index_type) {
return "SPTAGBKT";
case milvus::IndexType::HNSW:
return "HNSW";
case milvus::IndexType::HNSW_SQ8NR:
return "HNSW_SQ8NR";
case milvus::IndexType::HNSW_SQ8NM:
return "HNSW_SQ8NM";
case milvus::IndexType::ANNOY:
return "ANNOY";
case milvus::IndexType::IVFSQ8NR:

View File

@ -40,7 +40,7 @@ enum class IndexType {
HNSW = 11,
ANNOY = 12,
IVFSQ8NR = 13,
HNSW_SQ8NR = 14,
HNSW_SQ8NM = 14,
};
enum class MetricType {