|
85 | 85 | cp, has_cp = optional_import("cupy") |
86 | 86 | cp_ndarray, _ = optional_import("cupy", name="ndarray") |
87 | 87 | exposure, has_skimage = optional_import("skimage.exposure") |
88 | | -_cucim_skimage, _has_cucim_skimage = optional_import("cucim.skimage") |
89 | | -_cucim_morphology_edt, _has_cucim_morphology = optional_import( |
90 | | - "cucim.core.operations.morphology", name="distance_transform_edt" |
91 | | -) |
| 88 | +# NOTE: cucim is deliberately NOT imported at module level. |
| 89 | +# Module-level cucim imports caused very slow import times and other buggy behaviour. |
| 90 | +# Keep cucim imports inside the functions that need them. |
92 | 91 |
|
93 | 92 | __all__ = [ |
94 | 93 | "allow_missing_keys_mode", |
@@ -1151,10 +1150,11 @@ def get_largest_connected_component_mask( |
1151 | 1150 | """ |
1152 | 1151 | # use skimage/cucim.skimage and np/cp depending on whether packages are |
1153 | 1152 | # available and input is non-cpu torch.tensor |
1154 | | - use_cp = has_cp and _has_cucim_skimage and isinstance(img, torch.Tensor) and img.device != torch.device("cpu") |
| 1153 | + skimage, has_cucim = optional_import("cucim.skimage") |
| 1154 | + use_cp = has_cp and has_cucim and isinstance(img, torch.Tensor) and img.device != torch.device("cpu") |
1155 | 1155 | if use_cp: |
1156 | 1156 | img_ = convert_to_cupy(img.short()) # type: ignore |
1157 | | - label = _cucim_skimage.measure.label |
| 1157 | + label = skimage.measure.label |
1158 | 1158 | lib = cp |
1159 | 1159 | else: |
1160 | 1160 | if not has_measure: |
@@ -1207,13 +1207,13 @@ def keep_merge_components_with_points( |
1207 | 1207 | margins: include points outside of the region but within the margin. |
1208 | 1208 | """ |
1209 | 1209 |
|
1210 | | - use_cp = ( |
1211 | | - has_cp and _has_cucim_skimage and isinstance(img_pos, torch.Tensor) and img_pos.device != torch.device("cpu") |
1212 | | - ) |
| 1210 | + cucim_skimage, has_cucim = optional_import("cucim.skimage") |
| 1211 | + |
| 1212 | + use_cp = has_cp and has_cucim and isinstance(img_pos, torch.Tensor) and img_pos.device != torch.device("cpu") |
1213 | 1213 | if use_cp: |
1214 | 1214 | img_pos_ = convert_to_cupy(img_pos.short()) # type: ignore |
1215 | 1215 | img_neg_ = convert_to_cupy(img_neg.short()) # type: ignore |
1216 | | - label = _cucim_skimage.measure.label |
| 1216 | + label = cucim_skimage.measure.label |
1217 | 1217 | lib = cp |
1218 | 1218 | else: |
1219 | 1219 | if not has_measure: |
@@ -2466,7 +2466,10 @@ def distance_transform_edt( |
2466 | 2466 | Returned only when `return_indices` is True and `indices` is not supplied. dtype np.float64. |
2467 | 2467 |
|
2468 | 2468 | """ |
2469 | | - use_cp = has_cp and _has_cucim_morphology and isinstance(img, torch.Tensor) and img.device.type == "cuda" |
| 2469 | + distance_transform_edt, has_cucim = optional_import( |
| 2470 | + "cucim.core.operations.morphology", name="distance_transform_edt" |
| 2471 | + ) |
| 2472 | + use_cp = has_cp and has_cucim and isinstance(img, torch.Tensor) and img.device.type == "cuda" |
2470 | 2473 | if not return_distances and not return_indices: |
2471 | 2474 | raise RuntimeError("Neither return_distances nor return_indices True") |
2472 | 2475 |
|
@@ -2499,7 +2502,7 @@ def distance_transform_edt( |
2499 | 2502 | indices_ = convert_to_cupy(indices) |
2500 | 2503 | img_ = convert_to_cupy(img) |
2501 | 2504 | for channel_idx in range(img_.shape[0]): |
2502 | | - _cucim_morphology_edt( |
| 2505 | + distance_transform_edt( |
2503 | 2506 | img_[channel_idx], |
2504 | 2507 | sampling=sampling, |
2505 | 2508 | return_distances=return_distances, |
|
0 commit comments