Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 321
Support H2D/D2D/D2H SMV copy#1367
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
Closed
Uh oh!
There was an error while loading. Please reload this page.
Closed
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
a3a8bd3
Support H2D/D2D/D2H SMV copy
stiepan 5f2480c
Add missing copyright header
stiepan a22f2f6
More tests, typos, more concise pyproject includes
stiepan 012c31b
Addressing review comments
stiepan c761437
Fix typos and spelling
stiepan a15aef0
Fix tests: indicate device when creating cupy's ExternalStream, wrap …
stiepan 5ceea4d
Merge branch 'main' into support_memview_strided_copy
stiepan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -5,7 +5,11 @@ | ||
| from ._dlpack cimport * | ||
| from libc.stdint cimport intptr_t | ||
| from cuda.core.experimental._layout cimport StridedLayout | ||
| from cuda.core.experimental._stream import Stream | ||
| from cuda.core.experimental._memory._buffer cimport Buffer | ||
| from cuda.core.experimental._strided_copy._copy cimport copy_into_d2d, copy_into_d2h, copy_into_h2d | ||
| from cuda.core.experimental._strided_copy._copy_utils cimport get_data_ptr | ||
| from cuda.core.experimental._stream cimport Stream | ||
| from cuda.core.experimental._strided_copy._copy import CopyAllocatorOptions | ||
| import functools | ||
| import warnings | ||
| @@ -15,9 +19,6 @@ import numpy | ||
| from cuda.core.experimental._utils.cuda_utils import handle_return, driver | ||
| from cuda.core.experimental._memory import Buffer | ||
| # TODO(leofang): support NumPy structured dtypes | ||
| @@ -160,7 +161,7 @@ cdef class StridedMemoryView: | ||
| @classmethod | ||
| def from_buffer( | ||
| cls, buffer : Buffer, layout : StridedLayout, | ||
| cls, Buffer buffer, StridedLayout layout, | ||
| dtype : numpy.dtype | None = None, | ||
| is_readonly : bool = False | ||
| ) -> StridedMemoryView: | ||
| @@ -218,7 +219,7 @@ cdef class StridedMemoryView: | ||
| dlm_tensor.deleter(dlm_tensor) | ||
| def view( | ||
| self, layout : StridedLayout | None = None, dtype : numpy.dtype | None = None | ||
| self, StridedLayout layout = None, object dtype = None | ||
| ) -> StridedMemoryView: | ||
| """ | ||
| Creates a new view with adjusted layout and dtype. | ||
| @@ -236,7 +237,7 @@ cdef class StridedMemoryView: | ||
| def copy_from( | ||
| self, other : StridedMemoryView, stream : Stream, | ||
| allocator = None, | ||
| allocator : CopyAllocatorOptions | dict[str, MemoryResource] | None = None, | ||
leofang marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| blocking : bool | None = None, | ||
| ): | ||
| """ | ||
| @@ -253,16 +254,19 @@ cdef class StridedMemoryView: | ||
| if :attr:`dtype` is not specified). | ||
| * The destination's layout must be unique (see :meth:`StridedLayout.is_unique`). | ||
| It is the user's responsibility to ensure proper current device is set | ||
| when calling this method. | ||
| Parameters | ||
| ---------- | ||
| other : StridedMemoryView | ||
| The view to copy data from. | ||
| stream : Stream | None, optional | ||
| The stream to schedule the copy on. | ||
| allocator : MemoryResource | None, optional | ||
| If temporary buffers are needed, the specifed memory resources | ||
| will be used to allocate the memory. If not specified, default | ||
| resources will be used. | ||
| allocator : :obj:`~utils.CopyAllocatorOptions` | dict[str, :obj:`~_memory.MemoryResource`] | None, optional | ||
| If temporary buffers are needed, the specifed ``allocator.host`` and | ||
| ``allocator.device`` memory resources will be used to allocate the memory | ||
| on the host and device respectively. | ||
| blocking : bool | None, optional | ||
| Whether the call should block until the copy is complete. | ||
| * ``True``: the ``stream`` is synchronized with the host at the end of the call, | ||
| @@ -274,19 +278,19 @@ cdef class StridedMemoryView: | ||
| * for device-to-device, it defaults to ``False`` (non-blocking), | ||
| * for host-to-device or device-to-host, it defaults to ``True`` (blocking). | ||
| """ | ||
| raise NotImplementedError("Sorry, not supported: copy_from") | ||
| copy_into(self, other, stream, allocator, blocking) | ||
| def copy_to( | ||
| self, other : StridedMemoryView, stream : Stream | None = None, | ||
| allocator = None, | ||
| self, other : StridedMemoryView, Stream stream, | ||
| allocator : CopyAllocatorOptions | dict[str, MemoryResource] | None = None, | ||
| blocking : bool | None = None, | ||
| ): | ||
| """ | ||
| Copies the data from this view into the ``other`` view. | ||
| For details, see :meth:`copy_from`. | ||
| """ | ||
| raise NotImplementedError("Sorry, not supported: copy_to") | ||
| copy_into(other, self, stream, allocator, blocking) | ||
| @property | ||
| def layout(self) -> StridedLayout: | ||
| @@ -342,7 +346,7 @@ cdef class StridedMemoryView: | ||
| raise ValueError("Cannot infer layout from the exporting object") | ||
| return self._layout | ||
| cdef inline object get_buffer(self): | ||
| cdef inline Buffer get_buffer(self): | ||
| """ | ||
| Returns Buffer instance with the underlying data. | ||
| If the SMV was created from a Buffer, it will return the same Buffer instance. | ||
| @@ -661,13 +665,9 @@ cdef StridedLayout layout_from_cai(object metadata): | ||
| return layout | ||
| cdef inline intptr_t get_data_ptr(object buffer, StridedLayout layout) except? 0: | ||
| return <intptr_t>(int(buffer.handle)) + layout.get_slice_offset_in_bytes() | ||
| cdef inline int view_buffer_strided( | ||
| StridedMemoryView view, | ||
| object buffer, | ||
| Buffer buffer, | ||
| StridedLayout layout, | ||
| object dtype, | ||
| bint is_readonly, | ||
| @@ -706,3 +706,54 @@ cdef inline int view_buffer_strided( | ||
| view._layout = layout | ||
| view._dtype = dtype | ||
| return 0 | ||
| cdef int copy_into( | ||
| StridedMemoryView dst, | ||
| StridedMemoryView src, | ||
| Stream stream, | ||
| allocator : CopyAllocatorOptions | dict[str, MemoryResource] | None = None, | ||
| blocking : bool | None = None, | ||
| ) except -1: | ||
| cdef object dst_dtype = dst.get_dtype() | ||
| cdef object src_dtype = src.get_dtype() | ||
| if dst_dtype is not None and src_dtype is not None and dst_dtype != src_dtype: | ||
| raise ValueError( | ||
| f"The destination and source dtypes must be the same, " | ||
| f"got {dst_dtype} and {src_dtype}." | ||
| ) | ||
| if dst.readonly: | ||
| raise ValueError("The destination view is readonly.") | ||
| cdef bint is_src_device_accessible = src.is_device_accessible | ||
| cdef bint is_dst_device_accessible = dst.is_device_accessible | ||
| cdef bint is_blocking | ||
| cdef int device_id | ||
| cdef Buffer dst_buffer = dst.get_buffer() | ||
| cdef Buffer src_buffer = src.get_buffer() | ||
| cdef StridedLayout dst_layout = dst.get_layout() | ||
| cdef StridedLayout src_layout = src.get_layout() | ||
| if is_src_device_accessible and is_dst_device_accessible: | ||
| device_id = dst.device_id | ||
| if src.device_id != device_id: | ||
| raise ValueError( | ||
| f"The destination and source views must be on the " | ||
| f"same device, got {device_id} and {src.device_id}." | ||
| ) | ||
| is_blocking = blocking if blocking is not None else False | ||
| copy_into_d2d(dst_buffer, dst_layout, src_buffer, src_layout, device_id, stream, is_blocking) | ||
| return 0 | ||
| elif is_src_device_accessible: | ||
| device_id = src.device_id | ||
| is_blocking = blocking if blocking is not None else True | ||
| copy_into_d2h(dst_buffer, dst_layout, src_buffer, src_layout, device_id, stream, allocator, is_blocking) | ||
| return 0 | ||
| elif is_dst_device_accessible: | ||
| device_id = dst.device_id | ||
| is_blocking = blocking if blocking is not None else True | ||
| copy_into_h2d(dst_buffer, dst_layout, src_buffer, src_layout, device_id, stream, allocator, is_blocking) | ||
| return 0 | ||
| else: | ||
| raise ValueError( | ||
| "The host-to-host copy is not supported, " | ||
| "at least one of the views must be device-accessible." | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| from cuda.core.experimental._stream cimport Stream | ||
| from cuda.core.experimental._layout cimport StridedLayout | ||
| from cuda.core.experimental._memory._buffer cimport Buffer | ||
| from cuda.core.experimental._memory import MemoryResource | ||
| cdef int copy_into_d2d( | ||
| Buffer dst_buffer, | ||
| StridedLayout dst_layout, | ||
| Buffer src_buffer, | ||
| StridedLayout src_layout, | ||
| int device_id, | ||
| Stream stream, | ||
| bint blocking, | ||
| ) except -1 | ||
| cdef int copy_into_d2h( | ||
| Buffer dst_buffer, | ||
| StridedLayout dst_layout, | ||
| Buffer src_buffer, | ||
| StridedLayout src_layout, | ||
| int device_id, | ||
| Stream stream, | ||
| allocator : CopyAllocatorOptions | dict[str, MemoryResource] | None, | ||
| bint blocking, | ||
| ) except -1 | ||
| cdef int copy_into_h2d( | ||
| Buffer dst_buffer, | ||
| StridedLayout dst_layout, | ||
| Buffer src_buffer, | ||
| StridedLayout src_layout, | ||
| int device_id, | ||
| Stream stream, | ||
| allocator : CopyAllocatorOptions | dict[str, MemoryResource] | None, | ||
| bint blocking, | ||
| ) except -1 |
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
Why is one underscore-prefixed (
_base_equal_strides) and the other not (base_equal_shapes)?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.
It's because the shapes check the ndim equality first, while strides don't. I needed the shape equality for the copy, while strides not really. Maybe for completness it makes sense to add "public" version with ndim check too. :D