Thanks for the writeup Marten,
Nathaniel:
Output shape feels very similar to
output dtype to me, so maybe the general way to handle this would be
to make the first callback take the input shapes+dtypes and return the
desired output shapes+dtypes?
This hits on an interesting alternative to frozen dimensions - np.cross
could just become a regular ufunc with signature np.dtype((float64, 3)),
np.dtype((float64, 3)) → np.dtype((float64, 3))
Furthermore, the expansion quickly becomes cumbersome. For instance, for
the all_equal signature of (n|1),(n|1)->() …
I think this is only a good argument when used in conjunction with the
broadcasting syntax. I don’t think it’s a reason for matmul not to have
multiple signatures. Having multiple signatures is an disincentive to
introduced too many overloads of the same function, which seems like a good
thing to me
Summarizing my overall opinions:
- I’m +0.5 on frozen dimensions. The use-cases seem reasonable, and it
seems like an easy-ish way to get them. Allowing ufuncs to natively support
subarray types might be a tidier solution, but that could come down the road
- I’m -1 on optional dimensions: they seem to legitimize creating many
overloads of gufuncs. I’m already not a fan of how matmul has special cases
for lower dimensions that don’t generalize well. To me, the best way to
handle matmul would be to use the proposed __array_function__ to handle
the shape-based special-case dispatching, either by:
- Inserting dimensions, and calling the true gufunc
np.linalg.matmul_2d (which is a function I’d like direct access to
anyway).
- Dispatching to one of four ufuncs
- Broadcasting dimensions:
- I know you’re not suggesting this but: enabling broadcasting
unconditionally for all gufuncs would be a bad idea, masking linalg bugs.
(although einsum does support broadcasting…)
- Does it really need a per-dimension flag, rather than a global one?
Can you give a case where that’s useful?
- If we’d already made all_equal a gufunc, I’d be +1 on adding
broadcasting support to it
- I’m -0.5 on the all_equal path in the first place. I think we
either should have a more generic approach to combined ufuncs, or just
declare them numbas job.
- Can you come up with a broadcasting use-case that isn’t just
chaining a reduction with a broadcasting ufunc?
Eric
On Sun, 10 Jun 2018 at 16:02 Eric Wieser <[email protected]>
wrote:
Rendered here:
> https://github.com/mhvk/numpy/blob/nep-gufunc-signature-enhancement/doc/neps/nep-0020-gufunc-signature-enhancement.rst
>
>
> Eric
>
> On Sun, 10 Jun 2018 at 09:37 Marten van Kerkwijk <
> [email protected]> wrote:
>
>> OK, I spent my Sunday morning writing a NEP. I hope this can lead to some
>> closure...
>> See https://github.com/numpy/numpy/pull/11297
>> -- Marten
>> _______________________________________________
>> NumPy-Discussion mailing list
>> [email protected]
>> https://mail.python.org/mailman/listinfo/numpy-discussion
>>
>
_______________________________________________
NumPy-Discussion mailing list
[email protected]
https://mail.python.org/mailman/listinfo/numpy-discussion