CLI reference¶
serq run FILE [--seed N] [--horizon T] [--warmup T] [--arrivals N] [--set name=expr]...
[--def name=expr]... [--trace F] [--json] [--dump DIR]
serq check FILE [--set name=expr]... [--def name=expr]...
serq ir FILE [--set name=expr]... [--def name=expr]... [--seed N] [--horizon T] [--warmup T]
[--arrivals N] [--trace F] [--inline-trace]
serq draw FILE [--set name=expr]... [--def name=expr]... [--format tikz|svg] [--out PATH] (experimental)
serq fmt [--check] FILE...
serq --version
FILE is program text (.sq) or IR (.json, as written by serq ir).
Commands¶
run |
execute the program as a discrete-event simulation and print the report |
check |
parse, resolve every name and fold the constants; print a summary. This is what make check runs over every program |
ir |
print the program's IR as JSON |
draw |
render the program as a figure (visualization) |
fmt |
format one or more .sq files in place; comments, blank lines, number spellings, and aligned trailing comments are preserved |
--version (or -V) |
print serq X.Y.Z, the interpreter's version, for the record of a run; run --json writes the same as serq_version |
Options¶
| Flag | Applies to | Meaning |
|---|---|---|
--seed N |
run, ir | RNG seed, overriding the program's run block |
--horizon T |
run, ir | simulated seconds |
--warmup T |
run, ir | seconds discarded before anything is recorded |
--arrivals N |
run, ir | stop after N arrivals and drain their sessions, overriding the run block's arrivals (a finite run); open workloads only |
--set name=expr |
all | override a declared let constant (unknown names are errors; the last override of a name wins). Rejected if the constant, directly or through another let, sets a queue family's size. Rejected on .json: an IR's constants are already folded |
--def name=expr |
all | replace the body of a declared expression def, which then expands at each use as if written so: a distribution, a policy key or a law per class passed in as a parameter (--def service='~erlang(4, 1)'). The body may draw and read what the program's body could; the definition keeps its parameters. Unknown names and statement definitions are errors; the last override of a name wins. Rejected on .json: an IR's definitions are already expanded |
--trace F |
run, ir | replace the program's trace corpus |
--inline-trace |
ir | turn the trace file into the sessions' turns, as CArrival::Sessions data |
--json |
run | print the report as JSON |
--dump DIR |
run | write DIR/<name>.csv per observe, columns time,session,turn,value, and DIR/gauge/<name>.csv per gauge, columns time,value (its change points) |
--format |
draw | tikz (default) or svg |
--out PATH |
draw | write to a file instead of stdout |
--check |
fmt | exit with code 1 and list files that need formatting, without writing them |
The JSON report¶
observes and gauges are objects keyed by name; stages and pools are arrays.
serq run examples/multi-turn/vllm.sq --json | jq '.observes.ttft.mean'
serq run examples/multi-turn/vllm.sq --json | jq '.pools[] | select(.name=="kv") | .preemptions'
| Path | |
|---|---|
| top level | serq_version (the interpreter that ran, serq --version), horizon (the configured deadline), end (when the run ended: horizon, or earlier with --arrivals), warmup, seed, events, arrivals, ended, turns, mean_live |
observes.<name> |
count, mean, ci, cv2, p99 |
gauges.<name> |
mean (time average over [warmup, end]), ci, min, max |
stages[] |
name, index (the member's index in a stage array, null for a single stage), mean_number, utilization, completed, throughput, mean_wait, mean_service, iterations, and for a step stage: prefill_only, decode_only, mixed (fractions of the measured time an iteration of prefill only, decodes only, or both was running; the rest is idle), mean_decodes (time-average decodes in the running iteration, 0 while none runs), mean_decode_batch and mean_decode_step (the decodes and the duration of an iteration that carried a decode, averaged over those started after warm-up: the batch a decode is in and the step it waits for), mean_itl, itl_p50, itl_p99 (the gaps between a turn's successive tokens, a session's tokens with the same turn_no, that end on the stage after warm-up, wherever the earlier token was: a transfer between a prefill engine's first token and a decode engine's second is in the gap, and so is a preemption; a prefill's end is the next token after a decode or after a preemption on the previous token's stage, otherwise the first, replacing any before it, so a decoder's recompute replaces a prefiller's dropped token; a turn's gaps add up to its last token less its first; the quantiles are within 0.5 %, exact for a single value, the mean exact); 0 for the fractions and mean_decodes, null for the others, on other stages. An iteration that only preempted counts as idle; utilization is the time with a job present, which differs from 1 - idle while residents stall. iterations counts the whole run, warm-up included |
pools[] |
name, index (the member's index in a pool array, null for a single pool), mean_used, mean_cached, mean_queue, mean_holders, mean_wait, admissions, evicted_entries, evicted_units, preemptions, spills, rejected, stuck (sessions preempted again without progress since their previous preemption) |
Make targets¶
make check |
fmt, clippy, tests, every program links and draws, the oracles agree, IR files current |
make oracle-ir |
regenerate tools/oracle/*.ir.json |
make draw-golden |
regenerate tests/golden/ |
Input errors¶
fmt parses every input before writing any file. It leaves the batch untouched
if one file has a syntax error. make check runs fmt --check on the example
and tutorial programs.
Commands and their supported options are checked before the program is opened.
An unknown command or option, a missing value, or an invalid value prints the
problem and a correction hint to stderr and exits with code 2. Options belonging
to another command are rejected rather than ignored. --seed takes an unsigned
integer, --horizon a finite positive number, --warmup a finite nonnegative
number, and --arrivals a positive integer. Program loading, validation, and runtime errors exit with code 1. Failed commands
do not write a report to stdout.
Trace CSV errors identify the actual trace path, row, and column name, followed
by a correction hint. Paths declared in the program are relative to its directory;
--trace paths are relative to the current directory. run and
ir --inline-trace use the same trace diagnostics.
Name-resolution errors in .sq programs show the line, character column,
source excerpt, and a correction hint. A close, unambiguous name of the same
kind is suggested with its declaration location; duplicate pools and stages
identify both declarations. Locations survive server/request expansion and
header bindings. .json validation errors use IR context instead of inventing
text-source locations. Syntax errors, including unclosed /* comments, point
to the offending source location.