-
Notifications
You must be signed in to change notification settings - Fork 73
Migrate numba-cuda driver to use cuda.core.launch API #609
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
Changes from all commits
6e4c988
84b1440
7f0783f
ec4e346
dc540ea
401fa41
d0b7727
307312f
5091b75
9059965
e50501b
c85abc1
c614ee5
96d4e44
10a5b05
af95198
160ac13
d8e765e
319209a
98a12b4
9191b2c
72a173d
8f82249
9bda848
46441bd
d7f29df
8a5adab
c5b2013
67a3f02
4753b44
9e6d9bf
4e58ef5
c143077
636a7a5
c32b51c
7d70639
83fb41a
5f7b5b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,8 @@ | |
| import re | ||
| from warnings import warn | ||
|
|
||
| from cuda.core.experimental import launch | ||
|
|
||
| from numba.cuda.core import errors | ||
| from numba.cuda import serialize, utils | ||
| from numba import cuda | ||
|
|
@@ -39,6 +41,7 @@ | |
| from numba.cuda.core import sigutils, config, entrypoints | ||
| from numba.cuda.flags import Flags | ||
| from numba.cuda.cudadrv import driver, nvvm | ||
| from cuda.core.experimental import LaunchConfig | ||
| from numba.cuda.locks import module_init_lock | ||
| from numba.cuda.core.caching import Cache, CacheImpl, NullCache | ||
| from numba.cuda.descriptor import cuda_target | ||
|
|
@@ -475,18 +478,15 @@ def launch(self, args, griddim, blockdim, stream=0, sharedmem=0): | |
| for t, v in zip(self.argument_types, args): | ||
| self._prepare_args(t, v, stream, retr, kernelargs) | ||
|
|
||
| stream_handle = driver._stream_handle(stream) | ||
|
|
||
| # Invoke kernel | ||
| driver.launch_kernel( | ||
| cufunc.handle, | ||
| *griddim, | ||
| *blockdim, | ||
| sharedmem, | ||
| stream_handle, | ||
| kernelargs, | ||
| cooperative=self.cooperative, | ||
| config = LaunchConfig( | ||
| grid=griddim, | ||
| block=blockdim, | ||
| shmem_size=sharedmem, | ||
| cooperative_launch=self.cooperative, | ||
| ) | ||
| kernel = cufunc.kernel | ||
| launch(stream, config, kernel, *kernelargs) | ||
|
|
||
| if self.debug: | ||
| driver.device_to_host(ctypes.addressof(excval), excmem, excsz) | ||
|
|
@@ -540,30 +540,26 @@ def _prepare_args(self, ty, val, stream, retr, kernelargs): | |
|
|
||
| if isinstance(ty, types.Array): | ||
| devary = wrap_arg(val).to_device(retr, stream) | ||
| c_intp = ctypes.c_ssize_t | ||
|
|
||
| meminfo = ctypes.c_void_p(0) | ||
| parent = ctypes.c_void_p(0) | ||
| nitems = c_intp(devary.size) | ||
| itemsize = c_intp(devary.dtype.itemsize) | ||
|
|
||
| ptr = driver.device_pointer(devary) | ||
|
|
||
| ptr = int(ptr) | ||
|
|
||
| data = ctypes.c_void_p(ptr) | ||
| meminfo = 0 | ||
| parent = 0 | ||
|
|
||
| kernelargs.append(meminfo) | ||
| kernelargs.append(parent) | ||
| kernelargs.append(nitems) | ||
| kernelargs.append(itemsize) | ||
| kernelargs.append(data) | ||
| kernelargs.extend(map(c_intp, devary.shape)) | ||
| kernelargs.extend(map(c_intp, devary.strides)) | ||
|
|
||
| # non-pointer-arguments-without-ctypes might be dicey, since we're | ||
| # assuming shape, strides, size, and itemsize fit into intptr_t | ||
| # however, this saves a noticeable amount of overhead in kernel | ||
| # invocation | ||
| kernelargs.append(devary.size) | ||
| kernelargs.append(devary.dtype.itemsize) | ||
| kernelargs.append(devary.device_ctypes_pointer.value) | ||
| kernelargs.extend(devary.shape) | ||
| kernelargs.extend(devary.strides) | ||
|
|
||
| elif isinstance(ty, types.CPointer): | ||
| # Pointer arguments should be a pointer-sized integer | ||
| kernelargs.append(ctypes.c_uint64(val)) | ||
| kernelargs.append(val) | ||
|
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. This is okay, because Python |
||
|
|
||
| elif isinstance(ty, types.Integer): | ||
| cval = getattr(ctypes, "c_%s" % ty)(val) | ||
|
|
@@ -582,8 +578,7 @@ def _prepare_args(self, ty, val, stream, retr, kernelargs): | |
| kernelargs.append(cval) | ||
|
|
||
| elif ty == types.boolean: | ||
| cval = ctypes.c_uint8(int(val)) | ||
| kernelargs.append(cval) | ||
| kernelargs.append(val) | ||
|
|
||
| elif ty == types.complex64: | ||
| kernelargs.append(ctypes.c_float(val.real)) | ||
|
|
@@ -598,8 +593,7 @@ def _prepare_args(self, ty, val, stream, retr, kernelargs): | |
|
|
||
| elif isinstance(ty, types.Record): | ||
| devrec = wrap_arg(val).to_device(retr, stream) | ||
| ptr = devrec.device_ctypes_pointer | ||
| kernelargs.append(ptr) | ||
| kernelargs.append(devrec.device_ctypes_pointer.value) | ||
|
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. It's actually slightly faster to pull out the |
||
|
|
||
| elif isinstance(ty, types.BaseTuple): | ||
| assert len(ty) == len(val) | ||
|
|
@@ -671,7 +665,7 @@ def __init__(self, dispatcher, griddim, blockdim, stream, sharedmem): | |
| self.dispatcher = dispatcher | ||
| self.griddim = griddim | ||
| self.blockdim = blockdim | ||
| self.stream = stream | ||
| self.stream = driver._to_core_stream(stream) | ||
| self.sharedmem = sharedmem | ||
|
|
||
| if ( | ||
|
|
@@ -700,6 +694,16 @@ def __call__(self, *args): | |
| args, self.griddim, self.blockdim, self.stream, self.sharedmem | ||
| ) | ||
|
|
||
| def __getstate__(self): | ||
| state = self.__dict__.copy() | ||
| state["stream"] = int(state["stream"].handle) | ||
| return state | ||
|
|
||
| def __setstate__(self, state): | ||
| handle = state.pop("stream") | ||
| self.__dict__.update(state) | ||
| self.stream = driver._to_core_stream(handle) | ||
|
cpcloud marked this conversation as resolved.
|
||
|
|
||
|
|
||
| class CUDACacheImpl(CacheImpl): | ||
| def reduce(self, kernel): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,11 +13,10 @@ | |
| CUDATestCase, | ||
| skip_on_cudasim, | ||
| ) | ||
| from cuda.core.experimental import ObjectCode | ||
|
|
||
| if not config.ENABLE_CUDASIM: | ||
| from cuda.bindings.driver import cuModuleGetGlobal, cuMemcpyHtoD | ||
|
|
||
| from cuda.bindings.driver import CUmodule as cu_module_type | ||
| from cuda.bindings.driver import cuLibraryGetGlobal, cuMemcpyHtoD | ||
|
|
||
|
|
||
| def wipe_all_modules_in_context(): | ||
|
|
@@ -31,22 +30,22 @@ def wipe_all_modules_in_context(): | |
| ctx.reset() | ||
|
|
||
|
|
||
| def get_hashable_handle_value(handle): | ||
| return handle | ||
| def get_hashable_handle_value(object_code): | ||
| return object_code.handle | ||
|
|
||
|
|
||
| @skip_on_cudasim("Module loading not implemented in the simulator") | ||
| class TestModuleCallbacksBasic(CUDATestCase): | ||
| def test_basic(self): | ||
| counter = 0 | ||
|
|
||
| def setup(handle): | ||
| self.assertTrue(isinstance(handle, cu_module_type)) | ||
| def setup(object_code): | ||
| self.assertIsInstance(object_code, ObjectCode) | ||
| nonlocal counter | ||
| counter += 1 | ||
|
|
||
| def teardown(handle): | ||
| self.assertTrue(isinstance(handle, cu_module_type)) | ||
| def teardown(object_code): | ||
| self.assertIsInstance(object_code, ObjectCode) | ||
| nonlocal counter | ||
| counter -= 1 | ||
|
|
||
|
|
@@ -183,10 +182,10 @@ def setUp(self): | |
| } | ||
| """ | ||
|
|
||
| def set_forty_two(handle): | ||
| def set_forty_two(object_code): | ||
| # Initialize 42 to global variable `num` | ||
| res, dptr, size = cuModuleGetGlobal( | ||
| get_hashable_handle_value(handle), "num".encode() | ||
| res, dptr, size = cuLibraryGetGlobal( | ||
|
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. We'll probably have to update the callback signature in the documentation as well: |
||
| get_hashable_handle_value(object_code), b"num" | ||
| ) | ||
|
|
||
| arr = np.array([42], np.int32) | ||
|
|
||
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.
Should this be addressed before merging?
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.
Dunno. It likely requires some significant changes to
cuda.coreobjects and more plumbing. Seeing as how theinfo_logmember ofCudaPythonModuleis removed in this PR, and it was never used anywhere, I'd say that we remove it for now to avoid additional things blocking this PR.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.
cc @leofang
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.
I suspect there were very few users of
info_log, with me being the primary one - I used it when debugging issues only. It's not high priority to bring back unless someone asks for it, IMHO.