Skip to content

fix(clr): give graph signal sets back to a device pool instead of destroying them - #14878

Merged
saleelk merged 1 commit into
developfrom
users/saleelk/clr-graph-signal-pool
Nov 3, 2026
Merged

saleelk merged 1 commit into
developfrom
users/saleelk/clr-graph-signal-pool

Conversation

@saleelk

@saleelk saleelk commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Each graph executable takes its signal sets from GraphSignalManager,
which pre-creates 16 at instantiation and creates another on the launch
path whenever more launches are in flight. Each set was its own signal
batch, an allocation in device memory, and destroying the executable
destroyed every set. The last destroy of a batch's signals frees the
allocation with an unmap from the GPU, about 230 us per set in PyFR's
graphs.

With DEBUG_CLR_DEV_SIGNALS=1 those destroys landed in later graph
launches. RetiringSignalTracker keeps a reference to each signal its
GPU waits depend on, until the waits have passed, so it often held the
last reference to a destroyed graph's signals. It releases them from
Reclaim, 64 at a time, inside whichever hipGraphLaunch runs next:
PyFR's Couette graphs stalled for 4 to 15 ms every 16 launches after
another graph was destroyed. Without device signals the same destroys
ran inside hipGraphExecDestroy.

Devices now keep a pool of armed graph signals. AcquireHwEvents takes a
set from it, creating signals in batches of at least 256 when it runs
short, and ReturnHwEvents gives a set back. GraphSignalManager takes its
pre-created sets and the sets for extra launches in flight from the
pool, and returns them when the executable is destroyed or rebuilt for
a different set size. The pool holds a reference to each signal, so the
tracker's release never destroys one, and the pool's signals are only
destroyed with the device.

PyFR Couette graph launches, DEBUG_HIP_GRAPH_MIN_OVERLAP=0, MI300X,
DEBUG_CLR_DEV_SIGNALS=1:

graph avg launch us launches over 500 us
before after before after
graph_3 30.9 31.1 0 0
graph_5 27.7 8.9 4 0
graph_7 44.6 15.7 3 0

Medians, device time and the step simulation are unchanged. Without
device signals, the run creates 11 signal batches instead of 456, and
instantiation is faster (graph_7: 13.2 to 5.2 ms).

Testing

  • PyFR Couette graph perf tests (hipGraphPyFRCouette.cc) with
    DEBUG_HIP_GRAPH_MIN_OVERLAP=0 and DEBUG_CLR_DEV_SIGNALS=0 and 1: the
    numbers above. An LD_PRELOAD probe that times every hipGraphLaunch
    finds no launch over 500 us with this change; on develop the slow
    launches spent their time in hsa_signal_destroy, called from
    RetiringSignalTracker::ReleasePins.

JIRA ID : AIRUNTIME-2943

@saleelk
saleelk requested a review from a team as a code owner November 2, 2026 23:03
@therock-pr-bot

therock-pr-bot Bot commented Nov 2, 2026

Copy link
Copy Markdown

✅ All Policy Checks Passed

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ⚠️ Warning Error: Source/code files changed without an accompanying unit test.
Expected: add at least one test file named like test_<name>.py / test_<name>.cpp (or <name>_test.*).
Current: code file(s) changed: projects/clr/hipamd/src/hip_graph_internal.cpp, projects/clr/hipamd/src/hip_graph_internal.hpp, projects/clr/rocclr/device/device.hpp, projects/clr/rocclr/device/rocm/rocdevice.cpp, projects/clr/rocclr/device/rocm/rocdevice.hpp; no test file found
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —

🎉 All policy checks passed!

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

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

🤖 AI-assisted pre-review (for @mangupta)

Comment thread projects/clr/rocclr/device/device.hpp Resolved
…troying them

Each graph executable takes its signal sets from GraphSignalManager,
which pre-creates 16 at instantiation and creates another on the launch
path whenever more launches are in flight. Each set was its own signal
batch, an allocation in device memory, and destroying the executable
destroyed every set. The last destroy of a batch's signals frees the
allocation with an unmap from the GPU, about 230 us per set in PyFR's
graphs.

With DEBUG_CLR_DEV_SIGNALS=1 those destroys landed in later graph
launches. RetiringSignalTracker keeps a reference to each signal its
GPU waits depend on, until the waits have passed, so it often held the
last reference to a destroyed graph's signals. It releases them from
Reclaim, 64 at a time, inside whichever hipGraphLaunch runs next:
PyFR's Couette graphs stalled for 4 to 15 ms every 16 launches after
another graph was destroyed. Without device signals the same destroys
ran inside hipGraphExecDestroy.

Devices now keep a pool of armed graph signals. AcquireHwEvents takes a
set from it, creating signals in batches of at least 256 when it runs
short, and ReturnHwEvents gives a set back. GraphSignalManager takes its
pre-created sets and the sets for extra launches in flight from the
pool, and returns them when the executable is destroyed or rebuilt for
a different set size. The pool holds a reference to each signal, so the
tracker's release never destroys one, and the pool's signals are only
destroyed with the device.

PyFR Couette graph launches, DEBUG_HIP_GRAPH_MIN_OVERLAP=0, MI300X,
DEBUG_CLR_DEV_SIGNALS=1:

  graph     avg launch us       launches over 500 us
            before   after      before   after
  graph_3   30.9     31.1       0        0
  graph_5   27.7     8.9        4        0
  graph_7   44.6     15.7       3        0

Medians, device time and the step simulation are unchanged. Without
device signals, the run creates 11 signal batches instead of 456, and
instantiation is faster (graph_7: 13.2 to 5.2 ms).
@saleelk
saleelk force-pushed the users/saleelk/clr-graph-signal-pool branch from a3b383a to c93560a Compare November 3, 2026 02:35
@mangupta

mangupta commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

🤖 AI-assisted pre-review (for @mangupta)

Re-reviewed the updated head (c93560ac7400) — no new findings at or above the posting threshold.

@saleelk
saleelk merged commit 513c963 into develop Nov 3, 2026
409 of 412 checks passed
@saleelk
saleelk deleted the users/saleelk/clr-graph-signal-pool branch November 3, 2026 17:17
@systems-assistant

Copy link
Copy Markdown
Contributor

TheRock Submodule Bump Activity

Newest first

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants