RMM is a library for CUDA memory management.
- Minimal diffs: Change only what's necessary; avoid drive-by refactors.
- No mass reformatting: Don't run formatters over unrelated code.
- No API invention: Align with existing RMM patterns and documented APIs.
- Don't bypass CI: Don't suggest skipping checks or using
--no-verify. - CUDA/GPU hygiene: Keep operations stream-ordered, use RMM allocators (never use raw cudaMalloc or other CUDA APIs for device memory, except in the implementation of an RMM memory resource).
Ask yourself:
- What scenarios must be covered? (happy path, edge cases, failure modes)
- What's the expected behavior contract? (inputs/outputs, errors)
- Where should tests live? (C++ gtests under
cpp/tests/, Python pytest underpython/rmm/rmm/tests/)
For AI-assisted code review (CodeRabbit), see language-specific review guidelines:
- C++/CUDA:
cpp/REVIEW_GUIDELINES.md - Python:
python/REVIEW_GUIDELINES.md
build-rmm-cpp -j0 # Build C++ library, accepts CMake flags (-D...)
build-rmm-python -j0 # Build Python package
build-rmm -j0 # Build both C++ and Python, accepts CMake flags (-D...)./build.sh librmm # Build and install C++ library
./build.sh librmm -g # Debug build
./build.sh librmm tests # Build with tests
./build.sh librmm benchmarks # Build with benchmarks
./build.sh clean librmm # Clean rebuild
./build.sh rmm # Build and install Python package
./build.sh librmm rmm # Build both C++ and Pythoncmake -S cpp -B cpp/build -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release
cmake --build cpp/build -j$(nproc)test-rmm-cpp # Run all C++ tests, accepts ctest flags
test-rmm-python # Run all Python tests, accepts pytest flags# Run all C++ tests
ctest --test-dir cpp/build --output-on-failure
# Run single test by name pattern
ctest --test-dir cpp/build -R device_uvector
# Run specific test executable directly
./cpp/build/gtests/DEVICE_UVECTOR_TEST
# Run specific test case within executable
./cpp/build/gtests/DEVICE_UVECTOR_TEST --gtest_filter="TypedUVectorTest.*"
./cpp/build/gtests/DEVICE_UVECTOR_TEST --gtest_filter="*ZeroSizeConstructor"# Run all Python tests
pytest python/rmm/rmm/tests/ -v
# Run single test file
pytest python/rmm/rmm/tests/test_rmm.py -v
# Run single test function
pytest python/rmm/rmm/tests/test_rmm.py::test_reinitialize -v
# Run with coverage
pytest python/rmm/rmm/tests/ --cov=rmm --cov-report=xmlAlways use pre-commit to run linters and formatters:
pre-commit run --all-files # Run all hooks (recommended)
pre-commit run clang-format --all-files # C++ formatting only
pre-commit run ruff-check --all-files # Python linting only
pre-commit run ruff-format --all-files # Python formatting onlyUse pre-commit run --all-files to run linter and style checks. It will call clang-format, ruff, and other tools.
- C++ classes:
snake_case(e.g.,device_buffer) - C++ functions/methods:
snake_case - C++ constants/macros:
SCREAMING_SNAKE_CASE - C++ template params:
PascalCasewithTsuffix (e.g.,OffsetT) - Python:
snake_casefor functions, variables;PascalCasefor classes
- C++: Use RMM exception types from
<rmm/error.hpp>rmm::bad_allocfor allocation failuresrmm::logic_errorfor programming errors- Use
RMM_EXPECTS()macro for precondition checks - Use
RMM_CUDA_TRY()for CUDA API calls
- Python: Use
RMMErroror standard Python exceptions
C++ and CUDA:
/*
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/Python:
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0- C++: Doxygen comments for public APIs (
/** ... */) - Python: NumPy-style docstrings
- All public functions must be documented
cpp/ # C++ source code
├── include/rmm/ # Public headers (header-only library)
├── src/ # Implementation files
├── tests/ # GoogleTest tests
└── benchmarks/ # Google Benchmark benchmarks
python/rmm/ # Python package
├── rmm/ # Main module
│ ├── pylibrmm/ # Cython bindings
│ └── tests/ # pytest tests
ci/ # CI scripts
- All tests must pass
- Pre-commit checks must pass
- Update documentation for API changes
- Add tests for new functionality
#include <rmm/mr/cuda_async_memory_resource.hpp>
#include <rmm/mr/per_device_resource.hpp>
// Create a memory resource and set it as current
rmm::mr::cuda_async_memory_resource mr{};
rmm::mr::set_current_device_resource_ref(mr);
auto ref = rmm::mr::get_current_device_resource_ref();
rmm::device_buffer buf(size, stream, ref);// Stream-ordered (async) allocation - preferred for performance
void* ptr = mr.allocate(stream, bytes);
mr.deallocate(stream, ptr, bytes);
// Synchronous allocation - blocks until memory is ready on all streams
void* ptr = mr.allocate_sync(bytes);
mr.deallocate_sync(ptr, bytes);#include <cuda/stream>
void func(cuda::stream_ref stream) {
// Use stream for async operations
}import rmm
# Create a memory resource and set it as current
mr = rmm.mr.CudaAsyncMemoryResource()
rmm.mr.set_current_device_resource(mr)
ref = rmm.mr.get_current_device_resource()
buf = rmm.DeviceBuffer(size=size)- Never use raw CUDA memory APIs for device memory - use memory resources (except in memory resource implementations)
- Prefer
rmm::device_uvector<T>for typed device memory - Prefer
rmm::device_bufferfor untyped device memory - All operations should be stream-ordered - accept
cuda::stream_reffrom<cuda/stream> - Views (
*_viewsuffix) are non-owning - don't manage their lifetime
| Purpose | Location |
|---|---|
| Main build script (never used in devcontainers) | build.sh |
| CMake configuration | cpp/CMakeLists.txt |
| C++ public headers | cpp/include/rmm/ |
| Memory resources | cpp/include/rmm/mr/ |
| Device containers | cpp/include/rmm/device_uvector.hpp, device_buffer.hpp |
| Stream utilities | <cuda/stream>, cpp/include/rmm/cuda_stream.hpp |
| Error handling | cpp/include/rmm/error.hpp |
| Python bindings | python/rmm/rmm/ |
| C++ tests | cpp/tests/ |
| Python tests | python/rmm/rmm/tests/ |
| CI configuration | ci/ |
- Documentation: https://docs.nvidia.com/rmm/
- GitHub Issues: https://github.com/rapidsai/rmm/issues