def optimize_pair(self, op1: ElementwiseAdd, op2: ScalarMul): c1, v1 = _get_constant_and_variable(op1, "x0", "x1") if c1 is None: return False y2 = op2.outputs["y"] op2.remove_all() op1.remove_all() y = (v1 * op2.value) + (c1 * op2.value) # type: Variable y.replace(y2) return True
def _optimize_ElementwiseAdd_ScalarMul(op1: ElementwiseAdd, c1: ConstantVariable, v1: Variable, op2: Operator): if not isinstance(op2, ScalarMul): return False y2 = op2.outputs["y"] op2.remove_all() op1.remove_all() y = (v1 * op2.value) + (c1 * op2.value) y.replace(y2) return True
def optimize_pair(self, op1: ElementwiseAdd, op2: ScalarAdd): if isinstance(op1.inputs["x0"], ConstantVariable): c1 = op1.inputs["x0"], v1 = op1.inputs["x1"] elif isinstance(op1.inputs["x1"], ConstantVariable): c1 = op1.inputs["x1"], v1 = op1.inputs["x0"] else: return False y2 = op2.outputs["y"] op2.remove_all() op1.remove_all() y = v1 + (c1 + op2.value) # type: Variable y.replace(y2) return True
def optimize_pair(self, op1: ElementwiseAdd, op2: ElementwiseDiv): c1, v1 = _get_constant_and_variable(op1, "x0", "x1") if c1 is None: return False c2, v2 = _get_constant_and_variable(op2, "x0", "x1") if c2 is None: return False y2 = op2.outputs["y"] op2.remove_all() op1.remove_all() y = (v1 / c2) + (c1 / c2) # type: Variable y.replace(y2, with_assert=False) return True
def optimize_pair(self, op1: ScalarAdd, op2: ElementwiseAdd): x0 = op1.inputs["x0"] y1 = op1.outputs["y"] if y1 == op2.inputs["x0"]: w = op2.inputs["x1"] else: w = op2.inputs["x0"] y2 = op2.outputs["y"] op2.remove_all() op1.remove_all() y = (x0 + w) + op1.value # type: Variable y.replace(y2) return True
def optimize_pair(self, op1: ElementwiseAdd, op2: ElementwiseMul): c1, v1 = _get_constant_and_variable(op1, "x0", "x1") if c1 is None: return False c2, v2 = _get_constant_and_variable(op2, "x0", "x1") if c2 is None: return False y2 = op2.outputs["y"] op2.remove_all() op1.remove_all() y = (v1 * c2) + (c1 * c2) y.replace(y2) return True
def optimize_pair(self, graph: Graph, op1: ElementwiseAdd, op2: ElementwiseDiv): c1, v1 = _get_constant_and_variable(op1, "x0", "x1") if c1 is None: return False c2, v2 = _get_constant_and_variable(op2, "x0", "x1") if c2 is None: return False y2 = op2.outputs["y"] op2.remove_all() op1.remove_all() y = (v1 / c2) + (c1 / c2) OptimizeRule.replace_variable(graph, y2, y.change_order(y2.order)) return True
def _convert_average(converter: KerasConverter, k_op: "keras.layers.Average"): xs = [converter.get_variable(tensor) for tensor in converter.get_input_tensor(k_op)] for x in xs[1:]: xs[0].order.unify(x.order) y = ElementwiseAdd(None)(*xs)[0] / len(xs) converter.set_variable(converter.get_output_tensor(k_op)[0], y)
def _convert_add(converter: KerasConverter, k_op: "keras.layers.Add"): xs = [ converter.get_variable(tensor) for tensor in converter.get_input_tensor(k_op) ] y, = ElementwiseAdd(None)(*xs) converter.set_variable(converter.get_output_tensor(k_op)[0], y)
def _convert_average(converter: KerasConverter, k_op: "keras.layers.Average"): xs = [ converter.get_variable(tensor) for tensor in converter.get_input_tensor(k_op) ] # FIXME: More effective implementation y = ElementwiseAdd(None)(*xs)[0] / len(xs) converter.set_variable(converter.get_output_tensor(k_op)[0], y)
def _optimize_ElementwiseAdd_ElementwiseMul(op1: ElementwiseAdd, c1: ConstantVariable, v1: Variable, op2: Operator): if not isinstance(op2, ElementwiseMul): return False x0 = op2.inputs["x0"] x1 = op2.inputs["x1"] y2 = op2.outputs["y"] if isinstance(x0, ConstantVariable): c2 = x0 elif isinstance(x1, ConstantVariable): c2 = x1 else: return False op2.remove_all() op1.remove_all() y = (v1 * c2) + (c1 * c2) y.replace(y2) return True
def optimize(self, graph: Graph) -> Tuple[Graph, bool]: flag_changed = False for op1 in traverse.filter_nodes(traverse.listup_operators(graph), Concat): # type: Concat if len(op1.inputs) != 2: continue x0 = op1.inputs["x0"] x1 = op1.inputs["x1"] y = op1.outputs["y"] op2 = x0.output_from op3 = x1.output_from if isinstance(op2, ElementwiseAdd) and isinstance( op3, ElementwiseAdd) and len(x0.input_to) == 1 and len( x1.input_to) == 1: """ before) v1 -+ +-[op2: ElementwiseAdd]-> x0 -+ c1 -+ | +-[op1: Concat]-> y v2 -+ | +-[op3: ElementwiseAdd]-> x1 -+ c2 -+ after) v1 -+ +-[Concat]-> x6 -+ v2 -+ | +-[ElementwiseAdd]-> y | c3 -+ """ x2 = op2.inputs["x0"] x3 = op2.inputs["x1"] x4 = op3.inputs["x0"] x5 = op3.inputs["x1"] if isinstance(x2, ConstantVariable): c1 = x2 v1 = x3 elif isinstance(x3, ConstantVariable): c1 = x3 v1 = x2 else: continue if isinstance(x4, ConstantVariable): c2 = x4 v2 = x5 elif isinstance(x5, ConstantVariable): c2 = x5 v2 = x4 else: continue if not (c1.order == c2.order == Order([op1.axis])): continue op1.remove_all() op2.remove_all() op3.remove_all() c3 = ConstantVariable(np.hstack([c1.data, c2.data]), c1.order) x6, = Concat(None, axis=op1.axis)(v1, v2) y_dummy, = ElementwiseAdd(None)(x6, c3) y_dummy.replace(y) flag_changed = True return graph, flag_changed