-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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 to literal behaviour between <=0.49.0 and >=0.50.0 #6274
Comments
I think my situation is slightly different to your case @JSKenyon. I have a parallel numba and a serial numba implementation each using nested literals to further expand policies of the function. Those functions are both However, I find the reason for the error not obvious. None of my literal policy types declare another |
To expand on this here is an exact reproducer of the case I mentioned @JSKenyon from numba.extending import overload, register_jitable
from numba import jit, literally
### WORKS in version 0.51.2 and in <=0.49
@jit(nopython=True, fastmath=True, parallel=False, cache=True, nogil=True)
def f(mode_1, mode_2):
return subf(literally(mode_1), literally(mode_2))
@jit(nopython=True, fastmath=True, parallel=False, cache=True, nogil=True,
inline="always")
def subf(mode_1,mode_2):
return _f(mode_1, mode_2)
def _f(mode_1, mode_2):
return
#### DOES NOT WORK in version >=0.5, works in <=0.49
#
#@jit(nopython=True, fastmath=True, parallel=False, cache=True, nogil=True)
#def f(mode_1, mode_2):
# return subf(literally(mode_1), mode_2)
#
#@jit(nopython=True, fastmath=True, parallel=False, cache=True, nogil=True,
# inline="always")
#def subf(mode_1,mode_2):
# return _f(mode_1, literally(mode_2))
#
#def _f(mode_1, mode_2):
# return
##########################################
### Fake policies for nested static polymorphism
#########################################
@overload(_f, inline='always')
def _f_impl(mode_1, mode_2):
if mode_1.literal_value == "a":
return impl_a
elif mode_1.literal_value == "b":
return impl_b
else:
raise ValueError("Unsupported mode!")
@register_jitable
def impl_a(mode_1, mode_2):
print("Using impl_a!")
return sub_func_a(mode_2)
@register_jitable
def impl_b(mode_1, mode_2):
print("Using impl_b!")
return sub_func_b(mode_2)
def sub_func_a(mode_2):
return
@overload(sub_func_a, inline='always')
def _sub_func_a(mode_2):
if mode_2.literal_value == "c":
return lambda mode_2: 0
else:
return lambda mode_2: 1
def sub_func_b(mode_2):
return
@overload(sub_func_b, inline='always')
def _sub_func_b(mode_2):
if mode_2.literal_value == "c":
return lambda mode_2: 3
else:
return lambda mode_2: 4
if __name__ == "__main__":
print(f("a", "c"))
print(f("a", "d"))
print(f("b", "c"))
print(f("b", "d")) |
To any Numba devs who get involved - this looks to be two separate but related issues. |
Thanks for the report. I think the behavioural change is covered by point 2 of the core feature changes for 0.51: https://numba.readthedocs.io/en/stable/release-notes.html#version-0-51-0-august-12-2020 namely:
I think that from numba.extending import overload, register_jitable
from numba import jit, literally, types
@jit(nopython=True, fastmath=True, parallel=False, cache=True, nogil=True)
def f(mode):
return _f(mode)
def _f(mode):
return
@overload(_f, inline='always')
def _f_impl(mode):
# For the getattr to work, `mode` must be literal, so request it
if not isinstance(mode, types.Literal):
return lambda mode: literally(mode)
if mode.literal_value == "a":
return impl_a
elif mode.literal_value == "b":
return impl_b
else:
raise ValueError("Unsupported mode!")
@register_jitable
def impl_a(mode):
print("Using impl_a!")
return sub_func(mode)
@register_jitable
def impl_b(mode):
print("Using impl_b!")
return sub_func(mode)
def sub_func(mode):
return
@overload(sub_func, inline='always')
def _sub_func(mode):
# For the getattr to work, `mode` must be literal, so request it
if not isinstance(mode, types.Literal):
return lambda mode: literally(mode)
if mode.literal_value == "a":
return lambda mode: 0
else:
return lambda mode: 1
if __name__ == "__main__":
print(f("a"))
print(f("b")) |
Thanks @stuartarchibald - this does seem more reliable! Will play around with it. :-) |
No problem, the way |
As title. Fixes numba#6238 Closes numba#6274
Reporting a bug
visible in the change log (https://github.com/numba/numba/blob/master/CHANGE_LOG).
to write one see http://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports).
Reproducer
Problem
The above fails when using
numba>=0.50.0
with'NoneType' object is not callable
. This example runs without issue withnumba<=0.49.0
. I believe the issue stems from literally'ing an already literally'ed value - removing the literally calls from thesub_func
invocations makes this run withnumba>=0.50.0
.Question
Will this be the expected behaviour going forward and is the above pattern acceptable?
The text was updated successfully, but these errors were encountered: