MCPcopy Create free account
hub / github.com/pytorch/tutorials / ProfilingInterpreter

Class ProfilingInterpreter

intermediate_source/fx_profiling_tutorial.py:98–194  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

96# Let's define our ``ProfilingInterpreter`` class:
97
98class ProfilingInterpreter(Interpreter):
99 def __init__(self, mod : torch.nn.Module):
100 # Rather than have the user symbolically trace their model,
101 # we're going to do it in the constructor. As a result, the
102 # user can pass in any ``Module`` without having to worry about
103 # symbolic tracing APIs
104 gm = torch.fx.symbolic_trace(mod)
105 super().__init__(gm)
106
107 # We are going to store away two things here:
108 #
109 # 1. A list of total runtimes for ``mod``. In other words, we are
110 # storing away the time ``mod(...)`` took each time this
111 # interpreter is called.
112 self.total_runtime_sec : List[float] = []
113 # 2. A map from ``Node`` to a list of times (in seconds) that
114 # node took to run. This can be seen as similar to (1) but
115 # for specific sub-parts of the model.
116 self.runtimes_sec : Dict[torch.fx.Node, List[float]] = {}
117
118 ######################################################################
119 # Next, let's override our first method: ``run()``. ``Interpreter``'s ``run``
120 # method is the top-level entry point for execution of the model. We will
121 # want to intercept this so that we can record the total runtime of the
122 # model.
123
124 def run(self, *args) -> Any:
125 # Record the time we started running the model
126 t_start = time.time()
127 # Run the model by delegating back into Interpreter.run()
128 return_val = super().run(*args)
129 # Record the time we finished running the model
130 t_end = time.time()
131 # Store the total elapsed time this model execution took in the
132 # ``ProfilingInterpreter``
133 self.total_runtime_sec.append(t_end - t_start)
134 return return_val
135
136 ######################################################################
137 # Now, let's override ``run_node``. ``Interpreter`` calls ``run_node`` each
138 # time it executes a single node. We will intercept this so that we
139 # can measure and record the time taken for each individual call in
140 # the model.
141
142 def run_node(self, n : torch.fx.Node) -> Any:
143 # Record the time we started running the op
144 t_start = time.time()
145 # Run the op by delegating back into Interpreter.run_node()
146 return_val = super().run_node(n)
147 # Record the time we finished running the op
148 t_end = time.time()
149 # If we don't have an entry for this node in our runtimes_sec
150 # data structure, add one with an empty list value.
151 self.runtimes_sec.setdefault(n, [])
152 # Record the total elapsed time for this single invocation
153 # in the runtimes_sec data structure
154 self.runtimes_sec[n].append(t_end - t_start)
155 return return_val

Callers 1

Calls

no outgoing calls

Tested by

no test coverage detected