From c55949fc6ae5740550727c9a6b5f1d04570fa573 Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Thu, 25 Jun 2026 18:23:40 +0000 Subject: [PATCH 01/13] Pin Polars<1.43 --- conda/environments/all_cuda-129_arch-aarch64.yaml | 2 +- conda/environments/all_cuda-129_arch-x86_64.yaml | 2 +- conda/environments/all_cuda-133_arch-aarch64.yaml | 2 +- conda/environments/all_cuda-133_arch-x86_64.yaml | 2 +- conda/recipes/cudf-polars/recipe.yaml | 4 ++-- dependencies.yaml | 8 ++++++-- python/cudf_polars/pyproject.toml | 2 +- 7 files changed, 13 insertions(+), 9 deletions(-) diff --git a/conda/environments/all_cuda-129_arch-aarch64.yaml b/conda/environments/all_cuda-129_arch-aarch64.yaml index 84620d9b12ea..88ad92c49342 100644 --- a/conda/environments/all_cuda-129_arch-aarch64.yaml +++ b/conda/environments/all_cuda-129_arch-aarch64.yaml @@ -74,7 +74,7 @@ dependencies: - packaging - pandas>=3.0.0,<3.1.0 - pandoc -- polars>=1.35,<1.42 +- polars>=1.35,<1.43 - pre-commit - pyarrow>=19.0.0,<24 - pydata-sphinx-theme>=0.15.4 diff --git a/conda/environments/all_cuda-129_arch-x86_64.yaml b/conda/environments/all_cuda-129_arch-x86_64.yaml index 618dad2442a7..aa2f0849232d 100644 --- a/conda/environments/all_cuda-129_arch-x86_64.yaml +++ b/conda/environments/all_cuda-129_arch-x86_64.yaml @@ -74,7 +74,7 @@ dependencies: - packaging - pandas>=3.0.0,<3.1.0 - pandoc -- polars>=1.35,<1.42 +- polars>=1.35,<1.43 - pre-commit - pyarrow>=19.0.0,<24 - pydata-sphinx-theme>=0.15.4 diff --git a/conda/environments/all_cuda-133_arch-aarch64.yaml b/conda/environments/all_cuda-133_arch-aarch64.yaml index 0c247e6b10a1..a51cfdbb85f3 100644 --- a/conda/environments/all_cuda-133_arch-aarch64.yaml +++ b/conda/environments/all_cuda-133_arch-aarch64.yaml @@ -74,7 +74,7 @@ dependencies: - packaging - pandas>=3.0.0,<3.1.0 - pandoc -- polars>=1.35,<1.42 +- polars>=1.35,<1.43 - pre-commit - pyarrow>=19.0.0,<24 - pydata-sphinx-theme>=0.15.4 diff --git a/conda/environments/all_cuda-133_arch-x86_64.yaml b/conda/environments/all_cuda-133_arch-x86_64.yaml index 94cd3772c26d..9e31a2204601 100644 --- a/conda/environments/all_cuda-133_arch-x86_64.yaml +++ b/conda/environments/all_cuda-133_arch-x86_64.yaml @@ -74,7 +74,7 @@ dependencies: - packaging - pandas>=3.0.0,<3.1.0 - pandoc -- polars>=1.35,<1.42 +- polars>=1.35,<1.43 - pre-commit - pyarrow>=19.0.0,<24 - pydata-sphinx-theme>=0.15.4 diff --git a/conda/recipes/cudf-polars/recipe.yaml b/conda/recipes/cudf-polars/recipe.yaml index 12aa1e19f162..632f5547679c 100644 --- a/conda/recipes/cudf-polars/recipe.yaml +++ b/conda/recipes/cudf-polars/recipe.yaml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2018-2026, NVIDIA CORPORATION. +# SPDX-FileCopyrightText: Copyright (c) 2018-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 schema_version: 1 @@ -38,7 +38,7 @@ requirements: - pylibcudf =${{ version }} - rapidsmpf =${{ minor_version }} - cudf-streaming =${{ version }} - - polars>=1.35,<1.42 + - polars>=1.35,<1.43 - packaging - ${{ pin_compatible("cuda-version", upper_bound="x", lower_bound="x") }} - if: cuda_major == "12" diff --git a/dependencies.yaml b/dependencies.yaml index 01113fdba333..8d6fea9adc6e 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -589,7 +589,7 @@ files: test_cudf_polars_compat: output: none matrix: - polars_compat_version: ["1.35", "1.36", "1.37", "1.38", "1.39", "1.40", "1.41"] + polars_compat_version: ["1.35", "1.36", "1.37", "1.38", "1.39", "1.40", "1.41", "1.42"] includes: - test_cudf_polars_compat channels: @@ -969,7 +969,7 @@ dependencies: # 'nvidia-ml-py' provides the 'pynvml' module - &nvidia_ml_py nvidia-ml-py>=12 - packaging - - polars>=1.35,<1.42 + - polars>=1.35,<1.43 - typing_extensions>=4.0.0 run_cudf_polars_dask: common: @@ -1726,5 +1726,9 @@ dependencies: polars_compat_version: "1.41" packages: - polars==1.41.* + - matrix: + polars_compat_version: "1.42" + packages: + - polars==1.42.* - matrix: packages: diff --git a/python/cudf_polars/pyproject.toml b/python/cudf_polars/pyproject.toml index b4d8662c62db..41d21714bf89 100644 --- a/python/cudf_polars/pyproject.toml +++ b/python/cudf_polars/pyproject.toml @@ -25,7 +25,7 @@ dependencies = [ "cudf-streaming==26.8.*,>=0.0.0a0", "nvidia-ml-py>=12", "packaging", - "polars>=1.35,<1.42", + "polars>=1.35,<1.43", "pylibcudf==26.8.*,>=0.0.0a0", "rapidsmpf==26.8.*,>=0.0.0a0", "typing_extensions>=4.0.0", From 5bc2314da4f2012dc485b1a962bf714d69ac0683 Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Mon, 29 Jun 2026 18:40:48 +0000 Subject: [PATCH 02/13] compat IR --- .../cudf_polars/cudf_polars/dsl/translate.py | 20 +++++++++++++++---- .../cudf_polars/cudf_polars/utils/versions.py | 3 ++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/python/cudf_polars/cudf_polars/dsl/translate.py b/python/cudf_polars/cudf_polars/dsl/translate.py index d9f2b03c3f74..82c31f8c120b 100644 --- a/python/cudf_polars/cudf_polars/dsl/translate.py +++ b/python/cudf_polars/cudf_polars/dsl/translate.py @@ -38,6 +38,7 @@ POLARS_VERSION_LT_139, POLARS_VERSION_LT_140, POLARS_VERSION_LT_141, + POLARS_VERSION_LT_142, ) if TYPE_CHECKING: @@ -45,7 +46,7 @@ from polars import GPUEngine - from cudf_polars.typing import NodeTraverser + from cudf_polars.typing import NodeTraverser, Slice as Zlice __all__ = ["Translator", "translate_named_expr"] @@ -164,7 +165,7 @@ def translate_ir(self, *, n: int | None = None) -> ir.IR: # IR is versioned with major.minor, minor is bumped for backwards # compatible changes (e.g. adding new nodes), major is bumped for # incompatible changes (e.g. renaming nodes). - if (version := self.visitor.version()) >= (13, 1): + if (version := self.visitor.version()) >= (14, 4): e = NotImplementedError( f"No support for polars IR {version=}" ) # pragma: no cover; no such version for now. @@ -293,8 +294,14 @@ def _drop_dyn_pred_hints( node = translator.visitor.view_expression(n) except Exception as e: if str(e) == "dynamic_pred": - return None + return None # pragma: no cover raise # pragma: no cover + if ( + not POLARS_VERSION_LT_142 + and isinstance(node, plrs._expr_nodes.Function) + and node.function_data[0] == "dynamic_pred" + ): + return None if isinstance(node, plrs._expr_nodes.BinaryExpr) and node.op in ( plrs._expr_nodes.Operator.And, plrs._expr_nodes.Operator.LogicalAnd, @@ -629,7 +636,12 @@ def _(node: plrs._ir_nodes.Sort, translator: Translator, schema: Schema) -> ir.I order, null_order = sorting.sort_order( descending, nulls_last=nulls_last, num_keys=len(by) ) - return ir.Sort(schema, by, order, null_order, stable, node.slice, inp) + if not POLARS_VERSION_LT_142 and node.slice is not None: + offset, length, *_ = node.slice + zlice: Zlice | None = (offset, length) + else: + zlice = node.slice + return ir.Sort(schema, by, order, null_order, stable, zlice, inp) @_translate_ir.register diff --git a/python/cudf_polars/cudf_polars/utils/versions.py b/python/cudf_polars/cudf_polars/utils/versions.py index df564318aecd..3c74ef2cb298 100644 --- a/python/cudf_polars/cudf_polars/utils/versions.py +++ b/python/cudf_polars/cudf_polars/utils/versions.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 """Version utilities so that cudf_polars supports a range of polars versions.""" @@ -18,6 +18,7 @@ POLARS_VERSION_LT_139 = POLARS_VERSION < parse("1.39.0") POLARS_VERSION_LT_140 = POLARS_VERSION < parse("1.40.0") POLARS_VERSION_LT_141 = POLARS_VERSION < parse("1.41.0") +POLARS_VERSION_LT_142 = POLARS_VERSION < parse("1.42.0") def _ensure_polars_version() -> None: From e6887c6004462a33c9dfd898ccfdfef81c2d3b69 Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Mon, 29 Jun 2026 18:45:16 +0000 Subject: [PATCH 03/13] only polars CI --- .github/workflows/pr.yaml | 804 ++++++++++++++++++-------------------- 1 file changed, 391 insertions(+), 413 deletions(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 6748558938f4..e03a1c3df5cc 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -14,36 +14,14 @@ jobs: - check-nightly-ci - changed-files - checks - - cmake-tests - - conda-cpp-build - - cpp-linters - - conda-cpp-checks - - conda-cpp-tests - - conda-python-build - - conda-python-build-noarch - - conda-python-cudf-tests - - conda-python-other-tests - - conda-java-tests - - conda-notebook-tests - - docs-build - wheel-build-libcudf - wheel-build-libcudf-streaming - wheel-build-cudf-streaming - - wheel-tests-cudf-streaming - wheel-build-pylibcudf - - wheel-build-cudf - - wheel-tests-cudf - wheel-build-cudf-polars - wheel-tests-cudf-polars - cudf-polars-polars-tests - - wheel-build-dask-cudf - - wheel-tests-dask-cudf - - devcontainer - - unit-tests-cudf-pandas - - pandas-tests - - narwhals-tests - telemetry-setup - - third-party-integration-tests-cudf-pandas uses: rapidsai/shared-workflows/.github/workflows/pr-builder.yaml@main permissions: contents: read @@ -346,186 +324,186 @@ jobs: with: enable_check_generated_files: false ignored_pr_jobs: "telemetry-summarize spark-rapids-jni cuml-compat-tests" - conda-cpp-build: - needs: checks - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-build.yaml@main - with: - build_type: pull-request - node_type: cpu16 - script: ci/build_cpp.sh - cmake-tests: - needs: checks - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main - with: - build_type: pull-request - node_type: cpu16 - arch: "amd64" - container_image: "rapidsai/ci-conda:26.08-latest" - script: "ci/test_cmake.sh" - cpp-linters: - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - needs: checks - uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main - with: - build_type: pull-request - script: "ci/cpp_linters.sh" - conda-cpp-checks: - needs: conda-cpp-build - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-post-build-checks.yaml@main - with: - build_type: pull-request - package_name: libcudf - conda-cpp-tests: - needs: [conda-cpp-build, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-tests.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_cpp - with: - build_type: pull-request - script: ci/test_cpp.sh - conda-python-build: - needs: conda-cpp-build - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@main - with: - build_type: pull-request - script: ci/build_python.sh - # Build a conda package for each CUDA x ARCH x minimum supported Python version - matrix_filter: group_by({CUDA_VER, ARCH}) | map(min_by(.PY_VER | split(".") | map(tonumber))) - conda-python-build-noarch: - needs: [conda-cpp-build, conda-python-build] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@main - with: - build_type: pull-request - script: ci/build_python_noarch.sh - pure-conda: cuda_major - conda-python-cudf-tests: - needs: [conda-python-build, conda-python-build-noarch, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf - with: - build_type: pull-request - script: "ci/test_python_cudf.sh" - conda-python-other-tests: - # Tests for dask_cudf, cudf_polars, custreamz, cudf_kafka are separated for CI parallelism - needs: [conda-python-build-noarch, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda - with: - build_type: pull-request - # https://github.com/rapidsai/cudf/pull/22381/changes#r3196736965 - container-options: "--cap-add CAP_SYS_PTRACE --shm-size=8g --ulimit=nofile=1000000:1000000" - script: "ci/test_python_other.sh" - conda-java-tests: - needs: [conda-cpp-build, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_java - with: - build_type: pull-request - node_type: "gpu-l4-latest-1" - arch: "amd64" - container_image: "rapidsai/ci-conda:26.08-latest" - script: "ci/test_java.sh" - conda-notebook-tests: - needs: [conda-python-build, conda-python-build-noarch, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_notebooks - with: - build_type: pull-request - node_type: "gpu-l4-latest-1" - arch: "amd64" - container_image: "rapidsai/ci-conda:26.08-latest" - script: "ci/test_notebooks.sh" - docs-build: - needs: [conda-python-build, conda-python-build-noarch, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).build_docs - with: - build_type: pull-request - node_type: "gpu-l4-latest-1" - arch: "amd64" - container_image: "rapidsai/ci-conda:26.08-latest" - script: "ci/build_docs.sh" +# conda-cpp-build: +# needs: checks +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-build.yaml@main +# with: +# build_type: pull-request +# node_type: cpu16 +# script: ci/build_cpp.sh +# cmake-tests: +# needs: checks +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main +# with: +# build_type: pull-request +# node_type: cpu16 +# arch: "amd64" +# container_image: "rapidsai/ci-conda:26.08-latest" +# script: "ci/test_cmake.sh" +# cpp-linters: +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# needs: checks +# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main +# with: +# build_type: pull-request +# script: "ci/cpp_linters.sh" +# conda-cpp-checks: +# needs: conda-cpp-build +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-post-build-checks.yaml@main +# with: +# build_type: pull-request +# package_name: libcudf +# conda-cpp-tests: +# needs: [conda-cpp-build, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-tests.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_cpp +# with: +# build_type: pull-request +# script: ci/test_cpp.sh +# conda-python-build: +# needs: conda-cpp-build +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@main +# with: +# build_type: pull-request +# script: ci/build_python.sh +# # Build a conda package for each CUDA x ARCH x minimum supported Python version +# matrix_filter: group_by({CUDA_VER, ARCH}) | map(min_by(.PY_VER | split(".") | map(tonumber))) +# conda-python-build-noarch: +# needs: [conda-cpp-build, conda-python-build] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@main +# with: +# build_type: pull-request +# script: ci/build_python_noarch.sh +# pure-conda: cuda_major +# conda-python-cudf-tests: +# needs: [conda-python-build, conda-python-build-noarch, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf +# with: +# build_type: pull-request +# script: "ci/test_python_cudf.sh" +# conda-python-other-tests: +# # Tests for dask_cudf, cudf_polars, custreamz, cudf_kafka are separated for CI parallelism +# needs: [conda-python-build-noarch, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda +# with: +# build_type: pull-request +# # https://github.com/rapidsai/cudf/pull/22381/changes#r3196736965 +# container-options: "--cap-add CAP_SYS_PTRACE --shm-size=8g --ulimit=nofile=1000000:1000000" +# script: "ci/test_python_other.sh" +# conda-java-tests: +# needs: [conda-cpp-build, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_java +# with: +# build_type: pull-request +# node_type: "gpu-l4-latest-1" +# arch: "amd64" +# container_image: "rapidsai/ci-conda:26.08-latest" +# script: "ci/test_java.sh" +# conda-notebook-tests: +# needs: [conda-python-build, conda-python-build-noarch, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_notebooks +# with: +# build_type: pull-request +# node_type: "gpu-l4-latest-1" +# arch: "amd64" +# container_image: "rapidsai/ci-conda:26.08-latest" +# script: "ci/test_notebooks.sh" +# docs-build: +# needs: [conda-python-build, conda-python-build-noarch, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).build_docs +# with: +# build_type: pull-request +# node_type: "gpu-l4-latest-1" +# arch: "amd64" +# container_image: "rapidsai/ci-conda:26.08-latest" +# script: "ci/build_docs.sh" wheel-build-libcudf: needs: checks permissions: @@ -580,20 +558,20 @@ jobs: script: "ci/build_wheel_cudf_streaming.sh" package-name: cudf_streaming package-type: python - wheel-tests-cudf-streaming: - needs: [wheel-build-cudf-streaming, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels - with: - build_type: pull-request - script: ci/test_wheel_cudf_streaming.sh +# wheel-tests-cudf-streaming: +# needs: [wheel-build-cudf-streaming, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels +# with: +# build_type: pull-request +# script: ci/test_wheel_cudf_streaming.sh wheel-build-pylibcudf: needs: [checks, wheel-build-libcudf] permissions: @@ -612,38 +590,38 @@ jobs: package-type: python # Build a wheel for each CUDA x ARCH x minimum supported Python version matrix_filter: group_by({CUDA_VER, ARCH}) | map(min_by(.PY_VER | split(".") | map(tonumber))) - wheel-build-cudf: - needs: wheel-build-pylibcudf - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main - with: - build_type: pull-request - node_type: cpu8 - script: "ci/build_wheel_cudf.sh" - package-name: cudf - package-type: python - # Build a wheel for each CUDA x ARCH x minimum supported Python version - matrix_filter: group_by({CUDA_VER, ARCH}) | map(min_by(.PY_VER | split(".") | map(tonumber))) - wheel-tests-cudf: - needs: [wheel-build-cudf, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf - with: - build_type: pull-request - script: ci/test_wheel_cudf.sh +# wheel-build-cudf: +# needs: wheel-build-pylibcudf +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main +# with: +# build_type: pull-request +# node_type: cpu8 +# script: "ci/build_wheel_cudf.sh" +# package-name: cudf +# package-type: python +# # Build a wheel for each CUDA x ARCH x minimum supported Python version +# matrix_filter: group_by({CUDA_VER, ARCH}) | map(min_by(.PY_VER | split(".") | map(tonumber))) +# wheel-tests-cudf: +# needs: [wheel-build-cudf, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf +# with: +# build_type: pull-request +# script: ci/test_wheel_cudf.sh wheel-build-cudf-polars: needs: wheel-build-pylibcudf permissions: @@ -696,171 +674,171 @@ jobs: matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) build_type: pull-request script: "ci/test_cudf_polars_polars_tests.sh" - wheel-build-dask-cudf: - needs: wheel-build-cudf - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main - with: - # This selects "ARCH=amd64 + the latest supported Python + CUDA". - matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) - build_type: pull-request - node_type: cpu8 - script: "ci/build_wheel_dask_cudf.sh" - package-name: dask_cudf - package-type: python - pure-wheel: true - wheel-tests-dask-cudf: - needs: [wheel-build-dask-cudf, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels && fromJSON(needs.changed-files.outputs.changed_file_groups).not_cudf_polars - with: - # This selects "ARCH=amd64 + the latest supported Python + CUDA". - matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) - build_type: pull-request - script: ci/test_wheel_dask_cudf.sh - # build cudf with benchmarks but disable for cudf_streaming since we can't use MPI/UCX in wheel-based builds - devcontainer: - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - needs: telemetry-setup - uses: rapidsai/shared-workflows/.github/workflows/build-in-devcontainer.yaml@main - with: - arch: '["amd64", "arm64"]' - cuda: '["13.3"]' - node_type: "cpu8" - timeout-minutes: 90 - env: | - SCCACHE_DIST_MAX_RETRIES=inf - SCCACHE_SERVER_LOG=sccache=debug - SCCACHE_DIST_FALLBACK_TO_LOCAL_COMPILE=false - build_command: | - sccache --zero-stats; - build-all -j0 --verbose -DBUILD_BENCHMARKS=ON 2>&1 | tee telemetry-artifacts/build.log; - sccache --show-adv-stats | tee telemetry-artifacts/sccache-stats.txt; - unit-tests-cudf-pandas: - needs: [wheel-build-cudf, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main - if: (fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels || fromJSON(needs.changed-files.outputs.changed_file_groups).test_cudf_pandas) && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf - with: - # This selects the latest supported Python + CUDA minor versions for each ARCH/CUDA major version combo - matrix_filter: group_by([(.ARCH), (.CUDA_VER|split(".")|map(tonumber)|.[0])]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) - build_type: pull-request - script: ci/cudf_pandas_scripts/run_tests.sh - third-party-integration-tests-cudf-pandas: - needs: [conda-python-build, conda-python-build-noarch, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cpp_nor_cudf_polars_nor_dask_cudf - with: - build_type: pull-request - branch: ${{ inputs.branch }} - date: ${{ inputs.date }} - sha: ${{ inputs.sha }} - node_type: "gpu-l4-latest-1" - continue-on-error: true - container_image: "rapidsai/ci-conda:26.08-latest" - script: | - ci/cudf_pandas_scripts/third-party-integration/test.sh python/cudf/cudf_pandas_tests/third_party_integration_tests/dependencies.yaml - cuml-compat-tests: - needs: [conda-python-build, conda-python-build-noarch, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf - with: - build_type: pull-request - branch: ${{ inputs.branch }} - date: ${{ inputs.date }} - sha: ${{ inputs.sha }} - node_type: "gpu-l4-latest-1" - continue-on-error: true - container_image: "rapidsai/ci-conda:26.06-latest" - script: "ci/test_cuml_compat.sh" - pandas-tests: - # run the Pandas unit tests using PR branch - needs: [wheel-build-cudf, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cpp_nor_cudf_polars_nor_dask_cudf - with: - build_type: pull-request - branch: ${{ inputs.branch }} - date: ${{ inputs.date }} - sha: ${{ inputs.sha }} - node_type: "gpu-l4-latest-1" - container_image: "rapidsai/citestwheel:26.08-latest" - script: ci/cudf_pandas_scripts/pandas-tests/run.sh pr - narwhals-tests: - needs: [conda-python-build, conda-python-build-noarch, changed-files] - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - secrets: inherit # zizmor: ignore[secrets-inherit] - uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cpp_nor_cudf_polars_nor_dask_cudf - with: - build_type: pull-request - branch: ${{ inputs.branch }} - date: ${{ inputs.date }} - sha: ${{ inputs.sha }} - node_type: "gpu-l4-latest-1" - container_image: "rapidsai/ci-conda:26.08-latest" - script: ci/test_narwhals.sh - spark-rapids-jni: - needs: changed-files - permissions: - actions: read - contents: read - id-token: write - packages: read - pull-requests: read - uses: ./.github/workflows/spark-rapids-jni.yaml - if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_java +# wheel-build-dask-cudf: +# needs: wheel-build-cudf +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main +# with: +# # This selects "ARCH=amd64 + the latest supported Python + CUDA". +# matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) +# build_type: pull-request +# node_type: cpu8 +# script: "ci/build_wheel_dask_cudf.sh" +# package-name: dask_cudf +# package-type: python +# pure-wheel: true +# wheel-tests-dask-cudf: +# needs: [wheel-build-dask-cudf, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels && fromJSON(needs.changed-files.outputs.changed_file_groups).not_cudf_polars +# with: +# # This selects "ARCH=amd64 + the latest supported Python + CUDA". +# matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) +# build_type: pull-request +# script: ci/test_wheel_dask_cudf.sh +# # build cudf with benchmarks but disable for cudf_streaming since we can't use MPI/UCX in wheel-based builds +# devcontainer: +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# needs: telemetry-setup +# uses: rapidsai/shared-workflows/.github/workflows/build-in-devcontainer.yaml@main +# with: +# arch: '["amd64", "arm64"]' +# cuda: '["13.3"]' +# node_type: "cpu8" +# timeout-minutes: 90 +# env: | +# SCCACHE_DIST_MAX_RETRIES=inf +# SCCACHE_SERVER_LOG=sccache=debug +# SCCACHE_DIST_FALLBACK_TO_LOCAL_COMPILE=false +# build_command: | +# sccache --zero-stats; +# build-all -j0 --verbose -DBUILD_BENCHMARKS=ON 2>&1 | tee telemetry-artifacts/build.log; +# sccache --show-adv-stats | tee telemetry-artifacts/sccache-stats.txt; +# unit-tests-cudf-pandas: +# needs: [wheel-build-cudf, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main +# if: (fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels || fromJSON(needs.changed-files.outputs.changed_file_groups).test_cudf_pandas) && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf +# with: +# # This selects the latest supported Python + CUDA minor versions for each ARCH/CUDA major version combo +# matrix_filter: group_by([(.ARCH), (.CUDA_VER|split(".")|map(tonumber)|.[0])]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) +# build_type: pull-request +# script: ci/cudf_pandas_scripts/run_tests.sh +# third-party-integration-tests-cudf-pandas: +# needs: [conda-python-build, conda-python-build-noarch, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cpp_nor_cudf_polars_nor_dask_cudf +# with: +# build_type: pull-request +# branch: ${{ inputs.branch }} +# date: ${{ inputs.date }} +# sha: ${{ inputs.sha }} +# node_type: "gpu-l4-latest-1" +# continue-on-error: true +# container_image: "rapidsai/ci-conda:26.08-latest" +# script: | +# ci/cudf_pandas_scripts/third-party-integration/test.sh python/cudf/cudf_pandas_tests/third_party_integration_tests/dependencies.yaml +# cuml-compat-tests: +# needs: [conda-python-build, conda-python-build-noarch, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf +# with: +# build_type: pull-request +# branch: ${{ inputs.branch }} +# date: ${{ inputs.date }} +# sha: ${{ inputs.sha }} +# node_type: "gpu-l4-latest-1" +# continue-on-error: true +# container_image: "rapidsai/ci-conda:26.06-latest" +# script: "ci/test_cuml_compat.sh" +# pandas-tests: +# # run the Pandas unit tests using PR branch +# needs: [wheel-build-cudf, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cpp_nor_cudf_polars_nor_dask_cudf +# with: +# build_type: pull-request +# branch: ${{ inputs.branch }} +# date: ${{ inputs.date }} +# sha: ${{ inputs.sha }} +# node_type: "gpu-l4-latest-1" +# container_image: "rapidsai/citestwheel:26.08-latest" +# script: ci/cudf_pandas_scripts/pandas-tests/run.sh pr +# narwhals-tests: +# needs: [conda-python-build, conda-python-build-noarch, changed-files] +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# secrets: inherit # zizmor: ignore[secrets-inherit] +# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cpp_nor_cudf_polars_nor_dask_cudf +# with: +# build_type: pull-request +# branch: ${{ inputs.branch }} +# date: ${{ inputs.date }} +# sha: ${{ inputs.sha }} +# node_type: "gpu-l4-latest-1" +# container_image: "rapidsai/ci-conda:26.08-latest" +# script: ci/test_narwhals.sh +# spark-rapids-jni: +# needs: changed-files +# permissions: +# actions: read +# contents: read +# id-token: write +# packages: read +# pull-requests: read +# uses: ./.github/workflows/spark-rapids-jni.yaml +# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_java telemetry-summarize: # This job must use a self-hosted runner to record telemetry traces. runs-on: linux-amd64-cpu4 From 5bb9a569bc3bf1053fd31b1c6bba1cac9dc09cee Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Mon, 29 Jun 2026 20:19:22 +0000 Subject: [PATCH 04/13] fix xpass'ing tests and implemented is_sorted boolean expr --- .../cudf_polars/dsl/expressions/boolean.py | 22 +++++++++++++++++++ .../tests/dsl/test_serialization.py | 8 ++++++- python/cudf_polars/tests/test_scan.py | 4 +++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/python/cudf_polars/cudf_polars/dsl/expressions/boolean.py b/python/cudf_polars/cudf_polars/dsl/expressions/boolean.py index 93859947b425..374e79175b4c 100644 --- a/python/cudf_polars/cudf_polars/dsl/expressions/boolean.py +++ b/python/cudf_polars/cudf_polars/dsl/expressions/boolean.py @@ -65,6 +65,7 @@ class Name(IntEnum): IsNotNan = auto() IsNotNull = auto() IsNull = auto() + IsSorted = auto() IsUnique = auto() Not = auto() @@ -100,6 +101,7 @@ def __init__( BooleanFunction.Name.IsDuplicated, BooleanFunction.Name.IsFirstDistinct, BooleanFunction.Name.IsLastDistinct, + BooleanFunction.Name.IsSorted, BooleanFunction.Name.IsUnique, ) if self.name in { @@ -409,6 +411,26 @@ def do_evaluate( ), dtype=self.dtype, ) + elif self.name is BooleanFunction.Name.IsSorted: + (column,) = columns + (descending, nulls_last) = self.options + order = ( + plc.types.Order.DESCENDING if descending else plc.types.Order.ASCENDING + ) + null_order = ( + plc.types.NullOrder.AFTER if nulls_last else plc.types.NullOrder.BEFORE + ) + result = plc.sorting.is_sorted( + plc.Table([column.obj]), [order], [null_order], stream=df.stream + ) + return Column( + plc.Column.from_scalar( + plc.Scalar.from_py(py_val=result, stream=df.stream), + 1, + stream=df.stream, + ), + dtype=self.dtype, + ) elif self.name is BooleanFunction.Name.Not: (column,) = columns # Polars semantics: diff --git a/python/cudf_polars/tests/dsl/test_serialization.py b/python/cudf_polars/tests/dsl/test_serialization.py index a845b106ea70..2cad17324682 100644 --- a/python/cudf_polars/tests/dsl/test_serialization.py +++ b/python/cudf_polars/tests/dsl/test_serialization.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 from __future__ import annotations @@ -16,6 +16,7 @@ from cudf_polars.utils.versions import ( POLARS_VERSION_LT_138, POLARS_VERSION_LT_141, + POLARS_VERSION_LT_142, ) @@ -57,6 +58,9 @@ def test_from_polars_all_names(function): if POLARS_VERSION_LT_141 and function == BooleanFunction: # 'HasNulls' and 'IsEmpty' were added to polars' BooleanFunction in 1.41. cudf_polars_names_set = cudf_polars_names_set - {"HasNulls", "IsEmpty"} + if POLARS_VERSION_LT_142 and function == BooleanFunction: + # 'IsSorted' was added to polars' BooleanFunction in 1.42. + cudf_polars_names_set = cudf_polars_names_set - {"IsSorted"} assert polars_names_set == cudf_polars_names_set names = function.Name if function == StructFunction: @@ -71,6 +75,8 @@ def test_from_polars_all_names(function): BooleanFunction.Name.HasNulls, BooleanFunction.Name.IsEmpty, } + if POLARS_VERSION_LT_142 and function == BooleanFunction: + names = set(names) - {BooleanFunction.Name.IsSorted} for name in names: attr = getattr(polars_function, name.name) assert function.Name.from_polars(attr) == name diff --git a/python/cudf_polars/tests/test_scan.py b/python/cudf_polars/tests/test_scan.py index 7a9a4f2bb10f..daaffdda78b6 100644 --- a/python/cudf_polars/tests/test_scan.py +++ b/python/cudf_polars/tests/test_scan.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 from __future__ import annotations @@ -25,6 +25,7 @@ from cudf_polars.utils.versions import ( POLARS_VERSION_LT_138, POLARS_VERSION_LT_139, + POLARS_VERSION_LT_142, ) if TYPE_CHECKING: @@ -532,6 +533,7 @@ def test_scan_with_row_index(engine: pl.GPUEngine, tmp_path: Path) -> None: pytest.param( "foo=bar", marks=pytest.mark.xfail( + condition=POLARS_VERSION_LT_142, reason="https://github.com/pola-rs/polars/issues/27840", strict=True, ), From 950fe2a02756a9ad9eb00300771a8df371e6ba38 Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Mon, 29 Jun 2026 22:19:47 +0000 Subject: [PATCH 05/13] fallback for hive-partitioned scans, skip upstream polars tests --- python/cudf_polars/cudf_polars/dsl/translate.py | 2 ++ python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/python/cudf_polars/cudf_polars/dsl/translate.py b/python/cudf_polars/cudf_polars/dsl/translate.py index 82c31f8c120b..f6c19163a1cf 100644 --- a/python/cudf_polars/cudf_polars/dsl/translate.py +++ b/python/cudf_polars/cudf_polars/dsl/translate.py @@ -394,6 +394,8 @@ def _(node: plrs._ir_nodes.Scan, translator: Translator, schema: Schema) -> ir.I raise NotImplementedError( "Iceberg format is not supported in cudf-polars. Furthermore, row-level deletions are not supported." ) # pragma: no cover + if not POLARS_VERSION_LT_142 and node.hive_parts is not None: + raise NotImplementedError("Hive-partitioned scans are not supported") config_options = translator.config_options parquet_options = config_options.parquet_options diff --git a/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py b/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py index 6a1b5748bc5c..fca2b1e0acb1 100644 --- a/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py +++ b/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py @@ -151,7 +151,7 @@ def pytest_report_header(config: pytest.Config) -> str: "tests/unit/io/test_iceberg.py::test_scan_iceberg_nested_column_cast_deletion_rename": "Iceberg column_mapping (schema evolution) not yet implemented in cudf-polars", "tests/unit/io/test_iceberg.py::test_scan_iceberg_parquet_prefilter_with_column_mapping": "Iceberg column_mapping (schema evolution) not yet implemented in cudf-polars", "tests/unit/io/test_iceberg.py::test_fill_missing_fields_with_identity_partition_values_nested": "Iceberg partition column injection not yet implemented in cudf-polars", - "tests/unit/io/test_iceberg.py::test_scan_iceberg_fast_count": "Iceberg support not yet implemented in cudf-polars", + "tests/unit/io/test_iceberg.py::test_scan_iceberg_fast_count[native]": "Iceberg fast count from metadata not yet supported in cudf-polars", "tests/unit/io/test_iceberg.py::test_iceberg_filter_bool_26474": "Iceberg support not yet implemented in cudf-polars", "tests/unit/io/test_lazy_count_star.py::test_count_parquet[small.parquet-4]": "Debug output on stderr doesn't match", "tests/unit/io/test_lazy_count_star.py::test_count_parquet[foods*.parquet-54]": "Debug output on stderr doesn't match", @@ -246,6 +246,7 @@ def pytest_report_header(config: pytest.Config) -> str: "tests/unit/sql/test_cast.py::test_cast_errors[values2-values::int1-conversion from `i64` to `i8` failed]": "Casting that raises not supported on GPU", "tests/unit/sql/test_cast.py::test_cast_errors[values5-values::int4-conversion from `str` to `i32` failed]": "Cast raises, but error user receives is wrong", "tests/unit/lazyframe/test_predicates.py::test_predicate_pushdown_split_pushable": "Casting that raises not supported on GPU", + "tests/unit/lazyframe/test_predicates.py::test_filter_contradiction_fallible_error_handling": "Casting that raises not supported on GPU", "tests/unit/sql/test_miscellaneous.py::test_read_csv": "Incorrect handling of missing_is_null in read_csv", "tests/unit/lazyframe/test_cse.py::test_cse_predicate_self_join[False]": "Debug output on stderr doesn't match", "tests/unit/io/test_scan_row_deletion.py::test_scan_row_deletion_skips_file_with_all_rows_deleted": "The test intentionally corrupts the parquet file, so we cannot read the row count from the header.", From 93434d62c88213fe6a52c7ddaa0054d6e6e4aae5 Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Mon, 29 Jun 2026 22:52:24 +0000 Subject: [PATCH 06/13] unpin polars version in pre-commit and a test for boolean is_sorted --- .pre-commit-config.yaml | 2 +- .../cudf_polars/containers/dataframe.py | 2 +- .../cudf_polars/dsl/expressions/boolean.py | 4 +-- .../tests/expressions/test_booleanfunction.py | 32 ++++++++++++++++++- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fc09522bd478..35aaccc112f4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -39,7 +39,7 @@ repos: hooks: - id: mypy additional_dependencies: [ - "polars>=1.35,<1.39", + "polars>=1.35,<1.43", "numpy>=1.26", "pyarrow-stubs>=19.0", "pyarrow>=19.0.0,<24.0.0", # https://github.com/rapidsai/cudf/issues/22229 diff --git a/python/cudf_polars/cudf_polars/containers/dataframe.py b/python/cudf_polars/cudf_polars/containers/dataframe.py index d9cae1d6e38b..ad75a8fde151 100644 --- a/python/cudf_polars/cudf_polars/containers/dataframe.py +++ b/python/cudf_polars/cudf_polars/containers/dataframe.py @@ -73,7 +73,7 @@ def __init__( self.stream = stream def __arrow_c_array__( - self, requested_schema: None = None + self, requested_schema: object | None = None ) -> tuple[CapsuleType, CapsuleType]: return self.obj._to_schema(self.metadata), self.obj._to_host_array( stream=self.stream diff --git a/python/cudf_polars/cudf_polars/dsl/expressions/boolean.py b/python/cudf_polars/cudf_polars/dsl/expressions/boolean.py index 374e79175b4c..d08d95a9616d 100644 --- a/python/cudf_polars/cudf_polars/dsl/expressions/boolean.py +++ b/python/cudf_polars/cudf_polars/dsl/expressions/boolean.py @@ -420,12 +420,12 @@ def do_evaluate( null_order = ( plc.types.NullOrder.AFTER if nulls_last else plc.types.NullOrder.BEFORE ) - result = plc.sorting.is_sorted( + bool_result = plc.sorting.is_sorted( plc.Table([column.obj]), [order], [null_order], stream=df.stream ) return Column( plc.Column.from_scalar( - plc.Scalar.from_py(py_val=result, stream=df.stream), + plc.Scalar.from_py(py_val=bool_result, stream=df.stream), 1, stream=df.stream, ), diff --git a/python/cudf_polars/tests/expressions/test_booleanfunction.py b/python/cudf_polars/tests/expressions/test_booleanfunction.py index 294063eb3080..64ca99584c53 100644 --- a/python/cudf_polars/tests/expressions/test_booleanfunction.py +++ b/python/cudf_polars/tests/expressions/test_booleanfunction.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 from __future__ import annotations @@ -12,6 +12,7 @@ assert_gpu_result_equal, assert_ir_translation_raises, ) +from cudf_polars.utils.versions import POLARS_VERSION_LT_142 if TYPE_CHECKING: from collections.abc import Callable @@ -294,6 +295,35 @@ def test_boolean_not_with_integers(engine: pl.GPUEngine, dtype, col): assert_gpu_result_equal(q, engine=engine) +@pytest.mark.skipif( + POLARS_VERSION_LT_142, reason="IsSorted BooleanFunction was added in polars 1.42" +) +@pytest.mark.parametrize("descending", [False, True]) +@pytest.mark.parametrize("nulls_last", [False, True]) +def test_boolean_is_sorted( + engine: pl.GPUEngine, *, descending: bool, nulls_last: bool, has_nulls: bool +) -> None: + values: list[int | None] = [1, 2, 3, 4, 5] + if has_nulls: + values[2] = None + + ldf = pl.LazyFrame( + { + "asc": pl.Series(values, dtype=pl.Int64()), + "desc": pl.Series(list(reversed(values)), dtype=pl.Int64()), + "unsorted": pl.Series([3, 1, None, 4, 2], dtype=pl.Int64()), + } + ) + + q = ldf.select( + pl.col("asc").is_sorted(descending=descending, nulls_last=nulls_last), + pl.col("desc").is_sorted(descending=descending, nulls_last=nulls_last), + pl.col("unsorted").is_sorted(descending=descending, nulls_last=nulls_last), + ) + + assert_gpu_result_equal(q, engine=engine) + + @pytest.mark.parametrize( "expr", [ From 1ad3e5ff47ec83a6e5ecfea72b698753246ce76f Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Tue, 30 Jun 2026 00:45:54 +0000 Subject: [PATCH 07/13] code coverage :( --- python/cudf_polars/cudf_polars/dsl/translate.py | 6 +++--- python/cudf_polars/tests/test_scan.py | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/python/cudf_polars/cudf_polars/dsl/translate.py b/python/cudf_polars/cudf_polars/dsl/translate.py index f6c19163a1cf..de6436140566 100644 --- a/python/cudf_polars/cudf_polars/dsl/translate.py +++ b/python/cudf_polars/cudf_polars/dsl/translate.py @@ -292,10 +292,10 @@ def _drop_dyn_pred_hints( ) -> expr.Expr | None: try: node = translator.visitor.view_expression(n) - except Exception as e: + except Exception as e: # pragma: no cover if str(e) == "dynamic_pred": - return None # pragma: no cover - raise # pragma: no cover + return None + raise if ( not POLARS_VERSION_LT_142 and isinstance(node, plrs._expr_nodes.Function) diff --git a/python/cudf_polars/tests/test_scan.py b/python/cudf_polars/tests/test_scan.py index daaffdda78b6..ccbd68050588 100644 --- a/python/cudf_polars/tests/test_scan.py +++ b/python/cudf_polars/tests/test_scan.py @@ -814,3 +814,16 @@ def test_scan_parquet_is_between_literal_dtype_mismatch_22622( ) assert_gpu_result_equal(q, engine=engine) + + +@pytest.mark.skipif( + POLARS_VERSION_LT_142, + reason="hive::HivePartitionedDf not exposed in the logical plan before 1.42", +) +def test_scan_parquet_hive_partitioned_raises( + engine: pl.GPUEngine, tmp_path: Path +) -> None: + (tmp_path / "part=1").mkdir() + pl.DataFrame({"x": [1, 2, 3]}).write_parquet(tmp_path / "part=1" / "data.parquet") + q = pl.scan_parquet(tmp_path, hive_schema={"part": pl.Int32}) + assert_ir_translation_raises(q, engine, NotImplementedError) From 6c041a4bf62f6c7f6ba035fb9b1455f1e641e99b Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Tue, 30 Jun 2026 19:08:05 +0000 Subject: [PATCH 08/13] temp test all versions --- .github/workflows/pr.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index e03a1c3df5cc..1a783b0cb885 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -657,7 +657,7 @@ jobs: matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) build_type: pull-request container-options: "--cap-add CAP_SYS_PTRACE --shm-size=8g --ulimit=nofile=1000000:1000000" - script: "env POLARS_VERSIONS=endpoints ci/test_wheel_cudf_polars.sh" + script: "ci/test_wheel_cudf_polars.sh" cudf-polars-polars-tests: needs: [wheel-build-cudf-polars, wheel-build-cudf-streaming, changed-files] permissions: From 7bb624f377dfdde1bf1a74719b91c2f31d1e4eb9 Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Tue, 30 Jun 2026 19:46:09 +0000 Subject: [PATCH 09/13] add dyn pred comment and revert polars only CI --- .github/workflows/pr.yaml | 806 +++++++++--------- .../cudf_polars/cudf_polars/dsl/translate.py | 5 + 2 files changed, 419 insertions(+), 392 deletions(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 1a783b0cb885..6748558938f4 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -14,14 +14,36 @@ jobs: - check-nightly-ci - changed-files - checks + - cmake-tests + - conda-cpp-build + - cpp-linters + - conda-cpp-checks + - conda-cpp-tests + - conda-python-build + - conda-python-build-noarch + - conda-python-cudf-tests + - conda-python-other-tests + - conda-java-tests + - conda-notebook-tests + - docs-build - wheel-build-libcudf - wheel-build-libcudf-streaming - wheel-build-cudf-streaming + - wheel-tests-cudf-streaming - wheel-build-pylibcudf + - wheel-build-cudf + - wheel-tests-cudf - wheel-build-cudf-polars - wheel-tests-cudf-polars - cudf-polars-polars-tests + - wheel-build-dask-cudf + - wheel-tests-dask-cudf + - devcontainer + - unit-tests-cudf-pandas + - pandas-tests + - narwhals-tests - telemetry-setup + - third-party-integration-tests-cudf-pandas uses: rapidsai/shared-workflows/.github/workflows/pr-builder.yaml@main permissions: contents: read @@ -324,186 +346,186 @@ jobs: with: enable_check_generated_files: false ignored_pr_jobs: "telemetry-summarize spark-rapids-jni cuml-compat-tests" -# conda-cpp-build: -# needs: checks -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-build.yaml@main -# with: -# build_type: pull-request -# node_type: cpu16 -# script: ci/build_cpp.sh -# cmake-tests: -# needs: checks -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main -# with: -# build_type: pull-request -# node_type: cpu16 -# arch: "amd64" -# container_image: "rapidsai/ci-conda:26.08-latest" -# script: "ci/test_cmake.sh" -# cpp-linters: -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# needs: checks -# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main -# with: -# build_type: pull-request -# script: "ci/cpp_linters.sh" -# conda-cpp-checks: -# needs: conda-cpp-build -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-post-build-checks.yaml@main -# with: -# build_type: pull-request -# package_name: libcudf -# conda-cpp-tests: -# needs: [conda-cpp-build, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-tests.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_cpp -# with: -# build_type: pull-request -# script: ci/test_cpp.sh -# conda-python-build: -# needs: conda-cpp-build -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@main -# with: -# build_type: pull-request -# script: ci/build_python.sh -# # Build a conda package for each CUDA x ARCH x minimum supported Python version -# matrix_filter: group_by({CUDA_VER, ARCH}) | map(min_by(.PY_VER | split(".") | map(tonumber))) -# conda-python-build-noarch: -# needs: [conda-cpp-build, conda-python-build] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@main -# with: -# build_type: pull-request -# script: ci/build_python_noarch.sh -# pure-conda: cuda_major -# conda-python-cudf-tests: -# needs: [conda-python-build, conda-python-build-noarch, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf -# with: -# build_type: pull-request -# script: "ci/test_python_cudf.sh" -# conda-python-other-tests: -# # Tests for dask_cudf, cudf_polars, custreamz, cudf_kafka are separated for CI parallelism -# needs: [conda-python-build-noarch, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda -# with: -# build_type: pull-request -# # https://github.com/rapidsai/cudf/pull/22381/changes#r3196736965 -# container-options: "--cap-add CAP_SYS_PTRACE --shm-size=8g --ulimit=nofile=1000000:1000000" -# script: "ci/test_python_other.sh" -# conda-java-tests: -# needs: [conda-cpp-build, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_java -# with: -# build_type: pull-request -# node_type: "gpu-l4-latest-1" -# arch: "amd64" -# container_image: "rapidsai/ci-conda:26.08-latest" -# script: "ci/test_java.sh" -# conda-notebook-tests: -# needs: [conda-python-build, conda-python-build-noarch, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_notebooks -# with: -# build_type: pull-request -# node_type: "gpu-l4-latest-1" -# arch: "amd64" -# container_image: "rapidsai/ci-conda:26.08-latest" -# script: "ci/test_notebooks.sh" -# docs-build: -# needs: [conda-python-build, conda-python-build-noarch, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).build_docs -# with: -# build_type: pull-request -# node_type: "gpu-l4-latest-1" -# arch: "amd64" -# container_image: "rapidsai/ci-conda:26.08-latest" -# script: "ci/build_docs.sh" + conda-cpp-build: + needs: checks + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-build.yaml@main + with: + build_type: pull-request + node_type: cpu16 + script: ci/build_cpp.sh + cmake-tests: + needs: checks + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main + with: + build_type: pull-request + node_type: cpu16 + arch: "amd64" + container_image: "rapidsai/ci-conda:26.08-latest" + script: "ci/test_cmake.sh" + cpp-linters: + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + needs: checks + uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main + with: + build_type: pull-request + script: "ci/cpp_linters.sh" + conda-cpp-checks: + needs: conda-cpp-build + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-post-build-checks.yaml@main + with: + build_type: pull-request + package_name: libcudf + conda-cpp-tests: + needs: [conda-cpp-build, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-tests.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_cpp + with: + build_type: pull-request + script: ci/test_cpp.sh + conda-python-build: + needs: conda-cpp-build + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@main + with: + build_type: pull-request + script: ci/build_python.sh + # Build a conda package for each CUDA x ARCH x minimum supported Python version + matrix_filter: group_by({CUDA_VER, ARCH}) | map(min_by(.PY_VER | split(".") | map(tonumber))) + conda-python-build-noarch: + needs: [conda-cpp-build, conda-python-build] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@main + with: + build_type: pull-request + script: ci/build_python_noarch.sh + pure-conda: cuda_major + conda-python-cudf-tests: + needs: [conda-python-build, conda-python-build-noarch, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf + with: + build_type: pull-request + script: "ci/test_python_cudf.sh" + conda-python-other-tests: + # Tests for dask_cudf, cudf_polars, custreamz, cudf_kafka are separated for CI parallelism + needs: [conda-python-build-noarch, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda + with: + build_type: pull-request + # https://github.com/rapidsai/cudf/pull/22381/changes#r3196736965 + container-options: "--cap-add CAP_SYS_PTRACE --shm-size=8g --ulimit=nofile=1000000:1000000" + script: "ci/test_python_other.sh" + conda-java-tests: + needs: [conda-cpp-build, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_java + with: + build_type: pull-request + node_type: "gpu-l4-latest-1" + arch: "amd64" + container_image: "rapidsai/ci-conda:26.08-latest" + script: "ci/test_java.sh" + conda-notebook-tests: + needs: [conda-python-build, conda-python-build-noarch, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_notebooks + with: + build_type: pull-request + node_type: "gpu-l4-latest-1" + arch: "amd64" + container_image: "rapidsai/ci-conda:26.08-latest" + script: "ci/test_notebooks.sh" + docs-build: + needs: [conda-python-build, conda-python-build-noarch, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).build_docs + with: + build_type: pull-request + node_type: "gpu-l4-latest-1" + arch: "amd64" + container_image: "rapidsai/ci-conda:26.08-latest" + script: "ci/build_docs.sh" wheel-build-libcudf: needs: checks permissions: @@ -558,20 +580,20 @@ jobs: script: "ci/build_wheel_cudf_streaming.sh" package-name: cudf_streaming package-type: python -# wheel-tests-cudf-streaming: -# needs: [wheel-build-cudf-streaming, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels -# with: -# build_type: pull-request -# script: ci/test_wheel_cudf_streaming.sh + wheel-tests-cudf-streaming: + needs: [wheel-build-cudf-streaming, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels + with: + build_type: pull-request + script: ci/test_wheel_cudf_streaming.sh wheel-build-pylibcudf: needs: [checks, wheel-build-libcudf] permissions: @@ -590,38 +612,38 @@ jobs: package-type: python # Build a wheel for each CUDA x ARCH x minimum supported Python version matrix_filter: group_by({CUDA_VER, ARCH}) | map(min_by(.PY_VER | split(".") | map(tonumber))) -# wheel-build-cudf: -# needs: wheel-build-pylibcudf -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main -# with: -# build_type: pull-request -# node_type: cpu8 -# script: "ci/build_wheel_cudf.sh" -# package-name: cudf -# package-type: python -# # Build a wheel for each CUDA x ARCH x minimum supported Python version -# matrix_filter: group_by({CUDA_VER, ARCH}) | map(min_by(.PY_VER | split(".") | map(tonumber))) -# wheel-tests-cudf: -# needs: [wheel-build-cudf, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf -# with: -# build_type: pull-request -# script: ci/test_wheel_cudf.sh + wheel-build-cudf: + needs: wheel-build-pylibcudf + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main + with: + build_type: pull-request + node_type: cpu8 + script: "ci/build_wheel_cudf.sh" + package-name: cudf + package-type: python + # Build a wheel for each CUDA x ARCH x minimum supported Python version + matrix_filter: group_by({CUDA_VER, ARCH}) | map(min_by(.PY_VER | split(".") | map(tonumber))) + wheel-tests-cudf: + needs: [wheel-build-cudf, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf + with: + build_type: pull-request + script: ci/test_wheel_cudf.sh wheel-build-cudf-polars: needs: wheel-build-pylibcudf permissions: @@ -657,7 +679,7 @@ jobs: matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) build_type: pull-request container-options: "--cap-add CAP_SYS_PTRACE --shm-size=8g --ulimit=nofile=1000000:1000000" - script: "ci/test_wheel_cudf_polars.sh" + script: "env POLARS_VERSIONS=endpoints ci/test_wheel_cudf_polars.sh" cudf-polars-polars-tests: needs: [wheel-build-cudf-polars, wheel-build-cudf-streaming, changed-files] permissions: @@ -674,171 +696,171 @@ jobs: matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) build_type: pull-request script: "ci/test_cudf_polars_polars_tests.sh" -# wheel-build-dask-cudf: -# needs: wheel-build-cudf -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main -# with: -# # This selects "ARCH=amd64 + the latest supported Python + CUDA". -# matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) -# build_type: pull-request -# node_type: cpu8 -# script: "ci/build_wheel_dask_cudf.sh" -# package-name: dask_cudf -# package-type: python -# pure-wheel: true -# wheel-tests-dask-cudf: -# needs: [wheel-build-dask-cudf, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels && fromJSON(needs.changed-files.outputs.changed_file_groups).not_cudf_polars -# with: -# # This selects "ARCH=amd64 + the latest supported Python + CUDA". -# matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) -# build_type: pull-request -# script: ci/test_wheel_dask_cudf.sh -# # build cudf with benchmarks but disable for cudf_streaming since we can't use MPI/UCX in wheel-based builds -# devcontainer: -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# needs: telemetry-setup -# uses: rapidsai/shared-workflows/.github/workflows/build-in-devcontainer.yaml@main -# with: -# arch: '["amd64", "arm64"]' -# cuda: '["13.3"]' -# node_type: "cpu8" -# timeout-minutes: 90 -# env: | -# SCCACHE_DIST_MAX_RETRIES=inf -# SCCACHE_SERVER_LOG=sccache=debug -# SCCACHE_DIST_FALLBACK_TO_LOCAL_COMPILE=false -# build_command: | -# sccache --zero-stats; -# build-all -j0 --verbose -DBUILD_BENCHMARKS=ON 2>&1 | tee telemetry-artifacts/build.log; -# sccache --show-adv-stats | tee telemetry-artifacts/sccache-stats.txt; -# unit-tests-cudf-pandas: -# needs: [wheel-build-cudf, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main -# if: (fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels || fromJSON(needs.changed-files.outputs.changed_file_groups).test_cudf_pandas) && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf -# with: -# # This selects the latest supported Python + CUDA minor versions for each ARCH/CUDA major version combo -# matrix_filter: group_by([(.ARCH), (.CUDA_VER|split(".")|map(tonumber)|.[0])]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) -# build_type: pull-request -# script: ci/cudf_pandas_scripts/run_tests.sh -# third-party-integration-tests-cudf-pandas: -# needs: [conda-python-build, conda-python-build-noarch, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cpp_nor_cudf_polars_nor_dask_cudf -# with: -# build_type: pull-request -# branch: ${{ inputs.branch }} -# date: ${{ inputs.date }} -# sha: ${{ inputs.sha }} -# node_type: "gpu-l4-latest-1" -# continue-on-error: true -# container_image: "rapidsai/ci-conda:26.08-latest" -# script: | -# ci/cudf_pandas_scripts/third-party-integration/test.sh python/cudf/cudf_pandas_tests/third_party_integration_tests/dependencies.yaml -# cuml-compat-tests: -# needs: [conda-python-build, conda-python-build-noarch, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf -# with: -# build_type: pull-request -# branch: ${{ inputs.branch }} -# date: ${{ inputs.date }} -# sha: ${{ inputs.sha }} -# node_type: "gpu-l4-latest-1" -# continue-on-error: true -# container_image: "rapidsai/ci-conda:26.06-latest" -# script: "ci/test_cuml_compat.sh" -# pandas-tests: -# # run the Pandas unit tests using PR branch -# needs: [wheel-build-cudf, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cpp_nor_cudf_polars_nor_dask_cudf -# with: -# build_type: pull-request -# branch: ${{ inputs.branch }} -# date: ${{ inputs.date }} -# sha: ${{ inputs.sha }} -# node_type: "gpu-l4-latest-1" -# container_image: "rapidsai/citestwheel:26.08-latest" -# script: ci/cudf_pandas_scripts/pandas-tests/run.sh pr -# narwhals-tests: -# needs: [conda-python-build, conda-python-build-noarch, changed-files] -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# secrets: inherit # zizmor: ignore[secrets-inherit] -# uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cpp_nor_cudf_polars_nor_dask_cudf -# with: -# build_type: pull-request -# branch: ${{ inputs.branch }} -# date: ${{ inputs.date }} -# sha: ${{ inputs.sha }} -# node_type: "gpu-l4-latest-1" -# container_image: "rapidsai/ci-conda:26.08-latest" -# script: ci/test_narwhals.sh -# spark-rapids-jni: -# needs: changed-files -# permissions: -# actions: read -# contents: read -# id-token: write -# packages: read -# pull-requests: read -# uses: ./.github/workflows/spark-rapids-jni.yaml -# if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_java + wheel-build-dask-cudf: + needs: wheel-build-cudf + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main + with: + # This selects "ARCH=amd64 + the latest supported Python + CUDA". + matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) + build_type: pull-request + node_type: cpu8 + script: "ci/build_wheel_dask_cudf.sh" + package-name: dask_cudf + package-type: python + pure-wheel: true + wheel-tests-dask-cudf: + needs: [wheel-build-dask-cudf, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels && fromJSON(needs.changed-files.outputs.changed_file_groups).not_cudf_polars + with: + # This selects "ARCH=amd64 + the latest supported Python + CUDA". + matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) + build_type: pull-request + script: ci/test_wheel_dask_cudf.sh + # build cudf with benchmarks but disable for cudf_streaming since we can't use MPI/UCX in wheel-based builds + devcontainer: + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + needs: telemetry-setup + uses: rapidsai/shared-workflows/.github/workflows/build-in-devcontainer.yaml@main + with: + arch: '["amd64", "arm64"]' + cuda: '["13.3"]' + node_type: "cpu8" + timeout-minutes: 90 + env: | + SCCACHE_DIST_MAX_RETRIES=inf + SCCACHE_SERVER_LOG=sccache=debug + SCCACHE_DIST_FALLBACK_TO_LOCAL_COMPILE=false + build_command: | + sccache --zero-stats; + build-all -j0 --verbose -DBUILD_BENCHMARKS=ON 2>&1 | tee telemetry-artifacts/build.log; + sccache --show-adv-stats | tee telemetry-artifacts/sccache-stats.txt; + unit-tests-cudf-pandas: + needs: [wheel-build-cudf, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@main + if: (fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels || fromJSON(needs.changed-files.outputs.changed_file_groups).test_cudf_pandas) && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf + with: + # This selects the latest supported Python + CUDA minor versions for each ARCH/CUDA major version combo + matrix_filter: group_by([(.ARCH), (.CUDA_VER|split(".")|map(tonumber)|.[0])]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) + build_type: pull-request + script: ci/cudf_pandas_scripts/run_tests.sh + third-party-integration-tests-cudf-pandas: + needs: [conda-python-build, conda-python-build-noarch, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cpp_nor_cudf_polars_nor_dask_cudf + with: + build_type: pull-request + branch: ${{ inputs.branch }} + date: ${{ inputs.date }} + sha: ${{ inputs.sha }} + node_type: "gpu-l4-latest-1" + continue-on-error: true + container_image: "rapidsai/ci-conda:26.08-latest" + script: | + ci/cudf_pandas_scripts/third-party-integration/test.sh python/cudf/cudf_pandas_tests/third_party_integration_tests/dependencies.yaml + cuml-compat-tests: + needs: [conda-python-build, conda-python-build-noarch, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_polars_nor_dask_cudf + with: + build_type: pull-request + branch: ${{ inputs.branch }} + date: ${{ inputs.date }} + sha: ${{ inputs.sha }} + node_type: "gpu-l4-latest-1" + continue-on-error: true + container_image: "rapidsai/ci-conda:26.06-latest" + script: "ci/test_cuml_compat.sh" + pandas-tests: + # run the Pandas unit tests using PR branch + needs: [wheel-build-cudf, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cpp_nor_cudf_polars_nor_dask_cudf + with: + build_type: pull-request + branch: ${{ inputs.branch }} + date: ${{ inputs.date }} + sha: ${{ inputs.sha }} + node_type: "gpu-l4-latest-1" + container_image: "rapidsai/citestwheel:26.08-latest" + script: ci/cudf_pandas_scripts/pandas-tests/run.sh pr + narwhals-tests: + needs: [conda-python-build, conda-python-build-noarch, changed-files] + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + secrets: inherit # zizmor: ignore[secrets-inherit] + uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cpp_nor_cudf_polars_nor_dask_cudf + with: + build_type: pull-request + branch: ${{ inputs.branch }} + date: ${{ inputs.date }} + sha: ${{ inputs.sha }} + node_type: "gpu-l4-latest-1" + container_image: "rapidsai/ci-conda:26.08-latest" + script: ci/test_narwhals.sh + spark-rapids-jni: + needs: changed-files + permissions: + actions: read + contents: read + id-token: write + packages: read + pull-requests: read + uses: ./.github/workflows/spark-rapids-jni.yaml + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_java telemetry-summarize: # This job must use a self-hosted runner to record telemetry traces. runs-on: linux-amd64-cpu4 diff --git a/python/cudf_polars/cudf_polars/dsl/translate.py b/python/cudf_polars/cudf_polars/dsl/translate.py index de6436140566..c77f35ace3c9 100644 --- a/python/cudf_polars/cudf_polars/dsl/translate.py +++ b/python/cudf_polars/cudf_polars/dsl/translate.py @@ -638,6 +638,11 @@ def _(node: plrs._ir_nodes.Sort, translator: Translator, schema: Schema) -> ir.I order, null_order = sorting.sort_order( descending, nulls_last=nulls_last, num_keys=len(by) ) + # TODO: use the DynamicPred hint from node.slice (offset, length, + # dynamic_pred_id). dynamic_pred_id is an int (u128 UUID) matching a + # DynamicPred Function node in an upstream scan. The sort actor could + # set a threshold predicate on it (e.g. col < max_seen) to prune rows + # at the source. if not POLARS_VERSION_LT_142 and node.slice is not None: offset, length, *_ = node.slice zlice: Zlice | None = (offset, length) From 0564da00556569da6253ec3e7c3679a97f66087b Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Tue, 30 Jun 2026 20:33:29 +0000 Subject: [PATCH 10/13] xfail more upstream polars tests --- python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py b/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py index fca2b1e0acb1..252160ce4982 100644 --- a/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py +++ b/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py @@ -247,6 +247,8 @@ def pytest_report_header(config: pytest.Config) -> str: "tests/unit/sql/test_cast.py::test_cast_errors[values5-values::int4-conversion from `str` to `i32` failed]": "Cast raises, but error user receives is wrong", "tests/unit/lazyframe/test_predicates.py::test_predicate_pushdown_split_pushable": "Casting that raises not supported on GPU", "tests/unit/lazyframe/test_predicates.py::test_filter_contradiction_fallible_error_handling": "Casting that raises not supported on GPU", + "tests/unit/lazyframe/test_predicates.py::test_hconcat_predicate": "polars 1.42.1: how='horizontal' in concat triggers DeprecationWarning, fails on CPU too", + "tests/unit/functions/test_union.py::test_union_lazyframe_horizontal": "polars 1.42.1: how='horizontal' in union triggers DeprecationWarning, fails on CPU too", "tests/unit/sql/test_miscellaneous.py::test_read_csv": "Incorrect handling of missing_is_null in read_csv", "tests/unit/lazyframe/test_cse.py::test_cse_predicate_self_join[False]": "Debug output on stderr doesn't match", "tests/unit/io/test_scan_row_deletion.py::test_scan_row_deletion_skips_file_with_all_rows_deleted": "The test intentionally corrupts the parquet file, so we cannot read the row count from the header.", From 363ebe29b430811d6f44e4113f550feef9471f9c Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Tue, 30 Jun 2026 23:49:38 +0000 Subject: [PATCH 11/13] fix incorrect DeprecationWarning failure in in xfail set, and use Column.is_sorted --- python/cudf_polars/cudf_polars/dsl/expressions/boolean.py | 4 ++-- python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/python/cudf_polars/cudf_polars/dsl/expressions/boolean.py b/python/cudf_polars/cudf_polars/dsl/expressions/boolean.py index d08d95a9616d..92234805d0cd 100644 --- a/python/cudf_polars/cudf_polars/dsl/expressions/boolean.py +++ b/python/cudf_polars/cudf_polars/dsl/expressions/boolean.py @@ -420,8 +420,8 @@ def do_evaluate( null_order = ( plc.types.NullOrder.AFTER if nulls_last else plc.types.NullOrder.BEFORE ) - bool_result = plc.sorting.is_sorted( - plc.Table([column.obj]), [order], [null_order], stream=df.stream + bool_result: bool = column.check_sorted( + order=order, null_order=null_order, stream=df.stream ) return Column( plc.Column.from_scalar( diff --git a/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py b/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py index 252160ce4982..3fe91d2c0a6b 100644 --- a/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py +++ b/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py @@ -247,8 +247,8 @@ def pytest_report_header(config: pytest.Config) -> str: "tests/unit/sql/test_cast.py::test_cast_errors[values5-values::int4-conversion from `str` to `i32` failed]": "Cast raises, but error user receives is wrong", "tests/unit/lazyframe/test_predicates.py::test_predicate_pushdown_split_pushable": "Casting that raises not supported on GPU", "tests/unit/lazyframe/test_predicates.py::test_filter_contradiction_fallible_error_handling": "Casting that raises not supported on GPU", - "tests/unit/lazyframe/test_predicates.py::test_hconcat_predicate": "polars 1.42.1: how='horizontal' in concat triggers DeprecationWarning, fails on CPU too", - "tests/unit/functions/test_union.py::test_union_lazyframe_horizontal": "polars 1.42.1: how='horizontal' in union triggers DeprecationWarning, fails on CPU too", + "tests/unit/lazyframe/test_predicates.py::test_hconcat_predicate": "polars 1.42.1: how='horizontal' in concat is deprecated and raises a warning treated as error; fails on CPU too", + "tests/unit/functions/test_union.py::test_union_lazyframe_horizontal": "polars 1.42.1: how='horizontal' in union is deprecated and raises a warning treated as error; fails on CPU too", "tests/unit/sql/test_miscellaneous.py::test_read_csv": "Incorrect handling of missing_is_null in read_csv", "tests/unit/lazyframe/test_cse.py::test_cse_predicate_self_join[False]": "Debug output on stderr doesn't match", "tests/unit/io/test_scan_row_deletion.py::test_scan_row_deletion_skips_file_with_all_rows_deleted": "The test intentionally corrupts the parquet file, so we cannot read the row count from the header.", From 9741a1d66378c5164dc425b8733d8ec0bb4614ab Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Thu, 2 Jul 2026 17:47:11 +0000 Subject: [PATCH 12/13] update xfails --- ci/test_narwhals.sh | 8 ++++++-- .../cudf_polars/cudf_polars/testing/inject_gpu_engine.py | 2 -- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ci/test_narwhals.sh b/ci/test_narwhals.sh index 4c5d020593d9..13c30f178279 100755 --- a/ci/test_narwhals.sh +++ b/ci/test_narwhals.sh @@ -1,5 +1,5 @@ #!/bin/bash -# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION. +# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 set -euo pipefail @@ -122,6 +122,9 @@ PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 \ # test_dtypes: narwhals' dtype mapping changed with polars 1.40 (reports Object where the test expects Int8). # test_namespace_len[polars[lazy]]: len() row count lost in zero-column streaming chunks # (https://github.com/rapidsai/cudf/issues/21428). +# test_explode_*[polars[lazy]-*]: polars 1.42 emits a DeprecationWarning when explode() is called +# without empty_as_null=True; narwhals 2.16.0 doesn't pass the kwarg yet, so filterwarnings=error +# turns this into a failure. Remove once narwhals is updated. TESTS_THAT_NEED_NARWHALS_FIX_FOR_CUDF_POLARS=" \ test_dtypes or \ test_namespace_len[polars[lazy]] or \ @@ -131,7 +134,8 @@ test_to_datetime_tz_aware[polars[lazy]-None] or \ test_truncate[polars[lazy]-1ns-expected0] or \ test_truncate_multiples[polars[lazy]-2ns-expected0] or \ ((test_nested_structures and polars and lazy) and (value0 or value1 or value3 or value4 or value6 or value7)) or \ -(test_series_from_iterable and pandas) \ +(test_series_from_iterable and pandas) or \ +(test_explode and polars and lazy) \ " rapids-logger "Run narwhals tests for cuDF Polars" diff --git a/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py b/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py index 3fe91d2c0a6b..fca2b1e0acb1 100644 --- a/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py +++ b/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py @@ -247,8 +247,6 @@ def pytest_report_header(config: pytest.Config) -> str: "tests/unit/sql/test_cast.py::test_cast_errors[values5-values::int4-conversion from `str` to `i32` failed]": "Cast raises, but error user receives is wrong", "tests/unit/lazyframe/test_predicates.py::test_predicate_pushdown_split_pushable": "Casting that raises not supported on GPU", "tests/unit/lazyframe/test_predicates.py::test_filter_contradiction_fallible_error_handling": "Casting that raises not supported on GPU", - "tests/unit/lazyframe/test_predicates.py::test_hconcat_predicate": "polars 1.42.1: how='horizontal' in concat is deprecated and raises a warning treated as error; fails on CPU too", - "tests/unit/functions/test_union.py::test_union_lazyframe_horizontal": "polars 1.42.1: how='horizontal' in union is deprecated and raises a warning treated as error; fails on CPU too", "tests/unit/sql/test_miscellaneous.py::test_read_csv": "Incorrect handling of missing_is_null in read_csv", "tests/unit/lazyframe/test_cse.py::test_cse_predicate_self_join[False]": "Debug output on stderr doesn't match", "tests/unit/io/test_scan_row_deletion.py::test_scan_row_deletion_skips_file_with_all_rows_deleted": "The test intentionally corrupts the parquet file, so we cannot read the row count from the header.", From 909017a82037ad8215d62f99fea12d78fc02fa6d Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Thu, 2 Jul 2026 20:11:08 +0000 Subject: [PATCH 13/13] skip tests --- python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py b/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py index e87542d7664d..8e6a212a7cba 100644 --- a/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py +++ b/python/cudf_polars/cudf_polars/testing/inject_gpu_engine.py @@ -345,6 +345,12 @@ def pytest_report_header(config: pytest.Config) -> str: "tests/unit/io/test_scan.py::test_scan_metrics[False-parquet]": "Checks to IO metric logs specific to Polars CPU", "tests/unit/io/test_scan.py::test_scan_metrics[False-csv]": "Checks to IO metric logs specific to Polars CPU", "tests/unit/io/test_scan.py::test_scan_metrics[False-ndjson]": "Checks to IO metric logs specific to Polars CPU", + # polars 1.42 updated these tests to also assert deprecated_call and strict=True ShapeError + # in the same test function. The SPMD engine fails on the strict=True collect() inside a + # pytest.raises block because the DeprecationWarning from how='horizontal' propagates differently + # across engines. Skip both runs rather than xfail (which would XPASS on in-memory). + "tests/unit/lazyframe/test_predicates.py::test_hconcat_predicate": "polars 1.42: test uses deprecated how='horizontal' with strict=True in ways that behave differently across GPU engines", + "tests/unit/functions/test_union.py::test_union_lazyframe_horizontal": "polars 1.42: test uses deprecated how='horizontal' with strict=True in ways that behave differently across GPU engines", }