amd-agi/geak/roofline
Claude Code and agent skill by amd-agi/geak
- community
Checking that the SKILL.md file is still in the repository.
Install
npx vskill@latest install amd-agi/geak/rooflineSKILL.md
SKILL — roofline headroom analysis
Turn the standardized Top-N into a per-kernel answer to: "how much of this hardware's ceiling is this kernel already getting, and therefore how much is left to win?"
You (an agent) can execute this skill by reading this file. roofline_tools.py next to it holds mechanical primitives (peak-table parsing, counter parsing, unit math) — use them if they import, do the arithmetic yourself if they don't. A broken helper must not disable this skill; a broken skill must not fail the run.
0. The one doctrine that matters
roofline_pctmeasures how well the kernel executes its current algorithm's byte/FLOP budget.It says nothing about whether that budget is necessary.
A kernel at 90% of the memory roofline is not "done" — it is done with kernel micro-tuning. The remaining lever is to move fewer bytes. Never read a high roofline_pct as "stop optimizing this kernel", especially when it is the largest consumer of GPU time. See §7.
Corollary: this skill is advisory. It reorders and annotates. pct_gpu_time remains the primary key and the measurement remains the judge. This skill may never prune a candidate.
1. Inputs
profile/round_<R>/profile_topN.json— the standardized Top-N (required).env_report.json—gfx, structureddevice_target,physical_cu_count,
model_arch_class, model_dtype, workload (required).
- The model's
config.json— layer count, expert count, hidden/intermediate sizes, head counts
(optional but needed for a good MoE/attention byte model).
peaks.md— hardware denominators, keyed bygfx.- Optionally, captured shapes from the Kernel Extractor and/or rocprofv3 counters (stage B/C, §5).
2. Output artifact
Write profile/round_<R>/profile_roofline.json and a human-readable profile_roofline.md beside it.
ranking_by_pct and ranking_by_expected_gain are both emitted deliberately. The consumer must see the disagreement rather than a single blended number that hides it.
3. Procedure
- Scope to the head. Analyse ONLY entries with
pct_gpu_time >= HEAD_THRESHOLD_PCT(default 5),
biggest first, capped at ~8. Below that bar the Amdahl ceiling is under the noise band no matter what the roofline says, so a headroom estimate cannot change a decision — modelling those kernels only adds failure modes. Skipped entries are absent from the artifact; they are NOT degraded[] (a kernel too small to matter is not a modelling failure and must not read as one).
- Resolve peaks from
peaks.mdvia
resolve_peaks(gfx, product=env_report.device_target). device_target=unknown (every non-R9700 card, MI300/MI355 included) is no product constraint: the ISA-keyed tables still resolve. Client RDNA4 numeric peaks exist only for product r9700. A bare gfx1201 (or any other gfx120x SKU) is a hard unknown: do not derive a numeric denominator, emit unknown headroom, and do not rank on roofline. gfx125x is CDNA5, not RDNA4 — it must not use that gate. Other unknown architectures may derive from device props with peaks.confidence="low" (§6 L1). Use peak_flops_for() canonical dtype keys; a missing dtype is unknown, never the table maximum.
- For each selected entry, pick the e2e-critical regime — the one carrying the launches
(serving.n_decode_steps vs n_prefill_steps; a decode-dominated run means decode). Use that regime's base_latency_ms as t_ms.
- Classify
op_classfromname/classification/shapes. - Apply the §4 byte/FLOP model for that class. Cannot model it → §6 L2 (degrade this entry only).
- Compute:
``` achieved_bw = bytes_est / t achieved_flops = flops_est / t hbm_util = achieved_bw / peak_bw compute_util = achieved_flops / peak_flops AI = flops_est / bytes_est ridge_point = peak_flops / peak_bw
# AI picks which roof the kernel walks TOWARD; roofline_pct is measured on that roof. roof_axis = "compute" if AI > ridge_point else "memory" roofline_pct = compute_util if roof_axis == "compute" else hbm_util
# But which roof actually BINDS is decided by utilization, not by AI alone. A small AI does NOT # by itself mean memory-bound — that is the most common mislabel. If neither roof is near its # ceiling (both utils < 0.60) and the launch is above the dispatch floor, the kernel is # LATENCY / occupancy-bound, not bandwidth- or compute-bound. bound_type = "latency" if (hbm_util < 0.60 and compute_util < 0.60) else roof_axis
attainable_speedup = max(1.0, target_eff / roofline_pct) expected_e2e_gain_pct = pct_gpu_time × (1 − 1/attainable_speedup) `` A latency-bound kernel **still gets a headroom verdict** (its roofline_pct on the AI-selected roof is real, and target_eff already prices in the occupancy penalty for irregular classes like paged attention) — so a low-utilization head still ranks by its headroom. What changes is the **lever**: latency-bound underperformance is fixed by occupancy / shorter dependency chains / fusion, **not** by byte reduction (§7.1). Byte reduction only helps a genuinely bandwidth-bound (high-hbm_util`) head.
- Classify headroom, banded against
target_eff(not against the raw roofline — what matters is
the distance to what a good implementation of this class can realistically reach): roofline_pct ≥ 0.9×target_eff → saturated; ≥ 0.6×target_eff → moderate; else → underperforming; unmodelled or low-confidence → unknown. *88% against a 0.90 target is saturated, not "nearly there" — tuning has nothing left to give.*
Two outcomes must produce NO verdict (headroom_class: "unknown"), because in each the ratio is not evidence about the kernel:
- Dispatch-bound — the per-launch time is within launch-overhead scale (~5 µs), so the launch is
timed by dispatch, not by its transfer or its math. Emit bound_type: "latency"; the lever is fusion / graph capture, not kernel tuning. Typical of tiny high-call-count kernels. This is the no-verdict sub-case of latency-bound — distinct from the general latency-bound kernel in step 5 (low utilization but well above the dispatch floor), which keeps its verdict because it is doing real work and has recoverable occupancy/dependency headroom.
- Infeasible —
roofline_pctoutside(0,1]. That is the byte/FLOP model being wrong, not the
kernel being at the wall. A clamped 100% must NEVER be reported as `saturated` — that turns a modelling failure into a routing decision. A compute-axis ratio above 1.0 is most often an unvalidated peak (the BF16 MFMA microbench commonly reads ~2× low; see §4). See §6 L3.
bound_type is a CLOSED set: memory | compute | latency | unknown. If none fits, emit unknown — never invent a category the consumer has no routing rule for.
- Sanity-check (§6 L3), emit both rankings, write the artifact.
Per-launch, not aggregate. Compare bytes for ONE launch against ONE launch's base_latency_ms. If a logical op is split across several launches (e.g. a fused-MoE layer issuing a stage-1 and a stage-2 kernel), sum the launches for one logical unit and compare against the summed time. Getting this factor wrong is the single most common way to produce a nonsense roofline_pct — state in notes which unit you used.
4. Byte / FLOP models by op class
Weight bytes use the weight dtype (fp8 = 1 B/elem, bf16 = 2 B). Activation bytes use the activation dtype. Only count HBM traffic — a tensor re-read within one launch and small enough to sit in L2 (l2_bytes) counts once.
Trust the memory axis over the compute axis, especially at decode. The compute peaks in peaks.md are validated for fp8, but empirical MFMA peaks are not always right — the BF16 microbench commonly reads ~2× low, which makes a BF16 compute_util read ~2× high (and can push roofline_pct above 1.0, where §6 L3 catches it as suspect). A decode workload is memory-bound anyway, so prefer hbm_util; only rank on a compute-axis roofline_pct after the peak for that dtype has been validated (§8 rule: BF16 and FP16 MFMA run at the same rate, so those two peaks must be equal — if they are not, the peak is mis-calibrated and the compute-axis number is not usable).
dense GEMM [M,K]×[K,N]
MoE / grouped expert GEMM
The decisive question is how many expert weights are streamed, which dominates at decode.
If the implementation streams all E experts regardless of routing, use E instead of experts_hit — and note that the difference between the two IS a byte-reduction lever (§7). When unsure which the kernel does, compute both, report the experts_hit figure, and put the all-expert figure in notes.
Feasibility rule (general, applies to every op class with more than one plausible byte model). A byte estimate implying a rate above peak is refuted by the measurement itself. When you have several candidate models, pick the largest one that stays feasible (bytes ≤ peak_bw × t) and say which you used. If every candidate is infeasible, the class model is wrong: emit no verdict (§6 L3) rather than clamping to 100% and calling it saturated.
attention (paged decode)
KV traffic dominates; Q and the output are negligible at decode.
seq_len is the current average context, not the max — for an isl/osl workload sampled mid-run, isl + osl/2 is a reasonable estimate. Say so in notes; it is a real source of error.
elementwise / norm / quant
unknown
Do not guess. Emit modeled: false and degrade this entry (§6 L2).
5. Confidence stages — the estimate sharpens as the run proceeds
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckinge2e_workflow/knowledge/analysis_skills/roofline/SKILL.md
Popularity
- Repository stars
- 157
- Repository forks
- 42
- 7-day trend score
- 25
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/amd-agi/geak/roofline)