def print_system_config(cls): MdpLogger.write_log("################### " + ("EDGE SERVER" if cls._offloading_site_code in [OffloadingSiteCode.EDGE_DATABASE_SERVER, OffloadingSiteCode.EDGE_COMPUTATIONAL_INTENSIVE_SERVER, \ OffloadingSiteCode.EDGE_REGULAR_SERVER] else "CLOUD DATA CENTER") + " SYSTEM CONFIGURATION ###################") MdpLogger.write_log("Name: " + cls._name) MdpLogger.write_log("CPU: " + str(cls._mips) + " M cycles") MdpLogger.write_log("Memory: " + str(cls._memory) + " Gb") MdpLogger.write_log("Data Storage: " + str(cls._data_storage) + " Gb")
def remove_in_edge(cls, executed_task): if executed_task in cls._in_edges: cls._in_edges.remove(executed_task) return True else: MdpLogger.write_log("Task " + cls._name + " is not depended on executed task " + executed_task.get_name() + "!") return False
def check_validity_of_deployment(cls, task): if not isinstance(task, Task): MdpLogger.write_log("Task for execution on offloading site should be Task class instance!") return ExecutionErrorCode.EXE_NOK # check that task resouce requirements fits mobile device's resource capacity if cls._data_storage > (cls._data_storage_consumption + ((task.get_data_in() + task.get_data_out())) / GIGABYTES) and \ cls._memory > (cls._memory_consumption + task.get_memory()): return ExecutionErrorCode.EXE_OK return ExecutionErrorCode.EXE_NOK
def flush_executed_task(cls, task): if not isinstance(task, Task): MdpLogger.write_log("Task for execution on offloading site should be Task class instance!") return ExecutionErrorCode.EXE_NOK cls._memory_consumption = cls._memory_consumption - task.get_memory() cls._data_storage_consumption = cls._data_storage_consumption - ((task.get_data_in() + task.get_data_out()) / GIGABYTES) if cls._memory_consumption < 0 or cls._data_storage_consumption < 0: raise ValueError("Memory consumption: " + str(cls._memory_consumption) + "Gb, data storage consumption: " + str(cls._data_storage_consumption) + \ "Gb, both should be positive! Node: " + cls._name + ", task: " + task.get_name())
def execute(cls, task): print_text = "Task " if not isinstance(task, Task): MdpLogger.write_log("Task for execution on offloading site should be Task class instance!") return ExecutionErrorCode.EXE_NOK if not task.execute(): return ExecutionErrorCode.EXE_NOK print_text = print_text + task.get_name() task_data_storage_consumption = task.get_data_in() + task.get_data_out() task_memory_consumption = task.get_memory() cls._data_storage_consumption = cls._data_storage_consumption + (task_data_storage_consumption / GIGABYTES) cls._memory_consumption = cls._memory_consumption + task_memory_consumption #MdpLogger.write_log(print_text + " (off = " + str(task.is_offloadable()) + ") is executed on MOBILE_DEVICE!") return ExecutionErrorCode.EXE_OK
def execute(cls): if cls._execute: MdpLogger.write_log( "Task " + cls._name + " cannot be executed since it is already been executed!") return ExecutionErrorCode.EXE_NOK elif cls._in_edges: MdpLogger.write_log( "Task " + cls._name + " cannot be executed since other dependable tasks " + str(cls._in_edges) + " are not executed!") return ExecutionErrorCode.EXE_NOK else: # input edges of next task are removed since current task is executed for task in cls._out_edges: if not task.remove_in_edge(cls): # application execution is not valid according to DAG graph MdpLogger.write_log( "Invalid task dependancy during application execution!" ) return ExecutionErrorCode.EXE_NOK # remove all output edges of the current executed task cls._out_edges = [] # tag this task as executed cls._execute = True return ExecutionErrorCode.EXE_OK
def get_ready_tasks(cls): ready_tasks = () if not cls._running: MdpLogger.write_log("You have to run " + cls._name + " application before you start execution!") return False for task in cls._delay_dict: if not task.get_in_edges() and not task.is_executed(): ready_tasks = ready_tasks + (task, ) # if there are no ready tasks, then tasks should be executed if not ready_tasks: for task in cls._delay_dict: if not task.is_executed(): MdpLogger.write_log( cls._name + " application is not executed entirely but it should!") MdpLogger.write_log( "There are no ready tasks but not all tasks are tagged as executed!" ) MdpLogger.write_log( "Error in application execution order!") MdpLogger.write_log( "Task " + task.get_name() + " is not executed but there are no ready tasks for execution!" ) return False #MdpLogger.write_log(cls._name + " application is EXECUTED!\n") cls.print_task_exe_status() # reset all application tasks for new future executions cls.__init_task_dependencies() # if all tasks are executed then application is not running anymore cls._running = False return ready_tasks
def __evaluate_params(cls, mobile_device, edge_servers, cloud_dc, network): # if not isinstance(mobile_device, MobileDevice): # return False if not isinstance(cloud_dc, OffloadingSite): MdpLogger.write_log( "Cloud data center should be OffloadingSite object instance in ODE class!" ) return False if not edge_servers: MdpLogger.write_log( "Edge servers should not be empty in ODE class!") return False for edge in edge_servers: if not isinstance(edge, OffloadingSite): MdpLogger.write_log( "Edge servers should be OffloadingSite object instance in ODE class!" ) return False if not (cloud_dc.get_offloading_site_code() == OffloadingSiteCode.CLOUD_DATA_CENTER): MdpLogger.write_log( "Cloud data center should be configured as cloud data center in ODE class!" ) return False for edge in edge_servers: if not (edge.get_offloading_site_code() in [OffloadingSiteCode.EDGE_DATABASE_SERVER, OffloadingSiteCode.EDGE_COMPUTATIONAL_INTENSIVE_SERVER, \ OffloadingSiteCode.EDGE_REGULAR_SERVER]): MdpLogger.write_log( "Edge server should be configured as edge server in ODE class!" ) return False return True
def run(cls, samplings, executions, mixed_mode, sensitivity_analysis): if cls._ode: cls._sensitivity_analysis = sensitivity_analysis previous_progress = 0 current_progress = 0 if cls._sensitivity_analysis: sensitivity_params = [] for i in range(0, 11): sensitivity_params.append((round(i / 10, 1), round(1 - i / 10, 1))) else: sensitivity_params = [(0.5, 0.5)] print("Sensitivity parameters: " + str(sensitivity_params) + '\n') print("**************** PROGRESS with " + cls._ode.get_name() + "****************") # Logger.write_log("######################### " + cls._ode.get_name() + " application trace logs #########################") print(str(previous_progress) + "% - " + str(datetime.datetime.utcnow())) for sens_params in sensitivity_params: cls._ode.set_sensitivity_params(sens_params[0], sens_params[1]) # diff_time = [] # diff_energy = [] # diff_fail_time = [] # diff_fail_energy = [] applications = ['ANTIVIRUS', 'GPS_NAVIGATOR', 'FACERECOGNIZER', 'FACEBOOK', 'CHESS'] for i in range(samplings): # print("Currently used sensitivity params: " + str(sens_params)) application_time_completion = 0 # measure total application completion time during execution application_energy_consumption = 0 # measure total application energy consumption during execution application_overall_rewards = 0 # measure total application overall rewards during execution application_fail_time_completion = 0 application_fail_energy_consumption = 0 application_failures = 0 # reset test data after each simulation sampling to start from the beginning for edge in cls._edge_servers: edge.reset_test_data() cls._cloud_dc.reset_test_data() # simulate application executions for j in range(executions): if mixed_mode: choice = np.random.choice(5, 1, p = [0.05, 0.3, 0.1, 0.45, 0.1])[0] if choice == 0: cls.deploy_antivirus_application() elif choice == 1: cls.deploy_gps_navigator_application() elif choice == 2: cls.deploy_facerecognizer_application() elif choice == 3: cls.deploy_facebook_application() elif choice == 4: cls.deploy_chess_application() cls._ode.save_app_name(cls._mobile_app.get_name()) previous_progress = current_progress current_progress = round((j + (i * executions)) / (samplings * executions) * 100) if current_progress != previous_progress and (current_progress % PROGRESS_REPORT_INTERVAL == 0): print(str(current_progress) + "% - " + str(datetime.datetime.utcnow())) cls._mobile_app.run() ready_tasks = cls._mobile_app.get_ready_tasks() single_app_exe_task_comp = 0 single_app_exe_energy_consum = 0 while ready_tasks: # MdpLogger.write_log('##############################################################') # MdpLogger.write_log('##################### RESOURCE CONSUMPTION ###################') # MdpLogger.write_log('##############################################################\n') cls._discrete_epoch_counter = cls._discrete_epoch_counter + 1 #MdpLogger.write_log("********************* " + str(cls._discrete_epoch_counter) + ". DISCRETE EPOCH *********************") (task_completion_time, task_energy_consumption, task_overall_reward, task_failure_time_cost,\ task_failure_energy_cost, task_failures) = cls._ode.offload(ready_tasks) ready_tasks = cls._mobile_app.get_ready_tasks() application_time_completion = round(application_time_completion + task_completion_time, 3) application_fail_time_completion += round(task_failure_time_cost, 3) single_app_exe_task_comp = round(single_app_exe_task_comp + task_completion_time, 3) # MdpLogger.write_log('\nFilename: ' + getframeinfo(currentframe()).filename + ', Line = ' + str(getframeinfo(currentframe()).lineno)) # MdpLogger.write_log("Current application runtime: " + str(application_time_completion) + " s") application_energy_consumption = round(application_energy_consumption + task_energy_consumption, 3) application_fail_energy_consumption = round(application_fail_energy_consumption + task_failure_energy_cost, 3) single_app_exe_energy_consum = round(single_app_exe_energy_consum + task_energy_consumption, 3) # MdpLogger.write_log("Current application energy consumption: " + str(application_energy_consumption) + " J") application_failures += task_failures application_overall_rewards = round(application_overall_rewards + task_overall_reward, 3) # MdpLogger.write_log("Current application overall rewards: " + str(application_overall_rewards) + '\n') # MdpLogger.write_log('Task application runtime: ' + str(task_completion_time) + 's') # MdpLogger.write_log('Task energy consumption: ' + str(task_energy_consumption) + 'J') # MdpLogger.write_log('Task rewards: ' + str(task_overall_reward)) # MdpLogger.write_log('Task failure time cost:' + str(task_failure_time_cost) + 's') cls._mobile_app.print_task_exe_status() # deploy facebook mobile application for further execution cls.__reset_application() cls._ode.get_statistics().add_time_comp_single_app_exe(single_app_exe_task_comp) cls._ode.get_statistics().add_energy_consum_single_app_exe(single_app_exe_energy_consum) # if len(diff_time) != 0: # diff_time.append(application_time_completion - np.sum(diff_time)) # diff_energy.append(application_energy_consumption - np.sum(diff_energy)) # diff_fail_time.append(application_fail_time_completion - np.sum(diff_fail_time)) # diff_fail_energy.append(application_fail_energy_consumption - np.sum(diff_fail_energy)) # else: # diff_time.append(application_time_completion) # diff_energy.append(application_energy_consumption) # diff_fail_time.append(application_fail_time_completion) # diff_fail_energy.append(application_fail_energy_consumption) cls._ode.get_statistics().add_time_comp(application_time_completion) cls._ode.get_statistics().add_energy_eff(application_energy_consumption) cls._ode.get_statistics().add_reward(application_overall_rewards) cls._ode.get_statistics().add_failure_rate(application_failures) cls.__reset_offloading_site_discrete_epoch_counters() cls._stats_log = cls._stats_log + (cls._ode, ) # for stats in cls._stats_log: # ("ODE name: " + stats.get_name()) if mixed_mode: app_name = 'MIXED MODE' else: app_name = cls._mobile_app.get_name() MdpLogger.write_log('\nFilename: ' + getframeinfo(currentframe()).filename + ', Line = ' + str(getframeinfo(currentframe()).lineno)) MdpLogger.write_log('##############################################################') MdpLogger.write_log('################## ' + cls._ode.get_name() + ' OFFLOADING RESULT SUMMARY #################') MdpLogger.write_log('################## ' + app_name + ' ###########################################') MdpLogger.write_log('##############################################################\n') MdpLogger.write_log("Time mean: " + str(cls._ode.get_statistics().get_time_completion_mean()) + ' s') MdpLogger.write_log("Time variance: " + str(cls._ode.get_statistics().get_time_completion_var()) + ' s\n') # MdpLogger.write_log("Failure time cost mean: " + str(np.mean(diff_fail_time)) + ' s') # MdpLogger.write_log("Failure time cost variance: " + str(np.var(diff_fail_time)) + ' s\n') MdpLogger.write_log("Energy mean: " + str(cls._ode.get_statistics().get_energy_consumption_mean()) + ' J') MdpLogger.write_log("Energy variance: " + str(cls._ode.get_statistics().get_energy_consumption_var()) + ' J\n') MdpLogger.write_log("Offloading failure rate mean: " + str(cls._ode.get_statistics().get_failure_rates_mean()) + ' failures') MdpLogger.write_log("Offloading failure rate variance: " + str(cls._ode.get_statistics().get_failure_rates_var()) + ' failures\n') # MdpLogger.write_log("Failure energy cost mean: " + str(np.mean(diff_fail_energy)) + ' J') # MdpLogger.write_log("Failure energy cost variance: " + str(np.var(diff_fail_energy)) + ' J\n') # MdpLogger.write_log("Mobile application runtime: " + str(application_time_completion) + ' s') # MdpLogger.write_log("Mobile device energy consumption: " + str(application_energy_consumption) + ' J\n') MdpLogger.write_log("Offloading distribution: " + \ str(cls._ode.get_statistics().get_offloading_distribution())) MdpLogger.write_log("Offloading distribution relative: " + \ str(cls._ode.get_statistics().get_offloading_distribution_relative())) MdpLogger.write_log("Num of offloadings: " + \ str(cls._ode.get_statistics().get_num_of_offloadings()) + '\n') text = "" all_failures = 0 for edge in cls._edge_servers: all_failures += edge.get_failure_cnt() text += edge.get_name() + ': ' + str(edge.get_failure_cnt()) + ', ' all_failures += cls._cloud_dc.get_failure_cnt() text += cls._cloud_dc.get_name() + ': ' + str(cls._cloud_dc.get_failure_cnt()) MdpLogger.write_log("Failure frequency occurence: " + text) text = "" for edge in cls._edge_servers: text += edge.get_name() + ': ' + str(round(edge.get_failure_cnt() / all_failures * 100, 2)) + ', ' text += cls._cloud_dc.get_name() + ': ' + str(round(cls._cloud_dc.get_failure_cnt() / all_failures * 100, 2)) MdpLogger.write_log("Relative failure frequency occurence: " + text) MdpLogger.write_log("Num of failures: " + str(all_failures) + '\n') MdpLogger.write_log("Offloading failure distribution: " + \ str(cls._ode.get_statistics().get_offloading_failure_frequencies())) MdpLogger.write_log("Offloading failure frequency relative: " + \ str(cls._ode.get_statistics().get_offloading_failure_relative())) MdpLogger.write_log("Num of offloading failures: " + \ str(cls._ode.get_statistics().get_num_of_offloading_failures()) + '\n') MdpLogger.write_log('Offloading site datasets:') for edge in cls._edge_servers: MdpLogger.write_log(edge.get_name() + ' ' + str(edge.get_node_candidate())) MdpLogger.write_log(cls._cloud_dc.get_name() + ' ' + str(cls._cloud_dc.get_node_candidate())) if isinstance(cls._ode, LocalOde): cls.deploy_local_ode() elif isinstance(cls._ode, EfpoOde): cls.deploy_efpo_ode() elif isinstance(cls._ode, EnhancedEfpoOde): cls.deploy_enhanced_efpo_ode() elif isinstance(cls._ode, MobileCloudOde): cls.deploy_mobile_cloud_ode() elif isinstance(cls._ode, EnergyEfficientOde): cls.deploy_energy_efficient_ode() for edge in cls._edge_servers: edge.reset_failure_cnt() cls._cloud_dc.reset_failure_cnt() else: MdpLogger.write_log("You need to DEPLOY mobile application AND offloading decision engine on mobile device before you execute it!") MdpLogger.write_log('\n')