Repository: numba/numba

Issue:
@intrinsic not working with CUDA
<!--

Thanks for opening an issue! To help the Numba team handle your information
efficiently, please first ensure that there is no other issue present that
already describes the issue you have
(search at https://github.com/numba/numba/issues?&q=is%3Aissue).

-->

## Reporting a bug

<!--

Before submitting a bug report please ensure that you can check off these boxes:

-->

- [x] I have tried using the mainline version of Numba (most recent is
 visible in the change log (https://github.com/numba/numba/blob/master/CHANGE_LOG).
- [x] I have included a self contained code sample to reproduce the problem.
  i.e. it's possible to run as 'python bug.py'.
This:
```
./runtests.py numba.cuda.tests.cudadrv.test_cuda_array_slicing.CudaArraySetting.test_array_assign_all
```
and others, produce:
```
No implementation of function Function(<intrinsic to_fixed_tuple>) found for signature:
 
 >>> to_fixed_tuple(array(int64, 1d, C), Literal[int](2))
 
There are 2 candidate implementations:
     - Of which 2 did not match due to:
     Intrinsic in function 'to_fixed_tuple': File: numba/np/unsafe/ndarray.py: Line 41.
       With argument(s): '(array(int64, 1d, C), int64)':
      Rejected as the implementation raised a specific error:
        KeyError: <class 'numba.core.extending_hardware.CUDA'>
          Traceback (most recent call last):
            File "<path>/numba/numba/core/types/functions.py", line 329, in get_call_type
              sig = temp.apply(nolitargs, nolitkws)
            File "<path>/numba/numba/core/typing/templates.py", line 347, in apply
              sig = generic(args, kws)
            File "<path>/numba/numba/core/typing/templates.py", line 905, in generic
              disp = dispatcher_registry[target_hw]
            File "<path>/numba/numba/core/registry.py", line 99, in __getitem__
              return super(TargetRegistry, self).__getitem__(item)
          KeyError: <class 'numba.core.extending_hardware.CUDA'>
  raised from <path>/numba/numba/core/registry.py:99

During: resolving callee type: Function(<intrinsic to_fixed_tuple>)
During: typing of call at <path>/numba/numba/cuda/cudadrv/devicearray.py (452)


File "numba/cuda/cudadrv/devicearray.py", line 452:
    def kernel(lhs, rhs):
        <source elided>

        lhs[to_fixed_tuple(idx[0], ndim)] = rhs[to_fixed_tuple(idx[1], ndim)]
        ^
```
xref: https://github.com/numba/numba/pull/6944, turns out that the dispatcher registration was needed, but not at exactly that point in the PR sequence to support this new extension functionality.


Discussion:

Resolving patch:
diff --git a/numba/cuda/compiler.py b/numba/cuda/compiler.py
--- a/numba/cuda/compiler.py
+++ b/numba/cuda/compiler.py
@@ -29,6 +29,7 @@
 from .errors import missing_launch_config_msg, normalize_kernel_dimensions
 from .api import get_current_device
 from .args import wrap_arg
+from .descriptor import cuda_target
 
 
 def _nvvm_options_type(x):
@@ -852,6 +853,8 @@ class Dispatcher(_dispatcher.Dispatcher, serialize.ReduceMixin):
     # cases.
     _fold_args = False
 
+    targetdescr = cuda_target
+
     def __init__(self, py_func, sigs, targetoptions):
         self.py_func = py_func
         self.sigs = []
@@ -870,9 +873,7 @@ def __init__(self, py_func, sigs, targetoptions):
         self.targetoptions['extensions'] = \
             list(self.targetoptions.get('extensions', []))
 
-        from .descriptor import cuda_target
-
-        self.typingctx = cuda_target.typing_context
+        self.typingctx = self.targetdescr.typing_context
 
         self._tm = default_type_manager
 
diff --git a/numba/cuda/initialize.py b/numba/cuda/initialize.py
--- a/numba/cuda/initialize.py
+++ b/numba/cuda/initialize.py
@@ -3,11 +3,15 @@ def initialize_all():
     import numba.cuda.models  # noqa: F401
 
     from numba import cuda
+    from numba.cuda.compiler import Dispatcher
     from numba.core import decorators
-    from numba.core.extending_hardware import hardware_registry
+    from numba.core.extending_hardware import (hardware_registry,
+                                               dispatcher_registry)
 
     def cuda_jit_device(*args, **kwargs):
         kwargs['device'] = True
         return cuda.jit(*args, **kwargs)
 
-    decorators.jit_registry[hardware_registry["cuda"]] = cuda_jit_device
+    cuda_hw = hardware_registry["cuda"]
+    decorators.jit_registry[cuda_hw] = cuda_jit_device
+    dispatcher_registry[cuda_hw] = Dispatcher
diff --git a/numba/cuda/target.py b/numba/cuda/target.py
--- a/numba/cuda/target.py
+++ b/numba/cuda/target.py
@@ -11,7 +11,6 @@
 
 from .cudadrv import nvvm
 from numba.cuda import codegen, nvvmutils
-from .decorators import jitdevice
 from numba.cpython import cmathimpl
 
 
@@ -39,6 +38,7 @@ def resolve_value_type(self, val):
                     raise ValueError('using cpu function on device '
                                      'but its compilation is disabled')
                 opt = val.targetoptions.get('opt', True)
+                from .decorators import jitdevice
                 jd = jitdevice(val, debug=val.targetoptions.get('debug'),
                                opt=opt)
                 # cache the device function for future use and to avoid


Test patch: