numpy/numpy — pull request #4458 by jaimefrio (2014-03-07 10:05:13+00:00)
Title: BUG: Minimize iterator size in gufunc allocation of output arrays

Closes #4442 (or at least mitigates it)

Prior to this PR, the iterator created by a gufunc had all core dimensions
of all output arguments appended to the broadcasted non-core dimensions.
When working with gufuncs with multiple return arguments, this could lead
to "iterator is too large" errors with moderately sized inputs.

This PR changes that mechanism, and now each distinct core-dimension is
appended only the maximum number of times that it comes up in an output
argument's signature.

As an example, take #4442, which was failing in a call to SVD with
signature `(m,n)->(m,n),(n),(n,n)`. The iterator was created with shape
`(m ,n, n, n, n)` (all output arguments' core dimensions), and then the
`op_axes` for each of the three output parameters were set to
`[0, 1, -1, -1, -1]`, `[-1, -1, 0, -1, -1]` and `[-1, -1, -1, 0, 1]`. After
this PR, in this same case the iterator has shape `(m, n, n)`, and the
`op_axes` now are `[0, 1, -1]`, `[-1, 0, -1]` and `[-1, 0, 1]`.

The only concern is that a function with e.g. signature `(a,b)->(b,a)` would
have had its output created with an iterator of shape `(b, a)` and `op_axes`
set to `[0, 1]`. Now it will be created with shape `(a, b)` and `op_axes` set
to `[1, 0]`. Not sure if it will result in a different memory layout of the
allocated array.