Example #1
0
    def apply(self, sdfg):
        state = sdfg.nodes()[self.subgraph[StateAssignElimination._end_state]]
        edge = sdfg.in_edges(state)[0]
        # Since inter-state assignments that use an assigned value leads to
        # undefined behavior (e.g., {m: n, n: m}), we can replace each
        # assignment separately.
        keys_to_remove = set()
        assignments_to_consider = _assignments_to_consider(sdfg, edge)
        for varname, assignment in assignments_to_consider.items():
            state.replace(varname, assignment)
            keys_to_remove.add(varname)

        repl_dict = {}

        for varname in keys_to_remove:
            # Remove assignments from edge
            del edge.data.assignments[varname]

            for e in sdfg.edges():
                if varname in e.data.free_symbols:
                    break
            else:
                # If removed assignment does not appear in any other edge,
                # replace and remove symbol
                if assignments_to_consider[varname] in sdfg.symbols:
                    repl_dict[varname] = assignments_to_consider[varname]
                if varname in sdfg.symbols:
                    sdfg.remove_symbol(varname)

        def _str_repl(s, d):
            for k, v in d.items():
                s.replace(str(k), str(v))

        if repl_dict:
            symbolic.safe_replace(repl_dict, lambda m: _str_repl(sdfg, m))
Example #2
0
    def apply(self, _, sdfg: SDFG):
        state = self.end_state
        edge = sdfg.in_edges(state)[0]
        # Since inter-state assignments that use an assigned value leads to
        # undefined behavior (e.g., {m: n, n: m}), we can replace each
        # assignment separately.
        assignments_to_consider = _assignments_to_consider(sdfg, edge, True)

        def _str_repl(s, d, **kwargs):
            for k, v in d.items():
                s.replace(str(k), str(v), **kwargs)

        # Replace in state, and all successors
        symbolic.safe_replace(assignments_to_consider,
                              lambda m: _str_repl(state, m))
        visited = {edge}
        for isedge in sdfg.bfs_edges(state):
            if isedge not in visited:
                symbolic.safe_replace(
                    assignments_to_consider,
                    lambda m: _str_repl(isedge.data, m, replace_keys=False))
                visited.add(isedge)
            if isedge.dst not in visited:
                symbolic.safe_replace(assignments_to_consider,
                                      lambda m: _str_repl(isedge.dst, m))
                visited.add(isedge.dst)

        repl_dict = {}

        for varname in assignments_to_consider.keys():
            # Remove assignments from edge
            del edge.data.assignments[varname]

            for e in sdfg.edges():
                if varname in e.data.free_symbols:
                    break
            else:
                # If removed assignment does not appear in any other edge,
                # replace and remove symbol
                if varname in sdfg.symbols:
                    sdfg.remove_symbol(varname)
                # if assignments_to_consider[varname] in sdfg.symbols:
                if varname in sdfg.free_symbols:
                    repl_dict[varname] = assignments_to_consider[varname]

        if repl_dict:
            symbolic.safe_replace(repl_dict, lambda m: _str_repl(sdfg, m))
Example #3
0
    def can_be_applied(graph, candidate, expr_index, sdfg, strict=False):
        state = graph.nodes()[candidate[StateAssignElimination._end_state]]

        out_edges = graph.out_edges(state)
        in_edges = graph.in_edges(state)

        # We only match end states with one source and at least one assignment
        if len(in_edges) != 1:
            return False
        edge = in_edges[0]

        assignments_to_consider = _assignments_to_consider(sdfg, edge)

        # No assignments to eliminate
        if len(assignments_to_consider) == 0:
            return False

        # If this is an end state, there are no other edges to consider
        if len(out_edges) == 0:
            return True

        # Otherwise, ensure the symbols are never set/used again in edges
        akeys = set(assignments_to_consider.keys())
        for e in sdfg.edges():
            if e is edge:
                continue
            if e.data.free_symbols & akeys:
                return False

        # If used in any state that is not the current one, fail
        for s in sdfg.nodes():
            if s is state:
                continue
            if s.free_symbols & akeys:
                return False

        return True