# 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.

```console
$ 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

```console
$ sexpgpu check bad-shape.sx
error[E-DIM-001]: matmul: inner dims differ: [2, 16] x [32, 8]
  --> 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))
   |               ^^^^^^^^^^^
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](https://sexpgpu.041.io/docs/errors.md).

## --json

`check <file> --json` puts an array on standard output instead, one object
per diagnostic. Flags come after the file.

```json
[{"code": "E-DIM-001",
  "message": "matmul: inner dims differ: [2, 16] x [32, 8]",
  "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"]}]
```

`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 (a standard module, or a file with a directory called `lib` in its
path) moves its span to the innermost model application that is yours,
and 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. `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](https://sexpgpu.041.io/docs/cli.md#the-selection).

Related: [explain](https://sexpgpu.041.io/docs/explain.md), [diagnostic codes](https://sexpgpu.041.io/docs/errors.md).

---

SexpGPU documentation. Every page: https://sexpgpu.041.io/llms.txt
