Skip to content

npu-pack: head_stored_rows() comment says what main does with a graph head (follow-up to #2104) - #2107

Merged
bong-water-water-bong merged 1 commit into
mainfrom
1bit/npupack-b-head-rows-comment
Nov 11, 2026
Merged

bong-water-water-bong merged 1 commit into
mainfrom
1bit/npupack-b-head-rows-comment

Conversation

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator

Follow-up to #2104, which merged at efde6ab twenty seconds before this correction reached its branch.

The comment on head_stored_rows() in npu/pack_import.h says a graph head's "own padding, to the 32-row tile quantum, is engine#1992's". That reads as if main pads graph heads. It does not: #1992 was closed unmerged, and on main a graph head whose row count is not a multiple of 32 is refused by the tile writer (npu/pack_import.cpp, "q4_1 tiles need N % 32 == 0"). A reviewer of #2104 read the old comment that way and proposed a 32-row quantum on that basis.

The comment now says: a graph head is stored as it is, an unaligned one is refused, and if graph-head padding lands its quantum belongs in this function.

Comment only, one file, +4 −2. No code or test changes; npu_pack_import_test was rebuilt with this text on #2104's branch and passes.

🤖 Generated with Claude Code

…igned one is refused), review of #2104

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

ready for review at 4eee18d

@github-actions

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 1 🔵⚪⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Comment Clarity

The comment for head_stored_rows() was updated to clarify that graph heads are not padded by the main process, and that padding is refused if the row count is not a multiple of 32. This change improves accuracy and prevents misinterpretation, especially in light of a previous misunderstanding referenced in the PR description.

// How many rows a head read from the .fconst tail occupies in the container. The pack stores the head in whole 64-row
// tiles, so a vocabulary that is not a multiple of 64 is carried with the pack's own padding rows (Hunyuan: 120,818 ->
// 120,832) while `vocab_size` and the plan's tensor shape stay the vocabulary. A head that is a graph initializer is
// stored as it is: on main nothing pads it, and one whose row count is not a multiple of 32 is refused by the tile
// writer ("q4_1 tiles need N % 32 == 0"). If graph-head padding lands (engine#1992 was closed unmerged), its quantum
// belongs here. This is the number a container's lm_head tile count follows from.

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT at 4eee18d: READY

A comment-only change to head_stored_rows() saying what the main (non-.fconst-tail) path does. Worth a PR because it is the function #2104 extracted: a reader arriving at the guard needs to know that the unpadded case is vocab rows by construction rather than by omission, and a comment is cheaper than reading the caller.

No behaviour change, CI green.

@bong-water-water-bong
bong-water-water-bong merged commit 697db7d into main Nov 11, 2026
9 checks passed
@bong-water-water-bong
bong-water-water-bong deleted the 1bit/npupack-b-head-rows-comment branch November 11, 2026 03:58

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: READY at 4eee18d

A comment-only correction that is right on all four of its claims, and I checked them one at a time — because the previous comment pointed at a mechanism that does not exist.

The old text: "A head that is a graph initializer does not go through this (its own padding, to the 32-row tile quantum, is engine#1992's)". The new text: "A head
that is a graph initializer is stored as it is: on main nothing pads it, and one whose row count is not a multiple of 32 is refused by the tile writer … If
graph-head padding lands (engine#1992 was closed unmerged), its quantum belongs here."

claim check
nothing pads a graph head on main npu/pack_import.cpp:3366 — if (!from_fconst_tail || vocab <= 0) return vocab; → a graph head comes back unchanged
a non-multiple of 32 is refused npu/pack_import.cpp:2080 — if (q.N % q4nx::kRows) throw std::runtime_error("q4_1 tiles need N % 32 == 0");, the exact string the comment quotes, with q4nx.h:68 kRows = 32
the container's tiles are 64-row, the refusal quantum is 32 npu/pack_import.cpp:2190 — kTileRows = 64, kSubvRows = 32; head_stored_rows rounds by kTileRows, the tile writer refuses at kRows = 32. Two quanta, both stated, neither confused
#1992 was closed unmerged gh pr view 1992 → state=CLOSED merged=no

Why the old comment was worse than nothing: it named a mechanism (its own padding) as if it existed and attributed it to a PR that never landed. A reader planning
the lm_head tile count would have sized it for padding that main does not perform — and the failure is one model, later, with a row count that "should have worked".
Correcting it to "stored as it is" plus "refused by the tile writer" plus "if padding lands, its quantum belongs here" is the whole truth in three clauses, and
the third is a signpost rather than a promise.

Content-only, one function's docstring, verified against the implementation rather than against the sentence. The (+4/−2) is the entire diff.

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.

1 participant