示例#1
0
文件: cpp.py 项目: DeathyYoung/dace
def is_write_conflicted(dfg, edge, datanode=None, sdfg_schedule=None):
    """ Detects whether a write-conflict-resolving edge can be emitted without
        using atomics or critical sections. """

    if edge.data.wcr_nonatomic:
        return False

    # If it's an entire SDFG, it's probably write-conflicted
    if isinstance(dfg, SDFG):
        if datanode is None:
            return True
        in_edges = find_incoming_edges(datanode, dfg)
        if len(in_edges) != 1:
            return True
        if (isinstance(in_edges[0].src, nodes.ExitNode)
                and in_edges[0].src.map.schedule
                == dtypes.ScheduleType.Sequential):
            return False
        return True

    # Traverse memlet path to determine conflicts.
    # If no conflicts will occur, write without atomics
    # (e.g., if the array has been defined in a non-parallel schedule context)
    # TODO: This is not perfect (need to take indices into consideration)
    path = dfg.memlet_path(edge)
    for e in path:
        if (isinstance(e.dst, nodes.ExitNode)
                and e.dst.map.schedule != dtypes.ScheduleType.Sequential):
            return True
        # Should never happen (no such thing as write-conflicting reads)
        if (isinstance(e.src, nodes.EntryNode)
                and e.src.map.schedule != dtypes.ScheduleType.Sequential):
            return True

    # If SDFG schedule is not None (top-level) or not sequential
    if (sdfg_schedule is not None
            and sdfg_schedule != dtypes.ScheduleType.Sequential):
        return True

    return False
示例#2
0
文件: cpp.py 项目: andreaskuster/dace
def is_write_conflicted(dfg, edge, datanode=None, sdfg_schedule=None):
    """ Detects whether a write-conflict-resolving edge can be emitted without
        using atomics or critical sections. """

    if edge.data.wcr_nonatomic or edge.data.wcr is None:
        return False

    # If it's an entire SDFG, it's probably write-conflicted
    if isinstance(dfg, SDFG):
        if datanode is None:
            return True
        in_edges = find_incoming_edges(datanode, dfg)
        if len(in_edges) != 1:
            return True
        if (isinstance(in_edges[0].src, nodes.ExitNode)
                and in_edges[0].src.map.schedule
                == dtypes.ScheduleType.Sequential):
            return False
        return True

    # Traverse memlet path to determine conflicts.
    # If no conflicts will occur, write without atomics
    # (e.g., if the array has been defined in a non-parallel schedule context)
    while edge is not None:
        path = dfg.memlet_path(edge)
        for e in path:
            if (isinstance(e.dst, nodes.ExitNode)
                    and e.dst.map.schedule != dtypes.ScheduleType.Sequential):
                if _check_map_conflicts(e.dst.map, e):
                    # This map is parallel w.r.t. WCR
                    # print('PAR: Continuing from map')
                    continue
                # print('SEQ: Map is conflicted')
                return True
            # Should never happen (no such thing as write-conflicting reads)
            if (isinstance(e.src, nodes.EntryNode)
                    and e.src.map.schedule != dtypes.ScheduleType.Sequential):
                warnings.warn(
                    'Unexpected WCR path to have write-conflicting reads')
                return True

        sdfg = dfg.parent
        dst = path[-1].dst
        # Unexpected case
        if not isinstance(dst, nodes.AccessNode):
            warnings.warn('Unexpected WCR path to not end in access node')
            return True

        # If this is a nested SDFG and the access leads outside
        if not sdfg.arrays[dst.data].transient:
            if sdfg.parent_nsdfg_node is not None:
                dfg = sdfg.parent
                nsdfg = sdfg.parent_nsdfg_node
                edge = next(iter(dfg.out_edges_by_connector(nsdfg, dst.data)))
            else:
                break
        else:
            # Memlet path ends here, transient. We can thus safely write here
            edge = None
            # print('PAR: Reached transient')
            return False

    return False