Skip to content
Merged
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
6 changes: 4 additions & 2 deletions c/src/neighbors/all_neighbors.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION.
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION.
* SPDX-License-Identifier: Apache-2.0
*/

Expand All @@ -16,7 +16,9 @@
#include <cuvs/neighbors/ivf_pq.h>
#include <cuvs/neighbors/nn_descent.h>
#include <cuvs/neighbors/all_neighbors.hpp>
#include <cuvs/neighbors/graph_build_types.hpp>
#include <cuvs/neighbors/brute_force.hpp>
#include <cuvs/neighbors/ivf_pq.hpp>
#include <cuvs/neighbors/nn_descent.hpp>

#include "../core/exceptions.hpp"
#include "../core/interop.hpp"
Expand Down
1 change: 0 additions & 1 deletion c/src/neighbors/cagra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include <cuvs/neighbors/cagra.h>
#include <cuvs/neighbors/common.h>
#include <cuvs/neighbors/cagra.hpp>
#include <cuvs/neighbors/graph_build_types.hpp>

#include "../core/exceptions.hpp"
#include "../core/interop.hpp"
Expand Down
7 changes: 5 additions & 2 deletions cpp/include/cuvs/neighbors/all_neighbors.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION.
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION.
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <cuvs/neighbors/graph_build_types.hpp>
#include <cuvs/neighbors/brute_force.hpp>
#include <cuvs/neighbors/ivf_pq.hpp>
#include <cuvs/neighbors/nn_descent.hpp>

#include <variant>

namespace cuvs::neighbors::all_neighbors {
Expand Down
10 changes: 9 additions & 1 deletion cpp/include/cuvs/neighbors/brute_force.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2024, NVIDIA CORPORATION.
* SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION.
* SPDX-License-Identifier: Apache-2.0
*/

Expand Down Expand Up @@ -926,3 +926,11 @@ void deserialize(raft::resources const& handle,
*/

} // namespace cuvs::neighbors::brute_force

/** Specialized parameters utilizing brute force to build knn graph */
namespace cuvs::neighbors::graph_build_params {
struct brute_force_params {
cuvs::neighbors::brute_force::index_params build_params;
cuvs::neighbors::brute_force::search_params search_params;
};
} // namespace cuvs::neighbors::graph_build_params
68 changes: 67 additions & 1 deletion cpp/include/cuvs/neighbors/cagra.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include "common.hpp"
#include <cuvs/distance/distance.hpp>
#include <cuvs/neighbors/common.hpp>
#include <cuvs/neighbors/graph_build_types.hpp>
#include <cuvs/neighbors/ivf_pq.hpp>
#include <cuvs/neighbors/nn_descent.hpp>
#include <cuvs/util/file_io.hpp>
Expand All @@ -31,6 +30,73 @@
#include <string>
#include <variant>

namespace cuvs::neighbors::graph_build_params {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder- could we put these in all_neighbors.hpp and include in cagra.hpp? I know it sounds awkward to do this today, but if we consider that CAGRA will be using all_neighbors soon to build the underlying all-neighbors graph then that'll feel more natural. We could even add a comment in cagra.hpp where we include all_neighbors.hpp, stating that CAGRA shoudl beusing that soon (and maybe link to a Github issue so we remember to remove the comment eventually).

using iterative_search_params = cuvs::neighbors::search_params;

/** Specialized parameters for ACE (Augmented Core Extraction) graph build */
struct ace_params {
/**
* Number of partitions for ACE (Augmented Core Extraction) partitioned build.
*
* When set to 0 (default), the number of partitions is automatically derived
* based on available host and GPU memory to maximize partition size while
* ensuring the build fits in memory.
*
* Small values might improve recall but potentially degrade performance and
* increase memory usage. Partitions should not be too small to prevent issues
* in KNN graph construction. The partition size is on average 2 * (n_rows / npartitions) * dim *
* sizeof(T). 2 is because of the core and augmented vectors. Please account for imbalance in the
* partition sizes (up to 3x in our tests).
*
* If the specified number of partitions results in partitions that exceed
* available memory, the value will be automatically increased to fit memory
* constraints and a warning will be issued.
*/
size_t npartitions = 0;
/**
* The index quality for the ACE build.
*
* Bigger values increase the index quality. At some point, increasing this will no longer improve
* the quality.
*/
size_t ef_construction = 120;
/**
* Directory to store ACE build artifacts (e.g., KNN graph, optimized graph).
*
* Used when `use_disk` is true or when the graph does not fit in host and GPU
* memory. This should be the fastest disk in the system and hold enough space
* for twice the dataset, final graph, and label mapping.
*/
std::string build_dir = "/tmp/ace_build";
/**
* Whether to use disk-based storage for ACE build.
*
* When true, enables disk-based operations for memory-efficient graph construction.
*/
bool use_disk = false;

/**
* Maximum host memory to use for ACE build in GiB.
*
* When set to 0 (default), uses available host memory.
* When set to a positive value, limits host memory usage to the specified amount.
* Useful for testing or when running alongside other memory-intensive processes.
*/
double max_host_memory_gb = 0;
/**
* Maximum GPU memory to use for ACE build in GiB.
*
* When set to 0 (default), uses available GPU memory.
* When set to a positive value, limits GPU memory usage to the specified amount.
* Useful for testing or when running alongside other memory-intensive processes.
*/
double max_gpu_memory_gb = 0;

ace_params() = default;
};

} // namespace cuvs::neighbors::graph_build_params

namespace cuvs::neighbors::cagra {
// For re-exporting into cagra namespace
namespace graph_build_params = cuvs::neighbors::graph_build_params;
Expand Down
3 changes: 3 additions & 0 deletions cpp/include/cuvs/neighbors/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ namespace cuvs::neighbors {
* @{
*/

/* Graph build algo used in cagra and all_neighbors */
enum GRAPH_BUILD_ALGO { BRUTE_FORCE = 0, IVF_PQ = 1, NN_DESCENT = 2, ACE = 3 };

/** Parameters for VPQ compression. */
struct vpq_params {
/**
Expand Down
163 changes: 0 additions & 163 deletions cpp/include/cuvs/neighbors/graph_build_types.hpp

This file was deleted.

2 changes: 1 addition & 1 deletion cpp/include/cuvs/neighbors/hnsw.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "common.hpp"

#include <cuvs/distance/distance.hpp>
#include <cuvs/neighbors/graph_build_types.hpp>
#include <cuvs/neighbors/cagra.hpp>

#include "cagra.hpp"
#include <raft/core/host_mdspan.hpp>
Expand Down
69 changes: 69 additions & 0 deletions cpp/include/cuvs/neighbors/ivf_pq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3358,3 +3358,72 @@ void resize_list(raft::resources const& res,
} // namespace helpers

} // namespace cuvs::neighbors::ivf_pq

namespace cuvs::neighbors::graph_build_params {
/** Specialized parameters utilizing IVF-PQ to build knn graph */
struct ivf_pq_params {
cuvs::neighbors::ivf_pq::index_params build_params;
cuvs::neighbors::ivf_pq::search_params search_params;
float refinement_rate = 1.0;

ivf_pq_params() = default;

/**
* Set default parameters based on shape of the input dataset.
* Usage example:
* @code{.cpp}
* using namespace cuvs::neighbors;
* raft::resources res;
* // create index_params for a [N. D] dataset
* auto dataset = raft::make_device_matrix<float, int64_t>(res, N, D);
* auto pq_params =
* graph_build_params::ivf_pq_params(dataset.extents());
* // modify/update index_params as needed
* pq_params.kmeans_trainset_fraction = 0.1;
* @endcode
*/
ivf_pq_params(raft::matrix_extent<int64_t> dataset_extents,
cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded)
{
build_params = ivf_pq::index_params::from_dataset(dataset_extents, metric);
auto n_rows = dataset_extents.extent(0);
auto n_features = dataset_extents.extent(1);
if (n_features <= 32) {
build_params.pq_dim = 16;
build_params.pq_bits = 8;
} else {
build_params.pq_bits = 4;
if (n_features <= 64) {
build_params.pq_dim = 32;
} else if (n_features <= 128) {
build_params.pq_dim = 64;
} else if (n_features <= 192) {
build_params.pq_dim = 96;
} else {
build_params.pq_dim = raft::round_up_safe<uint32_t>(n_features / 2, 128);
}
}

build_params.n_lists = std::max<uint32_t>(1, n_rows / 2000);
build_params.kmeans_n_iters = 10;

const double kMinPointsPerCluster = 32;
const double min_kmeans_trainset_points = kMinPointsPerCluster * build_params.n_lists;
const double max_kmeans_trainset_fraction = 1.0;
const double min_kmeans_trainset_fraction =
std::min(max_kmeans_trainset_fraction, min_kmeans_trainset_points / n_rows);
build_params.kmeans_trainset_fraction = std::clamp(
1.0 / std::sqrt(n_rows * 1e-5), min_kmeans_trainset_fraction, max_kmeans_trainset_fraction);
build_params.codebook_kind = ivf_pq::codebook_gen::PER_SUBSPACE;

search_params = cuvs::neighbors::ivf_pq::search_params{};
search_params.n_probes = std::round(std::sqrt(build_params.n_lists) / 20 + 4);
search_params.lut_dtype = CUDA_R_16F;
search_params.internal_distance_dtype = CUDA_R_16F;
search_params.coarse_search_dtype = CUDA_R_16F;
search_params.max_internal_batch_size = 128 * 1024;

refinement_rate = 1;
}
};
} // namespace cuvs::neighbors::graph_build_params
Loading