Skip to content

ENH: pad: normalize pad_width on the host for torch#832

Merged
lucascolley merged 4 commits into
data-apis:mainfrom
rgommers:pad-width-host-normalization
Jul 5, 2026
Merged

ENH: pad: normalize pad_width on the host for torch#832
lucascolley merged 4 commits into
data-apis:mainfrom
rgommers:pad-width-host-normalization

Conversation

@rgommers

@rgommers rgommers commented Jul 5, 2026

Copy link
Copy Markdown
Member

pad_width is host metadata (an int or (before, after) pairs), but the torch delegation branch normalized it by round-tripping through a tensor: xp.asarray(pad_width) places it on the default device, and the tuple(...) call to build the python ints that torch.nn.functional.pad expects then performs one device-to-host transfer per element. With a CUDA default device that is a needless host-to-device copy plus 2*ndim synchronizing .item() reads per call; with a data-free meta default device it raises outright.

Factor the pure-python normalization out of _funcs.pad into normalize_pad_width and reuse it in the torch branch, reversing the axis order on the host.

This also aligns the torch branch with the documented pad_width types (the tensor broadcast incidentally accepted undocumented forms such as shape (n, 1)).

Found this when working on non-default device handling issues in scipy; SciPy tests will cover this so I won't worry about introducing multi-device testing here right now.

AI Generation Disclosure: patch generated with Claude Fable 5 (had to tweak both code comments and commit message a bit, but the hard work was done by Claude here).

`pad_width` is host metadata (an int or (before, after) pairs), but the
torch delegation branch normalized it by round-tripping through a tensor:
`xp.asarray(pad_width)` places it on the *default* device, and the
`tuple(...)` call to build the python ints that `torch.nn.functional.pad`
expects then performs one device-to-host transfer per element. With a CUDA
default device that is a needless host-to-device copy plus 2*ndim
synchronizing `.item()` reads per call; with a data-free `meta` default
device it raises outright.

Factor the pure-python normalization out of `_funcs.pad` into
`normalize_pad_width` and reuse it in the torch branch, reversing the axis
order on the host.

This also aligns the torch branch with the documented `pad_width` types (the
tensor broadcast incidentally accepted undocumented forms such as shape ``(n,
1)``).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@rgommers rgommers marked this pull request as ready for review July 5, 2026 17:13
Comment thread src/array_api_extra/_lib/_funcs.py Outdated
)


def normalize_pad_width(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arguably this belongs in _helpers instead

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll move it if you prefer that - but are you sure? It's specific to just pad and not useful as a standalone generic helper, so keeping it right above def pad: would be my choice.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that it is used in 2 separate modules, I would rather move it to _helpers, yes. Let's add it to __all__ over there, too.

Comment thread src/array_api_extra/_delegation.py Outdated
@lucascolley

Copy link
Copy Markdown
Member

SciPy tests will cover this so I won't worry about introducing multi-device testing here right now.

Would be good to at least open an issue for this

@rgommers

rgommers commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

It's already covered by the generic issue for non-default devices; it's one of very many (see gh-25567) so not worth a separate issue.

Co-authored-by: Lucas Colley <lucas.colley8@gmail.com>
@lucascolley

Copy link
Copy Markdown
Member

It's already covered by the generic issue for non-default devices; it's one of very many (see gh-25567) so not worth a separate issue.

Sorry, I meant an issue on this repo

@rgommers

rgommers commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

Ah, that seems reasonable - a generic "introduce multi-device or non-default device testing for array-api-extra" issue. I think after we have it for SciPy, it might be clearer if/how it can be done in this repo.

@lucascolley lucascolley added the enhancement New feature or request label Jul 5, 2026
@lucascolley lucascolley added this to the 0.11.1 milestone Jul 5, 2026
@rgommers

rgommers commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

Hmm, looks like torch isn't tested in CI, since only the linter failed.

@lucascolley

Copy link
Copy Markdown
Member

Hmm, looks like torch isn't tested in CI, since only the linter failed.

it is tested otherwise coverage would fail... I think the previous commit still worked due to the helper being imported into _funcs. That is what the error code suggests at least: reportPrivateLocalImportUsage

@lucascolley lucascolley merged commit eb8ff5d into data-apis:main Jul 5, 2026
13 checks passed
@lucascolley

Copy link
Copy Markdown
Member

thanks Ralf!

@rgommers rgommers deleted the pad-width-host-normalization branch July 6, 2026 04:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants