-
Notifications
You must be signed in to change notification settings - Fork 50
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
[RFC]: add broadcast_shapes
to the specification
#893
Comments
@crusaderky Would you mind sharing your use case for needing |
@kgryte I'm writing a backend-agnostic wrapper around |
broadcast_shapes
; broadcasting guarantees about viewsbroadcast_shapes
to the specification
It would be useful to add to the issue description which array libraries do or don't support |
That's a performance/implementation question - as a rule we never specify that, only syntax and semantics. It might not be true for all implementations (e.g., JAX in eager mode).
One shouldn't rely on such an assumption.
This syntax in itself is a good indication that
That sounds like a good idea to me. Based on usage frequency and library support it can be "promoted" to a standardized function afterwards. |
@rgommers I've updated the OP with a comparison across libraries. |
This RFC proposes adding an API to the specification for explicitly broadcasting a list of shapes to a single shape.
Overview
Based on array API comparison data, this API, or some variation of it, is commonly implemented across array libraries.
Currently, the Array API specification only includes
broadcast_arrays
andbroadcast_to
which both require array input. The specification lacks APIs for working directly with shapes without needing to create new array instances.Prior Art
does not currently supportbroadcast_shapes
from NumPy: https://github.com/cupy/cupy/blob/a888cc94c79729cf24ebb808d15b9702c0342392/cupy/__init__.py#L302da.core.broadcast_arrays
exists as private API only. Supports Dask's bespokenan
's in the shape.Size
broadcast_static_shape
: https://www.tensorflow.org/api_docs/python/tf/broadcast_static_shapebroadcast_dynamic_shape
: https://www.tensorflow.org/api_docs/python/tf/broadcast_dynamic_shapeNone
, so one cannot use numpy's implementation.Proposal
This RFC proposes adding the following API to the specification:
in which one or more shapes are broadcasted together according to broadcasting rules as enumerated in the specification.
Questions
How to handle shapes having unknown dimensions?
dask.array.core.broadcast_shapes
sets the output size to nan if any of the input shapes are nan on the same axisndonnx.broadcast_arrays(a, b)
returns arrays with material shapes.Note that shape materialization can be a very expensive operation, as it requires materializing the whole graph until that point. In the case of Dask, which doesn't cache intermediate results as a deliberate memory management policy, this means computing everything at least twice.
Notes
The top-level page on broadcasting mentions on the first line, using non-prescriptive language, that broadcasting allows creating views of the inputs:
However, no mention of sharing memory is made in broadcast_to or broadcast_arrays.
For the sake of comparison, see the verbiage in asarray(copy=False).
The problem with this ambiguity is that one can work around the lack of
broadcast_shapes
by callingxp.broadcast_arrays(*args)[0].shape
, but there is no strong guarantee that the backend won't deep-copy the inputs.Note that
numpy.broadcast_shapes
doesn't work with shapes containing None (ndonnx and hopefully in the future JAX too) or NaN (Dask; non-standard).I suggest to either
broadcast_to
andbroadcast_arrays
that the output must share memory with the input, or in other words the operation must be O(1), orbroadcast_shapes
to the standard, and change the verbiage of the broadcasting high level page to "typically without copying array data"For the time being I am adding the function to
array_api_extra
:broadcast_shapes
array-api-extra#80broadcast_shapes
array-api-extra#133The text was updated successfully, but these errors were encountered: