Skip to content

Commit ec2f746

Browse files
shino16Masato Shinokawacrcrparkiya00t-vi
authored
ThunderFX: Modify GraphModule in-place (#2399)
Co-authored-by: Masato Shinokawa <shino16@users.noreply.github.com> Co-authored-by: Masato Shinokawa <mshinokawa@viking-prod-235.ipp2u1.colossus.nvidia.com> Co-authored-by: Masaki Kozuki <mkozuki@nvidia.com> Co-authored-by: Yan Wang <kiya00wy@gmail.com> Co-authored-by: Thomas Viehmann <tv.code@beamnet.de>
1 parent 38733f0 commit ec2f746

5 files changed

Lines changed: 14 additions & 14 deletions

File tree

thunder/dynamo/compiler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def __init__(self, **thunder_options):
106106
self._torch_compile = torch.compile
107107

108108
def __call__(self, gm: torch.fx.GraphModule, sample_args: list[torch.SymInt, torch.Tensor]):
109-
gm = remove_empty_autocast(gm)
109+
remove_empty_autocast(gm)
110110

111111
# Dynamo uses lazy generation of the underlying Python code, so we need to
112112
# force recompilation of the GraphModule before passing it to Thunder.

thunder/dynamo/report.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1094,8 +1094,9 @@ def foo(x):
10941094
from thunder.dynamo.splitter import _splitter
10951095
from thunder import jit
10961096

1097+
gm = copy.deepcopy(report.graph)
10971098
# Splits the FX graph module using Thunder splitter
1098-
gm = remove_empty_autocast(report.graph)
1099+
remove_empty_autocast(gm)
10991100
# Dynamo uses lazy generation of the underlying Python code, so we need to
11001101
# force recompilation of the GraphModule before passing it to Thunder.
11011102
recompile_graph(gm)

thunder/dynamo/splitter.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,17 +144,20 @@ def callback(node) -> int:
144144
gm.recompile()
145145

146146
# `split_module` iterates over nodes and determines the partition to place them based on the callback.
147-
original_split_gm: torch.fx.GraphModule = split_module(
147+
split_gm: torch.fx.GraphModule = split_module(
148148
gm, root_m=None, split_callback=callback, keep_original_order=True, keep_original_node_name=True
149149
)
150150

151151
# Workaround for the Torch bug https://github.com/pytorch/pytorch/pull/139275
152-
for submodule in original_split_gm.children():
152+
for submodule in split_gm.children():
153153
if not submodule.graph.find_nodes(op="output"):
154154
submodule.graph.output(())
155-
if not original_split_gm.graph.find_nodes(op="output"):
156-
original_split_gm.graph.output(())
157-
split_gm = copy.deepcopy(original_split_gm)
155+
if not split_gm.graph.find_nodes(op="output"):
156+
split_gm.graph.output(())
157+
158+
# If split_gm contains Parameters or Tensors then deepcopy would also create their copies.
159+
# TODO: Eliminate deepcopy
160+
original_split_gm = copy.deepcopy(split_gm)
158161

159162
def is_thunder_supported_partition(node: torch.fx.Node) -> bool:
160163
return node.name.startswith("submod") and int(node.name.replace("submod_", "")) in supported_partitions

thunder/dynamo/utils.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -697,13 +697,10 @@ def remove_empty_autocast(graph_module: torch.fx.GraphModule) -> torch.fx.GraphM
697697
graph_module: Graph module to which this pass is applied.
698698
699699
"""
700-
701-
empty_autocast_removed_graph_module = copy.deepcopy(graph_module)
702-
703700
# Dummy init node.
704701
prev_node = torch.fx.node.Node(graph_module.graph, "start_node", "call_function", lambda: None, None, None)
705702
nodes_to_erase = []
706-
for node in empty_autocast_removed_graph_module.graph.nodes:
703+
for node in graph_module.graph.nodes:
707704
# As _enter_autocast and _exit_autocast functions map the regions created by context manager,
708705
# previous `_enter_autocast` will always correspond with current `_exit_autocast`.
709706
if (
@@ -721,9 +718,9 @@ def remove_empty_autocast(graph_module: torch.fx.GraphModule) -> torch.fx.GraphM
721718

722719
# Erase the marked nodes.
723720
for node in nodes_to_erase:
724-
empty_autocast_removed_graph_module.graph.erase_node(node)
721+
graph_module.graph.erase_node(node)
725722

726-
return empty_autocast_removed_graph_module
723+
return graph_module
727724

728725

729726
def arg_like_tensor(arg: torch.Tensor | ExampleInputMetaData):

thunder/tests/test_dynamo.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,6 @@ def func(x):
474474
dtypes=(dtypes.float32,),
475475
executors=(DynamoThunderExecutor,),
476476
decorators=(
477-
pytest.mark.skip(reason="https://github.com/Lightning-AI/lightning-thunder/issues/1821"),
478477
pytest.mark.parametrize(
479478
"optim",
480479
(

0 commit comments

Comments
 (0)