From 615868860b630df83c38091476040266b2f77adb Mon Sep 17 00:00:00 2001 From: viclafargue Date: Wed, 26 Mar 2025 15:35:25 +0000 Subject: [PATCH 1/6] Inspect KNN graph during smooth KNN generation and fail if necessary --- cpp/src/umap/fuzzy_simpl_set/naive.cuh | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/cpp/src/umap/fuzzy_simpl_set/naive.cuh b/cpp/src/umap/fuzzy_simpl_set/naive.cuh index 29f632692d..c7c1a12181 100644 --- a/cpp/src/umap/fuzzy_simpl_set/naive.cuh +++ b/cpp/src/umap/fuzzy_simpl_set/naive.cuh @@ -80,7 +80,8 @@ static const float MIN_K_DIST_SCALE = 1e-3; * */ template -CUML_KERNEL void smooth_knn_dist_kernel(const value_t* knn_dists, +CUML_KERNEL void smooth_knn_dist_kernel(bool* error_status, + const value_t* knn_dists, int n, float mean_dist, value_t* sigmas, @@ -120,6 +121,11 @@ CUML_KERNEL void smooth_knn_dist_kernel(const value_t* knn_dists, if (cur_dist > max_nonzero) max_nonzero = cur_dist; } + if (start_nonzero == -1) { + *error_status = true; + return; + } + float ith_distances_mean = sum / float(n_neighbors); if (total_nonzero >= local_connectivity) { int index = int(floor(local_connectivity)); @@ -265,9 +271,19 @@ void smooth_knn_dist(nnz_t n, /** * Smooth kNN distances to be continuous */ + + bool has_found_an_error = false; + rmm::device_scalar error_status(stream); + error_status.set_value_async(has_found_an_error, stream); + smooth_knn_dist_kernel<<>>( - knn_dists, n, mean_dist, sigmas, rhos, n_neighbors, local_connectivity); - RAFT_CUDA_TRY(cudaPeekAtLastError()); + error_status.data(), knn_dists, n, mean_dist, sigmas, rhos, n_neighbors, local_connectivity); + RAFT_CUDA_TRY(cudaStreamSynchronize(stream)); + + has_found_an_error = error_status.value(stream); + if (has_found_an_error) { + throw std::runtime_error("At least one row does not have any neighbor with non-zero distance."); + } } template From c9a76c7c54e829a42a6cc17c6c447a138f74a178 Mon Sep 17 00:00:00 2001 From: viclafargue Date: Tue, 1 Apr 2025 15:51:51 +0200 Subject: [PATCH 2/6] Fixing test --- python/cuml/cuml/tests/test_umap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/cuml/cuml/tests/test_umap.py b/python/cuml/cuml/tests/test_umap.py index a2220ae14e..31715aba4b 100644 --- a/python/cuml/cuml/tests/test_umap.py +++ b/python/cuml/cuml/tests/test_umap.py @@ -787,7 +787,7 @@ def test_umap_distance_metrics_fit_transform_trust_on_sparse_input( metric, supported, umap_learn_supported ): data, labels = make_blobs( - n_samples=1000, n_features=64, centers=5, random_state=42 + n_samples=1000, n_features=64, centers=30, random_state=42 ) data_selection = np.random.RandomState(42).choice( From b32dcc5f2971a21815022e506808f5b43b6ada4c Mon Sep 17 00:00:00 2001 From: viclafargue Date: Fri, 2 May 2025 10:41:07 +0200 Subject: [PATCH 3/6] Restore pytest file --- python/cuml/cuml/tests/test_umap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/cuml/cuml/tests/test_umap.py b/python/cuml/cuml/tests/test_umap.py index 31715aba4b..a2220ae14e 100644 --- a/python/cuml/cuml/tests/test_umap.py +++ b/python/cuml/cuml/tests/test_umap.py @@ -787,7 +787,7 @@ def test_umap_distance_metrics_fit_transform_trust_on_sparse_input( metric, supported, umap_learn_supported ): data, labels = make_blobs( - n_samples=1000, n_features=64, centers=30, random_state=42 + n_samples=1000, n_features=64, centers=5, random_state=42 ) data_selection = np.random.RandomState(42).choice( From b229213dd56aacf7b6ace74b4fc06e31f3779bb0 Mon Sep 17 00:00:00 2001 From: viclafargue Date: Thu, 15 May 2025 11:15:53 +0200 Subject: [PATCH 4/6] Change for RAFT_EXPECTS --- cpp/src/umap/fuzzy_simpl_set/naive.cuh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/src/umap/fuzzy_simpl_set/naive.cuh b/cpp/src/umap/fuzzy_simpl_set/naive.cuh index c7c1a12181..f90136bba3 100644 --- a/cpp/src/umap/fuzzy_simpl_set/naive.cuh +++ b/cpp/src/umap/fuzzy_simpl_set/naive.cuh @@ -282,7 +282,8 @@ void smooth_knn_dist(nnz_t n, has_found_an_error = error_status.value(stream); if (has_found_an_error) { - throw std::runtime_error("At least one row does not have any neighbor with non-zero distance."); + RAFT_EXPECTS(!has_found_an_error, + "At least one row does not have any neighbor with non-zero distance."); } } From d6815f52692758e758487c693aded55556673c90 Mon Sep 17 00:00:00 2001 From: viclafargue Date: Thu, 15 May 2025 19:07:10 +0200 Subject: [PATCH 5/6] fix typo --- cpp/src/umap/fuzzy_simpl_set/naive.cuh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cpp/src/umap/fuzzy_simpl_set/naive.cuh b/cpp/src/umap/fuzzy_simpl_set/naive.cuh index f90136bba3..1939387308 100644 --- a/cpp/src/umap/fuzzy_simpl_set/naive.cuh +++ b/cpp/src/umap/fuzzy_simpl_set/naive.cuh @@ -281,10 +281,8 @@ void smooth_knn_dist(nnz_t n, RAFT_CUDA_TRY(cudaStreamSynchronize(stream)); has_found_an_error = error_status.value(stream); - if (has_found_an_error) { - RAFT_EXPECTS(!has_found_an_error, - "At least one row does not have any neighbor with non-zero distance."); - } + RAFT_EXPECTS(!has_found_an_error, + "At least one row does not have any neighbor with non-zero distance."); } template From ce4cf6b7d4e44a4ac9cdddbe1af4e2a2d83a4a37 Mon Sep 17 00:00:00 2001 From: viclafargue Date: Mon, 26 May 2025 14:24:08 +0200 Subject: [PATCH 6/6] Update test for jaccard distance --- python/cuml/cuml/tests/test_umap.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/python/cuml/cuml/tests/test_umap.py b/python/cuml/cuml/tests/test_umap.py index 96d6bbf532..c68d981d16 100644 --- a/python/cuml/cuml/tests/test_umap.py +++ b/python/cuml/cuml/tests/test_umap.py @@ -783,8 +783,13 @@ def test_umap_distance_metrics_fit_transform_trust( def test_umap_distance_metrics_fit_transform_trust_on_sparse_input( metric, supported, umap_learn_supported ): + if metric == "jaccard": + n_features = 1000 + else: + n_features = 64 + data, labels = make_blobs( - n_samples=1000, n_features=64, centers=5, random_state=42 + n_samples=1000, n_features=n_features, centers=5, random_state=42 ) data_selection = np.random.RandomState(42).choice(