Esempio n. 1
0
    def optimize(self, graph: Graph):
        flag_changed = False
        """
        Some operators does not support splitting, but only appear as constant.
        Workaround for such case, use ConstantFolding for limited operators even if it is turned off.
        """
        cf = ConstantFolding()
        graph, flag_changed_in_cf = cf.optimize(graph, (Transpose, ))
        flag_changed |= flag_changed_in_cf

        c_before = traverse.filter_nodes(traverse.listup_variables(graph),
                                         ConstantVariable)
        c_size_before = sum([c.size for c in c_before])

        for v in traverse.filter_nodes(traverse.listup_variables(graph),
                                       SplitTarget):
            axis = _choose_split_axis(v)
            _split_axis(v, axis, graph)
            flag_changed = True

            c_after = traverse.filter_nodes(traverse.listup_variables(graph),
                                            ConstantVariable)
            c_size_after = sum([c.size for c in c_after])

            if c_size_before > c_size_after:
                raise Exception

        return graph, flag_changed
Esempio n. 2
0
def allocate(graph: Graph) -> WebGLMemoryLayout:
    nodes = traverse.listup_nodes(graph)
    operators = traverse.filter_nodes(nodes, Operator)  # type: List[Operator]
    variables = traverse.filter_nodes(nodes, Variable)  # type: List[Variable]

    for i, v in enumerate(variables):
        if v.name is None:
            v.name = _name("v")

    dynamic_constants = traverse.filter_nodes([v for v in variables if not Placeholder.check_resolved(v.size)], ConstantVariable)
    assert len(dynamic_constants) == 0, f"ConstantVariable with unresolved placeholder shape is detected: f{dynamic_constants}"

    allocations = _get_allocations(graph, operators, variables)
    _optimize_buffer_reuse(allocations)

    variable_allocations = {v: allocations[v] for v in variables if not isinstance(v, ConstantVariable)}
    constant_allocations = {v: allocations[v] for v in variables if isinstance(v, ConstantVariable)}

    data = _update_constant_offset(constant_allocations)

    allocations = variable_allocations
    allocations.update(constant_allocations)

    layout = WebGLMemoryLayout(allocations, data)
    return layout
Esempio n. 3
0
def allocate(graph: Graph) -> MemoryLayout:
    nodes = traverse.listup_nodes(graph)
    operators = traverse.filter_nodes(nodes, Operator)  # type: List[Operator]
    variables = traverse.filter_nodes(nodes, Variable)  # type: List[Variable]

    for i, v in enumerate(variables):
        if v.name is None:
            v.name = _name("v")

    dynamic_constants = traverse.filter_nodes([v for v in variables if not Placeholder.check_resolved(v.size)], ConstantVariable)
    assert len(dynamic_constants) == 0, f"ConstantVariable with unresolved placeholder shape is detected: f{dynamic_constants}"

    allocations = _get_allocations(graph, operators, variables)
    _optimize_inplace(operators, allocations)

    variable_allocations = {v: allocations[v] for v in variables if not isinstance(v, ConstantVariable)}
    constant_allocations = {v: allocations[v] for v in variables if isinstance(v, ConstantVariable)}

    _update_offset(variable_allocations)
    _optimize_buffer_reuse(variable_allocations)

    data = _update_constant_offset(constant_allocations)

    for allocation in set(variable_allocations.values()):
        allocation.offset += data.size

    allocations = variable_allocations
    allocations.update(constant_allocations)

    layout = MemoryLayout(allocations, data)

    if flags.VISUALIZE_MEMORY_ALLOCATION:
        _visualize_allocation(operators, variables, layout)

    return layout
