@eellison I did what you suggested, and I noticed the final optimized output looks like:
[DUMP profiling_graph_executor_impl.cpp:620] Optimized Graph:
[DUMP profiling_graph_executor_impl.cpp:620] graph(%x.1 : Tensor):
[DUMP profiling_graph_executor_impl.cpp:620]   %1 : int = prim::Constant[value=1]()
[DUMP profiling_graph_executor_impl.cpp:620]   %4 : Tensor = aten::add(%x.1, %x.1, %1) # triple_add.py:5:11
[DUMP profiling_graph_executor_impl.cpp:620]   %7 : Tensor = aten::add(%4, %x.1, %1) # triple_add.py:5:11
[DUMP profiling_graph_executor_impl.cpp:620]   return (%7)

It still makes two separate calls to add. I would think part of kernel fusion is that it could somehow make one call to add that takes in all three inputs. Am I misinterpreting the graph, or am I misunderstanding what kernel fusion does?