* -------------------------------------------------------------------------
* This file is part of the IndexSDK project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* IndexSDK is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*/
#include <unistd.h>
#include <cstdlib>
#include <string>
#include <iostream>
#include <limits.h>
#include "Utils.h"
TEST(IndexGreat, AKMode) {
int dim;
int nTotal;
auto index = CreateIndexGreat("AKMode");
std::string codebook_path = "../codebook.bin";
CreateCodebook(codebook_path);
index->AddCodeBooks(codebook_path);
std::string AModeIndexPath = "../great_vstar_128_mixed.index";
std::string KModeIndexPath = "../great_hnsw_128_mixed.index";
std::vector<float> baseData = GenRandData(g_dim, 256);
nTotal = index->GetNTotal();
index->AddVectors(baseData);
index->WriteIndex(AModeIndexPath, KModeIndexPath);
std::vector<float> queryData = GenRandData(g_dim, 10);
std::cout << "---------- start searching----------" << std::endl;
int batchSize = 5;
int topK = 10;
int gtK = 1;
int gtDim = index->GetDim();
int nb = index->GetNTotal();
size_t nq = queryData.size();
std::vector<float> dists(nq * topK);
std::vector<int64_t> labels(nq * topK);
ascendSearchacc::IndexGreatSearchParams params;
params.mode = "AKMode";
params.nProbeL1 = 72;
params.nProbeL2 = 64;
params.l3SegmentNum = 512;
params.ef = 150;
index->SetSearchParams(params);
ascendSearchacc::SearchImplParams searchparams1(batchSize, queryData, topK, dists, labels);
auto greatSearchParam = index->GetSearchParams();
for (size_t i = 0, j = 0; i < nq; i += batchSize, j++) {
index->Search(searchparams1);
}
ascendSearchacc::SearchImplParams searchparams2(1, queryData, topK, dists, labels);
for (size_t i = 0, j = 0; i < nq; i += 1, j++) {
index->Search(searchparams2);
}
ascendSearchacc::SearchImplParams searchparams3(521, queryData, topK, dists, labels);
for (size_t i = 0, j = 0; i < nq; i += 521, j++) {
index->Search(searchparams3);
}
std::remove(codebook_path.c_str());
std::remove(AModeIndexPath.c_str());
std::remove(KModeIndexPath.c_str());
}
TEST(IndexGreat, AKMode_SearchWithMask) {
int dim;
int nTotal;
auto index = CreateIndexGreat("AKMode");
std::string codebook_path = "../codebook.bin";
CreateCodebook(codebook_path);
index->AddCodeBooks(codebook_path);
std::vector<float> baseData = GenRandData(g_dim, 256);
nTotal = index->GetNTotal();
index->AddVectors(baseData);
std::vector<float> queryData = GenRandData(g_dim, 10);
std::cout << "---------- start searching----------" << std::endl;
int batchSize = 5;
int topK = 10;
int gtK = 1;
int gtDim = index->GetDim();
int nb = index->GetNTotal();
size_t nq = queryData.size();
std::vector<float> dists(nq * topK);
std::vector<int64_t> labels(nq * topK);
ascendSearchacc::IndexGreatSearchParams params;
params.mode = "AKMode";
params.nProbeL1 = 72;
params.nProbeL2 = 64;
params.l3SegmentNum = 512;
params.ef = 150;
index->SetSearchParams(params);
size_t maskDim = (nb + 7) / 8;
std::vector<uint8_t> mask1(nb * maskDim, 0);
std::vector<uint8_t> mask2(521 * maskDim, 0);
ascendSearchacc::SearchImplParams searchparams1(batchSize, queryData, topK, dists, labels);
for (size_t i = 0, j = 0; i < nq; i += batchSize, j++) {
index->SearchWithMask(searchparams1, mask1);
}
ascendSearchacc::SearchImplParams searchparams2(1, queryData, topK, dists, labels);
for (size_t i = 0, j = 0; i < nq; i += 1, j++) {
index->SearchWithMask(searchparams2, mask1);
}
ascendSearchacc::SearchImplParams searchparams3(521, queryData, topK, dists, labels);
for (size_t i = 0, j = 0; i < nq; i += 521, j++) {
index->SearchWithMask(searchparams3, mask2);
}
index->Reset();
std::remove(codebook_path.c_str());
}
TEST(IndexGreat, KMode) {
int nb;
int dim;
auto index = CreateIndexGreat("KMode");
nb = index->GetNTotal();
std::string KModeIndexPath = "../kmode.index";
std::vector<float> baseData = GenRandData(g_dim, 256);
index->AddVectors(baseData);
dim = index->GetDim();
nb = index->GetNTotal();
index->WriteIndex(KModeIndexPath);
std::vector<float> queryData = GenRandData(g_dim, 10);
std::cout << "---------- start searching----------" << std::endl;
int batchSize = 5;
int topK = 10;
int gtK = 1;
int gtDim = 128;
size_t nq = queryData.size();
std::vector<float> dists(nq * topK);
std::vector<int64_t> labels(nq * topK);
ascendSearchacc::IndexGreatSearchParams params;
params.mode = "KMode";
params.nProbeL1 = 72;
params.nProbeL2 = 64;
params.l3SegmentNum = 512;
params.ef = 150;
index->SetSearchParams(params);
ascendSearchacc::SearchImplParams searchparams1(batchSize, queryData, topK, dists, labels);
auto greatSearchParam = index->GetSearchParams();
{
printf("=================warm up start==================\n");
for (size_t i = 0; i < 100; i++) {
index->Search(searchparams1);
}
printf("================warm up end===================\n");
}
for (size_t i = 0, j = 0; i < nq; i += batchSize, j++) {
index->Search(searchparams1);
}
ascendSearchacc::SearchImplParams searchparams2(261, queryData, topK, dists, labels);
for (size_t i = 0, j = 0; i < nq; i += 261, j++) {
index->Search(searchparams2);
}
index->Reset();
std::remove(KModeIndexPath.c_str());
}
TEST(IndexGreat, KMode_SearchWithMask) {
auto index = CreateIndexGreat("KMode");
std::vector<float> baseData = GenRandData(g_dim, 256);
index->AddVectors(baseData);
std::vector<float> queryData = GenRandData(g_dim, 10);
int batchSize = 5;
int topK = 10;
int gtK = 1;
int gtDim = index->GetDim();
int nb = index->GetNTotal();
size_t nq = queryData.size();
std::vector<float> dists(nq * topK);
std::vector<int64_t> labels(nq * topK);
ascendSearchacc::IndexGreatSearchParams params;
params.mode = "KMode";
params.nProbeL1 = 72;
params.nProbeL2 = 64;
params.l3SegmentNum = 512;
params.ef = 150;
index->SetSearchParams(params);
size_t maskDim = (nb + 7) / 8;
std::vector<uint8_t> mask1(nb * maskDim, 0);
std::vector<uint8_t> mask2(521 * maskDim, 0);
ascendSearchacc::SearchImplParams searchparams1(batchSize, queryData, topK, dists, labels);
for (size_t i = 0, j = 0; i < nq; i += batchSize, j++) {
index->SearchWithMask(searchparams1, mask1);
}
ascendSearchacc::SearchImplParams searchparams2(521, queryData, topK, dists, labels);
for (size_t i = 0, j = 0; i < nq; i += 521, j++) {
index->SearchWithMask(searchparams2, mask2);
}
index->Reset();
}
TEST(IndexGreat, KMode_AddVectorsWithIds) {
auto index = CreateIndexGreat("KMode");
std::vector<float> baseData = GenRandData(g_dim, 256);
int dim = index->GetDim();
size_t num_vectors = baseData.size() / dim;
std::vector<int64_t> ids(num_vectors);
for (size_t i = 0; i < num_vectors; ++i) {
ids[i] = 1000 + i;
}
index->AddVectorsWithIds(baseData, ids);
}
TEST(IndexGreat, AKMode_AddVectorWithIds) {
auto index = CreateIndexGreat("AKMode");
std::vector<float> baseData = GenRandData(g_dim, 256);
int dim = index->GetDim();
size_t num_vectors = baseData.size() / dim;
std::vector<int64_t> ids(num_vectors);
for (size_t i = 0; i < num_vectors; ++i) {
ids[i] = 1000 + i;
}
std::string codebook_path = "../codebook.bin";
CreateCodebook(codebook_path);
index->AddCodeBooks(codebook_path);
index->AddVectorsWithIds(baseData, ids);
std::vector<float> queryData = GenRandData(g_dim, 10);
int batchSize = 5;
int topK = 10;
int gtK = 1;
int gtDim = index->GetDim();
int nq = 10;
int nb = index->GetNTotal();
std::vector<float> dists(nq * topK);
std::vector<int64_t> labels(nq * topK);
ascendSearchacc::IndexGreatSearchParams params;
params.mode = "AKMode";
params.nProbeL1 = 72;
params.nProbeL2 = 64;
params.l3SegmentNum = 512;
params.ef = 150;
index->SetSearchParams(params);
ascendSearchacc::SearchImplParams searchparams(batchSize, queryData, topK, dists, labels);
for (size_t i = 0, j = 0; i < nq; i += batchSize, j++) {
index->Search(searchparams);
}
size_t maskDim = (nb + 7) / 8;
std::vector<uint8_t> mask(nb * maskDim, 0);
for (size_t i = 0, j = 0; i < nq; i += batchSize, j++) {
index->SearchWithMask(searchparams, mask);
}
std::remove(codebook_path.c_str());
}
TEST(IndexGreat, KMode_initialize) {
std::vector<int> deviceList {0};
auto index = std::make_shared<ascendSearchacc::IndexGreat>("KMode", deviceList, true);
}
TEST(IndexGreat, AKMode_initilaize) {
std::vector<int> deviceList {0};
auto index = std::make_shared<ascendSearchacc::IndexGreat>("AKMode", deviceList, true);
}
TEST(IndexGreat, Error_initialize_1) {
std::vector<int> deviceList {0};
try {
auto index = std::make_shared<ascendSearchacc::IndexGreat>("GMode", deviceList, true);
FAIL() << "Expected AscendException but no exception was thrown";
} catch (const ascendSearchacc::AscendException& e) {
std::string errorMsg(e.what());
EXPECT_NE(errorMsg.find("Search Mode mismatched. Choose between 'KMode' and 'AKMode'."), std::string::npos);
}
}
TEST(IndexGreat, Error_initialize_2) {
try {
auto index = CreateIndexGreat("GMode");
FAIL() << "Expected AscendException but no exception was thrown";
} catch (const ascendSearchacc::AscendException& e) {
std::string errorMsg(e.what());
EXPECT_NE(errorMsg.find("Search Mode mismatched. Choose between 'KMode' and 'AKMode'."), std::string::npos);
}
}