Skip to content

[cudf] Adding memory_resources support for column wrappers - #23581

Open
nirandaperera wants to merge 20 commits into
NVIDIA:mainfrom
nirandaperera:test-column-wrappers-mr
Open

[cudf] Adding memory_resources support for column wrappers#23581
nirandaperera wants to merge 20 commits into
NVIDIA:mainfrom
nirandaperera:test-column-wrappers-mr

Conversation

@nirandaperera

Copy link
Copy Markdown
Contributor

Description

Depends on #23578

A part of #20780.

Port column wrappers to accept memory_resources and stream

Adds defaulted stream and memory_resources parameters to cudftestutil
column wrappers and helpers so tests can control allocation and stream
routing. Includes MR tests for wrappers and timestamp generators.

Checklist

  • I am familiar with the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

@nirandaperera nirandaperera added improvement Improvement / enhancement to an existing function non-breaking Non-breaking change labels Aug 7, 2026
@copy-pr-bot

copy-pr-bot Bot commented Aug 7, 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.

Adds defaulted stream and memory_resources parameters to cudftestutil
column wrappers and helpers so tests can control allocation and stream
routing. Includes MR tests for wrappers and timestamp generators.

Signed-off-by: niranda perera <niranda.perera@gmail.com>
@nirandaperera
nirandaperera force-pushed the test-column-wrappers-mr branch from 380696c to d11a8bb Compare August 7, 2026 21:35
@copy-pr-bot

copy-pr-bot Bot commented Aug 7, 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.

@nirandaperera
nirandaperera marked this pull request as ready for review August 7, 2026 21:35
@nirandaperera
nirandaperera requested a review from a team as a code owner August 7, 2026 21:35
@coderabbitai

coderabbitai Bot commented Aug 7, 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

Summary by CodeRabbit

  • New Features

    • Column-wrapper utilities now support custom CUDA streams and memory resources across supported column types and nested structures.
    • Timestamp generation supports custom streams and memory resources.
    • Column construction and copying consistently preserve the selected allocation context.
  • Bug Fixes

    • Intermediate test utilities now honor provided streams and temporary memory resources instead of default allocations.
  • Tests

    • Added coverage for allocation behavior across column wrappers, nested structures, dictionary columns, and timestamp generation.

Walkthrough

Column-wrapper APIs now accept CUDA streams and memory resources across primitive, dictionary, list, struct, timestamp, and comparison paths. Tests validate allocation routing and update empty-wrapper construction.

Changes

Column-wrapper allocation context

