-
Notifications
You must be signed in to change notification settings - Fork 210
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
Add async view memory resource bindings to Python. #1864
Changes from 3 commits
0370efd
4e4be1a
b34ea3b
88a2f71
b7e899d
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 |
---|---|---|
|
@@ -28,7 +28,8 @@ from libcpp.memory cimport make_unique, unique_ptr | |
from libcpp.optional cimport optional | ||
from libcpp.pair cimport pair | ||
|
||
from cuda.bindings.runtime import cudaError_t | ||
from cuda.bindings cimport cyruntime | ||
from cuda.bindings import runtime | ||
|
||
from rmm._cuda.gpu import CUDARuntimeError, getDevice, setDevice | ||
|
||
|
@@ -54,6 +55,7 @@ from rmm.librmm.memory_resource cimport ( | |
binning_memory_resource, | ||
callback_memory_resource, | ||
cuda_async_memory_resource, | ||
cuda_async_view_memory_resource, | ||
cuda_memory_resource, | ||
deallocate_callback_t, | ||
device_memory_resource, | ||
|
@@ -203,6 +205,38 @@ cdef class CudaAsyncMemoryResource(DeviceMemoryResource): | |
) | ||
|
||
|
||
cdef class CudaAsyncViewMemoryResource(DeviceMemoryResource): | ||
""" | ||
Memory resource that uses ``cudaMallocAsync``/``cudaFreeAsync`` for | ||
allocation/deallocation with an existing CUDA memory pool. | ||
|
||
This resource uses an existing CUDA memory pool handle (such as the default pool) | ||
instead of creating a new one. This is useful for integrating with existing GPU | ||
applications that already use a CUDA memory pool, or customizing the flags | ||
used by the memory pool. | ||
|
||
Parameters | ||
---------- | ||
valid_pool_handle : cudaMemPool_t | ||
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 like the name 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. Sure, though please mention somewhere in this docstring that the user is responsible for keeping the mempool alive 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. Done in b7e899d. The new sentence says,
|
||
Handle to a CUDA memory pool which will be used to serve allocation | ||
requests. | ||
""" | ||
def __cinit__( | ||
self, | ||
valid_pool_handle | ||
bdice marked this conversation as resolved.
Show resolved
Hide resolved
|
||
): | ||
cdef cyruntime.cudaMemPool_t c_memory_pool_handle = \ | ||
<cyruntime.cudaMemPool_t>valid_pool_handle | ||
self.c_obj.reset( | ||
new cuda_async_view_memory_resource(c_memory_pool_handle) | ||
) | ||
bdice marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def pool_handle(self): | ||
cdef cuda_async_view_memory_resource* c_mr = \ | ||
<cuda_async_view_memory_resource*>self.c_obj.get() | ||
return <uintptr_t>c_mr.pool_handle() | ||
|
||
|
||
cdef class ManagedMemoryResource(DeviceMemoryResource): | ||
def __cinit__(self): | ||
self.c_obj.reset( | ||
|
@@ -991,7 +1025,7 @@ cpdef void _initialize( | |
try: | ||
original_device = getDevice() | ||
except CUDARuntimeError as e: | ||
if e.status == cudaError_t.cudaErrorNoDevice: | ||
if e.status == runtime.cudaError_t.cudaErrorNoDevice: | ||
wence- marked this conversation as resolved.
Show resolved
Hide resolved
|
||
warnings.warn(e.msg) | ||
else: | ||
raise e | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1078,3 +1078,36 @@ def test_available_device_memory(): | |
assert initial_memory[1] == final_memory[1] | ||
assert initial_memory[0] > 0 | ||
assert final_memory[0] > 0 | ||
|
||
|
||
@pytest.mark.parametrize("dtype", _dtypes) | ||
@pytest.mark.parametrize("nelem", _nelems) | ||
@pytest.mark.parametrize("alloc", _allocs) | ||
def test_cuda_async_view_memory_resource_default_pool(dtype, nelem, alloc): | ||
# Get the default memory pool handle | ||
current_device = rmm._cuda.gpu.getDevice() | ||
err, pool = runtime.cudaDeviceGetDefaultMemPool(current_device) | ||
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. Does this pool need to be released? I don't know how the default mempool behaves 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 think so. It cannot be destroyed, per the docs. Attempting to destroy it returns an error code. 😄
|
||
assert err == runtime.cudaError_t.cudaSuccess | ||
|
||
mr = rmm.mr.CudaAsyncViewMemoryResource(pool) | ||
rmm.mr.set_current_device_resource(mr) | ||
assert rmm.mr.get_current_device_resource_type() is type(mr) | ||
array_tester(dtype, nelem, alloc) | ||
|
||
|
||
@pytest.mark.parametrize("dtype", _dtypes) | ||
@pytest.mark.parametrize("nelem", _nelems) | ||
@pytest.mark.parametrize("alloc", _allocs) | ||
def test_cuda_async_view_memory_resource_custom_pool(dtype, nelem, alloc): | ||
# Create a memory pool handle | ||
props = runtime.cudaMemPoolProps() | ||
props.allocType = runtime.cudaMemAllocationType.cudaMemAllocationTypePinned | ||
props.location.id = rmm._cuda.gpu.getDevice() | ||
props.location.type = runtime.cudaMemLocationType.cudaMemLocationTypeDevice | ||
err, pool = runtime.cudaMemPoolCreate(props) | ||
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. This test should also destroy the pool 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. Good idea! Tested in b7e899d. It also makes sure that the memory resource raises a |
||
assert err == runtime.cudaError_t.cudaSuccess | ||
|
||
mr = rmm.mr.CudaAsyncViewMemoryResource(pool) | ||
rmm.mr.set_current_device_resource(mr) | ||
assert rmm.mr.get_current_device_resource_type() is type(mr) | ||
array_tester(dtype, nelem, alloc) |
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.
Fixed a missing rule-of-6 destructor declaration here, which raised a warning in my IDE.