Repository navigation
Add writable args - #7009
Add writable args#7009
Conversation
|
Thanks very much for the PR, I've queued it for review. |
|
Why my PR was moved to Numba 0.56RC. I need this change for my work. Is it possible to return this PR back to Numba 0.55RC? |
|
@dmbelov Apologies for the long delay in someone reviewing your PR - it was moved to 0.56 because 0.55 RC was produced before someone could review this. |
gmarkall
left a comment
There was a problem hiding this comment.
Many thanks for the PR - some initial thoughts as I've had a quick look through this.
- The code changes generally look good and appear to align with the discussions in #6864 and numpy/numpy#18700
- The documentation presently states that you can't reliably write to input values in this section - https://numba--7009.org.readthedocs.build/en/7009/user/vectorize.html#overwriting-input-values - could you also update this documentation to explain that it is possible using
writable_args? Adapting your example from the PR description may also be helpful. - Swapping
nopython=Truefortarget='cuda'in the decorator results in aTypeError- I think it won't be as simple to support for the CUDA target so you probably won't want to make it work for CUDA; could you ensure that iftarget='cuda'is used withwritable_args, then an explanatory error message is presented to the user please? - How does this interact with dynamic gufuncs, where a signature is not provided up front?
- The PR description mentions that this adds the new kwarg for
vectorizeas well asguvectorize, but there aren't any tests or example withvectorize- I think it's fine if this is only forguvectorize(I'm not sure I see how it could be applied tovectorizeas the arguments to avectorizefunction tend to get passed in as scalars) - could you clarify whether there'svectorizesupport please? - I've only skimmed the tests so far - many thanks for adding tests with the PR.
(The error when trying to use the CUDA target was:
File "/home/gmarkall/numbadev/issues/7009/repro.py", line 8, in <module>
replace_2nd = numba.guvectorize(["void(f8[:], f8[:])"], "(t),()",)(_replace_2nd)
File "/home/gmarkall/numbadev/numba/numba/np/ufunc/decorators.py", line 201, in wrap
guvec = GUVectorize(func, signature, **kwargs)
File "/home/gmarkall/numbadev/numba/numba/np/ufunc/decorators.py", line 60, in __new__
return imp(func, signature, identity=identity, cache=cache,
TypeError: __init__() got an unexpected keyword argument 'writable_args'
)
3729f9f to
3f160f5
Compare
|
@dmbelov Many thanks for the update - I've marked this as waiting for another review. As a small request regarding the process - could you please avoid force-pushes / rebases and instead add new commits and merge from main please? It is quite hard to tell what changed since the previous review / comments if the history is edited - many thanks in advance. |
|
Many thanks for addressing the feedback.
It doesn't, but I don't think we need to be constrained by what the NumPy API is limited to, if we can provide a broader or easier-to-use API.
It does - I think it should be possible without too much trouble to allow arguments to be specified by name for diff --git a/numba/np/ufunc/ufuncbuilder.py b/numba/np/ufunc/ufuncbuilder.py
index b50a23d31..8b9dcabf4 100644
--- a/numba/np/ufunc/ufuncbuilder.py
+++ b/numba/np/ufunc/ufuncbuilder.py
@@ -332,7 +332,22 @@ class GUFuncBuilder(_BaseUFuncBuilder):
self.cache = cache
self._sigs = []
self._cres = {}
- self.writable_args = writable_args
+
+ args = inspect.getfullargspec(py_func).args
+ argpositions = {arg: i for i, arg in enumerate(args)}
+
+ def transform_arg(arg):
+ if isinstance(arg, int):
+ return arg
+
+ try:
+ return argpositions[arg]
+ except KeyError:
+ msg = (f"Specified writable arg {arg} not found in arg list "
+ f"{args} for function {py_func.__qualname__}")
+ raise RuntimeError(msg)
+
+ self.writable_args = tuple([transform_arg(a) for a in writable_args])
def _finalize_signature(self, cres, args, return_type):
if not cres.objectmode and cres.signature.return_type != types.void:
diff --git a/numba/tests/npyufunc/test_update_inplace.py b/numba/tests/npyufunc/test_update_inplace.py
index 27cabdc82..dc5a0b4a4 100644
--- a/numba/tests/npyufunc/test_update_inplace.py
+++ b/numba/tests/npyufunc/test_update_inplace.py
@@ -49,6 +49,11 @@ class TestUpdateInplace(TestCase):
nopython=True, writable_args=(0,))(py_replace_2nd)
self._run_test_for_gufunc(gufunc, py_replace_2nd)
+ # test with writable_args as strings
+ gufunc = guvectorize(['void(f8[:], f8[:])'], '(t),()',
+ nopython=True, writable_args=('x_t',))(py_replace_2nd)
+ self._run_test_for_gufunc(gufunc, py_replace_2nd)
+
def test_update_inplace_with_cache(self):
# test with writable_args
gufunc = guvectorize(['void(f8[:], f8[:])'], '(t),()',
@@ -80,6 +85,13 @@ class TestUpdateInplace(TestCase):
writable_args=(0, 1, 2))(py_update_3)
self._run_test_for_gufunc(gufunc, py_update_3)
+ # test with writable_args as strings
+ gufunc = guvectorize(['void(f8[:], f8[:], f8[:], f8[:])'],
+ '(t),(t),(t),()', nopython=True,
+ writable_args=('x0_t', 'x1_t', 'x2_t'))(py_update_3)
+ self._run_test_for_gufunc(gufunc, py_update_3)
+
+
def test_exceptions(self):
# check that len(writable_args) <= nin
with self.assertRaises(ValueError):makes it possible. What do you think about the above? If it seems acceptable to you, feel free to use it in this PR - if you do, I am missing a test for the exception being raised when an argument is not found, and a doc update, which would also need to be added.
This PR is in the milestone for the next release, so I do hope we can get it into the next release. I don't feel I can move this to "Ready-to-merge" yet because I'm still concerned about the API, but will also mention this PR in today's triage meeting to get the opinions of other maintainers. |
|
The consensus from the dev meeting is that the addition of |
…nt names, or mixture of both.
|
Thanks. I added changes as suggested. Please check again. |
|
@gmarkall, do you think that this PR is ready for merging to the |
|
@gmarkall, I just want to make sure that this PR will be a part of 0.57 release. Is there anything else that needs to be done here before you merge this PR? |
|
@gmarkall, any updates? |
gmarkall
left a comment
There was a problem hiding this comment.
Many thanks for the updates @dmbelov. I think the implementation is looking good. Some minor points to resolve:
- There are some suggestions on the docs. Additionally, the
writable_argskwarg should be documented in the reference manual in this section: https://numba--7009.org.readthedocs.build/en/7009/reference/jit-compilation.html#numba.guvectorize - A test of the exception raised when the user specifies a non-existent arg by name is still required.
Many thanks!
|
@gmarkall,
Please check if PR is good to be merged. |
gmarkall
left a comment
There was a problem hiding this comment.
@dmbelov Many thanks for the updates! I think this looks good.
Before a merge, I'd like this to have a buildfarm run because it contains changes at the C level. @esc / @stuartarchibald could this have a BF run please?
|
Thanks! |
|
BFID: |
passed |
This pull request adds an option
writable_argstoguvectorizethat allows one to specify indices of input arguments that should be read/write. In other words, this PR allows one to write vectorized functions that update arguments in-place with reliability.Here is simplistic example:
Related issue: #6864