Skip to content

Commit

Permalink
6020 avoid creating cufile.log when import monai (#6106)
Browse files Browse the repository at this point in the history
Fixes #6020

### Description

```
pip install cucim
python -c "import cucim"
```
may create a `cufile.log` file in the current working directory (please
see rapidsai/cucim#514)

this PR delays the cucim imports to when the modules are really needed. 

### Types of changes
<!--- Put an `x` in all the boxes that apply, and remove the not
applicable items -->
- [x] Non-breaking change (fix or new feature that would not break
existing functionality).
- [ ] Breaking change (fix or new feature that would cause existing
functionality to change).
- [ ] New tests added to cover the changes.
- [ ] Integration tests passed locally by running `./runtests.sh -f -u
--net --coverage`.
- [x] Quick tests passed locally by running `./runtests.sh --quick
--unittests --disttests`.
- [x] In-line docstrings updated.
- [ ] Documentation updated, tested `make html` command in the `docs/`
folder.

---------

Signed-off-by: Wenqi Li <wenqil@nvidia.com>
  • Loading branch information
wyli authored Mar 7, 2023
1 parent fa884a2 commit b85e2c6
Show file tree
Hide file tree
Showing 5 changed files with 6 additions and 8 deletions.
3 changes: 1 addition & 2 deletions monai/auto3dseg/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@

measure_np, has_measure = optional_import("skimage.measure", "0.14.2", min_version)
cp, has_cp = optional_import("cupy")
cucim, has_cucim = optional_import("cucim")


def get_foreground_image(image: MetaTensor) -> np.ndarray:
Expand Down Expand Up @@ -93,7 +92,7 @@ def get_label_ccp(mask_index: MetaTensor, use_gpu: bool = True) -> tuple[list[An
regardless of this setting.
"""

cucim, has_cucim = optional_import("cucim")
shape_list = []
if mask_index.device.type == "cuda" and has_cp and has_cucim and use_gpu:
mask_cupy = ToCupy()(mask_index.short())
Expand Down
3 changes: 1 addition & 2 deletions monai/data/image_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
nrrd, has_nrrd = optional_import("nrrd", allow_namespace_pkg=True)

OpenSlide, _ = optional_import("openslide", name="OpenSlide")
CuImage, _ = optional_import("cucim", name="CuImage")
TiffFile, _ = optional_import("tifffile", name="TiffFile")

__all__ = [
Expand Down Expand Up @@ -1274,7 +1273,7 @@ def _set_reader(backend: str):
if backend == "openslide":
return OpenSlide
if backend == "cucim":
return CuImage
return optional_import("cucim", name="CuImage")[0]
if backend == "tifffile":
return TiffFile
raise ValueError("`backend` should be 'cuCIM', 'OpenSlide' or 'TiffFile'.")
Expand Down
4 changes: 2 additions & 2 deletions monai/data/wsi_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from monai.data.utils import is_supported_format
from monai.utils import WSIPatchKeys, ensure_tuple, optional_import, require_pkg

CuImage, _ = optional_import("cucim", name="CuImage")
OpenSlide, _ = optional_import("openslide", name="OpenSlide")
TiffFile, _ = optional_import("tifffile", name="TiffFile")

Expand Down Expand Up @@ -491,13 +490,14 @@ def read(self, data: Sequence[PathLike] | PathLike | np.ndarray, **kwargs):
whole slide image object or list of such objects
"""
cuimage_cls, _ = optional_import("cucim", name="CuImage")
wsi_list: list = []

filenames: Sequence[PathLike] = ensure_tuple(data)
kwargs_ = self.kwargs.copy()
kwargs_.update(kwargs)
for filename in filenames:
wsi = CuImage(filename, **kwargs_)
wsi = cuimage_cls(filename, **kwargs_)
wsi_list.append(wsi)

return wsi_list if len(filenames) > 1 else wsi_list[0]
Expand Down
2 changes: 1 addition & 1 deletion monai/transforms/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@
ndimage, _ = optional_import("scipy.ndimage")
cp, has_cp = optional_import("cupy")
cp_ndarray, _ = optional_import("cupy", name="ndarray")
cucim, has_cucim = optional_import("cucim")
exposure, has_skimage = optional_import("skimage.exposure")

__all__ = [
Expand Down Expand Up @@ -974,6 +973,7 @@ def get_largest_connected_component_mask(
"""
# use skimage/cucim.skimage and np/cp depending on whether packages are
# available and input is non-cpu torch.tensor
cucim, has_cucim = optional_import("cucim")
use_cp = has_cp and has_cucim and isinstance(img, torch.Tensor) and img.device != torch.device("cpu")
if use_cp:
img_ = convert_to_cupy(img.short()) # type: ignore
Expand Down
2 changes: 1 addition & 1 deletion monai/utils/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,10 +477,10 @@ def require_pkg(
def _decorator(obj):
is_func = isinstance(obj, FunctionType)
call_obj = obj if is_func else obj.__init__
_, has = optional_import(module=pkg_name, version=version, version_checker=version_checker)

@wraps(call_obj)
def _wrapper(*args, **kwargs):
_, has = optional_import(module=pkg_name, version=version, version_checker=version_checker)
if not has:
err_msg = f"required package `{pkg_name}` is not installed or the version doesn't match requirement."
if raise_error:
Expand Down

0 comments on commit b85e2c6

Please sign in to comment.