-
-
Notifications
You must be signed in to change notification settings - Fork 789
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 all binary morphology functions to cupyx.scipy.ndimage #3907
Conversation
add binary_propagation, binary_hit_or_miss
I put some benchmarks for a (4096, 4096) binary image below. I only benchmarked binary erosion as all of the other functions also use it under the hood. Benchmark Scriptimport numpy as np
import cupy as cp
from cupyx.time import repeat
from scipy import ndimage as ndi
from cupyx.scipy import ndimage as cndi
shape = (4096, 4096)
x = np.random.randn(*shape) > 0.6
s = ndi.generate_binary_structure(x.ndim, 1)
# run 1 iteration on the CPU
perf = repeat(ndi.binary_erosion, (x, s), n_warmup=1, n_repeat=10)
print(perf)
# run 1 iteration on the GPU
xg = cp.asarray(x)
sg = cndi.generate_binary_structure(x.ndim, 1)
perf_gpu = repeat(cndi.binary_erosion, (xg, sg), n_warmup=20, n_repeat=100)
print(perf_gpu)
# compare with 5 iterations on the CPU
kwargs = dict(iterations=5, brute_force=True)
perf_cpu_5iter_bf = repeat(ndi.binary_erosion, (x, s), kwargs, n_warmup=1, n_repeat=10)
print(perf_cpu_5iter_bf)
kwargs = dict(iterations=5, brute_force=False)
perf_cpu_5iter = repeat(ndi.binary_erosion, (x, s), kwargs, n_warmup=1, n_repeat=10)
print(perf_cpu_5iter)
# compare with 5 iterations on the GPU (only brute_force=True is implemented)
xg = cp.asarray(x)
sg = cndi.generate_binary_structure(x.ndim, 1)
kwargs = dict(iterations=5, brute_force=True)
perf_gpu_5iter = repeat(cndi.binary_erosion, (xg, sg), kwargs, n_warmup=20, n_repeat=100)
print(perf_gpu_5iter) Benchmark Resultssingle iteration CPU
single iteration GPU
CPU, 5 iterations, brute_force=True
CPU, 5 iterations, brute_force=False
GPU, 5 iterations, brute_force=True
|
I think the call to For cases with |
single to double backticks remove unneeded on_cpu argument use astype rather than asarray to disallow array-like structure input
6c6c0bc
to
5ffead0
Compare
Jenkins, test this please. |
Jenkins CI test (for commit 45ab6e3, target branch master) failed with status FAILURE. |
It seems very odd that only a single parameterized case out of 1728 failed for |
Sure, let's restart CI and see if it clears 🙂 Jenkins, test this please. |
Jenkins CI test (for commit 45ab6e3, target branch master) succeeded! |
Would you be able to take another look @asi1024? 🙂 |
Jenkins, test this please. |
Jenkins CI test (for commit 45ab6e3, target branch master) succeeded! |
LGTM! |
Thank you both! 😄 |
This PR adds
binary_erosion
,binary_dilation
,binary_opening
,binary_closing
,binary_hit_or_miss
,binary_propagation
,binary_fill_holes
,generate_binary_structure
anditerate_structure
.The only new kernel is the one corresponding to binary erosion. I was able to mostly reuse the existing utility
_filters_core._generate_nd_kernel
, but did have to add a couple of arguments to get it to work for this case. @coderforlife, please take a look if you have a chance.All other binary morphological operations are built on top of
binary_erosion
. Some of the specific data arrays used in the tests were borrowed from SciPy's test suite.The only feature in SciPy that is not implemented here is the case where
iterations > 1
andbrute_force=False
. SciPy uses a different algorithm in that case, but I have only implemented the brute force kernel here.