diff --git a/conda/rsc_rapids_24.06.yml b/conda/rsc_rapids_24.10.yml similarity index 89% rename from conda/rsc_rapids_24.06.yml rename to conda/rsc_rapids_24.10.yml index e5354e55..c21bf794 100644 --- a/conda/rsc_rapids_24.06.yml +++ b/conda/rsc_rapids_24.10.yml @@ -5,9 +5,9 @@ channels: - conda-forge - bioconda dependencies: - - rapids=24.06 + - rapids=24.10 - python=3.11 - - cuda-version=11.8 + - cuda-version=12.5 - cudnn - cutensor - cusparselt diff --git a/docker/docker-push.sh b/docker/docker-push.sh index daeb6c35..2041e8c0 100755 --- a/docker/docker-push.sh +++ b/docker/docker-push.sh @@ -2,7 +2,7 @@ set -euxo pipefail docker_account=scverse -rapids_version=24.08 +rapids_version=24.10 grep -v -- '- rapids-singlecell' conda/rsc_rapids_${rapids_version}.yml > rsc_rapids.yml docker build -t rapids-singlecell-deps:latest -f docker/Dockerfile.deps . rm rsc_rapids.yml diff --git a/docs/release-notes/0.10.11.md b/docs/release-notes/0.10.11.md new file mode 100644 index 00000000..47279b44 --- /dev/null +++ b/docs/release-notes/0.10.11.md @@ -0,0 +1,18 @@ +### 0.10.11 {small}`2024-10-08` + +```{rubric} Features +``` + + +```{rubric} Performance +``` + +```{rubric} Bug fixes +``` + +```{rubric} Misc +``` +* Adds support for `Numpy-2.0` {pr}`277` {smaller}`S Dicks` +* Adds support for `rapids-24.10` {pr}`277` {smaller}`S Dicks` +* Updates testing to use `rapids-24.10` {pr}`277` {smaller}`S Dicks` +* Updates `docker` image to use `rapids-24.10` {pr}`277` {smaller}`S Dicks` diff --git a/docs/release-notes/index.md b/docs/release-notes/index.md index a5b0a755..faa775ff 100644 --- a/docs/release-notes/index.md +++ b/docs/release-notes/index.md @@ -3,6 +3,8 @@ # Release notes ## Version 0.10.0 +```{include} /release-notes/0.10.11.md +``` ```{include} /release-notes/0.10.10.md ``` ```{include} /release-notes/0.10.9.md diff --git a/pyproject.toml b/pyproject.toml index 0e0525d3..4505e519 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "hatchling.build" [project] name = "rapids_singlecell" description = "running single cell analysis on Nvidia GPUs" -requires-python = ">=3.8" +requires-python = ">=3.10" license = {file = "LICENSE"} authors = [{name = "Severin Dicks"}] readme = {file = "README.md", content-type="text/markdown"} @@ -26,8 +26,8 @@ dependencies = [ ] [project.optional-dependencies] -rapids11 = ["cupy-cuda11x","cudf-cu11==24.8.*", "cuml-cu11==24.8.*", "cugraph-cu11==24.8.*"] -rapids12 = ["cupy-cuda12x","cudf-cu12==24.8.*", "cuml-cu12==24.8.*", "cugraph-cu12==24.8.*"] +rapids11 = ["cupy-cuda11x","cudf-cu11==24.10.*", "cuml-cu11==24.10.*", "cugraph-cu11==24.10.*"] +rapids12 = ["cupy-cuda12x","cudf-cu12==24.10.*", "cuml-cu12==24.10.*", "cugraph-cu12==24.10.*"] doc = [ "sphinx>=4.5.0", "sphinx-copybutton", @@ -41,7 +41,7 @@ doc = [ test = [ "pytest", "profimp", - "scanpy[test]>=1.10.0", + "scanpy>=1.10.0", "bbknn", ] diff --git a/src/rapids_singlecell/_utils/__init__.py b/src/rapids_singlecell/_utils/__init__.py index ff09b389..201809b6 100644 --- a/src/rapids_singlecell/_utils/__init__.py +++ b/src/rapids_singlecell/_utils/__init__.py @@ -4,4 +4,4 @@ import numpy as np -AnyRandom = Union[int, np.random.RandomState, None] +AnyRandom = Union[int, np.random.RandomState, None] # noqa: UP007 diff --git a/src/rapids_singlecell/get/_aggregated.py b/src/rapids_singlecell/get/_aggregated.py index 199503dc..aa2729fe 100644 --- a/src/rapids_singlecell/get/_aggregated.py +++ b/src/rapids_singlecell/get/_aggregated.py @@ -2,8 +2,6 @@ from typing import ( TYPE_CHECKING, - Collection, - Iterable, Literal, Union, get_args, @@ -20,10 +18,12 @@ from rapids_singlecell.preprocessing._utils import _check_gpu_X if TYPE_CHECKING: + from collections.abc import Collection, Iterable + import pandas as pd from numpy.typing import NDArray -Array = Union[cp.ndarray, cp_sparse.csc_matrix, cp_sparse.csr_matrix] +Array = Union[cp.ndarray, cp_sparse.csc_matrix, cp_sparse.csr_matrix] # noqa: UP007 AggType = Literal["count_nonzero", "mean", "sum", "var"] diff --git a/src/rapids_singlecell/get/_anndata.py b/src/rapids_singlecell/get/_anndata.py index af4b6fc1..c42b52bf 100644 --- a/src/rapids_singlecell/get/_anndata.py +++ b/src/rapids_singlecell/get/_anndata.py @@ -16,8 +16,8 @@ if TYPE_CHECKING: from anndata import AnnData -GPU_ARRAY_TYPE = Union[cp.ndarray, csr_matrix_gpu, csc_matrix_gpu] -CPU_ARRAY_TYPE = Union[np.ndarray, csr_matrix_cpu, csc_matrix_cpu] +GPU_ARRAY_TYPE = Union[cp.ndarray, csr_matrix_gpu, csc_matrix_gpu] # noqa: UP007 +CPU_ARRAY_TYPE = Union[np.ndarray, csr_matrix_cpu, csc_matrix_cpu] # noqa: UP007 def anndata_to_GPU( diff --git a/src/rapids_singlecell/preprocessing/_neighbors.py b/src/rapids_singlecell/preprocessing/_neighbors.py index ac02963d..cf67b926 100644 --- a/src/rapids_singlecell/preprocessing/_neighbors.py +++ b/src/rapids_singlecell/preprocessing/_neighbors.py @@ -2,7 +2,7 @@ import math from types import MappingProxyType -from typing import TYPE_CHECKING, Any, Literal, Mapping, Union +from typing import TYPE_CHECKING, Any, Literal import cupy as cp import numpy as np @@ -14,9 +14,11 @@ from rapids_singlecell.tools._utils import _choose_representation if TYPE_CHECKING: + from collections.abc import Mapping + from anndata import AnnData -AnyRandom = Union[None, int, np.random.RandomState] +AnyRandom = None | int | np.random.RandomState _Alogithms = Literal["brute", "ivfflat", "ivfpq", "cagra"] _MetricsDense = Literal[ "l2", @@ -54,7 +56,7 @@ "minkowski", "taxicab", ] -_Metrics = Union[_MetricsDense, _MetricsSparse] +_Metrics = _MetricsDense | _MetricsSparse def _brute_knn( diff --git a/src/rapids_singlecell/squidpy_gpu/_autocorr.py b/src/rapids_singlecell/squidpy_gpu/_autocorr.py index 1b1802b4..26f0f878 100644 --- a/src/rapids_singlecell/squidpy_gpu/_autocorr.py +++ b/src/rapids_singlecell/squidpy_gpu/_autocorr.py @@ -2,8 +2,7 @@ from typing import ( TYPE_CHECKING, - Literal, # < 3.8 - Sequence, + Literal, ) import cupy as cp @@ -18,6 +17,8 @@ from ._utils import _p_value_calc if TYPE_CHECKING: + from collections.abc import Sequence + from anndata import AnnData diff --git a/src/rapids_singlecell/squidpy_gpu/_ligrec.py b/src/rapids_singlecell/squidpy_gpu/_ligrec.py index a9c810c7..f671582e 100644 --- a/src/rapids_singlecell/squidpy_gpu/_ligrec.py +++ b/src/rapids_singlecell/squidpy_gpu/_ligrec.py @@ -1,12 +1,10 @@ from __future__ import annotations import math +from collections.abc import Iterable, Mapping, Sequence from itertools import product from typing import ( - Iterable, Literal, - Mapping, - Sequence, ) import cupy as cp diff --git a/src/rapids_singlecell/tools/_clustering.py b/src/rapids_singlecell/tools/_clustering.py index 895c1de7..7bd8ec01 100644 --- a/src/rapids_singlecell/tools/_clustering.py +++ b/src/rapids_singlecell/tools/_clustering.py @@ -1,7 +1,7 @@ from __future__ import annotations import warnings -from typing import TYPE_CHECKING, Sequence +from typing import TYPE_CHECKING import cudf import numpy as np @@ -11,6 +11,8 @@ from scanpy.tools._utils_clustering import rename_groups, restrict_adjacency if TYPE_CHECKING: + from collections.abc import Sequence + from anndata import AnnData from scipy import sparse diff --git a/src/rapids_singlecell/tools/_embedding_density.py b/src/rapids_singlecell/tools/_embedding_density.py index c6bc35c6..6b4d59bf 100644 --- a/src/rapids_singlecell/tools/_embedding_density.py +++ b/src/rapids_singlecell/tools/_embedding_density.py @@ -1,12 +1,14 @@ from __future__ import annotations import math -from typing import TYPE_CHECKING, Sequence +from typing import TYPE_CHECKING import cupy as cp import numpy as np if TYPE_CHECKING: + from collections.abc import Sequence + from anndata import AnnData diff --git a/src/rapids_singlecell/tools/_rank_gene_groups.py b/src/rapids_singlecell/tools/_rank_gene_groups.py index fbd79fbc..21d455c4 100644 --- a/src/rapids_singlecell/tools/_rank_gene_groups.py +++ b/src/rapids_singlecell/tools/_rank_gene_groups.py @@ -1,12 +1,14 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Iterable, Literal +from typing import TYPE_CHECKING, Literal import cupy as cp import numpy as np import pandas as pd if TYPE_CHECKING: + from collections.abc import Iterable + from anndata import AnnData @@ -103,7 +105,7 @@ def rank_genes_groups_logreg( # for clarity, rename variable if groups == "all" or groups is None: groups_order = "all" - elif isinstance(groups, (str, int)): + elif isinstance(groups, str | int): raise ValueError("Specify a sequence of groups") else: groups_order = list(groups) diff --git a/src/rapids_singlecell/tools/_score_genes.py b/src/rapids_singlecell/tools/_score_genes.py index 9a7535cb..5678de4e 100644 --- a/src/rapids_singlecell/tools/_score_genes.py +++ b/src/rapids_singlecell/tools/_score_genes.py @@ -13,8 +13,7 @@ from ._utils import _nan_mean if TYPE_CHECKING: - from collections.abc import Generator - from typing import Sequence + from collections.abc import Generator, Sequence from anndata import AnnData diff --git a/tests/test_get_anndata.py b/tests/test_get_anndata.py index 3c7731c3..4a0ea4f7 100644 --- a/tests/test_get_anndata.py +++ b/tests/test_get_anndata.py @@ -21,10 +21,10 @@ def test_utils(mtype): rsc.get.anndata_to_GPU(adata) rsc.preprocessing._utils._check_gpu_X(adata.X) rsc.get.anndata_to_CPU(adata) - assert isinstance(adata.X, (np.ndarray, csr_matrix, csc_matrix)) + assert isinstance(adata.X, np.ndarray | csr_matrix | csc_matrix) # check layers adata.layers["test"] = adata.X.copy() rsc.get.anndata_to_GPU(adata, convert_all=True) _check_gpu_X(adata.layers["test"]) rsc.get.anndata_to_CPU(adata, convert_all=True) - assert isinstance(adata.layers["test"], (np.ndarray, csr_matrix, csc_matrix)) + assert isinstance(adata.layers["test"], np.ndarray | csr_matrix | csc_matrix) diff --git a/tests/test_hvg.py b/tests/test_hvg.py index 4a3c3226..ff9ac523 100644 --- a/tests/test_hvg.py +++ b/tests/test_hvg.py @@ -264,8 +264,8 @@ def _check_pearson_hvg_columns(output_df, n_top_genes): assert np.nanmax(output_df["highly_variable_rank"].values) <= n_top_genes - 1 -@pytest.mark.parametrize("clip", [None, np.Inf, 30]) -@pytest.mark.parametrize("theta", [100, np.Inf]) +@pytest.mark.parametrize("clip", [None, np.inf, 30]) +@pytest.mark.parametrize("theta", [100, np.inf]) @pytest.mark.parametrize("n_top_genes", [100, 200]) @pytest.mark.parametrize("dtype", ["float32", "float64"]) @pytest.mark.parametrize("sparse", [True, False]) diff --git a/tests/test_ligrec.py b/tests/test_ligrec.py index a1d4bcd5..9c5b6828 100644 --- a/tests/test_ligrec.py +++ b/tests/test_ligrec.py @@ -1,9 +1,10 @@ from __future__ import annotations import pickle +from collections.abc import Sequence from itertools import product from pathlib import Path -from typing import TYPE_CHECKING, Sequence, Tuple +from typing import TYPE_CHECKING import numpy as np import pandas as pd @@ -16,8 +17,8 @@ HERE = Path(__file__).parent _CK = "leiden" -Interactions_t = Tuple[Sequence[str], Sequence[str]] -Complexes_t = Sequence[Tuple[str, str]] +Interactions_t = tuple[Sequence[str], Sequence[str]] +Complexes_t = Sequence[tuple[str, str]] @pytest.fixture() diff --git a/tests/test_normalization.py b/tests/test_normalization.py index f2fc171e..295d3089 100644 --- a/tests/test_normalization.py +++ b/tests/test_normalization.py @@ -41,8 +41,8 @@ def test_normalize_total_layers(dtype): "sparsity_func", [cp.array, csr_matrix], ids=lambda x: x.__name__ ) @pytest.mark.parametrize("dtype", [np.float32, np.float64]) -@pytest.mark.parametrize("theta", [0.01, 1.0, 100, np.Inf]) -@pytest.mark.parametrize("clip", [None, 1.0, np.Inf]) +@pytest.mark.parametrize("theta", [0.01, 1.0, 100, np.inf]) +@pytest.mark.parametrize("clip", [None, 1.0, np.inf]) def test_normalize_pearson_residuals_values(sparsity_func, dtype, theta, clip): # toy data X = cp.array([[3, 6], [2, 4], [1, 0]], dtype=dtype)