Skip to content

Commit

Permalink
add nn-descent to python cagra
Browse files Browse the repository at this point in the history
  • Loading branch information
divyegala committed Sep 14, 2023
1 parent 4f0e425 commit c55ae4e
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 12 deletions.
2 changes: 2 additions & 0 deletions cpp/include/raft/neighbors/detail/nn_descent.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,8 @@ void GNND<Data_t, Index_t>::local_join(cudaStream_t stream)
template <typename Data_t, typename Index_t>
void GNND<Data_t, Index_t>::build(Data_t* data, const Index_t nrow, Index_t* output_graph)
{
using input_t = typename std::remove_const<Data_t>::type;

cudaStream_t stream = raft::resource::get_cuda_stream(res);
nrow_ = nrow;
graph_.h_graph = (InternalID_t<Index_t>*)output_graph;
Expand Down
23 changes: 12 additions & 11 deletions python/pylibraft/pylibraft/neighbors/cagra/cagra.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -104,24 +104,29 @@ cdef class IndexParams:
graph_degree : int, default = 64
add_data_on_build : bool, default = True
After training the coarse and fine quantizers, we will populate
the index with the dataset if add_data_on_build == True, otherwise
the index is left empty, and the extend method can be used
to add new vectors to the index.
build_algo: string denoting the graph building algorithm to use,
default = "ivf_pq"
Valid values for algo: ["ivf_pq", "nn_descent"], where
- ivf_pq will use the IVF-PQ algorithm for building the knn graph
- nn_descent (experimental) will use the NN-Descent algorithm for
building the knn graph. It is expected to be generally
faster than ivf_pq.
"""
cdef c_cagra.index_params params

def __init__(self, *,
metric="sqeuclidean",
intermediate_graph_degree=128,
graph_degree=64,
add_data_on_build=True):
build_algo="ivf_pq"):
self.params.metric = _get_metric(metric)
self.params.metric_arg = 0
self.params.intermediate_graph_degree = intermediate_graph_degree
self.params.graph_degree = graph_degree
self.params.add_data_on_build = add_data_on_build
if build_algo == "ivf_pq":
self.params.build_algo = c_cagra.graph_build_algo.IVF_PQ
elif build_algo == "nn_descent":
self.params.build_algo = c_cagra.graph_build_algo.NN_DESCENT

@property
def metric(self):
Expand All @@ -135,10 +140,6 @@ cdef class IndexParams:
def graph_degree(self):
return self.params.graph_degree

@property
def add_data_on_build(self):
return self.params.add_data_on_build


cdef class Index:
cdef readonly bool trained
Expand Down
5 changes: 5 additions & 0 deletions python/pylibraft/pylibraft/neighbors/cagra/cpp/c_cagra.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,14 @@ from pylibraft.neighbors.ivf_pq.cpp.c_ivf_pq cimport (
cdef extern from "raft/neighbors/cagra_types.hpp" \
namespace "raft::neighbors::cagra" nogil:

ctypedef enum graph_build_algo:
IVF_PQ "raft::neighbors::cagra::graph_build_algo::IVF_PQ",
NN_DESCENT "raft::neighbors::cagra::graph_build_algo::NN_DESCENT"

cpdef cppclass index_params(ann_index_params):
size_t intermediate_graph_degree
size_t graph_degree
graph_build_algo build_algo

ctypedef enum search_algo:
SINGLE_CTA "raft::neighbors::cagra::search_algo::SINGLE_CTA",
Expand Down
12 changes: 11 additions & 1 deletion python/pylibraft/pylibraft/test/test_cagra.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def run_cagra_build_search_test(
metric="euclidean",
intermediate_graph_degree=128,
graph_degree=64,
build_algo="ivf_pq",
array_type="device",
compare=True,
inplace=True,
Expand All @@ -67,6 +68,7 @@ def run_cagra_build_search_test(
metric=metric,
intermediate_graph_degree=intermediate_graph_degree,
graph_degree=graph_degree,
build_algo=build_algo,
)

if array_type == "device":
Expand Down Expand Up @@ -139,13 +141,17 @@ def run_cagra_build_search_test(
@pytest.mark.parametrize("inplace", [True, False])
@pytest.mark.parametrize("dtype", [np.float32, np.int8, np.uint8])
@pytest.mark.parametrize("array_type", ["device", "host"])
def test_cagra_dataset_dtype_host_device(dtype, array_type, inplace):
@pytest.mark.parametrize("build_algo", ["ivf_pq", "nn_descent"])
def test_cagra_dataset_dtype_host_device(
dtype, array_type, inplace, build_algo
):
# Note that inner_product tests use normalized input which we cannot
# represent in int8, therefore we test only sqeuclidean metric here.
run_cagra_build_search_test(
dtype=dtype,
inplace=inplace,
array_type=array_type,
build_algo=build_algo,
)


Expand All @@ -158,20 +164,23 @@ def test_cagra_dataset_dtype_host_device(dtype, array_type, inplace):
"add_data_on_build": True,
"k": 1,
"metric": "euclidean",
"build_algo": "ivf_pq",
},
{
"intermediate_graph_degree": 32,
"graph_degree": 16,
"add_data_on_build": False,
"k": 5,
"metric": "sqeuclidean",
"build_algo": "ivf_pq",
},
{
"intermediate_graph_degree": 128,
"graph_degree": 32,
"add_data_on_build": True,
"k": 10,
"metric": "inner_product",
"build_algo": "nn_descent",
},
],
)
Expand All @@ -184,6 +193,7 @@ def test_cagra_index_params(params):
graph_degree=params["graph_degree"],
intermediate_graph_degree=params["intermediate_graph_degree"],
compare=False,
build_algo=params["build_algo"],
)


Expand Down

0 comments on commit c55ae4e

Please sign in to comment.