Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmake/libs/libdiskann.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ include_directories(${double-conversion_INCLUDE_DIRS})
set(DISKANN_SOURCES
thirdparty/DiskANN/src/ann_exception.cpp
thirdparty/DiskANN/src/aux_utils.cpp
thirdparty/DiskANN/src/navigation_build.cpp
thirdparty/DiskANN/src/distance.cpp
thirdparty/DiskANN/src/index.cpp
thirdparty/DiskANN/src/linux_aligned_file_reader.cpp
Expand Down
1 change: 1 addition & 0 deletions include/knowhere/comp/index_param.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ constexpr const char* INDEX_HNSW_PRQ = "HNSW_PRQ";
constexpr const char* INDEX_HNSW_RABITQ = "HNSW_RABITQ";

constexpr const char* INDEX_DISKANN = "DISKANN";
constexpr const char* INDEX_DISKANN_RABITQ = "DISKANN_RABITQ";
constexpr const char* INDEX_AISAQ = "AISAQ";
constexpr const char* INDEX_MINHASH_LSH = "MINHASH_LSH";

Expand Down
1 change: 1 addition & 0 deletions include/knowhere/index/index_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ static std::set<std::pair<std::string, VecType>> legal_knowhere_index = {
{IndexEnum::INDEX_DISKANN, VecType::VECTOR_FLOAT},
{IndexEnum::INDEX_DISKANN, VecType::VECTOR_FLOAT16},
{IndexEnum::INDEX_DISKANN, VecType::VECTOR_BFLOAT16},
{IndexEnum::INDEX_DISKANN_RABITQ, VecType::VECTOR_FLOAT},

// aisaq
{IndexEnum::INDEX_AISAQ, VecType::VECTOR_FLOAT},
Expand Down
4 changes: 3 additions & 1 deletion python/knowhere/knowhere.i
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ class IndexWrap {
public:
IndexWrap(const std::string& name, const int32_t& version) {
GILReleaser rel;
if (name == std::string(knowhere::IndexEnum::INDEX_DISKANN) || name == std::string(knowhere::IndexEnum::INDEX_CARDINAL_TIERED)) {
if (name == std::string(knowhere::IndexEnum::INDEX_DISKANN) ||
name == std::string(knowhere::IndexEnum::INDEX_DISKANN_RABITQ) ||
name == std::string(knowhere::IndexEnum::INDEX_CARDINAL_TIERED)) {
std::shared_ptr<milvus::FileManager> file_manager = std::make_shared<milvus::LocalFileManager>();
auto diskann_pack = knowhere::Pack(file_manager);
idx = IndexFactory::Instance().Create<T>(name, version,
Expand Down
42 changes: 42 additions & 0 deletions src/index/diskann/build_files.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (C) 2026 Zilliz. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
#pragma once

#include <string>
#include <unordered_set>

#include "filemanager/FileManager.h"

namespace knowhere {
// Publication may have partial effects that FileManager cannot roll back.
// The caller must retain completed local outputs before attempting uploads.
class DiskANNBuildRegistration {
public:
explicit DiskANNBuildRegistration(milvus::FileManager& manager) : manager_(manager) {
}
DiskANNBuildRegistration(const DiskANNBuildRegistration&) = delete;
DiskANNBuildRegistration&
operator=(const DiskANNBuildRegistration&) = delete;
bool
Reserve(const std::string& path) {
// Check before creating local outputs: FileManager implementations may
// consult the local filesystem as well as their registered objects.
const auto exists = manager_.IsExisted(path);
if (!exists.has_value() || exists.value()) {
return false;
}
reserved_.insert(path);
return true;
}
bool
Add(const std::string& path) {
if (!reserved_.count(path))
return false;
return manager_.AddFile(path);
}

private:
milvus::FileManager& manager_;
std::unordered_set<std::string> reserved_;
};
} // namespace knowhere
338 changes: 273 additions & 65 deletions src/index/diskann/diskann.cc

Large diffs are not rendered by default.

11 changes: 2 additions & 9 deletions src/index/diskann/diskann_aisaq.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "diskann/aisaq.h"
#include "diskann/aux_utils.h"
#include "diskann/linux_aligned_file_reader.h"
#include "diskann/navigation_build.h"
#include "diskann/pq_flash_aisaq_index.h"
#include "diskann/pq_flash_index.h"
#include "filemanager/FileManager.h"
Expand Down Expand Up @@ -213,14 +214,9 @@ TryDiskANNCall(std::function<void()>&& diskann_call) {
std::vector<std::string>
GetNecessaryFilenames(const std::string& prefix, const bool need_norm, const bool use_sample_cache,
const bool use_sample_warmup, const bool rearrange, const bool entry_points) {
std::vector<std::string> filenames;
auto pq_pivots_filename = diskann::get_pq_pivots_filename(prefix);
auto filenames = diskann::pq_navigation_files(prefix, rearrange);
auto disk_index_filename = diskann::get_disk_index_filename(prefix);

filenames.push_back(pq_pivots_filename);
filenames.push_back(diskann::get_pq_rearrangement_perm_filename(pq_pivots_filename));
filenames.push_back(diskann::get_pq_chunk_offsets_filename(pq_pivots_filename));
filenames.push_back(diskann::get_pq_centroid_filename(pq_pivots_filename));
filenames.push_back(disk_index_filename);
if (need_norm) {
filenames.push_back(diskann::get_disk_index_max_base_norm_file(disk_index_filename));
Expand All @@ -230,9 +226,6 @@ GetNecessaryFilenames(const std::string& prefix, const bool need_norm, const boo
}
if (rearrange) {
filenames.push_back(diskann::get_index_rearranged_filename(prefix));
filenames.push_back(diskann::get_pq_compressed_rearranged_filename(prefix));
} else {
filenames.push_back(diskann::get_pq_compressed_filename(prefix));
}
if (entry_points) {
filenames.push_back(diskann::get_index_entry_points_filename(prefix));
Expand Down
70 changes: 67 additions & 3 deletions src/index/diskann/diskann_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

namespace knowhere {

class DiskANNNavigationConfig;
Status
ValidateNavigationConfig(const DiskANNNavigationConfig& config, std::string* error);

namespace {

constexpr const CFG_INT::value_type kSearchListSizeMinValue = 16;
Expand Down Expand Up @@ -116,7 +120,8 @@ class DiskANNConfig : public BaseConfig {
KNOWHERE_CONFIG_DECLARE_FIELD(disk_pq_dims)
.description("the dimension of compressed vectors stored on the ssd, use 0 to store uncompressed data.")
.set_default(0)
.for_train();
.for_train()
.for_static();
KNOWHERE_CONFIG_DECLARE_FIELD(accelerate_build)
.description("a flag to enbale fast build.")
.set_default(false)
Expand All @@ -126,13 +131,15 @@ class DiskANNConfig : public BaseConfig {
.set_default(0)
.set_range(0, std::numeric_limits<CFG_FLOAT::value_type>::max())
.for_train()
.for_deserialize();
.for_deserialize()
.for_static();
KNOWHERE_CONFIG_DECLARE_FIELD(search_cache_budget_gb)
.description("the size of cached nodes in GB.")
.set_default(0)
.set_range(0, std::numeric_limits<CFG_FLOAT::value_type>::max())
.for_train()
.for_deserialize();
.for_deserialize()
.for_static();
KNOWHERE_CONFIG_DECLARE_FIELD(warm_up)
.description("should do warm up before search.")
.set_default(false)
Expand Down Expand Up @@ -195,5 +202,62 @@ class DiskANNConfig : public BaseConfig {
return Status::success;
}
};

// Codec selection and codec-specific knobs are validated at this boundary;
// the disk graph searcher receives only a query-local distance computer.
class DiskANNNavigationConfig : public DiskANNConfig {
public:
CFG_STRING navigation_codec;
CFG_INT rbq_bits;
CFG_INT rbq_bits_query;

KNOWHERE_DECLARE_CONFIG(DiskANNNavigationConfig) {
KNOWHERE_CONFIG_DECLARE_FIELD(navigation_codec)
.description("navigation codec: build defaults to PQ; load detects stored codec unless constrained")
.allow_empty_without_default()
.for_train()
.for_deserialize()
.for_static();
KNOWHERE_CONFIG_DECLARE_FIELD(rbq_bits)
.description("number of RaBitQ bits per database vector dimension; build defaults to 1")
.allow_empty_without_default()
.set_range(1, 9)
.for_train()
.for_static();
KNOWHERE_CONFIG_DECLARE_FIELD(rbq_bits_query)
.description("query bits for the RaBitQ coarse estimator; 0 uses FP32")
.set_default(4)
.set_range(0, 8)
.for_search();
}

Status
CheckAndAdjust(PARAM_TYPE param_type, std::string* err_msg) override {
const auto base_status = DiskANNConfig::CheckAndAdjust(param_type, err_msg);
if (base_status != Status::success) {
return base_status;
}
return ValidateNavigationConfig(*this, err_msg);
}
};

class DiskANNRaBitQConfig : public DiskANNNavigationConfig {
public:
KNOWHERE_DECLARE_CONFIG(DiskANNRaBitQConfig) {
KNOWHERE_CONFIG_DECLARE_FIELD(navigation_codec)
.description("DISKANN_RABITQ fixes the navigation codec to RABITQ")
.set_default("RABITQ")
.for_train()
.for_deserialize()
.for_static();
}
Status
CheckAndAdjust(PARAM_TYPE type, std::string* error) override {
if (navigation_codec.value_or("RABITQ") != "RABITQ") {
return HandleError(error, "DISKANN_RABITQ requires navigation_codec=RABITQ", Status::invalid_args);
}
return DiskANNNavigationConfig::CheckAndAdjust(type, error);
}
};
} // namespace knowhere
#endif /* DISKANN_CONFIG_H */
Loading
Loading