-
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
A prototype of first-class functions [DON'T MERGE] #4967
Conversation
/AzurePipelines run |
Azure Pipelines successfully started running 1 pipeline(s). |
The current PR implements first-class function type support for |
@sklam @stuartarchibald I have addressed all Siu's notes:
|
Thanks @pearu I've marked it as such. I'll hopefully be able to look at it in the next day or so. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR, great to see this feature implemented. I've given this a review solely from the standpoint of looking at the code, please find suggestions/comments inline. The next phase will be to manually stress test the implementation. Thanks again!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR, great to see this feature implemented. I've given this a review solely from the standpoint of looking at the code, please find suggestions/comments inline. The next phase will be to manually stress test the implementation. Thanks again!
Before this branch is merged, this feature needs to be well documented and some examples need writing as users are sure to ask. Thanks. |
With this PR, i think Sample code that fails without `@njit`import numpy as np
from numba import njit, cfunc, intp, float64, function
@cfunc("intp(intp, float64)")
def foo1(x, y):
return x + y
@cfunc("intp(intp, float64)")
def foo2(x, y):
return x - y
# @njit # doesn't work without @njit
def bar(fx, fy, i):
a = np.array([10], dtype=np.intp)
b = np.array([12], dtype=np.float64)
if i == 0:
f = fx
elif i == 1:
f = fy
else:
return
return f(a[0], b[0]) # TypeError: 'CFunc' object is not callable
r = bar(foo1, foo2, 0)
print(r) |
… 2. cfunc object holds python function, hence pyaddr is always valid
@sklam @stuartarchibald, please review:
|
Note to self. Check docs. @sklam approves code. |
If #5287 is replacing, can this be closed now? |
yes, this can be closed. |
Tackles the issue #3405 but closes once support for
njit
decorated functions is implemented.The middle-level description of the first-class function model is as follows:
numba.cfunc(<signature>)
decorated function (of typeCFunc
), then the address is readily available via its_wrapper_address
attribute. This PR introduces so-called wrapper address protocol (see https://github.com/numba/numba/pull/4967/files#diff-275bdd7060d042bc811293de00e7878dR115-R143 for the definition and support) that enables interpreting arbitrary python objects as first-class functions when passed to a njitted function as an argument. For instance, to retrieve a function address from a python object such asCFunc
, the functionnumba.function._get_wrapper_address(obj, signature)
is called from the unboxing procedure. The implementation of the_get_wrapper_address
for theCFunc
objects would be as simple as (assuming thatCFunc
instance is compiled against a correct signature):cfunc
decorated functions). For instance, one can implement caching of compiled functions as an independent method to numba jit caching model, or one can call arbitrary library functions from njitted functions (as long as one is able to determine the pointer values of the library functions, one can usectypes
for that). See https://github.com/numba/numba/pull/4967/files#diff-75b50def42de3256e721ce2c6e79c47dR282-R322 for an example of how to call a libc functiontime
from a njitted function.Current status:
cfunc
decorated functionsnjit
decorated functionsBoth constant (available via namespace lookup) and passed in functions (available as arguments of njitted functions)
cfunc
decorated functionsnjit
decorated functionsBoth constant and passed in functions
cfunc
decorated functionsnjit
decorated functionsBoth constant and passed in functions
cfunc
decorated functionsnjit
decorated functionsSignature
vsFunctionType
issueExample: