-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
add Array API support to denoise_tv_chambolle #6132
base: main
Are you sure you want to change the base?
Conversation
np.diff has no equivalent in the array API so use explicit difference via slicing instead Have to use function forms (e.g. xp.sum) instead of calling a method on the array Have to use expand_dims instead of np.newaxis Had to use ugly if/else case to get image.astype(...) equivalent working across both np and np.array_api Currently only supports floating point images for the Array API case as img_as_float hasn't been converted to support Array API inputs.
Hello @grlee77! Thanks for opening this PR. We checked the lines you've touched for PEP 8 issues, and found:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seeing array_api
used is very informative. Thank you!
g[tuple(slices_g)] = np.diff(out, axis=ax) | ||
|
||
# first order difference along the axis (np.diff not in array API) | ||
_at = functools.partial(utils.slice_at_axis, axis=ax) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At a glance, this is similar to what np.diff does so there should not be a performance issue.
To actually make these workarounds maintainable, I see introducing a utils.array_api
module which has utils.array_api.diff
, utils.array_api.astype
and all other workarounds.
slices_g[ax+1] = slice(None) | ||
|
||
norm = np.sqrt((g ** 2).sum(axis=0))[np.newaxis, ...] | ||
E += weight * norm.sum() | ||
norm = xp.expand_dims(xp.sqrt(xp.sum(g * g, axis=0)), axis=0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is reasonable alternative. Although, there are 3 nested xp
calls, so I think it is a little less readable.
Hey, there hasn't been any activity on this for more than 180 days, so we have marked it as "dormant" for now until there is some new activity. You are welcome to reach out to people by mentioning them here or on our forum if you need more feedback! Otherwise, we would be thankful for a short update, for example if you would like to continue or if you are okay with someone else doing so. In any case, thank you for your contributions so far! |
Description
Here is a demo of converting an existing non-trivial function
denoise_tv_chambolle
to support any array object implementing the Array API as implemented for the upcoming NumPy 1.22.Demo code
The following is demo code that can be run with NumPy 1.22 (currently available via
pip install -U --pre numpy
):Some specific points of this conversion:
np.diff
has no equivalent in the array API so had to use explicit difference via slicing insteadHad to use functions (e.g.
xp.sum(image)
) instead of calling methods on the array object (e.g.image.sum()
)Had to use
expand_dims
instead ofnp.newaxis
Had to use an ugly if/else case to get an
image.astype
equivalent working across bothnp
andnp.array_api
arrays. This is because array_api defines a functionnumpy.array_api.astype
while innumpy
it is anastype
method on the array.Currently only supports floating point images for the Array API case as
img_as_float
hasn't been converted to support Array API inputs. That could be resolved, though.Other Limitations
This function is nearly the only one under
skimage.restoration
that is compatible with acceleration via the Array API. The various deconvolution functions require FFTs and complex dtypes which are not currently in the Array API. The other denoising functions, inpainting and phase unwrapping functions all rely on compiled Cython code and so can't be converted in this manner.Probably the higher level
calibrate_denoiser
is the only other functions underskimage.restoration
that we could currently convert to use the Array API and even then it would be restricted to use adenoise_function
that has Array API support (onlydenoise_tv_chambolle
among the ones we provide)Outside of
skimage.restoration
there are some other functions that could be implemented purely using the Array API, but I think this are in the minority (probably below 10% of all functions in the library).Checklist
./doc/examples
(new features only)./benchmarks
, if your changes aren't covered by anexisting benchmark
For reviewers
later.
__init__.py
.doc/release/release_dev.rst
.