Skip to content

Refactor memory resource ownership and type safety - #985

Merged
rapids-bot[bot] merged 26 commits into
rapidsai:mainfrom
nirandaperera:host_mrs_to_cccl_mr
Apr 30, 2026
Merged

Refactor memory resource ownership and type safety#985
rapids-bot[bot] merged 26 commits into
rapidsai:mainfrom
nirandaperera:host_mrs_to_cccl_mr

Conversation

@nirandaperera

@nirandaperera nirandaperera commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

RmmResourceAdaptorImpl — templated on primary and fallback resources

  • Add PrimaryMR and FallbackMR template parameters (both constrained to
    cuda::mr::resource_with<device_accessible>; FallbackMR defaults to
    any_resource<device_accessible>)
  • Move all method implementations into the header to support full template instantiation
  • Add explicit RmmResourceAdaptorImpl(std::in_place_t, Args&&...) constructor to
    support in-place construction of non-movable types (e.g. cuda::pinned_memory_pool)

PinnedMemoryResource — eliminate redundant heap allocation

  • Inherit from cuda::mr::shared_resource<RmmResourceAdaptorImpl<cuda::pinned_memory_pool>>
    directly, storing the pool inside the shared control block rather than through a
    separate RmmResourceAdaptor member
  • Remove virtual methods from HostMemoryResource, making it a standalone value-semantic type
  • Add default-alignment allocate/deallocate overloads so call sites omitting the
    alignment argument continue to work

Value-semantic factory methods

  • PinnedMemoryResource::make_if_available and from_options now return
    std::optional<PinnedMemoryResource> instead of std::shared_ptr<PinnedMemoryResource>
  • PinnedMemoryResource::Disabled changed from nullptr to std::nullopt_t — existing
    == Disabled comparisons remain valid via optional::operator==(nullopt_t)
  • BufferResource and Statistics members/parameters updated from shared_ptr to
    std::optional
  • BufferResource::host_mr_ reverted to the concrete HostMemoryResource type

Cython bindings

  • PinnedMemoryResource._handle changed from shared_ptr[cpp_PinnedMemoryResource] to
    optional[cpp_PinnedMemoryResource], matching the C++ value semantics throughout
  • buffer_resource.pyx and statistics.pyx updated accordingly

Closes #978

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 requested review from a team as code owners April 22, 2026 04:56
@nirandaperera nirandaperera added breaking Introduces a breaking change improvement Improves an existing functionality labels Apr 22, 2026
Signed-off-by: niranda perera <niranda.perera@gmail.com>

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

Thanks @nirandaperera, looks good. I only have one change request

Comment thread cpp/include/rapidsmpf/memory/pinned_memory_resource.hpp Outdated
Comment thread cpp/include/rapidsmpf/detail/rmm_resource_adaptor_impl.hpp
Comment thread cpp/include/rapidsmpf/detail/rmm_resource_adaptor_impl.hpp
Comment thread cpp/include/rapidsmpf/detail/rmm_resource_adaptor_impl.hpp
Comment on lines +264 to +265
auto* ptr = allocate(cuda::stream_ref{cudaStream_t{nullptr}}, bytes, alignment);
RAPIDSMPF_CUDA_TRY(cudaStreamSynchronize(cudaStream_t{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.

I think we should use an internal stream (stored in the adaptor) rather than the null stream.

Comment on lines +86 to +87
* holds the pool directly inside the shared control block — no extra heap allocation for
* the pool itself. Copies share the same underlying pool and memory statistics.

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.

This aspect seems like it is just not worth it.

@nirandaperera
nirandaperera requested a review from wence- April 22, 2026 18:40
Signed-off-by: niranda perera <niranda.perera@gmail.com>
Signed-off-by: niranda perera <niranda.perera@gmail.com>
Comment thread cpp/include/rapidsmpf/detail/rmm_resource_adaptor_impl.hpp
Comment thread cpp/include/rapidsmpf/detail/rmm_resource_adaptor_impl.hpp Outdated
nirandaperera and others added 6 commits April 23, 2026 11:39
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>
Co-authored-by: Lawrence Mitchell <wence@gmx.li>
Signed-off-by: niranda perera <niranda.perera@gmail.com>
@nirandaperera
nirandaperera requested a review from wence- April 24, 2026 16:40
@nirandaperera

Copy link
Copy Markdown
Contributor Author

@wence- Could you please go through this again? I am inclined to keep the templates in the detail::AdapterImpl, because IINM, we dont have a good way to create a resource in-place other than, wrapping it with a shared_resource.

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

I have some minor questions/suggestions, but I don't think they are blocking. I am just about convinced that the added complexity of templating here is worth it.

Comment thread cpp/benchmarks/bench_memory_resources.cpp Outdated
Comment thread cpp/include/rapidsmpf/detail/rmm_resource_adaptor_impl.hpp
Comment on lines +93 to +97
class PinnedMemoryResource final
: public cuda::mr::shared_resource<
detail::RmmResourceAdaptorImpl<cuda::pinned_memory_pool>> {
using shared_base = cuda::mr::shared_resource<
detail::RmmResourceAdaptorImpl<cuda::pinned_memory_pool>>;

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.

OK, so the only question I now have here is that effectively this bakes that allocation with the pinned pool always uses the RMMResourceAdaptor. I suppose we're going to be relying on that, and it's not different to the device MR which also has to have this wrapping?

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.

Yes, I think so. We can provide a mem-tracking-enabled device memory pool inside rapidsmpf that bakes in cuda mempool into the adapter. Do you think we should provide that?

Comment on lines 104 to 106
auto tracker = *this; // shared ownership — same underlying pool
return [tracker, limit]() { return limit - tracker.get().current_allocated(); };
}

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.

What does dereferencing this buy us here over return [this, limit]() {...};?

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.

this would simply pass by ptr, isnt it? We want to increment the refcount before passing it in IINM.

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

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit 82ba989 into rapidsai:main Apr 30, 2026
66 checks passed
@nirandaperera nirandaperera mentioned this pull request Apr 30, 2026
3 tasks
rapids-bot Bot pushed a commit that referenced this pull request May 6, 2026
## Remove memory resources from `Statistics` construction

`Statistics` held `RmmResourceAdaptor` and `PinnedMemoryResource` as instance fields, tying resource lifetime to the stats object and preventing a single `Statistics` instance from being used with different resources at report time.

### Solution
- Remove `mr_` / `pinned_mr_` fields and the `Statistics(RmmResourceAdaptor, ...)` constructor; `report()` and `create_memory_recorder()` now accept explicit `std::optional<any_device_resource>` / `std::optional<any_host_device_resource>` parameters — callers supply resources at use time.
- Add `try_pinned_mr()` returning `std::optional<any_host_device_resource>` non-throwingly; correct `pinned_mr()` return type to `host_device_async_resource_ref`.
- Add `memory/resource_types.hpp` with `any_device_resource` / `any_host_device_resource` aliases; update `RAPIDSMPF_MEMORY_PROFILE` macro to require an explicit `mr` argument.

Closes #979 

Depends on rapidsai/rapids-cmake#1008 and #985

Authors:
  - Niranda Perera (https://github.com/nirandaperera)

Approvers:
  - Lawrence Mitchell (https://github.com/wence-)

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

Labels

breaking Introduces a breaking change improvement Improves an existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use PinnedMemoryResource with shared_resource rather than shared_ptr

4 participants