Compile-time edge validation#
MADDENING v0.2 added a graph-edge consistency check. Every edge wires one
node’s output field to another node’s BoundaryInputSpec; the check flags
edges whose two ends disagree.
What it checks#
For each edge, GraphManager.validate() compares the source field against
the target node’s boundary_input_spec() entry on three axes:
shape — source array shape vs.
BoundaryInputSpec.shape.dtype — source array dtype vs.
BoundaryInputSpec.dtype.units — the edge’s declared
source_units/target_unitsvs. the spec’sexpected_units.
Shape and dtype checks are skipped when the edge carries a transform
(which may legitimately reshape or recast) or when the spec leaves a
dimension symbolic. Unit checks are advisory only.
How it runs#
issues = gm.validate() # returns a list of strings
Edge issues come back as strings prefixed WARNING[shape],
WARNING[dtype], or WARNING[units]. validate() is also run
automatically inside gm.compile(), which routes each prefix to a typed
warning:
Prefix |
Warning class |
|---|---|
|
|
|
|
|
|
All three subclass EdgeValidationWarning (in maddening/warnings.py),
so a caller can warnings.catch_warnings() on the base class to handle
them uniformly. In v0.2 these are warnings; the v0.2.1 plan flips shape
and dtype to hard EdgeValidationErrors — unit mismatches stay advisory
permanently, since units are documentation, not contract.
How MIME stays clean#
MIME’s representative experiment graphs are pinned edge-validation-clean
(v0.2 fit-up §4) by tests/verification/test_edge_validation.py. The test
builds each experiment graph, calls validate() directly, and asserts no
issue carries an edge prefix:
_EDGE_ISSUE_PREFIXES = ("WARNING[shape]", "WARNING[dtype]", "WARNING[units]")
edge_issues = [i for i in gm.validate() if i.startswith(_EDGE_ISSUE_PREFIXES)]
assert not edge_issues
It calls validate() rather than compile() because validate() is the
edge check — skipping the JIT keeps the test cheap. LBM/FVM graphs are
built at reduced resolution; edge-spec consistency does not depend on
lattice size. A new node that introduces a mismatched edge fails here
loudly, instead of letting MADDENING v0.2.1 escalate it to a hard error.
Adding a custom node#
To keep validate() clean for a new node:
Declare a complete
boundary_input_spec()— give every boundary input a concreteshape,dtype, and anexpected_unitstag where a physical unit applies.Make sure each edge feeding the node produces a field of the matching shape and dtype, or attach a
transformthat reconciles them.Add the node’s experiment to
test_edge_validation.py(register a builder) and confirmgm.validate()reports no edge issue.