-
Notifications
You must be signed in to change notification settings - Fork 254
Honor requested aligned adaptor alignment #2396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -14,6 +14,26 @@ | |||||
| namespace RMM_NAMESPACE { | ||||||
| namespace mr { | ||||||
| namespace detail { | ||||||
| namespace { | ||||||
|
|
||||||
| [[nodiscard]] std::size_t upstream_allocation_size(std::size_t bytes, std::size_t alignment) | ||||||
| { | ||||||
| auto const aligned_size = rmm::align_up(bytes, alignment); | ||||||
| return aligned_size + (alignment - rmm::CUDA_ALLOCATION_ALIGNMENT); | ||||||
| } | ||||||
|
|
||||||
| [[nodiscard]] std::size_t effective_alignment(std::size_t bytes, | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| std::size_t requested_alignment, | ||||||
| std::size_t configured_alignment, | ||||||
| std::size_t alignment_threshold) noexcept | ||||||
| { | ||||||
| return std::max( | ||||||
| {requested_alignment, | ||||||
| bytes >= alignment_threshold ? configured_alignment : rmm::CUDA_ALLOCATION_ALIGNMENT, | ||||||
| rmm::CUDA_ALLOCATION_ALIGNMENT}); | ||||||
| } | ||||||
|
|
||||||
| } // namespace | ||||||
|
|
||||||
| aligned_resource_adaptor_impl::aligned_resource_adaptor_impl( | ||||||
| cuda::mr::any_resource<cuda::mr::device_accessible> upstream, | ||||||
|
|
@@ -39,24 +59,21 @@ std::size_t aligned_resource_adaptor_impl::get_alignment_threshold() const noexc | |||||
| return alignment_threshold_; | ||||||
| } | ||||||
|
|
||||||
| std::size_t aligned_resource_adaptor_impl::upstream_allocation_size(std::size_t bytes) const | ||||||
| { | ||||||
| auto const aligned_size = rmm::align_up(bytes, alignment_); | ||||||
| return aligned_size + (alignment_ - rmm::CUDA_ALLOCATION_ALIGNMENT); | ||||||
| } | ||||||
|
|
||||||
| void* aligned_resource_adaptor_impl::allocate(cuda::stream_ref stream, | ||||||
| std::size_t bytes, | ||||||
| std::size_t /*alignment*/) | ||||||
| std::size_t alignment) | ||||||
| { | ||||||
| if (bytes == 0 || alignment_ == rmm::CUDA_ALLOCATION_ALIGNMENT || bytes < alignment_threshold_) { | ||||||
| RMM_EXPECTS(rmm::is_supported_alignment(alignment), "Allocation alignment is not a power of 2."); | ||||||
| auto const effective_align = | ||||||
| effective_alignment(bytes, alignment, alignment_, alignment_threshold_); | ||||||
| if (bytes == 0 || effective_align == rmm::CUDA_ALLOCATION_ALIGNMENT) { | ||||||
| return upstream_mr_.allocate(stream, bytes, 1); | ||||||
|
Comment on lines
+69
to
70
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note: this implicitly encodes that every RMM memory resource must provide allocations that are Imagine I am a writing my own resource, and I forget about this restriction. I think we should also push (again) for the "related" request in this cccl issue NVIDIA/cccl#8157 We can at least implement said properties on all RMM resources today, I think. |
||||||
| } | ||||||
| auto const size = upstream_allocation_size(bytes); | ||||||
| auto const size = upstream_allocation_size(bytes, effective_align); | ||||||
| void* pointer = upstream_mr_.allocate(stream, size, 1); | ||||||
| // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) | ||||||
| auto const address = reinterpret_cast<std::size_t>(pointer); | ||||||
| auto const aligned_address = rmm::align_up(address, alignment_); | ||||||
| auto const aligned_address = rmm::align_up(address, effective_align); | ||||||
| // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast,performance-no-int-to-ptr) | ||||||
| void* aligned_pointer = reinterpret_cast<void*>(aligned_address); | ||||||
| if (pointer != aligned_pointer) { | ||||||
|
|
@@ -70,9 +87,11 @@ void* aligned_resource_adaptor_impl::allocate(cuda::stream_ref stream, | |||||
| void aligned_resource_adaptor_impl::deallocate(cuda::stream_ref stream, | ||||||
| void* ptr, | ||||||
| std::size_t bytes, | ||||||
| std::size_t /*alignment*/) noexcept | ||||||
| std::size_t alignment) noexcept | ||||||
| { | ||||||
| if (bytes == 0 || alignment_ == rmm::CUDA_ALLOCATION_ALIGNMENT || bytes < alignment_threshold_) { | ||||||
| auto const effective_align = | ||||||
| effective_alignment(bytes, alignment, alignment_, alignment_threshold_); | ||||||
| if (bytes == 0 || effective_align == rmm::CUDA_ALLOCATION_ALIGNMENT) { | ||||||
| upstream_mr_.deallocate(stream, ptr, bytes, 1); | ||||||
| } else { | ||||||
| { | ||||||
|
|
@@ -83,7 +102,7 @@ void aligned_resource_adaptor_impl::deallocate(cuda::stream_ref stream, | |||||
| pointers_.erase(iter); | ||||||
| } | ||||||
| } | ||||||
| upstream_mr_.deallocate(stream, ptr, upstream_allocation_size(bytes), 1); | ||||||
| upstream_mr_.deallocate(stream, ptr, upstream_allocation_size(bytes, effective_align), 1); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -88,6 +88,15 @@ TEST(AlignedTest, ThrowOnInvalidAllocationAlignment) | |
| EXPECT_THROW(construct_alignment(wrapper, 768), rmm::logic_error); | ||
| } | ||
|
|
||
| TEST(AlignedTest, ThrowOnInvalidRequestedAlignment) | ||
| { | ||
| mock_resource mock; | ||
| mock_resource_wrapper wrapper{&mock}; | ||
| aligned_adaptor mr{device_async_resource_ref{wrapper}}; | ||
|
|
||
| EXPECT_THROW((void)mr.allocate(cuda_stream_view{}, 1024, 768), rmm::logic_error); | ||
| } | ||
|
|
||
| TEST(AlignedTest, SupportsGetMemInfo) | ||
| { | ||
| mock_resource mock; | ||
|
|
@@ -197,6 +206,54 @@ TEST(AlignedTest, AlignUpstreamAddress) | |
| } | ||
| } | ||
|
|
||
| TEST(AlignedTest, AlignsCallerRequestedAlignment) | ||
| { | ||
| mock_resource mock; | ||
| mock_resource_wrapper wrapper{&mock}; | ||
| aligned_adaptor mr{device_async_resource_ref{wrapper}}; | ||
|
|
||
| cuda_stream_view stream; | ||
| auto const alignment{4096}; | ||
| { | ||
| void* const pointer = int_to_address(256); | ||
| auto const size{7936}; | ||
| EXPECT_CALL(mock, allocate(_, size, _)).WillOnce(Return(pointer)); | ||
| EXPECT_CALL(mock, deallocate(_, pointer, size, _)).Times(1); | ||
| } | ||
|
|
||
| { | ||
| void* const expected_pointer = int_to_address(4096); | ||
| auto const size{1024}; | ||
| EXPECT_EQ(mr.allocate(stream, size, alignment), expected_pointer); | ||
| mr.deallocate(stream, expected_pointer, size, alignment); | ||
|
Comment on lines
+225
to
+228
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand how gtest's |
||
| } | ||
| } | ||
|
|
||
| TEST(AlignedTest, CallerRequestedAlignmentOverridesThreshold) | ||
| { | ||
| mock_resource mock; | ||
| mock_resource_wrapper wrapper{&mock}; | ||
| auto const alignment{4096}; | ||
| auto const threshold{65536}; | ||
| aligned_adaptor mr{device_async_resource_ref{wrapper}, alignment, threshold}; | ||
|
|
||
| cuda_stream_view stream; | ||
| auto const requested_alignment{8192}; | ||
| { | ||
| void* const pointer = int_to_address(256); | ||
| auto const size{16128}; | ||
| EXPECT_CALL(mock, allocate(_, size, _)).WillOnce(Return(pointer)); | ||
| EXPECT_CALL(mock, deallocate(_, pointer, size, _)).Times(1); | ||
| } | ||
|
|
||
| { | ||
| void* const expected_pointer = int_to_address(8192); | ||
| auto const size{1024}; | ||
| EXPECT_EQ(mr.allocate(stream, size, requested_alignment), expected_pointer); | ||
| mr.deallocate(stream, expected_pointer, size, requested_alignment); | ||
|
Comment on lines
+250
to
+253
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. again here. |
||
| } | ||
| } | ||
|
|
||
| TEST(AlignedTest, AlignMultiple) | ||
| { | ||
| mock_resource mock; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Although
align_upis notconstexprbecause inNDEBUGmode itasserts)