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
8 changes: 8 additions & 0 deletions cpp/bench/ann/src/cuvs/cuvs_ann_bench_param_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,14 @@ void parse_build_param(const nlohmann::json& conf,
throw std::runtime_error("invalid value for merge_type");
}
}

nlohmann::json comp_search_conf = collect_conf_with_prefix(conf, "compression_");
if (!comp_search_conf.empty()) {
auto vpq_pams = param.compression.value_or(cuvs::neighbors::vpq_params{});
parse_build_param(comp_search_conf, vpq_pams);
param.compression.emplace(vpq_pams);
}

param.cagra_params = [conf](raft::matrix_extent<int64_t> extents,
cuvs::distance::DistanceType dist_type) {
// Delayed parsing/initialization of cagra_params - it's called once the dataset shape is known
Expand Down
80 changes: 35 additions & 45 deletions cpp/bench/ann/src/cuvs/cuvs_cagra_diskann_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@
#include <cuvs/neighbors/hnsw.hpp>
#include <raft/core/logger.hpp>

#include <algorithm>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iterator>
#include <memory>
#include <optional>
#include <variant>

#include "../common/ann_types.hpp"
#include "../common/blob.hpp"
#include "../common/conf.hpp"
#include "../diskann/diskann_wrapper.h"
#include "cuvs_ann_bench_utils.h"
#include <cuvs/neighbors/vamana.hpp>
Expand Down Expand Up @@ -165,51 +171,35 @@ void cuvs_cagra_diskann<T, IdxT>::save(const std::string& file) const
index_of.close();
if (!index_of) { RAFT_FAIL("Error writing output %s", file.c_str()); }

// try allocating a buffer for the dataset on host
try {
auto const* idx_ptr = cagra_build_.get_index();
std::optional<raft::host_matrix<T, int64_t>> h_dataset = std::nullopt;
auto const& data_view = idx_ptr->dataset();
if constexpr (cuvs::neighbors::is_padded_dataset_view_v<std::decay_t<decltype(data_view)>>) {
auto const& v = data_view;
auto n_rows = v.n_rows();
auto dim = v.dim();
auto stride = v.stride();
h_dataset.emplace(raft::make_host_matrix<T, int64_t>(n_rows, dim));
raft::copy_matrix(h_dataset->data_handle(),
dim,
v.view().data_handle(),
stride,
dim,
n_rows,
raft::resource::get_cuda_stream(handle_));
} else {
RAFT_LOG_DEBUG("dataset serialization: index dataset is not device_padded_dataset_view");
}

if (h_dataset.has_value()) {
raft::resource::sync_stream(handle_);
std::string dataset_base_file = file + ".data";
std::ofstream dataset_of(dataset_base_file, std::ios::out | std::ios::binary);
if (!dataset_of) { RAFT_FAIL("Cannot open file %s", dataset_base_file.c_str()); }
size_t dataset_file_offset = 0;
int size = static_cast<int>(cagra_build_.get_index()->size());
int dim = static_cast<int>(cagra_build_.get_index()->dim());
dataset_of.seekp(dataset_file_offset, dataset_of.beg);
dataset_of.write((char*)&size, sizeof(int));
dataset_of.write((char*)&dim, sizeof(int));
for (int i = 0; i < size; i++) {
dataset_of.write((char*)(h_dataset->data_handle() + i * h_dataset->extent(1)),
dim * sizeof(T));
}
dataset_of.close();
if (!dataset_of) { RAFT_FAIL("Error writing output %s", dataset_base_file.c_str()); }
}
} catch (std::bad_alloc& e) {
RAFT_LOG_INFO("Failed to serialize dataset");
} catch (raft::logic_error& e) {
RAFT_LOG_INFO("Failed to serialize dataset");
}
// Write the rows next to the graph; diskann::Index::load() reads them from `<file>.data`.
// The benchmark base file is already in the same bin format, so copy it rather than pull the
// rows out of memory - this way `save()` does not care where the dataset was allocated.
const auto& ds_conf = configuration::singleton().get_dataset_conf();
blob_file<T> base{ds_conf.base_file, ds_conf.subset_first_row, ds_conf.subset_size};
int size = static_cast<int>(base.rows_limit());
int dim = static_cast<int>(base.n_cols());
RAFT_EXPECTS(dim == this->dim_, "base_file dimensionality does not match the index");

size_t header_bytes = 2 * sizeof(uint32_t);
size_t skip_bytes = sizeof(T) * static_cast<size_t>(base.rows_offset()) * dim;
size_t copy_bytes = sizeof(T) * static_cast<size_t>(size) * dim;
RAFT_EXPECTS(std::filesystem::file_size(base.path()) >= header_bytes + skip_bytes + copy_bytes,
"base_file is shorter than its header claims");

std::ifstream base_in(base.path(), std::ios::in | std::ios::binary);
if (!base_in) { RAFT_FAIL("Cannot open file %s", base.path().c_str()); }
base_in.seekg(header_bytes + skip_bytes);

std::string dataset_base_file = file + ".data";
std::ofstream dataset_of(dataset_base_file, std::ios::out | std::ios::binary);
if (!dataset_of) { RAFT_FAIL("Cannot open file %s", dataset_base_file.c_str()); }
dataset_of.write((char*)&size, sizeof(int));
dataset_of.write((char*)&dim, sizeof(int));
std::copy_n(std::istreambuf_iterator<char>(base_in),
copy_bytes,
std::ostreambuf_iterator<char>(dataset_of));
dataset_of.close();
if (!base_in || !dataset_of) { RAFT_FAIL("Error writing output %s", dataset_base_file.c_str()); }
}

template <typename T, typename IdxT>
Expand Down
Loading
Loading