Ambiguous overloads are allowed for calls to jitted functions inside other jitted functions
For example:
from numba import njit
@njit(['(float32, float64)', '(float64, float32)'])
def add(x, y):
return x + y
# (float64, float64) is an equal match for the (float32, float64) and (float64, float32) compiled versions
try:
add(1.0, 2.0)
except TypeError as te:
print(f"Got TypeError as expected: {str(te)}")
# Also an equal match for the compiled versions of add, but is allowed to compile
@njit('(float64, float64)')
def add_caller(x, y):
return add(x, y)
print(add_caller(1.0, 2.0))
Got TypeError as expected: Ambiguous overloading for <function add at 0x7fa5c51b9cf0> (float64, float64):
(float32, float64) -> float64
(float64, float32) -> float64
3.0
So the dispatcher disallows dispatch of ambiguous overloads, but the compiler permits compilation with them. Is this intended?
Why do ambiguous overloads even matter? Could we just pick the first one instead of giving an error?
the problem seems to be at https://github.com/numba/numba/blob/main/numba/core/typing/context.py#L620 and allows_ambiguous is True when resolving add() in add_caller().
This sample code produces the wrong answer due to the above.
from numba import njit
import numpy as np
@njit(['(float32, float64)', '(float64, float32)'])
def add(x, y):
return x + y
# Also an equal match for the compiled versions of add, but is allowed to compile
@njit('(float64, float64)')
def add_caller(x, y):
return add(x, y) # x will get converted to float32 as (float32, float64) is a match
a = np.uint64(0x0010000000000000).view(np.float64)
b = np.float64(0x0)
print(add_caller(a, b))
# Now use open compilation for add
@njit
def add_open(x, y):
return x + y
@njit('(float64, float64)')
def add_caller_to_open(x, y):
return add_open(x, y)
print(add_caller_to_open(a, b))
gives:
0.0
2.2250738585072014e-308
turning off the ambiguous overload leads to error like:
TypeError: Ambiguous overloading for <built-in function eq> (uint64, int64):
(float64, float64) -> bool
(complex128, complex128) -> bool
in the testsuite. So, eq(uin64, int64) is ambiguous and can be promoted to either (float64, float64) -> bool or (complex128, complex128) -> bool
This issue is marked as stale as it has had no activity in the past 30 days. Please close this issue if no further response or action is needed. Otherwise, please respond with any updates and confirm that this issue still needs to be addressed.