From 5edf0fb8eb204c5d81863ab98e4e753c9ea33a62 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sat, 5 Sep 2026 10:06:50 -0700 Subject: [PATCH 01/12] TEST: Reuse JIT cache in GroupBy apply tests --- python/cudf/cudf/tests/groupby/test_apply.py | 21 +++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/python/cudf/cudf/tests/groupby/test_apply.py b/python/cudf/cudf/tests/groupby/test_apply.py index 80a1dc7690f5..de71f075f8e0 100644 --- a/python/cudf/cudf/tests/groupby/test_apply.py +++ b/python/cudf/cudf/tests/groupby/test_apply.py @@ -282,18 +282,21 @@ def func(df): @pytest.mark.parametrize("dtype", ["float64", "float32"]) @pytest.mark.parametrize("func", ["min", "max", "sum", "mean", "var", "std"]) -@pytest.mark.parametrize("special_val", [np.nan, np.inf, -np.inf]) @pytest.mark.parametrize("dataset", ["small", "large", "nans"]) def test_groupby_apply_jit_reductions_special_vals( - func, dtype, dataset, groupby_jit_datasets, special_val + func, dtype, dataset, groupby_jit_datasets ): - dataset = groupby_jit_datasets[dataset].copy(deep=True) - with expect_warning_if( - func in {"var", "std"} and not np.isnan(special_val), RuntimeWarning - ): - groupby_apply_jit_reductions_special_vals_inner( - func, dataset, dtype, special_val - ) + # All special values use the same generated UDF and input dtypes, so run + # them in one test item to reuse the per-process JIT cache. + for special_val in (np.nan, np.inf, -np.inf): + data = groupby_jit_datasets[dataset].copy(deep=True) + with expect_warning_if( + func in {"var", "std"} and not np.isnan(special_val), + RuntimeWarning, + ): + groupby_apply_jit_reductions_special_vals_inner( + func, data, dtype, special_val + ) @pytest.mark.parametrize("func", ["idxmax", "idxmin"]) From bcfef5d8f7504ff1e54be9ad5817c8d33c71594c Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sat, 5 Sep 2026 10:46:33 -0700 Subject: [PATCH 02/12] TEST: Reuse GroupBy JIT cache across datasets --- python/cudf/cudf/tests/groupby/test_apply.py | 129 +++++++++---------- 1 file changed, 61 insertions(+), 68 deletions(-) diff --git a/python/cudf/cudf/tests/groupby/test_apply.py b/python/cudf/cudf/tests/groupby/test_apply.py index de71f075f8e0..b65c1286ec23 100644 --- a/python/cudf/cudf/tests/groupby/test_apply.py +++ b/python/cudf/cudf/tests/groupby/test_apply.py @@ -211,29 +211,35 @@ def func(df): @pytest.mark.parametrize( "func", ["min", "max", "sum", "mean", "var", "std", "idxmin", "idxmax"] ) -@pytest.mark.parametrize("dataset", ["small", "large", "nans"]) +@pytest.mark.parametrize( + "dataset_names", + [ + pytest.param(("small", "large"), id="small-large"), + pytest.param(("nans",), id="nans"), + ], +) def test_groupby_apply_jit_unary_reductions( - request, func, dtype, dataset, groupby_jit_datasets + request, func, dtype, dataset_names, groupby_jit_datasets ): - request.applymarker( - pytest.mark.xfail( - condition=( - ( - dataset == "nans" - and func in {"var", "std", "mean"} - and str(dtype) in {"int64", "float32", "float64"} - ) - or ( - dataset == "nans" - and func in {"idxmax", "idxmin", "sum"} - and dtype.kind == "f" - ) - ), - reason=("https://github.com/NVIDIA/cudf/issues/14860"), + if dataset_names == ("nans",): + request.applymarker( + pytest.mark.xfail( + condition=( + ( + func in {"var", "std", "mean"} + and str(dtype) in {"int64", "float32", "float64"} + ) + or ( + func in {"idxmax", "idxmin", "sum"} + and dtype.kind == "f" + ) + ), + reason=("https://github.com/NVIDIA/cudf/issues/14860"), + ) ) - ) - dataset = groupby_jit_datasets[dataset].copy(deep=True) - groupby_apply_jit_reductions_test_inner(func, dataset, dtype) + for dataset_name in dataset_names: + dataset = groupby_jit_datasets[dataset_name].copy(deep=True) + groupby_apply_jit_reductions_test_inner(func, dataset, dtype) # test unary reductions for special values @@ -301,26 +307,27 @@ def test_groupby_apply_jit_reductions_special_vals( @pytest.mark.parametrize("func", ["idxmax", "idxmin"]) @pytest.mark.parametrize( - "special_val", + "special_vals", [ pytest.param( - np.nan, + (np.nan,), marks=pytest.mark.xfail( reason="https://github.com/NVIDIA/cudf/issues/13832" ), + id="nan", ), - np.inf, - -np.inf, + pytest.param((np.inf, -np.inf), id="inf"), ], ) @pytest.mark.parametrize("dataset", ["small", "large", "nans"]) def test_groupby_apply_jit_idx_reductions_special_vals( - func, dataset, groupby_jit_datasets, special_val + func, dataset, groupby_jit_datasets, special_vals ): - dataset = groupby_jit_datasets[dataset].copy(deep=True) - groupby_apply_jit_idx_reductions_special_vals_inner( - func, dataset, "float64", special_val - ) + for special_val in special_vals: + data = groupby_jit_datasets[dataset].copy(deep=True) + groupby_apply_jit_idx_reductions_special_vals_inner( + func, data, "float64", special_val + ) def test_groupby_apply_jit_sum_integer_overflow(): @@ -340,46 +347,32 @@ def func(group): @pytest.mark.parametrize("dtype", ["int32", "int64", "float32", "float64"]) -@pytest.mark.parametrize( - "dataset", - [ - pytest.param( - "small", - marks=[ - pytest.mark.filterwarnings( - "ignore:Degrees of Freedom <= 0 for slice" - ), - pytest.mark.filterwarnings( - "ignore:divide by zero encountered in divide" - ), - ], - ), - "large", - ], -) -def test_groupby_apply_jit_correlation(dataset, groupby_jit_datasets, dtype): - dataset = groupby_jit_datasets[dataset].copy(deep=True) - - dataset["val1"] = dataset["val1"].astype(dtype) - dataset["val2"] = dataset["val2"].astype(dtype) - - keys = ["key1"] - - def func(group): - return group["val1"].corr(group["val2"]) - - if np.dtype(dtype).kind == "f": - # Correlation of floating types is not yet supported: - # https://github.com/NVIDIA/cudf/issues/13839 - m = ( - f"Series.corr\\(Series\\) is not " - f"supported for \\({dtype}, {dtype}\\)" - ) - with pytest.raises(UDFError, match=m): +@pytest.mark.filterwarnings("ignore:Degrees of Freedom <= 0 for slice") +@pytest.mark.filterwarnings("ignore:divide by zero encountered in divide") +def test_groupby_apply_jit_correlation(groupby_jit_datasets, dtype): + for dataset_name in ("small", "large"): + dataset = groupby_jit_datasets[dataset_name].copy(deep=True) + + dataset["val1"] = dataset["val1"].astype(dtype) + dataset["val2"] = dataset["val2"].astype(dtype) + + keys = ["key1"] + + def func(group): + return group["val1"].corr(group["val2"]) + + if np.dtype(dtype).kind == "f": + # Correlation of floating types is not yet supported: + # https://github.com/NVIDIA/cudf/issues/13839 + m = ( + f"Series.corr\\(Series\\) is not " + f"supported for \\({dtype}, {dtype}\\)" + ) + with pytest.raises(UDFError, match=m): + run_groupby_apply_jit_test(dataset, func, keys) + continue + with expect_warning_if(dtype in {"int32", "int64"}, RuntimeWarning): run_groupby_apply_jit_test(dataset, func, keys) - return - with expect_warning_if(dtype in {"int32", "int64"}, RuntimeWarning): - run_groupby_apply_jit_test(dataset, func, keys) @pytest.mark.parametrize("dtype", ["int32", "int64"]) From 21ea03ad01fd557d882620a68b627cbe897cc2d8 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sat, 5 Sep 2026 12:08:36 -0700 Subject: [PATCH 03/12] TEST: Reuse JIT cache across GroupBy datasets --- python/cudf/cudf/tests/groupby/test_apply.py | 63 +++++++++++++------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/python/cudf/cudf/tests/groupby/test_apply.py b/python/cudf/cudf/tests/groupby/test_apply.py index b65c1286ec23..fd18bf480fee 100644 --- a/python/cudf/cudf/tests/groupby/test_apply.py +++ b/python/cudf/cudf/tests/groupby/test_apply.py @@ -288,46 +288,63 @@ def func(df): @pytest.mark.parametrize("dtype", ["float64", "float32"]) @pytest.mark.parametrize("func", ["min", "max", "sum", "mean", "var", "std"]) -@pytest.mark.parametrize("dataset", ["small", "large", "nans"]) def test_groupby_apply_jit_reductions_special_vals( - func, dtype, dataset, groupby_jit_datasets + func, dtype, groupby_jit_datasets ): - # All special values use the same generated UDF and input dtypes, so run - # them in one test item to reuse the per-process JIT cache. - for special_val in (np.nan, np.inf, -np.inf): - data = groupby_jit_datasets[dataset].copy(deep=True) - with expect_warning_if( - func in {"var", "std"} and not np.isnan(special_val), - RuntimeWarning, - ): - groupby_apply_jit_reductions_special_vals_inner( - func, data, dtype, special_val - ) + # All datasets and special values use the same generated UDF and input + # dtypes, so run them in one test item to reuse the per-process JIT cache. + for dataset_name in ("small", "large", "nans"): + for special_val in (np.nan, np.inf, -np.inf): + data = groupby_jit_datasets[dataset_name].copy(deep=True) + with expect_warning_if( + func in {"var", "std"} and not np.isnan(special_val), + RuntimeWarning, + ): + groupby_apply_jit_reductions_special_vals_inner( + func, data, dtype, special_val + ) @pytest.mark.parametrize("func", ["idxmax", "idxmin"]) @pytest.mark.parametrize( - "special_vals", + "special_vals,dataset_names", [ pytest.param( (np.nan,), + ("small",), + marks=pytest.mark.xfail( + reason="https://github.com/NVIDIA/cudf/issues/13832" + ), + id="small-nan", + ), + pytest.param( + (np.nan,), + ("large",), + marks=pytest.mark.xfail( + reason="https://github.com/NVIDIA/cudf/issues/13832" + ), + id="large-nan", + ), + pytest.param( + (np.nan,), + ("nans",), marks=pytest.mark.xfail( reason="https://github.com/NVIDIA/cudf/issues/13832" ), - id="nan", + id="nans-nan", ), - pytest.param((np.inf, -np.inf), id="inf"), + pytest.param((np.inf, -np.inf), ("small", "large", "nans"), id="inf"), ], ) -@pytest.mark.parametrize("dataset", ["small", "large", "nans"]) def test_groupby_apply_jit_idx_reductions_special_vals( - func, dataset, groupby_jit_datasets, special_vals + func, dataset_names, groupby_jit_datasets, special_vals ): - for special_val in special_vals: - data = groupby_jit_datasets[dataset].copy(deep=True) - groupby_apply_jit_idx_reductions_special_vals_inner( - func, data, "float64", special_val - ) + for dataset_name in dataset_names: + for special_val in special_vals: + data = groupby_jit_datasets[dataset_name].copy(deep=True) + groupby_apply_jit_idx_reductions_special_vals_inner( + func, data, "float64", special_val + ) def test_groupby_apply_jit_sum_integer_overflow(): From 8f31797abc7720a936b83efcf2f1bec8bb5d8525 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sat, 5 Sep 2026 12:27:56 -0700 Subject: [PATCH 04/12] TEST: Reuse JIT cache for GroupBy unary reductions --- python/cudf/cudf/tests/groupby/test_apply.py | 78 ++++++++++++-------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/python/cudf/cudf/tests/groupby/test_apply.py b/python/cudf/cudf/tests/groupby/test_apply.py index fd18bf480fee..7777d6f60e52 100644 --- a/python/cudf/cudf/tests/groupby/test_apply.py +++ b/python/cudf/cudf/tests/groupby/test_apply.py @@ -203,45 +203,65 @@ def func(df): # test unary reductions +JIT_UNARY_REDUCTION_FUNCTIONS = [ + "min", + "max", + "sum", + "mean", + "var", + "std", + "idxmin", + "idxmax", +] + + +def _nans_unary_reduction_xfails(func, dtype): + return ( + func in {"var", "std", "mean"} + and str(dtype) in {"int64", "float32", "float64"} + ) or (func in {"idxmax", "idxmin", "sum"} and dtype.kind == "f") + + +NANS_UNARY_REDUCTION_XFAIL_PARAMS = [ + pytest.param( + func, + dtype, + marks=pytest.mark.xfail( + reason="https://github.com/NVIDIA/cudf/issues/14860" + ), + id=f"{func}-{dtype}", + ) + for func in JIT_UNARY_REDUCTION_FUNCTIONS + for dtype in SUPPORTED_GROUPBY_NUMPY_TYPES + if _nans_unary_reduction_xfails(func, dtype) +] + + @pytest.mark.parametrize( "dtype", SUPPORTED_GROUPBY_NUMPY_TYPES, ids=[str(t) for t in SUPPORTED_GROUPBY_NUMPY_TYPES], ) -@pytest.mark.parametrize( - "func", ["min", "max", "sum", "mean", "var", "std", "idxmin", "idxmax"] -) -@pytest.mark.parametrize( - "dataset_names", - [ - pytest.param(("small", "large"), id="small-large"), - pytest.param(("nans",), id="nans"), - ], -) -def test_groupby_apply_jit_unary_reductions( - request, func, dtype, dataset_names, groupby_jit_datasets -): - if dataset_names == ("nans",): - request.applymarker( - pytest.mark.xfail( - condition=( - ( - func in {"var", "std", "mean"} - and str(dtype) in {"int64", "float32", "float64"} - ) - or ( - func in {"idxmax", "idxmin", "sum"} - and dtype.kind == "f" - ) - ), - reason=("https://github.com/NVIDIA/cudf/issues/14860"), - ) - ) +@pytest.mark.parametrize("func", JIT_UNARY_REDUCTION_FUNCTIONS) +def test_groupby_apply_jit_unary_reductions(func, dtype, groupby_jit_datasets): + # Keep all passing datasets in one item to reuse the per-process JIT cache. + dataset_names = ["small", "large"] + if not _nans_unary_reduction_xfails(func, dtype): + dataset_names.append("nans") + for dataset_name in dataset_names: dataset = groupby_jit_datasets[dataset_name].copy(deep=True) groupby_apply_jit_reductions_test_inner(func, dataset, dtype) +@pytest.mark.parametrize("func,dtype", NANS_UNARY_REDUCTION_XFAIL_PARAMS) +def test_groupby_apply_jit_unary_reductions_nans_xfail( + func, dtype, groupby_jit_datasets +): + dataset = groupby_jit_datasets["nans"].copy(deep=True) + groupby_apply_jit_reductions_test_inner(func, dataset, dtype) + + # test unary reductions for special values def groupby_apply_jit_reductions_special_vals_inner( func, data, dtype, special_val From 9db96279474caeb4bda50af8379e69708caaee99 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sat, 5 Sep 2026 12:58:40 -0700 Subject: [PATCH 05/12] TEST: Reuse JIT cache for GroupBy special reductions --- python/cudf/cudf/tests/groupby/test_apply.py | 45 +++++++++++--------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/python/cudf/cudf/tests/groupby/test_apply.py b/python/cudf/cudf/tests/groupby/test_apply.py index 7777d6f60e52..5c22ea532dd0 100644 --- a/python/cudf/cudf/tests/groupby/test_apply.py +++ b/python/cudf/cudf/tests/groupby/test_apply.py @@ -213,6 +213,15 @@ def func(df): "idxmin", "idxmax", ] +JIT_UNARY_REDUCTION_SPECIAL_VALUE_FUNCTIONS = [ + "min", + "max", + "sum", + "mean", + "var", + "std", +] +JIT_UNARY_REDUCTION_SPECIAL_VALUE_DTYPES = {"float32", "float64"} def _nans_unary_reduction_xfails(func, dtype): @@ -253,6 +262,23 @@ def test_groupby_apply_jit_unary_reductions(func, dtype, groupby_jit_datasets): dataset = groupby_jit_datasets[dataset_name].copy(deep=True) groupby_apply_jit_reductions_test_inner(func, dataset, dtype) + if ( + func in JIT_UNARY_REDUCTION_SPECIAL_VALUE_FUNCTIONS + and str(dtype) in JIT_UNARY_REDUCTION_SPECIAL_VALUE_DTYPES + ): + # These use the same generated UDF and input dtypes as the ordinary + # reductions above, so keep them in this test item to reuse its cache. + for dataset_name in ("small", "large", "nans"): + for special_val in (np.nan, np.inf, -np.inf): + data = groupby_jit_datasets[dataset_name].copy(deep=True) + with expect_warning_if( + func in {"var", "std"} and not np.isnan(special_val), + RuntimeWarning, + ): + groupby_apply_jit_reductions_special_vals_inner( + func, data, dtype, special_val + ) + @pytest.mark.parametrize("func,dtype", NANS_UNARY_REDUCTION_XFAIL_PARAMS) def test_groupby_apply_jit_unary_reductions_nans_xfail( @@ -306,25 +332,6 @@ def func(df): run_groupby_apply_jit_test(data, func, ["key1"]) -@pytest.mark.parametrize("dtype", ["float64", "float32"]) -@pytest.mark.parametrize("func", ["min", "max", "sum", "mean", "var", "std"]) -def test_groupby_apply_jit_reductions_special_vals( - func, dtype, groupby_jit_datasets -): - # All datasets and special values use the same generated UDF and input - # dtypes, so run them in one test item to reuse the per-process JIT cache. - for dataset_name in ("small", "large", "nans"): - for special_val in (np.nan, np.inf, -np.inf): - data = groupby_jit_datasets[dataset_name].copy(deep=True) - with expect_warning_if( - func in {"var", "std"} and not np.isnan(special_val), - RuntimeWarning, - ): - groupby_apply_jit_reductions_special_vals_inner( - func, data, dtype, special_val - ) - - @pytest.mark.parametrize("func", ["idxmax", "idxmin"]) @pytest.mark.parametrize( "special_vals,dataset_names", From f75d4e4cb3f9293aabb4d2c0060e7839d6144bb6 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sat, 5 Sep 2026 13:27:42 -0700 Subject: [PATCH 06/12] TEST: Reuse JIT cache for GroupBy index reductions --- python/cudf/cudf/tests/groupby/test_apply.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/python/cudf/cudf/tests/groupby/test_apply.py b/python/cudf/cudf/tests/groupby/test_apply.py index 5c22ea532dd0..771828b93797 100644 --- a/python/cudf/cudf/tests/groupby/test_apply.py +++ b/python/cudf/cudf/tests/groupby/test_apply.py @@ -279,6 +279,16 @@ def test_groupby_apply_jit_unary_reductions(func, dtype, groupby_jit_datasets): func, data, dtype, special_val ) + if func in {"idxmin", "idxmax"} and str(dtype) == "float64": + # These share the generated UDF and input dtypes with the ordinary + # reductions above, so keep them in this test item to reuse its cache. + for dataset_name in ("small", "large", "nans"): + for special_val in (np.inf, -np.inf): + data = groupby_jit_datasets[dataset_name].copy(deep=True) + groupby_apply_jit_idx_reductions_special_vals_inner( + func, data, dtype, special_val + ) + @pytest.mark.parametrize("func,dtype", NANS_UNARY_REDUCTION_XFAIL_PARAMS) def test_groupby_apply_jit_unary_reductions_nans_xfail( @@ -360,7 +370,6 @@ def func(df): ), id="nans-nan", ), - pytest.param((np.inf, -np.inf), ("small", "large", "nans"), id="inf"), ], ) def test_groupby_apply_jit_idx_reductions_special_vals( From 4e97db72adbdf31c2b3d9c245fb040accd927ef8 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sun, 6 Sep 2026 16:45:37 -0700 Subject: [PATCH 07/12] TEST: Remove redundant GroupBy nunique parameterization --- python/cudf/cudf/tests/groupby/test_nunique.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/python/cudf/cudf/tests/groupby/test_nunique.py b/python/cudf/cudf/tests/groupby/test_nunique.py index 2ea2effed68f..c633c08b164b 100644 --- a/python/cudf/cudf/tests/groupby/test_nunique.py +++ b/python/cudf/cudf/tests/groupby/test_nunique.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION. +# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 import pandas as pd import pytest @@ -7,9 +7,8 @@ from cudf.testing import assert_groupby_results_equal -@pytest.mark.parametrize("agg", [lambda x: x.nunique(), "nunique"]) @pytest.mark.parametrize("by", ["a", ["a", "b"], ["a", "c"]]) -def test_groupby_nunique(agg, by): +def test_groupby_nunique(by): pdf = pd.DataFrame( {"a": [1, 1, 1, 2, 3], "b": [1, 2, 2, 2, 1], "c": [1, 2, None, 4, 5]} ) From 1fe090ac004ac39e04346ad9822790708ad5538a Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sat, 5 Sep 2026 15:20:49 -0700 Subject: [PATCH 08/12] TEST: Reuse GroupBy JIT datasets --- python/cudf/cudf/tests/groupby/test_apply.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/python/cudf/cudf/tests/groupby/test_apply.py b/python/cudf/cudf/tests/groupby/test_apply.py index 771828b93797..78580aa79bb2 100644 --- a/python/cudf/cudf/tests/groupby/test_apply.py +++ b/python/cudf/cudf/tests/groupby/test_apply.py @@ -103,7 +103,8 @@ def test_groupby_apply_args(func, args): assert_groupby_results_equal(expect, got) -@pytest.fixture +# These source datasets are read-only; tests that modify one take a deep copy. +@pytest.fixture(scope="module") def groupby_jit_data_small(): """ Return a small dataset for testing JIT Groupby Apply. The dataframe @@ -125,7 +126,7 @@ def groupby_jit_data_small(): return df -@pytest.fixture +@pytest.fixture(scope="module") def groupby_jit_data_large(groupby_jit_data_small): """ Larger version of groupby_jit_data_small which contains enough data @@ -142,7 +143,7 @@ def groupby_jit_data_large(groupby_jit_data_small): return df -@pytest.fixture +@pytest.fixture(scope="module") def groupby_jit_data_nans(groupby_jit_data_small): """ Returns a modified version of groupby_jit_data_small which contains @@ -156,7 +157,7 @@ def groupby_jit_data_nans(groupby_jit_data_small): return df -@pytest.fixture +@pytest.fixture(scope="module") def groupby_jit_datasets( groupby_jit_data_small, groupby_jit_data_large, groupby_jit_data_nans ): From abca44236b0d7eb0c76ed10b4778ac213a37c4ff Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sat, 5 Sep 2026 16:27:36 -0700 Subject: [PATCH 09/12] TEST: Build GroupBy JIT data efficiently --- python/cudf/cudf/tests/groupby/test_apply.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/python/cudf/cudf/tests/groupby/test_apply.py b/python/cudf/cudf/tests/groupby/test_apply.py index 78580aa79bb2..ff32a2499859 100644 --- a/python/cudf/cudf/tests/groupby/test_apply.py +++ b/python/cudf/cudf/tests/groupby/test_apply.py @@ -4,6 +4,7 @@ import textwrap from functools import partial +import cupy as cp import numpy as np import pandas as pd import pytest @@ -138,7 +139,12 @@ def groupby_jit_data_large(groupby_jit_data_small): factor = ( max_tpb + 1 ) # bigger than a block but not always an exact multiple - df = cudf.concat([groupby_jit_data_small] * factor) + df = cudf.DataFrame( + { + name: cp.tile(column.values, factor) + for name, column in groupby_jit_data_small.items() + } + ) return df From 24ae0818515d74438c89bd72d96c40278207f346 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sat, 5 Sep 2026 17:00:52 -0700 Subject: [PATCH 10/12] TEST: Reuse GroupBy transform test data --- .../cudf/cudf/tests/groupby/test_transform.py | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/python/cudf/cudf/tests/groupby/test_transform.py b/python/cudf/cudf/tests/groupby/test_transform.py index 5b87cde1e45e..f4c9bd73fab0 100644 --- a/python/cudf/cudf/tests/groupby/test_transform.py +++ b/python/cudf/cudf/tests/groupby/test_transform.py @@ -9,18 +9,23 @@ from cudf.testing import assert_eq, assert_groupby_results_equal -@pytest.fixture(params=[False, True], ids=["no-null-keys", "null-keys"]) +@pytest.fixture( + scope="module", params=[False, True], ids=["no-null-keys", "null-keys"] +) def keys_null(request): return request.param -@pytest.fixture(params=[False, True], ids=["no-null-values", "null-values"]) +@pytest.fixture( + scope="module", params=[False, True], ids=["no-null-values", "null-values"] +) def values_null(request): return request.param -@pytest.fixture +@pytest.fixture(scope="module") def df(keys_null, values_null): + # The transform tests only read these inputs across aggregation variants. keys = ["a", "b", "a", "c", "b", "b", "c", "a"] r = range(len(keys)) if keys_null: @@ -28,14 +33,15 @@ def df(keys_null, values_null): values = list(range(len(keys))) if values_null: values[1::3] = itertools.repeat(None, len(r[1::3])) - return cudf.DataFrame({"key": keys, "values": values}) + gdf = cudf.DataFrame({"key": keys, "values": values}) + return gdf, gdf.to_pandas() @pytest.mark.parametrize("agg", ["cumsum", "cumprod", "max", "sum", "prod"]) def test_transform_broadcast(agg, df): - pf = df.to_pandas() - got = df.groupby("key").transform(agg) - expect = pf.groupby("key").transform(agg) + gdf, pdf = df + got = gdf.groupby("key").transform(agg) + expect = pdf.groupby("key").transform(agg) assert_eq(got, expect, check_dtype=False) From a522d474ed0e3d1b65b0b486968088383c35a6fb Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sat, 5 Sep 2026 22:35:17 -0700 Subject: [PATCH 11/12] TEST: Reuse GroupBy head tail data --- python/cudf/cudf/tests/groupby/test_head_tail.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/cudf/cudf/tests/groupby/test_head_tail.py b/python/cudf/cudf/tests/groupby/test_head_tail.py index 49142c39f76f..78e66079be76 100644 --- a/python/cudf/cudf/tests/groupby/test_head_tail.py +++ b/python/cudf/cudf/tests/groupby/test_head_tail.py @@ -1,4 +1,4 @@ -# 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 import itertools @@ -24,8 +24,9 @@ def preserve_order(request): return request.param -@pytest.fixture +@pytest.fixture(scope="module") def df(): + # The test matrix only reads this source dataframe. return cudf.DataFrame( { "a": [1, 0, 1, 2, 2, 1, 3, 2, 3, 3, 3], From 5ec02591b03cc17f149d6ab6048cad7a298888b0 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sat, 5 Sep 2026 22:42:40 -0700 Subject: [PATCH 12/12] TEST: Reuse GroupBy sample data --- python/cudf/cudf/tests/groupby/test_sample.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/python/cudf/cudf/tests/groupby/test_sample.py b/python/cudf/cudf/tests/groupby/test_sample.py index 0bb1316a1afa..7ec1bf7848b3 100644 --- a/python/cudf/cudf/tests/groupby/test_sample.py +++ b/python/cudf/cudf/tests/groupby/test_sample.py @@ -1,4 +1,4 @@ -# 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 import collections @@ -11,7 +11,10 @@ from cudf.testing import assert_eq -@pytest.fixture(params=["default", "rangeindex", "intindex", "strindex"]) +@pytest.fixture( + scope="module", + params=["default", "rangeindex", "intindex", "strindex"], +) def index(request): n = 12 if request.param == "rangeindex": @@ -27,6 +30,7 @@ def index(request): @pytest.fixture( + scope="module", params=[ ["a", "a", "b", "b", "c", "c", "c", "d", "d", "d", "d", "d"], [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4], @@ -34,6 +38,7 @@ def index(request): ids=["str-group", "int-group"], ) def df(index, request): + # Sampling tests only read this shared source dataframe. return cudf.DataFrame( {"a": request.param, "b": request.param, "v": request.param}, index=index,