Skip to content

[Multi-GPU Polars] Ray mode in PDSH benchmarks - #21811

Merged
rapids-bot[bot] merged 4 commits into
NVIDIA:mainfrom
madsbk:rapidsmpf-ray-benchmarks
Mar 18, 2026
Merged

[Multi-GPU Polars] Ray mode in PDSH benchmarks#21811
rapids-bot[bot] merged 4 commits into
NVIDIA:mainfrom
madsbk:rapidsmpf-ray-benchmarks

Conversation

@madsbk

@madsbk madsbk commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

Update the PDSH benchmarks to support --cluster=ray runs.

Run using something like:

python \
  python/cudf_polars/cudf_polars/experimental/benchmarks/pdsh.py \
  --executor=streaming \
  --suffix="" \
  --spill-device=0.5 \
  --shuffle=rapidsmpf \
  --runtime=rapidsmpf \
  --stream-policy=pool \
  --no-print-results --no-summarize \
  --iterations=10 \
  --path /datasets/datasets/tpch-rs/scale-10 \
  --cluster ray \
  1

@madsbk madsbk self-assigned this Mar 17, 2026
@madsbk madsbk added improvement Improvement / enhancement to an existing function non-breaking Non-breaking change labels Mar 17, 2026
@github-actions github-actions Bot added Python Affects Python cuDF API. cudf-polars Issues specific to cudf-polars labels Mar 17, 2026
@GPUtester GPUtester moved this to In Progress in cuDF Python Mar 17, 2026
@madsbk
madsbk marked this pull request as ready for review March 17, 2026 10:21
@madsbk
madsbk requested a review from a team as a code owner March 17, 2026 10:21

@TomAugspurger TomAugspurger 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.

Trying this out locally, I hit

Traceback (most recent call last):
  File "/home/nfs/toaugspurger/gh/rapidsai/cudf/python/cudf_polars/cudf_polars/experimental/benchmarks/pdsh.py", line 1804, in <module>
    run_polars(PDSHQueries, args)
    ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "/home/nfs/toaugspurger/gh/rapidsai/cudf/python/cudf_polars/cudf_polars/experimental/benchmarks/utils.py", line 1766, in run_polars
    run_polars_ray(
    ~~~~~~~~~~~~~~^
        benchmark,
        ^^^^^^^^^^
    ...<5 lines>...
        validation_files,
        ^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/nfs/toaugspurger/gh/rapidsai/cudf/python/cudf_polars/cudf_polars/experimental/benchmarks/utils.py", line 1955, in run_polars_ray
    with ray_execution(
         ~~~~~~~~~~~~~^
        executor_options=executor_options,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        engine_options=engine_options,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ) as (ray_client, engine):
    ^
  File "/home/nfs/toaugspurger/gh/rapidsai/cudf/python/cudf_polars/cudf_polars/experimental/rapidsmpf/frontend/ray.py", line 615, in ray_execution
    root_ucxx_address_as_bytes = ray.get(rank_actors[0].setup_root.remote())
  File "/raid/toaugspurger/envs/gh/rapidsai/cudf/lib/python3.13/site-packages/ray/_private/auto_init_hook.py", line 22, in auto_init_wrapper
    return fn(*args, **kwargs)
  File "/raid/toaugspurger/envs/gh/rapidsai/cudf/lib/python3.13/site-packages/ray/_private/client_mode_hook.py", line 104, in wrapper
    return func(*args, **kwargs)
  File "/raid/toaugspurger/envs/gh/rapidsai/cudf/lib/python3.13/site-packages/ray/_private/worker.py", line 2981, in get
    values, debugger_breakpoint = worker.get_objects(
                                  ~~~~~~~~~~~~~~~~~~^
        object_refs, timeout, use_object_store=_use_object_store
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/raid/toaugspurger/envs/gh/rapidsai/cudf/lib/python3.13/site-packages/ray/_private/worker.py", line 1014, in get_objects
    raise value
ray.exceptions.ActorDiedError: The actor died because of an error raised in its creation task, ray::RankActor.__init__() (pid=2859867, ip=10.33.227.162, actor_id=dfbdb6136704c13c8ef33ba101000000, repr=<cudf_polars.experimental.rapidsmpf.frontend.ray.FunctionActorManager._create_fake_actor_class.<locals>.TemporaryActor object at 0x7fd68c0df770>)
    ...<4 lines>...
    )
RuntimeError: The actor with name RankActor failed to import on the worker. This may be because needed library dependencies are not installed in the worker environment:

IIRC, you might have hit that as well. Did you come to a conclusion on what caused it?

)
executor_options = get_executor_options(run_config, benchmark=benchmark)
# "runtime", "cluster" are reserved — ray_execution sets them
executor_options.pop("runtime", None)

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.

Validate that the user didn't pass something here? I guess the default is tasks, which makes this not straightforward :/

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 say we just raise an error? The Ray frontend requires the "rapidsmpf" runtime for sure.

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.

The plan is to remove the runtime option altogether. The runtime is implied by the chosen cluster; you simply set --cluster <single | ray | dask | spmd> (we may rename this to --frontend).

Currently, --cluster <spmd | ray> ignores --runtime, but it still affects performance. For example:

  1. Sampling is only enabled with runtime="rapidsmpf".
  2. The native C++ Parquet reader is only enabled with runtime="rapidsmpf".

For now, let’s ignore the --runtime option, but this is another strong reason to standardize all benchmark options and logging!

default=None,
type=str,
choices=["single", "distributed", "spmd"],
choices=["single", "distributed", "spmd", "ray"],

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.

Just a note (nothing to do in this PR): I'd like to see these options become ["single", "dask", "spmd", "ray"] for 26.06

Comment on lines +1940 to +1942
raise NotImplementedError(
"--collect-traces is not yet supported with --cluster ray."
)

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.

Can you describe the blocker for this? I use this option extensively when I debug performance.

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.

The blocker is mainly that I do not yet have the full picture. I want to take this design one step at a time.
Once the new Dask frontend and its benchmark are merged, I plan to work on:

  • Standardizing all configuration options by defining a clear policy for how cudf-polars options propagate to RapidsMPF, and which options must be configured directly in RapidsMPF rather than through cudf-polars.
  • Standardizing all benchmark options and logging.

Comment on lines +1944 to +1946
raise NotImplementedError(
"--rmm-async is not yet supported with --cluster ray."
)

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.

Are we just always using the async allocator with Ray?

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.

Are we accounting for --spill-device anywhere? That option is pretty critical for tuning performance in our nightlies.

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.

Currently, you would have to set RAPIDSMPF_SPILL_DEVICE_LIMIT.

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.

Are we just always using the async allocator with Ray?

yes

)
executor_options = get_executor_options(run_config, benchmark=benchmark)
# "runtime", "cluster" are reserved — ray_execution sets them
executor_options.pop("runtime", None)

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 say we just raise an error? The Ray frontend requires the "rapidsmpf" runtime for sure.

args,
run_config,
engine,
None,

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.

This is the client argument, right? Do we need _run_query_loop/etc to handle the Ray client to do collect traces and statistics?

@madsbk madsbk Mar 18, 2026

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.

Yes, we would need to either implement a general run method on the ray client, or implement specific logging methods.

@madsbk

madsbk commented Mar 18, 2026

Copy link
Copy Markdown
Contributor Author

Trying this out locally, I hit
...
IIRC, you might have hit that as well. Did you come to a conclusion on what caused it?

Yes, I ran into that as well when using the pip installation. In a conda environment, it seems to work.
It appears to be related to the ucxx pip package failing to load on the workers. I am still investigating it.

UPDATE: Hopefully, this fixes the issue: rapidsai/rapidsmpf#921

@NVIDIA NVIDIA deleted a comment from copy-pr-bot Bot Mar 18, 2026
@madsbk madsbk mentioned this pull request Mar 18, 2026
@madsbk
madsbk requested a review from rjzamora March 18, 2026 13:14

@rjzamora rjzamora 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.

Looks good. Approving since I'm expecting more changes to follow anyway.

My only remaining concern is that the spill-device argument is ignored, and so users may try to tune this value and not understand why it's having no effect.

@madsbk

madsbk commented Mar 18, 2026

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit 8fc7f3b into NVIDIA:main Mar 18, 2026
163 of 166 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in cuDF Python Mar 18, 2026
@madsbk
madsbk deleted the rapidsmpf-ray-benchmarks branch March 18, 2026 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants