Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
- check-nightly-ci
- changed-files
- checks
- cmake-tests
- conda-cpp-build
- conda-cpp-tests
- conda-cpp-debug-tests
Expand Down Expand Up @@ -208,6 +209,22 @@ jobs:
with:
enable_check_generated_files: false
ignored_pr_jobs: "telemetry-summarize conda-python-tests-integration-optional wheel-tests-integration-optional"
cmake-tests:
needs: checks
permissions:
actions: read
contents: read
id-token: write
packages: read
pull-requests: read
secrets: inherit # zizmor: ignore[secrets-inherit]
uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main
with:
build_type: pull-request
node_type: cpu16
arch: "amd64"
container_image: "rapidsai/ci-conda:26.08-latest"
script: "ci/test_cmake.sh"
conda-cpp-build:
needs: checks
permissions:
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@ If you frequently start new builds from scratch, consider setting the environmen
`CPM_SOURCE_CACHE` to an external download directory to avoid repeated downloads of the third-party
dependencies.

### ABI versioning

RMM symbols are placed in an inline namespace derived from the RMM major and minor version. The
public API remains available through the `rmm::` namespace, while static RMM libraries built for
different ABI versions can coexist in one process. Process-global state is shared by RMM copies
with the same ABI version and kept separate across different ABI versions.

## Using RMM in a downstream CMake project

The installed RMM library provides a set of config files that makes it easy to
Expand Down
37 changes: 37 additions & 0 deletions ci/test_cmake.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

set -euo pipefail

# Support invoking test_cmake.sh outside the script directory
cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/../

rapids-logger "Create CMake test conda environment"
. /opt/conda/etc/profile.d/conda.sh

rapids-logger "Configuring conda strict channel priority"
conda config --set channel_priority strict

ENV_YAML_DIR="$(mktemp -d)"

rapids-dependency-file-generator \
--output conda \
--file-key test_cmake \
--matrix "cuda=${RAPIDS_CUDA_VERSION%.*};arch=$(arch)" | tee "${ENV_YAML_DIR}/env.yaml"

rapids-mamba-retry env create --yes -f "${ENV_YAML_DIR}/env.yaml" -n cmake_tests

# Temporarily allow unbound variables for conda activation.
set +u
conda activate cmake_tests
set -u

rapids-print-env

rapids-logger "Run RMM CMake tests"
cmake -S cpp/cmake/tests \
-B cpp/build/cmake-tests \
-GNinja \
-DRMM_REPOSITORY_DIR="${PWD}"
ctest --test-dir cpp/build/cmake-tests --output-on-failure -j"$(nproc)"
32 changes: 32 additions & 0 deletions cpp/cmake/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# =============================================================================
# cmake-format: off
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# cmake-format: on
# =============================================================================
cmake_minimum_required(VERSION 4.0 FATAL_ERROR)

project(rmm_cmake_tests LANGUAGES NONE)

enable_testing()

set(RMM_REPOSITORY_DIR
""
CACHE PATH "Path to the RMM repository root")
if(NOT RMM_REPOSITORY_DIR)
cmake_path(SET RMM_REPOSITORY_DIR NORMALIZE "${CMAKE_CURRENT_LIST_DIR}/../../..")
endif()

set(rmm_abi_namespace_build_dir "${CMAKE_CURRENT_BINARY_DIR}/rmm_abi_namespace")

add_test(
NAME rmm_abi_namespace_configure
COMMAND
${CMAKE_COMMAND} -S "${CMAKE_CURRENT_LIST_DIR}/rmm_abi_namespace" -B
"${rmm_abi_namespace_build_dir}" -G "${CMAKE_GENERATOR}"
"-DRMM_REPOSITORY_DIR=${RMM_REPOSITORY_DIR}")

add_test(NAME rmm_abi_namespace COMMAND ${CMAKE_COMMAND} --build "${rmm_abi_namespace_build_dir}")

set_tests_properties(rmm_abi_namespace_configure PROPERTIES FIXTURES_SETUP rmm_abi_namespace)
set_tests_properties(rmm_abi_namespace PROPERTIES FIXTURES_REQUIRED rmm_abi_namespace)
94 changes: 94 additions & 0 deletions cpp/cmake/tests/rmm_abi_namespace/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# =============================================================================
# cmake-format: off
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# cmake-format: on
# =============================================================================
cmake_minimum_required(VERSION 4.0 FATAL_ERROR)

project(rmm_abi_namespace_test LANGUAGES CXX)

set(RMM_REPOSITORY_DIR
""
CACHE PATH "Path to the RMM repository root")
if(NOT RMM_REPOSITORY_DIR)
cmake_path(SET RMM_REPOSITORY_DIR NORMALIZE "${CMAKE_CURRENT_LIST_DIR}/../../../..")
endif()

# Normalize a two-digit RMM version component for use in a C++ identifier.
function(normalize_version_component input output)
string(REGEX REPLACE "^0+" "" normalized "${input}")
if(normalized STREQUAL "")
set(normalized 0)
endif()
set(${output}
"${normalized}"
PARENT_SCOPE)
endfunction()

file(STRINGS "${RMM_REPOSITORY_DIR}/VERSION" current_rmm_version LIMIT_COUNT 1)
if(NOT current_rmm_version MATCHES "^([0-9]+)\\.([0-9]+)\\.")
message(FATAL_ERROR "Unable to parse RMM version: ${current_rmm_version}")
endif()
normalize_version_component("${CMAKE_MATCH_1}" current_rmm_version_major)
normalize_version_component("${CMAKE_MATCH_2}" current_rmm_version_minor)
set(current_rmm_abi_namespace "_RMM_${current_rmm_version_major}_${current_rmm_version_minor}")

# rapids-pre-commit-hooks: disable-next-line[verify-hardcoded-version]
set(previous_rmm_version "26.06.00")
set(previous_rmm_abi_namespace "_RMM_26_6")
if(current_rmm_abi_namespace STREQUAL previous_rmm_abi_namespace)
message(FATAL_ERROR "The current and previous test ABI namespaces must be different")
endif()

set(previous_rmm_source_dir "${CMAKE_CURRENT_BINARY_DIR}/previous-rmm-source")
file(REMOVE_RECURSE "${previous_rmm_source_dir}")
file(MAKE_DIRECTORY "${previous_rmm_source_dir}")
file(
COPY "${RMM_REPOSITORY_DIR}/cpp"
DESTINATION "${previous_rmm_source_dir}"
PATTERN "build" EXCLUDE)
file(COPY "${RMM_REPOSITORY_DIR}/cmake" "${RMM_REPOSITORY_DIR}/RAPIDS_BRANCH"
DESTINATION "${previous_rmm_source_dir}")
file(WRITE "${previous_rmm_source_dir}/VERSION" "${previous_rmm_version}\n")

set(rmm_build_dir "${CMAKE_CURRENT_BINARY_DIR}/rmm-build")
set(previous_rmm_build_dir "${CMAKE_CURRENT_BINARY_DIR}/previous-rmm-build")
set(consumer_build_dir "${CMAKE_CURRENT_BINARY_DIR}/consumer-build")
set(consumer_source_dir "${CMAKE_CURRENT_LIST_DIR}/consumer")
set(rmm_library "${rmm_build_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}rmm${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(previous_rmm_library
"${previous_rmm_build_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}rmm${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(consumer_library
"${consumer_build_dir}/${CMAKE_SHARED_LIBRARY_PREFIX}rmm_abi_namespace_consumer${CMAKE_SHARED_LIBRARY_SUFFIX}"
)
set(state_test "${consumer_build_dir}/rmm_abi_state_test${CMAKE_EXECUTABLE_SUFFIX}")

add_custom_target(
verify_rmm_abi_namespace ALL
COMMAND ${CMAKE_COMMAND} -E rm -rf "${rmm_build_dir}" "${previous_rmm_build_dir}"
"${consumer_build_dir}"
COMMAND
${CMAKE_COMMAND} -S "${RMM_REPOSITORY_DIR}/cpp" -B "${rmm_build_dir}" -G "${CMAKE_GENERATOR}"
-DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_BENCHMARKS=OFF
COMMAND ${CMAKE_COMMAND} --build "${rmm_build_dir}" --target rmm
COMMAND
${CMAKE_COMMAND} -S "${previous_rmm_source_dir}/cpp" -B "${previous_rmm_build_dir}" -G
"${CMAKE_GENERATOR}" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF
-DBUILD_BENCHMARKS=OFF
COMMAND ${CMAKE_COMMAND} --build "${previous_rmm_build_dir}" --target rmm
COMMAND
${CMAKE_COMMAND} -S "${consumer_source_dir}" -B "${consumer_build_dir}" -G "${CMAKE_GENERATOR}"
"-Drmm_DIR=${rmm_build_dir}" "-DPREVIOUS_RMM_SOURCE_DIR=${previous_rmm_source_dir}/cpp"
"-DPREVIOUS_RMM_BUILD_DIR=${previous_rmm_build_dir}"
"-DPREVIOUS_RMM_LIBRARY=${previous_rmm_library}"
COMMAND ${CMAKE_COMMAND} --build "${consumer_build_dir}"
COMMAND
${CMAKE_COMMAND} "-DREADELF=${CMAKE_READELF}" "-DRMM_LIBRARY=${rmm_library}"
"-DPREVIOUS_RMM_LIBRARY=${previous_rmm_library}" "-DCONSUMER_LIBRARY=${consumer_library}"
"-DCURRENT_RMM_ABI_NAMESPACE=${current_rmm_abi_namespace}"
"-DPREVIOUS_RMM_ABI_NAMESPACE=${previous_rmm_abi_namespace}" -P
"${CMAKE_CURRENT_LIST_DIR}/verify_symbol_versions.cmake"
COMMAND "${state_test}"
COMMENT "Verifying composition and process state for multiple RMM ABI versions"
VERBATIM)
61 changes: 61 additions & 0 deletions cpp/cmake/tests/rmm_abi_namespace/consumer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# =============================================================================
# cmake-format: off
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# cmake-format: on
# =============================================================================
cmake_minimum_required(VERSION 4.0 FATAL_ERROR)

project(rmm_abi_namespace_consumer LANGUAGES CXX)

foreach(required_path IN ITEMS PREVIOUS_RMM_SOURCE_DIR PREVIOUS_RMM_BUILD_DIR PREVIOUS_RMM_LIBRARY)
if(NOT DEFINED ${required_path} OR NOT EXISTS "${${required_path}}")
message(FATAL_ERROR "${required_path} must name an existing path")
endif()
endforeach()

find_package(rmm REQUIRED CONFIG)

add_library(previous_rmm STATIC IMPORTED)
set_target_properties(previous_rmm PROPERTIES IMPORTED_LOCATION "${PREVIOUS_RMM_LIBRARY}")

get_target_property(rmm_link_libraries rmm::rmm INTERFACE_LINK_LIBRARIES)
if(NOT rmm_link_libraries)
message(FATAL_ERROR "rmm::rmm has no interface link libraries")
endif()

add_library(previous_rmm_call OBJECT previous.cpp)
target_include_directories(previous_rmm_call BEFORE PRIVATE "${PREVIOUS_RMM_SOURCE_DIR}/include"
"${PREVIOUS_RMM_BUILD_DIR}/include")
target_link_libraries(previous_rmm_call PRIVATE ${rmm_link_libraries})
set_target_properties(
previous_rmm_call
PROPERTIES POSITION_INDEPENDENT_CODE ON
CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON)

add_library(rmm_abi_namespace_consumer SHARED current.cpp $<TARGET_OBJECTS:previous_rmm_call>)
target_link_libraries(
rmm_abi_namespace_consumer
PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,rmm::rmm>" "$<LINK_LIBRARY:WHOLE_ARCHIVE,previous_rmm>"
${rmm_link_libraries})
set_property(TARGET rmm_abi_namespace_consumer PROPERTY CXX_STANDARD 20)
set_property(TARGET rmm_abi_namespace_consumer PROPERTY CXX_STANDARD_REQUIRED ON)

add_library(current_state_a SHARED current_state_a.cpp)
add_library(current_state_b SHARED current_state_b.cpp)
foreach(target IN ITEMS current_state_a current_state_b)
target_link_libraries(${target} PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,rmm::rmm>")
set_target_properties(${target} PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON)
endforeach()

add_library(previous_state SHARED previous_state.cpp)
target_include_directories(previous_state BEFORE PRIVATE "${PREVIOUS_RMM_SOURCE_DIR}/include"
"${PREVIOUS_RMM_BUILD_DIR}/include")
target_link_libraries(previous_state PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,previous_rmm>"
${rmm_link_libraries})
set_target_properties(previous_state PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON)

add_executable(rmm_abi_state_test state_test.cpp)
target_link_libraries(rmm_abi_state_test PRIVATE current_state_a current_state_b previous_state)
set_target_properties(rmm_abi_state_test PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON)
13 changes: 13 additions & 0 deletions cpp/cmake/tests/rmm_abi_namespace/consumer/current.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include <rmm/aligned.hpp>

#include <cstddef>

std::size_t call_current_rmm_align_up(std::size_t value, std::size_t alignment)
{
return rmm::align_up(value, alignment);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include <rmm/mr/per_device_resource.hpp>

extern "C" void const* current_state_a_map() { return &rmm::mr::detail::get_ref_map(); }
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include <rmm/mr/per_device_resource.hpp>

extern "C" void const* current_state_b_map() { return &rmm::mr::detail::get_ref_map(); }
13 changes: 13 additions & 0 deletions cpp/cmake/tests/rmm_abi_namespace/consumer/previous.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include <rmm/aligned.hpp>

#include <cstddef>

std::size_t call_previous_rmm_align_up(std::size_t value, std::size_t alignment)
{
return rmm::align_up(value, alignment);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include <rmm/mr/per_device_resource.hpp>

extern "C" void const* previous_state_map() { return &rmm::mr::detail::get_ref_map(); }
15 changes: 15 additions & 0 deletions cpp/cmake/tests/rmm_abi_namespace/consumer/state_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

extern "C" void const* current_state_a_map();
extern "C" void const* current_state_b_map();
extern "C" void const* previous_state_map();

int main()
{
if (current_state_a_map() != current_state_b_map()) { return 1; }
if (current_state_a_map() == previous_state_map()) { return 2; }
return 0;
}
Loading
Loading