(self, graph_module: GraphModule)
| 249 | ) |
| 250 | |
| 251 | def call(self, graph_module: GraphModule) -> PassResult: |
| 252 | modified = False |
| 253 | for node in graph_module.graph.nodes: |
| 254 | if node.op != "call_function" or node not in self.table_ops: |
| 255 | continue |
| 256 | input_qparams = node.meta.get("input_qparams", {}) |
| 257 | output_qparams = node.meta.get("output_qparams", {}) |
| 258 | if len(input_qparams) == 0 or len(output_qparams) == 0: |
| 259 | # We only want to replace the node if it's quantized |
| 260 | continue |
| 261 | # Create table node |
| 262 | insert_pos = list(node.graph.nodes)[0] |
| 263 | with graph_module.graph.inserting_before(insert_pos): |
| 264 | # Expect exactly one quantization parameter for input and output |
| 265 | if len(input_qparams) != 1: |
| 266 | raise ValueError( |
| 267 | f"InsertTableOpsPass expected exactly one input quantization parameter, " |
| 268 | f"got {len(input_qparams)} for node {node.name}" |
| 269 | ) |
| 270 | if len(output_qparams) != 1: |
| 271 | raise ValueError( |
| 272 | f"InsertTableOpsPass expected exactly one output quantization parameter, " |
| 273 | f"got {len(output_qparams)} for node {node.name}" |
| 274 | ) |
| 275 | |
| 276 | # Generate table buffer and how much to lshift the table output. |
| 277 | buffer, lshift = self.generate_table_values( |
| 278 | torch_op=self.table_ops[node], |
| 279 | in_quantargs=input_qparams[0], |
| 280 | out_quantargs=output_qparams[0], |
| 281 | ) |
| 282 | # Register buffer in self.exported_program.state_dict |
| 283 | # b_ prefix is important to be recognized as a constant in RemovePermutesAroundElementwiseOps |
| 284 | const_table_node = create_constant_placeholder( |
| 285 | exp_program=self.exported_program, |
| 286 | graph=node.graph, |
| 287 | kind=InputKind.BUFFER, |
| 288 | name="b_" + node.name + "_table_constant", |
| 289 | data=buffer, |
| 290 | persistent_buffer=True, |
| 291 | ) |
| 292 | |
| 293 | # Create table node |
| 294 | with graph_module.graph.inserting_before(node): |
| 295 | table_op_node = create_node( |
| 296 | graph=graph_module.graph, |
| 297 | op_target=exir_ops.backend.tosa.TABLE.default, |
| 298 | args=(node.args[0], const_table_node), |
| 299 | ) |
| 300 | output_node = table_op_node |
| 301 | |
| 302 | if lshift != 0: |
| 303 | scale = 2.0**lshift |
| 304 | rescale_node = create_node( |
| 305 | graph=graph_module.graph, |
| 306 | op_target=exir_ops.backend.tosa.RESCALE.default, |
| 307 | args=(table_op_node, output_qparams[0].dtype, [scale], 0, 0), |
| 308 | ) |
nothing calls this directly
no test coverage detected