pub fn base_map_hash(graph: &Graph, root: NodeId) -> u64Expand description
NodeId-independent content hash of the subgraph rooted at root.
Recursively hashes each node as (op identity, child hashes), folding in
each child’s hash rather than its NodeId — so two independently-built
graphs (different arenas, different NodeId numbering) that are
structurally identical hash equal. Reuses this module’s existing
canonicalization primitives rather than duplicating them:
op_keyfor op identity when available (covers every primitive +Op::Fusedvariant CSE already relies on).is_commutativeto sort child hashes forAdd/Mul, soa + bandb + ahash equal (mirrors CSE’s own commutative-operand canonicalization).Maximum/Minimumare excluded – see GAP-271.
op_key deliberately excludes Op::Const (its payload lives in the
graph’s storage_map slot, not the Op enum) and returns None
for a handful of other ops (in-place,
indexing, and anything else not explicitly listed). For those, this
function falls back to (discriminant, shape, dtype) — and, for
Op::Const specifically, additionally folds the constant’s real bytes
when they’re readable (see fold_const_bytes below) so two
independently-built recipes with equal constants hash equal, not just
equal-shaped placeholders.
This is a cheap structural pre-filter for cross-graph recipe identity:
structurally-equal-up-to-commutative-reordering-and-fusion-depth base
maps hash equal. It does NOT canonicalize associativity or
distributivity ((a + b) + c vs a + (b + c) hash differently) — a
numeric verify pass covers that residual. Hashes are only stable within
one process / DefaultHasher instance; never persist or compare them
across processes.