def minimum_completion_time(tg, ag, shm, logging): """ :param tg: Task Graph :param ag: Architecture Graph :param shm: System Health Map :param logging: logging File :return: (TG, AG) """ # The difference with Min Min or Max Min is that we don't add priorities to # tasks based on their WCET but we randomly choose a task and schedule it... # Note :: This heuristic is not taking task ciriticality into account... print ("===========================================") print ("STARTING MIN COMPLETION TIME MAPPING") for task_to_be_mapped in tg.nodes(): chosen_node = random.choice(Mapping_Functions.nodes_with_smallest_ct(ag, tg, shm, task_to_be_mapped)) tg.node[task_to_be_mapped]['task'].node = chosen_node ag.node[chosen_node]['PE'].mapped_tasks.append(task_to_be_mapped) ag.node[chosen_node]['PE'].utilization += tg.node[task_to_be_mapped]['task'].wcet node_speed_down = 1+((100.0-shm.node[chosen_node]['NodeSpeed'])/100) task_execution_on_node = tg.node[task_to_be_mapped]['task'].wcet*node_speed_down completion_on_node = tg.node[task_to_be_mapped]['task'].release + task_execution_on_node Scheduling_Functions_Nodes.add_tg_task_to_node(tg, ag, task_to_be_mapped, chosen_node, tg.node[task_to_be_mapped]['task'].release, completion_on_node, None) print ("\tTASK "+str(task_to_be_mapped)+" MAPPED ON NODE: "+str(chosen_node)) print ("MIN COMPLETION TIME MAPPING FINISHED...") Scheduling_Reports.report_mapped_tasks(ag, logging) return tg, ag
def min_execution_time(tg, ag, shm, logging): """ :param tg: Task Graph :param ag: Architecture Graph :param shm: System Health Map :param logging: logging file :return: (TG, AG) """ # this sounds a little stupid because there are no job specific machines... # we can Add Specific Accelerators or define different run time on different # PEs so this becomes more interesting... print ("===========================================") print ("STARTING MIN EXECUTION TIME MAPPING") for task_to_be_mapped in tg.nodes(): chosen_node = random.choice(Mapping_Functions.fastest_nodes(ag, shm)) tg.node[task_to_be_mapped]['task'].node = chosen_node ag.node[chosen_node]['PE'].mapped_tasks.append(task_to_be_mapped) ag.node[chosen_node]['PE'].utilization += tg.node[task_to_be_mapped]['task'].wcet node_speed_down = 1+((100.0-shm.node[chosen_node]['NodeSpeed'])/100) task_execution_on_node = tg.node[task_to_be_mapped]['task'].wcet*node_speed_down completion_on_node = tg.node[task_to_be_mapped]['task'].release + task_execution_on_node Scheduling_Functions_Nodes.add_tg_task_to_node(tg, ag, task_to_be_mapped, chosen_node, tg.node[task_to_be_mapped]['task'].release, completion_on_node, None) print ("\tTASK "+str(task_to_be_mapped)+" MAPPED ON NODE: "+str(chosen_node)) print ("MIN EXECUTION TIME MAPPING FINISHED...") Scheduling_Reports.report_mapped_tasks(ag, logging) return tg, ag
def nodes_with_smallest_ct(ag, tg, shm, task): """ finds nodes with smallest completion time of the task! THIS FUNCTION CAN BE STRICTLY USED FOR INDEPENDENT TGs :param ag: Arch Graph :param tg: Task Graph :param shm: System Health Map :param task: Task number :return: list of nodes with smallest completion time for Task """ node_with_smallest_ct = [] random_node = random.choice(list(ag.nodes())) while (not shm.node[random_node]['NodeHealth'] ) or ag.node[random_node]['PE'].dark: random_node = random.choice(list(ag.nodes())) node_speed_down = 1 + ((100.0 - shm.node[random_node]['NodeSpeed']) / 100) task_execution_on_node = tg.node[task]['task'].wcet * node_speed_down last_allocated_time_on_node = Scheduling_Functions_Nodes.find_last_allocated_time_on_node( ag, random_node, logging=None) if last_allocated_time_on_node < tg.node[task]['task'].release: smallest_completion_time = tg.node[task][ 'task'].release + task_execution_on_node else: smallest_completion_time = last_allocated_time_on_node + task_execution_on_node for node in ag.nodes(): if shm.node[node]['NodeHealth'] and ( not ag.node[random_node]['PE'].dark): node_speed_down = 1 + ((100.0 - shm.node[node]['NodeSpeed']) / 100) task_execution_on_node = tg.node[task][ 'task'].wcet * node_speed_down last_allocated_time_on_node = Scheduling_Functions_Nodes.find_last_allocated_time_on_node( ag, node, logging=None) if last_allocated_time_on_node < tg.node[task]['task'].release: completion_on_node = tg.node[task][ 'task'].release + task_execution_on_node else: completion_on_node = last_allocated_time_on_node + task_execution_on_node if ceil(completion_on_node) < smallest_completion_time: smallest_completion_time = completion_on_node for node in ag.nodes(): if shm.node[node]['NodeHealth'] and ( not ag.node[random_node]['PE'].dark): node_speed_down = 1 + ((100.0 - shm.node[node]['NodeSpeed']) / 100) last_allocated_time_on_node = Scheduling_Functions_Nodes.find_last_allocated_time_on_node( ag, node, logging=None) task_execution_on_node = tg.node[task][ 'task'].wcet * node_speed_down if last_allocated_time_on_node < tg.node[task]['task'].release: completion_on_node = tg.node[task][ 'task'].release + task_execution_on_node else: completion_on_node = last_allocated_time_on_node + task_execution_on_node if completion_on_node == smallest_completion_time: node_with_smallest_ct.append(node) return node_with_smallest_ct
def min_min_mapping(tg, ag, shm, logging): """ :param tg: Task Graph :param ag: Architecture Graph :param shm: System Health Map :param logging: logging file :return: (TG, AG) """ # this function finds the task with the smallest WCET and # maps it on the machine that can offer smallest completion time... # this means that the mapping algorithm has to take into account the mapping # of the edges of the task graph on the links. # Note:: this is a heuristic for independent tasks... so we are not going to # schedule any link # Note 2:: This heuristic is not taking task ciriticality into account... print("===========================================") print("STARTING MIN-MIN MAPPING") shortest_tasks = Mapping_Functions.unmapped_task_with_smallest_wcet( tg, logging) while len(shortest_tasks) > 0: task_to_be_mapped = shortest_tasks.pop() # map the task on the Node that yields smallest Completion time candidate_nodes = Mapping_Functions.nodes_with_smallest_ct( ag, tg, shm, task_to_be_mapped) print("\tCANDIDATE NODES FOR MAPPING: " + str(candidate_nodes)) if len(candidate_nodes) > 0: chosen_node = random.choice(candidate_nodes) print("\t\tMAPPING TASK " + str(task_to_be_mapped) + " WITH RELEASE: " + str(tg.node[task_to_be_mapped]['task'].release) + " ---> NODE: " + str(chosen_node)) tg.node[task_to_be_mapped]['task'].node = chosen_node ag.node[chosen_node]['PE'].mapped_tasks.append(task_to_be_mapped) ag.node[chosen_node]['PE'].utilization += tg.node[ task_to_be_mapped]['task'].wcet node_speed_down = 1 + ( (100.0 - shm.node[chosen_node]['NodeSpeed']) / 100) task_execution_on_node = tg.node[task_to_be_mapped][ 'task'].wcet * node_speed_down completion_on_node = tg.node[task_to_be_mapped][ 'task'].release + task_execution_on_node Scheduling_Functions_Nodes.add_tg_task_to_node( tg, ag, task_to_be_mapped, chosen_node, tg.node[task_to_be_mapped]['task'].release, completion_on_node, None) if len(shortest_tasks) == 0: shortest_tasks = Mapping_Functions.unmapped_task_with_smallest_wcet( tg, logging) print("MIN-MIN MAPPING FINISHED...") Scheduling_Reports.report_mapped_tasks(ag, logging) return tg, ag
def max_min_mapping(tg, ag, shm, logging): """ :param tg: Task Graph :param ag: Architecture Graph :param shm: System Health Map :param logging: logging file :return: (TG, AG) """ # this function finds the task with the biggest WCET and # maps it on the machine that can offer smallest completion time... # this means that the mapping algorithm has to take into account the mapping # of the edges of the task graph on the links. # Note:: this is a heuristic for independent tasks... so we are not going to # schedule any link # Note 2:: This heuristic is not taking task ciriticality into account... print ("===========================================") print ("STARTING MAX-MIN MAPPING") longest_tasks = Mapping_Functions.unmapped_task_with_biggest_wcet(tg, logging) while len(longest_tasks) > 0: task_to_be_mapped = longest_tasks.pop() # map the task on the Node that yields smallest Completion time candidate_nodes = Mapping_Functions.nodes_with_smallest_ct(ag, tg, shm, task_to_be_mapped) print ("CANDIDATE NODES FOR MAPPING: "+str(candidate_nodes)) if len(candidate_nodes) > 0: chosen_node = random.choice(candidate_nodes) if len(candidate_nodes) > 1: print ("\tMAPPING TASK "+str(task_to_be_mapped)+" WITH RELEASE: " + str(tg.node[task_to_be_mapped]['task'].release) + " ---> NODE: "+str(chosen_node)+" (RANDOMLY CHOSEN FROM CANDIDATES)") else: print ("\tMAPPING TASK "+str(task_to_be_mapped)+" WITH RELEASE: " + str(tg.node[task_to_be_mapped]['task'].release) + " ---> NODE: "+str(chosen_node)) tg.node[task_to_be_mapped]['task'].node = chosen_node ag.node[chosen_node]['PE'].mapped_tasks.append(task_to_be_mapped) ag.node[chosen_node]['PE'].utilization += tg.node[task_to_be_mapped]['task'].wcet node_speed_down = 1+((100.0-shm.node[chosen_node]['NodeSpeed'])/100) task_execution_on_node = tg.node[task_to_be_mapped]['task'].wcet*node_speed_down completion_on_node = tg.node[task_to_be_mapped]['task'].release + task_execution_on_node Scheduling_Functions_Nodes.add_tg_task_to_node(tg, ag, task_to_be_mapped, chosen_node, tg.node[task_to_be_mapped]['task'].release, completion_on_node, None) if len(longest_tasks) == 0: longest_tasks = Mapping_Functions.unmapped_task_with_biggest_wcet(tg, logging) print ("MIN-MAX MAPPING FINISHED...") Scheduling_Reports.report_mapped_tasks(ag, logging) return tg, ag
def nodes_with_smallest_ct(ag, tg, shm, task): """ finds nodes with smallest completion time of the task! THIS FUNCTION CAN BE STRICTLY USED FOR INDEPENDENT TGs :param ag: Arch Graph :param tg: Task Graph :param shm: System Health Map :param task: Task number :return: list of nodes with smallest completion time for Task """ node_with_smallest_ct = [] random_node = random.choice(ag.nodes()) while (not shm.node[random_node]['NodeHealth']) or ag.node[random_node]['PE'].dark: random_node = random.choice(ag.nodes()) node_speed_down = 1+((100.0-shm.node[random_node]['NodeSpeed'])/100) task_execution_on_node = tg.node[task]['task'].wcet*node_speed_down last_allocated_time_on_node = Scheduling_Functions_Nodes.find_last_allocated_time_on_node(ag, random_node, logging=None) if last_allocated_time_on_node < tg.node[task]['task'].release: smallest_completion_time = tg.node[task]['task'].release + task_execution_on_node else: smallest_completion_time = last_allocated_time_on_node + task_execution_on_node for node in ag.nodes(): if shm.node[node]['NodeHealth'] and (not ag.node[random_node]['PE'].dark): node_speed_down = 1+((100.0-shm.node[node]['NodeSpeed'])/100) task_execution_on_node = tg.node[task]['task'].wcet*node_speed_down last_allocated_time_on_node = Scheduling_Functions_Nodes.find_last_allocated_time_on_node(ag, node, logging=None) if last_allocated_time_on_node < tg.node[task]['task'].release: completion_on_node = tg.node[task]['task'].release + task_execution_on_node else: completion_on_node = last_allocated_time_on_node + task_execution_on_node if ceil(completion_on_node) < smallest_completion_time: smallest_completion_time = completion_on_node for node in ag.nodes(): if shm.node[node]['NodeHealth'] and (not ag.node[random_node]['PE'].dark): node_speed_down = 1+((100.0-shm.node[node]['NodeSpeed'])/100) last_allocated_time_on_node = Scheduling_Functions_Nodes.find_last_allocated_time_on_node(ag, node, logging=None) task_execution_on_node = tg.node[task]['task'].wcet*node_speed_down if last_allocated_time_on_node < tg.node[task]['task'].release: completion_on_node = tg.node[task]['task'].release+task_execution_on_node else: completion_on_node = last_allocated_time_on_node+task_execution_on_node if completion_on_node == smallest_completion_time: node_with_smallest_ct.append(node) return node_with_smallest_ct
def MinExecutionTime(TG, AG, SHM, logging): """ :param TG: Task Graph :param AG: Architecture Graph :param SHM: System Health Map :param logging: logging file :return: (TG, AG) """ # this sounds a little stupid because there are no job specific machines... # we can Add Specific Accelerators or define different run time on different # PEs so this becomes more interesting... print("===========================================") print("STARTING MIN EXECUTION TIME MAPPING") for TaskToBeMapped in TG.nodes(): ChosenNode = random.choice( Mapping_Functions.fastest_nodes(AG, SHM, TaskToBeMapped)) TG.node[TaskToBeMapped]['Node'] = ChosenNode AG.node[ChosenNode]['PE'].MappedTasks.append(TaskToBeMapped) AG.node[ChosenNode]['PE'].Utilization += TG.node[TaskToBeMapped][ 'WCET'] NodeSpeedDown = 1 + ((100.0 - SHM.node[ChosenNode]['NodeSpeed']) / 100) TaskExecutionOnNode = TG.node[TaskToBeMapped]['WCET'] * NodeSpeedDown CompletionOnNode = TG.node[TaskToBeMapped][ 'Release'] + TaskExecutionOnNode Scheduling_Functions_Nodes.Add_TG_TaskToNode( TG, AG, TaskToBeMapped, ChosenNode, TG.node[TaskToBeMapped]['Release'], CompletionOnNode, logging) print("\tTASK " + str(TaskToBeMapped) + " MAPPED ON NODE: " + str(ChosenNode)) print("MIN EXECUTION TIME MAPPING FINISHED...") Scheduling_Reports.report_mapped_tasks(AG, logging) return TG, AG
def Min_Min_Mapping(TG, AG, NoCRG, SHM, logging): """ :param TG: Task Graph :param AG: Architecture Graph :param NoCRG: NoC Routing Graph :param SHM: System Health Map :param logging: logging file :return: (TG, AG) """ # this function finds the task with the smallest WCET and # maps it on the machine that can offer smallest completion time... # this means that the mapping algorithm has to take into account the mapping # of the edges of the task graph on the links. # Note:: this is a heuristic for independent tasks... so we are not going to # schedule any link # Note 2:: This heuristic is not taking task ciriticality into account... print("===========================================") print("STARTING MIN-MIN MAPPING") ShortestTasks = Mapping_Functions.unmapped_task_with_smallest_wcet( TG, logging) while len(ShortestTasks) > 0: TaskToBeMapped = ShortestTasks.pop() # map the task on the Node that yields smallest Completion time CandidateNodes = Mapping_Functions.nodes_with_smallest_ct( AG, TG, SHM, TaskToBeMapped) print("\tCANDIDATE NODES FOR MAPPING: " + str(CandidateNodes)) if len(CandidateNodes) > 0: ChosenNode = random.choice(CandidateNodes) print("\t\tMAPPING TASK " + str(TaskToBeMapped) + " WITH RELEASE: " + str(TG.node[TaskToBeMapped]['Release']) + " ---> NODE: " + str(ChosenNode)) TG.node[TaskToBeMapped]['Node'] = ChosenNode AG.node[ChosenNode]['PE'].MappedTasks.append(TaskToBeMapped) AG.node[ChosenNode]['PE'].Utilization += TG.node[TaskToBeMapped][ 'WCET'] NodeSpeedDown = 1 + ( (100.0 - SHM.node[ChosenNode]['NodeSpeed']) / 100) TaskExecutionOnNode = TG.node[TaskToBeMapped][ 'WCET'] * NodeSpeedDown CompletionOnNode = TG.node[TaskToBeMapped][ 'Release'] + TaskExecutionOnNode Scheduling_Functions_Nodes.Add_TG_TaskToNode( TG, AG, TaskToBeMapped, ChosenNode, TG.node[TaskToBeMapped]['Release'], CompletionOnNode, logging) if len(ShortestTasks) == 0: ShortestTasks = Mapping_Functions.unmapped_task_with_smallest_wcet( TG, logging) print("MIN-MIN MAPPING FINISHED...") Scheduling_Reports.report_mapped_tasks(AG, logging) return TG, AG
def minimum_completion_time(tg, ag, shm, logging): """ :param tg: Task Graph :param ag: Architecture Graph :param shm: System Health Map :param logging: logging File :return: (TG, AG) """ # The difference with Min Min or Max Min is that we don't add priorities to # tasks based on their WCET but we randomly choose a task and schedule it... # Note :: This heuristic is not taking task ciriticality into account... print("===========================================") print("STARTING MIN COMPLETION TIME MAPPING") for task_to_be_mapped in tg.nodes(): chosen_node = random.choice( Mapping_Functions.nodes_with_smallest_ct(ag, tg, shm, task_to_be_mapped)) tg.node[task_to_be_mapped]['task'].node = chosen_node ag.node[chosen_node]['PE'].mapped_tasks.append(task_to_be_mapped) ag.node[chosen_node]['PE'].utilization += tg.node[task_to_be_mapped][ 'task'].wcet node_speed_down = 1 + ( (100.0 - shm.node[chosen_node]['NodeSpeed']) / 100) task_execution_on_node = tg.node[task_to_be_mapped][ 'task'].wcet * node_speed_down completion_on_node = tg.node[task_to_be_mapped][ 'task'].release + task_execution_on_node Scheduling_Functions_Nodes.add_tg_task_to_node( tg, ag, task_to_be_mapped, chosen_node, tg.node[task_to_be_mapped]['task'].release, completion_on_node, None) print("\tTASK " + str(task_to_be_mapped) + " MAPPED ON NODE: " + str(chosen_node)) print("MIN COMPLETION TIME MAPPING FINISHED...") Scheduling_Reports.report_mapped_tasks(ag, logging) return tg, ag
def min_execution_time(tg, ag, shm, logging): """ :param tg: Task Graph :param ag: Architecture Graph :param shm: System Health Map :param logging: logging file :return: (TG, AG) """ # this sounds a little stupid because there are no job specific machines... # we can Add Specific Accelerators or define different run time on different # PEs so this becomes more interesting... print("===========================================") print("STARTING MIN EXECUTION TIME MAPPING") for task_to_be_mapped in tg.nodes(): chosen_node = random.choice(Mapping_Functions.fastest_nodes(ag, shm)) tg.node[task_to_be_mapped]['task'].node = chosen_node ag.node[chosen_node]['PE'].mapped_tasks.append(task_to_be_mapped) ag.node[chosen_node]['PE'].utilization += tg.node[task_to_be_mapped][ 'task'].wcet node_speed_down = 1 + ( (100.0 - shm.node[chosen_node]['NodeSpeed']) / 100) task_execution_on_node = tg.node[task_to_be_mapped][ 'task'].wcet * node_speed_down completion_on_node = tg.node[task_to_be_mapped][ 'task'].release + task_execution_on_node Scheduling_Functions_Nodes.add_tg_task_to_node( tg, ag, task_to_be_mapped, chosen_node, tg.node[task_to_be_mapped]['task'].release, completion_on_node, None) print("\tTASK " + str(task_to_be_mapped) + " MAPPED ON NODE: " + str(chosen_node)) print("MIN EXECUTION TIME MAPPING FINISHED...") Scheduling_Reports.report_mapped_tasks(ag, logging) return tg, ag
def find_test_task_asap_scheduling(tg, ag, shm, task, node, logging=None): """ :param tg: :param ag: :param shm: System Health Map :param task: :param node: :param logging: :return: """ predecessor_finish_time = task_predecessors_finish_time(tg, ag, task) start_time = Scheduling_Functions_Nodes.find_first_empty_slot_for_task_on_node(tg, ag, shm, node, task, predecessor_finish_time, logging) # This includes the aging and lower frequency of the nodes of graph... # however, we do not include fractions of a cycle so we take ceiling of the execution time node_speed_down = 1+((100.0-shm.node[node]['NodeSpeed'])/100) task_execution_on_node = ceil(tg.node[task]['task'].wcet*node_speed_down) end_time = start_time+task_execution_on_node return start_time, end_time
def find_task_asap_scheduling(tg, ag, shm, task, node, logging=None): """ :param tg: :param ag: :param shm: System Health Map :param task: :param node: :param logging: logging file :return: """ start_time = max(Scheduling_Functions_Nodes.find_last_allocated_time_on_node(ag, node, logging), task_predecessors_finish_time(tg, ag, task), tg.node[task]['task'].release) # This includes the aging and lower frequency of the nodes of graph... # however, we do not include fractions of a cycle so we take ceiling of the execution time node_speed_down = 1+((100.0-shm.node[node]['NodeSpeed'])/100) task_execution_on_node = ceil(tg.node[task]['task'].wcet*node_speed_down) if tg.node[task]['task'].criticality == 'H': end_time = start_time+task_execution_on_node + Config.Task_SlackCount*task_execution_on_node else: end_time = start_time+task_execution_on_node return start_time, end_time
def MinimumCompletionTime(TG, AG, SHM, logging): """ :param TG: Task Graph :param AG: Architecture Graph :param SHM: System Health Map :param logging: logging File :return: (TG, AG) """ # The difference with Min Min or Max Min is that we don't add priorities to # tasks based on their WCET but we randomly choose a task and schedule it... # Note :: This heuristic is not taking task ciriticality into account... print("===========================================") print("STARTING MIN COMPLETION TIME MAPPING") for TaskToBeMapped in TG.nodes(): ChosenNode = random.choice( Mapping_Functions.nodes_with_smallest_ct(AG, TG, SHM, TaskToBeMapped)) TG.node[TaskToBeMapped]['Node'] = ChosenNode AG.node[ChosenNode]['PE'].MappedTasks.append(TaskToBeMapped) AG.node[ChosenNode]['PE'].Utilization += TG.node[TaskToBeMapped][ 'WCET'] NodeSpeedDown = 1 + ((100.0 - SHM.node[ChosenNode]['NodeSpeed']) / 100) TaskExecutionOnNode = TG.node[TaskToBeMapped]['WCET'] * NodeSpeedDown CompletionOnNode = TG.node[TaskToBeMapped][ 'Release'] + TaskExecutionOnNode Scheduling_Functions_Nodes.Add_TG_TaskToNode( TG, AG, TaskToBeMapped, ChosenNode, TG.node[TaskToBeMapped]['Release'], CompletionOnNode, logging) print("\tTASK " + str(TaskToBeMapped) + " MAPPED ON NODE: " + str(ChosenNode)) print("MIN COMPLETION TIME MAPPING FINISHED...") Scheduling_Reports.report_mapped_tasks(AG, logging) return TG, AG
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
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