Context
NumPy is planning to add support for the array API standard in NumPy 2.0 (NEP pending), and other array libraries are expected to follow if this work goes through.
This means that NumPy's API will become a superset of the array API standard specification, which will allow users to write 'array-agnostic' code to the standard specification and have it work with NumPy.
The converse, however, is not true, since NumPy's API will be a proper superset; a user cannot write code to the NumPy API and have it work with any standard-compliant array library. This is for two reasons:
-
For some functionality, NumPy provides multiple ways to achieve it, while the standard only requires one (or a proper subset) of those ways.
-
NumPy provides some functionality which is not present in the standard.
'Array consumer' libraries are interested in array-agnostic code as it has the potential to open up their code to new devices and greater interoperability. A ruff rule could help automate part of the conversion process described in my blog post, The Array API Standard in SciPy.
Proposal
Add a new (indefinitely preview? certainly opt-in) rule category, XP, to fix/flag code which is not array-agnostic. The first of these rules, XP001, would do so for code using NumPy. The rule would assume that code has already been migrated to NumPy 2.0, and would fill in the gaps as noted above:
- For cases of (1), fix the code where there is a drop in alternative (e.g.
np.shape(a) -> a.shape).
- For cases of (2), flag that the user either needs to find an alternative way of achieving the same functionality, or write their own array-agnostic version (e.g. in SciPy we wrote an array-agnostic version of
np.cov).
Use Case
Context: a hypothetical future where PyTorch is compliant with the array API standard (as they plan to be).
Problem: The user has code which uses NumPy 1.x. They want their code to work with PyTorch tensors for speedy GPU reasons, or for interoperability with a package built around PyTorch tensors.
Solution:
- Migrate to NumPy 2.0 using @mtsokol 's
NPY201.
- Convert to array-agnostic code using the proposed
XP001.
(2.5: write np as xp and do a whole bunch of work on their test suite etc.)
- Swap
import numpy as xp for import torch as xp (side note: or get the namespace directly from inputs).
Voilà!
Additional Information
- The idiomatic way to write array-agnostic code is with the array library spelled
xp. A find-and-replace of np with xp is strongly recommended, but I don't know whether this would fit into ruff's part of the story.
Please let me know any thoughts on whether this is something which could belong in ruff, or how to go about implementing it. I'm new to Rust, but would be happy to get started on a PR when I find the time! Cheers 👋
Context
NumPy is planning to add support for the array API standard in NumPy 2.0 (NEP pending), and other array libraries are expected to follow if this work goes through.
This means that NumPy's API will become a superset of the array API standard specification, which will allow users to write 'array-agnostic' code to the standard specification and have it work with NumPy.
The converse, however, is not true, since NumPy's API will be a proper superset; a user cannot write code to the NumPy API and have it work with any standard-compliant array library. This is for two reasons:
For some functionality, NumPy provides multiple ways to achieve it, while the standard only requires one (or a proper subset) of those ways.
NumPy provides some functionality which is not present in the standard.
'Array consumer' libraries are interested in array-agnostic code as it has the potential to open up their code to new devices and greater interoperability. A ruff rule could help automate part of the conversion process described in my blog post, The Array API Standard in SciPy.
Proposal
Add a new (indefinitely preview? certainly opt-in) rule category,
XP, to fix/flag code which is not array-agnostic. The first of these rules,XP001, would do so for code using NumPy. The rule would assume that code has already been migrated to NumPy 2.0, and would fill in the gaps as noted above:np.shape(a)->a.shape).np.cov).Use Case
Context: a hypothetical future where PyTorch is compliant with the array API standard (as they plan to be).
Problem: The user has code which uses NumPy 1.x. They want their code to work with PyTorch tensors for speedy GPU reasons, or for interoperability with a package built around PyTorch tensors.
Solution:
NPY201.XP001.(2.5: write
npasxpand do a whole bunch of work on their test suite etc.)import numpy as xpforimport torch as xp(side note: or get the namespace directly from inputs).Voilà!
Additional Information
xp. A find-and-replace ofnpwithxpis strongly recommended, but I don't know whether this would fit into ruff's part of the story.Please let me know any thoughts on whether this is something which could belong in ruff, or how to go about implementing it. I'm new to Rust, but would be happy to get started on a PR when I find the time! Cheers 👋