Esempio n. 4
0
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False

        ops = traverse.listup_operators(graph)
        ops = traverse.filter_nodes(ops, Inplace)
        ops = traverse.filter_nodes(ops, InlineInplace, mode_not=True)
        for op in ops:  # type: Operator
            inplace = op.get_attribute(Inplace)[0]  # type: Inplace

            if isinstance(op, Relu):
                op.attributes.add(
                    InlineInplace(op, lambda exp: f"({exp}>0?{exp}:0)",
                                  inplace))
                flag_changed = True

            elif isinstance(op, Elu):
                op.attributes.add(
                    InlineInplace(
                        op, lambda exp: f"({exp}>0?{exp}:(exp({exp})-1))",
                        inplace))
                flag_changed = True

            elif isinstance(op, Tanh):
                op.attributes.add(
                    InlineInplace(op, lambda exp: f"(tanh({exp}))", inplace))
                flag_changed = True

            else:
                continue

        return graph, flag_changed
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for op1 in traverse.filter_nodes(traverse.listup_operators(graph),
                                         Elementwise):  # type: Elementwise
            if len(op1.inputs) <= 1:
                continue

            x0 = op1.inputs["x0"]
            x1 = op1.inputs["x1"]

            if isinstance(op1, ElementwiseAdd):
                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:

                    #
                    #  x2 -+
                    #      +-[op2: ElementwiseAdd]-> x0 -+
                    #  x3 -+                             |
                    #                                    +-[op1: ElementwiseAdd]-> y
                    #  x4 -+                             |
                    #      +-[op3: ElementwiseAdd]-> x1 -+
                    #  x5 -+
                    #

                    x2 = op2.inputs["x0"]
                    x3 = op2.inputs["x1"]
                    x4 = op3.inputs["x0"]
                    x5 = op3.inputs["x1"]

                    cs = []
                    xs = []

                    for x in [x2, x3, x4, x5]:
                        if isinstance(x, ConstantVariable):
                            cs.append(x)
                        else:
                            xs.append(x)

                    if len(cs) >= 2:
                        y = op1.outputs["y"]

                        y_new = cs[0]
                        for c in cs[1:]:
                            y_new = y_new + c
                        for x in xs:
                            y_new = y_new + x

                        op1.remove_all()
                        op2.remove_all()
                        op3.remove_all()

                        y.change_order(y_new.order)
                        y_new.replace(y)
                        flag_changed = True

        return graph, flag_changed
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False

        for op in traverse.filter_nodes(traverse.listup_operators(graph), self.pattern):
            flag_changed |= self.optimize_operator(graph, op)

        return graph, flag_changed
Esempio n. 7
0
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for concat in traverse.filter_nodes(traverse.listup_operators(graph), Concat):
            if len(concat.inputs) == 2:
                # Unrolling is not needed
                continue

            flag_changed = True
            xs = [concat.inputs[f"x{i}"] for i in range(len(concat.inputs))]
            y = concat.outputs["y"]
            concat.remove_all()

            while len(xs) > 1:
                hs = []
                while len(xs) > 0:
                    if len(xs) == 1:
                        hs.append(xs.pop(0))

                    else:
                        x0, x1 = xs.pop(0), xs.pop(0)
                        h, = Concat(None, axis=concat.axis)(x0, x1)
                        hs.append(h)

                xs = hs

            OptimizeRule.replace_variable(graph, y, xs[0].transpose_like(y))

        return graph, flag_changed
Esempio n. 8
0
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for op in traverse.filter_nodes(traverse.listup_operators(graph),
                                        Sgemm):  # type: Sgemm
            A = op.inputs["A"]
            B = op.inputs["B"]
            M = op.M
            N = op.N
            K = op.K
            transpose_A = op.transpose_A
            transpose_B = op.transpose_B

            if transpose_A:
                if TextureShape.get(A) != [M, K]:
                    flag_changed = True
                    TextureShape.set(A, width=K, height=M)

            else:
                if TextureShape.get(A) != [K, M]:
                    flag_changed = True
                    TextureShape.set(A, width=M, height=K)

            if transpose_B:
                if TextureShape.get(B) != [K, N]:
                    flag_changed = True
                    TextureShape.set(B, width=N, height=K)

            else:
                if TextureShape.get(B) != [N, K]:
                    flag_changed = True
                    TextureShape.set(B, width=K, height=N)

        return graph, flag_changed
Esempio n. 9
0
    def generate(cls, graph: Graph, **kwargs):
        graph, _ = WebGLOptimizeRule().optimize(graph)
        if flags.DEBUG:
            traverse.dump(graph)
            with open("cg.dot", "w") as f:
                f.write(traverse.dump_dot(graph))

        memory_layout = allocate(graph)

        constants_map = {}
        for constant in traverse.filter_nodes(traverse.listup_nodes(graph), ConstantVariable):  # type: ConstantVariable
            constants_map[constant.name] = {
                "byte_offset": memory_layout[constant].offset * 4,
                "size": constant.size
            }

        constant_encoder = ConstantEncoder.get_encoder(kwargs.get("constant_encoder_name", None))
        constants_bytes = constant_encoder.encode(memory_layout)

        kernels = cls.generate_kernels(graph)

        descriptor = GraphDescriptor(
            kernels=kernels,
            memory_layout=memory_layout,
            inputs=graph.inputs,
            outputs=graph.outputs,
            constants_encoding=constant_encoder.name,
            constants_map=constants_map,
            licenses=graph.licenses
        )

        return GraphExecutionData(graph, descriptor, constants_bytes)
Esempio n. 10
0
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for op in traverse.filter_nodes(
                traverse.listup_operators(graph),
                Deconvolution2D):  # type: Deconvolution2D
            x = op.inputs["x"]
            w = op.inputs["w"]
            y = op.outputs["y"]
            flag_changed = True
            op.remove_all()

            a_filter, a_kh, a_kw = Axis(), Axis(), Axis()
            w, = ReinterpretAxis(None,
                                 in_order=OrderNHWC,
                                 out_order=Order(
                                     [Axis.C, a_kh, a_kw, a_filter]))(w)
            x, = ReinterpretAxis(None,
                                 in_order=OrderNHWC,
                                 out_order=Order(
                                     [Axis.N, Axis.H, Axis.W, a_filter]))(x)

            col, = Tensordot(None, axes=a_filter)(x, w)
            col = col.transpose(
                Order([Axis.N, Axis.H, Axis.W, a_kh, a_kw, Axis.C]))
            col = col.reshape(shape=[*col.shape[0:3],
                                     mul(col.shape[3:6])],
                              order=OrderNHWC)

            new_y, = Col2Im(None,
                            ksize=op.ksize,
                            stride=op.stride,
                            padding=op.padding)(col)
            OptimizeRule.replace_variable(graph, new_y.transpose_like(y), y)

        return graph, flag_changed
Esempio n. 11
0
    def allocate_variables(cls, graph: Graph, variables: List[Variable]):
        # check if constant variable with shape with unresolved placeholder.
        dynamic_constants = traverse.filter_nodes(
            [v for v in variables if not Placeholder.check_resolved(v.size)],
            ConstantVariable)
        assert len(
            dynamic_constants
        ) == 0, f"ConstantVariable with unresolved placeholder shape is detected: f{dynamic_constants}"

        ops = traverse.listup_operators(graph)
        layout = MemoryLayout()

        lifetime = get_lifetime(
            graph, ops, variables)  # type: Dict[Variable, Tuple[int, int]]
        offsets = generate_allocation_info(
            variables,
            lifetime)  # type: Dict[Variable, Union[int, Placeholder]]
        for variable, offset in offsets.items():
            layout.append(variable, offset)

        layout.data = np.zeros(layout.static_size, dtype=np.float32)
        constant_size = 0
        for var in variables:
            if not isinstance(var, ConstantVariable):
                continue

            allocation = layout[var]
            layout.data[allocation.offset:allocation.offset +
                        allocation.size] = var.data.flatten()
            constant_size += var.data.size
        layout.data = layout.data[:constant_size]
        if flags.VISUALIZE_MEMORY_ALLOCATION:
            _visualize_allocation(ops, variables, layout, lifetime, offsets)

        return layout
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for op in traverse.filter_nodes(traverse.listup_operators(graph),
                                        Linear):
            x = op.inputs["x"]
            w = op.inputs["w"]
            y = op.outputs["y"]

            flag_changed = True
            op.remove_all()
            a_filter = Axis()

            if x.ndim == 2:
                w, = ReinterpretAxis(None,
                                     in_order=OrderNC,
                                     out_order=Order([Axis.C, a_filter]))(w)
                new_y, = Tensordot(None, axes=[Axis.C, a_filter])(x, w)

            elif x.ndim == 4:
                w, = ReinterpretAxis(
                    None,
                    in_order=OrderNHWC,
                    out_order=Order([Axis.C, Axis.H, Axis.W, a_filter]))(w)
                new_y, = Tensordot(None,
                                   axes=[[Axis.H, Axis.W, Axis.C],
                                         [Axis.H, Axis.W, a_filter]])(x, w)

            else:
                raise NotImplementedError

            OptimizeRule.replace_variable(graph, new_y.transpose_like(y), y)

        return graph, flag_changed