Layer / File(s) Summary
Primitive wrapper allocation routing
cpp/include/cudf_test/column_wrapper.hpp, cpp/include/cudf_test/memory_resource_utilities.hpp, cpp/tests/utilities_tests/column_wrapper_tests.cpp
Primitive wrappers and resource-test factories now use explicit allocation contexts.
Dictionary wrapper resource propagation
cpp/include/cudf_test/column_wrapper.hpp, cpp/tests/utilities_tests/column_wrapper_tests.cpp
Dictionary construction routes source and encoded data through the supplied resources.
Nested list and struct allocation routing
cpp/include/cudf_test/column_wrapper.hpp, cpp/tests/utilities_tests/column_utilities_tests.cpp
Nested construction propagates streams and resources through child columns, offsets, masks, normalization, and comparisons.
Timestamp and utility integration
cpp/include/cudf_test/timestamp_utilities.cuh, cpp/tests/utilities/column_utilities.cu, cpp/tests/wrappers/timestamps_test.cu, cpp/tests/utilities_tests/column_utilities_tests.cpp
Timestamp generation, difference-column construction, and utility tests use explicit allocation contexts.
Empty wrapper construction updates
cpp/tests/*
Empty test columns now use direct empty-wrapper construction.

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

Possibly related PRs

  • rapidsai/cudf#23028: Provides the memory-resource types and harness used by this change.
  • rapidsai/cudf#23486: Adds related stream and memory-resource propagation in column-related code.
  • rapidsai/cudf#23578: Extends related stream and memory-resource propagation in cudf test utilities.

Suggested reviewers: kingcrimsontianyu, lamarrr

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.78% 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 clearly summarizes the main change: adding memory_resources support to column wrappers.
Description check ✅ Passed The description directly explains the stream and memory_resources changes and the added allocation tests.
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.
✨ 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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cpp/include/cudf_test/column_wrapper.hpp (1)

1963-1970: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Pass stream and the output resource to make_lists_column.

The offsets, the concatenated child data, and the null mask now use the supplied stream and output resource. make_lists_column at Line 1969 still uses the default stream and the current device resource. make_lists_column can allocate when it sanitizes null rows, and it enforces ordering on its own stream. This creates two problems: allocations escape the supplied resource, and work on the caller stream is not ordered against work on the default stream. The same call appears at Line 2004 in build_from_non_nested and at Line 1885 in the private adopting constructor.

🛠️ Proposed change
     // construct the list column
-    wrapped = make_lists_column(
-      cols.size(), std::move(offsets), std::move(data), null_count, std::move(null_mask));
+    wrapped = make_lists_column(cols.size(),
+                                std::move(offsets),
+                                std::move(data),
+                                null_count,
+                                std::move(null_mask),
+                                stream,
+                                mr.get_output_mr());
As per coding guidelines: "Propagate stream and memory-resource parameters through all internal APIs and correctly order operations across streams using events or explicit dependencies."
🤖 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/include/cudf_test/column_wrapper.hpp` around lines 1963 - 1970, Update
the list-column construction calls in the current builder,
build_from_non_nested, and the private adopting constructor to pass the supplied
stream and output memory resource to make_lists_column. Ensure all related
allocations and sanitization work use that resource and execute on the caller’s
stream, preserving correct ordering.

Source: Coding guidelines

🧹 Nitpick comments (1)
cpp/include/cudf_test/timestamp_utilities.cuh (1)

8-9: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Include the headers that declare the new parameter types.

The signature now uses rmm::cuda_stream_view and cudf::memory_resources. Both arrive only through cudf_test/column_wrapper.hpp. Include them directly.

♻️ Proposed change
 `#include` <cudf_test/column_wrapper.hpp>
 `#include` <cudf_test/default_stream.hpp>
 
 `#include` <cudf/detail/iterator.cuh>
 `#include` <cudf/utilities/export.hpp>
+#include <cudf/utilities/memory_resource.hpp>
 `#include` <cudf/wrappers/timestamps.hpp>
+
+#include <rmm/cuda_stream_view.hpp>
As per coding guidelines: "include headers directly for every used symbol without unused or incorrectly styled includes."
🤖 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/include/cudf_test/timestamp_utilities.cuh` around lines 8 - 9, Update the
includes in timestamp_utilities.cuh to directly include the headers declaring
rmm::cuda_stream_view and cudf::memory_resources, rather than relying on
cudf_test/column_wrapper.hpp transitively. Preserve the existing includes only
if their symbols remain used.

Source: Coding guidelines

🤖 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/include/cudf_test/column_wrapper.hpp`:
- Around line 823-837: Remove the stale preceding Doxygen block above the
constructor `strings_column_wrapper` so only the new documentation block remains
attached to it. Apply the same cleanup to the duplicated documentation blocks
near the other `strings_column_wrapper` constructors identified in the comment,
without changing constructor behavior.
- Around line 1846-1861: Update make_one_empty_row_column so both constructor
calls pass arguments in stream-then-memory-resource order: construct values with
stream and mr, and construct lists_column_wrapper with stream and mr after the
existing data arguments. Preserve the current validity and null-mask behavior.
- Around line 2163-2181: Remove the no-validity structs_column_wrapper
constructors, including the vector and initializer-list overloads, and retain
the overloads that require an explicit validity argument so calls such as
structs_column_wrapper{{child_a, child_b}} are no longer ambiguous.

In `@cpp/tests/utilities_tests/column_wrapper_tests.cpp`:
- Around line 133-171: Update StringsColumnWrapperMemoryResourceTest inputs to
include non-ASCII UTF-8 strings in the relevant strings_column_wrapper overload
cases, while retaining the existing empty values and null validity coverage.
Ensure the added values are used consistently where input vectors, initializer
lists, and pair-based strings are exercised so character-buffer and offset
allocations are tested with multi-byte text.

---

Outside diff comments:
In `@cpp/include/cudf_test/column_wrapper.hpp`:
- Around line 1963-1970: Update the list-column construction calls in the
current builder, build_from_non_nested, and the private adopting constructor to
pass the supplied stream and output memory resource to make_lists_column. Ensure
all related allocations and sanitization work use that resource and execute on
the caller’s stream, preserving correct ordering.

---

Nitpick comments:
In `@cpp/include/cudf_test/timestamp_utilities.cuh`:
- Around line 8-9: Update the includes in timestamp_utilities.cuh to directly
include the headers declaring rmm::cuda_stream_view and cudf::memory_resources,
rather than relying on cudf_test/column_wrapper.hpp transitively. Preserve the
existing includes only if their symbols remain used.
🪄 Autofix

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: 9f5adc43-3fc8-43e3-8862-a51b77cbe169

📥 Commits

Reviewing files that changed from the base of the PR and between 9fed14e and d11a8bb.

📒 Files selected for processing (6)
  • cpp/include/cudf_test/column_wrapper.hpp
  • cpp/include/cudf_test/memory_resource_utilities.hpp
  • cpp/include/cudf_test/timestamp_utilities.cuh
  • cpp/tests/utilities/column_utilities.cu
  • cpp/tests/utilities_tests/column_wrapper_tests.cpp
  • cpp/tests/wrappers/timestamps_test.cu

Comment thread cpp/include/cudf_test/column_wrapper.hpp
Comment thread cpp/include/cudf_test/column_wrapper.hpp
Comment thread cpp/include/cudf_test/column_wrapper.hpp Outdated
Comment thread cpp/tests/utilities_tests/column_wrapper_tests.cpp
Signed-off-by: niranda perera <niranda.perera@gmail.com>

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

🤖 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/utilities_tests/column_wrapper_tests.cpp`:
- Around line 416-435: In cpp/tests/utilities_tests/column_wrapper_tests.cpp
lines 416-435 and 520-539, update both comparison tests around match_col, col,
and CUDF_TEST_EXPECT_COLUMNS_EQUAL to assert the combined output allocation size
while both released columns remain alive, using the fixture’s
validate_with_harness() contract. Then explicitly destroy match_col and col so
TearDown() can verify all tracked allocations are released.
🪄 Autofix

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: 16135ac2-adf3-40cd-ae52-5f8cfa27aec9

📥 Commits

Reviewing files that changed from the base of the PR and between d11a8bb and 3f518af.

📒 Files selected for processing (1)
  • cpp/tests/utilities_tests/column_wrapper_tests.cpp

Comment thread cpp/tests/utilities_tests/column_wrapper_tests.cpp
Signed-off-by: niranda perera <niranda.perera@gmail.com>

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

🤖 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/utilities_tests/column_utilities_tests.cpp`:
- Around line 80-86: Update all three cudf::split calls in
cpp/tests/utilities_tests/column_utilities_tests.cpp at lines 80-86, 105-111,
and 307-312 to pass stream as the third argument, while preserving the existing
col and splits arguments.
🪄 Autofix

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: 378c8a02-4ee3-40d2-8393-7375b50d2186

📥 Commits

Reviewing files that changed from the base of the PR and between 3f518af and cb35fb0.

📒 Files selected for processing (1)
  • cpp/tests/utilities_tests/column_utilities_tests.cpp

Comment thread cpp/tests/utilities_tests/column_utilities_tests.cpp
rmm::device_buffer make_elements(
InputIterator begin,
InputIterator end,
rmm::cuda_stream_view stream = cudf::test::get_default_stream(),

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.

I think we typically say that detail functions do not get defaults for stream or mr, to ensure that callers pass the parameters and don’t get the wrong stream/mr by default.

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.

Yes please.

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.

@bdice I think we can easily do this to make_elements util. But changing this in make_null_mask to accept explicit stream/mr is going to touch many places 😞
https://github.com/rapidsai/cudf/blob/7ec9b08f8791c18a01cd56453575cd1c302f59a2/cpp/include/cudf_test/column_wrapper.hpp#L276

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.

@nirandaperera and I discussed and that work will go into a follow-up PR.

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.

#23639 This PR will remove the defaults from the make_null_mask declaration.

Signed-off-by: niranda perera <niranda.perera@gmail.com>
Signed-off-by: niranda perera <niranda.perera@gmail.com>
Signed-off-by: niranda perera <niranda.perera@gmail.com>
Signed-off-by: niranda perera <niranda.perera@gmail.com>
Signed-off-by: niranda perera <niranda.perera@gmail.com>
Signed-off-by: niranda perera <niranda.perera@gmail.com>
Signed-off-by: niranda perera <niranda.perera@gmail.com>
@nirandaperera
nirandaperera marked this pull request as draft August 11, 2026 03:22
@nirandaperera
nirandaperera marked this pull request as ready for review August 11, 2026 03:22
rmm::device_buffer make_elements(
InputIterator begin,
InputIterator end,
rmm::cuda_stream_view stream = cudf::test::get_default_stream(),

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.

@nirandaperera and I discussed and that work will go into a follow-up PR.

: strings_column_wrapper(std::cbegin(strings), std::cend(strings), v)
template <
typename ValidityIterator,
std::enable_if_t<!std::is_convertible_v<ValidityIterator&, cudf::memory_resources>>* = nullptr>

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 there some ambiguity in the constructor here? I wonder what else we could do -- do we really need all of these constructors? If we remove parameter defaults, can we reduce ambiguity?

Also let's use requires instead of SFINAE if we can.

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.

Update: we're going to try cuda::stream_ref instead of rmm::cuda_stream_view. The types are implicitly convertible but cuda::stream_ref isn't default-constructible (or at least that's deprecated).

template <
typename InputIterator,
typename ValidityIterator,
std::enable_if_t<!std::is_convertible_v<ValidityIterator&, cudf::memory_resources>>* = nullptr>

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.

Same question here and elsewhere.

Comment on lines +53 to +54
scoped_current_device_resource(scoped_current_device_resource&&) noexcept;
scoped_current_device_resource& operator=(scoped_current_device_resource&&) noexcept;

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.

Why did we need to make this movable?

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.

I wanted to be able to move an obj to std::optional. Either way, I think moveable is a correct semantic for scoped_current_device_resource, is it not?

Comment thread cpp/tests/utilities/column_utilities.cu Outdated
Comment on lines +545 to +546
// TODO: Pass `mr` once two_table_comparator / equality preprocessed_table::create accept
// memory_resources instead of allocating from the current device resource.

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 doesn't seem like this is included in #23027. Is this a requirement to get to the cudf::label_bins pilot, or is this additional scope? Either way we should make sure it's tracked in the issue.

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.

Its already drafted #23617

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.

We need the comparators and preprocessed table changes, to fully make the column utils like
CUDF_TEST_EXPECT_COLUMNS_EQUAL free from current resource.

Signed-off-by: niranda perera <niranda.perera@gmail.com>
@nirandaperera

Copy link
Copy Markdown
Contributor Author

@bdice I simplified this a lot. Waiting for the GH forks to be unblocked

Signed-off-by: niranda perera <niranda.perera@gmail.com>
@nirandaperera
nirandaperera requested a review from a team as a code owner August 12, 2026 16:25
nirandaperera and others added 5 commits August 12, 2026 09:39
Co-authored-by: Bradley Dice <bdice@bradleydice.com>
Signed-off-by: niranda perera <niranda.perera@gmail.com>
return rmm::device_buffer{
elements.data(), size * sizeof(ElementTo), cudf::test::get_default_stream()};
rmm::device_buffer buffer{elements.data(), size * sizeof(ElementTo), stream, mr.get_output_mr()};
stream.synchronize(); // wait for async H2D before host source is destroyed

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.

I have the impression this stream sync might be too conservative.
Unless we are reading from the device to the host, I don't think we need to insert a stream sync

return rmm::device_buffer{
elements.data(), size * sizeof(RepType), cudf::test::get_default_stream()};
rmm::device_buffer buffer{elements.data(), size * sizeof(RepType), stream, mr.get_output_mr()};
stream.synchronize(); // wait for async H2D before host source is destroyed

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.

same as above

cudf::bitmask_allocation_size_bytes(cudf::distance(begin, end)),
stream,
mr.get_output_mr()};
stream.synchronize(); // wait for async H2D before host source is destroyed

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.

same as above

0});
rmm::device_buffer data{elements.data(), size * sizeof(Rep), stream, mr.get_output_mr()};
wrapped.reset(new cudf::column{data_type, size, std::move(data), rmm::device_buffer{}, 0});
stream.synchronize(); // wait for async H2D before host source is destroyed

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.

same as above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improvement / enhancement to an existing function libcudf Affects libcudf (C++/CUDA) code. non-breaking Non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants