feat: add broadcast_shapes to the specification#983
feat: add broadcast_shapes to the specification#983kgryte wants to merge 5 commits intodata-apis:mainfrom
broadcast_shapes to the specification#983Conversation
|
the array-api-extra docs just say |
ev-br
left a comment
There was a problem hiding this comment.
One small suggestion about the unknown dimensions, LGTM otherwise.
| ----- | ||
|
|
||
| - If not provided one or more arguments, the function **must** return an empty tuple. | ||
| - An array-conforming library **may** accept a non-integer value (e.g., ``None``) for one or more dimensions. This is common for array libraries which build computation graphs (e.g., ndonnx and Dask) and which need to provide a mechanism for indicating dimensions of unknown size. Array-conforming libraries which accept non-integer values for dimensions of unknown size **must** propagate such values (e.g., if a shape contains a dimension size of ``None``, the returned broadcasted shape **must** also have a corresponding dimension having a size equal to ``None``); otherwise, an array-conforming library **must** raise a ``ValueError``. |
There was a problem hiding this comment.
Is this deliberately less strict than https://data-apis.org/array-api/draft/API_specification/generated/array_api.array.shape.html#shape, which seems to imply that None is the only acceptable non-integer value in a shape (at least where that value is supposed to represent an unknown dimension)?
E.g. this appears to be accommodating Dask's math.nan, suggesting that it should propagate that math.nan? That would differ from the existing behaviour in https://data-apis.org/array-api-extra/generated/array_api_extra.broadcast_shapes.html which replaces that non-standard math.nan with a None.
| - An array-conforming library **may** accept a non-integer value (e.g., ``None``) for one or more dimensions. This is common for array libraries which build computation graphs (e.g., ndonnx and Dask) and which need to provide a mechanism for indicating dimensions of unknown size. Array-conforming libraries which accept non-integer values for dimensions of unknown size **must** propagate such values (e.g., if a shape contains a dimension size of ``None``, the returned broadcasted shape **must** also have a corresponding dimension having a size equal to ``None``); otherwise, an array-conforming library **must** raise a ``ValueError``. | |
| - An array-conforming library **may** accept a ``None`` value for one or more shape dimensions. This is common for array libraries which build computation graphs (e.g., ndonnx and Dask) and which need to provide a mechanism for indicating dimensions of unknown size. Array-conforming libraries which accept ``None`` values for dimensions of unknown size **must** propagate those values (i.e., if a shape contains a dimension size of ``None``, the returned broadcasted shape **must** also have a corresponding dimension having a size equal to ``None``); otherwise, an array-conforming library **must** raise a ``ValueError``. |
There was a problem hiding this comment.
@lucascolley I think it depends on how you define "non-standard". Is there a reason to prohibit the use of non-none sentinel values?
There was a problem hiding this comment.
Or stated differently, in what scenario do consumers need to rely on a standardized sentinel value (e.g., checking for None vs checking whether a value simply isn't an integer)?
There was a problem hiding this comment.
Is there a reason to prohibit the use of non-none sentinel values?
Not that I can think of! But for consistency, if you want to go ahead with this PR as is, I think the
There was a problem hiding this comment.
Thanks for pointing that out. Will raise during the workgroup meeting today.
|
An issue should be opened regarding deprecation of https://data-apis.org/array-api-extra/generated/array_api_extra.broadcast_shapes.html. |
| """ | ||
|
|
||
|
|
||
| def broadcast_shapes(*shapes: Tuple[int, ...]) -> Tuple[int, ...]: |
There was a problem hiding this comment.
| def broadcast_shapes(*shapes: Tuple[int, ...]) -> Tuple[int, ...]: | |
| def broadcast_shapes(*shapes: Tuple[int | None, ...]) -> Tuple[int | None, ...]: |
|
|
||
| Parameters | ||
| ---------- | ||
| shapes: Tuple[int, ...] |
There was a problem hiding this comment.
| shapes: Tuple[int, ...] | |
| shapes: Tuple[int | None, ...] |
|
|
||
| Returns | ||
| ------- | ||
| out: Tuple[int, ...] |
There was a problem hiding this comment.
| out: Tuple[int, ...] | |
| out: Tuple[int | None, ...] |

This PR
broadcast_shapesto the specification #893 by adding support forbroadcast_shapesto the specification.Nonefor a dimension of unknown size, behavior is left unspecified and thus implementation-defined.