Skip to content

Commit fdd404f

Browse files
authored
update_dataset CAGRA (#2427)
This PR introduces the `update_dataset` function in the cpp api. `update_dataset` should swap out the dataset from an index. For instance, from a device_standard_dataset_view -> device_padded_dataset_view. The major use case here is when a user builds a cagra index with a certain type of dataset. But during search they want to use a different type of dataset. This may look like device_standard_dataset_view -> device_pq_dataset_view. The type of dataset is coupled to the index type. So we need to construct a new index object altogether. To avoid copying expensive member variables like the cagra graph or source indices we simply move them to the new object instead. This means the user relinquishes the old index object. A new constructor in cagra.hpp has been introduced to move and take ownership of the resources from an existing cagra index and assign the new dataset. We intend to remove the `attach_dataset` and other helper functions such as `convert_standard_to_padded_index` and `convert_host_to_device_index`. The callers that use the removed functions should be updated to use `update_dataset` instead. Resolves #2404 ### I've annotated this PR below to make it easier to review. Authors: - Anupam (https://github.com/aamijar) Approvers: - Tarang Jain (https://github.com/tarang-jain) - Divye Gala (https://github.com/divyegala) URL: #2427
1 parent e7db5c6 commit fdd404f

32 files changed

Lines changed: 427 additions & 344 deletions

c/src/neighbors/cagra.cpp

Lines changed: 14 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ static void make_host_standard_dataset_view(raft::resources*,
529529
}
530530

531531
template <typename T>
532-
static void attach_dataset(raft::resources* res_ptr,
532+
static void update_dataset(raft::resources* res_ptr,
533533
cuvsDataset_t device_padded_dataset,
534534
cuvsCagraIndex_t index)
535535
{
@@ -542,7 +542,7 @@ static void attach_dataset(raft::resources* res_ptr,
542542
auto* box = reinterpret_cast<sg_cagra_c_api_index_box*>(index->addr);
543543
RAFT_EXPECTS(device_padded_dataset->mem_type == CUVS_DATASET_MEM_TYPE_DEVICE &&
544544
device_padded_dataset->layout == CUVS_DATASET_LAYOUT_PADDED,
545-
"cuvsCagraAttachDataset: dataset must be device padded");
545+
"cuvsCagraUpdateDataset: dataset must be device padded");
546546

547547
using owner_t = cuvs::neighbors::device_padded_dataset<T, int64_t>;
548548
using view_t = cuvs::neighbors::device_padded_dataset_view<T, int64_t>;
@@ -552,7 +552,8 @@ static void attach_dataset(raft::resources* res_ptr,
552552
"cuvsCagraUpdateDataset: null index handle",
553553
"cuvsCagraUpdateDataset: host index layout is allowed for this operation",
554554
[&](auto& idx) {
555-
auto padded_idx = cuvs::neighbors::cagra::attach_dataset(*res_ptr, idx, padded_view);
555+
auto padded_idx =
556+
cuvs::neighbors::cagra::update_dataset(*res_ptr, std::move(idx), padded_view);
556557
auto* holder =
557558
new cuvs_cagra_c_api_index_lifetime_holder<T, view_t>{std::move(padded_idx)};
558559
destroy_sg_cagra_c_api_box(index->addr);
@@ -562,53 +563,6 @@ static void attach_dataset(raft::resources* res_ptr,
562563
});
563564
}
564565

565-
template <typename T>
566-
static void update_device_dataset_same_layout(raft::resources* res_ptr,
567-
cuvsDataset_t device_dataset,
568-
cuvsCagraIndex_t index)
569-
{
570-
RAFT_EXPECTS(device_dataset != nullptr, "cuvsCagraUpdateDataset: null dataset");
571-
RAFT_EXPECTS(index != nullptr, "cuvsCagraUpdateDataset: null index handle");
572-
RAFT_EXPECTS(index->addr != 0, "cuvsCagraUpdateDataset: null index storage");
573-
RAFT_EXPECTS(device_dataset->addr != 0, "cuvsCagraUpdateDataset: null dataset storage");
574-
575-
auto* box = reinterpret_cast<sg_cagra_c_api_index_box*>(index->addr);
576-
if (box->layout == sg_cagra_c_api_index_box::dataset_layout::device_padded) {
577-
RAFT_EXPECTS(device_dataset->mem_type == CUVS_DATASET_MEM_TYPE_DEVICE &&
578-
device_dataset->layout == CUVS_DATASET_LAYOUT_PADDED,
579-
"cuvsCagraUpdateDeviceDatasetSameLayout: device-padded index "
580-
"requires a "
581-
"device-padded dataset");
582-
using owner_t = cuvs::neighbors::device_padded_dataset<T, int64_t>;
583-
using view_t = cuvs::neighbors::device_padded_dataset_view<T, int64_t>;
584-
with_dataset_view<owner_t, view_t>(device_dataset, [&](auto const& dataset_view) {
585-
auto* idx =
586-
reinterpret_cast<cuvs::neighbors::cagra::device_padded_index<T, uint32_t>*>(box->index_ptr);
587-
RAFT_EXPECTS(idx != nullptr, "cuvsCagraUpdateDataset: null index handle");
588-
idx->update_device_dataset_same_layout(*res_ptr, dataset_view);
589-
});
590-
} else if (box->layout == sg_cagra_c_api_index_box::dataset_layout::device_standard) {
591-
RAFT_EXPECTS(device_dataset->mem_type == CUVS_DATASET_MEM_TYPE_DEVICE &&
592-
device_dataset->layout == CUVS_DATASET_LAYOUT_STANDARD,
593-
"cuvsCagraUpdateDeviceDatasetSameLayout: device-standard "
594-
"index requires a "
595-
"device-standard dataset");
596-
using owner_t = cuvs::neighbors::device_standard_dataset<T, int64_t>;
597-
using view_t = cuvs::neighbors::device_standard_dataset_view<T, int64_t>;
598-
with_dataset_view<owner_t, view_t>(device_dataset, [&](auto const& dataset_view) {
599-
auto* idx =
600-
reinterpret_cast<cuvs::neighbors::cagra::device_standard_index<T, uint32_t>*>(box->index_ptr);
601-
RAFT_EXPECTS(idx != nullptr, "cuvsCagraUpdateDataset: null index handle");
602-
idx->update_device_dataset_same_layout(*res_ptr, dataset_view);
603-
});
604-
} else {
605-
RAFT_FAIL(
606-
"cuvsCagraUpdateDataset: C++ "
607-
"update_device_dataset_same_layout "
608-
"requires a device index and dataset");
609-
}
610-
}
611-
612566
static void _set_graph_build_params(
613567
std::variant<std::monostate,
614568
cuvs::neighbors::cagra::graph_build_params::ivf_pq_params,
@@ -716,7 +670,8 @@ void _from_args(cuvsResources_t res,
716670
auto dataset_view = cuvs::neighbors::make_device_padded_dataset_view(*res_ptr, mds);
717671
auto* raw = new cuvs::neighbors::cagra::device_padded_index<T, uint32_t>(
718672
*res_ptr, metric);
719-
raw->update_device_dataset_same_layout(*res_ptr, dataset_view);
673+
*raw =
674+
cuvs::neighbors::cagra::update_dataset(*res_ptr, std::move(*raw), dataset_view);
720675
update_graph_from_dlpack(raw);
721676
wrap_CPP_index_in_lifetime_holder_and_bind_to_C_index<
722677
T,
@@ -726,7 +681,8 @@ void _from_args(cuvsResources_t res,
726681
auto dataset_view = cuvs::neighbors::make_device_standard_dataset_view(mds);
727682
auto* raw = new cuvs::neighbors::cagra::device_standard_index<T, uint32_t>(
728683
*res_ptr, metric);
729-
raw->update_device_dataset_same_layout(*res_ptr, dataset_view);
684+
*raw =
685+
cuvs::neighbors::cagra::update_dataset(*res_ptr, std::move(*raw), dataset_view);
730686
update_graph_from_dlpack(raw);
731687
wrap_CPP_index_in_lifetime_holder_and_bind_to_C_index<
732688
T,
@@ -1584,7 +1540,7 @@ extern "C" cuvsError_t cuvsDatasetMakeStandardView(cuvsResources_t res,
15841540
});
15851541
}
15861542

1587-
static cuvsError_t dispatch_attach_dataset(cuvsResources_t res,
1543+
static cuvsError_t dispatch_update_dataset(cuvsResources_t res,
15881544
cuvsDataset_t device_padded_dataset,
15891545
cuvsCagraIndex_t index)
15901546
{
@@ -1598,40 +1554,13 @@ static cuvsError_t dispatch_attach_dataset(cuvsResources_t res,
15981554
index->dtype.bits == device_padded_dataset->dtype.bits,
15991555
"cuvsCagraUpdateDataset: dtype mismatch between index and dataset");
16001556
if (index->dtype.code == kDLFloat && index->dtype.bits == 32) {
1601-
attach_dataset<float>(res_ptr, device_padded_dataset, index);
1602-
} else if (index->dtype.code == kDLFloat && index->dtype.bits == 16) {
1603-
attach_dataset<half>(res_ptr, device_padded_dataset, index);
1604-
} else if (index->dtype.code == kDLInt && index->dtype.bits == 8) {
1605-
attach_dataset<int8_t>(res_ptr, device_padded_dataset, index);
1606-
} else if (index->dtype.code == kDLUInt && index->dtype.bits == 8) {
1607-
attach_dataset<uint8_t>(res_ptr, device_padded_dataset, index);
1608-
} else {
1609-
RAFT_FAIL("Unsupported index dtype: %d and bits: %d", index->dtype.code, index->dtype.bits);
1610-
}
1611-
});
1612-
}
1613-
1614-
static cuvsError_t dispatch_update_device_dataset_same_layout(cuvsResources_t res,
1615-
cuvsDataset_t device_dataset,
1616-
cuvsCagraIndex_t index)
1617-
{
1618-
return cuvs::core::translate_exceptions([=] {
1619-
auto* res_ptr = reinterpret_cast<raft::resources*>(res);
1620-
RAFT_EXPECTS(index != nullptr, "cuvsCagraUpdateDataset: null index handle");
1621-
RAFT_EXPECTS(device_dataset != nullptr,
1622-
"cuvsCagraUpdateDataset: null dataset view");
1623-
RAFT_EXPECTS(index->dtype.code == device_dataset->dtype.code &&
1624-
index->dtype.bits == device_dataset->dtype.bits,
1625-
"cuvsCagraUpdateDataset: dtype mismatch "
1626-
"between index and dataset");
1627-
if (index->dtype.code == kDLFloat && index->dtype.bits == 32) {
1628-
update_device_dataset_same_layout<float>(res_ptr, device_dataset, index);
1557+
update_dataset<float>(res_ptr, device_padded_dataset, index);
16291558
} else if (index->dtype.code == kDLFloat && index->dtype.bits == 16) {
1630-
update_device_dataset_same_layout<half>(res_ptr, device_dataset, index);
1559+
update_dataset<half>(res_ptr, device_padded_dataset, index);
16311560
} else if (index->dtype.code == kDLInt && index->dtype.bits == 8) {
1632-
update_device_dataset_same_layout<int8_t>(res_ptr, device_dataset, index);
1561+
update_dataset<int8_t>(res_ptr, device_padded_dataset, index);
16331562
} else if (index->dtype.code == kDLUInt && index->dtype.bits == 8) {
1634-
update_device_dataset_same_layout<uint8_t>(res_ptr, device_dataset, index);
1563+
update_dataset<uint8_t>(res_ptr, device_padded_dataset, index);
16351564
} else {
16361565
RAFT_FAIL("Unsupported index dtype: %d and bits: %d", index->dtype.code, index->dtype.bits);
16371566
}
@@ -1656,12 +1585,7 @@ extern "C" cuvsError_t cuvsCagraUpdateDataset(cuvsResources_t res,
16561585
"cuvsCagraUpdateDataset: dtype mismatch between index and dataset");
16571586
});
16581587
if (status != CUVS_SUCCESS) { return status; }
1659-
1660-
auto* box = reinterpret_cast<sg_cagra_c_api_index_box*>(index->addr);
1661-
if (box->layout == sg_cagra_c_api_index_box::dataset_layout::device_padded) {
1662-
return dispatch_update_device_dataset_same_layout(res, device_padded_dataset, index);
1663-
}
1664-
return dispatch_attach_dataset(res, device_padded_dataset, index);
1588+
return dispatch_update_dataset(res, device_padded_dataset, index);
16651589
}
16661590

16671591
/**

c/src/neighbors/mg_cagra.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,16 +229,16 @@ void _mg_update_dataset(cuvsResources_t res,
229229
using padded_ann_t = cuvs::neighbors::cagra::device_padded_index<T, uint32_t>;
230230
auto* standard_index = reinterpret_cast<mg_cagra_index_t<T, standard_ann_t>*>(box->index_ptr);
231231
auto* padded_index = new mg_cagra_index_t<T, padded_ann_t>(
232-
cuvs::neighbors::cagra::attach_dataset(*res_ptr, *standard_index, padded_view));
232+
cuvs::neighbors::cagra::update_dataset(
233+
*res_ptr, std::move(*standard_index), padded_view));
233234
auto* padded_box =
234235
make_mg_cagra_box<T, padded_ann_t>(padded_index, mg_cagra_dataset_layout::device_padded);
235236
destroy_mg_cagra_c_api_box(index->addr);
236237
index->addr = reinterpret_cast<uintptr_t>(padded_box);
237238
} else if (box->layout == mg_cagra_dataset_layout::device_padded) {
238239
using padded_ann_t = cuvs::neighbors::cagra::device_padded_index<T, uint32_t>;
239240
auto* padded_index = reinterpret_cast<mg_cagra_index_t<T, padded_ann_t>*>(box->index_ptr);
240-
cuvs::neighbors::cagra::update_device_dataset_same_layout(
241-
*res_ptr, *padded_index, padded_view);
241+
cuvs::neighbors::cagra::update_dataset(*res_ptr, *padded_index, padded_view);
242242
} else {
243243
RAFT_FAIL("cuvsMultiGpuCagraUpdateDataset: unsupported index dataset layout");
244244
}

cpp/bench/ann/src/cuvs/cuvs_cagra_wrapper.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,8 @@ void cuvs_cagra<T, IdxT>::compress_dataset(const T* dataset, size_t nrow)
418418
// Search runs on the compressed rows and the graph, so release the dense copy of the dataset.
419419
cuvs::neighbors::device_padded_dataset_view<T, int64_t> empty_dv(
420420
raft::make_device_matrix_view(static_cast<T const*>(nullptr), 0, this->dim_), this->dim_);
421-
index_->update_device_dataset_same_layout(handle_, empty_dv);
422-
*dataset_ = raft::make_device_matrix<T, int64_t>(handle_, 0, 0);
421+
*index_ = cuvs::neighbors::cagra::update_dataset(handle_, std::move(*index_), empty_dv);
422+
*dataset_ = raft::make_device_matrix<T, int64_t>(handle_, 0, 0);
423423
need_dataset_update_ = false;
424424
}
425425

@@ -485,7 +485,7 @@ void cuvs_cagra<T, IdxT>::set_search_param(const search_param_base& param,
485485
*dataset_ = raft::make_device_matrix<T, int64_t>(handle_, 0, 0);
486486
cuvs::neighbors::device_padded_dataset_view<T, int64_t> empty_dv(
487487
raft::make_device_matrix_view(static_cast<T const*>(nullptr), 0, this->dim_), this->dim_);
488-
index_->update_device_dataset_same_layout(handle_, empty_dv);
488+
*index_ = cuvs::neighbors::cagra::update_dataset(handle_, std::move(*index_), empty_dv);
489489

490490
// Allocate space using the correct memory resource.
491491
RAFT_LOG_DEBUG("moving dataset to new memory space: %s",
@@ -498,7 +498,7 @@ void cuvs_cagra<T, IdxT>::set_search_param(const search_param_base& param,
498498
raft::make_device_matrix_view(
499499
dataset_->data_handle(), dataset_->extent(0), dataset_->extent(1)),
500500
this->dim_);
501-
index_->update_device_dataset_same_layout(handle_, dv);
501+
*index_ = cuvs::neighbors::cagra::update_dataset(handle_, std::move(*index_), dv);
502502

503503
need_dataset_update_ = false;
504504
needs_dynamic_batcher_update = true;
@@ -562,11 +562,15 @@ void cuvs_cagra<T, IdxT>::set_search_dataset(const T* dataset, size_t nrow)
562562
auto& sub_dataset_buffer = (*sub_dataset_buffers_)[i];
563563
sub_dataset_buffer = raft::make_device_matrix<T, int64_t>(handle_, 0, 0);
564564
if (dataset_is_on_host) {
565-
sub_index->update_device_dataset_same_layout(
566-
handle_, detail::make_padded_view<T>(handle_, sub_host, sub_dataset_buffer));
565+
*sub_index = cuvs::neighbors::cagra::update_dataset(
566+
handle_,
567+
std::move(*sub_index),
568+
detail::make_padded_view<T>(handle_, sub_host, sub_dataset_buffer));
567569
} else {
568-
sub_index->update_device_dataset_same_layout(
569-
handle_, detail::make_padded_view<T>(handle_, sub_dev, sub_dataset_buffer));
570+
*sub_index = cuvs::neighbors::cagra::update_dataset(
571+
handle_,
572+
std::move(*sub_index),
573+
detail::make_padded_view<T>(handle_, sub_dev, sub_dataset_buffer));
570574
}
571575
}
572576
need_dataset_update_ = false;

0 commit comments

Comments
 (0)