Appendix to Connectivities as types. The mechanics behind rules 1 and 3-6 of Identity is the qualified Python name: reconstruction by import, the one
copyreghook, fingerprinting, the injective codegen mangling, and theStaggered[D]tag grammar.
Rule 1 — reconstruction from the IR is an import
- Reconstruction from the IR is an import.
resolve(tag)imports the longest importable module prefix and walks the rest as attributes (nested classes likeV2E.Localresolve naturally), the waypicklereferences a class. Only where the module path ends is memoized: the attribute walk is repeated, so a declaration redefined under the same name (a re-run notebook cell) resolves to the new class.AxisLiteralstores only the tag and deriveskindanddimfrom it as read-only properties (theTODOatiterator/ir.py:93); the derivedkindis optional, since a local dimension’s isNone; printing IR never imports (resolve_loaded).Staggered[D]tags use the small grammar<owner tag>[<base tag>], resolved by subscripting the owner.
Rules 3-6 — registry, fingerprints, mangling, staggering
- No registry. Classes pickle by reference. One narrow
copyreghook exists, forStaggered[D], whose bracketed qualnamesave_globalcannot look up; it reduces to the base dimension and re-interns. - Fingerprints depend on qualified names, plus
kind. A dimension is deconstructed as its by-reference name and its declaration-timekind, which decides a field’s layout order and the scan axis — so a dimension redefined under the same name with another kind does not reuse artifacts.Staggered[D]goes through its base and inherits this; its base cannot be flipped in place, since the class is interned by base identity and its tag embeds the base tag. The axis level (CartesianAxisIndexversusDimensionIndex) is deliberately not fingerprinted: it changes what is accepted, never what is emitted. A connectivity declaration is fingerprinted additionally by its domain, codomain,Localand counts. Consequently the ADR 0023 build cache invalidates on module renames. - Codegen names need injective mangling.
codegen_name(tag)is a prefix escape —_→_u,.→_d,[→_l,]→_r— used by gtfn, DaCe, the roundtrip backend and the nanobind bindings; its inversefrom_codegen_nameis used by DaCe to parse names back. The simpler “escape__, then replace.” is not injective (".."and"_"collide); the prefix escape is tested exhaustively over its alphabet up to length 4. - Staggering is part of the dimension change. The
_Staggeredname prefix needs the name→class lookup that type identity removes, soStaggered[D]is a real class and part of ADR 0029 (PR A), together with the Cartesian axis dimensions its parameter is bounded on; see [[personal/egparedes/connectivities-as-types/connectivities-as-types#staggeredd|Staggered[D]]].
The Staggered[D] tag
- IR and serialization. The tag is
gt4py.next.common.Staggered[<base tag>]— the one tag that is not a qualified name.resolveparses the<owner>[<base>]grammar and subscripts the owner, the IR pretty-parser accepts it, andcodegen_nameescapes the brackets.picklecannot look up a bracketed qualname, so onecopyreghook reduces a staggered class to its base and re-subscripts on load; fingerprints are likewise taken through the base.