[executorch][native] Add Graph index arena to the in-memory IR - #22280
[executorch][native] Add Graph index arena to the in-memory IR#22280SS-JIA wants to merge 1 commit into
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/22280
Note: Links to docs will display an error until the docs builds have been completed. ✅ You can merge normally! (1 Unrelated Failure)As of commit 50bc327 with merge base a5f15b5 ( FLAKY - The following job failed but was likely due to flakiness present on trunk:
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
This PR needs a
|
digantdesai
left a comment
There was a problem hiding this comment.
Review automatically exported from Phabricator review in Meta.
Stack from ghstack (oldest at bottom):
Adds
ptn::Graph, the index arena that owns the value layer landed so far. Itis a pure function body (mirrors the schema
Graph): it holds theNodes andValues that theNodeId/ValueIdhandles point into, the ordered graphinput / output value lists, and -- recursively -- the subgraph bodies for
higher-order ops. Stateful method-level bindings (constants, output specs,
mutable buffers) are deferred to a later
Methodtype.Design decisions baked in:
Per-graph subgraph arena.
Graphownsstd::vector<Graph> subgraphsandGraphIdindexes the enclosing graph'ssubgraphs, matching the schema'srecursion and the per-Graph SSA namespace so a subgraph stays self-contained
with its parent. (A
std::vector<Graph>member ofGraphis legal C++17 --the standard containers permit an incomplete value type at the point of the
member declaration.)
Storage identity vs execution order are decoupled.
nodesis anappend-only arena so a
NodeIdnever shifts (the index-arena invariant),while
schedule(std::vector<NodeId>) carries the topological / executionorder a runtime walks. At load the arena order equals the wire's topological
order and
scheduleis the identity[0, n)(initialize_schedule()); acrossmutation the arena order is no longer topological, so
scheduleisauthoritative -- reorder / insert there (moving
int32s, invalidating no id)rather than moving storage. Deletion via tombstone + a compacting pass is
deferred until a mutating pass needs it.
Pure arena.
inputs/outputsareValueIdlists (schema SSA namesresolved to ids at deserialize); no
tensor_valuesside table in memory(each
Valuealready carries itsTensorMeta); the name to id map staysdeserializer-local.
rebuild_def_use()recomputes everyValue'sproducer/consumersfrom thenodes (order-independent -- it walks the arena, not
schedule). Placeholder andOutput nodes are real entries in
nodes, so def-use is uniform: a graph inputvalue's producer is its placeholder node, and graph inputs are identified by
membership in
inputs, not byproducer == kInvalid. This corrects the nowstale
Value.hproducercomment (also in this diff). Bounds-checkednode()/value()/subgraph()accessors throw on an invalid id, and theIR printer gains
to_string(const Graph&), a multi-line dump inscheduleorder.
consumer_idsis a set of consuming nodes rather than a bag of uses, soadd(x, x)lists its consumer once andsize()counts consumers. Since nodesare walked in arena order a repeated operand appends consecutively, so a tail
check keeps that exact without a lookup structure.
rebuild_def_use()distinguishes the two things an unusable id can mean.kInvalidis an absent operand and is skipped; an id that is set but does notaddress the value arena can only be a corrupt graph, and now throws rather than
being skipped, which would have left def-use half-wired with no signal. That
matches the accessors, which already throw on a bad id.
Pure std only (no ExecuTorch, no flatbuffers), consistent with the rest of the
standalone
ptnruntime.Differential Revision: D114396767