Skip to content

poc: Mokka + AICR pre-silicon coverage sweep, measured twice - #744

Open
ArangoGutierrez wants to merge 9 commits into
NVIDIA:mainfrom
ArangoGutierrez:poc/mokka-aicr-kind-sweep
Open

poc: Mokka + AICR pre-silicon coverage sweep, measured twice#744
ArangoGutierrez wants to merge 9 commits into
NVIDIA:mainfrom
ArangoGutierrez:poc/mokka-aicr-kind-sweep

Conversation

@ArangoGutierrez

Copy link
Copy Markdown
Collaborator

Problem

The 2026-07-25 POC (#503) answered whether AICR runs against Mokka at all. It could not answer the
question the AICR maintainer actually put on 2026-07-24:

Does Mokka + AICR materially reduce GB200 bring-up time, or does it merely prove the stack deploys
against mocked APIs?

Answering that needs a permutation matrix and a way to say what each check proves when no GPU is
present, not a single recipe and a pass count.

Approach

A harness at tests/aicr-sweep/ classifies every AICR check into A (meaningful), B (trivial),
C (hardware-dependent) or G (closable Mokka gap), and records a cause code for anything that did not
reach a verdict. Blocked cells stay in the denominator, so coverage cannot be inflated by deleting
the work that did not happen.

It is built so an incomplete run degrades to "not run" rather than to a favourable number. Seven
invariants each have a test that goes red if it regresses, and invariant 1 was mutation-checked:
flipping OutcomeNotRun to OutcomePass in Classify turns two tests red.

Two runs are recorded, and both regenerate byte-identically:

Run Cells Results Mokka
2026-08-03 cells.yaml results/ v0.3.0
2026-08-26 cells-57ef016.yaml results-57ef016/ 57ef01659

AICR is pinned to 0752ea14 in both, so Mokka is the only axis that moved between them. Verified
rather than assumed: the base cell's generated recipe is byte-identical across the two runs.

What it found

The re-run's headline is negative, and that is the point. #672 fixed the PCI bus ID gap the first
run reported (0000:01:00.0 to 00000000:01:00.0, confirmed by a differential probe of the two
published images). gpu-operator-health did not move. GFD now receives a well-formed BDF and
still cannot read the vendor file, because Mokka's rendered PCI tree uses relative symlinks and is
not grafted onto GFD's /sys. Both statements are true at once, and AICR's check cannot tell them
apart: it only sees ClusterPolicy state=notReady.

One verdict flipped. dra-support passes now, because k8s-dra-driver-gpu v0.5.0 released
altProcDevices on 2026-08-19. D-009 had recorded that flag as unreleased, which was correct when
written. Mokka's IMEX rendering already worked at v0.3.0; a released consumer was what was missing.

Coverage moved a long way. 13 of 210 check-results reached a verdict in the first run; 53 in the
second. The BUDGET and U blocks are both zero. The largest single gain is the h100 cell, where
AICR dispatches 14 of 21 checks against 9 for gb200.

Two cells the first run blocked were misattributed, and this PR reclassifies them with CLI output
as evidence: both declare intent=training, which resolves no recipe on the kind service for
gb200. That is X, not BUDGET/U.

Two consumers, one shape of problem. GFD is dynamically linked and fails on a sysfs path.
AICR's own snapshot agent is a static ko-built Go binary with no PT_INTERP, so library
interception cannot reach it at all, and it fails on sysfs content. Raised by @giuliocalzo in
review and verified here against the published image. The common remedy is a filesystem graft, not
library interception.

An injected uncorrectable ECC fault moves no verdict. With the mock reporting 6 and 9 DRAM
Uncorrectable errors and all four GPUs still enumerating, every dispatched check is identical to the
base cell. That is a statement about which checks this recipe dispatches, not about Mokka.

Testing done

go build ./tests/aicr-sweep/...
go test -race -count=1 ./tests/aicr-sweep/
golangci-lint run ./tests/aicr-sweep/...
go run ./tests/aicr-sweep -catalog ... -cells ... -results ...   # both runs

Build clean, tests pass, lint reports 0 issues, and both recorded runs regenerate byte-identical
coverage.md and report.json. Every number in the write-ups comes from that last command rather
than from memory.

Known limits, stated rather than buried

  • Nothing here ran on silicon. Every record carries sim provenance. Bucket C is non-empty by
    construction: 4 checks cannot be judged without hardware.
  • The chart came from the checkout, not from a release. Chart.yaml on main is still 0.3.0, so
    the published OCI chart does not carry the 60 commits under test. The image is the published
    sha-57ef016, so anyone can pull it by digest.
  • The GFD failure is still cause K, not G. D-014 named the experiment that would settle it
    (run with cdi.enabled=true and the toolkit installed). It has not been run, the honest status is
    "not distinguished", and it is the single most valuable cell still outstanding.
  • dra-support needed --set nameOverride. v0.5.0's chart was renamed, so its default resource
    names no longer match what AICR looks for. AICR itself was not modified.

Breaking changes

None. This adds a test harness and documentation. No production code path changes.

Relationship to other work

Supersedes and replaces #503, now closed. Its code had already landed on main via #541 and #542, and
the IMEX renderer it introduced now lives at internal/imex/ after #729 relocated it. The
preflight-workflow diagram and the diagrams index are carried forward here; its harness and
2026-07-25 results are deliberately left behind, because that harness will not be in the tree and
those numbers could not be regenerated or checked. They remain reachable at pull/503/head.

Related: #502 tracks the coverage gaps, and its body still carries the July figures that this PR
supersedes. Not closing it here, since correcting those numbers is a separate call.

Answers the question Mark Chmarny put on 2026-07-24: does Mokka + AICR
materially reduce GB200 bring-up time, or does it merely prove the stack
deploys against mocked APIs?

Adds a re-runnable harness that runs the AICR recipe and validation suite
against an nvml-mock cluster and classifies what each of AICR's 21 checks
actually proves when no GPU is present. Everything is pinned: image
ghcr.io/nvidia/nvml-mock:0.3.0, chart 0.3.0, AICR upstream/main @0752ea14.

The harness is built so an incomplete run degrades to "not run" rather than
to a favourable number. Seven invariants carry tests; the load-bearing one
(a check absent from the run is never promoted to a pass) was mutation
checked by flipping it and confirming two tests go red.

Bucket (what a check would prove) and cause (what stopped this run) are kept
as independent axes, because conflating a kind artifact with a Mokka gap is
the easiest way to produce a misleading result.

Result from the run on 2026-08-03: AICR dispatched 9 of 21 checks; 3 passed
for real integration reasons, including check-nvidia-smi, which exercises
device-plugin allocation and dlopen of libnvidia-ml.so.1 end to end. None of
the 5 failures was caused by a Mokka capability gap. One real gap was found
and is not yet fixed: the PCI bus ID reaches NVML consumers without its
domain prefix, breaking dra.k8s.io/pcieRoot and crashing GFD.

Supersedes the 2026-07-25 POC in NVIDIA#503, which predates v0.3.0.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
…n without running

Adds the hybrid cell asked for after the base sweep: 250 hollow KWOK GPU nodes
alongside 2 real Mokka workers, 253 nodes advertising 2016 nvidia.com/gpu, same
recipe, same AICR.

Every AICR check reported PASS in 4.2s and 5.2s, against 9m0s on the pure-Mokka
baseline, with no container ever executing. Four verified facts compose into it:
validator Jobs tolerate every taint (empty key, operator Exists); KWOK nodes
carry the full GPU label set and real nvidia.com/gpu capacity; the scheduler
therefore places validators on them, 250 hollow against 2 real; and KWOK's
pod-complete stage transitions any Job-owned pod to Succeeded. Container status
shows an empty imageID with started false and startedAt equal to finishedAt, so
the image was never pulled.

The documented mitigation does not work. --node-selector reaches the snapshot
agent's pod spec and stops there; deployer.go:66 passes it to inner workloads via
AICR_NODE_SELECTOR and never applies it to the validator Job itself.

Not a Mokka gap and not a KWOK bug. It is a composition hazard whose actionable
half sits in AICR, and it is the architecture the fake-gpu-operator per-nodepool
backend design produces.

The 9 false passes are deliberately excluded from cells.yaml and the rollup, so
they cannot raise the headline coverage number. Raw CTRF kept for audit.

The recommendation panel dissented against running this, arguing it would
document the obvious, and I agreed before being overruled. Both of us were wrong
about the direction of the result; the dissent is recorded in DECISIONS.md D-015.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
…ks added

The previous wording said every check passed, which reads as all 21. Both runs
dispatched the same 9 of 21; adding hollow KWOK nodes changed no selection, it
changed the verdicts from 3 pass / 5 fail / 1 inconclusive to 9 pass / 0 fail.
The other 12 stayed undispatched in both runs, so the KWOK run is not a coverage
gain, it is the same 9 verdicts fabricated. Corrected in FINDINGS.md and
HYBRID-KWOK-FINDING.md.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
The v0.3.0 sweep was 23 days old and its headline gap, the PCI bus ID missing
its domain, was fixed upstream by NVIDIA#672. Re-measuring was the only way to know
whether the verdict moved.

AICR is held at the same pin, 0752ea14, so Mokka is the only axis that changed.
Verified rather than assumed: the base cell's generated recipe is byte-identical
to the one recorded on 2026-08-03. Both runs regenerate byte-identically and
neither overwrites the other.

NVIDIA#672 landed and is real, and gpu-operator-health did NOT move. GFD now receives
a well-formed BDF and still cannot read the vendor file: Mokka's rendered PCI
tree uses relative symlinks and is not grafted onto GFD's /sys. D-014's K
classification survives; its distinguishing cell is still the one to run.

One verdict flipped. dra-support passes now because k8s-dra-driver-gpu v0.5.0
released altProcDevices on 2026-08-19, which D-009 had recorded as unreleased.
Mokka's IMEX rendering already worked at v0.3.0; a released consumer was what
was missing.

Coverage went from 13 of 210 check-results reaching a verdict to 53, with the
BUDGET and U blocks both to zero. Two cells the first run blocked as BUDGET and
U are reclassified X: they declare intent=training, which resolves no recipe on
the kind service for gb200.

Also recorded: an injected uncorrectable ECC fault moves no verdict, and AICR's
own snapshot agent is a static Go binary with no PT_INTERP, so library
interception cannot reach it. The second was raised by Giulio Calzolari in
review and verified here against the published image.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Five documents carried 2026-08-03 figures with nothing marking them as a single
dated run. A reader opening FINDINGS.md met "the one real gap this sweep found",
which upstream fixed on 2026-08-19, and "nvidia.com/gpu: 8 per worker", which
NVIDIA#727 changed to 4, with no signal that newer numbers exist.

The measurements themselves are left alone. They were correct when taken, and
rewriting them would destroy the first run's record. Each file gets a dated
banner naming what has since changed and where to find the current figures.

DECISIONS.md notes the two decisions the re-run bears on: D-009's cause-U block
is released, and D-014's K classification survives with a changed diagnosis.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
…VIDIA#503

PR NVIDIA#503 is superseded by this branch and is being closed. Three files existed
only there: the preflight-workflow diagram pair and the diagrams index. The
index lists every diagram by name, so porting it without preflight-workflow
would leave a dangling row.

The index gains a row for break-matrix, which this branch added and NVIDIA#503 never
had. Verified both directions: every diagram named in the index has both a .mmd
and a .svg on disk, and no diagram file is left unindexed.

The rest of NVIDIA#503 is genuinely superseded. Its code landed on main through NVIDIA#541
and NVIDIA#542, and the IMEX renderer it introduced now lives at internal/imex after
NVIDIA#729 relocated it. Its harness and 2026-07-25 results are left behind
deliberately: that run predates v0.3.0, its harness will not exist in the tree,
so its numbers could not be regenerated or checked. They stay reachable at
pull/503/head.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Rebasing onto main surfaced 8 lint findings that did not exist at the branch's
old base: main enabled cyclop and perfsprint since the fork. CI would have gone
red on a branch that was green locally before the rebase.

perfsprint is fixed properly. Three fmt.Errorf calls carry no format verbs and
become errors.New.

cyclop is suppressed with the pattern already established on main
(cmd/generate-bridge, cmd/nvml-mock-ctl, pkg/diagnostics all use
"//nolint:cyclop // existing complexity; refactor deferred"). These five
functions are branchy by nature: they map CTRF statuses onto outcomes, roll up
buckets and causes, and render a table. Splitting them to chase a complexity
number would scatter logic the tests pin precisely. nolintlint requires the
suppression be specific and explained, and it is both.

Verified behaviour-neutral: both recorded runs still regenerate byte-identical
coverage.md and report.json after the edits.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
…to be closed

The next-steps list told a reader to close NVIDIA#498. Checking it rather than
assuming: it was closed already. What remains true is that the imex note in
the chart's values.yaml still says altProcDevices is in no release and still
points at that issue, so the note outlived the issue and is wrong on both.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
The Pages workflow runs `mkdocs build --strict`, which promotes an unresolvable
link to an error. Five links failed. Reproduced locally with mkdocs 1.6.1 and
`make docs-check-exclusion`, the same target CI runs.

Three are in coverage.md and point at real, current files under tests/aicr-sweep/
that are simply not part of the docs site. They become absolute GitHub URLs, which
mkdocs does not try to resolve and which are more useful to a reader on the
published site anyway. Directory links are left alone: mkdocs reports those at
INFO and does not fail them.

Two came in with the diagram index carried over from NVIDIA#503, and the fix is larger
than the links. That section cited tests/aicr-preflight/, the harness this branch
deliberately does not carry, and quoted NVIDIA#503's bucket split (A 14, B 0, C 4, G 3,
66.7%, 81.0%). Those numbers are superseded twice over and contradicted the
coverage-map SVG sitting beside them, which already carries the sweep's A 16,
B 1, C 4, G 0 and the 76% ceiling. The section now cites tests/aicr-sweep/catalog.yaml,
states the catalog's real counts, and points at the second run.

Porting a file without auditing its body is what let the stale numbers in.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
@ArangoGutierrez
ArangoGutierrez marked this pull request as ready for review August 27, 2026 14:06
@ArangoGutierrez ArangoGutierrez self-assigned this Aug 27, 2026
@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds a reproducible AICR-on-Mokka coverage sweep, two recorded result sets, supporting evidence, and documentation explaining the pre-silicon coverage boundary.

  • Introduces CTRF parsing, conservative result classification, matrix roll-ups, and JSON/Markdown rendering.
  • Records and compares sweeps against Mokka v0.3.0 and commit 57ef016.
  • Adds operational documentation and diagrams describing coverage, failure attribution, and the silicon readiness gate.

Confidence Score: 4/5

The PR should fix cell-ID validation before merging because duplicate IDs can reuse and double-count a single result directory; duplicate CTRF handling is additional non-blocking hardening.

The harness trusts operator-supplied cell IDs as unique result identities, allowing repeated IDs to classify the same on-disk results more than once and corrupt the coverage roll-up.

Files Needing Attention: tests/aicr-sweep/main.go, tests/aicr-sweep/classify.go, tests/aicr-sweep/ctrf.go

Important Files Changed

Filename Overview
tests/aicr-sweep/main.go Orchestrates matrix loading and report generation, but does not enforce unique cell IDs before mapping cells to result directories.
tests/aicr-sweep/classify.go Implements conservative classification and roll-up invariants; duplicate runtime test names are silently overwritten.
tests/aicr-sweep/ctrf.go Parses and merges phase reports deterministically, although merged duplicate names have no explicit resolution contract.
tests/aicr-sweep/report.go Produces deterministic machine- and human-readable roll-ups with explicit simulation and roadmap qualifications.
tests/aicr-sweep/classify_test.go Covers core classification invariants and catalog validation but omits duplicate merged-result and cell-ID cases.
tests/aicr-sweep/catalog.yaml Defines the evidence-backed A/B/C/G classification used by both recorded sweeps.
docs/aicr-preflight/coverage.md Documents measured versus analytical coverage and preserves the boundary between simulated evidence and silicon-only checks.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  C[Catalog and cell matrix] --> R[Per-cell CTRF reports]
  R --> P[Parse and merge reports]
  P --> K[Classify each catalog check]
  K --> U[Roll up checks across cells]
  U --> J[report.json]
  U --> M[coverage.md]
  K --> N[Blocked and not-run remain in denominator]
  K --> S[Simulated hardware-only passes marked suspect]
Loading

Reviews (1): Last reviewed commit: "fix(docs): unbreak the site build the ai..." | Re-trigger Greptile

Comment thread tests/aicr-sweep/main.go
Comment on lines +83 to +88
results := make([]CellResult, 0, len(doc.Cells))
for _, spec := range doc.Cells {
var run *RunResults
cause, why := spec.BlockedCause, spec.BlockedWhy

if cause == CauseNone && *resultsDir != "" {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Duplicate cell identities

When an operator-supplied cells file repeats an ID, both entries load the same CTRF directory and classify it as separate matrix cells, causing duplicate attribution and an incorrect aggregate coverage result. Validate that cell IDs are unique before processing the matrix.

Comment on lines +79 to +83
byName := map[string]RunTest{}
if run != nil {
for _, t := range run.Tests {
byName[t.Name] = t
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Duplicate verdict overwrite

When multiple phase or retained rerun reports contain the same check name, this assignment silently keeps whichever entry sorts last by filename. The generated verdict therefore depends on incidental file ordering and hides the other result; reject duplicates or define an explicit resolution rule.

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