Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
475b7cd
Run Polars TPC benchmarks in CI
Matt711 Jun 9, 2026
c94a0dc
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jun 11, 2026
ebcb626
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jun 25, 2026
e04ef1c
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jun 25, 2026
c72714b
move tpcds gen script to python, use existing pdsh and pdsds python s…
Matt711 Jun 25, 2026
4dc4c16
copyright
Matt711 Jun 25, 2026
b89f51d
merge conflict
Matt711 Jun 29, 2026
494fa40
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jun 29, 2026
d9d00b4
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 2, 2026
79dc8b8
update artifact names
Matt711 Jul 2, 2026
1be401f
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 2, 2026
63dda74
add --matrix
Matt711 Jul 6, 2026
8a333f8
add tpcds datagen file
Matt711 Jul 6, 2026
9a55a91
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 6, 2026
87c8460
tpcgen-cli cmd clap sub-cmd
Matt711 Jul 6, 2026
22b4131
remove implicit pyarrow dependency, fix SQL Q64
Matt711 Jul 6, 2026
32c4b4f
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 6, 2026
6cdfe35
add TODO about tpcds gen
Matt711 Jul 6, 2026
4b444a5
mypy
Matt711 Jul 6, 2026
664153c
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 6, 2026
aedb32a
increase verbosity, switch to SF1
Matt711 Jul 6, 2026
00eeef4
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 6, 2026
c792edf
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 7, 2026
facd442
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 7, 2026
6724c90
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 7, 2026
d013cff
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 7, 2026
75b3d51
fixes for decimals
Matt711 Jul 8, 2026
ae470f1
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 8, 2026
ae10992
validate more queries, xfail some, len and window function fix
Matt711 Jul 8, 2026
63cfddc
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 8, 2026
1c88b62
dont convert to floats to workaround groupby-sum agg bug
Matt711 Jul 9, 2026
21fb8ed
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 9, 2026
096f223
xfail more queries due to groupby-sum agg bug
Matt711 Jul 9, 2026
0bf566f
merge conflict
Matt711 Jul 20, 2026
670a78c
update query comments
Matt711 Jul 20, 2026
b296f57
Fix stale EXPECTED_FAILURES entries and lukewarm cache drop semantics
Matt711 Jul 21, 2026
73aeb3e
Refactor benchmark runner to use RunOptions dataclass instead of argp…
Matt711 Jul 21, 2026
dde3b2f
Add TPC-H and TPC-DS pytest validation tests for the streaming engine
Matt711 Jul 21, 2026
95da769
Run TPC validation tests via pytest in CI
Matt711 Jul 21, 2026
6bfdcb7
pin tpchgen-cli, pre-commit
Matt711 Jul 21, 2026
ded1a0d
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 21, 2026
03207a1
Add pytest>=9 lower bound to TPC test deps to get subtests for free
Matt711 Jul 21, 2026
cd07205
pytest pinning
Matt711 Jul 21, 2026
c843e99
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 21, 2026
69aac80
merge conflict
Matt711 Jul 21, 2026
ea82fef
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 21, 2026
1467cc5
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Jul 22, 2026
82825c5
address reviews
Matt711 Jul 23, 2026
74cdd1c
address reviews
Matt711 Jul 23, 2026
d2ebd23
add arg parsing tests
Matt711 Jul 23, 2026
fa9a0a4
pre-commit check
Matt711 Jul 23, 2026
cddd9d7
merge conflict
Matt711 Aug 22, 2026
7ebca1b
address reviews
Matt711 Aug 22, 2026
ab57e72
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Aug 24, 2026
53bf6ad
add datagen script
Matt711 Aug 24, 2026
84c3d23
just use test fixtures for data generation
Matt711 Aug 24, 2026
b910f04
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Aug 25, 2026
b21116b
Merge branch 'main' into ci/polars/run-tpc-bench
Matt711 Aug 25, 2026
ed1a3bd
merge conflict
Matt711 Aug 26, 2026
6a1c5bb
move module scoped settings under __name__ == __main__
Matt711 Aug 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/pr.yaml

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore changes in this file. Will remove them before this PR is merged

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder that these changes should be removed before the PR is merged. We only want to run these tests nightly

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder that these changes should be removed before the PR is merged. We only want to run these tests nightly

Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
- wheel-build-cudf-polars
- wheel-tests-cudf-polars
- cudf-polars-polars-tests
- tpc-tests-cudf-polars
- wheel-build-dask-cudf
- wheel-tests-dask-cudf
- devcontainer
Expand Down Expand Up @@ -816,6 +817,23 @@ 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"
tpc-tests-cudf-polars:
needs: [wheel-build-cudf-polars, 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 && fromJSON(needs.changed-files.outputs.changed_file_groups).neither_cudf_nor_dask_cudf
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
container-options: "--cap-add CAP_SYS_PTRACE --shm-size=8g --ulimit=nofile=1000000:1000000"
script: "ci/run_cudf_polars_tpc.sh"
wheel-build-dask-cudf:
needs: [build-details, wheel-build-cudf]
permissions:
Expand Down
4 changes: 3 additions & 1 deletion ci/run_cudf_polars_pytests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ TIMEOUT_TOOL_PATH="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/timeout_with_st
cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/../python/cudf_polars/

python "${TIMEOUT_TOOL_PATH}" --enable-python 5400 \
python -m pytest --cache-clear -p no:benchmark "$@" tests
python -m pytest --cache-clear -p no:benchmark "$@" tests \
--ignore=tests/streaming/test_tpch.py \
--ignore=tests/streaming/test_tpcds.py
50 changes: 50 additions & 0 deletions ci/run_cudf_polars_tpc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/bash
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

set -euo pipefail

source rapids-init-pip

rapids-logger "Download wheels"

RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen "${RAPIDS_CUDA_VERSION}")"
LIBCUDF_WHEELHOUSE=$(rapids-download-from-github "$(rapids-artifact-name wheel_cpp libcudf cudf --cuda "$RAPIDS_CUDA_VERSION")")
PYLIBCUDF_WHEELHOUSE=$(rapids-download-from-github "$(rapids-artifact-name wheel_python pylibcudf cudf --stable --cuda "$RAPIDS_CUDA_VERSION")")
CUDF_POLARS_WHEELHOUSE=$(rapids-download-from-github "$(rapids-artifact-name wheel_python cudf-polars cudf --pure --arch any --cuda "$RAPIDS_CUDA_VERSION")")
LIBCUDF_STREAMING_WHEELHOUSE=$(rapids-download-from-github "$(rapids-artifact-name wheel_cpp libcudf-streaming cudf --cuda "$RAPIDS_CUDA_VERSION")")
CUDF_STREAMING_WHEELHOUSE=$(rapids-download-from-github "$(rapids-artifact-name wheel_python cudf-streaming cudf --stable --cuda "$RAPIDS_CUDA_VERSION")")

rapids-generate-pip-constraints py_test_cudf_polars "${PIP_CONSTRAINT}"

rapids-logger "Installing cudf_polars and TPC test dependencies"

TPCH_REQUIREMENTS=$(mktemp --suffix=.txt)
rapids-dependency-file-generator \
--config dependencies.yaml \
--file-key test_cudf_polars_tpch \
--output requirements \
--matrix "cuda=${RAPIDS_CUDA_VERSION%.*};arch=$(arch);py=${RAPIDS_PY_VERSION}" \
> "${TPCH_REQUIREMENTS}"

rapids-pip-retry install \
-v \
--prefer-binary \
--constraint "${PIP_CONSTRAINT}" \
"$(echo "${CUDF_POLARS_WHEELHOUSE}"/cudf_polars_"${RAPIDS_PY_CUDA_SUFFIX}"*.whl)[test]" \
"$(echo "${LIBCUDF_WHEELHOUSE}"/libcudf_"${RAPIDS_PY_CUDA_SUFFIX}"*.whl)" \
"$(echo "${PYLIBCUDF_WHEELHOUSE}"/pylibcudf_"${RAPIDS_PY_CUDA_SUFFIX}"*.whl)" \
"$(echo "${LIBCUDF_STREAMING_WHEELHOUSE}"/libcudf_streaming_"${RAPIDS_PY_CUDA_SUFFIX}"*.whl)" \
"$(echo "${CUDF_STREAMING_WHEELHOUSE}"/cudf_streaming_"${RAPIDS_PY_CUDA_SUFFIX}"*.whl)" \
-r "${TPCH_REQUIREMENTS}"

rapids-logger "Check GPU usage"
nvidia-smi

rapids-logger "Running TPC-H and TPC-DS validation tests"

cd python/cudf_polars

python -m pytest tests/streaming/test_tpch.py tests/streaming/test_tpcds.py \

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to make running and validating the benchmark proper pytests so we get the benefits of using pytest. Alternatively, we could run the benchmarks in using python -m ...pdsh and check that all queries were validated.

Sample output of running the tests

(rapids) coder ➜ ~/cudf/python/cudf_polars $ CUDA_VISIBLE_DEVICES=7 python -m pytest tests/streaming/test_tpch.py --iterations 2 -v
========================================================= test session starts =========================================================
platform linux -- Python 3.13.14, pytest-9.0.3, pluggy-1.6.0 -- /home/coder/.conda/envs/rapids/bin/python
cachedir: .pytest_cache
benchmark: 5.2.3 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
hypothesis profile 'default'
rootdir: /home/coder/cudf/python/cudf_polars
configfile: pyproject.toml
plugins: benchmark-5.2.3, cov-7.1.0, zarr-3.1.6, xdist-3.8.0, timeout-2.4.0, asyncio-1.4.0, hypothesis-6.157.0, anyio-4.14.2, pytest_httpserver-1.1.5, rerunfailures-16.4, cases-3.10.1
asyncio: mode=Mode.STRICT, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collected 22 items                                                                                                                    

tests/streaming/test_tpch.py::test_tpch_query[q01] SUBPASSED[iter0]                                                             [  4%]
tests/streaming/test_tpch.py::test_tpch_query[q01] SUBPASSED[iter1]                                                             [  4%]
tests/streaming/test_tpch.py::test_tpch_query[q01] PASSED                                                                       [  4%]
tests/streaming/test_tpch.py::test_tpch_query[q02] SUBPASSED[iter0]                                                             [  9%]
tests/streaming/test_tpch.py::test_tpch_query[q02] SUBPASSED[iter1]                                                             [  9%]
tests/streaming/test_tpch.py::test_tpch_query[q02] PASSED                                                                       [  9%]
tests/streaming/test_tpch.py::test_tpch_query[q03] SUBPASSED[iter0]                                                                                                               
...
tests/streaming/test_tpch.py::test_tpch_query[q20] PASSED                                                                       [ 90%]
tests/streaming/test_tpch.py::test_tpch_query[q21] SUBPASSED[iter0]                                                             [ 95%]
tests/streaming/test_tpch.py::test_tpch_query[q21] SUBPASSED[iter1]                                                             [ 95%]
tests/streaming/test_tpch.py::test_tpch_query[q21] PASSED                                                                       [ 95%]
tests/streaming/test_tpch.py::test_tpch_query[q22] SUBPASSED[iter0]                                                             [100%]
tests/streaming/test_tpch.py::test_tpch_query[q22] SUBPASSED[iter1]                                                             [100%]
tests/streaming/test_tpch.py::test_tpch_query[q22] PASSED                                                                       [100%]

=============================================== 22 passed, 44 subtests passed in 9.71s ================================================

--iterations 2 \
-v
Comment thread
coderabbitai[bot] marked this conversation as resolved.
21 changes: 21 additions & 0 deletions dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,14 @@ files:
- test_python_common
- test_python_cudf_polars
- cudf_polars_trace
py_tpch_cudf_polars:
output: pyproject
pyproject_dir: python/cudf_polars
extras:
table: project.optional-dependencies
key: tpch
includes:
- test_cudf_polars_tpch
py_trace_cudf_polars:
output: pyproject
matrix:
Expand Down Expand Up @@ -724,6 +732,10 @@ files:
polars_compat_version: ["1.35", "1.36", "1.37", "1.38", "1.39", "1.40", "1.41", "1.42"]
includes:
- test_cudf_polars_compat
test_cudf_polars_tpch:
output: none
includes:
- test_cudf_polars_tpch
channels:
- rapidsai-nightly
- rapidsai
Expand Down Expand Up @@ -1321,6 +1333,15 @@ dependencies:
packages:
# Used by timeout_with_stack.py utility
- gdb
test_cudf_polars_tpch:
common:
- output_types: [conda, requirements, pyproject]
packages:
- duckdb
- pyarrow

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where do we use pyarrow for the tpch benchmarks?

# added lower bound pinning to get pytest-subtests for free
- pytest>=9
- tpchgen-cli>=3.0.0
Comment thread
coderabbitai[bot] marked this conversation as resolved.
test_python_narwhals:
common:
- output_types: [conda, requirements, constraints, pyproject]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,10 @@ def sort_for_comparison(df: pl.DataFrame) -> pl.DataFrame:
pl.col(col).lt(val - 2 * abs_tol)
| pl.col(col).gt(val + 2 * abs_tol)
)
elif val is None:

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix for None boundary comparison in asserts.py: assert_tpch_result_equal emitted a UserWarning when the sort tie boundary value was None, because it called pl.col(col).lt(None). The fix treats a None boundary as meaning all rows are ties by appending pl.lit(False) instead.

filter_exprs.append(
pl.col(col).is_not_null() if nulls_last else pl.lit(value=False)
)
else:
if desc:
# then "before" means "greater than"
Expand Down
43 changes: 23 additions & 20 deletions python/cudf_polars/cudf_polars/streaming/benchmarks/pdsds.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,10 @@
if e.name is not None and not e.name.startswith("cudf_polars"):
raise


if TYPE_CHECKING:
from types import ModuleType

# Without this setting, the first IO task to run

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved these because setting them at module scope had bad interation with tests because we not import directly from this module in the tests.

# on each worker takes ~15 sec extra
os.environ["KVIKIO_COMPAT_MODE"] = os.environ.get("KVIKIO_COMPAT_MODE", "on")
os.environ["KVIKIO_NTHREADS"] = os.environ.get("KVIKIO_NTHREADS", "8")
# TODO: consider raising the rapidsmpf built-in default from 1 to 8.
os.environ["RAPIDSMPF_NUM_STREAMING_THREADS"] = os.environ.get(
"RAPIDSMPF_NUM_STREAMING_THREADS", "8"
)


def valid_query(name: str) -> bool:
"""Return True for valid query names eg. 'q9', 'q65', etc."""
Expand Down Expand Up @@ -75,12 +67,18 @@ class PDSDSQueries(metaclass=PDSDSQueriesMeta):

q_impl: str
name: str = "pdsds"
num_queries: int = 99


class PDSDSPolarsQueries(PDSDSQueries):
"""Polars Queries."""

