Skip to content

RapidsMPF SPMD mode - #21619

Merged
rapids-bot[bot] merged 36 commits into
NVIDIA:mainfrom
madsbk:rapidsmpf-spmd
Mar 6, 2026
Merged

RapidsMPF SPMD mode#21619
rapids-bot[bot] merged 36 commits into
NVIDIA:mainfrom
madsbk:rapidsmpf-spmd

Conversation

@madsbk

@madsbk madsbk commented Mar 2, 2026

Copy link
Copy Markdown
Contributor

This PR adds an spmd cluster type to the streaming executor, enabling multi-GPU execution via the rrun launcher without requiring Dask.

With this mode, users can run the same Python program on multiple ranks (SPMD style) and use RapidsMPF collectives directly from Python. Each rank processes its own slice of data and coordinates through collectives such as allgather.

Example

Launch with:

rrun -n 4 python script.py
from cudf_polars.experimental.rapidsmpf.spmd import (
    allgather_polars_dataframe,
    spmd_execution,
)
from cudf_polars.experimental.rapidsmpf.collectives.common import reserve_op_id

with spmd_execution() as (ctx, engine):
    rank = ctx.comm().rank

    # Each rank holds its own slice of the data
    local = pl.LazyFrame({"a": [rank], "b": [rank * 10]})
    local_result = (
        local.group_by("a")
        .agg(pl.col("b").sum())
        .collect(engine=engine)
    )

    # Gather results from all ranks
    with reserve_op_id() as op_id:
        full_result = allgather_polars_dataframe(
            ctx=ctx, local_df=local_result, op_id=op_id
        )  # all ranks gets an identical copy of `full_result`

Running the pdsh benchmarks

Update: the benchmark update has been moved to a follow-up PR: #21652

@madsbk madsbk self-assigned this Mar 2, 2026
@madsbk madsbk added improvement Improvement / enhancement to an existing function non-breaking Non-breaking change labels Mar 2, 2026
@github-actions github-actions Bot added Python Affects Python cuDF API. cudf-polars Issues specific to cudf-polars labels Mar 2, 2026
@GPUtester GPUtester moved this to In Progress in cuDF Python Mar 2, 2026
@madsbk
madsbk force-pushed the rapidsmpf-spmd branch 2 times, most recently from d1da9cd to 204eebf Compare March 3, 2026 20:04
@madsbk
madsbk marked this pull request as ready for review March 3, 2026 21:16
@madsbk
madsbk requested a review from a team as a code owner March 3, 2026 21:16
@madsbk
madsbk requested review from TomAugspurger and rjzamora March 3, 2026 21:16
@madsbk madsbk added breaking Breaking change and removed non-breaking Non-breaking change labels Mar 4, 2026
Comment thread python/cudf_polars/cudf_polars/utils/config.py Outdated
Comment thread python/cudf_polars/cudf_polars/experimental/rapidsmpf/spmd.py
Comment thread python/cudf_polars/cudf_polars/experimental/rapidsmpf/io.py Outdated
The concatenated output DataFrame and, if ``collect_metadata`` is
True, the list of channel metadata objects; otherwise ``None``.
"""
if config_options.executor.runtime != "rapidsmpf":

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.

There's quite a bit of duplication between this and evaluate_pipeline, though I haven't looked closely to see what the difference is.

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.

I prefer to keep them separate for now. The long-term goal is to remove most of evaluate_pipeline, and eventually drop Dask entirely once this implementation matures.

Comment thread python/cudf_polars/cudf_polars/experimental/rapidsmpf/spmd.py Outdated
if not bootstrap.is_running_with_rrun():
raise RuntimeError(
"spmd_execution() requires the rrun launcher. "
"Use `rrun -n <nproc> python -m pytest ...` to run SPMD tests."

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.

Is there any chance that a user could hit this error, say by misconfiguring their engine? If so, I think we'd want a friendlier error message, ideally telling them what they did wrong.

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.

Yeah, I think we shouldn't mention pytest here.

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.

renamed to:

        raise RuntimeError(
            "spmd_execution() requires the rrun launcher. "
            "Launch your script with `rrun -n <nproc> python your_script.py` "
            "to enable SPMD execution."
        )

Comment thread python/cudf_polars/cudf_polars/experimental/rapidsmpf/spmd.py Outdated
Extra keyword arguments forwarded directly to
:class:`~polars.lazyframe.engine_config.GPUEngine`. For example,
pass ``parquet_options={"use_rapidsmpf_native": True}`` to enable
native Parquet reads.

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.

Maybe note that "raise_on_fail", "memory_resource", "executor" are reserved, like you did for exeuctor_options?

And just confirming, we do want to hardcode raise_on_fail here? I understand why the others have to be hardcoded.

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.

Why do we hardcode raise_on_fail?
I have removed it here

@madsbk
madsbk requested a review from TomAugspurger March 5, 2026 15:43

@wence- wence- left a comment

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.

tiny fixes

Comment thread python/cudf_polars/cudf_polars/experimental/benchmarks/pdsds.py
Comment thread python/cudf_polars/cudf_polars/experimental/rapidsmpf/core.py Outdated
Comment thread python/cudf_polars/cudf_polars/experimental/rapidsmpf/spmd.py
Comment thread python/cudf_polars/cudf_polars/experimental/rapidsmpf/spmd.py Outdated
Comment thread python/cudf_polars/cudf_polars/experimental/rapidsmpf/spmd.py Outdated
if not bootstrap.is_running_with_rrun():
raise RuntimeError(
"spmd_execution() requires the rrun launcher. "
"Use `rrun -n <nproc> python -m pytest ...` to run SPMD tests."

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.

Yeah, I think we shouldn't mention pytest here.

@madsbk

madsbk commented Mar 6, 2026

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit 54477aa into NVIDIA:main Mar 6, 2026
89 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in cuDF Python Mar 6, 2026
@madsbk
madsbk deleted the rapidsmpf-spmd branch March 6, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Breaking change cudf-polars Issues specific to cudf-polars improvement Improvement / enhancement to an existing function Python Affects Python cuDF API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants