Skip to content

Add model stats to Ping Pong example#265

Merged
caitlinross merged 4 commits into
codes-org:masterfrom
caitlinross:ping-pong-model-stats
Jul 15, 2026
Merged

Add model stats to Ping Pong example#265
caitlinross merged 4 commits into
codes-org:masterfrom
caitlinross:ping-pong-model-stats

Conversation

@caitlinross

@caitlinross caitlinross commented Jul 14, 2026

Copy link
Copy Markdown
Member

Ping pong example will be integrated into NetMaestro soon, so this adds the model stats to be collected by ROSS instrumentation layer to the terminal LP in that example, as well as adds some additional metrics to what's collected in dragonfly dally. This also adds some documentation and a reference python parser and some tests that run if python3 is available.

Terminal GVT/RT payloads now carry packets generated/finished deltas,
minimal and non-minimal finished-chunk deltas, per-rail stalled-chunk
deltas, and vc_occupancy/terminal_length snapshots. Router payloads gain
per-port stalled-chunk deltas, vc-occupancy sums, and queued-byte
snapshots. The virtual-time (analysis LP) path carries the same fields
via new dfly_cn_ross_sample / dfly_router_ross_sample structs, kept
deliberately separate from dfly_cn_sample / dfly_router_sample so the
CODES-native sampling on-disk format is untouched.

Also fixes three pre-existing bugs:

(1) terminal mstat_sz was a static 48 B, but the collect fn writes
    40 + 8*num_rails, so multi-rail configs overflowed the heap; the
    size is now computed at runtime like the router already does.

(2) surrogate freeze memset the terminal state and dropped the
    instrumentation array pointers, so GVT collection during frozen
    mode dereferenced NULL; the pointers are now carried across
    freeze/unfreeze and the collect/sample fns NULL-guard, emitting
    zeros for hidden network state.

(3) the terminal VT sample fn initialized its appended-array pointer
    from an uninitialized buffer value (a wild write if --model-stats=3
    was ever used); it now uses the array-after-struct pattern the
    router fn already used.

New scalar shadows are wired into check_terminal_state; the new arrays
are listed in the save/check exclusion comments. Payload layouts are
documented in doc/model-stats-binary-format.md (later commit in this
series).
Register st_model_types for the nw-lp server LP with every mode
implemented: event-type tracing, a 44-byte GVT/RT delta payload
(ping/pong send/recv counts, bytes sent, RTT sum/count), and
virtual-time sampling via a new svr_sample struct with forward and
reverse callbacks.

App-level RTT is measured by stamping the PING send time into the
message and echoing it back in the PONG; the computed RTT is stored in
the message so the reverse handler can subtract it exactly. Two
accumulator sets are kept -- scalars for GVT/RT and svr_sample for VT --
following the dragonfly convention, so the --model-stats=4 modes do not
zero each other's deltas.

Registration mirrors model-net-synthetic.c and is gated on
g_st_ev_trace / g_st_model_stats / g_st_use_analysis_lps before
codes_mapping_setup(). Comments are deliberately didactic since this is
teaching code.

svr_msg grew 16 bytes, so message_size goes 440 -> 456 in all four
config templates. The config headers gain a model-stats run-line note,
and the tutorial comment warns that --vt-samp-end must be set explicitly
because g_tw_ts_end is 24h here.
Add a byte-level spec of ross-stats-model.bin (sample_metadata +
model_metadata framing, GVT/RT) and ross-stats-analysis-lps.bin
(lp_metadata framing, VT), plus the per-LP payload layouts for the ping
pong server and the dally terminal/router. It is written for downstream
consumers (NetMaestro) so the layout no longer lives only in C code.

Caveats are documented: records are not time-sorted across PEs,
buffer-overflow drops can occur, the final partial interval is not
emitted, RT deltas can go slightly negative under optimistic sync, and
GVT and RT share an accumulator under --model-stats=4 while VT is
independently complete.

scripts/parse-ross-model-stats.py is a stdlib-only reference parser that
emits per-LP-type CSV, dispatching payloads by size with --num-rails /
--num-qos / --radix and exiting non-zero on framing errors so tests can
assert parseability.

codes-vis-readme.md gets a cross-link to the spec, an "nw-lp" typo fix,
and its implemented-LP list brought up to date.
example-ping-pong-model-stats.sh runs GVT mode (--model-stats=1,
--num-gvt=100 to keep output around 1 MB; sampling every GVT would be
~50x larger) and asserts ross-stats-model.bin is non-empty and
round-trips through the reference parser with records for all three LP
types and zero unknown payload sizes.

example-ping-pong-model-stats-modes.sh runs --model-stats=4 and asserts
the analysis-lps file exists and parses with virtual-time records
present; RT record counts are wall-clock dependent, so they are not
asserted.

Both scripts soft-skip the parser checks when python3 is absent, since
python3 is not a hard test dependency, and both are registered in the
test-shell-files list.
@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.08602% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/networks/model-net/dragonfly-dally.cxx 94.08% 11 Missing ⚠️

📢 Thoughts on this report? Let us know!

@caitlinross

Copy link
Copy Markdown
Member Author

FYI @marySalvi and @bnmajor

@caitlinross caitlinross merged commit 483a069 into codes-org:master Jul 15, 2026
16 checks passed
@caitlinross caitlinross deleted the ping-pong-model-stats branch July 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.

1 participant