def ReportGSNoCFriendlyReachabilityInFile(AG):
    ReachabilityFile = open("Generated_Files/GSNoC_RectangleFile.txt", 'w')
    for Node in AG.nodes():
        NodeX, NodeY, NodeZ = AG_Functions.return_node_location(Node)
        for Port in AG.node[Node]['Router'].Unreachable:
            if Port == "S":
                Direction = "SOUTH"
            elif Port == "N":
                Direction = "NORTH"
            elif Port == "W":
                Direction = "WEST"
            elif Port == "E":
                Direction = "EAST"
            for Entry in AG.node[Node]['Router'].Unreachable[Port]:
                ReachabilityFile.write("[" + str(NodeX) + "," + str(NodeY) +
                                       "," + str(NodeZ) + "] ")
                UnreachableArea = AG.node[Node]['Router'].Unreachable[Port][
                    Entry]
                if UnreachableArea[0] is not None:
                    UnreachableX, UnreachableY, UnreachableZ = AG_Functions.return_node_location(
                        UnreachableArea[0])
                    ReachabilityFile.write(
                        str(Direction) + " NetLocCube(ll=[" +
                        str(UnreachableX) + "," + str(UnreachableY) + "," +
                        str(UnreachableZ) + "],")
                    UnreachableX, UnreachableY, UnreachableZ = AG_Functions.return_node_location(
                        UnreachableArea[1])
                    ReachabilityFile.write("ur=[" + str(UnreachableX) + "," +
                                           str(UnreachableY) + "," +
                                           str(UnreachableZ) + "])\n")
                else:
                    ReachabilityFile.write(
                        str(Direction) + " NetLocCube(invalid)\n")
        ReachabilityFile.write("\n")
    ReachabilityFile.close()
예제 #2
0
def report_gsnoc_friendly_reachability_in_file(ag):
    """
    generates a GSNoC readable reachability file. (how ever last time i checked,
    i couldn't find any trace of the tool online.)
    :param ag: architecture graph
    :return: None
    """
    reachability_file = open("Generated_Files/GSNoC_RectangleFile.txt", 'w')
    for node in ag.nodes():
        node_x, node_y, node_z = AG_Functions.return_node_location(node)
        for port in ag.node[node]['Router'].unreachable:
            if port == "S":
                direction = "SOUTH"
            elif port == "N":
                direction = "NORTH"
            elif port == "W":
                direction = "WEST"
            elif port == "E":
                direction = "EAST"
            for entry in ag.node[node]['Router'].unreachable[port]:
                reachability_file.write("["+str(node_x)+","+str(node_y)+","+str(node_z)+"] ")
                unreachable_area = ag.node[node]['Router'].unreachable[port][entry]
                if unreachable_area[0] is not None:
                    unreachable_x, unreachable_y, unreachable_z = AG_Functions.return_node_location(unreachable_area[0])
                    reachability_file.write(str(direction)+" NetLocCube(ll=["+str(unreachable_x)+"," +
                                            str(unreachable_y)+","+str(unreachable_z)+"],")
                    unreachable_x, unreachable_y, unreachable_z = AG_Functions.return_node_location(unreachable_area[1])
                    reachability_file.write("ur=["+str(unreachable_x)+","+str(unreachable_y) +
                                            ","+str(unreachable_z)+"])\n")
                else:
                    reachability_file.write(str(direction)+" NetLocCube(invalid)\n")
        reachability_file.write("\n")
    reachability_file.close()
    return None
예제 #3
0
def evaluate_actual_odd_even_turn_model():
    turns_health_2d_network = {
        "N2W": False,
        "N2E": False,
        "S2W": False,
        "S2E": False,
        "W2N": False,
        "W2S": False,
        "E2N": False,
        "E2S": False
    }
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = 3
    Config.ag.y_size = 3
    Config.ag.z_size = 1
    Config.RotingType = 'MinimalPath'
    ag = copy.deepcopy(AG_Functions.generate_ag())
    number_of_pairs = len(ag.nodes()) * (len(ag.nodes()) - 1)

    turn_model_odd = ['E2N', 'E2S', 'W2N', 'W2S', 'S2E', 'N2E']
    turn_model_even = ['E2N', 'E2S', 'S2W', 'S2E', 'N2W', 'N2E']

    if not check_tm_domination(turn_model_odd,
                               turn_model_even):  # taking out the domination!
        turns_health = copy.deepcopy(turns_health_2d_network)
        shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
        shmu.setup_noc_shm(ag, turns_health, False)
        noc_rg = copy.deepcopy(
            Routing.generate_noc_route_graph(ag, shmu, [], False, False))

        for node in ag.nodes():
            node_x, node_y, node_z = AG_Functions.return_node_location(node)
            if node_x % 2 == 1:
                for turn in turn_model_odd:
                    shmu.restore_broken_turn(node, turn, False)
                    from_port = str(node) + str(turn[0]) + "I"
                    to_port = str(node) + str(turn[2]) + "O"
                    Routing.update_noc_route_graph(noc_rg, from_port, to_port,
                                                   'ADD')
            else:
                for turn in turn_model_even:
                    shmu.restore_broken_turn(node, turn, False)
                    from_port = str(node) + str(turn[0]) + "I"
                    to_port = str(node) + str(turn[2]) + "O"
                    Routing.update_noc_route_graph(noc_rg, from_port, to_port,
                                                   'ADD')
        draw_rg(noc_rg)
        connectivity_metric = reachability_metric(ag, noc_rg, False)
        print("connectivity_metric:", connectivity_metric)
        if check_deadlock_freeness(noc_rg):
            print("Deadlock free!")

        doa = degree_of_adaptiveness(ag, noc_rg,
                                     False) / float(number_of_pairs)
        doa_ex = extended_degree_of_adaptiveness(
            ag, noc_rg, False) / float(number_of_pairs)
        print("doa:", doa)
        print("doa_ex", doa_ex)

        sys.stdout.flush()
def report_gsnoc_friendly_reachability_in_file(ag):
    """
    generates a GSNoC readable reachability file. (how ever last time i checked,
    i couldn't find any trace of the tool online.)
    :param ag: architecture graph
    :return: None
    """
    reachability_file = open("Generated_Files/GSNoC_RectangleFile.txt", 'w')
    for node in ag.nodes():
        node_x, node_y, node_z = AG_Functions.return_node_location(node)
        for port in ag.node[node]['Router'].unreachable:
            if port == "S":
                direction = "SOUTH"
            elif port == "N":
                direction = "NORTH"
            elif port == "W":
                direction = "WEST"
            elif port == "E":
                direction = "EAST"
            for entry in ag.node[node]['Router'].unreachable[port]:
                reachability_file.write("["+str(node_x)+","+str(node_y)+","+str(node_z)+"] ")
                unreachable_area = ag.node[node]['Router'].unreachable[port][entry]
                if unreachable_area[0] is not None:
                    unreachable_x, unreachable_y, unreachable_z = AG_Functions.return_node_location(unreachable_area[0])
                    reachability_file.write(str(direction)+" NetLocCube(ll=["+str(unreachable_x)+"," +
                                            str(unreachable_y)+","+str(unreachable_z)+"],")
                    unreachable_x, unreachable_y, unreachable_z = AG_Functions.return_node_location(unreachable_area[1])
                    reachability_file.write("ur=["+str(unreachable_x)+","+str(unreachable_y) +
                                            ","+str(unreachable_z)+"])\n")
                else:
                    reachability_file.write(str(direction)+" NetLocCube(invalid)\n")
        reachability_file.write("\n")
    reachability_file.close()
    return None
def is_node_inside_rectangle(Rect, Node):
    RX1, RY1, RZ1 = AG_Functions.return_node_location(Rect[0])
    RX2, RY2, RZ2 = AG_Functions.return_node_location(Rect[1])
    NodeX, NodeY, NodeZ = AG_Functions.return_node_location(Node)
    if RX1 <= NodeX <= RX2 and RY1 <= NodeY <= RY2 and RZ1 <= NodeZ <= RZ2:
        return True
    else:
        return False
def translate_node_number_to_noxim_system(node):
    """
    Translates the numbering system of Schedule and Depend to Noxim system
    :param node: Node ID in AG
    :return: Node coordination in Noxim System
    """
    x, y, z = AG_Functions.return_node_location(node)
    z = Config.ag.z_size - z - 1
    y = Config.ag.y_size - y - 1
    return AG_Functions.return_node_number(x, y, z)
def translate_node_number_to_noxim_system(node):
    """
    Translates the numbering system of Schedule and Depend to Noxim system
    :param node: Node ID in AG
    :return: Node coordination in Noxim System
    """
    x, y, z = AG_Functions.return_node_location(node)
    z = Config.Network_Z_Size - z - 1
    y = Config.Network_Y_Size - y - 1
    return AG_Functions.return_node_number(x, y, z)
def MergeRectangleWithNode(Rect_ll, Rect_ur, Node):
    x1, y1, z1 = AG_Functions.return_node_location(Rect_ll)
    x2, y2, z2 = AG_Functions.return_node_location(Rect_ur)
    NodeX, NodeY, NodeZ = AG_Functions.return_node_location(Node)
    MergedX1 = min(x1, NodeX)
    MergedY1 = min(y1, NodeY)
    MergedZ1 = min(z1, NodeZ)
    MergedX2 = max(x2, NodeX)
    MergedY2 = max(y2, NodeY)
    MergedZ2 = max(z2, NodeZ)
    return MergedX1, MergedY1, MergedZ1, MergedX2, MergedY2, MergedZ2
예제 #9
0
def evaluate_actual_odd_even_turn_model():
    """
    evaluates the classic odd-even turn model in terms of DoA and DoA_ex
    :return: None
    """
    turns_health_2d_network = {"N2W": False, "N2E": False, "S2W": False, "S2E": False,
                               "W2N": False, "W2S": False, "E2N": False, "E2S": False}
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = 3
    Config.ag.y_size = 3
    Config.ag.z_size = 1
    Config.RotingType = 'MinimalPath'
    ag = copy.deepcopy(AG_Functions.generate_ag())
    number_of_pairs = len(ag.nodes())*(len(ag.nodes())-1)

    turn_model_odd = ['E2N', 'E2S', 'W2N', 'W2S', 'S2E', 'N2E']
    turn_model_even = ['E2N', 'E2S', 'S2W', 'S2E', 'N2W', 'N2E']

    if not check_tm_domination(turn_model_odd, turn_model_even):   # taking out the domination!
        turns_health = copy.deepcopy(turns_health_2d_network)
        shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
        shmu.setup_noc_shm(ag, turns_health, False)
        noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, [], False,  False))

        for node in ag.nodes():
            node_x, node_y, node_z = AG_Functions.return_node_location(node)
            if node_x % 2 == 1:
                for turn in turn_model_odd:
                    shmu.restore_broken_turn(node, turn, False)
                    from_port = str(node)+str(turn[0])+"I"
                    to_port = str(node)+str(turn[2])+"O"
                    Routing.update_noc_route_graph(noc_rg, from_port, to_port, 'ADD')
            else:
                for turn in turn_model_even:
                    shmu.restore_broken_turn(node, turn, False)
                    from_port = str(node)+str(turn[0])+"I"
                    to_port = str(node)+str(turn[2])+"O"
                    Routing.update_noc_route_graph(noc_rg, from_port, to_port, 'ADD')
        draw_rg(noc_rg)
        connectivity_metric = reachability_metric(ag, noc_rg, False)
        print "connectivity_metric:", connectivity_metric
        if check_deadlock_freeness(noc_rg):
            print "Deadlock free!"

        doa = degree_of_adaptiveness(ag, noc_rg, False)/float(number_of_pairs)
        doa_ex = extended_degree_of_adaptiveness(ag, noc_rg, False)/float(number_of_pairs)
        print "doa:", doa
        print "doa_ex", doa_ex
    return None
def enumerate_all_2d_turn_models_based_on_df(combination):
    """
    Lists all 2D deadlock free turn models in "deadlock_free_turns" in "Generated_Files"
    folder!
    ---------------------
        We have 256 turns in 2D Mesh NoC!
    ---------------------
    :param combination: number of turns which should be checked for combination!
    :return: None
    """
    counter = 0
    all_turns_file = open('Generated_Files/Turn_Model_Lists/all_2D_turn_models_'+str(combination)+'.txt', 'w')
    turns_health_2d_network = {"N2W": False, "N2E": False, "S2W": False, "S2E": False,
                               "W2N": False, "W2S": False, "E2N": False, "E2S": False}
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = 3
    Config.ag.y_size = 3
    Config.ag.z_size = 1
    Config.RotingType = 'NonMinimalPath'

    all_turns_file.write("#"+"\t\tDF/D\t"+'%25s' % "turns"+'%20s' % " "+"\t\t"+'%10s' % "c-metric" +
                         "\t\t"+'%10s' % "DoA"+"\t\t"+'%10s' % "DoAx"+"\n")
    all_turns_file.write("--------------"*8+"\n")
    ag = copy.deepcopy(AG_Functions.generate_ag())
    number_of_pairs = len(ag.nodes())*(len(ag.nodes())-1)
    turn_model_list = copy.deepcopy(PackageFile.FULL_TurnModel_2D)

    deadlock_free_counter = 0
    deadlock_counter = 0
    # print "Number of Turns:", combination
    for turns in itertools.combinations(turn_model_list, combination):
        turns_health = copy.deepcopy(turns_health_2d_network)
        for turn in turns:
            turns_health[turn] = True
        counter += 1
        shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
        shmu.setup_noc_shm(ag, turns_health, False)
        noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, list(turns), False,  False))
        if check_deadlock_freeness(noc_rg):
            connectivity_metric = reachability_metric(ag, noc_rg, False)
            doa = degree_of_adaptiveness(ag, noc_rg, False)/float(number_of_pairs)
            doa_ex = extended_degree_of_adaptiveness(ag, noc_rg, False)/float(number_of_pairs)
            deadlock_free_counter += 1
            # print counter, "\t \033[92mDF\033[0m \t", list(turns), "\t\t", connectivity_metric
            all_turns_file.write(str(counter)+"\t\tDF\t"+'%51s' % str(list(turns)) +
                                 "\t\t"+'%10s' % str(connectivity_metric) +
                                 "\t\t"+'%10s' % str(round(doa, 2))+"\t\t"+'%10s' % str(round(doa_ex, 2))+"\n")
        else:
            deadlock_counter += 1
            # print counter, "\t \033[31mDL\033[0m   \t", list(turns), "\t\t----"
            all_turns_file.write(str(counter)+"\t\tDL\t"+'%51s' % str(list(turns)) +
                                 "\t\t-----"+"\t\t-----"+"\t\t-----"+"\n")
        del shmu
        del noc_rg
    all_turns_file.write("---------------------------"+"\n")
    all_turns_file.write("Number of turn models with deadlock: "+str(deadlock_counter)+"\n")
    all_turns_file.write("Number of turn models without deadlock: "+str(deadlock_free_counter)+"\n")
    all_turns_file.write("=========================================="+"\n")
    all_turns_file.close()
    return None
def MergeNodeWithRectangles(RectangleList, UnreachableNodeList):
    # todo: in this function if we can not perform any loss-less merge, we terminate the process...
    # which is bad... we need to make sure that this node is covered
    for UnreachableNode in UnreachableNodeList:
        Covered = False
        for Rectangle in RectangleList:
            if RectangleList[Rectangle][0] == None:
                # there is no entry, this is the first node to get in...
                RectangleList[Rectangle] = (UnreachableNode, UnreachableNode)
                Covered = True
                break
            else:
                if is_node_inside_rectangle(RectangleList[Rectangle],
                                            UnreachableNode):
                    Covered = True
                    break
                else:
                    MergedX1, MergedY1, MergedZ1, MergedX2, MergedY2, MergedZ2 = MergeRectangleWithNode(
                        RectangleList[Rectangle][0],
                        RectangleList[Rectangle][1], UnreachableNode)
                    # print ("Merged:" ,MergedY1 * Config.Network_X_Size + MergedX1,
                    #        MergedY2 * Config.Network_X_Size + MergedX2)
                    LossLessMerge = True
                    for NetworkNode_X in range(MergedX1, MergedX2 + 1):
                        for NetworkNode_Y in range(MergedY1, MergedY2 + 1):
                            for NetworkNode_Z in range(MergedZ1, MergedZ2 + 1):
                                NodeNumber = AG_Functions.return_node_number(
                                    NetworkNode_X, NetworkNode_Y,
                                    NetworkNode_Z)
                                if NodeNumber not in UnreachableNodeList:
                                    LossLessMerge = False
                                    break
                    # if we are not losing any Node, we perform Merge...
                    if LossLessMerge:
                        Merged1 = AG_Functions.return_node_number(
                            MergedX1, MergedY1, MergedZ1)
                        Merged2 = AG_Functions.return_node_number(
                            MergedX2, MergedY2, MergedZ2)
                        RectangleList[Rectangle] = copy.deepcopy(
                            (Merged1, Merged2))
                        Covered = True
                        break
        if not Covered:
            print("COULD NOT PERFORM ANY LOSS-LESS MERGE FOR:" +
                  str(UnreachableNode))
            print(RectangleList)
    return RectangleList
def draw_mapping_distribution(ag, shmu):
    """
    Draws mapping Task Number and Utilization Distribution
    :param ag: Architecture Graph
    :param shmu: System health Monitoring Unit
    :return: None
    """
    print ("===========================================")
    print ("GENERATING MAPPING DISTRIBUTIONS VISUALIZATION...")
    fig_num = plt.figure(figsize=(4*Config.ag.x_size, 4*Config.ag.y_size))
    fig_util = plt.figure(figsize=(4*Config.ag.x_size, 4*Config.ag.y_size))
    max_number_of_tasks = 0
    max_utilization = 0
    for node in ag.nodes():
        max_number_of_tasks = max(len(ag.node[node]['PE'].mapped_tasks), max_number_of_tasks)
        max_utilization = max(ag.node[node]['PE'].utilization, max_utilization)

    for node in ag.nodes():
        location = AG_Functions.return_node_location(node)
        x_size = float(Config.ag.x_size)
        y_size = float(Config.ag.y_size)
        z_size = float(Config.ag.y_size)
        num = 255*len(ag.node[node]['PE'].mapped_tasks)/float(max_number_of_tasks)
        util = 255*ag.node[node]['PE'].utilization/float(max_utilization)
        if shmu.SHM.node[node]['NodeHealth']:
            if not ag.node[node]['PE'].dark:
                color = '#%02X%02X%02X' % (255, 255-num, 255-num)
            else:
                color = 'gray'
        else:   # node is broken
            color = '#7B747B'
        fig_num.gca().add_patch(patches.Rectangle((location[0]/x_size+location[2]/(z_size*x_size**2),
                                                   location[1]/y_size+location[2]/(z_size*y_size**2)),
                                width=0.15, height=0.15, facecolor=color,
                                edgecolor="black", linewidth=3, zorder=z_size-location[2]))
        if shmu.SHM.node[node]['NodeHealth']:
            if not ag.node[node]['PE'].dark:
                color = '#%02X%02X%02X' % (255, 255-util, 255-util)
            else:
                color = 'gray'
        else:   # node is broken
            color = '#7B747B'
        fig_util.gca().add_patch(patches.Rectangle((location[0]/x_size+location[2]/(z_size*x_size**2),
                                                    location[1]/y_size+location[2]/(z_size*y_size**2)),
                                 width=0.15, height=0.15, facecolor=color,
                                 edgecolor="black", linewidth=3, zorder=z_size-location[2]))

    fig_num.text(0.25, 0.03, 'Distribution of number of the tasks on the network', fontsize=15)
    fig_util.text(0.25, 0.03, 'Distribution of utilization of network nodes', fontsize=15)
    fig_num.savefig("GraphDrawings/Mapping_Num.png", bbox_inches='tight')
    fig_util.savefig("GraphDrawings/Mapping_Util.png", bbox_inches='tight')
    fig_num.clf()
    fig_util.clf()
    plt.close(fig_num)
    plt.close(fig_util)
    print ("\033[35m* VIZ::\033[0mMAPPING UTILIZATION DISTRIBUTION DRAWING CREATED AT: GraphDrawings/Mapping_Util.png")
    print ("\033[35m* VIZ::\033[0mMAPPING TASK NUMBER DISTRIBUTION DRAWING CREATED AT: GraphDrawings/Mapping_Num.png")
    return None
def enumerate_all_3d_turn_models_based_on_df(combination):
    """
    Lists all 3D deadlock free turn models in "deadlock_free_turns" in "Generated_Files"
    folder!
    ---------------------
        We have 16,777,216 turns in 3D Mesh NoC! if it takes one second to calculate
        deadlock freeness Then it takes almost 194.2 Days (almost 6.4 Months) to
        check all of them. that is the reason we need to make this parallel!
    ---------------------
    :param combination: number of turns which should be checked for combination!
    :return: None
    """
    counter = 0
    all_turns_file = open('Generated_Files/Turn_Model_Lists/all_3D_turn_models_'+str(combination)+'.txt', 'w')
    turns_health_3d_network = {"N2W": False, "N2E": False, "S2W": False, "S2E": False,
                               "W2N": False, "W2S": False, "E2N": False, "E2S": False,
                               "N2U": False, "N2D": False, "S2U": False, "S2D": False,
                               "W2U": False, "W2D": False, "E2U": False, "E2D": False,
                               "U2W": False, "U2E": False, "U2N": False, "U2S": False,
                               "D2W": False, "D2E": False, "D2N": False, "D2S": False}
    Config.ag.topology = '3DMesh'
    Config.ag.x_size = 3
    Config.ag.y_size = 3
    Config.ag.z_size = 3

    ag = copy.deepcopy(AG_Functions.generate_ag())
    turn_model_list = copy.deepcopy(PackageFile.FULL_TurnModel_3D)

    deadlock_free_counter = 0
    deadlock_counter = 0
    # print "Number of Turns:", combination
    for turns in itertools.combinations(turn_model_list, combination):
        turns_health = copy.deepcopy(turns_health_3d_network)
        for turn in turns:
            turns_health[turn] = True
        counter += 1
        shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
        shmu.setup_noc_shm(ag, turns_health, False)
        noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, list(turns), False,  False))
        if check_deadlock_freeness(noc_rg):
            connectivity_metric = reachability_metric(ag, noc_rg, False)
            doa = degree_of_adaptiveness(ag, noc_rg, False)
            deadlock_free_counter += 1
            # print counter, "\t \033[92mDF\033[0m \t", list(turns), "\t\t", connectivity_metric
            all_turns_file.write(str(counter)+"\t\tDF\t"+str(list(turns))+"\t\t"+str(connectivity_metric) +
                                 "\t\t"+str(doa)+"\n")
        else:
            deadlock_counter += 1
            # print counter, "\t \033[31mDL\033[0m   \t", list(turns), "\t\t----"
            all_turns_file.write(str(counter)+"\t\tDL\t"+str(list(turns))+"\t\t-----""\n")
        del shmu
        del noc_rg
    all_turns_file.write("---------------------------"+"\n")
    all_turns_file.write("Number of turn models with deadlock: "+str(deadlock_counter)+"\n")
    all_turns_file.write("Number of turn models without deadlock: "+str(deadlock_free_counter)+"\n")
    all_turns_file.write("=========================================="+"\n")
    all_turns_file.close()
    return None
예제 #14
0
def ReturnMinimalPaths(CurrentRG, SourceNode, DestinationNode):
    AllMinimalPaths=[]
    MaxHopCount= AG_Functions.manhattan_distance(SourceNode, DestinationNode)
    Source = str(SourceNode)+str('L')+str('I')
    Destination = str(DestinationNode)+str('L')+str('O')
    AllPaths = list(networkx.all_shortest_paths(CurrentRG, Source, Destination))
    for Path in AllPaths:
        if (len(Path)-2)/2 <= MaxHopCount:
            AllMinimalPaths.append(Path)
    return AllMinimalPaths
def enumerate_all_odd_even_turn_models(network_size, routing_type):
    all_odd_evens_file = open('Generated_Files/Turn_Model_Lists/'+str(network_size)+"x"
                              +str(network_size)+"_"+str(routing_type)+"_"+'odd_even_tm_list_dl_free.txt', 'w')
    turns_health_2d_network = {"N2W": False, "N2E": False, "S2W": False, "S2E": False,
                               "W2N": False, "W2S": False, "E2N": False, "E2S": False}
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = network_size
    Config.ag.y_size = network_size
    Config.ag.z_size = 1
    Config.RotingType = routing_type
    ag = copy.deepcopy(AG_Functions.generate_ag())
    number_of_pairs = len(ag.nodes())*(len(ag.nodes())-1)

    turn_model_list = []
    for length in range(0, len(turns_health_2d_network.keys())+1):
        for item in list(itertools.combinations(turns_health_2d_network.keys(), length)):
            if len(item) > 0:
                turn_model_list.append(list(item))

    connected_counter = 0
    deadlock_free_counter = 0
    tm_counter = 0
    turns_health = copy.deepcopy(turns_health_2d_network)
    shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
    shmu.setup_noc_shm(ag, turns_health, False)
    noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, [], False,  False))

    for turn_model_odd in turn_model_list:
        for turn_model_even in turn_model_list:
            if not check_tm_domination(turn_model_odd, turn_model_even):   # taking out the domination!

                update_rg_odd_even(ag, turn_model_odd, turn_model_even, shmu, noc_rg)
                connectivity_metric = reachability_metric(ag, noc_rg, False)
                if connectivity_metric == number_of_pairs:
                    connected_counter += 1
                    if check_deadlock_freeness(noc_rg):
                        deadlock_free_counter += 1
                        all_odd_evens_file.write("["+str(turn_model_odd)+","+str(turn_model_even)+"],\n")

                tm_counter += 1
                sys.stdout.write("\rchecked TM: %i " % tm_counter +
                                 " number of fully connected TM: %i" % connected_counter +
                                 " number of deadlock free connected TM: %i" % deadlock_free_counter)
                sys.stdout.flush()

                clean_rg_from_odd_even(ag, turn_model_odd, turn_model_even, shmu, noc_rg)

    all_odd_evens_file.write("checked TM: %i " + str(tm_counter) +
                             " number of fully connected TM: %i" +str(connected_counter) +
                             " number of deadlock free connected TM: %i"+str(deadlock_free_counter))
    all_odd_evens_file.close()
    return None
예제 #16
0
def draw_temp_distribution(shm):
    """

    :param shm: System Health Map
    :return:
    """
    print ("===========================================")
    print ("GENERATING TEMPERATURE DISTRIBUTIONS VISUALIZATION...")
    fig_util = plt.figure(figsize=(4*Config.ag.x_size, 4*Config.ag.y_size))
    max_temp = 0
    for node in shm.nodes():
        max_temp = max(shm.node[node]['NodeTemp'], max_temp)

    for node in shm.nodes():
        location = AG_Functions.return_node_location(node)
        x_size = float(Config.ag.x_size)
        y_size = float(Config.ag.y_size)
        z_size = float(Config.ag.y_size)

        x_offset = location[2]/(z_size*x_size)
        y_offset = location[2]/(z_size*y_size)

        temp = 255*(float(shm.node[node]['RouterTemp'])/Config.MaxTemp)
        if shm.node[node]['NodeHealth']:
            color = '#%02X%02X%02X' % (temp, 0, 255-temp)
        else:   # node is broken
            color = '#7B747B'
        fig_util.gca().add_patch(patches.Rectangle((location[0]/x_size+x_offset,
                                                    location[1]/y_size+y_offset),
                                                   width=0.08, height=0.08, facecolor=color,
                                                   edgecolor="black", linewidth=3, zorder=z_size-location[2]))

        temp = 255*(float(shm.node[node]['NodeTemp'])/Config.MaxTemp)

        if shm.node[node]['NodeHealth']:
            color = '#%02X%02X%02X' % (temp, 0, 255-temp)
        else:   # node is broken
            color = '#7B747B'
        fig_util.gca().add_patch(patches.Rectangle((location[0]/x_size+x_offset+0.05,
                                                    location[1]/y_size+y_offset),
                                                   width=0.03, height=0.03, facecolor=color,
                                                   edgecolor="black", linewidth=3, zorder=z_size-location[2]))

    fig_util.text(0.25, 0.03, 'Distribution of temperature of network nodes', fontsize=15)
    fig_util.savefig("GraphDrawings/Temp_Distribute.png", dpi=100)
    fig_util.clf()
    plt.close(fig_util)
    print("\033[35m* VIZ::\033[0mMAPPING UTILIZATION DISTRIBUTION DRAWING " +
          "CREATED AT: GraphDrawings/Temp_Distribute.png")
    return None
예제 #17
0
def calculate_com_cost(tg):
    """
    Calculates the cost of the current mapping
    :param tg: Task Graph
    :return:  cost of the mapping
    """
    cost = 0
    for edge in tg.edges():
        task_1 = edge[0]
        task_2 = edge[1]
        node_1 = tg.node[task_1]['task'].node
        node_2 = tg.node[task_2]['task'].node
        com_weight = tg.edge[edge[0]][edge[1]]["ComWeight"]
        manhatan_distance = AG_Functions.manhattan_distance(node_1, node_2)
        cost += manhatan_distance * com_weight
    return cost
예제 #18
0
def calculate_com_cost(tg):
    """
    Calculates the cost of the current mapping
    :param tg: Task Graph
    :return:  cost of the mapping
    """
    cost = 0
    for edge in tg.edges():
        task_1 = edge[0]
        task_2 = edge[1]
        node_1 = tg.node[task_1]['Node']
        node_2 = tg.node[task_2]['Node']
        com_weight = tg.edge[edge[0]][edge[1]]["ComWeight"]
        manhatan_distance = AG_Functions.manhattan_distance(node_1, node_2)
        cost += manhatan_distance * com_weight
    return cost
def evaluate_actual_odd_even_turn_model():
    """
    evaluates the classic odd-even turn model in terms of DoA and DoA_ex
    :return: None
    """
    turns_health_2d_network = {
        "N2W": False,
        "N2E": False,
        "S2W": False,
        "S2E": False,
        "W2N": False,
        "W2S": False,
        "E2N": False,
        "E2S": False
    }
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = 3
    Config.ag.y_size = 3
    Config.ag.z_size = 1
    Config.RotingType = 'MinimalPath'
    ag = copy.deepcopy(AG_Functions.generate_ag())
    number_of_pairs = len(ag.nodes()) * (len(ag.nodes()) - 1)

    turn_model_odd = ['E2N', 'E2S', 'W2N', 'W2S', 'S2E', 'N2E']
    turn_model_even = ['E2N', 'E2S', 'S2W', 'S2E', 'N2W', 'N2E']

    if not check_tm_domination(turn_model_odd,
                               turn_model_even):  # taking out the domination!
        turns_health = copy.deepcopy(turns_health_2d_network)
        shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
        shmu.setup_noc_shm(ag, turns_health, False)
        noc_rg = copy.deepcopy(
            Routing.generate_noc_route_graph(ag, shmu, [], False, False))
        update_rg_odd_even(ag, turn_model_odd, turn_model_even, shmu, noc_rg)
        draw_rg(noc_rg)
        connectivity_metric = reachability_metric(ag, noc_rg, False)
        print("connectivity_metric:", connectivity_metric)
        if check_deadlock_freeness(noc_rg):
            print("Deadlock free!")

        doa = degree_of_adaptiveness(ag, noc_rg,
                                     False) / float(number_of_pairs)
        doa_ex = extended_degree_of_adaptiveness(
            ag, noc_rg, False) / float(number_of_pairs)
        print("doa:", doa)
        print("doa_ex", doa_ex)
    return None
def clean_rg_from_odd_even(ag, turn_model_odd, turn_model_even, shmu, noc_rg):
    """
    gets a turn model for odd and even columns, along with an noc_rg and a SHMU
    and removes added connections in the SHMU and noc_rg based on the turn models
    """
    for node in ag.nodes():
        node_x, node_y, node_z = AG_Functions.return_node_location(node)
        if node_x % 2 == 1:
            for turn in turn_model_odd:
                shmu.restore_broken_turn(node, turn, False)
                from_port = str(node)+str(turn[0])+"I"
                to_port = str(node)+str(turn[2])+"O"
                Routing.update_noc_route_graph(noc_rg, from_port, to_port, 'REMOVE')
        else:
            for turn in turn_model_even:
                shmu.restore_broken_turn(node, turn, False)
                from_port = str(node)+str(turn[0])+"I"
                to_port = str(node)+str(turn[2])+"O"
                Routing.update_noc_route_graph(noc_rg, from_port, to_port, 'REMOVE')
    return
def clean_rg_from_odd_even(ag, turn_model_odd, turn_model_even, shmu, noc_rg):
    """
    gets a turn model for odd and even columns, along with an noc_rg and a SHMU
    and removes added connections in the SHMU and noc_rg based on the turn models
    """
    for node in ag.nodes():
        node_x, node_y, node_z = AG_Functions.return_node_location(node)
        if node_x % 2 == 1:
            for turn in turn_model_odd:
                shmu.restore_broken_turn(node, turn, False)
                from_port = str(node) + str(turn[0]) + "I"
                to_port = str(node) + str(turn[2]) + "O"
                Routing.update_noc_route_graph(noc_rg, from_port, to_port,
                                               'REMOVE')
        else:
            for turn in turn_model_even:
                shmu.restore_broken_turn(node, turn, False)
                from_port = str(node) + str(turn[0]) + "I"
                to_port = str(node) + str(turn[2]) + "O"
                Routing.update_noc_route_graph(noc_rg, from_port, to_port,
                                               'REMOVE')
    return
예제 #22
0
def initialize_system_DoS(logging):
    """
    Generates the Task graph, Architecture Graph, System Health Monitoring Unit, NoC routing graph(s) and
    Test Task Graphs and does the mapping and scheduling and returns to the user the initial system
    :param logging: logging file
    :return:  ag, shmu, noc_rg
    """

    ####################################################################
    ag = copy.deepcopy(AG_Functions.generate_ag(logging))
    AG_Functions.update_ag_regions(ag)
    AG_Functions.random_darkness(ag)
    if Config.EnablePartitioning:
        AG_Functions.setup_network_partitioning(ag)
    if Config.FindOptimumAG:
        Arch_Graph_Reports.draw_ag(ag, "AG_Full")
    else:
        Arch_Graph_Reports.draw_ag(ag, "AG")
    ####################################################################
    Config.setup_turns_health()
    shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
    shmu.setup_noc_shm(ag, Config.TurnsHealth, True)
    # Here we are injecting initial faults of the system: we assume these fault
    # information is obtained by post manufacturing system diagnosis
    SHMU_Functions.apply_initial_faults(shmu)
    if Config.viz.shm:
        SHMU_Reports.draw_shm(shmu.SHM)
        SHMU_Reports.draw_temp_distribution(shmu.SHM)
    # SHM_Reports.report_noc_shm()
    ####################################################################
    routing_graph_start_time = time.time()
    noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, Config.UsedTurnModel,
                           Config.DebugInfo, Config.DebugDetails))
    Routing_Functions.check_deadlock_freeness(noc_rg)
    print("\033[92mTIME::\033[0m ROUTING GRAPH GENERATION TOOK: " +
           str(round(time.time()-routing_graph_start_time))+" SECONDS")
    # Some visualization...
    if Config.viz.rg:
        RoutingGraph_Reports.draw_rg(noc_rg)
    return ag, shmu, noc_rg
def initialize_system_DoS(logging):
    """
    Generates the Task graph, Architecture Graph, System Health Monitoring Unit, NoC routing graph(s) and
    Test Task Graphs and does the mapping and scheduling and returns to the user the initial system
    :param logging: logging file
    :return:  ag, shmu, noc_rg
    """

    ####################################################################
    ag = copy.deepcopy(AG_Functions.generate_ag(logging))
    AG_Functions.update_ag_regions(ag)
    AG_Functions.random_darkness(ag)
    if Config.EnablePartitioning:
        AG_Functions.setup_network_partitioning(ag)
    if Config.FindOptimumAG:
        Arch_Graph_Reports.draw_ag(ag, "AG_Full")
    else:
        Arch_Graph_Reports.draw_ag(ag, "AG")
    ####################################################################
    Config.setup_turns_health()
    shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
    shmu.setup_noc_shm(ag, Config.TurnsHealth, True)
    # Here we are injecting initial faults of the system: we assume these fault
    # information is obtained by post manufacturing system diagnosis
    SHMU_Functions.apply_initial_faults(shmu)
    if Config.viz.shm:
        SHMU_Reports.draw_shm(shmu.SHM)
        SHMU_Reports.draw_temp_distribution(shmu.SHM)
    # SHM_Reports.report_noc_shm()
    ####################################################################
    routing_graph_start_time = time.time()
    noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, Config.UsedTurnModel,
                           Config.DebugInfo, Config.DebugDetails))
    Routing_Functions.check_deadlock_freeness(noc_rg)
    print ("\033[92mTIME::\033[0m ROUTING GRAPH GENERATION TOOK: " +
           str(round(time.time()-routing_graph_start_time))+" SECONDS")
    # Some visualization...
    if Config.viz.rg:
        RoutingGraph_Reports.draw_rg(noc_rg)
    return ag, shmu, noc_rg
def draw_mapping_distribution(ag, shmu):
    """
    Draws mapping Task Number and Utilization Distribution
    :param ag: Architecture Graph
    :param shmu: System health Monitoring Unit
    :return: None
    """
    print("===========================================")
    print("GENERATING MAPPING DISTRIBUTIONS VISUALIZATION...")
    fig_num = plt.figure(figsize=(4 * Config.ag.x_size, 4 * Config.ag.y_size))
    fig_util = plt.figure(figsize=(4 * Config.ag.x_size, 4 * Config.ag.y_size))
    max_number_of_tasks = 0
    max_utilization = 0
    for node in ag.nodes():
        max_number_of_tasks = max(len(ag.node[node]['PE'].mapped_tasks),
                                  max_number_of_tasks)
        max_utilization = max(ag.node[node]['PE'].utilization, max_utilization)

    for node in ag.nodes():
        location = AG_Functions.return_node_location(node)
        x_size = float(Config.ag.x_size)
        y_size = float(Config.ag.y_size)
        z_size = float(Config.ag.y_size)
        num = 255 * len(
            ag.node[node]['PE'].mapped_tasks) / float(max_number_of_tasks)
        util = 255 * ag.node[node]['PE'].utilization / float(max_utilization)
        if shmu.SHM.node[node]['NodeHealth']:
            if not ag.node[node]['PE'].dark:
                color = '#%02X%02X%02X' % (255, 255 - num, 255 - num)
            else:
                color = 'gray'
        else:  # node is broken
            color = '#7B747B'
        fig_num.gca().add_patch(
            patches.Rectangle(
                (location[0] / x_size + location[2] / (z_size * x_size**2),
                 location[1] / y_size + location[2] / (z_size * y_size**2)),
                width=0.15,
                height=0.15,
                facecolor=color,
                edgecolor="black",
                linewidth=3,
                zorder=z_size - location[2]))
        if shmu.SHM.node[node]['NodeHealth']:
            if not ag.node[node]['PE'].dark:
                color = '#%02X%02X%02X' % (255, 255 - util, 255 - util)
            else:
                color = 'gray'
        else:  # node is broken
            color = '#7B747B'
        fig_util.gca().add_patch(
            patches.Rectangle(
                (location[0] / x_size + location[2] / (z_size * x_size**2),
                 location[1] / y_size + location[2] / (z_size * y_size**2)),
                width=0.15,
                height=0.15,
                facecolor=color,
                edgecolor="black",
                linewidth=3,
                zorder=z_size - location[2]))

    fig_num.text(0.25,
                 0.03,
                 'Distribution of number of the tasks on the network',
                 fontsize=15)
    fig_util.text(0.25,
                  0.03,
                  'Distribution of utilization of network nodes',
                  fontsize=15)
    fig_num.savefig("GraphDrawings/Mapping_Num.png", bbox_inches='tight')
    fig_util.savefig("GraphDrawings/Mapping_Util.png", bbox_inches='tight')
    fig_num.clf()
    fig_util.clf()
    plt.close(fig_num)
    plt.close(fig_util)
    print(
        "\033[35m* VIZ::\033[0mMAPPING UTILIZATION DISTRIBUTION DRAWING CREATED AT: GraphDrawings/Mapping_Util.png"
    )
    print(
        "\033[35m* VIZ::\033[0mMAPPING TASK NUMBER DISTRIBUTION DRAWING CREATED AT: GraphDrawings/Mapping_Num.png"
    )
    return None
예제 #25
0
def DrawSHM(SHM):
    """

    :param SHM: System Health Map
    :return:
    """
    print("===========================================")
    print("GENERATING SYSTEM HEALTH MAP DRAWING...")

    XSize = float(Config.Network_X_Size)
    YSize = float(Config.Network_Y_Size)
    ZSize = float(Config.Network_Z_Size)

    fig = plt.figure(figsize=(10 * XSize, 10 * YSize))
    if ZSize == 1:
        plt.ylim([0, 1])
        plt.xlim([0, 1])
    else:
        plt.ylim([0, ZSize])
        plt.xlim([0, ZSize])

    for node in SHM.nodes():
        Location = AG_Functions.return_node_location(node)
        X = (Location[0] / XSize) * ZSize
        Y = (Location[1] / YSize) * ZSize
        Z = (Location[2] / ZSize)
        X_offset = Z
        Y_offset = Z

        fontsize = 35 / ZSize
        plt.text(X + 0.155 + X_offset,
                 Y + 0.055 + Y_offset,
                 str(node),
                 fontsize=fontsize)
        CircleRouter = plt.Circle((X + 0.1 + X_offset, Y + 0.1 + Y_offset),
                                  0.05,
                                  facecolor='w')
        plt.gca().add_patch(CircleRouter)
        if SHM.node[node]['NodeHealth']:
            color = 'w'
        else:
            color = 'r'
        CircleNode = plt.Circle((X + 0.14 + X_offset, Y + 0.06 + Y_offset),
                                0.01,
                                facecolor=color)
        plt.gca().add_patch(CircleNode)

        for turn in SHM.node[node]['TurnsHealth']:
            if SHM.node[node]['TurnsHealth'][turn]:
                color = 'black'
            else:
                color = 'r'

            if turn == 'S2E':
                plt.gca().add_patch(
                    patches.Arrow(X + 0.11 + X_offset,
                                  Y + 0.065 + Y_offset,
                                  0.015,
                                  0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'E2S':
                plt.gca().add_patch(
                    patches.Arrow(X + 0.135 + X_offset,
                                  Y + 0.08 + Y_offset,
                                  -0.015,
                                  -0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'W2N':
                plt.gca().add_patch(
                    patches.Arrow(X + 0.065 + X_offset,
                                  Y + 0.117 + Y_offset,
                                  0.015,
                                  0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'N2W':
                plt.gca().add_patch(
                    patches.Arrow(X + 0.09 + X_offset,
                                  Y + 0.132 + Y_offset,
                                  -0.015,
                                  -0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'N2E':
                plt.gca().add_patch(
                    patches.Arrow(X + 0.12 + X_offset,
                                  Y + 0.132 + Y_offset,
                                  0.015,
                                  -0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'E2N':
                plt.gca().add_patch(
                    patches.Arrow(X + 0.125 + X_offset,
                                  Y + 0.117 + Y_offset,
                                  -0.015,
                                  0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'W2S':
                plt.gca().add_patch(
                    patches.Arrow(X + 0.075 + X_offset,
                                  Y + 0.08 + Y_offset,
                                  0.015,
                                  -0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'S2W':
                plt.gca().add_patch(
                    patches.Arrow(X + 0.080 + X_offset,
                                  Y + 0.065 + Y_offset,
                                  -0.015,
                                  0.015,
                                  width=0.01,
                                  color=color))

            if SHM.node[node]['TurnsHealth'][turn]:
                color = 'black'
            else:
                color = 'r'

            if turn == 'N2U':
                CircleNode = plt.Circle(
                    (X + 0.09 + X_offset, Y + 0.142 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)

            elif turn == 'N2D':
                CircleNode = plt.Circle(
                    (X + 0.11 + X_offset, Y + 0.142 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                CircleNode = plt.Circle(
                    (X + 0.11 + X_offset, Y + 0.142 + Y_offset),
                    0.001,
                    facecolor='b')
                plt.gca().add_patch(CircleNode)

            elif turn == 'S2U':
                CircleNode = plt.Circle(
                    (X + 0.11 + X_offset, Y + 0.057 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)

            elif turn == 'S2D':
                CircleNode = plt.Circle(
                    (X + 0.09 + X_offset, Y + 0.057 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                CircleNode = plt.Circle(
                    (X + 0.09 + X_offset, Y + 0.057 + Y_offset),
                    0.001,
                    facecolor='b')
                plt.gca().add_patch(CircleNode)

            elif turn == 'E2U':
                CircleNode = plt.Circle(
                    (X + 0.142 + X_offset, Y + 0.11 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)

            elif turn == 'E2D':
                CircleNode = plt.Circle(
                    (X + 0.142 + X_offset, Y + 0.09 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                CircleNode = plt.Circle(
                    (X + 0.142 + X_offset, Y + 0.09 + Y_offset),
                    0.001,
                    facecolor='b')
                plt.gca().add_patch(CircleNode)

            elif turn == 'W2U':
                CircleNode = plt.Circle(
                    (X + 0.057 + X_offset, Y + 0.09 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)

            elif turn == 'W2D':
                CircleNode = plt.Circle(
                    (X + 0.057 + X_offset, Y + 0.11 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                CircleNode = plt.Circle(
                    (X + 0.057 + X_offset, Y + 0.11 + Y_offset),
                    0.001,
                    facecolor='b')
                plt.gca().add_patch(CircleNode)

            elif turn == 'U2N':
                CircleNode = plt.Circle(
                    (X + 0.105 + X_offset, Y + 0.111 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                CircleNode = plt.Circle(
                    (X + 0.105 + X_offset, Y + 0.111 + Y_offset),
                    0.001,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                plt.gca().add_patch(
                    patches.Arrow(X + 0.105 + X_offset,
                                  Y + 0.116 + Y_offset,
                                  0,
                                  0.01,
                                  width=0.01,
                                  color=color))

            elif turn == 'U2S':
                CircleNode = plt.Circle(
                    (X + 0.105 + X_offset, Y + 0.086 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                CircleNode = plt.Circle(
                    (X + 0.105 + X_offset, Y + 0.086 + Y_offset),
                    0.001,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                plt.gca().add_patch(
                    patches.Arrow(X + 0.105 + X_offset,
                                  Y + 0.081 + Y_offset,
                                  0,
                                  -0.01,
                                  width=0.01,
                                  color=color))

            elif turn == 'U2W':
                CircleNode = plt.Circle(
                    (X + 0.085 + X_offset, Y + 0.093 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                CircleNode = plt.Circle(
                    (X + 0.085 + X_offset, Y + 0.093 + Y_offset),
                    0.001,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                plt.gca().add_patch(
                    patches.Arrow(X + 0.08 + X_offset,
                                  Y + 0.093 + Y_offset,
                                  -0.01,
                                  0,
                                  width=0.01,
                                  color=color))

            elif turn == 'U2E':
                CircleNode = plt.Circle(
                    (X + 0.115 + X_offset, Y + 0.093 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                CircleNode = plt.Circle(
                    (X + 0.115 + X_offset, Y + 0.093 + Y_offset),
                    0.001,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                plt.gca().add_patch(
                    patches.Arrow(X + 0.12 + X_offset,
                                  Y + 0.093 + Y_offset,
                                  0.01,
                                  0,
                                  width=0.01,
                                  color=color))

            elif turn == 'D2N':
                CircleNode = plt.Circle(
                    (X + 0.095 + X_offset, Y + 0.111 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                plt.gca().add_patch(
                    patches.Arrow(X + 0.095 + X_offset,
                                  Y + 0.116 + Y_offset,
                                  0,
                                  0.01,
                                  width=0.01,
                                  color=color))

            elif turn == 'D2S':
                CircleNode = plt.Circle(
                    (X + 0.095 + X_offset, Y + 0.086 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                plt.gca().add_patch(
                    patches.Arrow(X + 0.095 + X_offset,
                                  Y + 0.081 + Y_offset,
                                  0,
                                  -0.01,
                                  width=0.01,
                                  color=color))

            elif turn == 'D2W':
                CircleNode = plt.Circle(
                    (X + 0.085 + X_offset, Y + 0.104 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                plt.gca().add_patch(
                    patches.Arrow(X + 0.08 + X_offset,
                                  Y + 0.104 + Y_offset,
                                  -0.01,
                                  0,
                                  width=0.01,
                                  color=color))

            elif turn == 'D2E':
                CircleNode = plt.Circle(
                    (X + 0.115 + X_offset, Y + 0.104 + Y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(CircleNode)
                plt.gca().add_patch(
                    patches.Arrow(X + 0.12 + X_offset,
                                  Y + 0.104 + Y_offset,
                                  0.01,
                                  0,
                                  width=0.01,
                                  color=color))

    for link in SHM.edges():
        if SHM.edge[link[0]][link[1]]['LinkHealth']:
            color = 'black'
        else:
            color = 'r'
        SourceLoc = AG_Functions.return_node_location(link[0])
        DestinLoc = AG_Functions.return_node_location(link[1])

        X = (SourceLoc[0] / XSize) * ZSize
        Y = (SourceLoc[1] / YSize) * ZSize
        Z = SourceLoc[2] / ZSize
        X_offset = Z
        Y_offset = Z

        dx = ((DestinLoc[0] - SourceLoc[0]) / XSize)
        dy = ((DestinLoc[1] - SourceLoc[1]) / YSize)
        dz = ((DestinLoc[2] - SourceLoc[2]) / ZSize)
        if dz == 0:
            if dx == 0:
                if dy > 0:
                    plt.gca().add_patch(
                        patches.Arrow(X + 0.11 + X_offset,
                                      Y + 0.15 + Y_offset,
                                      0,
                                      dy * ZSize - 0.1,
                                      width=0.01,
                                      color=color))
                else:
                    plt.gca().add_patch(
                        patches.Arrow(X + 0.09 + X_offset,
                                      Y + 0.05 + Y_offset,
                                      0,
                                      dy * ZSize + 0.1,
                                      width=0.01,
                                      color=color))

            elif dy == 0:
                if dx > 0:
                    plt.gca().add_patch(
                        patches.Arrow(X + 0.15 + X_offset,
                                      Y + 0.11 + Y_offset,
                                      dx * ZSize - 0.1,
                                      0,
                                      width=0.01,
                                      color=color))
                else:
                    plt.gca().add_patch(
                        patches.Arrow(X + 0.05 + X_offset,
                                      Y + 0.09 + Y_offset,
                                      dx * ZSize + 0.1,
                                      0,
                                      width=0.01,
                                      color=color))
            else:
                raise ValueError("Can not draw link", link)
        elif dz > 0:
            Z_offset = 1.4 / ZSize
            plt.gca().add_patch(
                patches.Arrow(X + 0.130 + X_offset,
                              Y + 0.140 + Y_offset,
                              dz * Z_offset,
                              dz * Z_offset,
                              width=0.01,
                              color=color))
        elif dz < 0:
            plt.gca().add_patch(
                patches.Arrow(X + 0.07 + X_offset,
                              Y + 0.06 + Y_offset,
                              dz * Z_offset,
                              dz * Z_offset,
                              width=0.01,
                              color=color))

    fig.text(0.25, 0.02, "System Health Map", fontsize=35)
    plt.savefig("GraphDrawings/SHM.png", dpi=200)
    plt.clf()
    plt.close(fig)
    print(
        "\033[35m* VIZ::\033[0mSYSTEM HEALTH MAP DRAWING CREATED AT: GraphDrawings/SHM.png"
    )
    return None
예제 #26
0
def enumerate_all_odd_even_turn_models(network_size, routing_type):
    all_odd_evens_file = open(
        'Generated_Files/Turn_Model_Lists/' + str(network_size) + "x" +
        str(network_size) + "_" + str(routing_type) + "_" +
        'odd_even_tm_list_dl_free.txt', 'w')
    turns_health_2d_network = {
        "N2W": False,
        "N2E": False,
        "S2W": False,
        "S2E": False,
        "W2N": False,
        "W2S": False,
        "E2N": False,
        "E2S": False
    }
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = network_size
    Config.ag.y_size = network_size
    Config.ag.z_size = 1
    Config.RotingType = routing_type
    ag = copy.deepcopy(AG_Functions.generate_ag())
    number_of_pairs = len(ag.nodes()) * (len(ag.nodes()) - 1)

    turn_model_list = []
    for length in range(0, len(turns_health_2d_network.keys()) + 1):
        for item in list(
                itertools.combinations(turns_health_2d_network.keys(),
                                       length)):
            if len(item) > 0:
                turn_model_list.append(list(item))

    connected_counter = 0
    deadlock_free_counter = 0
    tm_counter = 0
    turns_health = copy.deepcopy(turns_health_2d_network)
    shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
    shmu.setup_noc_shm(ag, turns_health, False)
    noc_rg = copy.deepcopy(
        Routing.generate_noc_route_graph(ag, shmu, [], False, False))

    for turn_model_odd in turn_model_list:
        for turn_model_even in turn_model_list:
            if not check_tm_domination(
                    turn_model_odd,
                    turn_model_even):  # taking out the domination!
                for node in ag.nodes():
                    node_x, node_y, node_z = AG_Functions.return_node_location(
                        node)
                    if node_x % 2 == 1:
                        for turn in turn_model_odd:
                            shmu.restore_broken_turn(node, turn, False)
                            from_port = str(node) + str(turn[0]) + "I"
                            to_port = str(node) + str(turn[2]) + "O"
                            Routing.update_noc_route_graph(
                                noc_rg, from_port, to_port, 'ADD')
                    else:
                        for turn in turn_model_even:
                            shmu.restore_broken_turn(node, turn, False)
                            from_port = str(node) + str(turn[0]) + "I"
                            to_port = str(node) + str(turn[2]) + "O"
                            Routing.update_noc_route_graph(
                                noc_rg, from_port, to_port, 'ADD')
                connectivity_metric = reachability_metric(ag, noc_rg, False)
                if connectivity_metric == number_of_pairs:
                    connected_counter += 1
                    if check_deadlock_freeness(noc_rg):
                        deadlock_free_counter += 1
                        all_odd_evens_file.write("[" + str(turn_model_odd) +
                                                 "," + str(turn_model_even) +
                                                 "],\n")

                tm_counter += 1
                sys.stdout.write("\rchecked TM: %i " % tm_counter +
                                 " number of fully connected TM: %i" %
                                 connected_counter +
                                 " number of deadlock free connected TM: %i" %
                                 deadlock_free_counter)
                sys.stdout.flush()

                for node in ag.nodes():
                    node_x, node_y, node_z = AG_Functions.return_node_location(
                        node)
                    if node_x % 2 == 1:
                        for turn in turn_model_odd:
                            shmu.restore_broken_turn(node, turn, False)
                            from_port = str(node) + str(turn[0]) + "I"
                            to_port = str(node) + str(turn[2]) + "O"
                            Routing.update_noc_route_graph(
                                noc_rg, from_port, to_port, 'REMOVE')
                    else:
                        for turn in turn_model_even:
                            shmu.restore_broken_turn(node, turn, False)
                            from_port = str(node) + str(turn[0]) + "I"
                            to_port = str(node) + str(turn[2]) + "O"
                            Routing.update_noc_route_graph(
                                noc_rg, from_port, to_port, 'REMOVE')

    all_odd_evens_file.write("checked TM: %i " + str(tm_counter) +
                             " number of fully connected TM: %i" +
                             str(connected_counter) +
                             " number of deadlock free connected TM: %i" +
                             str(deadlock_free_counter))
    all_odd_evens_file.close()
    return None
예제 #27
0
def generate_frames(tg, ag, shm):
    """
    Generates Animation frames for the mapping process.
    :param tg: Task Graph
    :param ag: Architecture Graph
    :param shm: System Health Map
    :return: None
    """
    print ("===========================================")
    print ("GENERATING MAPPING ANIMATION FRAMES...")
    mapping_process_file = open("Generated_Files/Internal/MappingProcess.txt", 'r')
    x_size = float(Config.Network_X_Size)
    y_size = float(Config.Network_Y_Size)
    line = mapping_process_file.readline()

    bound = int(log10(2 * Config.MaxNumberOfIterations)) + 1   # UpperBoundOnFileNumberDigits
    counter = 0
    while line != '':
        fig = plt.figure(figsize=(4*Config.Network_X_Size, 4*Config.Network_Y_Size), dpi=Config.FrameResolution)
        # initialize an empty list of cirlces
        mapped_pe_list = line.split(" ")
        for node in ag.nodes():
            location = AG_Functions.return_node_location(node)
            # print (node, location)
            if shm.node[node]['NodeHealth']:
                if Config.EnablePartitioning:
                    if node in Config.CriticalRegionNodes:
                        color = '#FF878B'
                    elif node in Config.GateToNonCritical:
                        color = '#928AFF'
                    elif node in Config.GateToCritical:
                        color = '#FFC29C'
                    else:
                        color = 'white'
                else:
                    color = 'white'
            else:   # node is broken
                color = '#7B747B'
            fig.gca().add_patch(patches.Rectangle((location[0]/x_size, location[1]/y_size),
                                width=0.15, height=0.15, facecolor=color,
                                edgecolor="black", linewidth=3, alpha=0.5))
            if str(node) in mapped_pe_list:
                tasks = [i for i, x in enumerate(mapped_pe_list) if x == str(node)]
                offset_x = 0
                offset_y = 0.02
                task_count = 0
                for task in tasks:
                    task_count += 1
                    offset_x += 0.03
                    if task_count == 5:
                        task_count = 1
                        offset_x = 0.03
                        offset_y += 0.03
                    random.seed(task)
                    r = random.randrange(0, 255)
                    g = random.randrange(0, 255)
                    b = random.randrange(0, 255)
                    color = '#%02X%02X%02X' % (r, g, b)
                    circle = plt.Circle((location[0]/x_size+offset_x, location[1]/y_size+offset_y), 0.01, fc=color)
                    if Config.FrameResolution >= 50:
                        plt.text(location[0]/x_size+offset_x, location[1]/y_size+offset_y-0.001, task)
                    plt.gca().add_patch(circle)
        fig.text(0.25, 0.02, "Iteration:" + str(counter), fontsize=35)
        plt.savefig("GraphDrawings/Mapping_Animation_Material/Mapping_Frame_"+str(counter).zfill(bound) + ".png",
                    dpi=Config.FrameResolution)
        plt.clf()
        plt.close(fig)
        counter += 1
        line = mapping_process_file.readline()
    mapping_process_file.close()
    print ("\033[35m* VIZ::\033[0mMAPPING ANIMATION FRAMES READY AT: GraphDrawings/Mapping_Animation_Material")
    return None
def mixed_critical_rg(network_size, routing_type, critical_nodes,
                      critical_rg_nodes, broken_links, turn_model, viz,
                      report):

    turns_health_2d_network = {
        "N2W": True,
        "N2E": True,
        "S2W": True,
        "S2E": True,
        "W2N": True,
        "W2S": True,
        "E2N": True,
        "E2S": True
    }

    Config.ag.topology = '2DMesh'
    Config.ag.x_size = network_size
    Config.ag.y_size = network_size
    Config.ag.z_size = 1
    Config.RotingType = routing_type

    ag = copy.deepcopy(AG_Functions.generate_ag())
    shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
    shmu.setup_noc_shm(ag, turns_health_2d_network, False)
    noc_rg = copy.deepcopy(
        Routing.generate_noc_route_graph(ag, shmu,
                                         turns_health_2d_network.keys(), False,
                                         False))
    copy_rg = copy.deepcopy(noc_rg)

    for node in critical_rg_nodes:
        if node not in noc_rg.nodes():
            raise ValueError(str(node) + " doesnt exist in noc_rg")

    for node in noc_rg.nodes():
        if node in critical_rg_nodes:
            noc_rg.node[node]["criticality"] = "H"
        else:
            noc_rg.node[node]["criticality"] = "L"

    edges_to_be_removed = []
    for edge in noc_rg.edges():
        if (int(edge[0][:-2]), int(edge[1][:-2])) in broken_links:
            edges_to_be_removed.append(edge)
        # removing edges that go from non-critical ports to ports used by critical ports
        if noc_rg.node[edge[0]]["criticality"] != noc_rg.node[
                edge[1]]["criticality"]:
            edges_to_be_removed.append(edge)
        else:
            if noc_rg.node[edge[0]]["criticality"] == "L":
                if edge[0][:-2] == edge[1][:-2]:
                    # remove the links that do not follow the turn model rules!
                    if str(edge[0][-2]) + "2" + str(
                            edge[1][-2]) not in turn_model:
                        if edge[0][-2] == "L" or edge[1][-2] == "L":
                            pass
                        elif edge[0][-2] == "E" and edge[1][-2] == "W":
                            pass
                        elif edge[0][-2] == "W" and edge[1][-2] == "E":
                            pass
                        elif edge[0][-2] == "S" and edge[1][-2] == "N":
                            pass
                        elif edge[0][-2] == "N" and edge[1][-2] == "S":
                            pass
                        else:
                            edges_to_be_removed.append(edge)

    for edge in edges_to_be_removed:
        noc_rg.remove_edge(edge[0], edge[1])
    if viz:
        noc_rg = copy.deepcopy(cleanup_routing_graph(ag, noc_rg))
        RoutingGraph_Reports.draw_rg(noc_rg)

    reachability_counter = 0
    connectivity_counter = 0
    print("deadlock freeness:", check_deadlock_freeness(noc_rg))
    for node_1 in ag.nodes():
        for node_2 in ag.nodes():
            if node_1 != node_2:
                if node_1 in critical_nodes or node_2 in critical_nodes:
                    pass
                else:

                    if is_destination_reachable_from_source(
                            noc_rg, node_1, node_2):
                        connectivity_counter += 1
                        if routing_type == "MinimalPath":
                            paths = return_minimal_paths(
                                noc_rg, node_1, node_2)
                            all_minimal_paths = return_minimal_paths(
                                copy_rg, node_1, node_2)
                            valid_path = True
                            for path in paths:
                                for node in path:
                                    successors = noc_rg.successors(node)
                                    if str(node_2) + str('L') + str(
                                            'O') in successors:
                                        #print(node_2, successors)
                                        break
                                    else:
                                        for successor in successors:
                                            valid_successor = False

                                            for path_1 in all_minimal_paths:
                                                if successor in path_1:
                                                    valid_successor = True
                                                    break
                                            if valid_successor:
                                                sucessor_paths = []
                                                max_hop_count = manhattan_distance(
                                                    int(successor[:-2]),
                                                    node_2)
                                                if has_path(
                                                        noc_rg, successor,
                                                        str(node_2) +
                                                        str('L') + str('O')):
                                                    all_paths_from_sucessor = list(
                                                        all_shortest_paths(
                                                            noc_rg, successor,
                                                            str(node_2) +
                                                            str('L') +
                                                            str('O')))
                                                    for Path in all_paths_from_sucessor:
                                                        if (
                                                                len(Path) - 2
                                                        ) / 2 <= max_hop_count:
                                                            sucessor_paths.append(
                                                                Path)
                                                if len(sucessor_paths) == 0:
                                                    valid_path = False
                                                    #print(path, node, node_2, successor, "FALSE")
                                                    break
                                                else:
                                                    pass
                                                    #print(path, node, node_2, successor, "TRUE")

                            if valid_path:
                                reachability_counter += 1
                            else:
                                if report:
                                    print(node_1, "can not reach  ", node_2)
                        else:
                            reachability_counter += 1
                    else:
                        if report:
                            print(node_1, "can not connect", node_2)
    print(
        "average connectivity for non-critical nodes:",
        float(connectivity_counter) / (len(ag.nodes()) - len(critical_nodes)))
    print(
        "average reachability for non-critical nodes:",
        float(reachability_counter) / (len(ag.nodes()) - len(critical_nodes)))
    return float(connectivity_counter) / (len(ag.nodes()) -
                                          len(critical_nodes)), noc_rg
예제 #29
0
def draw_temp_distribution(shm):
    """

    :param shm: System Health Map
    :return:
    """
    print("===========================================")
    print("GENERATING TEMPERATURE DISTRIBUTIONS VISUALIZATION...")
    fig_util = plt.figure(figsize=(4 * Config.ag.x_size, 4 * Config.ag.y_size))
    max_temp = 0
    for node in shm.nodes():
        max_temp = max(shm.node[node]['NodeTemp'], max_temp)

    for node in shm.nodes():
        location = AG_Functions.return_node_location(node)
        x_size = float(Config.ag.x_size)
        y_size = float(Config.ag.y_size)
        z_size = float(Config.ag.y_size)

        x_offset = location[2] / (z_size * x_size)
        y_offset = location[2] / (z_size * y_size)

        temp = 255 * (float(shm.node[node]['RouterTemp']) / Config.MaxTemp)
        if shm.node[node]['NodeHealth']:
            color = '#%02X%02X%02X' % (temp, 0, 255 - temp)
        else:  # node is broken
            color = '#7B747B'
        fig_util.gca().add_patch(
            patches.Rectangle((location[0] / x_size + x_offset,
                               location[1] / y_size + y_offset),
                              width=0.08,
                              height=0.08,
                              facecolor=color,
                              edgecolor="black",
                              linewidth=3,
                              zorder=z_size - location[2]))

        temp = 255 * (float(shm.node[node]['NodeTemp']) / Config.MaxTemp)

        if shm.node[node]['NodeHealth']:
            color = '#%02X%02X%02X' % (temp, 0, 255 - temp)
        else:  # node is broken
            color = '#7B747B'
        fig_util.gca().add_patch(
            patches.Rectangle((location[0] / x_size + x_offset + 0.05,
                               location[1] / y_size + y_offset),
                              width=0.03,
                              height=0.03,
                              facecolor=color,
                              edgecolor="black",
                              linewidth=3,
                              zorder=z_size - location[2]))

    fig_util.text(0.25,
                  0.03,
                  'Distribution of temperature of network nodes',
                  fontsize=15)
    fig_util.savefig("GraphDrawings/Temp_Distribute.png", dpi=100)
    fig_util.clf()
    plt.close(fig_util)
    print("\033[35m* VIZ::\033[0mMAPPING UTILIZATION DISTRIBUTION DRAWING " +
          "CREATED AT: GraphDrawings/Temp_Distribute.png")
    return None
def mapping_cost_function(tg, ag, shm, report, initial_mapping_string=None):
    """
    Calculates the Costs of a mapping based on the configurations of Config file
    :param tg: Task Graph
    :param ag: Architecture Graph
    :param shm: System Health Map
    :param report: If true prints cost function report to Command-line
    :param initial_mapping_string: Initial mapping string used for calculating distance from the current mapping
    :return: cost of the mapping
    """

    node_makespan_list = []
    link_makespan_list = []
    for node in ag.nodes():
        if shm.node[node]['NodeHealth'] and (not ag.node[node]['PE'].dark):
            node_makespan_list.append(Scheduling_Functions_Nodes.find_last_allocated_time_on_node(ag, node,
                                                                                                  logging=None))
    for link in ag.edges():
        if shm.edge[link[0]][link[1]]['LinkHealth']:
            link_makespan_list.append(Scheduling_Functions_Links.find_last_allocated_time_on_link(ag, link,
                                                                                                  logging=None))
    node_makspan_sd = statistics.stdev(node_makespan_list)
    node_makspan_max = max(node_makespan_list)
    link_makspan_sd = statistics.stdev(link_makespan_list)
    link_makspan_max = max(link_makespan_list)

    node_util_list = []
    link_util_list = []
    for node in ag.nodes():
        if shm.node[node]['NodeHealth'] and (not ag.node[node]['PE'].dark):
            node_util_list.append(AG_Functions.return_node_util(tg, ag, node))
    for link in ag.edges():
            link_util_list.append(AG_Functions.return_link_util(tg,ag,link))
    node_util_sd = statistics.stdev(node_util_list)
    link_util_sd = statistics.stdev(link_util_list)

    if Config.Mapping_CostFunctionType == 'SD':
        cost = node_makspan_sd + link_makspan_sd
    elif Config.Mapping_CostFunctionType == 'Node_SD':
        cost = node_makspan_sd
    elif Config.Mapping_CostFunctionType == 'Link_Util_SD':
        cost = link_util_sd
    elif Config.Mapping_CostFunctionType == 'Node_Util_SD':
        cost = node_util_sd
    elif Config.Mapping_CostFunctionType == 'Util_SD':
        cost = node_util_sd + link_util_sd
    elif Config.Mapping_CostFunctionType == 'Link_SD':
        cost = link_makspan_sd
    elif Config.Mapping_CostFunctionType == 'SD+MAX':
        cost = node_makspan_max + node_makspan_sd + link_makspan_sd + link_makspan_max
    elif Config.Mapping_CostFunctionType == 'MAX':
        cost = node_makspan_max + link_makspan_max
    elif Config.Mapping_CostFunctionType == 'CONSTANT':
        cost = 1
    else:
        raise ValueError("Mapping_CostFunctionType is not valid")

    distance = None
    if initial_mapping_string is not None:
        distance = hamming_distance_of_mapping(initial_mapping_string, mapping_into_string(tg))
        cost += 20* distance
    if report:
        print ("===========================================")
        print ("      REPORTING MAPPING COST")
        print ("===========================================")
        print ("NODES MAKE SPAN MAX:"+str(node_makspan_max))
        print ("NODES MAKE SPAN STANDARD DEVIATION:"+str(node_makspan_sd))
        print ("LINKS MAKE SPAN MAX:"+str(link_makspan_max))
        print ("LINKS MAKE SPAN STANDARD DEVIATION:"+str(link_makspan_sd))
        if distance is not None:
            print ("DISTANCE FROM STARTING SOLUTION:"+str(distance))
        print ("MAPPING SCHEDULING COST:"+str(cost))

    if cost == 0:
            raise ValueError("Mapping with 0 cost... Something is wrong here...")
    if check_if_all_deadlines_are_met(tg, ag):
        return cost
    else:
        return cost+1000
예제 #31
0
def mapping_cost_function(tg, ag, shm, report, initial_mapping_string=None):
    """
    Calculates the Costs of a mapping based on the configurations of Config file
    :param tg: Task Graph
    :param ag: Architecture Graph
    :param shm: System Health Map
    :param report: If true prints cost function report to Command-line
    :param initial_mapping_string: Initial mapping string used for calculating distance from the current mapping
    :return: cost of the mapping
    """

    node_makespan_list = []
    link_makespan_list = []
    for node in ag.nodes():
        if shm.node[node]['NodeHealth'] and (not ag.node[node]['PE'].dark):
            node_makespan_list.append(
                Scheduling_Functions_Nodes.find_last_allocated_time_on_node(
                    ag, node, logging=None))
    for link in ag.edges():
        if shm.edges[link]['LinkHealth']:
            link_makespan_list.append(
                Scheduling_Functions_Links.find_last_allocated_time_on_link(
                    ag, link, logging=None))
    node_makspan_sd = statistics.stdev(node_makespan_list)
    node_makspan_max = max(node_makespan_list)
    link_makspan_sd = statistics.stdev(link_makespan_list)
    link_makspan_max = max(link_makespan_list)

    node_util_list = []
    link_util_list = []
    for node in ag.nodes():
        if shm.node[node]['NodeHealth'] and (not ag.node[node]['PE'].dark):
            node_util_list.append(AG_Functions.return_node_util(tg, ag, node))
    for link in ag.edges():
        link_util_list.append(AG_Functions.return_link_util(tg, ag, link))
    node_util_sd = statistics.stdev(node_util_list)
    link_util_sd = statistics.stdev(link_util_list)

    if Config.Mapping_CostFunctionType == 'SD':
        cost = node_makspan_sd + link_makspan_sd
    elif Config.Mapping_CostFunctionType == 'Node_SD':
        cost = node_makspan_sd
    elif Config.Mapping_CostFunctionType == 'Link_Util_SD':
        cost = link_util_sd
    elif Config.Mapping_CostFunctionType == 'Node_Util_SD':
        cost = node_util_sd
    elif Config.Mapping_CostFunctionType == 'Util_SD':
        cost = node_util_sd + link_util_sd
    elif Config.Mapping_CostFunctionType == 'Link_SD':
        cost = link_makspan_sd
    elif Config.Mapping_CostFunctionType == 'SD+MAX':
        cost = node_makspan_max + node_makspan_sd + link_makspan_sd + link_makspan_max
    elif Config.Mapping_CostFunctionType == 'MAX':
        cost = node_makspan_max + link_makspan_max
    elif Config.Mapping_CostFunctionType == 'CONSTANT':
        cost = 1
    else:
        raise ValueError("Mapping_CostFunctionType is not valid")

    distance = None
    if initial_mapping_string is not None:
        distance = hamming_distance_of_mapping(initial_mapping_string,
                                               mapping_into_string(tg))
        cost += 20 * distance
    if report:
        print("===========================================")
        print("      REPORTING MAPPING COST")
        print("===========================================")
        print("NODES MAKE SPAN MAX:" + str(node_makspan_max))
        print("NODES MAKE SPAN STANDARD DEVIATION:" + str(node_makspan_sd))
        print("LINKS MAKE SPAN MAX:" + str(link_makspan_max))
        print("LINKS MAKE SPAN STANDARD DEVIATION:" + str(link_makspan_sd))
        if distance is not None:
            print("DISTANCE FROM STARTING SOLUTION:" + str(distance))
        print("MAPPING SCHEDULING COST:" + str(cost))

    if cost == 0:
        raise ValueError("Mapping with 0 cost... Something is wrong here...")
    if check_if_all_deadlines_are_met(tg, ag):
        return cost
    else:
        return cost + 1000
예제 #32
0
def odd_even_fault_tolerance_metric(network_size, routing_type):

    turns_health_2d_network = {"N2W": False, "N2E": False, "S2W": False, "S2E": False,
                               "W2N": False, "W2S": False, "E2N": False, "E2S": False}
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = network_size
    Config.ag.y_size = network_size
    Config.ag.z_size = 1
    Config.RotingType = routing_type

    all_odd_evens_file = open('Generated_Files/Turn_Model_Eval/'+str(network_size)+"x"+str(network_size)+
                              '_OE_metric_'+Config.RotingType+'.txt', 'w')
    all_odd_evens_file.write("TOPOLOGY::"+str(Config.ag.topology)+"\n")
    all_odd_evens_file.write("X SIZE:"+str(Config.ag.x_size)+"\n")
    all_odd_evens_file.write("Y SIZE:"+str(Config.ag.y_size)+"\n")
    all_odd_evens_file.write("Z SIZE:"+str(Config.ag.z_size)+"\n")
    ag = copy.deepcopy(AG_Functions.generate_ag())
    shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
    turns_health = copy.deepcopy(turns_health_2d_network)
    shmu.setup_noc_shm(ag, turns_health, False)
    noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, [], False,  False))

    classes_of_doa_ratio = []
    turn_model_class_dict = {}
    tm_counter = 0

    """
    selected_turn_models = []
    for tm in all_odd_even_list:
        if len(tm[0])+len(tm[1]) == 11 or len(tm[0])+len(tm[1]) == 12:
            selected_turn_models.append(all_odd_even_list.index(tm))
    """
    #selected_turn_models = [677, 678, 697, 699, 717, 718, 737, 739, 757, 759, 778, 779, 797, 799, 818, 819,
    #                        679, 698, 719, 738, 758, 777, 798, 817]

    for turn_model in all_odd_even_list:
    #for item in selected_turn_models:
        # print item
        # turn_model = all_odd_even_list[item]

        sys.stdout.write("\rnumber of processed turn models: %i " % tm_counter)
        sys.stdout.flush()
        tm_counter += 1
        link_dict = {}
        turn_model_index = all_odd_even_list.index(turn_model)
        turn_model_odd = turn_model[0]
        turn_model_even = turn_model[1]

        for node in ag.nodes():
                node_x, node_y, node_z = AG_Functions.return_node_location(node)
                if node_x % 2 == 1:
                    for turn in turn_model_odd:
                        shmu.restore_broken_turn(node, turn, False)
                        from_port = str(node)+str(turn[0])+"I"
                        to_port = str(node)+str(turn[2])+"O"
                        Routing.update_noc_route_graph(noc_rg, from_port, to_port, 'ADD')
                else:
                    for turn in turn_model_even:
                        shmu.restore_broken_turn(node, turn, False)
                        from_port = str(node)+str(turn[0])+"I"
                        to_port = str(node)+str(turn[2])+"O"
                        Routing.update_noc_route_graph(noc_rg, from_port, to_port, 'ADD')

        number_of_pairs = len(ag.nodes())*(len(ag.nodes())-1)

        all_paths_in_graph = []
        for source_node in ag.nodes():
                for destination_node in ag.nodes():
                    if source_node != destination_node:
                        if is_destination_reachable_from_source(noc_rg, source_node, destination_node):
                            # print source_node, "--->", destination_node
                            if Config.RotingType == 'MinimalPath':
                                shortest_paths = list(all_shortest_paths(noc_rg, str(source_node)+str('L')+str('I'),
                                                                         str(destination_node)+str('L')+str('O')))
                                paths = []
                                for path in shortest_paths:
                                    minimal_hop_count = manhattan_distance(source_node, destination_node)
                                    if (len(path)/2)-1 <= minimal_hop_count:
                                        paths.append(path)
                                        all_paths_in_graph.append(path)
                            else:
                                paths = list(all_simple_paths(noc_rg, str(source_node)+str('L')+str('I'),
                                                              str(destination_node)+str('L')+str('O')))
                                all_paths_in_graph += paths
                            link_dict = find_similarity_in_paths(link_dict, paths)

        metric = 0
        for item in link_dict.keys():
            metric += link_dict[item]

        if Config.RotingType == 'MinimalPath':
            doa = degree_of_adaptiveness(ag, noc_rg, False)/float(number_of_pairs)
            #metric = doa/(float(metric)/len(ag.edges()))
            metric = 1/(float(metric)/len(ag.edges()))
            metric = float("{:3.3f}".format(metric))
            # print "Turn Model ", '%5s' %turn_model_index, "\tdoa:", "{:3.3f}".format(doa),
            #       "\tmetric:", "{:3.3f}".format(metric)
        else:
            doa_ex = extended_degree_of_adaptiveness(ag, noc_rg, False)/float(number_of_pairs)
            #metric = doa_ex/(float(metric)/len(ag.edges()))
            metric = 1/(float(metric)/len(ag.edges()))
            metric = float("{:3.3f}".format(metric))
            # print "Turn Model ", '%5s' %turn_model_index, "\tdoa:", "{:3.3f}".format(doa_ex),
            #       "\tmetric:", "{:3.3f}".format(metric)

        if metric not in classes_of_doa_ratio:
            classes_of_doa_ratio.append(metric)
        if metric in turn_model_class_dict.keys():
            turn_model_class_dict[metric].append(turn_model_index)
        else:
            turn_model_class_dict[metric] = [turn_model_index]

        # return SHMU and RG back to default
        for node in ag.nodes():
                node_x, node_y, node_z = AG_Functions.return_node_location(node)
                if node_x % 2 == 1:
                    for turn in turn_model_odd:
                        shmu.break_turn(node, turn, False)
                        from_port = str(node)+str(turn[0])+"I"
                        to_port = str(node)+str(turn[2])+"O"
                        Routing.update_noc_route_graph(noc_rg, from_port, to_port, 'REMOVE')
                else:
                    for turn in turn_model_even:
                        shmu.break_turn(node, turn, False)
                        from_port = str(node)+str(turn[0])+"I"
                        to_port = str(node)+str(turn[2])+"O"
                        Routing.update_noc_route_graph(noc_rg, from_port, to_port, 'REMOVE')

    all_odd_evens_file.write("classes of metric"+str(classes_of_doa_ratio)+"\n")
    all_odd_evens_file.write("----------"*3+"\n")
    all_odd_evens_file.write("turn models of class"+"\n")
    # print "classes of metric", classes_of_doa_ratio
    for item in sorted(turn_model_class_dict.keys()):
        # print item, turn_model_class_dict[item]
        all_odd_evens_file.write(str(item)+" "+str(turn_model_class_dict[item])+"\n")

    all_odd_evens_file.write("----------"*3+"\n")
    all_odd_evens_file.write("distribution of turn models"+"\n")
    for item in sorted(turn_model_class_dict.keys()):
        temp_list = []
        for tm in turn_model_class_dict[item]:
            turn_model = all_odd_even_list[tm]
            number_of_turns = len(turn_model[0])+len(turn_model[1])
            temp_list.append(number_of_turns)
        # print item, temp_list.count(8), temp_list.count(9), temp_list.count(10),
        # temp_list.count(11), temp_list.count(12)
        all_odd_evens_file.write(str(item)+" "+str(temp_list.count(8))+" "+str(temp_list.count(9))+" " +
                                 str(temp_list.count(10))+" "+str(temp_list.count(11))+" " +
                                 str(temp_list.count(12))+"\n")
    all_odd_evens_file.close()
    return  turn_model_class_dict
예제 #33
0
def report_odd_even_turn_model_router_fault_tolerance(viz, routing_type,
                                                      combination,
                                                      network_size,
                                                      ft_dictionary,
                                                      selected_turn_models):
    """
    generates 2D architecture graph with all combinations C(len(ag.nodes), combination)
    of links and writes the average connectivity metric in a file.
    :param viz: if true, generates the visualization files
    :param routing_type: can be "minimal" or "nonminimal"
    :param combination: number of links to be present in the network
    :return: None
    """

    turns_health_2d_network = {
        "N2W": False,
        "N2E": False,
        "S2W": False,
        "S2E": False,
        "W2N": False,
        "W2S": False,
        "E2N": False,
        "E2S": False
    }
    tm_counter = 0
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = network_size
    Config.ag.y_size = network_size
    Config.ag.z_size = 1

    Config.RotingType = routing_type

    ag = copy.deepcopy(AG_Functions.generate_ag(report=False))
    router_list = list(itertools.combinations(ag.nodes(), combination))

    for turn_id in selected_turn_models:
        counter = 0
        metric_sum = 0
        turn_model = all_odd_even_list[turn_id]

        turn_model_odd = turn_model[0]
        turn_model_even = turn_model[1]

        file_name = str(tm_counter) + '_eval'
        turn_model_eval_file = open(
            'Generated_Files/Turn_Model_Eval/' + file_name + '.txt', 'a+')
        if viz:
            file_name_viz = str(tm_counter) + '_eval_' + str(
                len(ag.nodes()) - counter)
            turn_model_eval_viz_file = open(
                'Generated_Files/Internal/odd_even' + file_name_viz + '.txt',
                'w')
        else:
            turn_model_eval_viz_file = None

        for sub_router_list in router_list:
            turns_health = copy.deepcopy(turns_health_2d_network)
            shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
            shmu.setup_noc_shm(ag, turns_health, False)
            noc_rg = copy.deepcopy(
                Routing.generate_noc_route_graph(ag, shmu, [], False, False))

            for node in ag.nodes():
                if node not in sub_router_list:
                    node_x, node_y, node_z = AG_Functions.return_node_location(
                        node)
                    if node_x % 2 == 1:
                        for turn in turn_model_odd:
                            shmu.restore_broken_turn(node, turn, False)
                            from_port = str(node) + str(turn[0]) + "I"
                            to_port = str(node) + str(turn[2]) + "O"
                            Routing.update_noc_route_graph(
                                noc_rg, from_port, to_port, 'ADD')
                    else:
                        for turn in turn_model_even:
                            shmu.restore_broken_turn(node, turn, False)
                            from_port = str(node) + str(turn[0]) + "I"
                            to_port = str(node) + str(turn[2]) + "O"
                            Routing.update_noc_route_graph(
                                noc_rg, from_port, to_port, 'ADD')
                else:
                    for port_1 in ["N", "S", "E", "W", "L"]:
                        for port_2 in ["N", "S", "E", "W", "L"]:
                            if port_1 != port_2:
                                from_port = str(node) + str(port_1) + "I"
                                to_port = str(node) + str(port_2) + "O"
                                if (from_port, to_port) in noc_rg.edges():
                                    Routing.update_noc_route_graph(
                                        noc_rg, from_port, to_port, 'REMOVE')

            connectivity_metric = reachability_metric(ag, noc_rg, False)
            counter += 1
            metric_sum += connectivity_metric
            if viz:
                turn_model_eval_viz_file.write(
                    str(float(metric_sum) / counter) + "\n")
            # print "#:"+str(counter)+"\t\tC.M.:"+str(connectivity_metric)+"\t\t avg:", \
            #     float(metric_sum)/counter, "\t\tstd:", std

        shuffle(router_list)

        if counter > 0:
            avg_connectivity = float(metric_sum) / counter
        else:
            avg_connectivity = 0
        turn_model_eval_file.write(
            str(len(ag.nodes()) - combination) + "\t\t" +
            str(avg_connectivity) + "\n")
        if turn_id in ft_dictionary.keys():
            ft_dictionary[turn_id].append(avg_connectivity)
        else:
            ft_dictionary[turn_id] = [avg_connectivity]
        if viz:
            turn_model_eval_viz_file.close()
        turn_model_eval_file.close()
        sys.stdout.write("\rchecked TM: %i " % tm_counter +
                         "\t\t\tnumber of broken routers: %i " % combination)
        sys.stdout.flush()
        tm_counter += 1
    return ft_dictionary
def report_3d_turn_model_fault_tolerance(turn_model, viz, combination):
    """
    generates 3D architecture graph with all combinations C(len(ag.nodes), combination)
    of links and writes the average connectivity metric in a file.
    :param turn_model: list of allowed turns for generating the routing graph
    :param combination: number of links to be present in the network
    :param viz: if true, generates the visualization files
    :return: None
    """
    if combination == 108:
        raise ValueError("breaking 108 edges out of 108 edges is not possible your connectivity is 0!")

    Config.UsedTurnModel = copy.deepcopy(turn_model)
    Config.TurnsHealth = copy.deepcopy(Config.setup_turns_health())

    ag = copy.deepcopy(AG_Functions.generate_ag(report=False))

    turn_model_name = return_turn_model_name(Config.UsedTurnModel)

    file_name = str(turn_model_name)+'_eval'
    turn_model_eval_file = open('Generated_Files/Turn_Model_Eval/'+file_name+'.txt', 'a+')
    if viz:
        file_name_viz = str(turn_model_name)+'_eval_'+str(len(ag.edges())-combination)
        turn_model_eval_viz_file = open('Generated_Files/Internal/'+file_name_viz+'.txt', 'w')
    else:
        turn_model_eval_viz_file = None
    counter = 0
    metric_sum = 0

    list_of_avg = []
    number_of_combinations = comb(108, combination)
    while True:
        sub_ag = sample(ag.edges(), combination)
        shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
        shmu.setup_noc_shm(ag, copy.deepcopy(Config.TurnsHealth), False)
        for link in list(sub_ag):
            shmu.break_link(link, False)
        noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, Config.UsedTurnModel,
                                                                False,  False))
        connectivity_metric = reachability_metric(ag, noc_rg, False)
        counter += 1
        metric_sum += connectivity_metric
        # std = None
        list_of_avg.append(float(metric_sum)/counter)
        if len(list_of_avg) > 5000:
            list_of_avg.pop(0)
            std = stdev(list_of_avg)
            if std < 0.009:
                # turn_model_eval_file.write("STD of the last 5000 average samples is bellow 0.009\n")
                # turn_model_eval_file.write("Terminating the search!\n")
                del shmu
                del noc_rg
                break
        if viz:
            turn_model_eval_viz_file.write(str(float(metric_sum)/counter)+"\n")

        if counter >= number_of_combinations:
            del shmu
            del noc_rg
            break

        # print "#:"+str(counter)+"\t\tC.M.:"+str(connectivity_metric)+"\t\t avg:", \
        #    float(metric_sum)/counter, "\t\tstd:", std
        del shmu
        del noc_rg

    if counter > 0:
        avg_connectivity = float(metric_sum)/counter
    else:
        avg_connectivity = 0
    turn_model_eval_file.write(str(len(ag.edges())-combination)+"\t\t"+str(avg_connectivity)+"\n")
    turn_model_eval_file.close()
    if viz:
        turn_model_eval_viz_file.close()
    return None
예제 #35
0
def odd_even_fault_tolerance_metric(network_size, routing_type):

    turns_health_2d_network = {
        "N2W": False,
        "N2E": False,
        "S2W": False,
        "S2E": False,
        "W2N": False,
        "W2S": False,
        "E2N": False,
        "E2S": False
    }
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = network_size
    Config.ag.y_size = network_size
    Config.ag.z_size = 1
    Config.RotingType = routing_type

    all_odd_evens_file = open(
        'Generated_Files/Turn_Model_Eval/' + str(network_size) + "x" +
        str(network_size) + '_OE_metric_' + Config.RotingType + '.txt', 'w')
    all_odd_evens_file.write("TOPOLOGY::" + str(Config.ag.topology) + "\n")
    all_odd_evens_file.write("X SIZE:" + str(Config.ag.x_size) + "\n")
    all_odd_evens_file.write("Y SIZE:" + str(Config.ag.y_size) + "\n")
    all_odd_evens_file.write("Z SIZE:" + str(Config.ag.z_size) + "\n")
    ag = copy.deepcopy(AG_Functions.generate_ag())
    shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
    turns_health = copy.deepcopy(turns_health_2d_network)
    shmu.setup_noc_shm(ag, turns_health, False)
    noc_rg = copy.deepcopy(
        Routing.generate_noc_route_graph(ag, shmu, [], False, False))

    classes_of_doa_ratio = []
    turn_model_class_dict = {}
    tm_counter = 0
    """
    selected_turn_models = []
    for tm in all_odd_even_list:
        if len(tm[0])+len(tm[1]) == 11 or len(tm[0])+len(tm[1]) == 12:
            selected_turn_models.append(all_odd_even_list.index(tm))
    """
    #selected_turn_models = [677, 678, 697, 699, 717, 718, 737, 739, 757, 759, 778, 779, 797, 799, 818, 819,
    #                        679, 698, 719, 738, 758, 777, 798, 817]

    for turn_model in all_odd_even_list:
        #for item in selected_turn_models:
        # print item
        # turn_model = all_odd_even_list[item]

        sys.stdout.write("\rnumber of processed turn models: %i " % tm_counter)
        sys.stdout.flush()
        tm_counter += 1
        link_dict = {}
        turn_model_index = all_odd_even_list.index(turn_model)
        turn_model_odd = turn_model[0]
        turn_model_even = turn_model[1]

        for node in ag.nodes():
            node_x, node_y, node_z = AG_Functions.return_node_location(node)
            if node_x % 2 == 1:
                for turn in turn_model_odd:
                    shmu.restore_broken_turn(node, turn, False)
                    from_port = str(node) + str(turn[0]) + "I"
                    to_port = str(node) + str(turn[2]) + "O"
                    Routing.update_noc_route_graph(noc_rg, from_port, to_port,
                                                   'ADD')
            else:
                for turn in turn_model_even:
                    shmu.restore_broken_turn(node, turn, False)
                    from_port = str(node) + str(turn[0]) + "I"
                    to_port = str(node) + str(turn[2]) + "O"
                    Routing.update_noc_route_graph(noc_rg, from_port, to_port,
                                                   'ADD')

        number_of_pairs = len(ag.nodes()) * (len(ag.nodes()) - 1)

        all_paths_in_graph = []
        for source_node in ag.nodes():
            for destination_node in ag.nodes():
                if source_node != destination_node:
                    if is_destination_reachable_from_source(
                            noc_rg, source_node, destination_node):
                        # print source_node, "--->", destination_node
                        if Config.RotingType == 'MinimalPath':
                            shortest_paths = list(
                                all_shortest_paths(
                                    noc_rg,
                                    str(source_node) + str('L') + str('I'),
                                    str(destination_node) + str('L') +
                                    str('O')))
                            paths = []
                            for path in shortest_paths:
                                minimal_hop_count = manhattan_distance(
                                    source_node, destination_node)
                                if (len(path) / 2) - 1 <= minimal_hop_count:
                                    paths.append(path)
                                    all_paths_in_graph.append(path)
                        else:
                            paths = list(
                                all_simple_paths(
                                    noc_rg,
                                    str(source_node) + str('L') + str('I'),
                                    str(destination_node) + str('L') +
                                    str('O')))
                            all_paths_in_graph += paths
                        link_dict = find_similarity_in_paths(link_dict, paths)

        metric = 0
        for item in link_dict.keys():
            metric += link_dict[item]

        if Config.RotingType == 'MinimalPath':
            doa = degree_of_adaptiveness(ag, noc_rg,
                                         False) / float(number_of_pairs)
            #metric = doa/(float(metric)/len(ag.edges()))
            metric = 1 / (float(metric) / len(ag.edges()))
            metric = float("{:3.3f}".format(metric))
            # print "Turn Model ", '%5s' %turn_model_index, "\tdoa:", "{:3.3f}".format(doa),
            #       "\tmetric:", "{:3.3f}".format(metric)
        else:
            doa_ex = extended_degree_of_adaptiveness(
                ag, noc_rg, False) / float(number_of_pairs)
            #metric = doa_ex/(float(metric)/len(ag.edges()))
            metric = 1 / (float(metric) / len(ag.edges()))
            metric = float("{:3.3f}".format(metric))
            # print "Turn Model ", '%5s' %turn_model_index, "\tdoa:", "{:3.3f}".format(doa_ex),
            #       "\tmetric:", "{:3.3f}".format(metric)

        if metric not in classes_of_doa_ratio:
            classes_of_doa_ratio.append(metric)
        if metric in turn_model_class_dict.keys():
            turn_model_class_dict[metric].append(turn_model_index)
        else:
            turn_model_class_dict[metric] = [turn_model_index]

        # return SHMU and RG back to default
        for node in ag.nodes():
            node_x, node_y, node_z = AG_Functions.return_node_location(node)
            if node_x % 2 == 1:
                for turn in turn_model_odd:
                    shmu.break_turn(node, turn, False)
                    from_port = str(node) + str(turn[0]) + "I"
                    to_port = str(node) + str(turn[2]) + "O"
                    Routing.update_noc_route_graph(noc_rg, from_port, to_port,
                                                   'REMOVE')
            else:
                for turn in turn_model_even:
                    shmu.break_turn(node, turn, False)
                    from_port = str(node) + str(turn[0]) + "I"
                    to_port = str(node) + str(turn[2]) + "O"
                    Routing.update_noc_route_graph(noc_rg, from_port, to_port,
                                                   'REMOVE')

    all_odd_evens_file.write("classes of metric" + str(classes_of_doa_ratio) +
                             "\n")
    all_odd_evens_file.write("----------" * 3 + "\n")
    all_odd_evens_file.write("turn models of class" + "\n")
    # print "classes of metric", classes_of_doa_ratio
    for item in sorted(turn_model_class_dict.keys()):
        # print item, turn_model_class_dict[item]
        all_odd_evens_file.write(
            str(item) + " " + str(turn_model_class_dict[item]) + "\n")

    all_odd_evens_file.write("----------" * 3 + "\n")
    all_odd_evens_file.write("distribution of turn models" + "\n")
    for item in sorted(turn_model_class_dict.keys()):
        temp_list = []
        for tm in turn_model_class_dict[item]:
            turn_model = all_odd_even_list[tm]
            number_of_turns = len(turn_model[0]) + len(turn_model[1])
            temp_list.append(number_of_turns)
        # print item, temp_list.count(8), temp_list.count(9), temp_list.count(10),
        # temp_list.count(11), temp_list.count(12)
        all_odd_evens_file.write(
            str(item) + " " + str(temp_list.count(8)) + " " +
            str(temp_list.count(9)) + " " + str(temp_list.count(10)) + " " +
            str(temp_list.count(11)) + " " + str(temp_list.count(12)) + "\n")
    all_odd_evens_file.close()
    return turn_model_class_dict
def draw_mapping(tg, ag, shm, mapping_file_name):
    """
    This function draws the tasks on tiles of network. this would be very useful to check how our
    mapping optimization is acting...
    :param tg: Task Graph
    :param ag: Architecture Graph
    :param shm: System Health Map
    :param mapping_file_name: string containing name of the file in which the mapping would be generated
    :return: None
    """
    print ("===========================================")
    print ("GENERATING MAPPING VISUALIZATION...")
    fig = plt.figure(figsize=(4*Config.ag.x_size, 4*Config.ag.y_size))
    color_list = []
    position = {}
    x_size = float(Config.ag.x_size)
    y_size = float(Config.ag.y_size)
    z_size = float(Config.ag.z_size)
    node_size = 0.3
    step_size = node_size * 1.08
    distance = step_size * z_size * 1.2
    for node in ag.nodes():
        location = AG_Functions.return_node_location(node)
        if shm.node[node]['NodeHealth']:
            if not ag.node[node]['PE'].dark:
                if Config.EnablePartitioning:
                    if node in Config.CriticalRegionNodes:
                        color = '#FF878B'
                    elif node in Config.GateToNonCritical:
                        color = '#928AFF'
                    elif node in Config.GateToCritical:
                        color = '#FFC29C'
                    else:
                        color = 'white'
                else:
                    color = 'white'
            else:
                color = 'gray'
        else:   # node is broken
            color = '#7B747B'

        fig.gca().add_patch(patches.Rectangle(((distance*location[0])+location[2]*step_size,
                                               (distance*location[1])+location[2]*step_size),
                                              width=node_size, height=node_size, facecolor=color,
                                              linewidth=3, alpha=0.5))

        plt.text((distance*location[0])+location[2]*step_size,
                 (distance*location[1])+location[2]*step_size+node_size, str(node), fontsize=15)
        if location[0] < x_size-1:
            x = distance*(location[0])+location[2]*step_size+node_size
            y = distance*(location[1])+location[2]*step_size+(node_size/2)
            plt.plot([x, x+distance-node_size], [y, y], color='black', lw=3)
            # plt.gca().add_patch(patches.Arrow(x, y, 1.0/x_size - 0.1, 0, width=0.01))
        if location[1] < y_size-1:
            x = distance*(location[0])+location[2]*step_size+(node_size/2)
            y = distance*(location[1])+location[2]*step_size+node_size
            # plt.plot([y, y], [x, x+1.0/x_size - 0.1], color ='black')
            plt.plot([x, x], [y, y+distance-node_size], color='black', lw=3)

        number_of_task_in_row = 4
        offset_x = -(node_size/(2*number_of_task_in_row))
        offset_y = node_size / (number_of_task_in_row+1)
        task_count = 0
        for task in ag.node[node]['PE'].mapped_tasks:
            offset_x += node_size / number_of_task_in_row
            if task_count == number_of_task_in_row:
                task_count = 0
                offset_x = (node_size/(2*number_of_task_in_row))
                offset_y += node_size / number_of_task_in_row
            random.seed(task)
            r = random.randrange(0, 255)
            g = random.randrange(0, 255)
            b = random.randrange(0, 255)
            color = '#%02X%02X%02X' % (r, g, b)
            color_list.append(color)
            position[task] = (distance*location[0]+location[2]*step_size+offset_x,
                              distance*location[1]+location[2]*step_size+offset_y)
            task_count += 1
    task_size = 800/Config.ag.z_size
    networkx.draw(tg, position, with_labels=True, node_size=task_size, node_color=color_list, width=0, alpha=0.5)
    fig.text(0.35, 0.1, 'Mapping visualization for network nodes', fontsize=15)

    plt.text(0, -node_size*2/3, 'X', fontsize=15)
    plt.text(-node_size*2/3, 0, 'Y', fontsize=15)
    plt.text(-node_size*2/3 + node_size/3, -node_size*2/3 + node_size/3, 'Z', fontsize=15)

    plt.gca().add_patch(patches.Arrow(-node_size*2/3, -node_size*2/3, node_size, 0, width=node_size/10))
    plt.gca().add_patch(patches.Arrow(-node_size*2/3, -node_size*2/3, node_size/3, node_size/3, width=node_size/10))
    plt.gca().add_patch(patches.Arrow(-node_size*2/3, -node_size*2/3, 0, node_size, width=node_size/10))

    fig.savefig("GraphDrawings/"+mapping_file_name+".png", bbox_inches='tight')
    plt.clf()
    plt.close(fig)
    print ("\033[35m* VIZ::\033[0mMAPPING DRAWING CREATED AT: GraphDrawings/"+mapping_file_name+".png")
    return None
예제 #37
0
def NMap(tg, ag, NoCRG, CriticalRG, NonCriticalRG, SHM, logging):
    """
    Performs NMap Mapping algorithm
    :param tg: Task Graph
    :param AG: Architecture Graph
    :param NoCRG: NoC Routing Graph
    :param CriticalRG: NoC Routing Graph for Critical Region
    :param NonCriticalRG: NoC Routing Graph for Non-Critical Region
    :param SHM: System Health Map
    :param logging: logging File
    :return: TG and AG
    """
    print("===========================================")
    print("STARTING N-MAP MAPPING...\n")

    if len(tg.nodes()) > len(ag.nodes()):
        raise ValueError(
            "Number of tasks should be smaller or equal to number of PEs")

    mapped_tasks = []
    unmapped_tasks = copy.deepcopy(tg.nodes())
    allocated_nodes = []
    unallocated_nodes = copy.deepcopy(ag.nodes())

    # remove all broken nodes from unallocated_nodes list
    for node in unallocated_nodes:
        if not SHM.node[node]['NodeHealth']:
            unallocated_nodes.remove(node)
            print("REMOVED BROKEN NODE " + str(node) +
                  " FROM UN-ALLOCATED NODES")

    print("------------------")
    print("STEP 1:")
    # step 1: find the task with highest weighted communication volume
    tasks_com_dict = TG_Functions.tasks_communication_weight(tg)
    sorted_tasks_com = sorted(tasks_com_dict,
                              key=tasks_com_dict.get,
                              reverse=True)
    print("\t SORTED TASKS BY COMMUNICATION WEIGHT:\n" + "\t " +
          str(sorted_tasks_com))
    print("\t -------------")
    chosen_task = sorted_tasks_com[0]
    print("\t CHOSEN TASK: " + str(chosen_task))
    mapped_tasks.append(chosen_task)
    print("\t ADDED TASK " + str(chosen_task) + "TO MAPPED TASKS LIST")
    unmapped_tasks.remove(chosen_task)
    print("\t REMOVED TASK " + str(chosen_task) + "FROM UN-MAPPED TASKS LIST")

    print("------------------")
    print("STEP 2:")
    node_neighbors_dict = AG_Functions.node_neighbors(ag, SHM)
    sorted_node_neighbors = sorted(node_neighbors_dict,
                                   key=node_neighbors_dict.get,
                                   reverse=True)
    max_neighbors_node = AG_Functions.max_node_neighbors(
        node_neighbors_dict, sorted_node_neighbors)
    print("\t SORTED NODES BY NUMBER OF NEIGHBOURS:\n" + "\t " +
          str(sorted_node_neighbors))
    print("\t -------------")
    print("\t NODES WITH MAX NEIGHBOURS:\t" + str(max_neighbors_node))
    chosen_node = random.choice(max_neighbors_node)

    print("\t CHOSEN NODE: " + str(chosen_node))
    allocated_nodes.append(chosen_node)
    print("\t ADDED NODE " + str(chosen_node) + " TO ALLOCATED NODES LIST")
    unallocated_nodes.remove(chosen_node)
    print("\t REMOVED NODE " + str(chosen_node) +
          " FROM UN-ALLOCATED NODES LIST")
    # Map Chosen Task on Chosen Node...
    if Mapping_Functions.map_task_to_node(tg, ag, SHM, NoCRG, CriticalRG,
                                          NonCriticalRG, chosen_task,
                                          chosen_node, logging):
        print("\t \033[32m* NOTE::\033[0mTASK " + str(chosen_task) +
              " MAPPED ON NODE " + str(chosen_node))
    else:
        raise ValueError("Mapping task on node failed...")

    print("------------------")
    print("STEP 3:")
    while len(unmapped_tasks) > 0:
        print("\033[33m==>\033[0m  UN-MAPPED TASKS #: " +
              str(len(unmapped_tasks)))
        print("\t -------------")
        print("\t STEP 3.1:")
        # find the unmapped task which communicates most with mapped_tasks
        max_com = 0
        unmapped_tasks_com = {}
        tasks_with_max_com_to_mapped = []
        for Task in unmapped_tasks:
            task_weight = 0
            for mapped_task in mapped_tasks:
                if (Task, mapped_task) in tg.edges():
                    task_weight += tg.edge[Task][mapped_task]["ComWeight"]
                if (mapped_task, Task) in tg.edges():
                    task_weight += tg.edge[mapped_task][Task]["ComWeight"]
            unmapped_tasks_com[Task] = task_weight
            if max_com < task_weight:
                max_com = task_weight
                tasks_with_max_com_to_mapped = [Task]
            elif max_com == task_weight:
                tasks_with_max_com_to_mapped.append(Task)
        print("\t MAX COMMUNICATION WITH THE MAPPED TASKS: " + str(max_com))
        print("\t TASK(S) WITH MAX COMMUNICATION TO MAPPED TASKS: " +
              str(tasks_with_max_com_to_mapped))
        if len(tasks_with_max_com_to_mapped) > 1:
            # multiple tasks with same comm to mapped
            # Find the one that communicate most with Un-mapped takss...
            candid_task_with_max_com_to_unmapped = []
            max_com = 0
            for CandidateTask in tasks_with_max_com_to_mapped:
                task_weight = 0
                for unmapped_task in unmapped_tasks:
                    if (Task, unmapped_task) in tg.edges():
                        task_weight += tg.edge[Task][unmapped_task][
                            "ComWeight"]
                    if (unmapped_task, Task) in tg.edges():
                        task_weight += tg.edge[unmapped_task][Task][
                            "ComWeight"]
                if task_weight > max_com:
                    candid_task_with_max_com_to_unmapped = [CandidateTask]
                elif task_weight == max_com:
                    candid_task_with_max_com_to_unmapped.append(CandidateTask)
            print(
                "\t CANDIDATE TASK(S) THAT COMMUNICATE MOST WITH UN_MAPPED: " +
                str(candid_task_with_max_com_to_unmapped))
            if len(candid_task_with_max_com_to_unmapped) > 1:
                # if multiple tasks with the same com to unmmaped also,
                # choose randomly
                chosen_task = random.choice(
                    candid_task_with_max_com_to_unmapped)
            else:
                chosen_task = candid_task_with_max_com_to_unmapped[0]
        else:
            chosen_task = tasks_with_max_com_to_mapped[0]
        print("\t CHOSEN TASK: " + str(chosen_task))

        # Find the unallocated tile with lowest communication cost to/from the allocated_tiles_set.
        print("\t -------------")
        print("\t STEP 3.2:")
        min_cost = float("inf")
        node_candidates = []
        for unallocated_node in unallocated_nodes:
            cost = 0
            reachable = True
            for mapped_task in mapped_tasks:
                com_weight = 0
                if (chosen_task, mapped_task) in tg.edges():
                    # print ("TASK CONNECTED TO MAPPED TASK:", mapped_task)
                    com_weight += tg.edge[chosen_task][mapped_task][
                        "ComWeight"]
                    destination_node = tg.node[mapped_task]['Node']
                    # here we check if this node is even reachable from the chosen node?
                    if Calculate_Reachability.IsDestReachableFromSource(
                            NoCRG, unallocated_node, destination_node):
                        manhatan_distance = AG_Functions.manhattan_distance(
                            unallocated_node, destination_node)
                        cost += manhatan_distance * com_weight
                    else:
                        reachable = False
                elif (mapped_task, chosen_task) in tg.edges():
                    # print ("TASK CONNECTED TO MAPPED TASK:", mapped_task)
                    com_weight += tg.edge[mapped_task][chosen_task][
                        "ComWeight"]
                    destination_node = tg.node[mapped_task]['Node']
                    # here we check if this node is even reachable from the chosen node?
                    if Calculate_Reachability.IsDestReachableFromSource(
                            NoCRG, destination_node, unallocated_node):
                        manhatan_distance = AG_Functions.manhattan_distance(
                            unallocated_node, destination_node)
                        cost += manhatan_distance * com_weight
                    else:
                        reachable = False
            if reachable:
                if cost < min_cost:
                    node_candidates = [unallocated_node]
                    min_cost = cost
                elif cost == min_cost:
                    node_candidates.append(unallocated_node)
            else:
                print("\t \033[33m* NOTE::\033[0m NODE " +
                      str(unallocated_node) + " CAN NOT REACH...")
                pass
        print("\t CANDIDATE NODES: " + str(node_candidates) + " MIN COST: " +
              str(min_cost))

        if len(node_candidates) == 0:
            raise ValueError("COULD NOT FIND A REACHABLE CANDIDATE NODE...")
        elif len(node_candidates) > 1:
            chosen_node = random.choice(node_candidates)
        elif len(node_candidates) == 1:
            chosen_node = node_candidates[0]
        else:
            # this means that the chosen task is not connected to any other task... so its cost is infinity
            chosen_node = random.choice(unallocated_nodes)

        mapped_tasks.append(chosen_task)
        print("\t ADDED TASK " + str(chosen_task) + " TO MAPPED TASKS LIST")
        unmapped_tasks.remove(chosen_task)
        print("\t REMOVED TASK " + str(chosen_task) +
              " FROM UN-MAPPED TASKS LIST")

        allocated_nodes.append(chosen_node)
        print("\t ADDED NODE " + str(chosen_node) + " TO ALLOCATED NODES LIST")
        unallocated_nodes.remove(chosen_node)
        print("\t REMOVED NODE " + str(chosen_node) +
              " FROM UN-ALLOCATED NODES LIST")

        if Mapping_Functions.map_task_to_node(tg, ag, SHM, NoCRG, CriticalRG,
                                              NonCriticalRG, chosen_task,
                                              chosen_node, logging):
            print("\t \033[32m* NOTE::\033[0mTASK " + str(chosen_task) +
                  " MAPPED ON NODE " + str(chosen_node))
        else:
            raise ValueError("Mapping task on node failed...")

    # Added by Behrad (Still under development)
    # Swapping phase
    print "-----------------------"
    print "PHASE ONE IS DONE... STARTING SWAP PROCESS..."
    for node_id_1 in range(0, len(ag.nodes()) - 1):
        for node_id_2 in range(node_id_1 + 1, len(ag.nodes()) - 1):
            pass
            # Save current mapping in an array
            # Also save the mapping's csomm_cost in a variable
            comm_cost = calculate_com_cost(tg)

            # Swap (node_id_1 , node_id_2)
            swap_nodes(tg, ag, SHM, NoCRG, CriticalRG, NonCriticalRG,
                       node_id_1, node_id_2, logging)
            # Check and calculate communication cost for all communication flows in the task graph
            #   (which is equal to the total number of edges in the application graph
            #   starting from the communication flow with the largest communication volume first
            comm_cost_new = calculate_com_cost(tg)
            # If comm_cost of current mapping is the same or bigger than the previous mapping, discard mapping
            #   Revert back to previous mapping with better comm_cost
            # Else
            #   Save new mapping as better mapping with less comm_cost
            if comm_cost_new < comm_cost:
                print "\033[32m* NOTE::\033[0m BETTER SOLUTION FOUND WITH COST:", comm_cost_new
            else:
                pass
                # print "Reverting to old solution"
                swap_nodes(tg, ag, SHM, NoCRG, CriticalRG, NonCriticalRG,
                           node_id_2, node_id_1, logging)
            # Reset the comm_cost after each swapping

    # End of Swapping phase
    print "SWAP PROCESS FINISHED..."
    Scheduler.schedule_all(tg, ag, SHM, True, False, logging)
    return tg, ag
def evaluate_doa_for_all_odd_even_turn_model_list(network_size):
    all_odd_evens_file = open('Generated_Files/Turn_Model_Lists/all_odd_evens_doa.txt', 'w')
    turns_health_2d_network = {"N2W": False, "N2E": False, "S2W": False, "S2E": False,
                               "W2N": False, "W2S": False, "E2N": False, "E2S": False}
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = network_size
    Config.ag.y_size = network_size
    Config.ag.z_size = 1
    ag = copy.deepcopy(AG_Functions.generate_ag())
    number_of_pairs = len(ag.nodes())*(len(ag.nodes())-1)

    turn_model_list = []
    for length in range(0, len(turns_health_2d_network.keys())+1):
        for item in list(itertools.combinations(turns_health_2d_network.keys(), length)):
            if len(item) > 0:
                turn_model_list.append(list(item))

    classes_of_doa = {}
    classes_of_doax = {}
    tm_counter = 0

    all_odd_evens_file.write("    #  |                  "+'%51s' % " "+" \t|")
    all_odd_evens_file.write(" DoA    |   DoAx | \tC-metric\n")
    all_odd_evens_file.write("-------|--------------------------------------------" +
                             "----------------------------|--------|--------|-------------"+"\n")
    for turn_model in all_odd_even_list:
        turn_model_odd = turn_model[0]
        turn_model_even = turn_model[1]

        turns_health = copy.deepcopy(turns_health_2d_network)
        shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
        shmu.setup_noc_shm(ag, turns_health, False)
        noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, [], False,  False))

        update_rg_odd_even(ag, turn_model_odd, turn_model_even, shmu, noc_rg)
        doa = degree_of_adaptiveness(ag, noc_rg, False)/float(number_of_pairs)
        doa_ex = extended_degree_of_adaptiveness(ag, noc_rg, False)/float(number_of_pairs)

        if round(doa, 2) not in classes_of_doa.keys():
            classes_of_doa[round(doa, 2)] = [tm_counter]
        else:
            classes_of_doa[round(doa, 2)].append(tm_counter)

        if round(doa_ex, 2) not in classes_of_doax.keys():
            classes_of_doax[round(doa_ex, 2)] = [tm_counter]
        else:
            classes_of_doax[round(doa_ex, 2)].append(tm_counter)

        all_odd_evens_file.write('%5s' % str(tm_counter)+"  | even turn model:"+'%53s' % str(turn_model_even)+"\t|")
        all_odd_evens_file.write("        |        |\n")
        all_odd_evens_file.write("       | odd turn model: "+'%53s' % str(turn_model_odd)+" \t|")

        all_odd_evens_file.write('%8s' % str(round(doa, 2)) + "|" + '%8s' % str(round(doa_ex, 2)) +
                                 "|\n")     # +'%8s' % str(round(connectivity_metric,2))+"\n")
        all_odd_evens_file.write("-------|--------------------------------------------" +
                                 "----------------------------|--------|--------|-------------"+"\n")
        tm_counter += 1
        sys.stdout.write("\rchecked TM: %i " % tm_counter)
        sys.stdout.flush()

    all_odd_evens_file.write("----------"*3+"\n")
    all_odd_evens_file.write("distribution of turn models"+"\n")
    for item in sorted(classes_of_doa.keys()):
        temp_list = []
        for tm in classes_of_doa[item]:
            turn_model = all_odd_even_list[tm]
            number_of_turns = len(turn_model[0])+len(turn_model[1])
            temp_list.append(number_of_turns)
        all_odd_evens_file.write(str(item)+" "+str(temp_list.count(8))+" "+str(temp_list.count(9))+" " +
                                 str(temp_list.count(10))+" "+str(temp_list.count(11))+" " +
                                 str(temp_list.count(12))+"\n")

    all_odd_evens_file.write("----------"*3+"\n")
    all_odd_evens_file.write("distribution of turn models"+"\n")
    for item in sorted(classes_of_doax.keys()):
        temp_list = []
        for tm in classes_of_doax[item]:
            turn_model = all_odd_even_list[tm]
            number_of_turns = len(turn_model[0])+len(turn_model[1])
            temp_list.append(number_of_turns)

        all_odd_evens_file.write(str(item)+" "+str(temp_list.count(8))+" "+str(temp_list.count(9))+" " +
                                 str(temp_list.count(10))+" "+str(temp_list.count(11))+" " +
                                 str(temp_list.count(12))+"\n")

    all_odd_evens_file.close()
    return classes_of_doa, classes_of_doax
예제 #39
0
def mixed_critical_rg(network_size, routing_type, critical_nodes, critical_rg_nodes, turn_model, viz, report):

    turns_health_2d_network = {"N2W": True, "N2E": True, "S2W": True, "S2E": True,
                               "W2N": True, "W2S": True, "E2N": True, "E2S": True}

    Config.ag.topology = '2DMesh'
    Config.ag.x_size = network_size
    Config.ag.y_size = network_size
    Config.ag.z_size = 1
    Config.RotingType = routing_type

    ag = copy.deepcopy(AG_Functions.generate_ag())
    shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
    shmu.setup_noc_shm(ag, turns_health_2d_network, False)
    noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, turns_health_2d_network.keys(), False,  False))
    copy_rg =copy.deepcopy(noc_rg)

    for node in critical_rg_nodes:
        if node not in noc_rg.nodes():
            raise ValueError(str(node)+" doesnt exist in noc_rg")

    for node in noc_rg.nodes():
        if node in critical_rg_nodes:
            noc_rg.node[node]["criticality"] = "H"
        else:
            noc_rg.node[node]["criticality"] = "L"

    edges_to_be_removed = []
    for edge in noc_rg.edges():
        if noc_rg.node[edge[0]]["criticality"] != noc_rg.node[edge[1]]["criticality"]:
            edges_to_be_removed.append(edge)
        else:
            if noc_rg.node[edge[0]]["criticality"] == "L":
                if edge[0][:-2] == edge[1][:-2]:
                    if str(edge[0][-2])+"2"+str(edge[1][-2]) not in turn_model:
                        if edge[0][-2] == "L" or  edge[1][-2] == "L":
                            pass
                        elif edge[0][-2] == "E" and edge[1][-2] == "W":
                            pass
                        elif edge[0][-2] == "W" and edge[1][-2] == "E":
                            pass
                        elif edge[0][-2] == "S" and edge[1][-2] == "N":
                            pass
                        elif edge[0][-2] == "N" and edge[1][-2] == "S":
                            pass
                        else:
                            edges_to_be_removed.append(edge)

    for edge in edges_to_be_removed:
        noc_rg.remove_edge(edge[0], edge[1])
    if viz:
        noc_rg = copy.deepcopy(cleanup_routing_graph(ag, noc_rg))
        RoutingGraph_Reports.draw_rg(noc_rg)

    reachability_counter = 0
    connectivity_counter = 0
    print "its deadlock free:", check_deadlock_freeness(noc_rg)
    for node_1 in ag.nodes():
        for node_2 in ag.nodes():
            if node_1 != node_2:
                if node_1 in critical_nodes or node_2 in critical_nodes:
                    pass
                else:

                    if is_destination_reachable_from_source(noc_rg, node_1, node_2):
                        connectivity_counter += 1
                        if routing_type == "MinimalPath":
                            paths = return_minimal_paths(noc_rg, node_1, node_2)
                            all_minimal_paths = return_minimal_paths(copy_rg, node_1, node_2)
                            valid_path = True
                            for path in paths:
                                for node in path:
                                    successors = noc_rg.successors(node)
                                    if str(node_2)+str('L')+str('O') in successors:
                                        #print node_2, successors
                                        break
                                    else:
                                        for successor in successors:
                                            valid_successor = False

                                            for path_1 in all_minimal_paths:
                                                if successor in path_1:
                                                    valid_successor = True
                                                    break
                                            if valid_successor:
                                                #print path, node, node_2, successor
                                                if not has_path(noc_rg, successor, str(node_2)+str('L')+str('O')):
                                                    valid_path = False
                                                    break
                            if valid_path:
                                reachability_counter += 1
                            else:
                                print node_1,"can not reach  ", node_2
                        else:
                            reachability_counter += 1
                    else:
                        if report:
                            print node_1,"can not connect", node_2
    print "average connectivity for non-critical nodes:", float(connectivity_counter)/(len(ag.nodes())-len(critical_nodes))
    print "average reachability for non-critical nodes:", float(reachability_counter)/(len(ag.nodes())-len(critical_nodes))
    return float(connectivity_counter)/(len(ag.nodes())-len(critical_nodes)), noc_rg
예제 #40
0
def draw_shm(shm, iteration=None):
    """

    :param shm: System Health Map
    :return:
    """
    print("===========================================")
    print("GENERATING SYSTEM HEALTH MAP DRAWING...")

    x_size = float(Config.ag.x_size)
    y_size = float(Config.ag.y_size)
    z_size = float(Config.ag.z_size)

    fig = plt.figure(figsize=(10 * x_size, 10 * y_size))
    if z_size == 1:
        plt.ylim([0, 1])
        plt.xlim([0, 1])
    else:
        plt.ylim([0, z_size])
        plt.xlim([0, z_size])

    for node in shm.nodes():
        location = AG_Functions.return_node_location(node)
        x = (location[0] / x_size) * z_size
        y = (location[1] / y_size) * z_size
        z = (location[2] / z_size)
        x_offset = z
        y_offset = z

        font_size = 35 / z_size
        plt.text(x + 0.155 + x_offset,
                 y + 0.055 + y_offset,
                 str(node),
                 fontsize=font_size)
        circle_router = plt.Circle((x + 0.1 + x_offset, y + 0.1 + y_offset),
                                   0.05,
                                   facecolor='w')
        plt.gca().add_patch(circle_router)
        if shm.node[node]['NodeHealth']:
            color = 'w'
        else:
            color = 'r'
        circle_node = plt.Circle((x + 0.14 + x_offset, y + 0.06 + y_offset),
                                 0.01,
                                 facecolor=color)
        plt.gca().add_patch(circle_node)

        for turn in shm.node[node]['TurnsHealth']:
            if shm.node[node]['TurnsHealth'][turn]:
                color = 'black'
            else:
                color = 'r'

            if turn == 'S2E':
                plt.gca().add_patch(
                    patches.Arrow(x + 0.11 + x_offset,
                                  y + 0.065 + y_offset,
                                  0.015,
                                  0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'E2S':
                plt.gca().add_patch(
                    patches.Arrow(x + 0.135 + x_offset,
                                  y + 0.08 + y_offset,
                                  -0.015,
                                  -0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'W2N':
                plt.gca().add_patch(
                    patches.Arrow(x + 0.065 + x_offset,
                                  y + 0.117 + y_offset,
                                  0.015,
                                  0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'N2W':
                plt.gca().add_patch(
                    patches.Arrow(x + 0.09 + x_offset,
                                  y + 0.132 + y_offset,
                                  -0.015,
                                  -0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'N2E':
                plt.gca().add_patch(
                    patches.Arrow(x + 0.12 + x_offset,
                                  y + 0.132 + y_offset,
                                  0.015,
                                  -0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'E2N':
                plt.gca().add_patch(
                    patches.Arrow(x + 0.125 + x_offset,
                                  y + 0.117 + y_offset,
                                  -0.015,
                                  0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'W2S':
                plt.gca().add_patch(
                    patches.Arrow(x + 0.075 + x_offset,
                                  y + 0.08 + y_offset,
                                  0.015,
                                  -0.015,
                                  width=0.01,
                                  color=color))
            elif turn == 'S2W':
                plt.gca().add_patch(
                    patches.Arrow(x + 0.080 + x_offset,
                                  y + 0.065 + y_offset,
                                  -0.015,
                                  0.015,
                                  width=0.01,
                                  color=color))

            if shm.node[node]['TurnsHealth'][turn]:
                color = 'black'
            else:
                color = 'r'

            if turn == 'N2U':
                circle_node = plt.Circle(
                    (x + 0.09 + x_offset, y + 0.142 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)

            elif turn == 'N2D':
                circle_node = plt.Circle(
                    (x + 0.11 + x_offset, y + 0.142 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle(
                    (x + 0.11 + x_offset, y + 0.142 + y_offset),
                    0.001,
                    facecolor='b')
                plt.gca().add_patch(circle_node)

            elif turn == 'S2U':
                circle_node = plt.Circle(
                    (x + 0.11 + x_offset, y + 0.057 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)

            elif turn == 'S2D':
                circle_node = plt.Circle(
                    (x + 0.09 + x_offset, y + 0.057 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle(
                    (x + 0.09 + x_offset, y + 0.057 + y_offset),
                    0.001,
                    facecolor='b')
                plt.gca().add_patch(circle_node)

            elif turn == 'E2U':
                circle_node = plt.Circle(
                    (x + 0.142 + x_offset, y + 0.11 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)

            elif turn == 'E2D':
                circle_node = plt.Circle(
                    (x + 0.142 + x_offset, y + 0.09 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle(
                    (x + 0.142 + x_offset, y + 0.09 + y_offset),
                    0.001,
                    facecolor='b')
                plt.gca().add_patch(circle_node)

            elif turn == 'W2U':
                circle_node = plt.Circle(
                    (x + 0.057 + x_offset, y + 0.09 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)

            elif turn == 'W2D':
                circle_node = plt.Circle(
                    (x + 0.057 + x_offset, y + 0.11 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle(
                    (x + 0.057 + x_offset, y + 0.11 + y_offset),
                    0.001,
                    facecolor='b')
                plt.gca().add_patch(circle_node)

            elif turn == 'U2N':
                circle_node = plt.Circle(
                    (x + 0.105 + x_offset, y + 0.111 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle(
                    (x + 0.105 + x_offset, y + 0.111 + y_offset),
                    0.001,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(
                    patches.Arrow(x + 0.105 + x_offset,
                                  y + 0.116 + y_offset,
                                  0,
                                  0.01,
                                  width=0.01,
                                  color=color))

            elif turn == 'U2S':
                circle_node = plt.Circle(
                    (x + 0.105 + x_offset, y + 0.086 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle(
                    (x + 0.105 + x_offset, y + 0.086 + y_offset),
                    0.001,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(
                    patches.Arrow(x + 0.105 + x_offset,
                                  y + 0.081 + y_offset,
                                  0,
                                  -0.01,
                                  width=0.01,
                                  color=color))

            elif turn == 'U2W':
                circle_node = plt.Circle(
                    (x + 0.085 + x_offset, y + 0.093 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle(
                    (x + 0.085 + x_offset, y + 0.093 + y_offset),
                    0.001,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(
                    patches.Arrow(x + 0.08 + x_offset,
                                  y + 0.093 + y_offset,
                                  -0.01,
                                  0,
                                  width=0.01,
                                  color=color))

            elif turn == 'U2E':
                circle_node = plt.Circle(
                    (x + 0.115 + x_offset, y + 0.093 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle(
                    (x + 0.115 + x_offset, y + 0.093 + y_offset),
                    0.001,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(
                    patches.Arrow(x + 0.12 + x_offset,
                                  y + 0.093 + y_offset,
                                  0.01,
                                  0,
                                  width=0.01,
                                  color=color))

            elif turn == 'D2N':
                circle_node = plt.Circle(
                    (x + 0.095 + x_offset, y + 0.111 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(
                    patches.Arrow(x + 0.095 + x_offset,
                                  y + 0.116 + y_offset,
                                  0,
                                  0.01,
                                  width=0.01,
                                  color=color))

            elif turn == 'D2S':
                circle_node = plt.Circle(
                    (x + 0.095 + x_offset, y + 0.086 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(
                    patches.Arrow(x + 0.095 + x_offset,
                                  y + 0.081 + y_offset,
                                  0,
                                  -0.01,
                                  width=0.01,
                                  color=color))

            elif turn == 'D2W':
                circle_node = plt.Circle(
                    (x + 0.085 + x_offset, y + 0.104 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(
                    patches.Arrow(x + 0.08 + x_offset,
                                  y + 0.104 + y_offset,
                                  -0.01,
                                  0,
                                  width=0.01,
                                  color=color))

            elif turn == 'D2E':
                circle_node = plt.Circle(
                    (x + 0.115 + x_offset, y + 0.104 + y_offset),
                    0.005,
                    edgecolor=color,
                    facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(
                    patches.Arrow(x + 0.12 + x_offset,
                                  y + 0.104 + y_offset,
                                  0.01,
                                  0,
                                  width=0.01,
                                  color=color))

    for link in shm.edges():
        if shm.edge[link[0]][link[1]]['LinkHealth']:
            color = 'black'
        else:
            color = 'r'
        source_loc = AG_Functions.return_node_location(link[0])
        destination_loc = AG_Functions.return_node_location(link[1])

        x = (source_loc[0] / x_size) * z_size
        y = (source_loc[1] / y_size) * z_size
        z = source_loc[2] / z_size
        x_offset = z
        y_offset = z

        dx = ((destination_loc[0] - source_loc[0]) / x_size)
        dy = ((destination_loc[1] - source_loc[1]) / y_size)
        dz = ((destination_loc[2] - source_loc[2]) / z_size)
        if dz == 0:
            if dx == 0:
                if dy > 0:
                    plt.gca().add_patch(
                        patches.Arrow(x + 0.11 + x_offset,
                                      y + 0.15 + y_offset,
                                      0,
                                      dy * z_size - 0.1,
                                      width=0.01,
                                      color=color))
                else:
                    plt.gca().add_patch(
                        patches.Arrow(x + 0.09 + x_offset,
                                      y + 0.05 + y_offset,
                                      0,
                                      dy * z_size + 0.1,
                                      width=0.01,
                                      color=color))

            elif dy == 0:
                if dx > 0:
                    plt.gca().add_patch(
                        patches.Arrow(x + 0.15 + x_offset,
                                      y + 0.11 + y_offset,
                                      dx * z_size - 0.1,
                                      0,
                                      width=0.01,
                                      color=color))
                else:
                    plt.gca().add_patch(
                        patches.Arrow(x + 0.05 + x_offset,
                                      y + 0.09 + y_offset,
                                      dx * z_size + 0.1,
                                      0,
                                      width=0.01,
                                      color=color))
            else:
                raise ValueError("Can not draw link", link)
        elif dz > 0:
            z_offset = 1.4 / z_size
            plt.gca().add_patch(
                patches.Arrow(x + 0.130 + x_offset,
                              y + 0.140 + y_offset,
                              dz * z_offset,
                              dz * z_offset,
                              width=0.01,
                              color=color))
        elif dz < 0:
            plt.gca().add_patch(
                patches.Arrow(x + 0.07 + x_offset,
                              y + 0.06 + y_offset,
                              dz * z_offset,
                              dz * z_offset,
                              width=0.01,
                              color=color))

    fig.text(0.25, 0.02, "System Health Map", fontsize=35)
    if iteration is None:
        plt.savefig("GraphDrawings/SHM.png", dpi=200)
    else:
        plt.savefig("GraphDrawings/SHM_" + str(iteration) + ".png", dpi=200)
    plt.clf()
    plt.close(fig)
    print(
        "\033[35m* VIZ::\033[0mSYSTEM HEALTH MAP DRAWING CREATED AT: GraphDrawings/SHM.png"
    )
    return None
def enumerate_all_3d_turn_models_based_on_df(combination):
    """
    Lists all 3D deadlock free turn models in "deadlock_free_turns" in "Generated_Files"
    folder!
    ---------------------
        We have 16,777,216 turns in 3D Mesh NoC! if it takes one second to calculate
        deadlock freeness Then it takes almost 194.2 Days (almost 6.4 Months) to
        check all of them. that is the reason we need to make this parallel!
    ---------------------
    :param combination: number of turns which should be checked for combination!
    :return: None
    """
    counter = 0
    all_turns_file = open(
        'Generated_Files/Turn_Model_Lists/all_3D_turn_models_' +
        str(combination) + '.txt', 'w')
    turns_health_3d_network = {
        "N2W": False,
        "N2E": False,
        "S2W": False,
        "S2E": False,
        "W2N": False,
        "W2S": False,
        "E2N": False,
        "E2S": False,
        "N2U": False,
        "N2D": False,
        "S2U": False,
        "S2D": False,
        "W2U": False,
        "W2D": False,
        "E2U": False,
        "E2D": False,
        "U2W": False,
        "U2E": False,
        "U2N": False,
        "U2S": False,
        "D2W": False,
        "D2E": False,
        "D2N": False,
        "D2S": False
    }
    Config.ag.topology = '3DMesh'
    Config.ag.x_size = 3
    Config.ag.y_size = 3
    Config.ag.z_size = 3

    ag = copy.deepcopy(AG_Functions.generate_ag())
    turn_model_list = copy.deepcopy(PackageFile.FULL_TurnModel_3D)

    deadlock_free_counter = 0
    deadlock_counter = 0
    # print("Number of Turns:", combination)
    for turns in itertools.combinations(turn_model_list, combination):
        turns_health = copy.deepcopy(turns_health_3d_network)
        for turn in turns:
            turns_health[turn] = True
        counter += 1
        shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
        shmu.setup_noc_shm(ag, turns_health, False)
        noc_rg = copy.deepcopy(
            Routing.generate_noc_route_graph(ag, shmu, list(turns), False,
                                             False))
        if check_deadlock_freeness(noc_rg):
            connectivity_metric = reachability_metric(ag, noc_rg, False)
            doa = degree_of_adaptiveness(ag, noc_rg, False)
            deadlock_free_counter += 1
            all_turns_file.write(
                str(counter) + "\t\tDF\t" + str(list(turns)) + "\t\t" +
                str(connectivity_metric) + "\t\t" + str(doa) + "\n")
        else:
            deadlock_counter += 1
            all_turns_file.write(
                str(counter) + "\t\tDL\t" + str(list(turns)) + "\t\t-----"
                "\n")
        del shmu
        del noc_rg
    all_turns_file.write("---------------------------" + "\n")
    all_turns_file.write("Number of turn models with deadlock: " +
                         str(deadlock_counter) + "\n")
    all_turns_file.write("Number of turn models without deadlock: " +
                         str(deadlock_free_counter) + "\n")
    all_turns_file.write("==========================================" + "\n")
    all_turns_file.close()
    return None
def mixed_critical_rg(network_size, routing_type, critical_nodes, critical_rg_nodes, broken_links,
                      turn_model, viz, report):

    turns_health_2d_network = {"N2W": True, "N2E": True, "S2W": True, "S2E": True,
                               "W2N": True, "W2S": True, "E2N": True, "E2S": True}

    Config.ag.topology = '2DMesh'
    Config.ag.x_size = network_size
    Config.ag.y_size = network_size
    Config.ag.z_size = 1
    Config.RotingType = routing_type

    ag = copy.deepcopy(AG_Functions.generate_ag())
    shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
    shmu.setup_noc_shm(ag, turns_health_2d_network, False)
    noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, turns_health_2d_network.keys(), False,  False))
    copy_rg =copy.deepcopy(noc_rg)

    for node in critical_rg_nodes:
        if node not in noc_rg.nodes():
            raise ValueError(str(node)+" doesnt exist in noc_rg")

    for node in noc_rg.nodes():
        if node in critical_rg_nodes:
            noc_rg.node[node]["criticality"] = "H"
        else:
            noc_rg.node[node]["criticality"] = "L"

    edges_to_be_removed = []
    for edge in noc_rg.edges():
        if (int(edge[0][:-2]), int(edge[1][:-2]))in broken_links:
            edges_to_be_removed.append(edge)
        # removing edges that go from non-critical ports to ports used by critical ports
        if noc_rg.node[edge[0]]["criticality"] != noc_rg.node[edge[1]]["criticality"]:
            edges_to_be_removed.append(edge)
        else:
            if noc_rg.node[edge[0]]["criticality"] == "L":
                if edge[0][:-2] == edge[1][:-2]:
                    # remove the links that do not follow the turn model rules!
                    if str(edge[0][-2])+"2"+str(edge[1][-2]) not in turn_model:
                        if edge[0][-2] == "L" or edge[1][-2] == "L":
                            pass
                        elif edge[0][-2] == "E" and edge[1][-2] == "W":
                            pass
                        elif edge[0][-2] == "W" and edge[1][-2] == "E":
                            pass
                        elif edge[0][-2] == "S" and edge[1][-2] == "N":
                            pass
                        elif edge[0][-2] == "N" and edge[1][-2] == "S":
                            pass
                        else:
                            edges_to_be_removed.append(edge)

    for edge in edges_to_be_removed:
        noc_rg.remove_edge(edge[0], edge[1])
    if viz:
        noc_rg = copy.deepcopy(cleanup_routing_graph(ag, noc_rg))
        RoutingGraph_Reports.draw_rg(noc_rg)

    reachability_counter = 0
    connectivity_counter = 0
    print "deadlock freeness:", check_deadlock_freeness(noc_rg)
    for node_1 in ag.nodes():
        for node_2 in ag.nodes():
            if node_1 != node_2:
                if node_1 in critical_nodes or node_2 in critical_nodes:
                    pass
                else:

                    if is_destination_reachable_from_source(noc_rg, node_1, node_2):
                        connectivity_counter += 1
                        if routing_type == "MinimalPath":
                            paths = return_minimal_paths(noc_rg, node_1, node_2)
                            all_minimal_paths = return_minimal_paths(copy_rg, node_1, node_2)
                            valid_path = True
                            for path in paths:
                                for node in path:
                                    successors = noc_rg.successors(node)
                                    if str(node_2)+str('L')+str('O') in successors:
                                        #print node_2, successors
                                        break
                                    else:
                                        for successor in successors:
                                            valid_successor = False

                                            for path_1 in all_minimal_paths:
                                                if successor in path_1:
                                                    valid_successor = True
                                                    break
                                            if valid_successor:
                                                sucessor_paths = []
                                                max_hop_count = manhattan_distance(int(successor[:-2]), node_2)
                                                if has_path(noc_rg, successor, str(node_2)+str('L')+str('O')):
                                                    all_paths_from_sucessor = list(all_shortest_paths(noc_rg, successor, str(node_2)+str('L')+str('O')))
                                                    for Path in all_paths_from_sucessor:
                                                        if (len(Path)-2)/2 <= max_hop_count:
                                                            sucessor_paths.append(Path)
                                                if len(sucessor_paths)==0:
                                                    valid_path = False
                                                    #print path, node, node_2, successor, "FALSE"
                                                    break
                                                else:
                                                    pass
                                                    #print path, node, node_2, successor, "TRUE"


                            if valid_path:
                                reachability_counter += 1
                            else:
                                if report:
                                    print node_1,"can not reach  ", node_2
                        else:
                            reachability_counter += 1
                    else:
                        if report:
                            print node_1,"can not connect", node_2
    print "average connectivity for non-critical nodes:", float(connectivity_counter)/(len(ag.nodes())-len(critical_nodes))
    print "average reachability for non-critical nodes:", float(reachability_counter)/(len(ag.nodes())-len(critical_nodes))
    return float(connectivity_counter)/(len(ag.nodes())-len(critical_nodes)), noc_rg
def report_3d_turn_model_fault_tolerance(turn_model, viz, combination):
    """
    generates 3D architecture graph with all combinations C(len(ag.nodes), combination)
    of links and writes the average connectivity metric in a file.
    :param turn_model: list of allowed turns for generating the routing graph
    :param combination: number of links to be present in the network
    :param viz: if true, generates the visualization files
    :return: None
    """
    if combination == 108:
        raise ValueError(
            "breaking 108 edges out of 108 edges is not possible your connectivity is 0!"
        )

    Config.UsedTurnModel = copy.deepcopy(turn_model)
    Config.TurnsHealth = copy.deepcopy(Config.setup_turns_health())

    ag = copy.deepcopy(AG_Functions.generate_ag(report=False))

    turn_model_name = return_turn_model_name(Config.UsedTurnModel)

    file_name = str(turn_model_name) + '_eval'
    turn_model_eval_file = open(
        'Generated_Files/Turn_Model_Eval/' + file_name + '.txt', 'a+')
    if viz:
        file_name_viz = str(turn_model_name) + '_eval_' + str(
            len(ag.edges()) - combination)
        turn_model_eval_viz_file = open(
            'Generated_Files/Internal/' + file_name_viz + '.txt', 'w')
    else:
        turn_model_eval_viz_file = None
    counter = 0
    metric_sum = 0

    list_of_avg = []
    number_of_combinations = comb(108, combination)
    while True:
        sub_ag = sample(ag.edges(), combination)
        shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
        shmu.setup_noc_shm(ag, copy.deepcopy(Config.TurnsHealth), False)
        for link in list(sub_ag):
            shmu.break_link(link, False)
        noc_rg = copy.deepcopy(
            Routing.generate_noc_route_graph(ag, shmu, Config.UsedTurnModel,
                                             False, False))
        connectivity_metric = reachability_metric(ag, noc_rg, False)
        counter += 1
        metric_sum += connectivity_metric
        # std = None
        list_of_avg.append(float(metric_sum) / counter)
        if len(list_of_avg) > 5000:
            list_of_avg.pop(0)
            std = stdev(list_of_avg)
            if std < 0.009:
                # turn_model_eval_file.write("STD of the last 5000 average samples is bellow 0.009\n")
                # turn_model_eval_file.write("Terminating the search!\n")
                del shmu
                del noc_rg
                break
        if viz:
            turn_model_eval_viz_file.write(
                str(float(metric_sum) / counter) + "\n")

        if counter >= number_of_combinations:
            del shmu
            del noc_rg
            break

        # print("#:"+str(counter)+"\t\tC.M.:"+str(connectivity_metric)+"\t\t avg:", \
        #    float(metric_sum)/counter, "\t\tstd:", std)
        del shmu
        del noc_rg

    if counter > 0:
        avg_connectivity = float(metric_sum) / counter
    else:
        avg_connectivity = 0
    turn_model_eval_file.write(
        str(len(ag.edges()) - combination) + "\t\t" + str(avg_connectivity) +
        "\n")
    turn_model_eval_file.close()
    if viz:
        turn_model_eval_viz_file.close()
    return None
def odd_even_fault_tolerance_metric(network_size, routing_type):

    turns_health_2d_network = {"N2W": False, "N2E": False, "S2W": False, "S2E": False,
                               "W2N": False, "W2S": False, "E2N": False, "E2S": False}
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = network_size
    Config.ag.y_size = network_size
    Config.ag.z_size = 1
    Config.RotingType = routing_type

    all_odd_evens_file = open('Generated_Files/Turn_Model_Eval/'+str(network_size)+"x"+str(network_size)+
                              '_OE_metric_'+Config.RotingType+'.txt', 'w')
    all_odd_evens_file.write("TOPOLOGY::"+str(Config.ag.topology)+"\n")
    all_odd_evens_file.write("X SIZE:"+str(Config.ag.x_size)+"\n")
    all_odd_evens_file.write("Y SIZE:"+str(Config.ag.y_size)+"\n")
    all_odd_evens_file.write("Z SIZE:"+str(Config.ag.z_size)+"\n")
    ag = copy.deepcopy(AG_Functions.generate_ag())
    shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
    turns_health = copy.deepcopy(turns_health_2d_network)
    shmu.setup_noc_shm(ag, turns_health, False)
    noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, [], False,  False))

    classes_of_doa_ratio = []
    turn_model_class_dict = {}
    tm_counter = 0

    for turn_model in all_odd_even_list:

        sys.stdout.write("\rnumber of processed turn models: %i " % tm_counter)
        sys.stdout.flush()
        tm_counter += 1
        link_dict = {}
        turn_model_index = all_odd_even_list.index(turn_model)
        turn_model_odd = turn_model[0]
        turn_model_even = turn_model[1]

        update_rg_odd_even(ag, turn_model_odd, turn_model_even, shmu, noc_rg)

        number_of_pairs = len(ag.nodes())*(len(ag.nodes())-1)

        all_paths_in_graph = []
        for source_node in ag.nodes():
                for destination_node in ag.nodes():
                    if source_node != destination_node:
                        if is_destination_reachable_from_source(noc_rg, source_node, destination_node):
                            if Config.RotingType == 'MinimalPath':
                                shortest_paths = list(all_shortest_paths(noc_rg, str(source_node)+str('L')+str('I'),
                                                                         str(destination_node)+str('L')+str('O')))
                                paths = []
                                for path in shortest_paths:
                                    minimal_hop_count = manhattan_distance(source_node, destination_node)
                                    if (len(path)/2)-1 <= minimal_hop_count:
                                        paths.append(path)
                                        all_paths_in_graph.append(path)
                            else:
                                paths = list(all_simple_paths(noc_rg, str(source_node)+str('L')+str('I'),
                                                              str(destination_node)+str('L')+str('O')))
                                all_paths_in_graph += paths
                            link_dict = find_similarity_in_paths(link_dict, paths)

        metric = 0
        for item in link_dict.keys():
            metric += link_dict[item]

        if Config.RotingType == 'MinimalPath':
            doa = degree_of_adaptiveness(ag, noc_rg, False)/float(number_of_pairs)
            metric = 1/(float(metric)/len(ag.edges()))
            metric = float("{:3.3f}".format(metric))
        else:
            doa_ex = extended_degree_of_adaptiveness(ag, noc_rg, False)/float(number_of_pairs)
            metric = 1/(float(metric)/len(ag.edges()))
            metric = float("{:3.3f}".format(metric))

        if metric not in classes_of_doa_ratio:
            classes_of_doa_ratio.append(metric)
        if metric in turn_model_class_dict.keys():
            turn_model_class_dict[metric].append(turn_model_index)
        else:
            turn_model_class_dict[metric] = [turn_model_index]
        # return SHMU and RG back to default
        clean_rg_from_odd_even(ag, turn_model_odd, turn_model_even, shmu, noc_rg)

    all_odd_evens_file.write("classes of metric"+str(classes_of_doa_ratio)+"\n")
    all_odd_evens_file.write("----------"*3+"\n")
    all_odd_evens_file.write("turn models of class"+"\n")
    for item in sorted(turn_model_class_dict.keys()):
        all_odd_evens_file.write(str(item)+" "+str(turn_model_class_dict[item])+"\n")

    all_odd_evens_file.write("----------"*3+"\n")
    all_odd_evens_file.write("distribution of turn models"+"\n")
    for item in sorted(turn_model_class_dict.keys()):
        temp_list = []
        for tm in turn_model_class_dict[item]:
            turn_model = all_odd_even_list[tm]
            number_of_turns = len(turn_model[0])+len(turn_model[1])
            temp_list.append(number_of_turns)
        all_odd_evens_file.write(str(item)+" "+str(temp_list.count(8))+" "+str(temp_list.count(9))+" " +
                                 str(temp_list.count(10))+" "+str(temp_list.count(11))+" " +
                                 str(temp_list.count(12))+"\n")
    all_odd_evens_file.close()
    return  turn_model_class_dict
예제 #45
0
def n_map(tg, ag, noc_rg, critical_rg, non_critical_rg, shm, logging):
    """
    Performs NMap Mapping algorithm
    :param tg: Task Graph
    :param ag: Architecture Graph
    :param noc_rg: NoC Routing Graph
    :param critical_rg: NoC Routing Graph for Critical Region
    :param non_critical_rg: NoC Routing Graph for Non-Critical Region
    :param shm: System Health Map
    :param logging: logging File
    :return: TG and AG
    """
    print ("===========================================")
    print ("STARTING N-MAP MAPPING...\n")

    if len(tg.nodes()) > len(ag.nodes()):
        raise ValueError("Number of tasks should be smaller or equal to number of PEs")

    mapped_tasks = []
    unmapped_tasks = copy.deepcopy(tg.nodes())
    allocated_nodes = []
    unallocated_nodes = copy.deepcopy(ag.nodes())

    # remove all broken nodes from unallocated_nodes list
    for node in unallocated_nodes:
        if not shm.node[node]['NodeHealth']:
            unallocated_nodes.remove(node)
            print ("REMOVED BROKEN NODE "+str(node)+" FROM UN-ALLOCATED NODES")

    print ("------------------")
    print ("STEP 1:")
    # step 1: find the task with highest weighted communication volume
    tasks_com_dict = TG_Functions.tasks_communication_weight(tg)
    sorted_tasks_com = sorted(tasks_com_dict, key=tasks_com_dict.get, reverse=True)
    print ("\t SORTED TASKS BY COMMUNICATION WEIGHT:\n"+"\t "+str(sorted_tasks_com))
    print ("\t -------------")
    chosen_task = sorted_tasks_com[0]
    print ("\t CHOSEN TASK: "+str(chosen_task))
    mapped_tasks.append(chosen_task)
    print ("\t ADDED TASK "+str(chosen_task)+"TO MAPPED TASKS LIST")
    unmapped_tasks.remove(chosen_task)
    print ("\t REMOVED TASK "+str(chosen_task)+"FROM UN-MAPPED TASKS LIST")

    print ("------------------")
    print ("STEP 2:")
    node_neighbors_dict = AG_Functions.node_neighbors(ag, shm)
    sorted_node_neighbors = sorted(node_neighbors_dict, key=node_neighbors_dict.get, reverse=True)
    max_neighbors_node = AG_Functions.max_node_neighbors(node_neighbors_dict, sorted_node_neighbors)
    print ("\t SORTED NODES BY NUMBER OF NEIGHBOURS:\n"+"\t "+str(sorted_node_neighbors))
    print ("\t -------------")
    print ("\t NODES WITH MAX NEIGHBOURS:\t"+str(max_neighbors_node))
    chosen_node = random.choice(max_neighbors_node)

    print ("\t CHOSEN NODE: "+str(chosen_node))
    allocated_nodes.append(chosen_node)
    print ("\t ADDED NODE "+str(chosen_node)+" TO ALLOCATED NODES LIST")
    unallocated_nodes.remove(chosen_node)
    print ("\t REMOVED NODE "+str(chosen_node)+" FROM UN-ALLOCATED NODES LIST")
    # Map Chosen Task on Chosen Node...
    if Mapping_Functions.map_task_to_node(tg, ag, shm, noc_rg, critical_rg,
                                          non_critical_rg, chosen_task, chosen_node, logging):
        print ("\t \033[32m* NOTE::\033[0mTASK "+str(chosen_task)+" MAPPED ON NODE "+str(chosen_node))
    else:
        raise ValueError("Mapping task on node failed...")

    print ("------------------")
    print ("STEP 3:")
    while len(unmapped_tasks) > 0:
        print ("\033[33m==>\033[0m  UN-MAPPED TASKS #: "+str(len(unmapped_tasks)))
        print ("\t -------------")
        print ("\t STEP 3.1:")
        # find the unmapped task which communicates most with mapped_tasks
        max_com = 0
        unmapped_tasks_com = {}
        tasks_with_max_com_to_mapped = []
        for Task in unmapped_tasks:
            task_weight = 0
            for mapped_task in mapped_tasks:
                if (Task, mapped_task) in tg.edges():
                    task_weight += tg.edge[Task][mapped_task]["ComWeight"]
                if (mapped_task, Task) in tg.edges():
                    task_weight += tg.edge[mapped_task][Task]["ComWeight"]
            unmapped_tasks_com[Task] = task_weight
            if max_com < task_weight:
                max_com = task_weight
                tasks_with_max_com_to_mapped = [Task]
            elif max_com == task_weight:
                tasks_with_max_com_to_mapped.append(Task)
        print ("\t MAX COMMUNICATION WITH THE MAPPED TASKS: "+str(max_com))
        print ("\t TASK(S) WITH MAX COMMUNICATION TO MAPPED TASKS: "+str(tasks_with_max_com_to_mapped))
        if len(tasks_with_max_com_to_mapped) > 1:
            # multiple tasks with same comm to mapped
            # Find the one that communicate most with Un-mapped takss...
            candid_task_with_max_com_to_unmapped = []
            max_com = 0
            for CandidateTask in tasks_with_max_com_to_mapped:
                task_weight = 0
                for unmapped_task in unmapped_tasks:
                    if (Task, unmapped_task) in tg.edges():
                        task_weight += tg.edge[Task][unmapped_task]["ComWeight"]
                    if (unmapped_task, Task) in tg.edges():
                        task_weight += tg.edge[unmapped_task][Task]["ComWeight"]
                if task_weight > max_com:
                    candid_task_with_max_com_to_unmapped = [CandidateTask]
                elif task_weight == max_com:
                    candid_task_with_max_com_to_unmapped.append(CandidateTask)
            print ("\t CANDIDATE TASK(S) THAT COMMUNICATE MOST WITH UN_MAPPED: " +
                   str(candid_task_with_max_com_to_unmapped))
            if len(candid_task_with_max_com_to_unmapped) > 1:
                # if multiple tasks with the same com to unmmaped also,
                # choose randomly
                chosen_task = random.choice(candid_task_with_max_com_to_unmapped)
            else:
                chosen_task = candid_task_with_max_com_to_unmapped[0]
        else:
            chosen_task = tasks_with_max_com_to_mapped[0]
        print ("\t CHOSEN TASK: "+str(chosen_task))

        # Find the unallocated tile with lowest communication cost to/from the allocated_tiles_set.
        print ("\t -------------")
        print ("\t STEP 3.2:")
        min_cost = float("inf")
        node_candidates = []
        for unallocated_node in unallocated_nodes:
            cost = 0
            reachable = True
            for mapped_task in mapped_tasks:
                com_weight = 0
                if (chosen_task, mapped_task) in tg.edges():
                    # print ("TASK CONNECTED TO MAPPED TASK:", mapped_task)
                    com_weight += tg.edge[chosen_task][mapped_task]["ComWeight"]
                    destination_node = tg.node[mapped_task]['task'].node
                    # here we check if this node is even reachable from the chosen node?
                    if Calculate_Reachability.is_destination_reachable_from_source(noc_rg, unallocated_node,
                                                                                   destination_node):
                        manhatan_distance = AG_Functions.manhattan_distance(unallocated_node, destination_node)
                        cost += manhatan_distance * com_weight
                    else:
                        reachable = False
                elif (mapped_task, chosen_task) in tg.edges():
                    # print ("TASK CONNECTED TO MAPPED TASK:", mapped_task)
                    com_weight += tg.edge[mapped_task][chosen_task]["ComWeight"]
                    destination_node = tg.node[mapped_task]['task'].node
                    # here we check if this node is even reachable from the chosen node?
                    if Calculate_Reachability.is_destination_reachable_from_source(noc_rg, destination_node,
                                                                                   unallocated_node):
                        manhatan_distance = AG_Functions.manhattan_distance(unallocated_node, destination_node)
                        cost += manhatan_distance * com_weight
                    else:
                        reachable = False
            if reachable:
                if cost < min_cost:
                    node_candidates = [unallocated_node]
                    min_cost = cost
                elif cost == min_cost:
                    node_candidates.append(unallocated_node)
            else:
                print ("\t \033[33m* NOTE::\033[0m NODE "+str(unallocated_node)+" CAN NOT REACH...")
                pass
        print ("\t CANDIDATE NODES: "+str(node_candidates)+" MIN COST: "+str(min_cost))

        if len(node_candidates) == 0:
            raise ValueError("COULD NOT FIND A REACHABLE CANDIDATE NODE...")
        elif len(node_candidates) > 1:
            chosen_node = random.choice(node_candidates)
        elif len(node_candidates) == 1:
            chosen_node = node_candidates[0]
        else:
            # this means that the chosen task is not connected to any other task... so its cost is infinity
            chosen_node = random.choice(unallocated_nodes)

        mapped_tasks.append(chosen_task)
        print ("\t ADDED TASK "+str(chosen_task)+" TO MAPPED TASKS LIST")
        unmapped_tasks.remove(chosen_task)
        print ("\t REMOVED TASK "+str(chosen_task)+" FROM UN-MAPPED TASKS LIST")

        allocated_nodes.append(chosen_node)
        print ("\t ADDED NODE "+str(chosen_node)+" TO ALLOCATED NODES LIST")
        unallocated_nodes.remove(chosen_node)
        print ("\t REMOVED NODE "+str(chosen_node)+" FROM UN-ALLOCATED NODES LIST")

        if Mapping_Functions.map_task_to_node(tg, ag, shm, noc_rg, critical_rg,
                                              non_critical_rg, chosen_task, chosen_node, logging):
            print ("\t \033[32m* NOTE::\033[0mTASK "+str(chosen_task)+" MAPPED ON NODE "+str(chosen_node))
        else:
            raise ValueError("Mapping task on node failed...")

    # Added by Behrad (Still under development)
    # Swapping phase
    print "-----------------------"
    print "PHASE ONE IS DONE... STARTING SWAP PROCESS..."
    for node_id_1 in range(0, len(ag.nodes())-1):
        for node_id_2 in range(node_id_1+1, len(ag.nodes())-1):
            pass
            # Save current mapping in an array
            # Also save the mapping's csomm_cost in a variable
            comm_cost = calculate_com_cost(tg)

            # Swap (node_id_1 , node_id_2)
            swap_nodes(tg, ag, shm, noc_rg, critical_rg, non_critical_rg, node_id_1, node_id_2, logging)
            # Check and calculate communication cost for all communication flows in the task graph
            #   (which is equal to the total number of edges in the application graph
            #   starting from the communication flow with the largest communication volume first
            comm_cost_new = calculate_com_cost(tg)
            # If comm_cost of current mapping is the same or bigger than the previous mapping, discard mapping
            #   Revert back to previous mapping with better comm_cost
            # Else
            #   Save new mapping as better mapping with less comm_cost
            if comm_cost_new < comm_cost:
                print "\033[32m* NOTE::\033[0m BETTER SOLUTION FOUND WITH COST:", comm_cost_new
            else:
                pass
                # print "Reverting to old solution"
                swap_nodes(tg, ag, shm, noc_rg, critical_rg, non_critical_rg,
                           node_id_2, node_id_1, logging)
            # Reset the comm_cost after each swapping

    # End of Swapping phase
    print "SWAP PROCESS FINISHED..."
    Scheduler.schedule_all(tg, ag, shm, True, logging)
    return tg, ag
def initialize_system(logging):
    """
    Generates the Task graph, Architecture Graph, System Health Monitoring Unit, NoC routing graph(s) and
    Test Task Graphs and does the mapping and scheduling and returns to the user the initial system
    :param logging: logging file
    :return:  tg, ag, shmu, noc_rg, critical_rg, noncritical_rg, pmcg
    """
    tg = copy.deepcopy(TG_Functions.generate_tg())
    if Config.DebugInfo:
        Task_Graph_Reports.report_task_graph(tg, logging)
    Task_Graph_Reports.draw_task_graph(tg)
    if Config.TestMode:
        TG_Test.check_acyclic(tg, logging)
    ####################################################################
    ag = copy.deepcopy(AG_Functions.generate_ag(logging))
    AG_Functions.update_ag_regions(ag)
    AG_Functions.random_darkness(ag)
    if Config.EnablePartitioning:
        AG_Functions.setup_network_partitioning(ag)
    if Config.FindOptimumAG:
        Arch_Graph_Reports.draw_ag(ag, "AG_Full")
    else:
        Arch_Graph_Reports.draw_ag(ag, "AG")
    ####################################################################
    Config.setup_turns_health()

    shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
    shmu.setup_noc_shm(ag, Config.TurnsHealth, True)
    # Here we are injecting initial faults of the system: we assume these fault
    # information is obtained by post manufacturing system diagnosis
    if Config.FindOptimumAG:
        vl_opt.optimize_ag_vertical_links(ag, shmu, logging)
        vl_opt_functions.cleanup_ag(ag, shmu)
        Arch_Graph_Reports.draw_ag(ag, "AG_VLOpt")
    SHMU_Functions.apply_initial_faults(shmu)
    if Config.viz.shm:
        SHMU_Reports.draw_shm(shmu.SHM)
        SHMU_Reports.draw_temp_distribution(shmu.SHM)
    # SHM_Reports.report_noc_shm()
    ####################################################################
    routing_graph_start_time = time.time()
    if Config.SetRoutingFromFile:
        noc_rg = copy.deepcopy(Routing.gen_noc_route_graph_from_file(ag, shmu, Config.RoutingFilePath,
                                                                     Config.DebugInfo, Config.DebugDetails))
    else:
        noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, Config.UsedTurnModel,
                                                                Config.DebugInfo, Config.DebugDetails))
    Routing_Functions.check_deadlock_freeness(noc_rg)
    print ("\033[92mTIME::\033[0m ROUTING GRAPH GENERATION TOOK: " +
           str(round(time.time()-routing_graph_start_time))+" SECONDS")
    # this is for double checking...
    if Config.FindOptimumAG:
        Calculate_Reachability.reachability_metric(ag, noc_rg, True)
    # Some visualization...
    if Config.viz.rg:
        RoutingGraph_Reports.draw_rg(noc_rg)
    ####################################################################
    # in case of partitioning, we have to route based on different Route-graphs
    if Config.EnablePartitioning:
        critical_rg, noncritical_rg = Calculate_Reachability.calculate_reachability_with_regions(ag, shmu)
        ReachabilityReports.report_gsnoc_friendly_reachability_in_file(ag)
    else:
        critical_rg, noncritical_rg = None, None
        Calculate_Reachability.calculate_reachability(ag, noc_rg)
        Calculate_Reachability.optimize_reachability_rectangles(ag, Config.NumberOfRects)
        # ReachabilityReports.report_reachability(ag)
        ReachabilityReports.report_reachability_in_file(ag, "ReachAbilityNodeReport")
        ReachabilityReports.report_gsnoc_friendly_reachability_in_file(ag)
    ####################################################################
    if Config.read_mapping_from_file:
        Mapping_Functions.read_mapping_from_file(tg, ag, shmu.SHM, noc_rg, critical_rg, noncritical_rg,
                                                 Config.mapping_file_path, logging)
        Scheduler.schedule_all(tg, ag, shmu.SHM, False, logging)
    else:
        best_tg, best_ag = Mapping.mapping(tg, ag, noc_rg, critical_rg, noncritical_rg, shmu.SHM, logging)
        if best_ag is not None and best_tg is not None:
            tg = copy.deepcopy(best_tg)
            ag = copy.deepcopy(best_ag)
            del best_tg, best_ag
            # SHM.add_current_mapping_to_mpm(tg)
            Mapping_Functions.write_mapping_to_file(ag, "mapping_report")
    if Config.viz.mapping_distribution:
        Mapping_Reports.draw_mapping_distribution(ag, shmu)
    if Config.viz.mapping:
        Mapping_Reports.draw_mapping(tg, ag, shmu.SHM, "Mapping_post_opt")
    if Config.viz.scheduling:
        Scheduling_Reports.generate_gantt_charts(tg, ag, "SchedulingTG")
    ####################################################################
    # PMC-Graph
    # at this point we assume that the system health map knows about the initial faults from
    # the diagnosis process
    if Config.GeneratePMCG:
        pmcg_start_time = time.time()
        if Config.OneStepDiagnosable:
            pmcg = TestSchedulingUnit.gen_one_step_diagnosable_pmcg(ag, shmu.SHM)
        else:
            pmcg = TestSchedulingUnit.gen_sequentially_diagnosable_pmcg(ag, shmu.SHM)
        test_tg = TestSchedulingUnit.generate_test_tg_from_pmcg(pmcg)
        print ("\033[92mTIME::\033[0m PMCG AND TTG GENERATION TOOK: " +
               str(round(time.time()-pmcg_start_time)) + " SECONDS")
        if Config.viz.pmcg:
            TestSchedulingUnit.draw_pmcg(pmcg)
        if Config.viz.ttg:
            TestSchedulingUnit.draw_ttg(test_tg)
        TestSchedulingUnit.insert_test_tasks_in_tg(pmcg, tg)
        Task_Graph_Reports.draw_task_graph(tg, ttg=test_tg)
        TestSchedulingUnit.map_test_tasks(tg, ag, shmu.SHM, noc_rg, logging)
        Scheduler.schedule_test_in_tg(tg, ag, shmu.SHM, False, logging)
        Scheduling_Reports.report_mapped_tasks(ag, logging)
        # TestSchedulingUnit.remove_test_tasks_from_tg(test_tg, tg)
        # Task_Graph_Reports.draw_task_graph(tg, TTG=test_tg)
        Scheduling_Reports.generate_gantt_charts(tg, ag, "SchedulingWithTTG")
    else:
        pmcg = None
    Arch_Graph_Reports.gen_latex_ag(ag, shmu.SHM)
    print ("===========================================")
    print ("SYSTEM IS UP...")

    TrafficTableGenerator.generate_noxim_traffic_table(ag, tg)
    if Config.viz.mapping_frames:
        Mapping_Animation.generate_frames(ag, shmu.SHM)
    return tg, ag, shmu, noc_rg, critical_rg, noncritical_rg, pmcg
예제 #47
0
def DrawTempDistribution(SHM):
    """

    :param SHM: System Health Map
    :return:
    """
    print("===========================================")
    print("GENERATING TEMPERATURE DISTRIBUTIONS VISUALIZATION...")
    fig_Util = plt.figure(figsize=(4 * Config.Network_X_Size,
                                   4 * Config.Network_Y_Size))
    MaxTemp = 0
    for node in SHM.nodes():
        MaxTemp = max(SHM.node[node]['NodeTemp'], MaxTemp)

    for node in SHM.nodes():
        Location = AG_Functions.return_node_location(node)
        XSize = float(Config.Network_X_Size)
        YSize = float(Config.Network_Y_Size)
        ZSize = float(Config.Network_Y_Size)

        X_Offset = Location[2] / (ZSize * XSize)
        Y_Offset = Location[2] / (ZSize * YSize)

        Temp = 255 * (float(SHM.node[node]['RouterTemp']) / Config.MaxTemp)
        if SHM.node[node]['NodeHealth']:
            color = '#%02X%02X%02X' % (Temp, 0, 255 - Temp)
        else:  # node is broken
            color = '#7B747B'
        fig_Util.gca().add_patch(
            patches.Rectangle((Location[0] / XSize + X_Offset,
                               Location[1] / YSize + Y_Offset),
                              width=0.08,
                              height=0.08,
                              facecolor=color,
                              edgecolor="black",
                              linewidth=3,
                              zorder=ZSize - Location[2]))

        Temp = 255 * (float(SHM.node[node]['NodeTemp']) / Config.MaxTemp)

        if SHM.node[node]['NodeHealth']:
            color = '#%02X%02X%02X' % (Temp, 0, 255 - Temp)
        else:  # node is broken
            color = '#7B747B'
        fig_Util.gca().add_patch(
            patches.Rectangle((Location[0] / XSize + X_Offset + 0.05,
                               Location[1] / YSize + Y_Offset),
                              width=0.03,
                              height=0.03,
                              facecolor=color,
                              edgecolor="black",
                              linewidth=3,
                              zorder=ZSize - Location[2]))

    fig_Util.text(0.25,
                  0.03,
                  'Distribution of temperature of network nodes',
                  fontsize=15)
    fig_Util.savefig("GraphDrawings/Temp_Distribute.png", dpi=100)
    fig_Util.clf()
    plt.close(fig_Util)
    print(
        "\033[35m* VIZ::\033[0mMAPPING UTILIZATION DISTRIBUTION DRAWING CREATED AT: GraphDrawings/Temp_Distribute.png"
    )

    return None
def enumerate_all_2d_turn_models_based_on_df(combination):
    """
    Lists all 2D deadlock free turn models in "deadlock_free_turns" in "Generated_Files"
    folder!
    ---------------------
        We have 256 turns in 2D Mesh NoC!
    ---------------------
    :param combination: number of turns which should be checked for combination!
    :return: None
    """
    counter = 0
    all_turns_file = open(
        'Generated_Files/Turn_Model_Lists/all_2D_turn_models_' +
        str(combination) + '.txt', 'w')
    turns_health_2d_network = {
        "N2W": False,
        "N2E": False,
        "S2W": False,
        "S2E": False,
        "W2N": False,
        "W2S": False,
        "E2N": False,
        "E2S": False
    }
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = 3
    Config.ag.y_size = 3
    Config.ag.z_size = 1
    Config.RotingType = 'NonMinimalPath'

    all_turns_file.write("#" + "\t\tDF/D\t" + '%25s' % "turns" + '%20s' % " " +
                         "\t\t" + '%10s' % "c-metric" + "\t\t" +
                         '%10s' % "DoA" + "\t\t" + '%10s' % "DoAx" + "\n")
    all_turns_file.write("--------------" * 8 + "\n")
    ag = copy.deepcopy(AG_Functions.generate_ag())
    number_of_pairs = len(ag.nodes()) * (len(ag.nodes()) - 1)
    turn_model_list = copy.deepcopy(PackageFile.FULL_TurnModel_2D)

    deadlock_free_counter = 0
    deadlock_counter = 0
    # print("Number of Turns:", combination)
    for turns in itertools.combinations(turn_model_list, combination):
        turns_health = copy.deepcopy(turns_health_2d_network)
        for turn in turns:
            turns_health[turn] = True
        counter += 1
        shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
        shmu.setup_noc_shm(ag, turns_health, False)
        noc_rg = copy.deepcopy(
            Routing.generate_noc_route_graph(ag, shmu, list(turns), False,
                                             False))
        if check_deadlock_freeness(noc_rg):
            connectivity_metric = reachability_metric(ag, noc_rg, False)
            doa = degree_of_adaptiveness(ag, noc_rg,
                                         False) / float(number_of_pairs)
            doa_ex = extended_degree_of_adaptiveness(
                ag, noc_rg, False) / float(number_of_pairs)
            deadlock_free_counter += 1
            all_turns_file.write(
                str(counter) + "\t\tDF\t" + '%51s' % str(list(turns)) +
                "\t\t" + '%10s' % str(connectivity_metric) + "\t\t" +
                '%10s' % str(round(doa, 2)) + "\t\t" +
                '%10s' % str(round(doa_ex, 2)) + "\n")
        else:
            deadlock_counter += 1
            all_turns_file.write(
                str(counter) + "\t\tDL\t" + '%51s' % str(list(turns)) +
                "\t\t-----" + "\t\t-----" + "\t\t-----" + "\n")
        del shmu
        del noc_rg
    all_turns_file.write("---------------------------" + "\n")
    all_turns_file.write("Number of turn models with deadlock: " +
                         str(deadlock_counter) + "\n")
    all_turns_file.write("Number of turn models without deadlock: " +
                         str(deadlock_free_counter) + "\n")
    all_turns_file.write("==========================================" + "\n")
    all_turns_file.close()
    return None
예제 #49
0
def draw_shm(shm, iteration=None):
    """

    :param shm: System Health Map
    :return:
    """
    print ("===========================================")
    print ("GENERATING SYSTEM HEALTH MAP DRAWING...")

    x_size = float(Config.ag.x_size)
    y_size = float(Config.ag.y_size)
    z_size = float(Config.ag.z_size)

    fig = plt.figure(figsize=(10*x_size, 10*y_size))
    if z_size == 1:
        plt.ylim([0, 1])
        plt.xlim([0, 1])
    else:
        plt.ylim([0, z_size])
        plt.xlim([0, z_size])

    for node in shm.nodes():
        location = AG_Functions.return_node_location(node)
        x = (location[0]/x_size)*z_size
        y = (location[1]/y_size)*z_size
        z = (location[2]/z_size)
        x_offset = z
        y_offset = z

        font_size = 35 / z_size
        plt.text(x+0.155+x_offset, y+0.055+y_offset, str(node), fontsize=font_size)
        circle_router = plt.Circle((x+0.1+x_offset, y+0.1+y_offset), 0.05, facecolor='w')
        plt.gca().add_patch(circle_router)
        if shm.node[node]['NodeHealth']:
            color = 'w'
        else:
            color = 'r'
        circle_node = plt.Circle((x+0.14+x_offset, y+0.06+y_offset), 0.01, facecolor=color)
        plt.gca().add_patch(circle_node)

        for turn in shm.node[node]['TurnsHealth']:
            if shm.node[node]['TurnsHealth'][turn]:
                color = 'black'
            else:
                color = 'r'

            if turn == 'S2E':
                plt.gca().add_patch(patches.Arrow(x+0.11+x_offset, y+0.065+y_offset, 0.015,
                                                  0.015, width=0.01, color=color))
            elif turn == 'E2S':
                plt.gca().add_patch(patches.Arrow(x+0.135+x_offset, y+0.08+y_offset, -0.015,
                                                  -0.015, width=0.01, color=color))
            elif turn == 'W2N':
                plt.gca().add_patch(patches.Arrow(x+0.065+x_offset, y+0.117+y_offset, 0.015,
                                                  0.015, width=0.01, color=color))
            elif turn == 'N2W':
                plt.gca().add_patch(patches.Arrow(x+0.09+x_offset, y+0.132+y_offset, -0.015,
                                                  -0.015, width=0.01, color=color))
            elif turn == 'N2E':
                plt.gca().add_patch(patches.Arrow(x+0.12+x_offset, y+0.132+y_offset, 0.015,
                                                  -0.015, width=0.01, color=color))
            elif turn == 'E2N':
                plt.gca().add_patch(patches.Arrow(x+0.125+x_offset, y+0.117+y_offset, -0.015,
                                                  0.015, width=0.01, color=color))
            elif turn == 'W2S':
                plt.gca().add_patch(patches.Arrow(x + 0.075+x_offset, y + 0.08+y_offset, 0.015,
                                                  -0.015, width=0.01, color=color))
            elif turn == 'S2W':
                plt.gca().add_patch(patches.Arrow(x + 0.080+x_offset, y + 0.065+y_offset, -0.015,
                                                  0.015, width=0.01, color=color))

            if shm.node[node]['TurnsHealth'][turn]:
                color = 'black'
            else:
                color = 'r'

            if turn == 'N2U':
                circle_node = plt.Circle((x+0.09+x_offset, y+0.142+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)

            elif turn == 'N2D':
                circle_node = plt.Circle((x+0.11+x_offset, y+0.142+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle((x+0.11+x_offset, y+0.142+y_offset), 0.001, facecolor='b')
                plt.gca().add_patch(circle_node)

            elif turn == 'S2U':
                circle_node = plt.Circle((x+0.11+x_offset, y+0.057+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)

            elif turn == 'S2D':
                circle_node = plt.Circle((x+0.09+x_offset, y+0.057+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle((x+0.09+x_offset, y+0.057+y_offset), 0.001, facecolor='b')
                plt.gca().add_patch(circle_node)

            elif turn == 'E2U':
                circle_node = plt.Circle((x+0.142+x_offset, y+0.11+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)

            elif turn == 'E2D':
                circle_node = plt.Circle((x+0.142+x_offset, y+0.09+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle((x+0.142+x_offset, y+0.09+y_offset), 0.001, facecolor='b')
                plt.gca().add_patch(circle_node)

            elif turn == 'W2U':
                circle_node = plt.Circle((x+0.057+x_offset, y+0.09+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)

            elif turn == 'W2D':
                circle_node = plt.Circle((x+0.057+x_offset, y+0.11+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle((x+0.057+x_offset, y+0.11+y_offset), 0.001, facecolor='b')
                plt.gca().add_patch(circle_node)

            elif turn == 'U2N':
                circle_node = plt.Circle((x+0.105+x_offset, y+0.111+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle((x+0.105+x_offset, y+0.111+y_offset), 0.001, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(patches.Arrow(x + 0.105+x_offset, y + 0.116+y_offset,
                                                  0, 0.01, width=0.01, color=color))

            elif turn == 'U2S':
                circle_node = plt.Circle((x+0.105+x_offset, y+0.086+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle((x+0.105+x_offset, y+0.086+y_offset), 0.001, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(patches.Arrow(x + 0.105+x_offset, y + 0.081+y_offset,
                                                  0, -0.01, width=0.01, color=color))

            elif turn == 'U2W':
                circle_node = plt.Circle((x+0.085+x_offset, y+0.093+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle((x+0.085+x_offset, y+0.093+y_offset), 0.001, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(patches.Arrow(x + 0.08+x_offset, y + 0.093+y_offset,
                                                  -0.01, 0, width=0.01, color=color))

            elif turn == 'U2E':
                circle_node = plt.Circle((x+0.115+x_offset, y+0.093+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                circle_node = plt.Circle((x+0.115+x_offset, y+0.093+y_offset), 0.001, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(patches.Arrow(x + 0.12+x_offset, y + 0.093+y_offset,
                                                  0.01, 0, width=0.01, color=color))

            elif turn == 'D2N':
                circle_node = plt.Circle((x+0.095+x_offset, y+0.111+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(patches.Arrow(x + 0.095+x_offset, y + 0.116+y_offset,
                                                  0, 0.01, width=0.01, color=color))

            elif turn == 'D2S':
                circle_node = plt.Circle((x+0.095+x_offset, y+0.086+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(patches.Arrow(x + 0.095+x_offset, y + 0.081+y_offset,
                                                  0, -0.01, width=0.01, color=color))

            elif turn == 'D2W':
                circle_node = plt.Circle((x+0.085+x_offset, y+0.104+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(patches.Arrow(x + 0.08+x_offset, y + 0.104+y_offset,
                                                  -0.01, 0, width=0.01, color=color))

            elif turn == 'D2E':
                circle_node = plt.Circle((x+0.115+x_offset, y+0.104+y_offset), 0.005, edgecolor=color, facecolor='w')
                plt.gca().add_patch(circle_node)
                plt.gca().add_patch(patches.Arrow(x + 0.12+x_offset, y + 0.104+y_offset,
                                                  0.01, 0, width=0.01, color=color))

    for link in shm.edges():
        if shm.edge[link[0]][link[1]]['LinkHealth']:
            color = 'black'
        else:
            color = 'r'
        source_loc = AG_Functions.return_node_location(link[0])
        destination_loc = AG_Functions.return_node_location(link[1])

        x = (source_loc[0]/x_size)*z_size
        y = (source_loc[1]/y_size)*z_size
        z = source_loc[2]/z_size
        x_offset = z
        y_offset = z

        dx = ((destination_loc[0] - source_loc[0])/x_size)
        dy = ((destination_loc[1] - source_loc[1])/y_size)
        dz = ((destination_loc[2] - source_loc[2])/z_size)
        if dz == 0:
            if dx == 0:
                if dy > 0:
                    plt.gca().add_patch(patches.Arrow(x+0.11+x_offset, y+0.15+y_offset,
                                                      0, dy*z_size - 0.1, width=0.01, color=color))
                else:
                    plt.gca().add_patch(patches.Arrow(x+0.09+x_offset, y+0.05+y_offset,
                                                      0, dy*z_size + 0.1, width=0.01, color=color))

            elif dy == 0:
                if dx > 0:
                    plt.gca().add_patch(patches.Arrow(x+0.15+x_offset, y+0.11+y_offset,
                                                      dx*z_size - 0.1, 0, width=0.01, color=color))
                else:
                    plt.gca().add_patch(patches.Arrow(x+0.05+x_offset, y+0.09+y_offset,
                                                      dx*z_size + 0.1, 0, width=0.01, color=color))
            else:
                raise ValueError("Can not draw link", link)
        elif dz > 0:
                z_offset = 1.4/z_size
                plt.gca().add_patch(patches.Arrow(x+0.130+x_offset, y+0.140+y_offset,
                                                  dz*z_offset, dz*z_offset, width=0.01, color=color))
        elif dz < 0:
                plt.gca().add_patch(patches.Arrow(x+0.07+x_offset, y+0.06+y_offset,
                                                  dz*z_offset, dz*z_offset, width=0.01, color=color))

    fig.text(0.25, 0.02, "System Health Map", fontsize=35)
    if iteration is None:
        plt.savefig("GraphDrawings/SHM.png", dpi=200)
    else:
        plt.savefig("GraphDrawings/SHM_"+str(iteration)+".png", dpi=200)
    plt.clf()
    plt.close(fig)
    print("\033[35m* VIZ::\033[0mSYSTEM HEALTH MAP DRAWING CREATED AT: GraphDrawings/SHM.png")
    return None
def generate_frames(ag, shm):
    """
    Generates Animation frames for the mapping process.
    :param ag: Architecture Graph
    :param shm: System Health Map
    :return: None
    """
    print ("===========================================")
    print ("GENERATING MAPPING ANIMATION FRAMES...")
    mapping_process_file = open("Generated_Files/Internal/MappingProcess.txt", 'r')
    x_size = float(Config.ag.x_size)
    y_size = float(Config.ag.y_size)
    line = mapping_process_file.readline()

    bound = int(log10(2 * Config.MaxNumberOfIterations)) + 1   # UpperBoundOnFileNumberDigits
    counter = 0
    while line != '':
        fig = plt.figure(figsize=(4*Config.ag.x_size, 4*Config.ag.y_size), dpi=Config.viz.frame_resolution)
        # initialize an empty list of cirlces
        mapped_pe_list = line.split(" ")
        for node in ag.nodes():
            location = AG_Functions.return_node_location(node)
            # print (node, location)
            if shm.node[node]['NodeHealth']:
                if Config.EnablePartitioning:
                    if node in Config.CriticalRegionNodes:
                        color = '#FF878B'
                    elif node in Config.GateToNonCritical:
                        color = '#928AFF'
                    elif node in Config.GateToCritical:
                        color = '#FFC29C'
                    else:
                        color = 'white'
                else:
                    color = 'white'
            else:   # node is broken
                color = '#7B747B'
            fig.gca().add_patch(patches.Rectangle((location[0]/x_size, location[1]/y_size),
                                width=0.15, height=0.15, facecolor=color,
                                edgecolor="black", linewidth=3, alpha=0.5))
            if str(node) in mapped_pe_list:
                tasks = [i for i, x in enumerate(mapped_pe_list) if x == str(node)]
                offset_x = 0
                offset_y = 0.02
                task_count = 0
                for task in tasks:
                    task_count += 1
                    offset_x += 0.03
                    if task_count == 5:
                        task_count = 1
                        offset_x = 0.03
                        offset_y += 0.03
                    random.seed(task)
                    r = random.randrange(0, 255)
                    g = random.randrange(0, 255)
                    b = random.randrange(0, 255)
                    color = '#%02X%02X%02X' % (r, g, b)
                    circle = plt.Circle((location[0]/x_size+offset_x, location[1]/y_size+offset_y), 0.01, fc=color)
                    if Config.viz.frame_resolution >= 50:
                        plt.text(location[0]/x_size+offset_x, location[1]/y_size+offset_y-0.001, task)
                    plt.gca().add_patch(circle)
        fig.text(0.25, 0.02, "Iteration:" + str(counter), fontsize=35)
        plt.savefig("GraphDrawings/Mapping_Animation_Material/Mapping_Frame_"+str(counter).zfill(bound) + ".png",
                    dpi=Config.viz.frame_resolution)
        plt.clf()
        plt.close(fig)
        counter += 1
        line = mapping_process_file.readline()
    mapping_process_file.close()
    print ("\033[35m* VIZ::\033[0mMAPPING ANIMATION FRAMES READY AT: GraphDrawings/Mapping_Animation_Material")
    return None
def draw_mapping(tg, ag, shm, mapping_file_name):
    """
    This function draws the tasks on tiles of network. this would be very useful to check how our
    mapping optimization is acting...
    :param tg: Task Graph
    :param ag: Architecture Graph
    :param shm: System Health Map
    :param mapping_file_name: string containing name of the file in which the mapping would be generated
    :return: None
    """
    print("===========================================")
    print("GENERATING MAPPING VISUALIZATION...")
    fig = plt.figure(figsize=(4 * Config.ag.x_size, 4 * Config.ag.y_size))
    color_list = []
    position = {}
    x_size = float(Config.ag.x_size)
    y_size = float(Config.ag.y_size)
    z_size = float(Config.ag.z_size)
    node_size = 0.3
    step_size = node_size * 1.08
    distance = step_size * z_size * 1.2
    for node in ag.nodes():
        location = AG_Functions.return_node_location(node)
        if shm.node[node]['NodeHealth']:
            if not ag.node[node]['PE'].dark:
                if Config.EnablePartitioning:
                    if node in Config.CriticalRegionNodes:
                        color = '#FF878B'
                    elif node in Config.GateToNonCritical:
                        color = '#928AFF'
                    elif node in Config.GateToCritical:
                        color = '#FFC29C'
                    else:
                        color = 'white'
                else:
                    color = 'white'
            else:
                color = 'gray'
        else:  # node is broken
            color = '#7B747B'

        fig.gca().add_patch(
            patches.Rectangle(
                ((distance * location[0]) + location[2] * step_size,
                 (distance * location[1]) + location[2] * step_size),
                width=node_size,
                height=node_size,
                facecolor=color,
                linewidth=3,
                alpha=0.5))

        plt.text(
            (distance * location[0]) + location[2] * step_size,
            (distance * location[1]) + location[2] * step_size + node_size,
            str(node),
            fontsize=15)
        if location[0] < x_size - 1:
            x = distance * (location[0]) + location[2] * step_size + node_size
            y = distance * (location[1]) + location[2] * step_size + (
                node_size / 2)
            plt.plot([x, x + distance - node_size], [y, y],
                     color='black',
                     lw=3)
            # plt.gca().add_patch(patches.Arrow(x, y, 1.0/x_size - 0.1, 0, width=0.01))
        if location[1] < y_size - 1:
            x = distance * (location[0]) + location[2] * step_size + (
                node_size / 2)
            y = distance * (location[1]) + location[2] * step_size + node_size
            # plt.plot([y, y], [x, x+1.0/x_size - 0.1], color ='black')
            plt.plot([x, x], [y, y + distance - node_size],
                     color='black',
                     lw=3)

        number_of_task_in_row = 4
        offset_x = -(node_size / (2 * number_of_task_in_row))
        offset_y = node_size / (number_of_task_in_row + 1)
        task_count = 0
        for task in ag.node[node]['PE'].mapped_tasks:
            offset_x += node_size / number_of_task_in_row
            if task_count == number_of_task_in_row:
                task_count = 0
                offset_x = (node_size / (2 * number_of_task_in_row))
                offset_y += node_size / number_of_task_in_row
            random.seed(task)
            r = random.randrange(0, 255)
            g = random.randrange(0, 255)
            b = random.randrange(0, 255)
            color = '#%02X%02X%02X' % (r, g, b)
            color_list.append(color)
            position[task] = (distance * location[0] +
                              location[2] * step_size + offset_x,
                              distance * location[1] +
                              location[2] * step_size + offset_y)
            task_count += 1
    task_size = 800 / Config.ag.z_size
    networkx.draw(tg,
                  position,
                  with_labels=True,
                  node_size=task_size,
                  node_color=color_list,
                  width=0,
                  alpha=0.5)
    fig.text(0.35, 0.1, 'Mapping visualization for network nodes', fontsize=15)

    plt.text(0, -node_size * 2 / 3, 'X', fontsize=15)
    plt.text(-node_size * 2 / 3, 0, 'Y', fontsize=15)
    plt.text(-node_size * 2 / 3 + node_size / 3,
             -node_size * 2 / 3 + node_size / 3,
             'Z',
             fontsize=15)

    plt.gca().add_patch(
        patches.Arrow(-node_size * 2 / 3,
                      -node_size * 2 / 3,
                      node_size,
                      0,
                      width=node_size / 10))
    plt.gca().add_patch(
        patches.Arrow(-node_size * 2 / 3,
                      -node_size * 2 / 3,
                      node_size / 3,
                      node_size / 3,
                      width=node_size / 10))
    plt.gca().add_patch(
        patches.Arrow(-node_size * 2 / 3,
                      -node_size * 2 / 3,
                      0,
                      node_size,
                      width=node_size / 10))

    fig.savefig("GraphDrawings/" + mapping_file_name + ".png",
                bbox_inches='tight')
    plt.clf()
    plt.close(fig)
    print("\033[35m* VIZ::\033[0mMAPPING DRAWING CREATED AT: GraphDrawings/" +
          mapping_file_name + ".png")
    return None
예제 #52
0
def draw_rg(rg):
    print("===========================================")
    print("GENERATING ROUTING GRAPH VISUALIZATION...")
    pos = {}
    color_list = []
    plt.figure(figsize=(10 * Config.Network_X_Size,
                        10 * Config.Network_Y_Size))
    distance = 100 * Config.Network_Z_Size
    step = (distance * 0.8) / Config.Network_Z_Size
    for node in rg.nodes():
        chosen_node = int(re.search(r'\d+', node).group())
        location = AG_Functions.return_node_location(chosen_node)
        circle1 = plt.Circle((location[0] * distance + step * location[2],
                              location[1] * distance + step * location[2]),
                             radius=35,
                             color='#8ABDFF',
                             fill=False)
        plt.gca().add_patch(circle1)

        circle2 = plt.Circle(
            (location[0] * distance + step * location[2] + 45,
             location[1] * distance + step * location[2] - 50),
            radius=10,
            color='#FF878B',
            fill=False)
        plt.gca().add_patch(circle2)

        plt.text(location[0] * distance + step * location[2] - 30,
                 location[1] * distance + step * location[2] + 30,
                 str(chosen_node),
                 fontsize=15)

        offset_x = 0
        offset_y = 0

        if 'N' in node:
            offset_y += 30
            if 'I' in node:
                color_list.append('#CFECFF')
                offset_x += 12
            else:
                color_list.append('#FF878B')
                offset_x -= 12
        elif 'S' in node:
            offset_y -= 30
            if 'I' in node:
                color_list.append('#CFECFF')
                offset_x -= 12
            else:
                color_list.append('#FF878B')
                offset_x += 12
        elif 'W' in node:
            offset_x -= 30
            if 'I' in node:
                color_list.append('#CFECFF')
                offset_y += 12
            else:
                color_list.append('#FF878B')
                offset_y -= 12

        elif 'E' in node:
            offset_x += 30
            if 'I' in node:
                color_list.append('#CFECFF')
                offset_y -= 12
            else:
                color_list.append('#FF878B')
                offset_y += 12

        if 'L' in node:
            if 'I' in node:
                color_list.append('#CFECFF')
                offset_x += 44
                offset_y -= 56
            else:
                color_list.append('#FF878B')
                offset_x += 48
                offset_y -= 48

        if 'U' in node:
            offset_y = 16
            if 'I' in node:
                color_list.append('#CFECFF')
                offset_x -= 15
            else:
                color_list.append('#FF878B')
                offset_x += 15

        if 'D' in node:
            offset_y = -16
            if 'I' in node:
                color_list.append('#CFECFF')
                offset_x -= 15
            else:
                color_list.append('#FF878B')
                offset_x += 15

        pos[node] = [
            location[0] * distance + offset_x + step * location[2],
            location[1] * distance + offset_y + step * location[2]
        ]

    networkx.draw(rg,
                  pos,
                  with_labels=False,
                  arrows=False,
                  node_size=30,
                  node_color=color_list)

    plt.text(0, -100, 'X', fontsize=15)
    plt.text(-100, 0, 'Y', fontsize=15)
    plt.text(-45, -45, 'Z', fontsize=15)

    plt.gca().add_patch(patches.Arrow(-100, -100, 100, 0, width=10))
    plt.gca().add_patch(patches.Arrow(-100, -100, 50, 50, width=10))
    plt.gca().add_patch(patches.Arrow(-100, -100, 0, 100, width=10))

    plt.savefig("GraphDrawings/RG.png", dpi=100)
    plt.clf()
    print(
        "\033[35m* VIZ::\033[0mROUTING GRAPH DRAWING CREATED AT: GraphDrawings/RG.png"
    )
    return None
def report_odd_even_turn_model_router_fault_tolerance(viz, routing_type, combination, network_size, ft_dictionary,
                                                      selected_turn_models):
    """
    generates 2D architecture graph with all combinations C(len(ag.nodes), combination)
    of links and writes the average connectivity metric in a file.
    :param viz: if true, generates the visualization files
    :param routing_type: can be "minimal" or "nonminimal"
    :param combination: number of links to be present in the network
    :return: ft_dictionary a dictionary with turn mode id (from selected_turn_models)
    as keys and average connectivity_metric as value.
    """

    turns_health_2d_network = {"N2W": False, "N2E": False, "S2W": False, "S2E": False,
                               "W2N": False, "W2S": False, "E2N": False, "E2S": False}
    tm_counter = 0
    Config.ag.topology = '2DMesh'
    Config.ag.x_size = network_size
    Config.ag.y_size = network_size
    Config.ag.z_size = 1

    Config.RotingType = routing_type

    ag = copy.deepcopy(AG_Functions.generate_ag(report=False))
    router_list = list(itertools.combinations(ag.nodes(), combination))


    for turn_id in selected_turn_models:
        counter = 0
        metric_sum = 0
        turn_model = all_odd_even_list[turn_id]

        turn_model_odd = turn_model[0]
        turn_model_even = turn_model[1]

        file_name = str(tm_counter)+'_eval'
        turn_model_eval_file = open('Generated_Files/Turn_Model_Eval/'+file_name+'.txt', 'a+')
        if viz:
            file_name_viz = str(tm_counter)+'_eval_'+str(len(ag.nodes())-counter)
            turn_model_eval_viz_file = open('Generated_Files/Internal/odd_even'+file_name_viz+'.txt', 'w')
        else:
            turn_model_eval_viz_file = None

        for sub_router_list in router_list:
            turns_health = copy.deepcopy(turns_health_2d_network)
            shmu = SystemHealthMonitoringUnit.SystemHealthMonitoringUnit()
            shmu.setup_noc_shm(ag, turns_health, False)
            noc_rg = copy.deepcopy(Routing.generate_noc_route_graph(ag, shmu, [], False,  False))

            for node in ag.nodes():
                if node not in sub_router_list:
                    node_x, node_y, node_z = AG_Functions.return_node_location(node)
                    if node_x % 2 == 1:
                        for turn in turn_model_odd:
                            shmu.restore_broken_turn(node, turn, False)
                            from_port = str(node)+str(turn[0])+"I"
                            to_port = str(node)+str(turn[2])+"O"
                            Routing.update_noc_route_graph(noc_rg, from_port, to_port, 'ADD')
                    else:
                        for turn in turn_model_even:
                            shmu.restore_broken_turn(node, turn, False)
                            from_port = str(node)+str(turn[0])+"I"
                            to_port = str(node)+str(turn[2])+"O"
                            Routing.update_noc_route_graph(noc_rg, from_port, to_port, 'ADD')
                else:
                    for port_1 in ["N", "S", "E", "W", "L"]:
                        for port_2 in ["N", "S", "E", "W", "L"]:
                            if port_1 != port_2:
                                from_port = str(node)+str(port_1)+"I"
                                to_port = str(node)+str(port_2)+"O"
                                if (from_port, to_port) in noc_rg.edges():
                                    Routing.update_noc_route_graph(noc_rg, from_port, to_port, 'REMOVE')


            connectivity_metric = reachability_metric(ag, noc_rg, False)
            counter += 1
            metric_sum += connectivity_metric
            if viz:
                turn_model_eval_viz_file.write(str(float(metric_sum)/counter)+"\n")

        shuffle(router_list)

        if counter > 0:
            avg_connectivity = float(metric_sum)/counter
        else:
            avg_connectivity = 0
        turn_model_eval_file.write(str(len(ag.nodes())-combination)+"\t\t"+str(avg_connectivity)+"\n")
        if turn_id in ft_dictionary.keys():
            ft_dictionary[turn_id].append(avg_connectivity)
        else:
            ft_dictionary[turn_id] = [avg_connectivity]
        if viz:
            turn_model_eval_viz_file.close()
        turn_model_eval_file.close()
        sys.stdout.write("\rchecked TM: %i " % tm_counter+"\t\t\tnumber of broken routers: %i " % combination)
        sys.stdout.flush()
        tm_counter += 1
    return ft_dictionary