Skip to content

gpu: the PC-sampling label set - #88

Merged
dpsoft merged 1 commit into
mainfrom
feat/pc-projection-labels
Aug 25, 2026
Merged

gpu: the PC-sampling label set#88
dpsoft merged 1 commit into
mainfrom
feat/pc-projection-labels

Conversation

@dpsoft

@dpsoft dpsoft commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Task 9 of the GPU PC sampling plan, minus gpu_serialized (deferred — see below).

ProjectExecutionsWith(snap, ProjectionConfig) beside the unchanged ProjectExecutions, same split shape as CountingSink.Snapshot/SnapshotWith. Per PC-derived sample: gpu_pc_attrib and gpu_src_status unconditionally, gpu_src_file/_line/_func only under resolved. gpu_pc and gpu_stall unchanged in form. Frames gain nothing — a negative test asserts no frame name contains gpu:pc, gpu:src or any stall-reason string.

The anti-forgery rule needed strengthening, and the reason is new

Overwriting reserved names was sufficient while every label was unconditional. It is not once they are conditional: a producer tag named gpu_src_file survives exactly where the projection derives nothing — a forged source location sitting beside gpu_src_status="no-module".

projectionLabels now clears all seven reserved per-sample names right after the Tags copy. Reserved names win by absence as well as by value. That also closes the same pre-existing hole for gpu_stall when the producer named no reason, and for all of them on an execution with no PC samples.

Three decisions

A nil is answered by an empty store, not a branch. Task 4's "the store is the single place gpu_src_status is decided" stays structurally true, and "no store configured" yields the same honest no-module as "the cubin never arrived". Both cmd/ drivers are still nil today, so their profiles read no-module everywhere — which points at the missing wiring instead of looking like a pre-Phase-6 profile.

gpu_src_file is the basename, via path.Base — not filepath.Base, because the separator belongs to the build host, not the agent. Full paths vary per build, inflate the string table for no reader benefit, and leak build-environment layout into a profile that may be shared. The fixtures resolve to /tmp/perf-agent-cubin-fixtures/single.cu, so the test fails the moment a directory survives.

gpu_pc_attrib renders "unset-pc-attrib" for a PC-bearing view the join left undecided, mirroring SrcStatus's "unset-src-status". Omitting it would hide a join bug behind the one reading (exact) that claims vendor truth.

The cap drops the numerous label, not the useful one

ProjectionConfig.MaxDistinctPCLabels, default 20,000 — reasoned, not measured: the top of the range the plan's own size estimate calls tolerable. Past it only gpu_pc gives way; the sample keeps its weight and every other label, because gpu_stall and gpu_src_* are coarser and more actionable. An offset already emitted is always readmitted, since the cap bounds the pprof string table and a repeat costs it nothing.

Suppressions land in ProjectionStats.PCLabelsSuppressed, are raised as an anomaly by the new JoinHealthWith, and both drivers were switched over so the counter is actually printed — a profile that silently lost its PC labels looks identical to one that never had them.

is deferred, and absent

Not emitted, not stubbed, no placeholder. Its values come from Task 10's sampling windows, and the only default available is "false" — which the design names as the one answer that must never be reachable by accident. Report §7 states the follow-up: it rides on every execution, so it belongs in projectionLabels' shared map, set after the Tags copy, with the anti-forgery test extended.

Verification

All four gpu_src_status values, all four gpu_pc_attrib values, kernel-ambiguous never coinciding with gpu_ambiguous="true", a Tags entry losing to the derived value, the cap suppressing gpu_pc and only gpu_pc with an exact count, and the negative frame test.

Seven mutations applied one at a time, each caught — including the cap dropping gpu_stall, the status made conditional, the directory kept, and the reserved-name clearing removed.

Cannot verify

The real distinct-value counts per label, which is what would turn the 20,000 ceiling into a measured number — DistinctPCLabels beside PCLabelCap is the instrument.

Inherited and load-bearing: that functionIndex is the .symtab index, and that pcOffset is function-relative in the sense the line table is — the one failure in this set that is not self-announcing, because a wrong resolved line looks exactly like a right one.

Task 9 of the PC-sampling plan, minus gpu_serialized.

Every sample projected from a GPUPCSample now carries, on top of the
gpu_stall and gpu_pc it already had:

  gpu_pc_attrib   how the sample reached this execution - unconditional
  gpu_src_status  why it does or does not have a source location -
                  unconditional, four values, decided by ModuleStore alone
  gpu_src_file    the source file's BASENAME, only under "resolved"
  gpu_src_line    the source line, only under "resolved"
  gpu_src_func    the device function, only under "resolved"

The two unconditional ones are unconditional for gpu_join's reason: an
absent label must never be readable as a positive answer by a consumer
who does not know to check for its absence. A nil ModuleStore is answered
by an empty store rather than by a branch here, so the projection never
decides the enum - "no store" and "the cubin never arrived" are the same
fact and get the same answer.

gpu_src_file drops the directory. A cubin's DWARF carries build-host
absolute paths, which vary per build, cost a long string in the string
table for nothing a reader acts on, and leak the build environment's
layout into a profile that may be shared.

ProjectExecutionsWith caps distinct gpu_pc values per projection
(default 20,000 - the top of the range the design already calls
tolerable, reasoned rather than measured). Past the ceiling gpu_pc is
dropped and counted in ProjectionStats.PCLabelsSuppressed; gpu_stall,
gpu_pc_attrib and gpu_src_* survive, and the sample keeps its full share
of the execution's duration. An offset already emitted is always
readmitted - the cap bounds the string table, and a repeat costs it
nothing. JoinHealthWith raises the suppression as an anomaly, because a
profile that silently lost its PC labels looks identical to one that
never had any; both drivers were switched over so the counter is
actually printed.

Reserved names now win by ABSENCE too. The new labels are conditional,
so a producer tag named gpu_src_file would have survived untouched in
exactly the cases where this package derives no value - a forged source
location standing beside gpu_src_status="no-module". projectionLabels
clears every per-PC-sample reserved name straight after the Tags copy,
which also closes the same hole for gpu_stall when no reason was named
and for every one of these names on a no-PC-sample execution.

Frames gain nothing, asserted negatively.

gpu_serialized is deliberately not here: its three values come from Tier
A's sampling windows, which do not exist yet, and the only default it
could take is "false" - the one answer the design says must never be
reachable by accident. Absent is honest; present and meaningless is not.

Seven mutations checked, each caught. See
.superpowers/sdd/task-9-labels-report.md.
@dpsoft
dpsoft merged commit f68dff6 into main Aug 25, 2026
10 checks passed
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.

1 participant