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
gufunc behavior on incorrect out shape #16484
Comments
Hehe, was thinking about this for a while….Also ping @mhvk just in case. The So I am considering adding a new It feels like a combination of allocate and no-broadcast, probably already somewhat implies this. But the question is if we want to make such a change, in theory it can affect external libraries using NpyIter. (Unless we make it a VisibleDeprecationWarning when it kicks in, but not sure that is super neat to implement.) I think that could address the issue. There are interesting side cases, such as an axes which is only used by one (or more) output arrays. One could try to support that (at some point?), but it probably adds too much complexity for no real gain. |
Bit confused about all the flags, I must admit. But a gufunc |
A bit more directly relevant to the issue here, where the output has an inconsistent outer shape, is that there is precedent from the regular ufuncs:
This suggests also for gufuncs, the outer shape should be determined from all inputs and outputs. Obviously, will cause needless calculations, but so be it... |
Oh, I somehow did not expect that to actually work. I suppose in that case we can simply allow the output to cause broadcasting in the inputs (and thus adjust the shape). Basically simply retaining the current behaviour. so, just do nothing here, except for making the sure the (g)ufunc gets called multiple times (it will a bit of a slow way to get the result in many cases, but that is the callers problem). While I do not think it is important to support this, I also see no problems with doing it. But we still need to fix this issue in gufuncs obviously! |
Ah, its very simple: diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c
index 19876d641..85820e3a0 100644
--- a/numpy/core/src/umath/ufunc_object.c
+++ b/numpy/core/src/umath/ufunc_object.c
@@ -2614,7 +2614,7 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
* dimensions.
*/
broadcast_ndim = 0;
- for (i = 0; i < nin; ++i) {
+ for (i = 0; i < nop; ++i) {
int n = PyArray_NDIM(op[i]) - op_core_num_dims[i];
if (n > broadcast_ndim) {
broadcast_ndim = n; is probably all there is to it. Then we get correct broadcasting of inputs to outputs, and any thoughts of deprecating this can just be deferred for future selves if it ever comes up. EDIT: Plus the null check of op... |
In this case no error was given, but additional dimensions in the output simply ignored. Thus the returned array was only partially set. Now it will be fully set, with the calculation being repeated as often as necessary (typical broadcasting logic). This is consistent with how normal ufuncs work. Closes numpygh-16484
From the discussion here : #15162 (comment)
The following example doesnt seem to raise an error when out shape is incorrect or broadcast the inputs to the output, but silently populates the out with result + garbage values.
Result:
The text was updated successfully, but these errors were encountered: