Skip to content

feat(compiler): pack dynamic pool allocs by lifetime (hip-pool-allocs) - #570

Open
fhanuman wants to merge 2 commits into
mainfrom
perf/pool-alloc-lifetime-only-port
Open

feat(compiler): pack dynamic pool allocs by lifetime (hip-pool-allocs)#570
fhanuman wants to merge 2 commits into
mainfrom
perf/pool-alloc-lifetime-only-port

Conversation

@fhanuman

@fhanuman fhanuman commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Port of closed PR #469. Its precursor, #468, is already merged into main.

Problem

Dynamic allocs can currently share a pool slab only when they have the same dynamic dimensions. Two lifetime-disjoint allocs with different dynamic dimensions therefore consume the sum of their footprints even though they are never live together.

Fix

Default hip-pool-allocs to lifetime-only dynamic packing:

  • Treat every runtime-sized alloc as its own group.
  • Allow provably lifetime-disjoint groups to share a slab regardless of dynamic dimensions.
  • Size each slab to the maximum footprint of its members.
  • Round small, non-alignment-multiple allocations so subsequent slabs remain aligned.

The previous per-dynamic-dimension best-fit strategy remains available with lifetime-only=false.

Example IR

Two disjoint allocs sized by different dynamic dimensions (%d0, %d1):

Before (stacked — pool = A + B):

%f0 = arith.muli %d0, %c32768 : index      // footprint A
%f1 = arith.muli %d1, %c16384 : index      // footprint B
%sz = arith.addi %f0, %f1 : index          // pool = A + B
%pool = hip.get_pool(%ctx, %sz) : memref<?xi8>
%a = memref.view %pool[%c0] ... : memref<?x8192xf32>
%b = memref.view %pool[%f0] ... : memref<?x4096xf32>   // B after A

After (shared slab — pool = max(A, B)):

%f0 = arith.muli %d0, %c32768 : index
%f1 = arith.muli %d1, %c16384 : index
%sz = arith.maxui %f0, %f1 : index         // pool = max(A, B)
%pool = hip.get_pool(%ctx, %sz) : memref<?xi8>
%a = memref.view %pool[%c0] ... : memref<?x8192xf32>
%b = memref.view %pool[%c0] ... : memref<?x4096xf32>   // aliases A; never co-live

Test plan

  • Pre-commit hooks passed.
  • LIT: 349 passed, 2 unsupported.
  • OutputAllocator and StaticPlugins unit tests passed.

Made with Cursor

Default `hip-pool-allocs` to lifetime-only dynamic packing: each
runtime-sized alloc is its own group, and a cross-group lifetime
coloring lets any two lifetime-disjoint allocs share one pool slab
regardless of their dynamic dimensions. A slab's cost is the MAX of its
concurrently-live members rather than the SUM of every alloc routed to
it. Only provably-disjoint groups ever share, so overlapping their
address ranges is always safe (no mis-pairing).

Small (non-alignment-multiple) allocs ride the same path; a slab that
holds one rounds its width up so the next slab stays aligned.

Keep the previous strategy as a fallback (`lifetime-only=false`): group
by dynamic dimension and best-fit-pack the integer static factors within
a group before the same cross-group coloring, sending non-multiple
allocs to per-size byte-space bins. It is strictly <= the default's
per-group footprint and never mis-pairs.

Rework the debug-only fragmentation report to compare the emitted
dynamic-pool coefficient against the max-load lower bound (single dynamic
factor only), which is the meaningful signal under the new default.

Tests: `hip-pool-allocs-lifetime-only.mlir` covers slab sharing across
different dynamic dims, the overlap-must-not-share guardrail, and the
small-alloc round-up; `hip-pool-allocs-dynamic-binning.mlir` now covers
the fallback path; the fragmentation-report expectations track the new
remark. Validated end-to-end on GPU with a byte-identical pool.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Made-with: Cursor
@github-actions

Copy link
Copy Markdown

Thanks for opening a PR!

This project follows LLVM's incremental-development and AI-tool-use
guidance. See CONTRIBUTING.md
for the project workflow.

Before requesting review, please check that:

  1. The change is focused. Substantial work links the relevant issue
    or design discussion.
  2. The PR documents relevant test results and updates affected
    documentation.
  3. If AI tools provided substantial assistance, the description
    explains what was assisted and how it was validated, and commit
    trailers identify the tool. The contributor has reviewed and
    understands the result.

Reviewers are assigned through
CODEOWNERS where ownership
is configured.

@fhanuman

Copy link
Copy Markdown
Collaborator Author

/run-test models=all

@amd-yanjunz

amd-yanjunz commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

ROCm OGA CI finished with result: SUCCESS.

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

L2 Accuracy Results (EP vs CPU)

Model Combined L2 Total Elems Skipped NaN/Inf
conv_test_hybrid 4.8668E-07 64 0
GroupQueryAttention_seq256 25.2366 2621440 0
MatMulNBits_o_seq128 259.906 368640 0
QMoE_seq128 34.957 368640 0

Threshold: 0.01 | Run: 3432 - Commit: a9715dc

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

MorphiZen EP Performance Results

Model QPS Session (s) 1st Infer (ms) CPU% Mem (MB)
full_model_seq128 7.50 6.12 369 3 1243
GroupQueryAttention_seq128 4363.41 1.66706 10 6 311
matmul_down_seq128 504.45 2.36 73 4 351

EPContext Export Performance

Model QPS Session (s) 1st Infer (ms) CPU% Mem (MB)
full_model_seq128 7.53 45.99 358 3 15590

EPContext Import Performance

Model QPS Session (s) 1st Infer (ms) CPU% Mem (MB)
full_model_seq128 7.51 9.59 358 3 15760

OGA Benchmark Results

Model Warmup Reps Prompt Len Gen Tokens TTFT (ms) TPS Peak Mem (GB) GPU Mem (GB)
gpt-oss-20b-webgpu-int4-rtn-block-32 1 5 128 128 171.7 79.7 1.33 13.54
Llama-3.1-8B-awq-g128-int4-asym-fp16-onnx-dml 1 5 128 128 233.3 42.0 1.22 6.43

OGA Wheel Smoke (Python benchmark_e2e.py)

Model TTFT (ms) TPS
Llama-3.1-8B-awq-g128-int4-asym-fp16-onnx-dml 195 40.8

Run: 3432 - Commit: a9715dc

@fhanuman

Copy link
Copy Markdown
Collaborator Author

/run-test models=all

@amd-yanjunz

amd-yanjunz commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

ROCm OGA CI finished with result: UNSTABLE.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants