All pages
check and watch
check compiles the whole experiment (evaluates the file, traces every
graph, checks every shape, validates the IR) and reports every diagnostic.
It reads the .sx and everything it requires, never the data, and writes
nothing. It needs no GPU and finishes in well under a second.
$ sexpgpu check my-run.sx
ok: 32 parameters, 66 graphs, 20 steps
The ok: line and warnings go to standard error; warnings do not fail.
Any error exits 1.
A failure
$ sexpgpu check bad-shape.sx
error[E-DIM-001]: matmul: inner dims differ: [2, 16] x [32, 8]: 16 against 32
--> bad-shape.sx:7:15
|
7 | (lambda (x) (matmul x weight)))
| ^^^^^^^^^^^^^^^^^
note: operands: `x` [2, 16] f32, `weight` [32, 8] f32
note: applying model `model`
--> bad-shape.sx:9:15
|
9 | (defvar model (tiny 32 8))
| ^^^^^^^^^^^
help: `(matmul a b)` contracts the last axis of `a` with the second to last of `b`
in: model -> matmul
Every diagnostic has a code, a primary span, the expected and actual facts, and a fix when one is known. Look codes up in diagnostic codes.
--json
check <file> --json puts an array on standard output instead, one object
per diagnostic. Flags come after the file.
[{"code": "E-DIM-001",
"message": "matmul: inner dims differ: [2, 16] x [32, 8]: 16 against 32",
"span": {"file": ".../bad-shape.sx", "line": 7, "col": 15, "start": 248, "end": 265},
"notes": [{"message": "operands: `x` [2, 16] f32, `weight` [32, 8] f32", "span": {...}},
{"message": "applying model `model`", "span": {"line": 9, "col": 15, ...}}],
"trace": ["model", "matmul"],
"fix": "`(matmul a b)` contracts the last axis of `a` with the second to last of `b`"}]
span is null when there is no location. An empty array is a clean file.
Where a diagnostic points
The primary span is a line in a file you own. A failure raised in library
code (the prelude, a standard module, or a file with a directory called
lib in its path) moves its span to the innermost call that is yours: a
model application, a function call, or the macro call whose expansion
built the failing form. The line that raised it becomes the note "raised
by this expression". Code generated by a macro keeps the macro call and
template origin as notes. A failure while loading a required file notes
every require on the way, each "file is required here".
The message states the expected and the actual facts: the value it found,
type and text (found string "4"), the axis and the sizes that disagree.
A wrong name gets the nearest one that exists, and the list when it is
short. A wrong argument count or keyword prints the callee's signature and
notes where it is defined. An unclosed bracket names the form it opens and
notes the first line inside it that starts at column one, where the closer
most likely belongs. W-* codes are warnings and never stop a
compilation.
watch
sexpgpu watch <file.sx> runs check, then polls every file the last
compilation read every 250 ms, clearing the terminal and checking again
whenever one moves, appears or disappears. It never exits on its own;
Ctrl-C stops it. Standard modules have no file on disk and are not watched.
It takes the selection.
Related: explain, diagnostic codes.