Repository: rapidsai/cucim (language: python)

Issue:
[QST] conda compatibility with scikit-image 0.20.0
scikit-image recently updated to 0.20.0 on conda-forge, however cucim's dependencies explicitly prevent 0.20.0 or above from being installed. Is there any reason why this limitation is in place, especially when cucim's API is already using the 0.20.0 scikit-image API?


Discussion / hints:
Hi @accelyte, thank you for reporting the issue! I will bump the conda version pinnings to allow scikit-image 0.20 as well.

I will update here once I know whether or not this will make it in for the 23.04 release later this week. 

As a workaround in the meantime, the PyPI version of the package does not have the version restriction. You could install it into a conda environment with `pip install cucim` after installing cupy and scikit-image via conda.

Fix patch:
diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml
index 90c70b5a7..d804f55b0 100644
--- a/conda/environments/all_cuda-118_arch-x86_64.yaml
+++ b/conda/environments/all_cuda-118_arch-x86_64.yaml
@@ -35,7 +35,7 @@ dependencies:
 - pytest>=6.2.4
 - python>=3.8,<3.11
 - recommonmark
-- scikit-image >=0.19.0,<0.20.0a0
+- scikit-image >=0.19.0,<0.21.0a0
 - scipy
 - sphinx<6
 - sysroot_linux-64==2.17
diff --git a/conda/recipes/cucim/meta.yaml b/conda/recipes/cucim/meta.yaml
index 1ad354094..7772aaaf6 100644
--- a/conda/recipes/cucim/meta.yaml
+++ b/conda/recipes/cucim/meta.yaml
@@ -48,7 +48,7 @@ requirements:
     - libcucim ={{ version }}
     - numpy 1.21
     - python
-    - scikit-image >=0.19.0,<0.20.0a0
+    - scikit-image >=0.19.0,<0.21.0a0
     - scipy
   run:
     - {{ pin_compatible('cudatoolkit', max_pin='x', min_pin='x') }}
@@ -58,7 +58,7 @@ requirements:
     - libcucim ={{ version }}
     # - openslide # skipping here but benchmark binary would need openslide library
     - python
-    - scikit-image >=0.19.0,<0.20.0a0
+    - scikit-image >=0.19.0,<0.21.0a0
     - scipy
 
 tests:
diff --git a/dependencies.yaml b/dependencies.yaml
index 9838dd13d..4dcb23f58 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -138,7 +138,7 @@ dependencies:
           - jpeg
           - libwebp-base
           - numpy >=1.21.3
-          - scikit-image >=0.19.0,<0.20.0a0
+          - scikit-image >=0.19.0,<0.21.0a0
           - scipy
           - xz
           - zlib


Test patch:
diff --git a/python/cucim/src/cucim/skimage/morphology/tests/test_isotropic.py b/python/cucim/src/cucim/skimage/morphology/tests/test_isotropic.py
index d0ecdb219..edd67bc7e 100644
--- a/python/cucim/src/cucim/skimage/morphology/tests/test_isotropic.py
+++ b/python/cucim/src/cucim/skimage/morphology/tests/test_isotropic.py
@@ -1,3 +1,5 @@
+import platform
+
 import cupy as cp
 import numpy as np
 import pytest
@@ -10,7 +12,12 @@
 img = color.rgb2gray(cp.asarray(data.astronaut()))
 bw_img = img > 100 / 255.
 
+# TODO: Some tests fail unexpectedly on ARM.
+ON_AARCH64 = platform.machine() == "aarch64"
+ON_AARCH64_REASON = "TODO: Test fails unexpectedly on ARM."
+
 
+@pytest.mark.xfail(ON_AARCH64, reason=ON_AARCH64_REASON)
 def test_non_square_image():
     isotropic_res = morphology.isotropic_erosion(bw_img[:100, :200], 3)
     binary_res = img_as_bool(morphology.binary_erosion(
@@ -18,6 +25,7 @@ def test_non_square_image():
     assert_array_equal(isotropic_res, binary_res)
 
 
+@pytest.mark.xfail(ON_AARCH64, reason=ON_AARCH64_REASON)
 def test_isotropic_erosion():
     isotropic_res = morphology.isotropic_erosion(bw_img, 3)
     binary_res = img_as_bool(
@@ -44,6 +52,7 @@ def _disk_with_spacing(
     return cp.asarray((X ** 2 + Y ** 2) <= radius ** 2, dtype=dtype)
 
 
+@pytest.mark.xfail(ON_AARCH64, reason=ON_AARCH64_REASON)
 def test_isotropic_erosion_spacing():
     isotropic_res = morphology.isotropic_dilation(bw_img, 6, spacing=(1, 2))
     binary_res = img_as_bool(
@@ -54,6 +63,7 @@ def test_isotropic_erosion_spacing():
     assert_array_equal(isotropic_res, binary_res)
 
 
+@pytest.mark.xfail(ON_AARCH64, reason=ON_AARCH64_REASON)
 def test_isotropic_dilation():
     isotropic_res = morphology.isotropic_dilation(bw_img, 3)
     binary_res = img_as_bool(
@@ -62,6 +72,7 @@ def test_isotropic_dilation():
     assert_array_equal(isotropic_res, binary_res)
 
 
+@pytest.mark.xfail(ON_AARCH64, reason=ON_AARCH64_REASON)
 def test_isotropic_closing():
     isotropic_res = morphology.isotropic_closing(bw_img, 3)
     binary_res = img_as_bool(
@@ -70,6 +81,7 @@ def test_isotropic_closing():
     assert_array_equal(isotropic_res, binary_res)
 
 
+@pytest.mark.xfail(ON_AARCH64, reason=ON_AARCH64_REASON)
 def test_isotropic_opening():
     isotropic_res = morphology.isotropic_opening(bw_img, 3)
     binary_res = img_as_bool(
@@ -78,6 +90,7 @@ def test_isotropic_opening():
     assert_array_equal(isotropic_res, binary_res)
 
 
+@pytest.mark.xfail(ON_AARCH64, reason=ON_AARCH64_REASON)
 def test_footprint_overflow():
     img = cp.zeros((20, 20), dtype=bool)
     img[2:19, 2:19] = True
@@ -88,6 +101,7 @@ def test_footprint_overflow():
     assert_array_equal(isotropic_res, binary_res)
 
 
+@pytest.mark.xfail(ON_AARCH64, reason=ON_AARCH64_REASON)
 @pytest.mark.parametrize('out_dtype', [bool, cp.uint8, cp.int32])
 def test_out_argument(out_dtype):
     for func in (morphology.isotropic_erosion, morphology.isotropic_dilation,