-
Notifications
You must be signed in to change notification settings - Fork 7
Benchmarking cupy based connected component labelling and bumping numpy to v2 #220
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
base: main
Are you sure you want to change the base?
Changes from all commits
391be00
ae9d1b8
e45b32c
2519be7
b53e639
a61873b
d91b21f
36c66d8
d170cff
f0dd198
96c538d
4990799
bb2d0ce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,6 +7,16 @@ | |||||||||||||||||||||||||||||||||||||||||||
| # scipy needs to be installed to run this benchmark, we use cc3d as it is quicker for 3D data | ||||||||||||||||||||||||||||||||||||||||||||
| from scipy import ndimage | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| # Try to import cupy for GPU acceleration | ||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||
| import cupy as cp | ||||||||||||||||||||||||||||||||||||||||||||
| from cupyx.scipy import ndimage as cp_ndimage | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| CUPY_AVAILABLE = True | ||||||||||||||||||||||||||||||||||||||||||||
| except ImportError: | ||||||||||||||||||||||||||||||||||||||||||||
| CUPY_AVAILABLE = False | ||||||||||||||||||||||||||||||||||||||||||||
| print("CuPy not available. GPU benchmarks will be skipped.") | ||||||||||||||||||||||||||||||||||||||||||||
aymuos15 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| def generate_random_binary_mask(size: Tuple[int, int, Union[int, None]]) -> np.ndarray: | ||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -64,6 +74,64 @@ def label_cc3d(): | |||||||||||||||||||||||||||||||||||||||||||
| return cc3d_time | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| def benchmark_cupy(mask: np.ndarray): | ||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||
| Benchmark the performance of cupy.ndimage.label for connected component labeling on GPU. | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| Args: | ||||||||||||||||||||||||||||||||||||||||||||
| mask (np.ndarray): Binary mask to label. | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| Returns: | ||||||||||||||||||||||||||||||||||||||||||||
| float: Time taken to label the mask in seconds, or None if CuPy is not available. | ||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||
| if not CUPY_AVAILABLE: | ||||||||||||||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| # Transfer data to GPU | ||||||||||||||||||||||||||||||||||||||||||||
| mask_gpu = cp.asarray(mask) | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+85
to
+91
|
||||||||||||||||||||||||||||||||||||||||||||
| float: Time taken to label the mask in seconds, or None if CuPy is not available. | |
| """ | |
| if not CUPY_AVAILABLE: | |
| return None | |
| # Transfer data to GPU | |
| mask_gpu = cp.asarray(mask) | |
| float: Time taken to label the mask in seconds, or None if CuPy is not available or out of memory. | |
| """ | |
| if not CUPY_AVAILABLE: | |
| return None | |
| # Transfer data to GPU | |
| try: | |
| mask_gpu = cp.asarray(mask) | |
| except cp.cuda.memory.OutOfMemoryError as e: | |
| print("CuPy OutOfMemoryError: Unable to allocate GPU memory for mask. Skipping GPU benchmark.") | |
| return None | |
| except cp.cuda.memory.MemoryError as e: | |
| print("CuPy MemoryError: Unable to allocate GPU memory for mask. Skipping GPU benchmark.") | |
| return None |
Copilot uses AI. Check for mistakes.
Copilot
AI
Aug 30, 2025
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.
Calling free_all_blocks() after every benchmark run is overly aggressive and may impact performance measurements. Consider using cp.get_default_memory_pool().free_all_blocks() only at the end of all benchmarks or using a context manager for better memory management.
| del mask_gpu | |
| cp.get_default_memory_pool().free_all_blocks() |
Copilot uses AI. Check for mistakes.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,6 +63,19 @@ def _connected_components( | |
| from scipy.ndimage import label | ||
|
|
||
| cc_arr, n_instances = label(array) | ||
| elif cca_backend == CCABackend.cupy: | ||
| try: | ||
| import cupy as cp | ||
| from cupyx.scipy.ndimage import label as cp_label | ||
|
Comment on lines
+68
to
+69
|
||
|
|
||
| array_gpu = cp.asarray(array) | ||
| cc_arr, n_instances = cp_label(array_gpu) | ||
| cc_arr = cp.asnumpy(cc_arr) | ||
| except ImportError: | ||
| raise ImportError( | ||
| "CuPy is not installed. Please install CuPy to use the GPU backend. " | ||
| "You can install it using: pip install cupy-cuda11x or cupy-cuda12x depending on your CUDA version." | ||
| ) | ||
| else: | ||
| raise NotImplementedError(cca_backend) | ||
|
|
||
|
|
||
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.
should this include 3.13 @aymuos15 ?