Skip to content

Clean up stale cuML multi-GPU build options - #8137

Merged
rapids-bot[bot] merged 18 commits into
NVIDIA:mainfrom
viclafargue:mg-build-cleanup
Jul 24, 2026
Merged

Clean up stale cuML multi-GPU build options#8137
rapids-bot[bot] merged 18 commits into
NVIDIA:mainfrom
viclafargue:mg-build-cleanup

Conversation

@viclafargue

@viclafargue viclafargue commented May 21, 2026

Copy link
Copy Markdown
Contributor

Addressing #7845.

This PR :

  • removes obsolete cuML communicator CMake options
  • makes BUILD_CUML_MG_TESTS the single switch for C++ multi-GPU tests
  • stop linking MPI/NCCL into libcuml unnecessarily and obtain distributed dependencies through RAFT
  • updates build docs to reflect current RAFT/MPI dependencies.
  • updates MG tests to work with the latest version of RMM/RAFT

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR removes the MPI-comms build option, updates CMake/test gating for multi-GPU builds, migrates KNN multi-GPU tests to RAFT device-vector-based storage and newer APIs, simplifies the PCA test matrix, and refreshes build documentation to match the new test and dependency flow.

Changes

Multi-GPU Test Infrastructure Refactoring

Layer / File(s) Summary
CMake build infrastructure: MPI comms removal and dependency gating
cpp/CMakeLists.txt
Removes BUILD_CUML_MPI_COMMS, drops MPI+NCCL wiring, and gates MPI discovery, thread setup, and test subdirectory inclusion around BUILD_CUML_MG_TESTS; also removes CUML_MG_TEST_TARGET and the SINGLEGPU MPI/UCX disable logic.
Test registration infrastructure: ConfigureTest enhancements and reorganization
cpp/tests/CMakeLists.txt
Adds NO_GTEST_MAIN to ConfigureTest, reworks single-GPU test registration under BUILD_CUML_TESTS, and updates multi-GPU KNN/PCA registrations to skip gtest_main where needed.
KNN test helper infrastructure: RAFT device_vector migration
cpp/tests/mg/knn_test_helper.cuh
Replaces manual allocator-based storage with RAFT device_vector and std::optional-backed ownership for KNN test data, labels, and output partitions, and updates cleanup to match the new storage model.
KNN test: RAFT API migration and buffer refactoring
cpp/tests/mg/knn.cu
Switches the KNN test to RAFT-backed buffers, changes the algorithm call from brute_force_knn to knn, and updates comparisons to MLCommon::CompareApprox.
KNN classify and regress tests: RAFT blob generation and buffer management
cpp/tests/mg/knn_classify.cu, cpp/tests/mg/knn_regress.cu
Updates blob generation to raft::random::make_blobs, removes now-unused output-part arguments, and switches assertions to MLCommon::CompareApprox.
PCA test parameter simplification
cpp/tests/mg/pca.cu
Removes the QR parameter case from the multi-GPU PCA test inputs.
Documentation updates: BUILD, build.sh, and cpp/README
BUILD.md, build.sh, cpp/README.md
Revises build and test instructions to use ctest, updates multi-GPU dependency wording, and refreshes the documented CMake flags and source-layout description.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested labels: improvement, non-breaking, ci

Suggested reviewers: jameslamb, csadorf, bdice

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: removing outdated cuML multi-GPU build options.
Description check ✅ Passed The description matches the changeset by describing communicator option cleanup, MG test switching, docs, and test updates.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
BUILD.md (1)

111-111: ⚡ Quick win

Remove $ prompts in command blocks to satisfy markdownlint MD014.

These lines use shell prompts without output, which triggers the current markdownlint rule. Please remove the leading $ (or adjust the rule config if prompts are intentional).

Also applies to: 116-116, 201-201, 206-206, 211-211, 212-212

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@BUILD.md` at line 111, Remove the leading "$" shell prompt from standalone
command lines in BUILD.md (e.g., change "$ ctest --test-dir cpp/build
--output-on-failure" and the other occurrences at the same command blocks on
lines showing "$ ...") so the command blocks contain only the raw commands;
update each occurrence (including the instances corresponding to the other
reported lines) to remove the prompt prefix to satisfy markdownlint MD014.
cpp/tests/mg/knn_test_helper.cuh (1)

144-164: ⚡ Quick win

Skip allocating unused KNN neighbor buffers here.

For the classify/regress paths in this PR, out_i_part_storage and out_d_part_storage are no longer consumed, but generate_data() still allocates them for every query partition. That is avoidable multi-GPU device-memory pressure with no coverage benefit. Consider making those buffers optional or splitting the helper setup for raw-KNN vs classify/regress tests.

As per coding guidelines, "Avoid excessive memory allocations in hot paths".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/tests/mg/knn_test_helper.cuh` around lines 144 - 164, generate_data() is
allocating out_d_part_storage and out_i_part_storage (and creating
Matrix::floatData_t / Matrix::Data<int64_t> and pushing to
out_d_parts/out_i_parts) even for classify/regress tests that don't consume KNN
neighbors; change the logic to allocate and create these device buffers and the
corresponding Matrix outputs only when they are actually needed (e.g., when the
test mode requires raw KNN neighbors or when params.k > 0), or add a boolean
flag like use_knn_buffers to gate the emplace_back and new Matrix::floatData_t /
Matrix::Data<int64_t> creation; if skipping allocation, ensure you also skip
pushing to out_d_parts/out_i_parts (or push nullptr consistently) so the rest of
the code handles the absence safely and avoids unnecessary multi-GPU memory
pressure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cpp/tests/mg/knn_classify.cu`:
- Around line 87-89: The test currently returns a hardcoded success via
MLCommon::CompareApprox<int>(1)(actual, expected); replace this sentinel with a
real assertion that compares the classifier output (knn_th.out_parts) to the
expected labels or deterministic invariants derived from the generated blobs:
locate the block where int actual/expected and the return are set, compute
expected labels from the same blob-generation logic used in the test (or
hardcode the deterministic expected vector), build an appropriate comparison
(element-wise equality or tolerance-based check) between knn_th.out_parts and
the expected labels, and return the result of that comparison instead of the
constant true value.

In `@cpp/tests/mg/knn_regress.cu`:
- Around line 65-67: The test currently compares two literals (1 vs 1) instead
of the regression output; change the comparison to assert knn_regress's actual
output against the expected value(s). Locate the knn_regress invocation and the
variables actual and expected, set actual to the predicted value(s) returned or
written by knn_regress (or the output buffer it fills), set expected to the
known ground-truth regression result(s), and call MLCommon::CompareApprox<T>
with those actual and expected values (or iterate/compare element-wise if the
prediction is an array) so the test fails when knn_regress returns incorrect
predictions.

In `@cpp/tests/mg/knn.cu`:
- Around line 208-210: The test currently uses a hardcoded placeholder
(actual/expected = 1) and MLCommon::CompareApprox<int> which masks failures;
replace this with real validation of knn() outputs by extracting the computed
neighbor indices and distances returned by the knn() call (e.g., the arrays or
device buffers produced by knn()) and comparing them to the known ground-truth
neighbors/distances for the test dataset: compute actual values from the knn()
outputs (neighbor indices and/or distances), set expected values to the
precomputed ground-truth vectors for this test case, and call the appropriate
MLCommon::CompareApprox (use CompareApprox<int> for indices and
CompareApprox<float/double> for distances) with a sensible tolerance to assert
equality; update the return to use those comparisons instead of the placeholder
CompareApprox<int>(1)(1,1).

---

Nitpick comments:
In `@BUILD.md`:
- Line 111: Remove the leading "$" shell prompt from standalone command lines in
BUILD.md (e.g., change "$ ctest --test-dir cpp/build --output-on-failure" and
the other occurrences at the same command blocks on lines showing "$ ...") so
the command blocks contain only the raw commands; update each occurrence
(including the instances corresponding to the other reported lines) to remove
the prompt prefix to satisfy markdownlint MD014.

In `@cpp/tests/mg/knn_test_helper.cuh`:
- Around line 144-164: generate_data() is allocating out_d_part_storage and
out_i_part_storage (and creating Matrix::floatData_t / Matrix::Data<int64_t> and
pushing to out_d_parts/out_i_parts) even for classify/regress tests that don't
consume KNN neighbors; change the logic to allocate and create these device
buffers and the corresponding Matrix outputs only when they are actually needed
(e.g., when the test mode requires raw KNN neighbors or when params.k > 0), or
add a boolean flag like use_knn_buffers to gate the emplace_back and new
Matrix::floatData_t / Matrix::Data<int64_t> creation; if skipping allocation,
ensure you also skip pushing to out_d_parts/out_i_parts (or push nullptr
consistently) so the rest of the code handles the absence safely and avoids
unnecessary multi-GPU memory pressure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a219478d-fa4f-4306-b3bf-cae7ecec7e44

📥 Commits

Reviewing files that changed from the base of the PR and between 2a2e844 and 5abf97b.

📒 Files selected for processing (10)
  • BUILD.md
  • build.sh
  • cpp/CMakeLists.txt
  • cpp/README.md
  • cpp/tests/CMakeLists.txt
  • cpp/tests/mg/knn.cu
  • cpp/tests/mg/knn_classify.cu
  • cpp/tests/mg/knn_regress.cu
  • cpp/tests/mg/knn_test_helper.cuh
  • cpp/tests/mg/pca.cu

Comment on lines 87 to +89
int actual = 1;
int expected = 1;
return raft::CompareApprox<int>(1)(actual, expected);
return MLCommon::CompareApprox<int>(1)(actual, expected);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Assert the classifier output instead of a sentinel value.

This always returns true, so changes in knn_classify() output will not fail the test. Please validate knn_th.out_parts against expected labels or deterministic invariants from the generated blobs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/tests/mg/knn_classify.cu` around lines 87 - 89, The test currently
returns a hardcoded success via MLCommon::CompareApprox<int>(1)(actual,
expected); replace this sentinel with a real assertion that compares the
classifier output (knn_th.out_parts) to the expected labels or deterministic
invariants derived from the generated blobs: locate the block where int
actual/expected and the return are set, compute expected labels from the same
blob-generation logic used in the test (or hardcode the deterministic expected
vector), build an appropriate comparison (element-wise equality or
tolerance-based check) between knn_th.out_parts and the expected labels, and
return the result of that comparison instead of the constant true value.

Comment on lines 65 to +67
int actual = 1;
int expected = 1;
return raft::CompareApprox<int>(1)(actual, expected);
return MLCommon::CompareApprox<int>(1)(actual, expected);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Assert the regression output instead of a sentinel value.

This still compares 1 to 1, so the test passes even if knn_regress() returns incorrect predictions. That makes the API migration untested for the actual regression results.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/tests/mg/knn_regress.cu` around lines 65 - 67, The test currently
compares two literals (1 vs 1) instead of the regression output; change the
comparison to assert knn_regress's actual output against the expected value(s).
Locate the knn_regress invocation and the variables actual and expected, set
actual to the predicted value(s) returned or written by knn_regress (or the
output buffer it fills), set expected to the known ground-truth regression
result(s), and call MLCommon::CompareApprox<T> with those actual and expected
values (or iterate/compare element-wise if the prediction is an array) so the
test fails when knn_regress returns incorrect predictions.

Comment thread cpp/tests/mg/knn.cu
Comment on lines 208 to +210
int actual = 1;
int expected = 1;
return raft::CompareApprox<int>(1)(actual, expected);
return MLCommon::CompareApprox<int>(1)(actual, expected);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Replace the placeholder assertion with a real KNN result check.

This still returns CompareApprox(1)(1, 1), so the test passes even if knn() produces wrong neighbors or distances. That leaves the RAFT/API migration effectively unvalidated on this path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/tests/mg/knn.cu` around lines 208 - 210, The test currently uses a
hardcoded placeholder (actual/expected = 1) and MLCommon::CompareApprox<int>
which masks failures; replace this with real validation of knn() outputs by
extracting the computed neighbor indices and distances returned by the knn()
call (e.g., the arrays or device buffers produced by knn()) and comparing them
to the known ground-truth neighbors/distances for the test dataset: compute
actual values from the knn() outputs (neighbor indices and/or distances), set
expected values to the precomputed ground-truth vectors for this test case, and
call the appropriate MLCommon::CompareApprox (use CompareApprox<int> for indices
and CompareApprox<float/double> for distances) with a sensible tolerance to
assert equality; update the return to use those comparisons instead of the
placeholder CompareApprox<int>(1)(1,1).

