Skip to content
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

Numba raises types error despite getting the appropriate types #9025

Closed
2 tasks done
Badr-MOUFAD opened this issue Jun 19, 2023 · 2 comments
Closed
2 tasks done

Numba raises types error despite getting the appropriate types #9025

Badr-MOUFAD opened this issue Jun 19, 2023 · 2 comments

Comments

@Badr-MOUFAD
Copy link

Badr-MOUFAD commented Jun 19, 2023

Reporting a bug

  • I have tried using the latest released version of Numba (most recent is
    visible in the change log (https://github.com/numba/numba/blob/main/CHANGE_LOG).
  • I have included a self contained code sample to reproduce the problem.
    i.e. it's possible to run as 'python bug.py'.

Bug description

When running the following snippet

import numpy as np
from numba import njit

@njit
def buggy_func(x, y):
    return 1. * x @ y

x = np.ones(2, np.float32)
y = np.ones(2, np.float32)

buggy_func(x, y)

I get an error telling me I'm computing the dot product of a float64 and float32.
Here is a full log of the error

(click to expend)
Traceback (most recent call last):
  File "~/debug_script.py", line 71, in <module>
    buggy_func(x, y)
  File "~/venv/lib/python3.9/site-packages/numba/core/dispatcher.py", line 468, in _compile_for_args
    error_rewrite(e, 'typing')
  File "~/venv/lib/python3.9/site-packages/numba/core/dispatcher.py", line 409, in error_rewrite
    raise e.with_traceback(None)
numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Failed in nopython mode pipeline (step: nopython frontend)
No implementation of function Function(<intrinsic _impl>) found for signature:
 
 >>> _impl(array(float64, 1d, C), array(float32, 1d, C))
 
There are 2 candidate implementations:
  - Of which 2 did not match due to:
  Intrinsic in function 'dot_2_impl.<locals>._impl': File: numba/np/linalg.py: Line 543.
    With argument(s): '(array(float64, 1d, C), array(float32, 1d, C))':
   Rejected as the implementation raised a specific error:
     TypingError: '@' arguments must all have the same dtype
  raised from ~/venv/lib/python3.9/site-packages/numba/np/linalg.py:563

During: resolving callee type: Function(<intrinsic _impl>)
During: typing of call at ~/venv/lib/python3.9/site-packages/numba/np/linalg.py (582)


File "venv/lib/python3.9/site-packages/numba/np/linalg.py", line 582:
            def _dot2_codegen(context, builder, sig, args):
                <source elided>

        return lambda left, right: _impl(left, right)
        ^

During: typing of intrinsic-call at ~debug_script.py (65)

File "debug_script.py", line 65:
def buggy_func(x, y):
    return 1. * x @ y
    ^

Considered alternative

As surprising as might seem to be,
computing the dot product first and then performing the multiplication solves the problem

@njit
def fixed_func(x, y):
    dot = x @ y
    return 1. * dot

Machine specs

  • Python version: 3.9
  • OS: Linux Ubuntu 64-bit
  • numba version: 0.57.0
  • numpy version: 1.24.3

Other details

Looking at the error log, nothing seems to be wrong with the implementation of the dot product.
Therefore, I suspect that the bug comes from the inference of the types.

Finally, I will be happy to work on fixing this bug.

@apmasell
Copy link
Contributor

The default type assumed for a floating point constant will be a float64. You can add an explicit conversion to float32 and that should do the right thing:

import numpy as np
from numba import njit

@njit
def buggy_func(x, y):
    return np.float32(1.) * x @ y

x = np.ones(2, np.float32)
y = np.ones(2, np.float32)

buggy_func(x, y)

@Badr-MOUFAD
Copy link
Author

Badr-MOUFAD commented Jun 20, 2023

Thanks @apmasell a lot for your response.

Explicitly converting to scaler is a bit cumbersome since I don't know in advance the type of x and y.

I ended up solving the problem by specifying an order in operations, wrapping the dot product in parentheses.

import numpy as np
from numba import njit

@njit
def fixed_func(x, y):
    return 1. * (x @ y)

x = np.ones(2, np.float32)
y = np.ones(2, np.float32)

fixed_func(x, y)

After analyzing further buggy_func, I released that numba performed the following

flowchart TD;
    A("float64") --> |1.| C("float64[:]");
    B("float32[:]") --> |x| C;
    C --> |1. * x| E(Type Error);
    D("float32[:]") --> |y| E;

Thanks again for your input!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants