Skip to content

Add basic runtime profiling in cudf-polars - #21277

Closed
rjzamora wants to merge 28 commits into
NVIDIA:mainfrom
rjzamora:profiling-config
Closed

Add basic runtime profiling in cudf-polars#21277
rjzamora wants to merge 28 commits into
NVIDIA:mainfrom
rjzamora:profiling-config

Conversation

@rjzamora

Copy link
Copy Markdown
Contributor

Description

Checklist

  • I am familiar with the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

@rjzamora rjzamora self-assigned this Jan 30, 2026
@rjzamora
rjzamora requested a review from a team as a code owner January 30, 2026 21:37
@rjzamora
rjzamora requested a review from wence- January 30, 2026 21:37
@rjzamora rjzamora added the 3 - Ready for Review Ready for review by team label Jan 30, 2026
@rjzamora rjzamora added improvement Improvement / enhancement to an existing function non-breaking Non-breaking change labels Jan 30, 2026
@github-actions github-actions Bot added Python Affects Python cuDF API. cudf-polars Issues specific to cudf-polars labels Jan 30, 2026
@GPUtester GPUtester moved this to In Progress in cuDF Python Jan 30, 2026
@rjzamora

Copy link
Copy Markdown
Contributor Author

cc @TomAugspurger

@TomAugspurger

Copy link
Copy Markdown
Contributor

Could you share a bit of background on the goal here, and what type of information we're trying to collect, and what our desired output looks like?

And I'll look more closely, but I'm especially curious whether we'd be able to integrate this into our cudf-polars tracing at https://github.com/rapidsai/cudf/blob/main/python/cudf_polars/cudf_polars/dsl/tracing.py. I think that we might already have some things like node count (if we mean the same thing for "node": a cudf-polars IR node):

❯ CUDF_POLARS_LOG_TRACES=1 python -m cudf_polars.experimental.benchmarks.pdsh --path /datasets/toaugspurger/tpch-rs/scale-10/ --suffix "" --iterations 1 1 --no-print-results --no-summarize
2026-01-30 13:50:01 [info     ] Execute IR                     count_frames_input=0 count_frames_output=1 frames_input=[] frames_output=[{'shape': (59142609, 7), 'size': 2957130458}] nvml_current_bytes_input=320864256 nvml_current_bytes_output=331350016 overhead_duration=2412492 rmm_current_bytes_input=0 rmm_current_bytes_output=2957130458 rmm_current_count_input=0 rmm_current_count_output=9 rmm_peak_bytes_input=0 rmm_peak_bytes_output=8592351777 rmm_peak_count_input=0 rmm_peak_count_output=120 rmm_total_bytes_input=0 rmm_total_bytes_output=10498498090 rmm_total_count_input=0 rmm_total_count_output=225 start=14767367239405135 stop=14767367600357750 total_bytes_input=0 total_bytes_output=2957130458 type=Scan
2026-01-30 13:50:01 [info     ] Execute IR                     count_frames_input=0 count_frames_output=1 frames_input=[] frames_output=[{'shape': (59142609, 8), 'size': 3430271330}] nvml_current_bytes_input=331350016 nvml_current_bytes_output=333447168 overhead_duration=1024010 rmm_current_bytes_input=2957130458 rmm_current_bytes_output=3430271330 rmm_current_count_input=9 rmm_current_count_output=10 rmm_peak_bytes_input=8592351777 rmm_peak_bytes_output=8592351777 rmm_peak_count_input=120 rmm_peak_count_output=120 rmm_total_bytes_input=10498498090 rmm_total_bytes_output=11444779860 rmm_total_count_input=225 rmm_total_count_output=232 start=14767367602411727 stop=14767367615460387 total_bytes_input=0 total_bytes_output=3430271330 type=HStack
2026-01-30 13:50:01 [info     ] Execute IR                     count_frames_input=1 count_frames_output=1 frames_input=[{'shape': (59142609, 8), 'size': 3430271330}] frames_output=[{'shape': (4, 10), 'size': 288}] nvml_current_bytes_input=333447168 nvml_current_bytes_output=339738624 overhead_duration=1327672 rmm_current_bytes_input=3430271330 rmm_current_bytes_output=3430271618 rmm_current_count_input=10 rmm_current_count_output=22 rmm_peak_bytes_input=8592351777 rmm_peak_bytes_output=8592351777 rmm_peak_count_input=120 rmm_peak_count_output=120 rmm_total_bytes_input=11444779860 rmm_total_bytes_output=13574741458 rmm_total_count_input=232 rmm_total_count_output=276 start=14767367616781167 stop=14767367739343388 total_bytes_input=3430271330 total_bytes_output=288 type=GroupBy
...

The list under frames_output have the shapes / sizes.

That's built on structlog, which I think gives us a couple of additional nice things:

  1. We can rely on the normal logging config for collection / persisting to file
  2. We can use context variables to propagate node-specific data we want to log (like a runtime decision on what join algorithm to use) from the IR.do_evaluate to the site where the record is logged without having to pass around object everywhere.

@rjzamora

Copy link
Copy Markdown
Contributor Author

Right now, this just allows us to view the plan after the run with real row- and chunk-count statistics. For example, if I pass in the --profile-output-path to pdsh, I get something like this for q6 (running on 4 ranks):

SELECT ('revenue',) rows=4 chunks=4
  SELECT ('_______________1',) rows=4 chunks=4
    REPARTITION ('_______________0',) rows=204 chunks=4
      SELECT ('_______________0',) rows=51 chunks=51
        HSTACK ('l_extendedprice', 'l_discount', 'l_quantity', 'l_shipdate', 'revenue') rows=34.26 M chunks=51
          SCAN PARQUET ('l_extendedprice', 'l_discount', 'l_quantity', 'l_shipdate') rows=34.26 M chunks=51

This is "nice to have", but the my biggest motivation for pushing this in now is that I've also been traking a decision= metric in my dynamic-planning work. This way I can see what kind of algorithm was used for GroupBy/Join/Distinct. Otherwise, there is currently no way to know without print statements.

With that said, I'm very happy to do something different here. In the short term, I just need a mechanism to review an adaptive plan.

@rjzamora
rjzamora requested review from a team as code owners February 3, 2026 17:39
@github-actions github-actions Bot added libcudf Affects libcudf (C++/CUDA) code. CMake CMake build issue cudf.pandas Issues specific to cudf.pandas pylibcudf Issues specific to the pylibcudf package labels Feb 3, 2026
@rjzamora

rjzamora commented Feb 3, 2026

Copy link
Copy Markdown
Contributor Author

Closing in favor of #21309

@rjzamora rjzamora closed this Feb 3, 2026
@github-project-automation github-project-automation Bot moved this from In Progress to Done in cuDF Python Feb 3, 2026
@rjzamora rjzamora mentioned this pull request Feb 3, 2026
3 tasks
rapids-bot Bot pushed a commit that referenced this pull request Feb 5, 2026
- Closes #21244
- **Another** Alternative to #21277 and #21309
- Part of #20482

Authors:
  - Richard (Rick) Zamora (https://github.com/rjzamora)

Approvers:
  - Tom Augspurger (https://github.com/TomAugspurger)

URL: #21316
@rjzamora
rjzamora deleted the profiling-config branch February 6, 2026 19:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3 - Ready for Review Ready for review by team CMake CMake build issue cudf.pandas Issues specific to cudf.pandas cudf-polars Issues specific to cudf-polars improvement Improvement / enhancement to an existing function libcudf Affects libcudf (C++/CUDA) code. non-breaking Non-breaking change pylibcudf Issues specific to the pylibcudf package Python Affects Python cuDF API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEA] Add IR-node profiling for the rapidsmpf runtime

3 participants