Skip to content
Open
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
14 changes: 11 additions & 3 deletions bindings/cpp/include/svs/runtime/dynamic_vamana_index.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,18 @@ struct SVS_RUNTIME_API DynamicVamanaIndex : public VamanaIndex {
// Utility function to check storage kind support
static Status check_storage_kind(StorageKind storage_kind) noexcept;

static Status check_params(const VamanaIndex::DynamicIndexParams& dynamic_index_params
) noexcept;

// Static constructors and destructors
static Status build(
DynamicVamanaIndex** index,
size_t dim,
MetricType metric,
StorageKind storage_kind,
const VamanaIndex::BuildParams& params = {},
const VamanaIndex::SearchParams& default_search_params = {}
const VamanaIndex::SearchParams& default_search_params = {},
const VamanaIndex::DynamicIndexParams& dynamic_index_params = {}
) noexcept;

static Status destroy(DynamicVamanaIndex* index) noexcept;
Expand All @@ -58,6 +62,8 @@ struct SVS_RUNTIME_API DynamicVamanaIndex : public VamanaIndex {
MetricType metric,
StorageKind storage_kind
) noexcept;

virtual size_t blocksize_bytes() const noexcept = 0;
};

struct SVS_RUNTIME_API DynamicVamanaIndexLeanVec : public DynamicVamanaIndex {
Expand All @@ -69,7 +75,8 @@ struct SVS_RUNTIME_API DynamicVamanaIndexLeanVec : public DynamicVamanaIndex {
StorageKind storage_kind,
size_t leanvec_dims,
const VamanaIndex::BuildParams& params = {},
const VamanaIndex::SearchParams& default_search_params = {}
const VamanaIndex::SearchParams& default_search_params = {},
const VamanaIndex::DynamicIndexParams& dynamic_index_params = {}
) noexcept;

// Specialization to build LeanVec-based Vamana index with provided training data
Expand All @@ -80,7 +87,8 @@ struct SVS_RUNTIME_API DynamicVamanaIndexLeanVec : public DynamicVamanaIndex {
StorageKind storage_kind,
const LeanVecTrainingData* training_data,
const VamanaIndex::BuildParams& params = {},
const VamanaIndex::SearchParams& default_search_params = {}
const VamanaIndex::SearchParams& default_search_params = {},
const VamanaIndex::DynamicIndexParams& dynamic_index_params = {}
) noexcept;
};

Expand Down
4 changes: 4 additions & 0 deletions bindings/cpp/include/svs/runtime/vamana_index.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ struct SVS_RUNTIME_API VamanaIndex {
size_t prefetch_step = Unspecify<size_t>();
};

struct DynamicIndexParams {
size_t blocksize_exp = 30;
};

virtual Status search(
size_t n,
const float* x,
Expand Down
53 changes: 45 additions & 8 deletions bindings/cpp/src/dynamic_vamana_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ struct DynamicVamanaIndexManagerBase : public DynamicVamanaIndex {
});
}

size_t blocksize_bytes() const noexcept { return impl_->blocksize_bytes(); }

Status
remove_selected(size_t* num_removed, const IDFilter& selector) noexcept override {
return runtime_error_wrapper([&] {
Expand Down Expand Up @@ -136,19 +138,40 @@ Status DynamicVamanaIndex::check_storage_kind(StorageKind storage_kind) noexcept
);
}

Status DynamicVamanaIndex::check_params(
const DynamicVamanaIndex::DynamicIndexParams& dynamic_index_params
) noexcept {
constexpr static size_t kMaxBlockSizeExp = 30; // 1GB
constexpr static size_t kMinBlockSizeExp = 12; // 4KB

if (dynamic_index_params.blocksize_exp > kMaxBlockSizeExp)
return Status(ErrorCode::INVALID_ARGUMENT, "Blocksize is too large");

if (dynamic_index_params.blocksize_exp < kMinBlockSizeExp)
return Status(ErrorCode::INVALID_ARGUMENT, "Blocksize is too small");

return Status_Ok;
}

Status DynamicVamanaIndex::build(
DynamicVamanaIndex** index,
size_t dim,
MetricType metric,
StorageKind storage_kind,
const DynamicVamanaIndex::BuildParams& params,
const DynamicVamanaIndex::SearchParams& default_search_params
const DynamicVamanaIndex::SearchParams& default_search_params,
const DynamicVamanaIndex::DynamicIndexParams& dynamic_index_params
) noexcept {
using Impl = DynamicVamanaIndexImpl;
*index = nullptr;

auto status = DynamicVamanaIndex::check_params(dynamic_index_params);
if (!status.ok())
return status;

return runtime_error_wrapper([&] {
auto impl = std::make_unique<Impl>(
dim, metric, storage_kind, params, default_search_params
dim, metric, storage_kind, params, default_search_params, dynamic_index_params
);
*index = new DynamicVamanaIndexManagerBase<Impl>{std::move(impl)};
});
Expand Down Expand Up @@ -181,13 +204,20 @@ Status DynamicVamanaIndexLeanVec::build(
StorageKind storage_kind,
size_t leanvec_dims,
const DynamicVamanaIndex::BuildParams& params,
const DynamicVamanaIndex::SearchParams& default_search_params
const DynamicVamanaIndex::SearchParams& default_search_params,
const DynamicVamanaIndex::DynamicIndexParams& dynamic_index_params
) noexcept {
using Impl = DynamicVamanaIndexLeanVecImpl;
*index = nullptr;
return runtime_error_wrapper([&] {
auto impl = std::make_unique<Impl>(
dim, metric, storage_kind, leanvec_dims, params, default_search_params
dim,
metric,
storage_kind,
leanvec_dims,
params,
default_search_params,
dynamic_index_params
);
*index = new DynamicVamanaIndexManagerBase<Impl>{std::move(impl)};
});
Expand All @@ -201,15 +231,22 @@ Status DynamicVamanaIndexLeanVec::build(
StorageKind storage_kind,
const LeanVecTrainingData* training_data,
const DynamicVamanaIndex::BuildParams& params,
const DynamicVamanaIndex::SearchParams& default_search_params
const DynamicVamanaIndex::SearchParams& default_search_params,
const DynamicVamanaIndex::DynamicIndexParams& dynamic_index_params
) noexcept {
using Impl = DynamicVamanaIndexLeanVecImpl;
*index = nullptr;
return runtime_error_wrapper([&] {
auto training_data_impl =
static_cast<const LeanVecTrainingDataManager*>(training_data)->impl_;
auto impl = std::make_unique<Impl>(
dim, metric, storage_kind, training_data_impl, params, default_search_params
dim,
metric,
storage_kind,
training_data_impl,
params,
default_search_params,
dynamic_index_params
);
*index = new DynamicVamanaIndexManagerBase<Impl>{std::move(impl)};
});
Expand All @@ -218,15 +255,15 @@ Status DynamicVamanaIndexLeanVec::build(
#else // SVS_LEANVEC_HEADER
// LeanVec storage kind is not supported in this build configuration
Status DynamicVamanaIndexLeanVec::
build(DynamicVamanaIndex**, size_t, MetricType, StorageKind, size_t, const DynamicVamanaIndex::BuildParams&, const DynamicVamanaIndex::SearchParams&) noexcept {
build(DynamicVamanaIndex**, size_t, MetricType, StorageKind, size_t, const DynamicVamanaIndex::BuildParams&, const DynamicVamanaIndex::SearchParams&, const DynamicVamanaIndex::DynamicIndexParams&) noexcept {
return Status(
ErrorCode::NOT_IMPLEMENTED,
"DynamicVamanaIndexLeanVec is not supported in this build configuration."
);
}

Status DynamicVamanaIndexLeanVec::
build(DynamicVamanaIndex**, size_t, MetricType, StorageKind, const LeanVecTrainingData*, const DynamicVamanaIndex::BuildParams&, const DynamicVamanaIndex::SearchParams&) noexcept {
build(DynamicVamanaIndex**, size_t, MetricType, StorageKind, const LeanVecTrainingData*, const DynamicVamanaIndex::BuildParams&, const DynamicVamanaIndex::SearchParams&, const DynamicVamanaIndex::DynamicIndexParams&) noexcept {
return Status(
ErrorCode::NOT_IMPLEMENTED,
"DynamicVamanaIndexLeanVec is not supported in this build configuration."
Expand Down
30 changes: 22 additions & 8 deletions bindings/cpp/src/dynamic_vamana_index_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,15 @@ class DynamicVamanaIndexImpl {
MetricType metric,
StorageKind storage_kind,
const VamanaIndex::BuildParams& params,
const VamanaIndex::SearchParams& default_search_params
const VamanaIndex::SearchParams& default_search_params,
const VamanaIndex::DynamicIndexParams& dynamic_index_params
)
: dim_{dim}
, metric_type_{metric}
, storage_kind_{storage_kind}
, build_params_{params}
, default_search_params_{default_search_params} {
, default_search_params_{default_search_params}
, dynamic_index_params_{dynamic_index_params} {
if (!storage::is_supported_storage_kind(storage_kind)) {
throw StatusException{
ErrorCode::INVALID_ARGUMENT,
Expand All @@ -63,6 +65,8 @@ class DynamicVamanaIndexImpl {

size_t size() const { return impl_ ? impl_->size() : 0; }

size_t blocksize_bytes() const { return 1u << dynamic_index_params_.blocksize_exp; }

size_t dimensions() const { return dim_; }

MetricType metric_type() const { return metric_type_; }
Expand All @@ -71,7 +75,8 @@ class DynamicVamanaIndexImpl {

void add(data::ConstSimpleDataView<float> data, std::span<const size_t> labels) {
if (!impl_) {
return init_impl(data, labels);
auto blocksize_bytes = lib::PowerOfTwo(dynamic_index_params_.blocksize_exp);
return init_impl(data, labels, blocksize_bytes);
}

impl_->add_points(data, labels);
Expand Down Expand Up @@ -385,6 +390,7 @@ class DynamicVamanaIndexImpl {
const index::vamana::VamanaBuildParameters& parameters,
const svs::data::ConstSimpleDataView<float>& data,
std::span<const size_t> labels,
svs::lib::PowerOfTwo blocksize_bytes,
StorageArgs&&... storage_args
) {
auto threadpool = default_threadpool();
Expand All @@ -393,6 +399,7 @@ class DynamicVamanaIndexImpl {
std::forward<Tag>(tag),
data,
threadpool,
blocksize_bytes,
std::forward<StorageArgs>(storage_args)...
);

Expand All @@ -408,26 +415,32 @@ class DynamicVamanaIndexImpl {
});
}

virtual void
init_impl(data::ConstSimpleDataView<float> data, std::span<const size_t> labels) {
virtual void init_impl(
data::ConstSimpleDataView<float> data,
std::span<const size_t> labels,
lib::PowerOfTwo blocksize_bytes
) {
impl_.reset(storage::dispatch_storage_kind(
get_storage_kind(),
[this](
auto&& tag,
data::ConstSimpleDataView<float> data,
std::span<const size_t> labels
std::span<const size_t> labels,
lib::PowerOfTwo blocksize_bytes
) {
using Tag = std::decay_t<decltype(tag)>;
return build_impl(
std::forward<Tag>(tag),
this->metric_type_,
this->vamana_build_parameters(),
data,
labels
labels,
blocksize_bytes
);
},
data,
labels
labels,
blocksize_bytes
));
}

Expand Down Expand Up @@ -522,6 +535,7 @@ class DynamicVamanaIndexImpl {
StorageKind storage_kind_;
VamanaIndex::BuildParams build_params_;
VamanaIndex::SearchParams default_search_params_;
VamanaIndex::DynamicIndexParams dynamic_index_params_;
std::unique_ptr<svs::DynamicVamana> impl_;
size_t ntotal_soft_deleted{0};
};
Expand Down
24 changes: 16 additions & 8 deletions bindings/cpp/src/dynamic_vamana_index_leanvec_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@ struct DynamicVamanaIndexLeanVecImpl : public DynamicVamanaIndexImpl {
StorageKind storage_kind,
const LeanVecTrainingDataImpl& training_data,
const VamanaIndex::BuildParams& params,
const VamanaIndex::SearchParams& default_search_params
const VamanaIndex::SearchParams& default_search_params,
const VamanaIndex::DynamicIndexParams& dynamic_index_params
)
: DynamicVamanaIndexImpl{dim, metric, storage_kind, params, default_search_params}
: DynamicVamanaIndexImpl{dim, metric, storage_kind, params, default_search_params, dynamic_index_params}
, leanvec_dims_{training_data.get_leanvec_dims()}
, leanvec_matrices_{training_data.get_leanvec_matrices()} {
check_storage_kind(storage_kind);
Expand All @@ -68,9 +69,10 @@ struct DynamicVamanaIndexLeanVecImpl : public DynamicVamanaIndexImpl {
StorageKind storage_kind,
size_t leanvec_dims,
const VamanaIndex::BuildParams& params,
const VamanaIndex::SearchParams& default_search_params
const VamanaIndex::SearchParams& default_search_params,
const VamanaIndex::DynamicIndexParams& dynamic_index_params
)
: DynamicVamanaIndexImpl{dim, metric, storage_kind, params, default_search_params}
: DynamicVamanaIndexImpl{dim, metric, storage_kind, params, default_search_params, dynamic_index_params}
, leanvec_dims_{leanvec_dims}
, leanvec_matrices_{std::nullopt} {
check_storage_kind(storage_kind);
Expand All @@ -91,15 +93,19 @@ struct DynamicVamanaIndexLeanVecImpl : public DynamicVamanaIndexImpl {
}
}

void init_impl(data::ConstSimpleDataView<float> data, std::span<const size_t> labels)
override {
void init_impl(
data::ConstSimpleDataView<float> data,
std::span<const size_t> labels,
lib::PowerOfTwo blocksize_bytes
) override {
assert(storage::is_leanvec_storage(this->storage_kind_));
impl_.reset(dispatch_leanvec_storage_kind(
this->storage_kind_,
[this](
auto&& tag,
data::ConstSimpleDataView<float> data,
std::span<const size_t> labels
std::span<const size_t> labels,
lib::PowerOfTwo blocksize_bytes
) {
using Tag = std::decay_t<decltype(tag)>;
return DynamicVamanaIndexImpl::build_impl(
Expand All @@ -108,12 +114,14 @@ struct DynamicVamanaIndexLeanVecImpl : public DynamicVamanaIndexImpl {
this->vamana_build_parameters(),
data,
labels,
blocksize_bytes,
this->leanvec_dims_,
this->leanvec_matrices_
);
},
data,
labels
labels,
blocksize_bytes
));
}

Expand Down
Loading
Loading