Skip to content

Commit e2a0868

Browse files
committed
adressing review
1 parent a14a6bc commit e2a0868

3 files changed

Lines changed: 25 additions & 20 deletions

File tree

cpp/include/cuvs/cluster/kmeans.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ struct params : base_params {
125125
* When set to 0 (default) with host data uses `min(3 * n_clusters, n_samples)`
126126
* as a default.
127127
*
128+
* In Batched multi-GPU host-data fits, the effective KMeansPlusPlus initialization
129+
* sample is materialized on device and seeding is run on rank 0. Rank 0
130+
* must have enough GPU memory for this sample and the seeding workspace.
131+
*
128132
* Default: 0.
129133
*/
130134
int64_t init_size = 0;
@@ -186,6 +190,10 @@ enum class kmeans_type { KMeans = 0, KMeansBalanced = 1 };
186190
* this worker's partition, and RAFT communicators are used for collectives.
187191
* - Otherwise: single-GPU batched k-means.
188192
*
193+
* With `params.init == InitMethod::KMeansPlusPlus` in multi-GPU mode, the
194+
* effective initialization sample must fit in rank 0 GPU memory because
195+
* seeding is run on rank 0 before centroids are broadcast.
196+
*
189197
* @code{.cpp}
190198
* #include <raft/core/resources.hpp>
191199
* #include <cuvs/cluster/kmeans.hpp>

cpp/src/cluster/detail/kmeans_mg_batched.cuh

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,7 @@ void mnmg_fit(const raft::resources& handle,
318318
true);
319319
}
320320

321-
bool need_compute_norms = metric == cuvs::distance::DistanceType::L2Expanded ||
322-
metric == cuvs::distance::DistanceType::L2SqrtExpanded;
323-
auto h_norm_cache =
324-
raft::make_pinned_vector<T, IdxT>(dev_res, (need_compute_norms && has_data) ? n_local : 0);
321+
auto h_norm_cache = raft::make_pinned_vector<T, IdxT>(dev_res, has_data ? n_local : 0);
325322
bool norms_cached = false;
326323

327324
auto mnmg_allreduce = [&](auto* sendbuf, auto* recvbuf, size_t count) {
@@ -407,21 +404,19 @@ void mnmg_fit(const raft::resources& handle,
407404
auto L2NormBatch_view =
408405
raft::make_device_vector_view<T, IdxT>(L2NormBatch.data_handle(), current_batch_size);
409406

410-
if (need_compute_norms) {
411-
auto batch_offset = static_cast<IdxT>(data_batch.offset());
412-
if (!norms_cached) {
413-
raft::linalg::norm<raft::linalg::L2Norm, raft::Apply::ALONG_ROWS>(
414-
dev_res, batch_data_view, L2NormBatch_view);
415-
raft::copy(h_norm_cache.data_handle() + batch_offset,
416-
L2NormBatch.data_handle(),
417-
current_batch_size,
418-
stream);
419-
} else {
420-
raft::copy(L2NormBatch.data_handle(),
421-
h_norm_cache.data_handle() + batch_offset,
422-
current_batch_size,
423-
stream);
424-
}
407+
auto batch_offset = static_cast<IdxT>(data_batch.offset());
408+
if (!norms_cached) {
409+
raft::linalg::norm<raft::linalg::L2Norm, raft::Apply::ALONG_ROWS>(
410+
dev_res, batch_data_view, L2NormBatch_view);
411+
raft::copy(h_norm_cache.data_handle() + batch_offset,
412+
L2NormBatch.data_handle(),
413+
current_batch_size,
414+
stream);
415+
} else {
416+
raft::copy(L2NormBatch.data_handle(),
417+
h_norm_cache.data_handle() + batch_offset,
418+
current_batch_size,
419+
stream);
425420
}
426421

427422
auto L2NormBatch_const = raft::make_const_mdspan(L2NormBatch_view);
@@ -447,7 +442,7 @@ void mnmg_fit(const raft::resources& handle,
447442
raft::make_device_scalar_view(clustering_cost.data_handle()),
448443
batch_workspace);
449444
}
450-
if (need_compute_norms) { norms_cached = true; }
445+
norms_cached = true;
451446
}
452447

453448
// Phase 2: grouped allreduce

cpp/src/cluster/detail/kmeans_mg_batched_init.cuh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ void init_centroids_for_mg_batched(raft::resources const& handle,
232232
handle, params, X_local, init_sample_size, rank, root, rank_counts, allreduce, bcast);
233233

234234
if (rank == root) {
235+
// KMeans++ seeding runs on root, so root must have enough device memory
236+
// for the full initialization sample plus the seeding workspace.
235237
auto init_view = raft::make_const_mdspan(init_sample.view());
236238
if (params.oversampling_factor == 0) {
237239
cuvs::cluster::kmeans::detail::kmeansPlusPlus<DataT, IndexT>(

0 commit comments

Comments
 (0)