Repository: numba/numba

Issue:
numba advices to use cross2d but specified path is wrong
Hello everyone,

# The issue (for which I propose a fix below)

While using numba, I got an error when trying to compile this code:
```python
@numba.njit(boolean(float64[:, :]))
def is_convex(polygon):
    vertices = get_vertices(polygon)
    m, _ = vertices.shape
    vectors = np.empty((m, 2), dtype=np.float64)
    for i, j in vertices:
        vectors[i] = polygon[j, :] - polygon[i, :]
        
    for i, j in vertices:
        if np.cross(vectors[i,:], vectors[j, :]) < 0:
            return False
    return True
```

The error I get:
```python
is_convex(polygon)
>>> ---------------------------------------------------------------------------
>>> ValueError                                Traceback (most recent call last)
>>> <ipython-input-18-dc4c8f71d7e1> in <module>
>>> ----> 1 is_convex(polygon)
>>> 
>>> ~/.local/lib/python3.6/site-packages/numba/np/arraymath.py in impl()
>>>    4380         else:
>>>    4381             raise ValueError((
>>> -> 4382                 "Dimensions for both inputs is 2.\n"
>>>    4383                 "Please replace your numpy.cross(a, b) call with "
>>>    4384                 "numba.numpy_extensions.cross2d(a, b)."
>>> 
>>> ValueError: Dimensions for both inputs is 2.
>>> Please replace your numpy.cross(a, b) call with numba.numpy_extensions.cross2d(a, b).
```

The problem is that `numba.numpy_extensions.cross2d` does not exist:
```python
numba.numpy_extensions.cross2d
>>> ---------------------------------------------------------------------------
>>> AttributeError                            Traceback (most recent call last)
>>> <ipython-input-19-a634a239d236> in <module>
>>> ----> 1 numba.numpy_extensions.cross2d
>>> 
>>> AttributeError: module 'numba' has no attribute 'numpy_extensions'
```

In the documentation, the reference is `numba.np.extensions.cross2d(a, b) (c.f. https://numba.pydata.org/numba-doc/dev/reference/numpysupported.html#other-functions). But it does not exist neither:

```python
numba.np.extensions.cross2d
>>> ---------------------------------------------------------------------------
>>> AttributeError                            Traceback (most recent call last)
>>> <ipython-input-20-3ddb1ccb7c32> in <module>
>>> ----> 1 numba.np.extensions.cross2d
>>> 
>>> AttributeError: module 'numba.np' has no attribute 'extensions'
```

The version I'm using:
```python
import numba
numba.__version__
>>> 0.51.2
```

Before posting this issue, I quickly read the release notes and it does not seem to be fixed in the 0.52.0 version.
https://numba.pydata.org/numba-doc/latest/release-notes.html

I hope my issue is not a duplicate.

# A fix suggestion

Digging in the `numba.np` module, I found that the correct path to the `cross2d` function is actually:
```python
numba.np.arraymath._cross2d_operation(a, b)
```

If it is a documentation error, I can easily make a PR with the fix as this will be a good way for me to start contributing to this nice project !


Discussion:
Thanks for the report. This is almost certainly a mistake made during the giant refactoring of Numba internals that took place earlier in the year. I think the thing you are looking for is now at `numba.np.extensions.cross2d`. Fixes to the error message and docs would most certainly be welcomed, contributing guide is [here](https://numba.readthedocs.io/en/stable/developer/contributing.html). Many thanks!
Also, this seems to be ok:
```pycon
>>> from numba.np.extensions import cross2d
>>> cross2d
CPUDispatcher(<function cross2d at 0x7ff854e13710>)
>>> import numba.np.extensions as ext
>>> ext.cross2d
CPUDispatcher(<function cross2d at 0x7ff854e13710>)
```
guess there needs to be a spelling change somewhere too.
Thank you @stuartarchibald for the quick reply ! It seems that the `extensions` module does not exist in my Jupyter Notebook (where I did the tests) but does exist in a terminal.

Both Terminal and Jupyter:
```python
import numba
numba
>>> <module 'numba' from '/home/jerome/.local/lib/python3.6/site-packages/numba/__init__.py'>
```

Terminal:
```python
numba.np.extensions
>>> <module 'numba.np.extensions' from '/home/jerome/.local/lib/python3.6/site-packages/numba/np/extensions.py'>
dir(numba.np)
>>> ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'arraymath', 'arrayobj', 'extensions', 'linalg', 'npdatetime_helpers', 'numpy_support', 'ufunc', 'unsafe']
```

Jupyer:
```python
numba.np.extensions
>>> ---------------------------------------------------------------------------
>>> AttributeError                            Traceback (most recent call last)
>>> <ipython-input-2-ab4cca6282b6> in <module>
>>> ----> 1 numba.np.extensions
>>> 
>>> AttributeError: module 'numba.np' has no attribute 'extensions'
dir(numba.np)
>>> ['__builtins__',  '__cached__',  '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'arrayobj', 'npdatetime_helpers', 'numpy_support', 'ufunc', 'unsafe']
```

So part of this problem may also be related to Jupyter. I need to dig a little deeper for that.

Anyway, I can still fix the first part of the error which was about non existing `numpy_extensions` module.
It there a way to automatically assign me to this issue ? I know that some public repo have automated bot that assign issue when we enter "take" but I don't know if it is the case here ?
> Thank you @stuartarchibald for the quick reply ! It seems that the `extensions` module does not exist in my Jupyter Notebook (where I did the tests) but does exist in a terminal.
> 
> Both Terminal and Jupyter:
> 
> ```python
> import numba
> numba
> >>> <module 'numba' from '/home/jerome/.local/lib/python3.6/site-packages/numba/__init__.py'>
> ```
> 
> Terminal:
> 
> ```python
> numba.np.extensions
> >>> <module 'numba.np.extensions' from '/home/jerome/.local/lib/python3.6/site-packages/numba/np/extensions.py'>
> dir(numba.np)
> >>> ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'arraymath', 'arrayobj', 'extensions', 'linalg', 'npdatetime_helpers', 'numpy_support', 'ufunc', 'unsafe']
> ```
> 
> Jupyer:
> 
> ```python
> numba.np.extensions
> >>> ---------------------------------------------------------------------------
> >>> AttributeError                            Traceback (most recent call last)
> >>> <ipython-input-2-ab4cca6282b6> in <module>
> >>> ----> 1 numba.np.extensions
> >>> 
> >>> AttributeError: module 'numba.np' has no attribute 'extensions'
> dir(numba.np)
> >>> ['__builtins__',  '__cached__',  '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'arrayobj', 'npdatetime_helpers', 'numpy_support', 'ufunc', 'unsafe']
> ```
> 
> So part of this problem may also be related to Jupyter. I need to dig a little deeper for that.

Could well be, the `numba -s` command will tell you about your local env which might help.

> Anyway, I can still fix the first part of the error which was about non existing `numpy_extensions` module.
> It there a way to automatically assign me to this issue ? I know that some public repo have automated bot that assign issue when we enter "take" but I don't know if it is the case here ?

Great, thanks. Just commenting that you are going to work on it is fine :) but I've assigned you anyway as I guess github UI might pick that up and provide useful things for you in relation to it.

Resolving patch:
diff --git a/numba/np/arraymath.py b/numba/np/arraymath.py
--- a/numba/np/arraymath.py
+++ b/numba/np/arraymath.py
@@ -4395,7 +4395,7 @@ def impl(a, b):
             raise ValueError((
                 "Dimensions for both inputs is 2.\n"
                 "Please replace your numpy.cross(a, b) call with "
-                "numba.numpy_extensions.cross2d(a, b)."
+                "a call to `cross2d(a, b)` from `numba.np.extensions`."
             ))
     return impl
 


Test patch:
diff --git a/numba/tests/test_np_functions.py b/numba/tests/test_np_functions.py
--- a/numba/tests/test_np_functions.py
+++ b/numba/tests/test_np_functions.py
@@ -15,7 +15,7 @@
 from numba.core.errors import TypingError
 from numba.core.config import IS_WIN32, IS_32BITS
 from numba.core.utils import pysignature
-from numba.np.arraymath import cross2d
+from numba.np.extensions import cross2d
 from numba.tests.support import (TestCase, CompilationCache, MemoryLeakMixin,
                                  needs_blas, skip_ppc64le_issue4026)
 import unittest
@@ -3587,7 +3587,12 @@ def test_cross_exceptions(self):
                 np.array((3, 4))
             )
         self.assertIn(
-            'Dimensions for both inputs is 2',
+            'Dimensions for both inputs is 2.',
+            str(raises.exception)
+        )
+
+        self.assertIn(
+            '`cross2d(a, b)` from `numba.np.extensions`.',
             str(raises.exception)
         )