[Skills] Add PR review and performance-regression validation skills - #1083
Draft
zhiding512 wants to merge 2 commits into
Draft
[Skills] Add PR review and performance-regression validation skills#1083zhiding512 wants to merge 2 commits into
zhiding512 wants to merge 2 commits into
Conversation
FlyDSL has no automated gate on performance. scripts/compare_benchmark.py prints ratios and ends with an unconditional `return 0`, so a regression cannot turn a PR red, and nothing else in the pipeline checks speed. PR #1009 is what that costs: a default-off trait placed in front of the bf16 XCD remap shipped a silent regression that lived in main for two weeks, and restoring the mapping recovered +17.4% and +19.4% at two production sequence lengths with bit-identical output. Add two skills under .claude/skills/. review-pr is a static advisory reviewer. Its rules are derived from this repository's own history rather than ported from another project: 796 human inline review comments (Copilot filtered out) and the diffs of roughly forty merged bugfix PRs. Every rule cites a real PR. The categories reflect what actually fails here -- JIT cache-key direction (#624, #556, #1020), architecture capability derived from a family predicate (#1024), index width at the ABI boundary (#1064, #1020), truncating division in copy decomposition (#1064, #1007), fastmath wrappers missing @dsl_math_wrap_result (#1035), layout algebra invariants (#1052, #926, #707), and tests or benchmarks that cannot fail (#1056, #1033, #654). Of the defects reconstructed, eleven returned silently wrong numbers and only six crashed, so the checklist is weighted toward silent failure. scan_flydsl_diff.py turns the mechanical checks into a deterministic candidate list, so a review works a fixed set of sites instead of whatever the model happened to notice. Each of its categories was confirmed to fire on real pre-fix code. validate-kernel-pr is the deterministic executor. Its perf stage runs base and head A/B/A on one verified-idle GPU: sandwiching head between two base runs cancels monotonic drift, and the two base runs form an A/A control whose disagreement is the noise floor, measured during the run rather than guessed. A fixed threshold cannot work here -- run_benchmark.sh already documents a softmax-backward tier that swings 24% run to run at low occupancy. The executor also forces FLYDSL_RUNTIME_ENABLE_CACHE=0 when the patch touches paths the JIT key does not track, since a warm cache would otherwise serve the previous kernel and produce a reproducible measurement of the wrong binary, and it isolates the two sides' cache directories so base cannot serve head. Every stage has been observed failing on a seeded defect and passing on a matched control; that pairing is the point, since a stage only ever observed passing is decoration. 23 regression tests cover regression detection, noise rejection across twelve seeds, drift cancellation, metric direction (#848 shipped inverted speedup columns), row-label preservation (#654 kept the last regex match and mislabelled layernorm for months), and the rule that an incomplete run can never report PASS. Signed-off-by: zhimding <zhimding@amd.com>
The repository's own agent-docs checker caught three drifted paths in the two new skills: - lib/Dialect/Fly/Utils/LayoutUtils.cpp does not exist. The layout utilities are IntTupleUtils.cpp and NormalForm.cpp; IntTupleUtils.cpp is where the crd2idx fix in #1052 actually landed. - The brace form lib/Dialect/FlyROCDL/{CDNA3,...}/ is not a resolvable path; name the parent directory and list the families in prose instead. - The validator's regression suite is at .claude/skills/validate-kernel-pr/tests/test_validator.py, not tests/. Also exclude .claude/ from scan_flydsl_diff.py: skill prose and test fixtures quote the scanner's own patterns literally, so any PR touching the skills lit up every category. Verified the nine seeded-defect categories still fire. Signed-off-by: zhimding <zhimding@amd.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds two skills under
.claude/skills/:review-pr— a static advisory reviewer whose rules are derived from this repository's review history, not ported from another project.validate-kernel-pr— a deterministic executor that runs base and head and produces a machine-checkablevalidation_report.json, including a performance stage.Draft: this is tooling that applies to the whole repo, so I would like agreement on the rule set and on the perf gate's decision rule before it is treated as usable.
Motivation
FlyDSL has no automated gate on performance.
scripts/compare_benchmark.pyprints ratios and ends with:return 0, unconditionally. A regression cannot turn a PR red, and nothing else in the pipeline checks speed — the numbers land in a job log nobody is required to read.#1009 is what that costs: a default-off trait placed in front of the bf16 XCD remap shipped a silent regression that lived in main for two weeks. Restoring the mapping recovered +17.4% at S=180,180 and +19.4% at S=239,580, with bit-identical output.
A second motivation is that the failure modes here are mostly quiet. Of ~30 defects reconstructed from merged bugfix PRs, 11 returned silently wrong numbers, 5 were silent perf regressions, 2 were tests or benchmarks that lied, and only 6 crashed. A checklist for this repo has to be weighted toward what fails without saying anything.
Changes
review-prRules were mined from 796 human inline review comments (Copilot's 1134 filtered out) and the diffs of ~40 merged bugfix PRs. Every rule cites a real PR. Categories reflect what actually breaks here:
cache_tag(#1020)False and(#650)is_rdna_arch— gfx1250 is wave32 and not matched by RDNA prefixes (#1024); prefix too wide (#544, #943)fx.Int64widening (#1064); flattening before launch, where_LayoutPlanpacks shapes as int32 (#1020)fx.*wrapper missing@dsl_math_wrap_result, costing 11.1–11.9% silently (#1035); ballot body assuming a per-lane predicate (#1033)getValue()withoutisStatic()(#926); slice not moving the base (#707)Two things are deliberate:
scan_flydsl_diff.pyturns the mechanical checks into a deterministic candidate list, so a review works a fixed set of sites rather than whatever the model happened to notice.validate-kernel-prStages:
merge_sim,gpu_claim,runtime_compat,test_policy,correctness,perf,diff_scan.The perf stage is the point. Design is A/B/A interleaved with the noise floor measured during the run:
A fixed threshold cannot work here, and
run_benchmark.shalready says why:A 5% gate would flag that row on roughly every other run.
Two FlyDSL-specific hazards are handled explicitly:
lib/,include/,python/flydsl/,kernels/common/ortools/, the JIT key does not move with the change and a warm cache serves the previous kernel — a perfectly reproducible measurement of the wrong binary. The executor forcesFLYDSL_RUNTIME_ENABLE_CACHE=0and records why. Base and head also get separate cache directories, so base cannot serve head.Testing
Every stage has been observed failing on a seeded defect and passing on a matched control. That pairing is the point: a stage only ever observed passing is decoration, not a check.
unchanged, not a coin flipLive A/B/A run through real subprocesses, seeded −20% on one row:
Also run end-to-end against a real PR (#1077) on this machine, where it correctly returned
INCONCLUSIVErather than blaming the author: the local prebuilt runtime is 0.3.1 while the checkout is 0.3.2, so every kernel import dies oncannot import name 'get_warp_size'— a symbol #1024 added.runtime_compatclassifies that as an environment fact and skips correctness and perf instead of filing a red result.The
agent-docschecker also caught three drifted paths in my own skill text (including aLayoutUtils.cppthat does not exist); fixed in the second commit.Performance
No runtime code is touched — this adds tooling only, so there is no kernel performance impact.
Dependencies
gh,git,amd-smiand the stdlib.Breaking Changes
None. Additive; no existing skill, script or workflow is modified.
Known limitations
Stated in the skill rather than implied:
--pr Norchestration. The caller creates the worktree and names--tests/--bench-cmd; an irrelevant target can still producePASS. The report names both so a reviewer can reject that evidence.Review asks
Made with Cursor