Skip to content

perf(preflight): batch IFoE L2 ping with ScriptLet [AIMVT-331] - #411

Merged
cijohnson merged 4 commits into
mainfrom
perf/aimvt-331-ifoe-scriptlet-batch
Sep 11, 2026
Merged

cijohnson merged 4 commits into
mainfrom
perf/aimvt-331-ifoe-scriptlet-batch

Conversation

@speriaswamy-amd

@speriaswamy-amd speriaswamy-amd commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • AIMVT-331: IFoE L2 ping issued one cluster-wide dispatch per work item (321 serialized round trips on Helios-R 4×8×7). Batch port discovery and pings with ScriptLet (one script per node) — measured 321 → 21 dispatches, same result structure.
  • Recover afmctl exit status when stderr is present (end-anchored sentinel was silently scored PASS).

Test plan

  • Unit tests in test_ifoe_l2_connectivity.py (batched vs unbatched differential)
  • Live Helios-R L2 ping preflight against current main

speriaswamy-amd and others added 4 commits September 10, 2026 18:19
…dispatches)

IFoE L2 connectivity issued one cluster-wide dispatch per work item: port
discovery cost 2 dispatches + 1 SFTP per (node, BDF), and every planned ping
cost another dispatch via _exec_on_node(), which ran the real command on one
host and `true` on all the others. At the production shape (4 nodes x 8 BDFs
x 7 vPOD peers, ports='up') that is 321 serialized round trips.

Both phases now follow the ScriptLet pattern already proven by
rdma_connectivity: generate one script per node containing all of that node's
work, distribute the scripts in a single parallel SCP, execute them with one
exec_cmd_list, and harvest the results. Same shape, measured on a fake
two/four-node cluster driving the real code path: 321 -> 21 dispatches, with
byte-identical results to the unbatched path.

Design notes where this deliberately differs from RDMA:

* No `set -e`. RDMA can afford it because every test is backgrounded and
  reaped with `wait` (always 0). IFoE ping invocations are synchronous and
  their exit codes are load-bearing, so `set -e` would let the first failing
  ping abort the node's remaining tests and report them as *missing* rather
  than *failed* - a false PASS in a check that exists to find failures.
* Per-invocation exit status is preserved, not discarded. Each invocation is
  framed by a BEGIN/END marker pair tagged with a per-run random token, and
  the END marker carries that invocation's own exit status.
* Full stdout is preserved, not grepped. RDMA's collection scripts emit
  key=value failure summaries; IFoE must keep the complete output because the
  real verdict comes from AfmctlPingParser + _evaluate_summary +
  _evaluate_invocation (loss vs threshold, port coverage, pings-per-port
  echo, BDF echo, destination match). A `Summary:` grep would pass a run with
  100% loss. `raw_output` and `parsed` are unchanged in the result structure.
* Port inventory JSON still travels over SFTP, not stdout, per the explicit
  guidance on Pssh.download_file. Artifact paths are now stable per round
  (not uuid-per-call) so one download call serves every node holding a BDF;
  grouped downloads fall back to per-node retries so one node missing a
  device cannot mask the others.
* Each invocation is individually bounded by coreutils `timeout` (falling
  back to unbounded if absent), so a hung afmctl cannot consume the whole
  batch window.

Correctness properties kept:

* Public result structure unchanged; batched and unbatched paths produce
  identical results (verified by differential test).
* Commands run via `bash -c` so the `exit 127` embedded in the sudo
  command form cannot tear down the batch.
* A missing result block fails loudly with an explicit error instead of
  silently vanishing from coverage.
* Backends without real exec_cmd_list/upload_file_list (mocks, lightweight
  wrappers) keep the per-item path via _batching_supported().
* Any batch failure falls back to the per-item path.
* Honors debug.scriptlet and reporting.artifacts_root_dir like RDMA.

Also removes _all_unique_bdfs and _resolve_bdfs_for_node, which had zero
callers repo-wide.

Co-Authored-By: Claude <noreply@anthropic.com>
Pssh._process_output appends a host's stderr after its stdout, so any
stderr output from the targeted afmctl command pushed the
__CVS_AFMCTL_EXIT_STATUS__ sentinel out of the end-anchored regex match
in _extract_exit_sentinel, causing exit_status to fall back to None.
_evaluate_invocation treats None as non-failing, so a failing afmctl
invocation that wrote anything to stderr was silently scored PASS.

Search for the sentinel anywhere in the combined output instead of
anchoring to the end, and splice out only its own line so trailing
stderr content is preserved rather than discarded.
…gurable 10s

check_connectivity()'s 2-second, zero-retry probe for a brand-new SSH
connection is too tight for real hardware: establishing a fresh TCP+SSH
session (especially right after a prior command kept the host busy) can
easily exceed 2s, causing the "double check" to fail and the host to be
permanently pruned from reachable_hosts on what was really a transient
timeout. Observed on real hardware where the first successful invocation
was immediately followed by false-positive pruning, silently turning all
later invocations in the run into no-ops.
@cijohnson
cijohnson merged commit b52ad31 into main Sep 11, 2026
2 checks passed
@cijohnson
cijohnson deleted the perf/aimvt-331-ifoe-scriptlet-batch branch September 15, 2026 00:10
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.

2 participants