perf(ops): one split4 Q5 parent for the q4/q5 small-column input projections - #281
Conversation
|
Review response — the selection evidence for this band, and three fusion attempts (all measured, none kept). The band end was argued from the wrong candidate. The earlier round justified stopping at 9 by comparing the row-block shape against the narrow c4 SIMT tile, but the shape that is routed here is split4, and split4 vs the c4 tile had never been measured past 9. Measured now on the complete public Op:
Fusion and batch organisation are now measured, not projected. The three candidates the round asked for were built and run against the routed form (complete public Op, cold L2):
None of them is in the PR. The measured reason is which kernels the existing fused template can reach — its Q4 side is the row-split SIMT kernel whereas the routed form uses the K-split MMA kernel — plus moving the convolution into the projection epilogue. Not implemented, and not claimed either way: fusing the K-split Q4 side with the Q5 split4 side and a sequence-collecting convolution. Housekeeping in the same commit: the row-block small-T shape is removed (no caller at any column count; its mechanism and the Verification on the final build: complete FP64 reference at |
|
Closing round: the explanations are corrected, the execution code is unchanged. The performance work ended with the previous round; this pass changes comments, tests' descriptions and What was wrong, and is now fixed in the body above, in
Also in the bundle: the three rejected candidates as minimal patches with their command set, their Deliverable: |
…o split4 at 7..10 columns # Conflicts: # tests/ops/test_gdn_input_proj_conv_record.cpp
|
The code review and local correctness/performance checks look good. Before merging, please squash the four commits into a single commit, rewrite the PR branch history, and force-push the updated branch. Please keep the final code unchanged. |
b76b8f7 to
32c3d51
Compare
|
History squashed. The branch is now a single commit,
The tree is byte-identical to |
…ections The Q5 parent of both Q4/Q5 input projections now uses the split4 shape - one CTA owns one output row and its four warps split the K dimension, reducing their partial sums through shared memory - instead of the row-block shape at 7..8 and the c4 narrow tile at 9..12. Per-side projection route change: no new kernel, no change to the complete-op structure, no change to the column catalog or to the grouped bands. Complete public Op medians, B0 (master + Neroued#271) against this branch. GDN: B=1 W=7 87.81 -> 69.31 us (21.1%), W=8 91.39 -> 76.86 (15.9%), W=9 108.29 -> 97.57 (9.9%), W=10 109.86 -> 105.86 (3.6%); the aggregate-10 organisations B=2/W=5 and B=5/W=2 by 4-5%; Record at 7/8/9/10 by 21.6/17.4/9.5/3.7%. Attention: 18.8/14.6/5.4% at 7/8/9. Both band ends are measured crossovers between two legal shapes, per parent. The GDN parent is extended to 10: split4 wins at 10 in every organisation that exposes 10 aggregate columns and loses at 11 and 12, so the band stops there. The attention parent stays at 2..9: it ties at 10 and loses at 11/12. Q4 is untouched - T=4 keeps its launch_t4_pdl SIMT pair and the Q4 K-split MMA band is 7..12. Also here: the row-block experiment header is removed (it has no caller), and the production comments and the tests' descriptions state each shape's actual mechanism, the W=4 candidate's result without a causal claim, the Snapshot/Record workspace split, and each boundary number's timing boundary. The research notes that describe the same material ship with the review bundle rather than as a file in the repository. The fusion and batch candidates that were built and measured along the way (fused T=4, fused W=7/8, batched fused at aggregate 8) all lost; none of them is in this change.
32c3d51 to
0435e21
Compare
Q4/Q5 GDN and attention input projections: one split4 Q5 parent for the small column counts
The Q5 parent of both Q4/Q5 input projections now uses the split4 shape (one CTA owns one output row,
its four warps split the K dimension and reduce their partial sums) for the low column counts instead of
three different shapes. This is a per-side projection route change: no new kernel, no change to the
complete-op structure, no change to the column catalog or to the grouped bands.
What changes, by public call
Tis the column count the projection actually receives. The route is resolved per call: the two fused C/Dresolutions (
T=1,2,3,5,6) and every batched call have their own resolution, and the flattened aggregatecount
W x Bis what selects the materialized projection route. Rows below are the public dispatch, notthe private launcher's internal range.
So this PR moves GDN's 7..10 and attention's 7..9; it does not unify every size on split4. The row-block
shape was in production for 7..8 in both projections. It was also a candidate at 9 (and at 10..12 in a
trial) during this work, but a candidate is not a production route, and 9's production route in the
baseline was the c4 SIMT tile.
Q4 dispatch is untouched:
T=4keeps itslaunch_t4_pdlSIMT pair, and the Q4 K-split MMA band is 7..12.Measured result
Complete public Op, GPU-side timing of a captured graph holding one call, cold L2,
--warmup 5 --repeat 50,median, baseline and candidate alternating inside one window, three rounds. Baseline is master + #271
(
9e163eee); the candidate is this branch.B=1 W=7B=1 W=8B=1 W=9B=1 W=10B=1 W=7/8/9B=1 W=10B=2 W=4(8 aggregate)B=8 W=1(8 aggregate)B=2 W=5(10 aggregate)B=5 W=2(10 aggregate)T=7/8/9Warm L2 ranks the same way, and the 10-aggregate organisations gain more there (about 9-11%). Every column
count from 11 up, every grouped count,
B=1 W=4and all larger organisations are unchanged, several ofthem bit-identical between the two builds.
Both band ends are crossovers between two legal shapes, measured per parent, not limits of either shape:
aggregate columns, in both forms and both cache policies; at 11 and 12 it loses (118.0 and 140.5 us
against 111.9 and 113.9 us), so the band stops at 10.
stays at 9.
Verification, by what each check actually compares
B=1 W=7/8/9/10: the mathematical reference is evaluated forevery output row and every state channel of Q/K/V and Z, and the code compares them. The output counts
printed in the log cover Q/K/V; Z and the state are compared by their own checks, so the printed count is
not the sum of all channels.
B=2/W=5case added here (10 aggregate columns), the earlierB=2/W=4 masked,B=8/W=1and the largerbatched cases.
run_case: the bit-level relation against the validated Snapshot outputs and record, thesource state left read-only, the invalid tails, the guards and the workspace contract. It does not run its
own sampled FP64 reference, so the record
B=2/W=4cases added here (dense and masked, 8 aggregatecolumns) are recorded as relation checks, not as sampled FP64.
outputs at the captured addresses before each launch and changing the activation at the captured address
before the second.
T=10is in its list. The conv record helper replays at widths 2/9/10/16 with changedinputs; it does the relation checks, not an independent FP64 per replay.
memcheck0 errors at the six aggregate-10 organisations;racecheck0 hazards on the split4 Q5parent at three of them, with the instrumented medians in the same logs (328-346 ms against about
106 us uninstrumented) showing the filtered instance really was analysed.
cteston the final build:100% tests passed, 0 tests failed out of 120; 7 of the 120 are skippedby design because no model artifact is supplied (
SKIP_RETURN_CODE 77,NINFER_TEST_ARTIFACT/--artifact), which is this environment's condition and not an effect of the change. The other 113 ran.Logs in
logs/tests/.Not in this PR: fusion and batch organisation
Three candidates were built and measured against the routed form (complete public Op, cold L2, both forms
where applicable):
B=1 W=4, fusedT=4B=1 W=7fusedB=1 W=8fusedB=2 W=4batched fused(request, token)axisB=8 W=1batched fusedThe candidates did not win, and those measurements only exclude those implementations. For
W=7/8and thebatched organisation, they drive the Q4 side through the row-split SIMT kernel whereas the routed form uses
the K-split MMA kernel there, and they move the convolution into the projection epilogue - an implementation
difference consistent with the size of the losses. For
W=4that explanation does not apply: the routedform is
launch_t4_pdl, whose Q4 side is also SIMT. The workspace saving belongs to the Snapshot prototypeonly; the Record form writes the caller-owned
conv_recordand its temporary-workspace query is 0 in bothbuilds.
Not implemented: fusing the K-split MMA Q4 side with the Q5 split4 side and a sequence-collecting
convolution. Nothing measured here excludes it.
Each candidate's minimal patch, its per-configuration table and its trial build's test logs are in the
review bundle
evidence_r7_review.zip. That bundle is a local file handed over with the review (the fork'sPR attachment facility is not used), and its
data/prototypes/README.mdstates which parts of the patchesare a reconstruction, since the measured prototype sources were reverted before the final build.
Housekeeping
q5_rowsplit_rowblock_small_t.cuhis removed from the production tree: it has no caller, and itsmechanism and the
__syncwarp()fix stay in git history, together with why it is not routed and the twoparent shapes' actual mechanisms in the research notes that ship with the review bundle.
candidates) are delivered with the review bundle instead of living in the repository.
numbers they used to carry live in this body and in the round's report.
repository-wide gate was not re-run for them. Formatting was checked on LF copies with the style
resolved from the repo root: as a count of lines clang-format would change, the two launchers went from
28 to 20 and from 20 to 8 lines of pre-existing debt, and the three touched test files are unchanged
(13/88/11 lines, worktree and reviewed revision identical).
Scope
No release or upload authorization is implied. Merge conditions are the maintainers' decision.