Esempio n. 13
0
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False

        for op in traverse.filter_nodes(traverse.listup_operators(graph),
                                        InplaceOperator):
            attr = op.get_attribute(InplaceOperator)[0]
            v_in = attr.get_input()
            v_out = attr.get_output()

            flag_inplace = True

            if v_in.has_attribute(Input):
                # Input variable cannot be overwritten.
                flag_inplace = False

            if isinstance(v_in, ConstantVariable):
                # Constant variable cannot be overwritten
                flag_inplace = False

            if any(v_in.stride_dict[a] != v_out.stride_dict[a]
                   for a in v_out.order.axes if a in v_in.order.axes):
                flag_inplace = False

            if flag_inplace != attr.get_status():
                attr.toggle_status(flag_inplace)
                flag_changed = True

        return graph, flag_changed
Esempio n. 14
0
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for op in traverse.filter_nodes(traverse.listup_operators(graph), Linear):  # type: Linear
            x = op.inputs["x"]
            w = op.inputs["w"]
            y = op.outputs["y"]
            assert x.order == OrderNC or x.order == OrderNHWC, f"(x.order) = {x.order}"
            assert w.order == OrderCN or w.order == OrderHWCN, f"(x.order) = {w.order}"
            assert y.order == OrderNC or y.order == OrderNHWC, f"(x.order) = {y.order}"
            assert w.ndim == x.ndim

            flag_changed = True
            op.remove_all()

            sgemm = Sgemm(None,
                          M=y.shape_dict[Axis.N],
                          N=y.size // y.shape_dict[Axis.N],
                          K=x.size // x.shape_dict[Axis.N],
                          out_shape=y.shape,
                          out_order=y.order,
                          transpose_A=True,
                          transpose_B=True)
            new_y, = sgemm(x, w)

            sgemm.replace_output(new_y, y)

        return graph, flag_changed
Esempio n. 15
0
    def generate(cls, graph: Graph, **kwargs):
        data_dict = {}  # type: Dict[int, Tuple[GraphDescriptor, bytes]]

        for max_texture_size in [4096, 8192, 16384]:
            config.WEBGL_MAX_TEXTURE_SIZE = max_texture_size
            graph, _ = WebGLOptimizeRule().optimize(graph)

            memory_layout = allocate(graph)

            constants_map = {}
            for constant in traverse.filter_nodes(traverse.listup_nodes(graph), ConstantVariable):  # type: ConstantVariable
                constants_map[constant.name] = {
                    "byte_offset": memory_layout[constant].offset * 4,
                    "size": constant.size
                }

            constant_encoder = ConstantEncoder.get_encoder(kwargs.get("constant_encoder_name", None))
            constants_bytes = constant_encoder.encode(memory_layout)

            kernels = cls.generate_kernels(graph)

            descriptor = GraphDescriptor(
                kernels=kernels,
                memory_layout=memory_layout,
                inputs=graph.inputs,
                outputs=graph.outputs,
                constants_encoding=constant_encoder.name,
                constants_map=constants_map,
                licenses=graph.licenses
            )
            data_dict[max_texture_size] = (descriptor, constants_bytes)

        return GraphExecutionData(graph, data_dict)
Esempio n. 16
0
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for op in traverse.filter_nodes(traverse.listup_operators(graph),
                                        Convolution2D):  # type: Convolution2D
            x = op.inputs["x"]
            w = op.inputs["w"]
            y = op.outputs["y"]
            flag_changed = True
            op.remove_all()

            a_filter, a_kh, a_kw = Axis(), Axis(), Axis()
            w, = ReinterpretAxis(None,
                                 in_order=OrderNHWC,
                                 out_order=Order(
                                     [Axis.C, a_kh, a_kw, a_filter]))(w)

            if op.WH == 1 and op.WW == 1 and op.stride == (
                    1, 1) and op.padding == (0, 0):
                # Projection
                col, = ReinterpretAxis(
                    None,
                    in_order=OrderNHWC,
                    out_order=Order([Axis.N, Axis.H, Axis.W, a_filter]))(x)

                new_y, = Tensordot(None,
                                   [[a_filter], [a_kh, a_kw, a_filter]])(col,
                                                                         w)

            elif op.WH == x.shape_dict[Axis.H] and op.WW == x.shape_dict[
                    Axis.W] and op.padding == (0, 0):
                # Global convolution
                col, = ReinterpretAxis(None,
                                       in_order=OrderNHWC,
                                       out_order=Order(
                                           [Axis.N, a_kh, a_kw, a_filter]))(x)

                new_y, = Tensordot(
                    None, [[[a_kh, a_kw, a_filter], [a_kh, a_kw, a_filter]],
                           [a_kh, a_kw, a_filter]])(col, w)

            else:
                # General convolution
                col, = Im2Col(None,
                              ksize=op.ksize,
                              stride=op.stride,
                              padding=op.padding,
                              dilation_rate=op.dilation_rate)(x)
                col, = ReinterpretAxis(
                    None,
                    in_order=OrderNHWC,
                    out_order=Order([Axis.N, Axis.H, Axis.W, a_filter]))(col)

                new_y, = Tensordot(None,
                                   [[a_filter], [a_kh, a_kw, a_filter]])(col,
                                                                         w)

            new_y = new_y.transpose(y.order)
            OptimizeRule.replace_variable(graph, new_y, y)

        return graph, flag_changed
Esempio n. 17
0
def _get_allocations(graph: Graph, operators: List[Operator], variables: List[Variable]) -> AllocationDict:
    T_LAST = len(operators)

    allocations = {}  # type: AllocationDict
    retain_count = {v: 0 for v in variables}  # type: Dict[Variable, int]
    allocated = set()  # type: Set[Variable]

    for v in traverse.filter_nodes(variables, ConstantVariable):  # type: ConstantVariable
        # Constant variable cannot be released
        allocations[v] = Allocation(size=v.size, begin=0, end=T_LAST)
        allocated.add(v)

    for v in graph.inputs:
        # Input variable cannot be released
        allocations[v] = Allocation(size=v.size, begin=0, end=T_LAST)
        allocated.add(v)

    for v in graph.outputs:
        # Output variable cannot be released, but it's not needed to be allocated from the begin
        allocations[v] = Allocation(size=v.size, begin=_T_UNKNOWN, end=T_LAST)
        allocated.add(v)

    for t, op in enumerate(operators):
        for v in op.outputs.values():
            if v in allocated:
                # Allocation object is already created (output variable, etc.)
                if allocations[v].begin == _T_UNKNOWN:
                    allocations[v].begin = t

            else:
                # Create new allocation object
                allocations[v] = Allocation(size=v.size, begin=t, end=_T_UNKNOWN)
                retain_count[v] = len(v.input_to)
                allocated.add(v)

        for v in op.inputs.values():
            if v not in allocated:
                # Allocate
                allocations[v] = Allocation(size=v.size, begin=t, end=_T_UNKNOWN)
                retain_count[v] = len(v.input_to)
                allocated.add(v)

            if allocations[v].end != _T_UNKNOWN:
                # Release timing is already determined (input, output, or constant variable).
                continue

            # Release input variable
            retain_count[v] -= 1
            if retain_count[v] == 0:
                # `t + 1` means that `v` will be released *AFTER* `op` will be finished.
                allocations[v].end = t + 1

        for a in allocations.values():
            if a.begin == _T_UNKNOWN:
                a.begin = 0

            if a.end == _T_UNKNOWN:
                a.end = T_LAST

    return allocations
Esempio n. 18
0
def test_filter_nodes():
    global graph, op1

    op1.attributes.add(TestAttribute(op1))
    op2.attributes.add(TestAttribute(op2))

    ops = filter_nodes([op1, op2, op3], TestAttribute)
    assert tuple(ops) == (op1, op2)
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for op1 in traverse.filter_nodes(traverse.listup_operators(graph),
                                         Associative):  # type: Operator
            associative1 = op1.get_attribute(Associative)[0]
            var1, var2 = associative1.vars
            op2 = var1.output_from

            if isinstance(var1, ConstantVariable):
                # Left hand operand(var1) has no child tree
                continue

            if var1 in graph.outputs or len(var1.input_to) > 1:
                # var1 will be removed in this optimize rule
                continue

            if not isinstance(op2, op1.__class__):
                # op1 and op2 must be same operator class
                continue

            associative2 = op2.get_attribute(Associative)[0]
            var3, var4 = associative2.vars

            if not isinstance(var4, ConstantVariable):
                # No optimization is needed.
                # If either var3 or var4 is constant, then it is var4 because optimization rule of commutative operator reorder operands to
                # gather constant variables for right hand.
                continue
            """
            var3 -+
                  +-{op2}- var1 -+
            var4 -+              +-{op1}-
                           var2 -+
            """

            if isinstance(var2, ConstantVariable):
                # Fold var4 and var2
                associative1.reorder(
                    op2)  # (var3*var4)*var2 => var3*(var4*var2)
                flag_changed = True

            else:
                # Sweep out var4
                if not op1.has_attribute(Commutative):
                    continue

                associative2 = op2.get_attribute(Associative)[0]
                commutative2 = op2.get_attribute(Commutative)[0]

                if not isinstance(associative2.vars[1], ConstantVariable):
                    continue

                commutative2.swap()  # (var3*var4)*var2 => (var4*var3)*var2
                associative1.reorder(
                    op2)  # (var4*var3)*var2 => var4*(var3*var2)
                flag_changed = True

        return graph, flag_changed
Esempio n. 20
0
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for op in traverse.filter_nodes(traverse.listup_operators(graph),
                                        Convolution2D):  # type: Convolution2D
            x = op.inputs["x"]
            w = op.inputs["w"]  # type: ConstantVariable
            old_y = op.outputs["y"]

            flag_changed = True
            op.remove_all()

            assert x.order == OrderNHWC
            assert isinstance(w, ConstantVariable)
            assert old_y.order == OrderNHWC

            w.change_order(OrderNHWC)

            col, = Im2Col(None,
                          ksize=op.ksize,
                          stride=op.stride,
                          padding=op.padding,
                          dilation_rate=op.dilation_rate)(x)
            col.change_order(OrderNHWC)
            ChannelMode.set_mode(col, ChannelModeEnum.RGBA)

            M = col.shape_dict[Axis.N] * col.shape_dict[
                Axis.H] * col.shape_dict[Axis.W]
            N = w.shape_dict[Axis.N]
            K = col.shape_dict[Axis.C]

            if K > (w.size // N):
                w2_data = np.hstack([
                    w.data.reshape(N, w.size // N),
                    np.zeros([N, K - w.size // N])
                ])
            else:
                w2_data = w.data.reshape(N, w.size // N)

            w = ConstantVariable(w2_data, OrderNC)
            ChannelMode.set_mode(w, ChannelModeEnum.RGBA)

            sgemm = Sgemm(None,
                          M=M,
                          N=N,
                          K=K,
                          out_shape=[
                              col.shape_dict[Axis.N], col.shape_dict[Axis.H],
                              col.shape_dict[Axis.W], w.shape_dict[Axis.N]
                          ],
                          out_order=OrderNHWC,
                          transpose_A=True,
                          transpose_B=False)
            new_y, = sgemm(col, w)

            sgemm.replace_output(new_y, old_y)

        return graph, flag_changed
Esempio n. 21
0
    def optimize(self, graph: Graph):
        flag_changed = False

        for v in traverse.filter_nodes(traverse.listup_nodes(graph), SplitTarget):  # type: Variable
            axis = _choose_split_axis(v)
            _split_axis(v, axis, graph)
            flag_changed = True

        return graph, flag_changed
Esempio n. 22
0
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for op in traverse.filter_nodes(traverse.listup_operators(graph),
                                        Tensordot):
            if not op.has_attribute(UseEigenAttribute):
                op.attributes.add(UseEigenAttribute())
                flag_changed = True
                graph.licenses["eigen"] = EIGEN_LICENSE

        return graph, flag_changed
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        if not (flags.optimize.OPTIMIZE
                and flags.optimize.CONCAT_SCALAR_OPERATION):
            return graph, False

        flag_changed = False

        nodes = traverse.listup_nodes(graph)

        filtered_nodes = traverse.filter_nodes(
            nodes, ScalarAffine)  # type: List[ScalarAffine]
        while len(filtered_nodes) > 0:
            op = filtered_nodes.pop()
            if op.scale == 1 and op.bias == 0:
                remove_operator(op)
                flag_changed = True

        filtered_nodes = traverse.filter_nodes(
            nodes, ScalarAdd)  # type: List[ScalarAdd]
        while len(filtered_nodes) > 0:
            op = filtered_nodes.pop()
            if op.value == 0:
                remove_operator(op)
                flag_changed = True

        filtered_nodes = traverse.filter_nodes(
            nodes, ScalarMul)  # type: List[ScalarMul]
        while len(filtered_nodes) > 0:
            op = filtered_nodes.pop()
            if op.value == 1:
                remove_operator(op)
                flag_changed = True

        filtered_nodes = traverse.filter_nodes(
            nodes, ScalarPow)  # type: List[ScalarPow]
        while len(filtered_nodes) > 0:
            op = filtered_nodes.pop()
            if op.value == 1:
                remove_operator(op)
                flag_changed = True

        return graph, flag_changed
Esempio n. 24
0
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for op in traverse.filter_nodes(traverse.listup_operators(graph),
                                        Sgemm):  # type: Sgemm

            if not op.has_attribute(SgemmWithEigen):
                op.attributes.add(SgemmWithEigen(op))
                flag_changed = True
                graph.licenses["eigen"] = EIGEN_LICENSE

        return graph, flag_changed
Esempio n. 25
0
    def optimize(self, graph: Graph):
        flag_changed = False

        c_before = traverse.filter_nodes(traverse.listup_variables(graph),
                                         ConstantVariable)
        c_size_before = sum([c.size for c in c_before])

        for v in traverse.filter_nodes(traverse.listup_variables(graph),
                                       SplitTarget):
            axis = _choose_split_axis(v)
            _split_axis(v, axis, graph)
            flag_changed = True

            c_after = traverse.filter_nodes(traverse.listup_variables(graph),
                                            ConstantVariable)
            c_size_after = sum([c.size for c in c_after])

            if c_size_before > c_size_after:
                raise Exception

        return graph, flag_changed
Esempio n. 26
0
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False

        # replace AxiswiseBias by ElementwiseAdd
        flag_warn = True
        for op in traverse.filter_nodes(traverse.listup_operators(graph),
                                        AxiswiseBias):  # type: AxiswiseBias
            flag_changed = True
            x = op.inputs["x0"]
            b = op.inputs["x1"]
            y = op.outputs["y"]
            op.remove_all()
            OptimizeRule.replace_variable(graph, (x + b).change_order(y.order),
                                          y)

            if flag_warn:
                flag_warn = False
                console.warning(
                    "AxiswiseBias will be removed in the future version. Use ElementwiseAdd.",
                    DeprecationWarning)

        # replace AxiswiseScale by ElementwiseMul
        flag_warn = True
        for op in traverse.filter_nodes(traverse.listup_operators(graph),
                                        AxiswiseScale):  # type: AxiswiseScale
            flag_changed = True
            x = op.inputs["x0"]
            s = op.inputs["x1"]
            y = op.outputs["y"]
            op.remove_all()
            OptimizeRule.replace_variable(graph, (x * s).change_order(y.order),
                                          y)

            if flag_warn:
                flag_warn = False
                console.warning(
                    "AxiswiseScale will be removed in the future version. Use ElementwiseMul.",
                    DeprecationWarning)

        return graph, flag_changed
Esempio n. 27
0
    def allocate(cls,
                 graph: Graph) -> Tuple[MemoryLayout, MemoryLayout, np.array]:
        variables = set(traverse.listup_variables(graph))
        constants = set(traverse.filter_nodes(
            variables, Constant))  # type: Set[ConstantVariable]
        variables = variables.difference(constants)

        variables = list(variables)
        constants = list(constants)

        constants_layout, data = cls.allocate_constants(constants)
        variables_layout = cls.allocate_variables(graph, variables)
        return variables_layout, constants_layout, data
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False

        ops = traverse.listup_operators(graph)
        ops = traverse.filter_nodes(ops, PostInlineInplace, mode_not=True)
        for op in ops:  # type: Operator
            if isinstance(op, Sgemm):
                op.attributes.add(PostInlineInplace(op))
                flag_changed = True

            else:
                continue

        return graph, flag_changed
Esempio n. 29
0
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for op in traverse.filter_nodes(traverse.listup_operators(graph),
                                        ScalarAffine):  # type: ScalarAffine
            x = op.inputs["x0"]
            y = op.outputs["y"]
            op.remove_all()

            y_dummy = x * op.scale + op.bias  # type: Variable
            y_dummy.change_order(y.order)
            y_dummy.replace(y)

            flag_changed = True

        return graph, flag_changed
    def optimize(self, graph: Graph) -> Tuple[Graph, bool]:
        flag_changed = False
        for concat in traverse.filter_nodes(traverse.listup_operators(graph),
                                            Concat):  # type: Concat
            if concat.has_attribute(ConcatWorkspaceAttached):
                attr = concat.get_attribute(ConcatWorkspaceAttached)[0]

            else:
                flag_changed = True
                attr = ConcatWorkspaceAttached(concat)
                concat.attributes.add(attr)

            flag_changed |= attr.update()

        return graph, flag_changed