Generate gufunc input shapes with a gufunc= arg to mutually_broadcastable_shapes
#2174
Labels
new-feature
entirely novel capabilities or strategies
This is the tracking issue for a long-awaited feature: generating a collection of array shapes for a Numpy 'generalised ufunc'. It's fairly niche, but very useful to anyone in that niche.
As background, a strategy for
gufunc_shapeswas first proposed in #1760/#1784 and later released as thehypothesis-gufuncextension. Around the same time, #1829 proposed ourboradcastable_shapesstrategy (for single shapes), and we later decided (#1969) to releasemutually_broadcastable_shapeswithout gufunc support in the first instance. That was added by #2153/#2173, so we're finally ready for gufunc support!The implementation isn't too bad, but there are a bunch of little details we'll need to handle carefully.
gufuncargument is keyword-only, defaults tonot_set, and exactly one of it ornum_shapesmust be passed.gufunccallable is passed, use its.signatureattribute. IMO we should reject None signatures, since the ufunc is not generalised and it simply gives usnum_shapes.gufuncsignature stringusingsomething which is actually NEP-20 compliant, i.e. our own regex-based parser.numpy.lib.function_base._parse_gufunc_signaturemandnin'(m,n),(n)->(m)'for matrix-vector multiplication), then draw an allowed size for each, and construct our initial tuples for each shape - the "core dimensions".and broadcastable dimensions(NEP rejected). Fiddly but no worse than our existing logic for other dimensions.min_dimsandmax_dimsare interpreted (and documented!) as applying to the "loop dimensions" only. In the example above,max_dims=1would mean that we could generate a three-dimensional output(loop,m,n)and the result shape would be(loop,m).min_dimsdimensions. We should also adjust the biased_coin probability in these cases to avoid squashing our uniform distribution against the upper bound.If for example the cap were two dimensions, it would be impossible to use any loop dimensions or have a 2D result from matrix-vector multiplication without supporting this (or ugly per-dimension size limits). It's very unlikely to arise in practice, but if Hypothesis doesn't handle edge cases who will?
I believe that optional dimensions (eg in matmul
(m?,n),(n,p?)->(m?,p?)) do count towards the limit of 32 dimensions even if unused, but we should check this and generate them if not.We'll also want to make sure it's well-tested and thoroughly documented before merging, but I think that's everything we need in for a viable implementation 😄
The text was updated successfully, but these errors were encountered: