-
Notifications
You must be signed in to change notification settings - Fork 25.6k
[FX] Make Graphs immutable and make GraphModule recompile after assigning graph #44830
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
[ghstack-poisoned]
Differential Revision: [D23743850](https://our.internmc.facebook.com/intern/diff/D23743850) [ghstack-poisoned]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should expose generate forward. It makes more sense that assignment to the .graph
property automatically regenerates forward. graph
itself should be immutable. This patch should also enforce the immutability of graph
after it has had an output declared.
@zdevito how do we enforce immutability of |
Differential Revision: [D23743850](https://our.internmc.facebook.com/intern/diff/D23743850) [ghstack-poisoned]
Differential Revision: [D23743850](https://our.internmc.facebook.com/intern/diff/D23743850) [ghstack-poisoned]
Differential Revision: [D23743850](https://our.internmc.facebook.com/intern/diff/D23743850) [ghstack-poisoned]
@zdevito updated. I don't particularly like how this breaks editing after copy/deepcopy |
torch/fx/graph.py
Outdated
self.nodes : FinalizableList = FinalizableList() | ||
val_map = {} | ||
for node in from_graph.nodes: | ||
val_map[node] = self.node_copy(node, lambda n: val_map[n]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, should node_copy
be delegate-customizable too? I'm thinking of cases when extra metadata is hanging off the node and we want to copy it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delegate is now Tracer and only affects how tracing occurs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then what is the recommended mechanism fo attaching more stuff to nodes in the graph and preserving them? Should we copy entries in the __dict__
(though it's a bit hacky)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could add extra_info : Dict[str, Any]
to Node that gets copied over?
torch/fx/graph.py
Outdated
def output(self, result: Argument): | ||
self.result = result | ||
self._mark_uses(result) | ||
self.nodes.finalize() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, have you considered just doing self.nodes = tuple(self.nodes)
? :) What is the benefit of FinalizableList over Tuple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every time you append to the tuple you'd have to create a new data structure? Also that doesn't match with the specification above, of immutable after an output has been specified
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean to change type from list
to tuple
only when you want to finalize. Afaiu, list and tuple are mostly indistinguishable from the consumption standpoint.
💊 CI failures summary and remediationsAs of commit e38e222 (more details on the Dr. CI page): ✅ None of the CI failures appear to be your fault 💚
🚧 1 fixed upstream failure:These were probably caused by upstream breakages that were already fixed.
Please rebase on the
|
torch/fx/graph.py
Outdated
else: | ||
return a | ||
|
||
class FinalizableList(list): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure all this infrastructure is worth it. We can just change nodes
to be a property and then editing nodes doesn't change the graph.
torch/fx/graph.py
Outdated
class Graph: | ||
def __init__(self): | ||
self.nodes : List[Node] = [] | ||
def __init__(self, from_graph : Optional['Graph'] = None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a big odd to put this in the constructor. A graph could have a function copy_graph
similar to copy node that would copy/append the entire graph. Then someone wanting to append to a graph can:
b = Graph()
a.copy_graph(b, input_fn) # same structure as copy node but copies an entire graph
Appending to a graph only is a specific use case, the general one is editing a graph (i.e. doing node-by-node transforms) and then splices graphs into eachother (graph_copy).
Differential Revision: [D23743850](https://our.internmc.facebook.com/intern/diff/D23743850) [ghstack-poisoned]
Differential Revision: [D23743850](https://our.internmc.facebook.com/intern/diff/D23743850) [ghstack-poisoned]
…after assigning graph" Differential Revision: [D23743850](https://our.internmc.facebook.com/intern/diff/D23743850) [ghstack-poisoned]
…after assigning graph" Differential Revision: [D23743850](https://our.internmc.facebook.com/intern/diff/D23743850) [ghstack-poisoned]
…after assigning graph" Differential Revision: [D23743850](https://our.internmc.facebook.com/intern/diff/D23743850) [ghstack-poisoned]
…after assigning graph" Differential Revision: [D23743850](https://our.internmc.facebook.com/intern/diff/D23743850) [ghstack-poisoned]
@jamesr66a merged this pull request in 79fe794. |
Stack from ghstack:
Differential Revision: D23743850