q_impl = "polars_impl"
# Queries expected to fail on GPU due to known bugs. Keys are query numbers;
# values are reasons for the failures. These queries will be skipped in GPU runs.
EXPECTED_FAILURES_TPCDS: ClassVar[dict[int, str]] = {
5: "GPU execution failure (packed data cannot be empty): https://github.com/rapidsai/cudf/issues/22073",
}
# See comments for EXPECTED_CASTS and EXPECTED_CASTS_DECIMAL
# in cudf/python/cudf_polars/cudf_polars/streaming/benchmarks/pdsh.py
# for more details.
Expand Down Expand Up @@ -111,18 +109,9 @@ class PDSDSPolarsQueries(PDSDSQueries):
pl.col("total net profit").cast(pl.Decimal(18, 2)),
],
19: [pl.col("ext_price").cast(pl.Decimal(18, 2))],
20: [
pl.col("itemrevenue").cast(pl.Decimal(18, 2)),
pl.col("revenueratio").cast(pl.Decimal(38, 2)),
],
20: [pl.col("revenueratio").cast(pl.Decimal(38, 2))],
24: [pl.col("paid").cast(pl.Decimal(18, 2))],
30: [pl.col("ctr_total_return").cast(pl.Decimal(18, 2))],
31: [
pl.col("web_q1_q2_increase").cast(pl.Decimal(38, 2)),
pl.col("store_q1_q2_increase").cast(pl.Decimal(38, 2)),
pl.col("web_q2_q3_increase").cast(pl.Decimal(38, 2)),
pl.col("store_q2_q3_increase").cast(pl.Decimal(38, 2)),
],
32: [pl.col("excess discount amount").cast(pl.Decimal(18, 2))],
33: [pl.col("total_sales").cast(pl.Decimal(18, 2))],
42: [pl.col("sum(ss_ext_sales_price)").cast(pl.Decimal(18, 2))],
Expand Down Expand Up @@ -239,6 +228,11 @@ class PDSDSPolarsQueries(PDSDSQueries):
pl.col("inv_before").cast(pl.Int32),
pl.col("inv_after").cast(pl.Int32),
],
29: [
pl.col("store_sales_quantity").cast(pl.Int64),
pl.col("store_returns_quantity").cast(pl.Int64),
pl.col("catalog_sales_quantity").cast(pl.Int64),
],
34: [pl.col("cnt").cast(COUNT_DTYPE)],
35: [
pl.col("cnt1").cast(COUNT_DTYPE),
Expand Down Expand Up @@ -331,7 +325,16 @@ class PDSDSDuckDBQueries(PDSDSQueries):


if __name__ == "__main__":
parser = build_parser(num_queries=99)
# Without this setting, the first IO task to run
# on each worker takes ~15 sec extra
os.environ["KVIKIO_COMPAT_MODE"] = os.environ.get("KVIKIO_COMPAT_MODE", "on")
os.environ["KVIKIO_NTHREADS"] = os.environ.get("KVIKIO_NTHREADS", "8")
# TODO: consider raising the rapidsmpf built-in default from 1 to 8.
os.environ["RAPIDSMPF_NUM_STREAMING_THREADS"] = os.environ.get(
"RAPIDSMPF_NUM_STREAMING_THREADS", "8"
)

parser = build_parser(num_queries=PDSDSQueries.num_queries)
args = parse_args(parser=parser)
if args.frontend not in _CPU_ENGINES:
os.environ["POLARS_MAX_THREADS"] = os.environ.get("POLARS_MAX_THREADS", "1")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,27 @@
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES.
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""DuckDB and Polars queries."""

from __future__ import annotations

import polars as pl


def sql_sum(expr: str | pl.Expr) -> pl.Expr:
"""
Sum that returns NULL for all-null/empty groups, matching SQL SUM semantics.

Polars sum() returns 0 for all-null or empty groups; SQL returns NULL.
See https://github.com/rapidsai/cudf/issues/19560.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't replace every sum expression with sql_sum in this PR (just what I had to get the tests passing). I'll do another careful audit in a follow-up and finally close out #19560.


Parameters
----------
expr
Column name or expression to sum. If a string, wraps in ``pl.col``.
Pass a conditional expression (e.g. ``pl.when(...).then(...).otherwise(None)``)
to implement SQL ``SUM(CASE WHEN ... END)`` without ``.filter()`` inside
a groupby, which is not supported on GPU.
"""
e = pl.col(expr) if isinstance(expr, str) else expr
return pl.when(e.count() > 0).then(e.sum()).otherwise(None)
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import polars as pl

from cudf_polars.streaming.benchmarks.pdsds_parameters import load_parameters
from cudf_polars.streaming.benchmarks.pdsds_queries import sql_sum
from cudf_polars.streaming.benchmarks.utils import QueryResult, get_data

if TYPE_CHECKING:
Expand Down Expand Up @@ -74,14 +75,7 @@ def polars_impl(run_config: RunConfig) -> QueryResult:
)
.filter(pl.col("d_year") == year)
.group_by(["sr_customer_sk", "sr_store_sk"])
.agg(
# Polars sum() returns 0 for all-null groups; SQL returns NULL.
# See https://github.com/NVIDIA/cudf/issues/19560.
pl.when(pl.col("sr_return_amt").count() > 0)
.then(pl.col("sr_return_amt").sum())
.otherwise(None)
.alias("ctr_total_return")
)
.agg(sql_sum("sr_return_amt").alias("ctr_total_return"))
.rename(
{
"sr_customer_sk": "ctr_customer_sk",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES.
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Query 12."""
Expand All @@ -11,6 +11,7 @@
import polars as pl

from cudf_polars.streaming.benchmarks.pdsds_parameters import load_parameters
from cudf_polars.streaming.benchmarks.pdsds_queries import sql_sum
from cudf_polars.streaming.benchmarks.utils import QueryResult, get_data

if TYPE_CHECKING:
Expand Down Expand Up @@ -95,23 +96,13 @@ def polars_impl(run_config: RunConfig) -> QueryResult:
.group_by(
["i_item_id", "i_item_desc", "i_category", "i_class", "i_current_price"]
)
.agg(
[
pl.when(pl.col("ws_ext_sales_price").count() > 0)
.then(pl.col("ws_ext_sales_price").sum())
.otherwise(None)
.alias("itemrevenue")
]
)
.agg([sql_sum("ws_ext_sales_price").alias("itemrevenue")])
.with_columns(
[
(
pl.col("itemrevenue")
* 100
/ pl.when(pl.col("itemrevenue").count() > 0)
.then(pl.col("itemrevenue").sum())
.otherwise(None)
.over("i_class")
/ sql_sum("itemrevenue").over("i_class")
).alias("revenueratio")
]
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES.
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Query 13."""
Expand All @@ -10,6 +10,7 @@
import polars as pl

from cudf_polars.streaming.benchmarks.pdsds_parameters import load_parameters
from cudf_polars.streaming.benchmarks.pdsds_queries import sql_sum
from cudf_polars.streaming.benchmarks.utils import QueryResult, get_data

if TYPE_CHECKING:
Expand Down Expand Up @@ -158,9 +159,9 @@ def polars_impl(run_config: RunConfig) -> QueryResult:
pl.col("ss_ext_wholesale_cost")
.mean()
.alias("avg(ss_ext_wholesale_cost)"),
pl.col("ss_ext_wholesale_cost")
.sum()
.alias("sum(ss_ext_wholesale_cost)"),
sql_sum("ss_ext_wholesale_cost").alias(
"sum(ss_ext_wholesale_cost)"
),
]
)
),
Expand Down
Loading
Loading