Skip to content

Migrate RMM usage to CCCL MR design - #7951

Merged
rapids-bot[bot] merged 9 commits into
NVIDIA:mainfrom
bdice:rmm-cccl-migration
Apr 21, 2026
Merged

rapids-bot[bot] merged 9 commits into
NVIDIA:mainfrom
bdice:rmm-cccl-migration

Conversation

@bdice

@bdice bdice commented Apr 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Migrate all raw RMM allocate/deallocate calls to the new CCCL 3-argument API that requires explicit alignment
  • Replace removed rmm.librmm.per_device_resource Cython import with rmm.pylibrmm.memory_resource and use make_any_device_resource to obtain the resource for device_buffer construction

Depends on rapidsai/rmm#2361.
Depends on rapidsai/ucxx#636.
Depends on NVIDIA/raft#2996.
Depends on NVIDIA/cuvs#1990.

Changes

  • cpp/src/genetic/genetic.cu: Add explicit alignof(node) / alignof(program) to all allocate and deallocate calls in parallel_evolve and symFit; fix deallocation bug in parallel_evolve where h_nextprogs[i].len was incorrectly used instead of tmp.len to compute the buffer size being freed
  • cpp/examples/symreg/symreg_example.cpp: Use params.population_size * sizeof(cg::program) and alignof(cg::program) for allocate/deallocate calls, fixing incorrect byte-size computation; remove unused <rmm/aligned.hpp> include
  • cpp/tests/sg/genetic/evolution_test.cu: Add alignment arguments to allocate/deallocate in SymReg test
  • cpp/tests/sg/genetic/program_test.cu: Add alignment arguments to SetUp/TearDown allocate/deallocate calls
  • python/cuml/cuml/manifold/umap/umap.pyx: Replace get_current_device_resource() with make_any_device_resource(get_current_device_resource().get_mr()) for device_buffer construction

@copy-pr-bot

copy-pr-bot Bot commented Apr 3, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the Cython / Python Cython or Python issue label Apr 3, 2026
@github-actions github-actions Bot added the ci label Apr 16, 2026
@bdice
bdice force-pushed the rmm-cccl-migration branch 4 times, most recently from 48202c6 to 4c9b17f Compare April 17, 2026 07:09
@bdice bdice added breaking Breaking change improvement Improvement / enhancement to an existing function labels Apr 17, 2026
@bdice
bdice force-pushed the rmm-cccl-migration branch from 4c9b17f to 67ee0f1 Compare April 17, 2026 07:29
@bdice bdice changed the title Migrate RMM usage to CCCL memory resource design Migrate RMM usage to CCCL MR design Apr 17, 2026
@bdice
bdice force-pushed the rmm-cccl-migration branch 5 times, most recently from 8fba1a6 to b55ccf5 Compare April 18, 2026 15:52
@bdice
bdice marked this pull request as ready for review April 19, 2026 19:16
@bdice
bdice requested review from a team as code owners April 19, 2026 19:16
@bdice
bdice requested review from KyleFromNVIDIA and csadorf April 19, 2026 19:16
@bdice
bdice requested review from divyegala and lowener April 19, 2026 19:16
@coderabbitai

coderabbitai Bot commented Apr 19, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The pull request updates device memory allocation and deallocation calls across C++ source files and examples to include explicit alignment parameters using alignof(), and adapts Python UMAP code to wrap RMM device resources with make_any_device_resource() for API compatibility.

Changes

Cohort / File(s) Summary
C++ Memory Allocation Updates
cpp/examples/symreg/symreg_example.cpp, cpp/src/genetic/genetic.cu
Device memory allocations and deallocations now include explicit alignment arguments: alignof(cg::program) for program arrays and alignof(node) for node buffers in both allocate and deallocate calls.
C++ Test Memory Allocation Updates
cpp/tests/sg/genetic/evolution_test.cu, cpp/tests/sg/genetic/program_test.cu
Test utilities updated to pass alignment parameters (alignof(program) and alignof(node)) consistently in device memory allocate/deallocate operations for GPU buffer management.
Python UMAP Resource Wrapping
python/cuml/cuml/manifold/umap/umap.pyx
RMM device memory resource initialization updated to wrap get_current_device_resource() with make_any_device_resource() and corresponding import adjustments for memory resource APIs.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and accurately summarizes the main change: migrating RMM usage to the new CCCL memory resource design pattern.
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.
Description check ✅ Passed The pull request description clearly and accurately describes the changeset, detailing migration to CCCL 3-argument allocation API with explicit alignment parameters and RMM import updates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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: 5

🧹 Nitpick comments (2)
ci/test_python_common.sh (1)

6-6: Source helper script relative to the script location.

Line 6 uses a repo-root relative path, so invocation from another working directory can fail. Resolve from BASH_SOURCE (and add a ShellCheck source hint).

Proposed patch
 set -euo pipefail
-source ./ci/use_conda_packages_from_prs.sh
+SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
+# shellcheck source=ci/use_conda_packages_from_prs.sh
+source "${SCRIPT_DIR}/use_conda_packages_from_prs.sh"

Based on learnings: For code reviews in rapidsai/cuml, whenever reviewing shell scripts, use ShellCheck to validate syntax and catch potential issues before posting comments.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ci/test_python_common.sh` at line 6, The script sources
./ci/use_conda_packages_from_prs.sh using a repo-root relative path which breaks
when the script is executed from another working directory; update the sourcing
in ci/test_python_common.sh to resolve the helper script relative to the current
script location using ${BASH_SOURCE[0]} (or a derived DIR variable) so the path
is stable regardless of CWD, and add a ShellCheck source directive (e.g. #
shellcheck source=ci/use_conda_packages_from_prs.sh) above the source line to
satisfy static checks.
ci/use_conda_packages_from_prs.sh (1)

28-31: Validate channel values before mutating conda config.

Add a non-empty check for each channel so failures are explicit and early.

Proposed patch
 for _channel in "${RAPIDS_PREPENDED_CONDA_CHANNELS[@]}"
 do
+   if [[ -z "${_channel}" ]]; then
+      echo "ERROR: empty channel value in RAPIDS_PREPENDED_CONDA_CHANNELS" >&2
+      return 1
+   fi
    conda config --system --add channels "${_channel}"
    RAPIDS_EXTRA_CONDA_CHANNEL_ARGS+=(--prepend-channel "${_channel}")
 done

As per coding guidelines: ci/**/*: Verify proper error handling and meaningful error messages.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ci/use_conda_packages_from_prs.sh` around lines 28 - 31, The loop that
mutates conda config iterates RAPIDS_PREPENDED_CONDA_CHANNELS without validating
entries; update the loop in use_conda_packages_from_prs.sh to skip or fail fast
on empty/whitespace channel values by checking each _channel for non-empty
content (e.g., trim and test -n) before calling conda config and appending to
RAPIDS_EXTRA_CONDA_CHANNEL_ARGS; on an invalid value emit a clear error message
naming the variable/loop (RAPIDS_PREPENDED_CONDA_CHANNELS / _channel) and exit
with a non-zero status so failures are explicit.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ci/test_cpp.sh`:
- Line 6: The script currently does "source ./ci/use_conda_packages_from_prs.sh"
which breaks out-of-repo invocation; replace that relative source with a source
that uses a computed SCRIPT_DIR (e.g., derived from "${BASH_SOURCE[0]}" or
similar) so the script always sources ci/use_conda_packages_from_prs.sh relative
to the script location, and then perform the existing cd to the repo root;
update the occurrence of "source ./ci/use_conda_packages_from_prs.sh" to "source
$SCRIPT_DIR/use_conda_packages_from_prs.sh" (and ensure SCRIPT_DIR is set before
this source and the later cd still runs).

In `@ci/use_wheels_from_prs.sh`:
- Around line 32-41: Add a guard before the heredoc that validates the
PIP_CONSTRAINT variable and fails with a clear message if it is empty or unset:
test that PIP_CONSTRAINT is non-empty (e.g. [ -n "${PIP_CONSTRAINT:-}" ] || {
echo "PIP_CONSTRAINT must be set" >&2; exit 1; }), then proceed to the existing
cat >> "${PIP_CONSTRAINT}" <<EOF block; reference the PIP_CONSTRAINT variable
and the heredoc block when locating where to insert the check.

In `@cpp/examples/symreg/symreg_example.cpp`:
- Around line 239-240: The allocation for d_finalprogs is using element count
and rmm::CUDA_ALLOCATION_ALIGNMENT, but allocate()/deallocate() expect bytes and
other code (e.g. symFit allocation in genetic.cu) uses alignof(program); change
the curr_mr.allocate call for d_finalprogs to request params.population_size *
sizeof(cg::program) bytes and use the same alignment as the symFit buffer
(alignof(cg::program) or the exact alignof(program) used in genetic.cu) so
allocation and subsequent deallocation/swapping use identical size-in-bytes and
alignment.

In `@cpp/src/genetic/genetic.cu`:
- Around line 231-232: The deallocation call currently uses h_nextprogs[i].len
but should use the old program length stored in tmp after raft::copy overwrote
it; update the rmm::mr::get_current_device_resource_ref().deallocate(...)
invocation to pass tmp.len * sizeof(node) (and alignof(node) as before) instead
of h_nextprogs[i].len so the freed size matches the original allocation
(references: tmp, h_nextprogs, d_oldprogs, raft::copy, and the deallocate call).

In `@python/cuml/cuml/manifold/umap/umap.pyx`:
- Line 1290: The call to convert an RMM device resource for
make_any_device_resource is using get_current_device_resource().get_mr(), but
the newer RMM API requires extracting the C pointer via
get_current_device_resource().c_ref.value(); update the invocation that
currently passes get_current_device_resource().get_mr() (around
make_any_device_resource usage) to instead pass
get_current_device_resource().c_ref.value() so make_any_device_resource receives
the proper device resource handle.

---

Nitpick comments:
In `@ci/test_python_common.sh`:
- Line 6: The script sources ./ci/use_conda_packages_from_prs.sh using a
repo-root relative path which breaks when the script is executed from another
working directory; update the sourcing in ci/test_python_common.sh to resolve
the helper script relative to the current script location using
${BASH_SOURCE[0]} (or a derived DIR variable) so the path is stable regardless
of CWD, and add a ShellCheck source directive (e.g. # shellcheck
source=ci/use_conda_packages_from_prs.sh) above the source line to satisfy
static checks.

In `@ci/use_conda_packages_from_prs.sh`:
- Around line 28-31: The loop that mutates conda config iterates
RAPIDS_PREPENDED_CONDA_CHANNELS without validating entries; update the loop in
use_conda_packages_from_prs.sh to skip or fail fast on empty/whitespace channel
values by checking each _channel for non-empty content (e.g., trim and test -n)
before calling conda config and appending to RAPIDS_EXTRA_CONDA_CHANNEL_ARGS; on
an invalid value emit a clear error message naming the variable/loop
(RAPIDS_PREPENDED_CONDA_CHANNELS / _channel) and exit with a non-zero status so
failures are explicit.
🪄 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: Pro Plus

Run ID: c86a26e5-791f-4cd7-bc39-414050dde04a

📥 Commits

Reviewing files that changed from the base of the PR and between 9f83155 and b55ccf5.

📒 Files selected for processing (19)
  • ci/build_cpp.sh
  • ci/build_docs.sh
  • ci/build_python.sh
  • ci/build_wheel_cuml.sh
  • ci/build_wheel_libcuml.sh
  • ci/run_clang_tidy.sh
  • ci/test_cpp.sh
  • ci/test_notebooks.sh
  • ci/test_python_common.sh
  • ci/test_wheel.sh
  • ci/test_wheel_dask.sh
  • ci/test_wheel_integrations.sh
  • ci/use_conda_packages_from_prs.sh
  • ci/use_wheels_from_prs.sh
  • cpp/examples/symreg/symreg_example.cpp
  • cpp/src/genetic/genetic.cu
  • cpp/tests/sg/genetic/evolution_test.cu
  • cpp/tests/sg/genetic/program_test.cu
  • python/cuml/cuml/manifold/umap/umap.pyx

Comment thread ci/test_cpp.sh Outdated
Comment thread ci/use_wheels_from_prs.sh Outdated
Comment thread cpp/examples/symreg/symreg_example.cpp Outdated
Comment thread cpp/src/genetic/genetic.cu Outdated
Comment thread python/cuml/cuml/manifold/umap/umap.pyx

@csadorf csadorf 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.

Thanks a lot!

@bdice

bdice commented Apr 20, 2026 •

Copy link
Copy Markdown
Contributor Author

@csadorf I didn't feel good leaving the loose ends so I did some analysis of the buggy allocations (checked CodeRabbit and verified with both my own eyes and AIs). I pushed a commit a23a300 that addresses the follow-up. Hope that is helpful.

@viclafargue viclafargue 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.

Thanks a lot! LGTM

auto curr_mr = rmm::mr::get_current_device_resource_ref();
d_finalprogs = static_cast<cg::program_t>(curr_mr.allocate(stream, params.population_size));
d_finalprogs = static_cast<cg::program_t>(
curr_mr.allocate(stream, params.population_size * sizeof(cg::program), alignof(cg::program)));

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.

It looks like the PR description states adding rmm::CUDA_ALLOCATION_ALIGNMENT to allocate/deallocate. Could you update the it?

Also, could we also state the allocation bugfix in genetic code in the PR description?

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.

Good call. Fixed!

symreg_example: pass byte count (population_size * sizeof(program)) instead of
element count to allocate/deallocate, and use alignof(program) to match
genetic.cu. Remove unused rmm/aligned.hpp include.

parallel_evolve: use tmp.len (the old program length from d_oldprogs) instead
of h_nextprogs[i].len (the new program length) in the deallocate call so the
freed size matches the original allocation.
@bdice
bdice force-pushed the rmm-cccl-migration branch from a23a300 to ba9cd2b Compare April 21, 2026 11:57
@github-actions github-actions Bot removed the ci label Apr 21, 2026
@bdice
bdice removed request for a team, KyleFromNVIDIA and lowener April 21, 2026 21:44
@bdice

bdice commented Apr 21, 2026

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit c6e85ee into NVIDIA:main Apr 21, 2026
188 of 190 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Breaking change CUDA/C++ Cython / Python Cython or Python issue improvement Improvement / enhancement to an existing function

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants