From 5263466d24076bc41e9c8c83a980432ef7527c68 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Fri, 27 Oct 2023 13:13:14 +0300 Subject: [PATCH 01/24] Wheels for arch64 --- .github/workflows/release.yml | 1 + .github/workflows/test_build.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dba7f648..6c539523 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -58,6 +58,7 @@ jobs: python -m pip install --upgrade pip python -m cibuildwheel --output-dir wheelhouse env: + CIBW_ARCHS_MACOS: "x86_64 arm64" CIBW_ENVIRONMENT_MACOS: > PATH="/usr/local/opt/llvm/bin:$PATH" LDFLAGS="-L/usr/local/opt/llvm/lib" CPPFLAGS="-I/usr/local/opt/llvm/include" CIBW_BUILD: cp36-* cp37-* cp38-* cp39-* cp310-* cp311-* diff --git a/.github/workflows/test_build.yml b/.github/workflows/test_build.yml index 2742c1e8..6955193b 100644 --- a/.github/workflows/test_build.yml +++ b/.github/workflows/test_build.yml @@ -32,6 +32,7 @@ jobs: python -m pip install --upgrade pip python -m cibuildwheel --output-dir wheelhouse env: + CIBW_ARCHS_MACOS: "x86_64 arm64" CIBW_ENVIRONMENT_MACOS: > PATH="/usr/local/opt/llvm/bin:$PATH" LDFLAGS="-L/usr/local/opt/llvm/lib" CPPFLAGS="-I/usr/local/opt/llvm/include" CIBW_BUILD: cp39-* cp36-* From 49746d2f5cd315e748b89a9aab069e37a8b9962f Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Fri, 27 Oct 2023 13:14:21 +0300 Subject: [PATCH 02/24] version --- imops/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imops/__version__.py b/imops/__version__.py index 21320a81..73f83151 100644 --- a/imops/__version__.py +++ b/imops/__version__.py @@ -1 +1 @@ -__version__ = '0.8.4' +__version__ = '0.8.5' From cb2204bc5d05bc39d705ad8edc4acacffe1ad738 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Thu, 9 Nov 2023 23:48:35 +0300 Subject: [PATCH 03/24] Bump `cibuildwheel` --- .github/workflows/test_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_build.yml b/.github/workflows/test_build.yml index 6955193b..3f1ecea4 100644 --- a/.github/workflows/test_build.yml +++ b/.github/workflows/test_build.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v3 - name: Install cibuildwheel - run: python -m pip install cibuildwheel==2.10.0 + run: python -m pip install cibuildwheel==2.16.2 - name: Install gcc for mac if: matrix.os == 'macOS-11' run: | From 869e3a591681839737c79720ab0ee22e056d2270 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Mon, 27 Nov 2023 12:35:48 +0300 Subject: [PATCH 04/24] stacklevel --- imops/zoom.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imops/zoom.py b/imops/zoom.py index 2752afd6..455966a2 100644 --- a/imops/zoom.py +++ b/imops/zoom.py @@ -238,6 +238,7 @@ def _zoom( warn( 'Fast zoom is only supported for ndim<=4, dtype=fp32 or fp64 (and bool-int16-32-64 if order == 0), ' "output=None, order=0 or 1, mode='constant', grid_mode=False. Falling back to scipy's implementation.", + stacklevel=3, ) return scipy_zoom( input, zoom, output=output, order=order, mode=mode, cval=cval, prefilter=prefilter, grid_mode=grid_mode @@ -276,7 +277,7 @@ def _zoom( *args, ) else: - warn("Input array can't be represented as C-contiguous, performance can drop a lot.") + warn("Input array can't be represented as C-contiguous, performance can drop a lot.", stacklevel=3) out = src_zoom(input, zoom, cval, *args) else: out = src_zoom(input, zoom, cval, *args) From 5492cc40437bd27c8493766e341ad1b22550bebd Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 19 Dec 2023 19:48:47 +0300 Subject: [PATCH 05/24] setuptools --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 03753a93..67a4801b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ['setuptools', 'numpy<2.0.0', 'Cython<3.0.0'] +requires = ['setuptools<69.0.0', 'numpy<2.0.0', 'Cython<3.0.0'] build-backend = 'setuptools.build_meta' [project] From 97da28f0a3e52dd6268bf8ab46e4ddcf2136c7fb Mon Sep 17 00:00:00 2001 From: Anihilatorgunn Date: Fri, 29 Mar 2024 20:14:51 +0300 Subject: [PATCH 06/24] faster --- imops/interp1d.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imops/interp1d.py b/imops/interp1d.py index e010cd4b..334434fe 100644 --- a/imops/interp1d.py +++ b/imops/interp1d.py @@ -2,6 +2,7 @@ from warnings import warn import numpy as np +import torch from scipy.interpolate import interp1d as scipy_interp1d from .backend import BackendLike, resolve_backend @@ -180,14 +181,14 @@ def __call__(self, x_new: np.ndarray) -> np.ndarray: if self.backend.name == 'Numba': set_num_threads(old_num_threads) - out = out.astype(max(self.y.dtype, self.x.dtype, x_new.dtype, key=lambda x: x.type(0).itemsize), copy=False) + out = torch.from_numpy(out).to(max(torch.from_numpy(self.y).dtype, torch.from_numpy(self.x).dtype, torch.from_numpy(x_new).dtype, key=lambda x: x.itemsize)).numpy() if self.n_dummy: out = out[(0,) * self.n_dummy] if self.axis not in (-1, out.ndim - 1): out = np.swapaxes(out, -1, self.axis) # FIXME: fix behaviour with np.inf-s - if np.isnan(out).any(): + if torch.isnan(torch.from_numpy(out)).any(): if not np.isinf(out).any(): raise RuntimeError("Can't decide how to handle nans in the output.") From 8d794247a645eee8d04c2130ea9244a7c112cf78 Mon Sep 17 00:00:00 2001 From: Anihilatorgunn Date: Fri, 29 Mar 2024 20:20:37 +0300 Subject: [PATCH 07/24] fix --- imops/interp1d.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/imops/interp1d.py b/imops/interp1d.py index 334434fe..878e25c0 100644 --- a/imops/interp1d.py +++ b/imops/interp1d.py @@ -2,7 +2,6 @@ from warnings import warn import numpy as np -import torch from scipy.interpolate import interp1d as scipy_interp1d from .backend import BackendLike, resolve_backend @@ -138,7 +137,9 @@ def __init__( njit_kwargs = {kwarg: getattr(backend, kwarg) for kwarg in backend.__dataclass_fields__.keys()} self.src_interp1d = njit(**njit_kwargs)(numba_interp1d) - def __call__(self, x_new: np.ndarray) -> np.ndarray: + def __call__(self, x_new: np.ndarray, use_torch: bool = False) -> np.ndarray: + if use_torch: + import torch """ Evaluate the interpolant @@ -181,14 +182,21 @@ def __call__(self, x_new: np.ndarray) -> np.ndarray: if self.backend.name == 'Numba': set_num_threads(old_num_threads) - out = torch.from_numpy(out).to(max(torch.from_numpy(self.y).dtype, torch.from_numpy(self.x).dtype, torch.from_numpy(x_new).dtype, key=lambda x: x.itemsize)).numpy() + if use_torch: + out = torch.from_numpy(out).to(max(torch.from_numpy(self.y).dtype, torch.from_numpy(self.x).dtype, torch.from_numpy(x_new).dtype, key=lambda x: x.itemsize)).numpy() + else: + out = out.astype(max(self.y.dtype, self.x.dtype, x_new.dtype, key=lambda x: x.type(0).itemsize), copy=False) if self.n_dummy: out = out[(0,) * self.n_dummy] if self.axis not in (-1, out.ndim - 1): out = np.swapaxes(out, -1, self.axis) # FIXME: fix behaviour with np.inf-s - if torch.isnan(torch.from_numpy(out)).any(): + if use_torch: + have_nan = torch.isnan(torch.from_numpy(out)).any() + else: + have_nan = np.isnan(out).any() + if have_nan: if not np.isinf(out).any(): raise RuntimeError("Can't decide how to handle nans in the output.") From 8965b96b8c5221865d382b6febd6dac316f53cdf Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Mon, 1 Apr 2024 19:21:24 +0300 Subject: [PATCH 08/24] Support uint16-32 --- imops/src/_zoom.pyx | 2 ++ imops/zoom.py | 13 +++++++------ tests/test_zoom.py | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/imops/src/_zoom.pyx b/imops/src/_zoom.pyx index 44b4d078..9aabbc81 100644 --- a/imops/src/_zoom.pyx +++ b/imops/src/_zoom.pyx @@ -18,6 +18,8 @@ from libc.math cimport floor, sqrt ctypedef cython.floating FLOAT ctypedef fused NUM: np.uint8_t + np.uint16_t + np.uint32_t short int long long diff --git a/imops/zoom.py b/imops/zoom.py index 455966a2..6d1868ff 100644 --- a/imops/zoom.py +++ b/imops/zoom.py @@ -81,7 +81,7 @@ def zoom( """ Rescale `x` according to `scale_factor` along the `axis`. - Uses a fast parallelizable implementation for fp32 / fp64 (and bool-int16-32-64 if order == 0) inputs, + Uses a fast parallelizable implementation for fp32-fp64 and bool-int16-32-64-uint8-16-32 if order == 0 inputs, ndim <= 4 and order = 0 or 1. Parameters @@ -136,7 +136,7 @@ def zoom_to_shape( """ Rescale `x` to match `shape` along the `axis`. - Uses a fast parallelizable implementation for fp32 / fp64 (and bool-int16-32-64 if order == 0) inputs, + Uses a fast parallelizable implementation for fp32-fp64 and bool-int16-32-64-uint8-16-32 if order == 0 inputs, ndim <= 4 and order = 0 or 1. Parameters @@ -198,7 +198,7 @@ def _zoom( backend: BackendLike = None, ) -> np.ndarray: """ - Faster parallelizable version of `scipy.ndimage.zoom` for fp32 / fp64 (and bool-int16-32-64 if order == 0) inputs. + Faster parallelizable version of `scipy.ndimage.zoom` for fp32-fp64 and bool-int16-32-64-uint8-16-32 if order == 0 Works faster only for ndim <= 4. Shares interface with `scipy.ndimage.zoom` except for @@ -228,7 +228,8 @@ def _zoom( or ( dtype not in (np.float32, np.float64) if order == 1 - else dtype not in (bool, np.float32, np.float64, np.int16, np.int32, np.int64) + else dtype + not in (bool, np.float32, np.float64, np.int16, np.int32, np.int64, np.uint8, np.uint16, np.uint32) ) or ndim > 4 or output is not None @@ -236,8 +237,8 @@ def _zoom( or grid_mode ): warn( - 'Fast zoom is only supported for ndim<=4, dtype=fp32 or fp64 (and bool-int16-32-64 if order == 0), ' - "output=None, order=0 or 1, mode='constant', grid_mode=False. Falling back to scipy's implementation.", + 'Fast zoom is only supported for ndim<=4, dtype=fp32-fp64 and bool-int16-32-64-uint8-16-32 if order == 0, ' + "output=None, order=0 or 1 , mode='constant', grid_mode=False. Falling back to scipy's implementation.", stacklevel=3, ) return scipy_zoom( diff --git a/tests/test_zoom.py b/tests/test_zoom.py index 88e9d6eb..353bcd40 100644 --- a/tests/test_zoom.py +++ b/tests/test_zoom.py @@ -39,7 +39,7 @@ def order(request): return request.param -@pytest.fixture(params=[np.float32, np.float64, bool, np.int16, np.int32, np.int64]) +@pytest.fixture(params=[np.float32, np.float64, bool, np.int16, np.int32, np.int64, np.uint8, np.uint16, np.uint32]) def dtype(request): return request.param From c5a7bd7c1b046c4facbb3406372925debe89d733 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Mon, 1 Apr 2024 19:24:18 +0300 Subject: [PATCH 09/24] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf8c8143..9f9c8b5f 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ y = zoom(x, 2, axis=[0, 1]) # without the need to compute the scale factor z = zoom_to_shape(x, (4, 120, 67)) ``` -Works faster only for `ndim<=4, dtype=float32 or float64 (and bool-int16-32-64 if order == 0), output=None, order=0 or 1, mode='constant', grid_mode=False` +Works faster only for `ndim<=4, dtype=float32 or float64 (and bool-int16-32-64-uint8-16-32 if order == 0), output=None, order=0 or 1, mode='constant', grid_mode=False` ### Fast 1d linear interpolation ```python From 058acec33d0668d37c127e3b65fce7c0348c1a1c Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Mon, 1 Apr 2024 19:25:23 +0300 Subject: [PATCH 10/24] version --- imops/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imops/__version__.py b/imops/__version__.py index 73f83151..8843c51c 100644 --- a/imops/__version__.py +++ b/imops/__version__.py @@ -1 +1 @@ -__version__ = '0.8.5' +__version__ = '0.8.7' From 9a19949e4089f042b02dd07647846680340e6231 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Mon, 1 Apr 2024 20:32:02 +0300 Subject: [PATCH 11/24] Avoid cropping to float shape/box --- imops/crop.py | 7 +++++++ tests/test_crop.py | 16 +++++++++++++++- tests/test_pad.py | 3 +++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/imops/crop.py b/imops/crop.py index 2476305e..5c210774 100644 --- a/imops/crop.py +++ b/imops/crop.py @@ -35,6 +35,9 @@ def crop_to_shape(x: np.ndarray, shape: AxesLike, axis: AxesLike = None, ratio: >>> cropped = crop_to_shape(x, [3, 4, 5]) # fail due to bigger resulting shape """ x = np.asarray(x) + shape = np.asarray(shape) + if not np.issubdtype(shape.dtype, np.integer): + raise ValueError(f'`shape` must be of integer dtype, got {shape.dtype}') axis, shape, ratio = broadcast_axis(axis, x.ndim, shape, ratio) old_shape, new_shape = np.array(x.shape), np.array(fill_by_indices(x.shape, shape, axis)) @@ -89,6 +92,10 @@ def crop_to_box( >>> cropped = crop_to_box(x, np.array([[0], [5]]), axis=0, padding_values=0) # pad with 0-s to shape [5, 3, 4] """ x = np.asarray(x) + box = np.asarray(box) + if not np.issubdtype(box.dtype, np.integer): + raise ValueError(f'`box` must be of integer dtype, got {box.dtype}') + start, stop = box axis, start, stop = broadcast_axis(axis, x.ndim, start, stop) diff --git a/tests/test_crop.py b/tests/test_crop.py index 8d9e569f..3be805b0 100644 --- a/tests/test_crop.py +++ b/tests/test_crop.py @@ -52,7 +52,21 @@ def test_raises(): @seeded_by(SEED) def test_crop_to_shape(): x = np.random.rand(3, 10, 10) - shape = 3, 4, 8 + shape = (3, 4, 8) assert crop_to_shape(x, shape).shape == shape with pytest.raises(ValueError): crop_to_shape(x, (3, 15, 10)) + + +def test_crop_to_float_shape(): + x = np.random.rand(3, 10, 10) + float_shape = (1.337, 3.1415, 2.7182) + with pytest.raises(ValueError): + crop_to_shape(x, float_shape) + + +def test_crop_to_float_box(): + x = np.random.rand(3, 10, 10) + float_box = [[0, 1], [4, 4.5], [3.1, 9]] + with pytest.raises(ValueError): + crop_to_box(x, float_box) diff --git a/tests/test_pad.py b/tests/test_pad.py index 664db814..19fa3a0a 100644 --- a/tests/test_pad.py +++ b/tests/test_pad.py @@ -140,6 +140,9 @@ def test_restore_crop_invalid_box(): with pytest.raises(ValueError): restore_crop(x, np.array([[0, 0, 0], [1, 1, 1]]), [4, 4, 4]) + with pytest.raises(ValueError): + restore_crop(x, np.array([[0.5, 0.5, 0.5], [1.5, 1.5, 1.5]]), [4.5, 4.5, 4.5]) + def test_pad_to_divisible(): x = np.zeros((4, 8, 12)) From fb56fade65f4a2104f7293e137fe3e4e8b574bd3 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 2 Apr 2024 12:06:36 +0300 Subject: [PATCH 12/24] style; --- imops/interp1d.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/imops/interp1d.py b/imops/interp1d.py index 878e25c0..d499b6a5 100644 --- a/imops/interp1d.py +++ b/imops/interp1d.py @@ -183,7 +183,18 @@ def __call__(self, x_new: np.ndarray, use_torch: bool = False) -> np.ndarray: set_num_threads(old_num_threads) if use_torch: - out = torch.from_numpy(out).to(max(torch.from_numpy(self.y).dtype, torch.from_numpy(self.x).dtype, torch.from_numpy(x_new).dtype, key=lambda x: x.itemsize)).numpy() + out = ( + torch.from_numpy(out) + .to( + max( + torch.from_numpy(self.y).dtype, + torch.from_numpy(self.x).dtype, + torch.from_numpy(x_new).dtype, + key=lambda x: x.itemsize, + ) + ) + .numpy() + ) else: out = out.astype(max(self.y.dtype, self.x.dtype, x_new.dtype, key=lambda x: x.type(0).itemsize), copy=False) From 644725b486fafac52517903e1e5deafe38d675ba Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 2 Apr 2024 12:14:09 +0300 Subject: [PATCH 13/24] update `setup-python` --- .github/workflows/docs.yml | 2 +- .github/workflows/release.yml | 8 ++++---- .github/workflows/test_build.yml | 7 ++++--- .github/workflows/tests.yml | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 766d566d..cdbe60be 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v3 - uses: fregante/setup-git-user@v1 - run: git fetch origin gh-pages --depth=1 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.10' - name: Install diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f42ab66a..745ce647 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Set up Python 3.9 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.9 @@ -42,9 +42,9 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 - name: Install cibuildwheel - run: python -m pip install cibuildwheel==2.10.0 + run: python -m pip install cibuildwheel==2.17.0 - name: Install gcc for mac if: matrix.os == 'macOS-11' run: | @@ -91,7 +91,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Set up Python 3.9 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 - name: Build run: python setup.py sdist - uses: actions/upload-artifact@v3 diff --git a/.github/workflows/test_build.yml b/.github/workflows/test_build.yml index 824bdca5..31631a47 100644 --- a/.github/workflows/test_build.yml +++ b/.github/workflows/test_build.yml @@ -16,9 +16,11 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.9' - name: Install cibuildwheel - run: python -m pip install cibuildwheel==2.16.2 + run: python -m pip install cibuildwheel==2.17.0 - name: Install gcc for mac if: matrix.os == 'macOS-11' run: | @@ -50,7 +52,6 @@ jobs: python -m pip install --upgrade pip python -m cibuildwheel --output-dir wheelhouse env: - CIBW_ARCHS_MACOS: "x86_64 arm64" CIBW_ENVIRONMENT_MACOS: > PATH="/usr/local/opt/llvm/bin:$PATH" LDFLAGS="-L/usr/local/opt/llvm/lib" CPPFLAGS="-I/usr/local/opt/llvm/include" CIBW_BUILD: cp39-* cp36-* diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 513995f8..7e674650 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} From 086a18be63594e556f45ece02e2d58e0b67b728e Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 2 Apr 2024 12:16:26 +0300 Subject: [PATCH 14/24] Support py312 --- .github/workflows/release.yml | 2 +- .github/workflows/test_build.yml | 2 +- .github/workflows/tests.yml | 2 +- pyproject.toml | 1 + setup.py | 1 + 5 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 745ce647..3db0141c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -79,7 +79,7 @@ jobs: CIBW_ARCHS_MACOS: "x86_64 arm64" CIBW_ENVIRONMENT_MACOS: > PATH="/usr/local/opt/llvm/bin:$PATH" LDFLAGS="-L/usr/local/opt/llvm/lib" CPPFLAGS="-I/usr/local/opt/llvm/include" - CIBW_BUILD: cp36-* cp37-* cp38-* cp39-* cp310-* cp311-* + CIBW_BUILD: cp36-* cp37-* cp38-* cp39-* cp310-* cp311-* cp312-* CIBW_BEFORE_BUILD_LINUX: 'if [ $(python -c "import sys; print(sys.version_info[1])") -ge 9 ]; then python -m pip install "numpy<2.0.0" --config-settings=setup-args="-Dallow-noblas=true"; fi' - uses: actions/upload-artifact@v3 with: diff --git a/.github/workflows/test_build.yml b/.github/workflows/test_build.yml index 31631a47..ffcc456e 100644 --- a/.github/workflows/test_build.yml +++ b/.github/workflows/test_build.yml @@ -54,6 +54,6 @@ jobs: env: CIBW_ENVIRONMENT_MACOS: > PATH="/usr/local/opt/llvm/bin:$PATH" LDFLAGS="-L/usr/local/opt/llvm/lib" CPPFLAGS="-I/usr/local/opt/llvm/include" - CIBW_BUILD: cp39-* cp36-* + CIBW_BUILD: cp39-* cp36-* cp312-* CIBW_SKIP: "*musllinux* *manylinux_x86_64" CIBW_BEFORE_BUILD_LINUX: 'if [ $(python -c "import sys; print(sys.version_info[1])") -ge 9 ]; then python -m pip install "numpy<2.0.0" --config-settings=setup-args="-Dallow-noblas=true"; fi' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7e674650..2a192669 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: [ '3.6', '3.7', '3.8', '3.9', '3.10', '3.11'] + python-version: [ '3.6', '3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v3 diff --git a/pyproject.toml b/pyproject.toml index 2ee62668..4ca5df98 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ classifiers = [ 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ] [options] diff --git a/setup.py b/setup.py index d20d0f10..f255b459 100644 --- a/setup.py +++ b/setup.py @@ -15,6 +15,7 @@ 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ] with open(root / 'requirements.txt', encoding='utf-8') as file: From 367b89856b6398f6d1526ee734527a5f2d61ccc7 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 2 Apr 2024 12:27:11 +0300 Subject: [PATCH 15/24] sdist --- .github/workflows/release.yml | 2 +- .github/workflows/tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3db0141c..e0608812 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -93,7 +93,7 @@ jobs: - name: Set up Python 3.9 uses: actions/setup-python@v5 - name: Build - run: python setup.py sdist + run: python -m build --sdist - uses: actions/upload-artifact@v3 with: path: dist/*.tar.gz diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2a192669..934a7543 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,7 +28,7 @@ jobs: if [ "$GITHUB_BASE_REF" = "master" ] && [ "$MATCH" != "" ]; then exit 1; fi - name: Build the package run: | - python setup.py sdist + python -m build --sdist - name: Install run: | From 8385faf97e44d68220a664c56eb26046dc2909e2 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 2 Apr 2024 12:30:41 +0300 Subject: [PATCH 16/24] Fix --- .github/workflows/release.yml | 4 +++- .github/workflows/tests.yml | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e0608812..4b2c6a7c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -93,7 +93,9 @@ jobs: - name: Set up Python 3.9 uses: actions/setup-python@v5 - name: Build - run: python -m build --sdist + run: | + pip install build + python -m build --sdist - uses: actions/upload-artifact@v3 with: path: dist/*.tar.gz diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 934a7543..0c04d2c8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,6 +28,7 @@ jobs: if [ "$GITHUB_BASE_REF" = "master" ] && [ "$MATCH" != "" ]; then exit 1; fi - name: Build the package run: | + pip install build python -m build --sdist - name: Install From f770844205291ee6360313f2d3b45aa878fbe0c4 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 2 Apr 2024 13:55:26 +0300 Subject: [PATCH 17/24] linters --- requirements-linters.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-linters.txt b/requirements-linters.txt index 36d44aaa..fab5a2ea 100644 --- a/requirements-linters.txt +++ b/requirements-linters.txt @@ -1,7 +1,7 @@ black<23.0.0 flake8<=5 flake8-tidy-imports -flake8-quotes +flake8-quotes<3.4.0 flake8-bugbear flake8-comprehensions isort From 07c457bc69bbc10f9ac695a1b8aa06f4fa02c9d6 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 2 Apr 2024 16:08:03 +0300 Subject: [PATCH 18/24] flake --- .flake8 | 3 ++- imops/morphology.py | 4 ++-- requirements-linters.txt | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.flake8 b/.flake8 index ce555863..c443919c 100644 --- a/.flake8 +++ b/.flake8 @@ -4,7 +4,8 @@ # F401: unused imports in __init__.py-s # I251: allow absolute imports in upper files # B028: !r is not supported for python<3.8 -ignore = W503,E203,B028 +# W604: backticks in str-s are ok +ignore = W503,E203,B028,W604 per-file-ignores = __init__.py:F401 tests/*:I251 diff --git a/imops/morphology.py b/imops/morphology.py index 249adc55..9f19d758 100644 --- a/imops/morphology.py +++ b/imops/morphology.py @@ -80,13 +80,13 @@ def wrapped( raise ValueError('Input image and footprint number of dimensions must be the same.') if not image.any(): - warn(f'{op_name} is applied to the fully False mask (mask.any() == False).', stacklevel=3) + warn(f'{op_name} is applied to the fully False mask (mask.any() == False).', stacklevel=3) # noqa output.fill(False) return output if image.all(): - warn(f'{op_name} is applied to the fully True mask (mask.all() == True).', stacklevel=3) + warn(f'{op_name} is applied to the fully True mask (mask.all() == True).', stacklevel=3) # noqa output.fill(True) return output diff --git a/requirements-linters.txt b/requirements-linters.txt index fab5a2ea..36d44aaa 100644 --- a/requirements-linters.txt +++ b/requirements-linters.txt @@ -1,7 +1,7 @@ black<23.0.0 flake8<=5 flake8-tidy-imports -flake8-quotes<3.4.0 +flake8-quotes flake8-bugbear flake8-comprehensions isort From bdb4996d501f8f3579543b3fa67af23c57305d29 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 16 Apr 2024 18:58:36 +0300 Subject: [PATCH 19/24] Revert "fix" This reverts commit 8d794247a645eee8d04c2130ea9244a7c112cf78. --- imops/interp1d.py | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/imops/interp1d.py b/imops/interp1d.py index d499b6a5..334434fe 100644 --- a/imops/interp1d.py +++ b/imops/interp1d.py @@ -2,6 +2,7 @@ from warnings import warn import numpy as np +import torch from scipy.interpolate import interp1d as scipy_interp1d from .backend import BackendLike, resolve_backend @@ -137,9 +138,7 @@ def __init__( njit_kwargs = {kwarg: getattr(backend, kwarg) for kwarg in backend.__dataclass_fields__.keys()} self.src_interp1d = njit(**njit_kwargs)(numba_interp1d) - def __call__(self, x_new: np.ndarray, use_torch: bool = False) -> np.ndarray: - if use_torch: - import torch + def __call__(self, x_new: np.ndarray) -> np.ndarray: """ Evaluate the interpolant @@ -182,32 +181,14 @@ def __call__(self, x_new: np.ndarray, use_torch: bool = False) -> np.ndarray: if self.backend.name == 'Numba': set_num_threads(old_num_threads) - if use_torch: - out = ( - torch.from_numpy(out) - .to( - max( - torch.from_numpy(self.y).dtype, - torch.from_numpy(self.x).dtype, - torch.from_numpy(x_new).dtype, - key=lambda x: x.itemsize, - ) - ) - .numpy() - ) - else: - out = out.astype(max(self.y.dtype, self.x.dtype, x_new.dtype, key=lambda x: x.type(0).itemsize), copy=False) + out = torch.from_numpy(out).to(max(torch.from_numpy(self.y).dtype, torch.from_numpy(self.x).dtype, torch.from_numpy(x_new).dtype, key=lambda x: x.itemsize)).numpy() if self.n_dummy: out = out[(0,) * self.n_dummy] if self.axis not in (-1, out.ndim - 1): out = np.swapaxes(out, -1, self.axis) # FIXME: fix behaviour with np.inf-s - if use_torch: - have_nan = torch.isnan(torch.from_numpy(out)).any() - else: - have_nan = np.isnan(out).any() - if have_nan: + if torch.isnan(torch.from_numpy(out)).any(): if not np.isinf(out).any(): raise RuntimeError("Can't decide how to handle nans in the output.") From 3b9ee95df68415eb68d47501aa33cfffb3049cc5 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 16 Apr 2024 18:58:48 +0300 Subject: [PATCH 20/24] Revert "faster" This reverts commit 97da28f0a3e52dd6268bf8ab46e4ddcf2136c7fb. --- imops/interp1d.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/imops/interp1d.py b/imops/interp1d.py index 334434fe..e010cd4b 100644 --- a/imops/interp1d.py +++ b/imops/interp1d.py @@ -2,7 +2,6 @@ from warnings import warn import numpy as np -import torch from scipy.interpolate import interp1d as scipy_interp1d from .backend import BackendLike, resolve_backend @@ -181,14 +180,14 @@ def __call__(self, x_new: np.ndarray) -> np.ndarray: if self.backend.name == 'Numba': set_num_threads(old_num_threads) - out = torch.from_numpy(out).to(max(torch.from_numpy(self.y).dtype, torch.from_numpy(self.x).dtype, torch.from_numpy(x_new).dtype, key=lambda x: x.itemsize)).numpy() + out = out.astype(max(self.y.dtype, self.x.dtype, x_new.dtype, key=lambda x: x.type(0).itemsize), copy=False) if self.n_dummy: out = out[(0,) * self.n_dummy] if self.axis not in (-1, out.ndim - 1): out = np.swapaxes(out, -1, self.axis) # FIXME: fix behaviour with np.inf-s - if torch.isnan(torch.from_numpy(out)).any(): + if np.isnan(out).any(): if not np.isinf(out).any(): raise RuntimeError("Can't decide how to handle nans in the output.") From 88d8c45bfbbc1927c4be442f15c71f9aaa0a07ab Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 16 Apr 2024 19:14:37 +0300 Subject: [PATCH 21/24] comments --- imops/crop.py | 9 ++++----- imops/utils.py | 5 +++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/imops/crop.py b/imops/crop.py index 5c210774..90cb338f 100644 --- a/imops/crop.py +++ b/imops/crop.py @@ -3,7 +3,7 @@ from .backend import BackendLike from .numeric import _NUMERIC_DEFAULT_NUM_THREADS from .pad import pad -from .utils import AxesLike, AxesParams, broadcast_axis, fill_by_indices +from .utils import AxesLike, AxesParams, assert_subdtype, broadcast_axis, fill_by_indices def crop_to_shape(x: np.ndarray, shape: AxesLike, axis: AxesLike = None, ratio: AxesParams = 0.5) -> np.ndarray: @@ -36,8 +36,8 @@ def crop_to_shape(x: np.ndarray, shape: AxesLike, axis: AxesLike = None, ratio: """ x = np.asarray(x) shape = np.asarray(shape) - if not np.issubdtype(shape.dtype, np.integer): - raise ValueError(f'`shape` must be of integer dtype, got {shape.dtype}') + assert_subdtype(shape.dtype, np.integer, 'shape') + axis, shape, ratio = broadcast_axis(axis, x.ndim, shape, ratio) old_shape, new_shape = np.array(x.shape), np.array(fill_by_indices(x.shape, shape, axis)) @@ -93,8 +93,7 @@ def crop_to_box( """ x = np.asarray(x) box = np.asarray(box) - if not np.issubdtype(box.dtype, np.integer): - raise ValueError(f'`box` must be of integer dtype, got {box.dtype}') + assert_subdtype(box.dtype, np.integer, 'box') start, stop = box axis, start, stop = broadcast_axis(axis, x.ndim, start, stop) diff --git a/imops/utils.py b/imops/utils.py index 4521ae7e..92d8d5c9 100644 --- a/imops/utils.py +++ b/imops/utils.py @@ -196,3 +196,8 @@ def check_len(*args) -> None: lengths = list(map(len, args)) if any(length != lengths[0] for length in lengths): raise ValueError(f'Arguments of equal length are required: {", ".join(map(str, lengths))}') + + +def assert_subdtype(dtype, ref_dtype, name): + if not np.issubdtype(dtype, ref_dtype): + raise ValueError(f'`{name}` must be of {ref_dtype.__name__} dtype, got {dtype}') From 606e0ff46a63a6ca44ead5b7f216ea637c74f901 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Wed, 17 Apr 2024 13:11:19 +0300 Subject: [PATCH 22/24] Bump codecov --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0c04d2c8..5da5ae49 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -74,7 +74,7 @@ jobs: if: ${{ always() }} - name: Upload coverage results - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: fail_ci_if_error: true files: reports/coverage-${{ matrix.python-version }}.xml From 0291c18cc81e31ba5c33b992cde1989c960c42d5 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 23 Apr 2024 18:11:10 +0300 Subject: [PATCH 23/24] Add codecov token usage --- .github/workflows/tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5da5ae49..b8106551 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -75,6 +75,8 @@ jobs: - name: Upload coverage results uses: codecov/codecov-action@v4 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: fail_ci_if_error: true files: reports/coverage-${{ matrix.python-version }}.xml From d9d38bec047a037a1fbb3f00094309e4fee3e751 Mon Sep 17 00:00:00 2001 From: Philipenko Vladimir Date: Tue, 23 Apr 2024 18:20:51 +0300 Subject: [PATCH 24/24] Bump workflows --- .github/workflows/docs.yml | 4 ++-- .github/workflows/release.yml | 7 +++---- .github/workflows/test_build.yml | 2 +- .github/workflows/tests.yml | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index cdbe60be..dc8f8d0f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -11,8 +11,8 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: fregante/setup-git-user@v1 + - uses: actions/checkout@v4 + - uses: fregante/setup-git-user@v2 - run: git fetch origin gh-pages --depth=1 - uses: actions/setup-python@v5 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4b2c6a7c..3a0e1017 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python 3.9 uses: actions/setup-python@v5 with: @@ -41,7 +41,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v5 - name: Install cibuildwheel run: python -m pip install cibuildwheel==2.17.0 @@ -76,7 +76,6 @@ jobs: python -m pip install --upgrade pip python -m cibuildwheel --output-dir wheelhouse env: - CIBW_ARCHS_MACOS: "x86_64 arm64" CIBW_ENVIRONMENT_MACOS: > PATH="/usr/local/opt/llvm/bin:$PATH" LDFLAGS="-L/usr/local/opt/llvm/lib" CPPFLAGS="-I/usr/local/opt/llvm/include" CIBW_BUILD: cp36-* cp37-* cp38-* cp39-* cp310-* cp311-* cp312-* @@ -89,7 +88,7 @@ jobs: needs: [ check_version ] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python 3.9 uses: actions/setup-python@v5 - name: Build diff --git a/.github/workflows/test_build.yml b/.github/workflows/test_build.yml index ffcc456e..b0498967 100644 --- a/.github/workflows/test_build.yml +++ b/.github/workflows/test_build.yml @@ -15,7 +15,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.9' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b8106551..322a975d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: python-version: [ '3.6', '3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: