Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 3 additions & 10 deletions ci/run_cudf_polars_experimental_pytests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,11 @@ set -euo pipefail
# Support invoking outside the script directory
cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/../python/cudf_polars/

rapids-logger "Running experimental legacy tests with the 'rapidsmpf' runtime and a 'single' cluster"
timeout 10m python -m pytest --cache-clear "$@" "tests" \
--executor streaming \
--cluster single \
--runtime rapidsmpf \
--blocksize-mode small
echo "Running the full cudf-polars test suite with both the in-memory and spmd engine"
timeout 10m python -m pytest --cache-clear "$@" tests --ignore=tests/experimental/legacy

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.

How close are we to collapsing these two pytest calls into ci/run_cudf_polars_pytests.sh?

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.

I suppose a final state of these existing runs should be

  1. With the in-memory executor
  2. With the streaming executor, single cluster with rapidsmpf
  3. With the streaming executor, distributed dask cluster with rapidsmpf

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hopefully we can remove all the legacy code next week.

At that point, we’ll be left with the in-memory engine alongside RayEngine, DaskEngine, and SPMDEngine.


rapids-logger "Running experimental legacy tests with the 'rapidsmpf' runtime and a 'distributed' cluster"
echo "Running experimental legacy tests with the 'rapidsmpf' runtime and a 'distributed' cluster"
Comment thread
gforsyth marked this conversation as resolved.
timeout 10m python -m pytest --cache-clear "$@" "tests/experimental/legacy" \
--executor streaming \
--cluster distributed \
--runtime rapidsmpf

rapids-logger "Running experimental tests"
timeout 10m python -m pytest --cache-clear "$@" tests/experimental --ignore=tests/experimental/legacy
7 changes: 1 addition & 6 deletions ci/run_cudf_polars_pytests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,4 @@ set -euo pipefail
# Support invoking run_cudf_polars_pytests.sh outside the script directory
cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/../python/cudf_polars/

# Run all non-experimental tests using both the in-memory and streaming executor.
IGNORE_EXPERIMENTAL="--ignore=tests/experimental/"
python -m pytest --cache-clear "$@" tests $IGNORE_EXPERIMENTAL --executor in-memory
python -m pytest --cache-clear "$@" tests $IGNORE_EXPERIMENTAL --executor streaming
python -m pytest --cache-clear "$@" tests $IGNORE_EXPERIMENTAL --executor streaming \
--blocksize-mode small
python -m pytest --cache-clear "$@" tests --ignore=tests/experimental
Comment thread
mroeschke marked this conversation as resolved.
60 changes: 15 additions & 45 deletions python/cudf_polars/cudf_polars/testing/asserts.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@
from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING, Any, Literal
from typing import TYPE_CHECKING, Any

import polars as pl
from polars import GPUEngine
from polars.testing.asserts import assert_frame_equal

from cudf_polars.dsl.translate import Translator
from cudf_polars.utils.config import ConfigOptions, StreamingFallbackMode
from cudf_polars.utils.config import ConfigOptions
from cudf_polars.utils.versions import POLARS_VERSION_LT_1323

if TYPE_CHECKING:
from cudf_polars.typing import OptimizationArgs
from cudf_polars.typing import CollectKwargs


__all__: list[str] = [
Expand All @@ -32,16 +32,15 @@
DEFAULT_EXECUTOR = "in-memory"
DEFAULT_RUNTIME = "tasks"
DEFAULT_CLUSTER = "single"
DEFAULT_BLOCKSIZE_MODE: Literal["small", "default"] = "default"


def assert_gpu_result_equal(
lazydf: pl.LazyFrame,
*,
engine: GPUEngine | None = None,
collect_kwargs: dict[OptimizationArgs, bool] | None = None,
polars_collect_kwargs: dict[OptimizationArgs, bool] | None = None,
cudf_collect_kwargs: dict[OptimizationArgs, bool] | None = None,
collect_kwargs: CollectKwargs | None = None,
polars_collect_kwargs: CollectKwargs | None = None,
cudf_collect_kwargs: CollectKwargs | None = None,
check_row_order: bool = True,
check_column_order: bool = True,
check_dtypes: bool = True,
Expand All @@ -50,7 +49,6 @@ def assert_gpu_result_equal(
atol: float = 1e-08,
categorical_as_str: bool = False,
executor: str | None = None,
blocksize_mode: Literal["small", "default"] | None = None,
) -> None:
"""
Assert that collection of a lazyframe on GPU produces correct results.
Expand Down Expand Up @@ -91,12 +89,6 @@ def assert_gpu_result_equal(
executor
The executor configuration to pass to `GPUEngine`. If not specified
uses the module level `Executor` attribute.
blocksize_mode
The "mode" to use for choosing the blocksize for the streaming executor.
If not specified, uses the module level ``DEFAULT_BLOCKSIZE_MODE`` attribute.
Set to "small" to configure small values for ``max_rows_per_partition``
and ``target_partition_size``, which will typically cause many partitions
to be created while executing the query.

Raises
------
Expand All @@ -105,7 +97,7 @@ def assert_gpu_result_equal(
NotImplementedError
If GPU collection failed in some way.
"""
engine = engine or get_default_engine(executor, blocksize_mode)
engine = engine or get_default_engine(executor)
final_polars_collect_kwargs, final_cudf_collect_kwargs = _process_kwargs(
collect_kwargs, polars_collect_kwargs, cudf_collect_kwargs
)
Expand Down Expand Up @@ -184,7 +176,6 @@ def assert_ir_translation_raises(q: pl.LazyFrame, *exceptions: type[Exception])

def get_default_engine(
executor: str | None = None,
blocksize_mode: Literal["small", "default"] | None = None,
) -> GPUEngine:
"""
Get the default engine used for testing.
Expand All @@ -194,12 +185,6 @@ def get_default_engine(
executor
The executor configuration to pass to `GPUEngine`. If not specified
uses the module level `Executor` attribute.
blocksize_mode
The "mode" to use for choosing the blocksize for the streaming executor.
If not specified, uses the module level ``DEFAULT_BLOCKSIZE_MODE`` attribute.
Set to "small" to configure small values for ``max_rows_per_partition``
and ``target_partition_size``, which will typically cause many partitions
to be created while executing the query.

Returns
-------
Expand All @@ -217,14 +202,6 @@ def get_default_engine(
executor_options["cluster"] = DEFAULT_CLUSTER
executor_options["runtime"] = DEFAULT_RUNTIME

blocksize_mode = blocksize_mode or DEFAULT_BLOCKSIZE_MODE

if blocksize_mode == "small": # pragma: no cover
executor_options["max_rows_per_partition"] = 4
executor_options["target_partition_size"] = 10
# We expect many tests to fall back, so silence the warnings
executor_options["fallback_mode"] = StreamingFallbackMode.SILENT

return GPUEngine(
raise_on_fail=True,
executor=executor,
Expand All @@ -233,10 +210,10 @@ def get_default_engine(


def _process_kwargs(
collect_kwargs: dict[OptimizationArgs, bool] | None,
polars_collect_kwargs: dict[OptimizationArgs, bool] | None,
cudf_collect_kwargs: dict[OptimizationArgs, bool] | None,
) -> tuple[dict[OptimizationArgs, bool], dict[OptimizationArgs, bool]]:
collect_kwargs: CollectKwargs | None,
polars_collect_kwargs: CollectKwargs | None,
cudf_collect_kwargs: CollectKwargs | None,
) -> tuple[CollectKwargs, CollectKwargs]:
if collect_kwargs is None:
collect_kwargs = {}
final_polars_collect_kwargs = collect_kwargs.copy()
Expand All @@ -253,9 +230,9 @@ def assert_collect_raises(
*,
polars_except: type[Exception] | tuple[type[Exception], ...],
cudf_except: type[Exception] | tuple[type[Exception], ...],
collect_kwargs: dict[OptimizationArgs, bool] | None = None,
polars_collect_kwargs: dict[OptimizationArgs, bool] | None = None,
cudf_collect_kwargs: dict[OptimizationArgs, bool] | None = None,
collect_kwargs: CollectKwargs | None = None,
polars_collect_kwargs: CollectKwargs | None = None,
cudf_collect_kwargs: CollectKwargs | None = None,
) -> None:
"""
Assert that collecting the result of a query raises the expected exceptions.
Expand Down Expand Up @@ -350,7 +327,6 @@ def assert_sink_result_equal(
read_kwargs: dict | None = None,
write_kwargs: dict | None = None,
executor: str | None = None,
blocksize_mode: Literal["small", "default"] | None = None,
) -> None:
"""
Assert that writing a LazyFrame via sink produces the same output.
Expand All @@ -371,12 +347,6 @@ def assert_sink_result_equal(
executor
The executor configuration to pass to `GPUEngine`. If not specified
uses the module level `Executor` attribute.
blocksize_mode
The "mode" to use for choosing the blocksize for the streaming executor.
If not specified, uses the module level ``DEFAULT_BLOCKSIZE_MODE`` attribute.
Set to "small" to configure small values for ``max_rows_per_partition``
and ``target_partition_size``, which will typically cause many partitions
to be created while executing the query.

Raises
------
Expand All @@ -385,7 +355,7 @@ def assert_sink_result_equal(
ValueError
If the file extension is not one of the supported formats.
"""
engine = engine or get_default_engine(executor, blocksize_mode)
engine = engine or get_default_engine(executor)
path = Path(path)
read_kwargs = read_kwargs or {}
write_kwargs = write_kwargs or {}
Expand Down
4 changes: 4 additions & 0 deletions python/cudf_polars/cudf_polars/typing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

__all__: list[str] = [
"ClosedInterval",
"CollectKwargs",
"ColumnHeader",
"ColumnOptions",
"DataFrameHeader",
Expand Down Expand Up @@ -145,8 +146,11 @@ def set_udf(
"comm_subexpr_elim",
"cluster_with_columns",
"no_optimization",
"optimizations",
]

CollectKwargs: TypeAlias = dict[OptimizationArgs, bool | pl.QueryOptFlags]


U_contra = TypeVar("U_contra", bound=Hashable, contravariant=True)
V_co = TypeVar("V_co", covariant=True)
Expand Down
Loading
Loading