@viclafargue viclafargue added improvement Improvement / enhancement to an existing function non-breaking Non-breaking change labels Jul 2, 2026
@chyunsu3

chyunsu3 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

I will review it this week, after I'm done reviewing #8371 and #8370

@chyunsu3 chyunsu3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some questions about the CMake changes

Comment thread cpp/tests/CMakeLists.txt
# ##################################################################################################
# * build ml_test executable -------------------------------------------------
if(all_algo OR dbscan_algo)
if(BUILD_CUML_TESTS AND (all_algo OR dbscan_algo))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it not possible to simply skip add_subdirectory(cpp/tests) when BUILD_CUML_TESTS is false?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The cpp/tests directory defines the SG, MG and prims tests.

Historically, --nolibcumltest (BUILD_CUML_TESTS=OFF) means remove the SG tests and cpp-mgtests (BUILD_CUML_MG_TESTS=ON) means add the MG tests.

We could either make --nolibcumltest disable all the tests but this would change the expected behavior. We could also have the SG, MG and prims tests be defined in three distinct directories, but this is a bit outside of the scope of this PR. Even though this may be something to look into.

Comment thread cpp/CMakeLists.txt
$<TARGET_NAME_IF_EXISTS:GPUTreeShap::GPUTreeShap>
$<$<BOOL:${LINK_CUFFT}>:CUDA::cufft${_ctk_fft_static_suffix}>
${OpenMP_CXX_LIB_NAMES}
$<$<OR:$<BOOL:${BUILD_CUML_STD_COMMS}>,$<BOOL:${BUILD_CUML_MPI_COMMS}>>:NCCL::NCCL>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Doesn't multi-GPU functionalities of cuML use NCCL?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

cuML’s own code calls the abstract raft::comms::comms_t interface. It does not include nccl.h or call NCCL functions directly. The MG tests link raft::distributed, whose CMake target links NCCL::NCCL.

Comment thread cpp/tests/mg/knn.cu Outdated
@viclafargue
viclafargue changed the base branch from main to release/26.08 July 20, 2026 08:23
@viclafargue
viclafargue requested a review from a team as a code owner July 20, 2026 08:23
@viclafargue
viclafargue requested a review from betatim July 20, 2026 08:23
@github-actions github-actions Bot added conda conda issue Cython / Python Cython or Python issue labels Jul 20, 2026
chyunsu3 added a commit to RAMitchell/cuml that referenced this pull request Jul 22, 2026
@chyunsu3

chyunsu3 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Let's try to merge this pull request soon, since #8394 requires it.

@copy-pr-bot

copy-pr-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@chyunsu3

Copy link
Copy Markdown
Contributor

/ok to test 508cb5d

@chyunsu3
chyunsu3 changed the base branch from release/26.08 to main July 23, 2026 22:56
@chyunsu3

Copy link
Copy Markdown
Contributor

/ok to test 5e8bd4b

@chyunsu3

Copy link
Copy Markdown
Contributor

Re-targeting this PR to 26.10.

@jameslamb jameslamb left a comment

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.

explanations all make sense to me, changes look good from a packaging-codeowners perspective

@jameslamb
jameslamb removed the request for review from bdice July 24, 2026 14:38
@viclafargue

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit b480747 into NVIDIA:main Jul 24, 2026
102 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CMake conda conda issue CUDA/C++ Cython / Python Cython or Python issue improvement Improvement / enhancement to an existing function non-breaking Non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants