diff --git a/.gitignore b/.gitignore index af5efaf..0e113b8 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,9 @@ Desktop.ini # bin folder bin +# simulation output folder +sim_results + # eclipse's files .settings .classpath diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 42df42c..38220c1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,7 +37,7 @@ If you want to specify more things, add additional notes here # How to Contribute to EdgeCloudSim -You can simply follow below steps to contribute to EdgeClouldSim: +You can simply follow below steps to contribute to EdgeCloudSim: 1. Create a working copy (fork the project & clone it) 2. Specify a new remote upstream repository diff --git a/README.md b/README.md index e88f05f..204153d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ EdgeCloudSim provides a simulation environment specific to Edge Computing scenar The discussion forum for EdgeCloudSim can be found [here](https://groups.google.com/forum/#!forum/edgecloudsim). We hope to meet with all interested parties in this forum. -Please feel free to join and let us discuss issues, share ideas related to EdgeCloudSim all togerther. +Please feel free to join and let us discuss issues, share ideas related to EdgeCloudSim all together. ## Needed Features @@ -112,3 +112,7 @@ You can plot lots of graphics by using the result of EdgeCloudSim. Some examples **[2]** C. Sonmez, A. Ozgovde and C. Ersoy, "[Performance evaluation of single-tier and two-tier cloudlet assisted applications](http://ieeexplore.ieee.org/document/7962674/)," *2017 IEEE International Conference on Communications Workshops (ICC Workshops)*, Paris, 2017, pp. 302-307. **[3]** Sonmez C, Ozgovde A, Ersoy C. "[EdgeCloudSim: An environment for performance evaluation of Edge Computing systems](https://onlinelibrary.wiley.com/doi/abs/10.1002/ett.3493)," *Transactions on Emerging Telecommunications Technologies*, 2018;e3493. + +**[4]** C. Sonmez, A. Ozgovde and C. Ersoy, "[Fuzzy Workload Orchestration for Edge Computing](https://ieeexplore.ieee.org/abstract/document/8651335/)," in *IEEE Transactions on Network and Service Management*, vol. 16, no. 2, pp. 769-782, June 2019. + +**[5]** C. Sonmez, A. Ozgovde and C. Ersoy, "[Machine Learning-Based Workload Orchestrator for Vehicular Edge Computing](https://ieeexplore.ieee.org/abstract/document/9208723/)," in *IEEE Transactions on Intelligent Transportation Systems*, doi: 10.1109/TITS.2020.3024233. diff --git a/doc/images/sample_app5/ml_details.png b/doc/images/sample_app5/ml_details.png new file mode 100644 index 0000000..1e1384c Binary files /dev/null and b/doc/images/sample_app5/ml_details.png differ diff --git a/doc/images/sample_app5/ml_stages.png b/doc/images/sample_app5/ml_stages.png new file mode 100644 index 0000000..a8535f4 Binary files /dev/null and b/doc/images/sample_app5/ml_stages.png differ diff --git a/doc/images/sample_app5/road.png b/doc/images/sample_app5/road.png new file mode 100644 index 0000000..3409891 Binary files /dev/null and b/doc/images/sample_app5/road.png differ diff --git a/doc/images/sample_app5/vec_architecture.png b/doc/images/sample_app5/vec_architecture.png new file mode 100644 index 0000000..6fb6d49 Binary files /dev/null and b/doc/images/sample_app5/vec_architecture.png differ diff --git a/lib/mtj-1.0.4.jar b/lib/mtj-1.0.4.jar new file mode 100644 index 0000000..8d0d0f0 Binary files /dev/null and b/lib/mtj-1.0.4.jar differ diff --git a/lib/weka.jar b/lib/weka.jar new file mode 100644 index 0000000..4d7dbe6 Binary files /dev/null and b/lib/weka.jar differ diff --git a/scripts/sample_app1/config/default_config.properties b/scripts/sample_app1/config/default_config.properties index a8462a0..f1c9f28 100644 --- a/scripts/sample_app1/config/default_config.properties +++ b/scripts/sample_app1/config/default_config.properties @@ -2,7 +2,7 @@ simulation_time=30 warm_up_period=3 vm_load_check_interval=0.1 -vm_location_check_interval=0.1 +location_check_interval=0.1 file_log_enabled=true deep_file_log_enabled=false @@ -10,7 +10,7 @@ min_number_of_mobile_devices=100 max_number_of_mobile_devices=1000 mobile_device_counter_size=100 -wan_propogation_delay=0.1 +wan_propagation_delay=0.1 lan_internal_delay=0.005 wlan_bandwidth=200 wan_bandwidth=15 diff --git a/scripts/sample_app1/matlab/plotGenericResult.m b/scripts/sample_app1/matlab/plotGenericResult.m index be15845..9e92ba8 100644 --- a/scripts/sample_app1/matlab/plotGenericResult.m +++ b/scripts/sample_app1/matlab/plotGenericResult.m @@ -21,7 +21,7 @@ function [] = plotGenericResult(rowOfset, columnOfset, yLabel, appType, calculat for j=1:numOfMobileDevices try mobileDeviceNumber = startOfMobileDeviceLoop + stepOfMobileDeviceLoop * (j-1); - filePath = strcat(folderPath,'\ite',int2str(s),'\SIMRESULT_',char(scenarioType(i)),'_NEXT_FIT_',int2str(mobileDeviceNumber),'DEVICES_',appType,'_GENERIC.log') + filePath = strcat(folderPath,'\ite',int2str(s),'\SIMRESULT_',char(scenarioType(i)),'_NEXT_FIT_',int2str(mobileDeviceNumber),'DEVICES_',appType,'_GENERIC.log'); readData = dlmread(filePath,';',rowOfset,0); value = readData(1,columnOfset); diff --git a/scripts/sample_app1/matlab/plotTaskFailureReason.m b/scripts/sample_app1/matlab/plotTaskFailureReason.m index d8f2c8e..54f94bb 100644 --- a/scripts/sample_app1/matlab/plotTaskFailureReason.m +++ b/scripts/sample_app1/matlab/plotTaskFailureReason.m @@ -1,27 +1,27 @@ function [] = plotTaskFailureReason() plotGenericResult(1, 10, 'Failed Task due to VM Capacity (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(1, 11, 'Failed Task due to Mobility (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 5, 'Failed Tasks due to WLAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 7, 'Failed Tasks due to WAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); end \ No newline at end of file diff --git a/scripts/sample_app2/config/default_config.properties b/scripts/sample_app2/config/default_config.properties index 3f37780..75e9047 100644 --- a/scripts/sample_app2/config/default_config.properties +++ b/scripts/sample_app2/config/default_config.properties @@ -2,7 +2,7 @@ simulation_time=30 warm_up_period=3 vm_load_check_interval=0.1 -vm_location_check_interval=0.1 +location_check_interval=0.1 file_log_enabled=true deep_file_log_enabled=false @@ -10,7 +10,7 @@ min_number_of_mobile_devices=200 max_number_of_mobile_devices=2000 mobile_device_counter_size=200 -wan_propogation_delay=0.1 +wan_propagation_delay=0.1 lan_internal_delay=0.005 wlan_bandwidth=0 wan_bandwidth=0 diff --git a/scripts/sample_app2/matlab/plotTaskFailureReason.m b/scripts/sample_app2/matlab/plotTaskFailureReason.m index 4e71b7f..a808001 100644 --- a/scripts/sample_app2/matlab/plotTaskFailureReason.m +++ b/scripts/sample_app2/matlab/plotTaskFailureReason.m @@ -1,33 +1,33 @@ function [] = plotTaskFailureReason() plotGenericResult(1, 10, 'Failed Task due to VM Capacity (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(1, 11, 'Failed Task due to Mobility (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 5, 'Failed Tasks due to WLAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 6, 'Failed Tasks due to MAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 7, 'Failed Tasks due to WAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); end \ No newline at end of file diff --git a/scripts/sample_app3/config/default_config.properties b/scripts/sample_app3/config/default_config.properties index a19a3ac..7c4fe34 100644 --- a/scripts/sample_app3/config/default_config.properties +++ b/scripts/sample_app3/config/default_config.properties @@ -2,7 +2,7 @@ simulation_time=33 warm_up_period=3 vm_load_check_interval=0.1 -vm_location_check_interval=0.1 +location_check_interval=0.1 file_log_enabled=true deep_file_log_enabled=false @@ -10,7 +10,7 @@ min_number_of_mobile_devices=200 max_number_of_mobile_devices=2000 mobile_device_counter_size=200 -wan_propogation_delay=0.1 +wan_propagation_delay=0.1 lan_internal_delay=0.005 wlan_bandwidth=0 wan_bandwidth=0 diff --git a/scripts/sample_app3/matlab/plotTaskFailureReason.m b/scripts/sample_app3/matlab/plotTaskFailureReason.m index e6216a0..daa6991 100644 --- a/scripts/sample_app3/matlab/plotTaskFailureReason.m +++ b/scripts/sample_app3/matlab/plotTaskFailureReason.m @@ -1,20 +1,20 @@ function [] = plotTaskFailureReason() plotGenericResult(1, 10, 'Failed Task due to VM Capacity (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(1, 11, 'Failed Task due to Mobility (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(1, 4, 'Failed Tasks due to Network failure (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); end \ No newline at end of file diff --git a/scripts/sample_app4/config/default_config.properties b/scripts/sample_app4/config/default_config.properties index 027d409..879a804 100644 --- a/scripts/sample_app4/config/default_config.properties +++ b/scripts/sample_app4/config/default_config.properties @@ -2,7 +2,7 @@ simulation_time=33 warm_up_period=3 vm_load_check_interval=0.1 -vm_location_check_interval=0.1 +location_check_interval=0.1 file_log_enabled=true deep_file_log_enabled=false @@ -10,7 +10,7 @@ min_number_of_mobile_devices=200 max_number_of_mobile_devices=2400 mobile_device_counter_size=200 -wan_propogation_delay=0.1 +wan_propagation_delay=0.1 lan_internal_delay=0.005 wlan_bandwidth=0 wan_bandwidth=0 diff --git a/scripts/sample_app4/matlab/plotTaskFailureReason.m b/scripts/sample_app4/matlab/plotTaskFailureReason.m index 2bd25b8..0bfee09 100755 --- a/scripts/sample_app4/matlab/plotTaskFailureReason.m +++ b/scripts/sample_app4/matlab/plotTaskFailureReason.m @@ -1,31 +1,31 @@ function [] = plotTaskFailureReason() plotGenericResult(1, 10, 'Failed Task due to VM Capacity (%)', 'ALL_APPS', 'percentage_for_failed'); -% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); -% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); -% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); -% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); +% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); +% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); +% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); +% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(1, 11, 'Average Failed Task due to Mobility (%)', 'ALL_APPS', 'percentage_for_failed'); -% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); -% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); -% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); -% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); +% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); +% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); +% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); +% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 4, 'Failed Tasks due to WLAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); -% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); -% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); -% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); -% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); +% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); +% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); +% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); +% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 5, 'Failed Tasks due to MAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); -% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); -% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); -% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); -% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); +% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); +% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); +% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); +% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 6, 'Failed Tasks due to WAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); -% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); -% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); -% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); -% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); +% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); +% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); +% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); +% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); end diff --git a/scripts/sample_app5/.gitignore b/scripts/sample_app5/.gitignore new file mode 100644 index 0000000..53752db --- /dev/null +++ b/scripts/sample_app5/.gitignore @@ -0,0 +1 @@ +output diff --git a/scripts/sample_app5/ai_trainer/.gitignore b/scripts/sample_app5/ai_trainer/.gitignore new file mode 100644 index 0000000..6b468b6 --- /dev/null +++ b/scripts/sample_app5/ai_trainer/.gitignore @@ -0,0 +1 @@ +*.class diff --git a/scripts/sample_app5/ai_trainer/README.md b/scripts/sample_app5/ai_trainer/README.md new file mode 100644 index 0000000..70b058a --- /dev/null +++ b/scripts/sample_app5/ai_trainer/README.md @@ -0,0 +1,23 @@ +# Configure Simulation Settings + +Firstly, edit config.json file in a way to declare the configuration of the simulation process used to collect training data + +# Preparing Training Data + +Invoke following command to convert collected data format for weka models + +``` +./generate_training_data.sh +``` + +This command creates *.arff files under the simulation results folder + +# Generating Classification and Regression Models + +Invoke following command to generate related weka models + +``` +./generate_weka_models.sh +``` + +This script creates weka model files under the simulation results folder. When you are done with training, you can move these files to ../config/weka/ folder diff --git a/scripts/sample_app5/ai_trainer/WekaModelCreator.java b/scripts/sample_app5/ai_trainer/WekaModelCreator.java new file mode 100644 index 0000000..6747fe0 --- /dev/null +++ b/scripts/sample_app5/ai_trainer/WekaModelCreator.java @@ -0,0 +1,208 @@ +import java.io.FileReader; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; + +import weka.classifiers.Evaluation; +import weka.classifiers.bayes.NaiveBayes; +import weka.classifiers.functions.LinearRegression; +import weka.classifiers.functions.MultilayerPerceptron; +import weka.classifiers.functions.SMO; +import weka.classifiers.functions.SMOreg; +import weka.core.Instances; +import weka.core.converters.ConverterUtils.DataSource; + +public class WekaModelCreator { + private static final String[] targets = {"edge","cloud_rsu","cloud_gsm"}; + + public static void main(String[] args) throws Exception { + String dataPath = ""; + String classifier = ""; + String regressor = ""; + + JSONParser parser = new JSONParser(); + try + { + Object object = parser.parse(new FileReader(args[0])); + + //convert Object to JSONObject + JSONObject jsonObject = (JSONObject)object; + + //Reading the String + dataPath = (String) jsonObject.get("sim_result_folder"); + classifier = (String) jsonObject.get("classifier"); + regressor = (String) jsonObject.get("regressor"); + } + catch(Exception e) + { + e.printStackTrace(); + System.exit(1); + } + + System.out.println("######### TRAINING FOR " + dataPath + " #########"); + for(int i=0; i0) + result += diffInDays + ((diffInDays>1 == true) ? " Days " : " Day "); + if(diffInHours>0) + result += diffInHours % 24 + ((diffInHours>1 == true) ? " Hours " : " Hour "); + if(diffInMinutes>0) + result += diffInMinutes % 60 + ((diffInMinutes>1 == true) ? " Minutes " : " Minute "); + if(diffInSeconds>0) + result += diffInSeconds % 60 + ((diffInSeconds>1 == true) ? " Seconds" : " Second"); + if(diffInMilli>0 && result.isEmpty()) + result += diffInMilli + ((diffInMilli>1 == true) ? " Milli Seconds" : " Milli Second"); + + return result; + } +} diff --git a/scripts/sample_app5/ai_trainer/config.json b/scripts/sample_app5/ai_trainer/config.json new file mode 100644 index 0000000..6b10e52 --- /dev/null +++ b/scripts/sample_app5/ai_trainer/config.json @@ -0,0 +1,10 @@ +{ + "sim_result_folder": "/home/cagatay/Projects/git-repos/EdgeCloudSim/scripts/sample_app5/output/18-10-2019_21-16/default_config", + "num_iterations": 10, + "train_data_ratio": 80, + "min_vehicle": 100, + "max_vehicle": 2200, + "vehicle_step_size": 100, + "classifier": "MultilayerPerceptron", + "regressor": "LinearRegression" +} diff --git a/scripts/sample_app5/ai_trainer/data_convertor.py b/scripts/sample_app5/ai_trainer/data_convertor.py new file mode 100644 index 0000000..8df314f --- /dev/null +++ b/scripts/sample_app5/ai_trainer/data_convertor.py @@ -0,0 +1,133 @@ +import pandas as pd +import json +import sys + +if len (sys.argv) != 5: + print('invalid arguments. Usage:') + print('python data_conventor.py config.json [edge|cloud_rsu|cloud_gsm] [classifier|regression] [train|test]') + sys.exit(1) + +with open(sys.argv[1]) as json_data_file: + data = json.load(json_data_file) + +target = sys.argv[2] +method = sys.argv[3] +datatype = sys.argv[4] + +print("conversion started with args " + target + ", " + method + ", " + datatype) + +sim_result_folder = data["sim_result_folder"] +num_iterations = data["num_iterations"] +train_data_ratio = data["train_data_ratio"] +min_vehicle = data["min_vehicle"] +max_vehicle = data["max_vehicle"] +vehicle_step_size = data["vehicle_step_size"] + +def getDecisionColumnName(target): + if target == "edge": + COLUMN_NAME = "EDGE" + elif target == "cloud_rsu": + COLUMN_NAME = "CLOUD_VIA_RSU" + elif target == "cloud_gsm": + COLUMN_NAME = "CLOUD_VIA_GSM" + return COLUMN_NAME + +def getClassifierColumns(target): + if target == "edge": + result = ["NumOffloadedTask", "TaskLength", "WLANUploadDelay", "WLANDownloadDelay", "AvgEdgeUtilization", "Result"] + elif target == "cloud_rsu": + result = ["NumOffloadedTask", "WANUploadDelay", "WANDownloadDelay", "Result"] + elif target == "cloud_gsm": + result = ["NumOffloadedTask", "GSMUploadDelay", "GSMDownloadDelay", "Result"] + return result + +def getRegressionColumns(target): + if target == "edge": + result = ["TaskLength", "AvgEdgeUtilization", "ServiceTime"] + elif target == "cloud_rsu": + result = ["TaskLength", "WANUploadDelay", "WANDownloadDelay", "ServiceTime"] + elif target == "cloud_gsm": + result = ["TaskLength", "GSMUploadDelay", "GSMDownloadDelay", "ServiceTime"] + return result + +def znorm(column): + column = (column - column.mean()) / column.std() + return column + +data_set = [] + +testDataStartIndex = (train_data_ratio * num_iterations) / 100 + +for ite in range(num_iterations): + for vehicle in range(min_vehicle, max_vehicle+1, vehicle_step_size): + if (datatype == "train" and ite < testDataStartIndex) or (datatype == "test" and ite >= testDataStartIndex): + file_name = sim_result_folder + "/ite" + str(ite + 1) + "/" + str(vehicle) + "_learnerOutputFile.cvs" + df = [pd.read_csv(file_name, na_values = "?", comment='\t', sep=",")] + df[0]['VehicleCount'] = vehicle + #print(file_name) + data_set += df + +data_set = pd.concat(data_set, ignore_index=True) +data_set = data_set[data_set['Decision'] == getDecisionColumnName(target)] + +if method == "classifier": + targetColumns = getClassifierColumns(target) +else: + targetColumns= getRegressionColumns(target) + +if datatype == "train": + print ("##############################################################") + print ("Stats for " + target + " - " + method) + print ("Please use relevant information from below table in java side:") + train_stats = data_set[targetColumns].describe() + train_stats = train_stats.transpose() + print(train_stats) + print ("##############################################################") + +#print("balancing " + target + " for " + method) + +#BALANCE DATA SET +if method == "classifier": + df0 = data_set[data_set['Result']=="fail"] + df1 = data_set[data_set['Result']=="success"] + + #size = min(len(df0[df0['VehicleCount']==max_vehicle]), len(df1[df1['VehicleCount']==min_vehicle])) + + size = len(df0[df0['VehicleCount']==max_vehicle]) // 2 + + df1 = df1.groupby('VehicleCount').apply(lambda x: x if len(x) < size else x.sample(size)) + df0 = df0.groupby('VehicleCount').apply(lambda x: x if len(x) < size else x.sample(size)) + + data_set = pd.concat([df0, df1], ignore_index=True) +else: + data_set = data_set[data_set['Result'] == 'success'] + + #size = min(len(data_set[data_set['VehicleCount']==min_vehicle]), len(data_set[data_set['VehicleCount']==max_vehicle])) + + size = len(data_set[data_set['VehicleCount']==max_vehicle]) // 3 + data_set = data_set.groupby('VehicleCount').apply(lambda x: x if len(x.index) < size else x.sample(size)) + +#EXTRACT RELATED ATTRIBUTES +df = pd.DataFrame(columns=targetColumns) +for column in targetColumns: + if column == 'Result' or column == 'ServiceTime': + df[column] = data_set[column] + else: + df[column] = znorm(data_set[column]) + +f = open(sim_result_folder + "/" + target + "_" + method + "_" + datatype + ".arff", 'w') +f.write('@relation ' + target + '\n\n') +for column in targetColumns: + if column == 'Result': + f.write('@attribute class {fail,success}\n') + else: + f.write('@attribute ' + column + ' REAL\n') +f.write('\n@data\n') +df.to_csv(f, header=False, index=False) +f.close() + +print ("##############################################################") +print ("Operation completed!") +print (".arff file is generated for weka.") +print ("##############################################################") + diff --git a/scripts/sample_app5/ai_trainer/generate_training_data.sh b/scripts/sample_app5/ai_trainer/generate_training_data.sh new file mode 100644 index 0000000..103f5ae --- /dev/null +++ b/scripts/sample_app5/ai_trainer/generate_training_data.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +python data_convertor.py config.json edge classifier train +python data_convertor.py config.json edge classifier test +python data_convertor.py config.json edge regression train +python data_convertor.py config.json edge regression test +python data_convertor.py config.json cloud_rsu classifier train +python data_convertor.py config.json cloud_rsu classifier test +python data_convertor.py config.json cloud_rsu regression train +python data_convertor.py config.json cloud_rsu regression test +python data_convertor.py config.json cloud_gsm classifier train +python data_convertor.py config.json cloud_gsm classifier test +python data_convertor.py config.json cloud_gsm regression train +python data_convertor.py config.json cloud_gsm regression test diff --git a/scripts/sample_app5/ai_trainer/generate_weka_models.sh b/scripts/sample_app5/ai_trainer/generate_weka_models.sh new file mode 100644 index 0000000..b931f1e --- /dev/null +++ b/scripts/sample_app5/ai_trainer/generate_weka_models.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +javac -classpath "./json-simple-1.1.1.jar:../../../lib/weka.jar:../../../lib/mtj-1.0.4.jar" WekaModelCreator.java +java -classpath ".:./json-simple-1.1.1.jar:../../../lib/weka.jar:../../../lib/mtj-1.0.4.jar" WekaModelCreator config.json diff --git a/scripts/sample_app5/ai_trainer/json-simple-1.1.1.jar b/scripts/sample_app5/ai_trainer/json-simple-1.1.1.jar new file mode 100644 index 0000000..66347a6 Binary files /dev/null and b/scripts/sample_app5/ai_trainer/json-simple-1.1.1.jar differ diff --git a/scripts/sample_app5/compile.sh b/scripts/sample_app5/compile.sh new file mode 100644 index 0000000..c821e94 --- /dev/null +++ b/scripts/sample_app5/compile.sh @@ -0,0 +1,4 @@ +#!/bin/sh +rm -rf ../../bin +mkdir ../../bin +javac -classpath "../../lib/cloudsim-4.0.jar:../../lib/commons-math3-3.6.1.jar:../../lib/colt.jar:../../lib/weka.jar:../../lib/mtj-1.0.4.jar" -sourcepath ../../src ../../src/edu/boun/edgecloudsim/applications/vec_ai_app/VehicularMainApp.java -d ../../bin diff --git a/scripts/sample_app5/config/applications.xml b/scripts/sample_app5/config/applications.xml new file mode 100644 index 0000000..e621370 --- /dev/null +++ b/scripts/sample_app5/config/applications.xml @@ -0,0 +1,51 @@ + + + + 30 + 0 + 0.5 + 0.5 + 3 + 3600 + 1 + 20 + 20 + 3000 + 1 + 6 + 1.2 + 0 + + + 35 + 0 + 0.8 + 1 + 5 + 3600 + 1 + 40 + 20 + 10000 + 1 + 20 + 4 + 0 + + + 35 + 0 + 0.25 + 1.5 + 15 + 3600 + 1 + 20 + 80 + 20000 + 1 + 40 + 8 + 0 + + \ No newline at end of file diff --git a/scripts/sample_app5/config/default_config.properties b/scripts/sample_app5/config/default_config.properties new file mode 100644 index 0000000..8d175e1 --- /dev/null +++ b/scripts/sample_app5/config/default_config.properties @@ -0,0 +1,53 @@ +#default config file +simulation_time=60 +warm_up_period=3 +file_log_enabled=true +deep_file_log_enabled=false + +#logging is disabled if it is 0 +vm_load_check_interval=0.025 + +#logging is disabled if it is 0 +location_check_interval=0.005 + +#logging is disabled if it is 0 +ap_delay_check_interval=0.1 + +min_number_of_mobile_devices=100 +max_number_of_mobile_devices=1800 +mobile_device_counter_size=100 + +wan_propogation_delay=0.15 +gsm_propogation_delay=0.16 +lan_internal_delay=0.01 +wlan_bandwidth=10 +man_bandwidth=1000 +wan_bandwidth=50 +gsm_bandwidth=20 + +#all the host on cloud runs on a single datacenter +number_of_host_on_cloud_datacenter=1 +number_of_vm_on_cloud_host=20 +core_for_cloud_vm=2 +mips_for_cloud_vm=75000 +ram_for_cloud_vm=8000 +storage_for_cloud_vm=125000 + +#each mobile device has one host which serves one VM +#all the host runs on a single datacenter due to the out of memory (oom) issue +core_for_mobile_vm=1 +mips_for_mobile_vm=1000 +ram_for_mobile_vm=1800 +storage_for_mobile_vm=32000 + +#use ',' for multiple values +#orchestrator_policies=AI_TRAINER,RANDOM,PREDICTIVE,MAB,AI_BASED +orchestrator_policies=RANDOM,PREDICTIVE,GAME_THEORY,MAB,AI_BASED + +#use ',' for multiple values +simulation_scenarios=ITS_SCENARIO + +#mean waiting time in seconds +attractiveness_L1_mean_waiting_time=480 +attractiveness_L2_mean_waiting_time=240 +attractiveness_L3_mean_waiting_time=120 diff --git a/scripts/sample_app5/config/edge_devices.xml b/scripts/sample_app5/config/edge_devices.xml new file mode 100644 index 0000000..64e86ba --- /dev/null +++ b/scripts/sample_app5/config/edge_devices.xml @@ -0,0 +1,1364 @@ + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 200 + 0 + 0 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 600 + 0 + 1 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 1000 + 0 + 2 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 1400 + 0 + 3 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 1800 + 0 + 4 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 2200 + 0 + 5 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 2600 + 0 + 6 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 3000 + 0 + 7 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 3400 + 0 + 8 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 3800 + 0 + 9 + 0 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 4200 + 0 + 10 + 0 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 4600 + 0 + 11 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 5000 + 0 + 12 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 5400 + 0 + 13 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 5800 + 0 + 14 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 6200 + 0 + 15 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 6600 + 0 + 16 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 7000 + 0 + 17 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 7400 + 0 + 18 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 7800 + 0 + 19 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 8200 + 0 + 20 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 8600 + 0 + 21 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 9000 + 0 + 22 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 9400 + 0 + 23 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 9800 + 0 + 24 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 10200 + 0 + 25 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 10600 + 0 + 26 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 11000 + 0 + 27 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 11400 + 0 + 28 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 11800 + 0 + 29 + 0 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 12200 + 0 + 30 + 0 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 12600 + 0 + 31 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 13000 + 0 + 32 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 13400 + 0 + 33 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 13800 + 0 + 34 + 1 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 14200 + 0 + 35 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 14600 + 0 + 36 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 15000 + 0 + 37 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 15400 + 0 + 38 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + + 0.1 + 3.0 + 0.05 + 0.1 + + 15800 + 0 + 39 + 2 + + + + 4 + 20000 + 16000 + 250000 + + + 2 + 10000 + 8000 + 125000 + + + 2 + 10000 + 8000 + 125000 + + + + + + \ No newline at end of file diff --git a/scripts/sample_app5/config/weka/lr_cloud_gsm.model b/scripts/sample_app5/config/weka/lr_cloud_gsm.model new file mode 100644 index 0000000..92eb0a4 Binary files /dev/null and b/scripts/sample_app5/config/weka/lr_cloud_gsm.model differ diff --git a/scripts/sample_app5/config/weka/lr_cloud_rsu.model b/scripts/sample_app5/config/weka/lr_cloud_rsu.model new file mode 100644 index 0000000..1cac92a Binary files /dev/null and b/scripts/sample_app5/config/weka/lr_cloud_rsu.model differ diff --git a/scripts/sample_app5/config/weka/lr_edge.model b/scripts/sample_app5/config/weka/lr_edge.model new file mode 100644 index 0000000..ca37d6e Binary files /dev/null and b/scripts/sample_app5/config/weka/lr_edge.model differ diff --git a/scripts/sample_app5/config/weka/mlp_cloud_gsm.model b/scripts/sample_app5/config/weka/mlp_cloud_gsm.model new file mode 100644 index 0000000..bbf0304 Binary files /dev/null and b/scripts/sample_app5/config/weka/mlp_cloud_gsm.model differ diff --git a/scripts/sample_app5/config/weka/mlp_cloud_rsu.model b/scripts/sample_app5/config/weka/mlp_cloud_rsu.model new file mode 100644 index 0000000..d0e3e37 Binary files /dev/null and b/scripts/sample_app5/config/weka/mlp_cloud_rsu.model differ diff --git a/scripts/sample_app5/config/weka/mlp_edge.model b/scripts/sample_app5/config/weka/mlp_edge.model new file mode 100644 index 0000000..b85eb06 Binary files /dev/null and b/scripts/sample_app5/config/weka/mlp_edge.model differ diff --git a/scripts/sample_app5/matlab/getConfiguration.m b/scripts/sample_app5/matlab/getConfiguration.m new file mode 100644 index 0000000..8dcaea5 --- /dev/null +++ b/scripts/sample_app5/matlab/getConfiguration.m @@ -0,0 +1,60 @@ +%-------------------------------------------------------------- +%description +% returns a value according to the given argumentssss +%-------------------------------------------------------------- +function [ret_val] = getConfiguration(argType) + if(argType == 1) + ret_val = 'D:\sim_results'; + elseif(argType == 2) + ret_val = 60; %simulation time (in minutes) + elseif(argType == 3) + ret_val = 2; %Number of iterations + elseif(argType == 4) + ret_val = 2; %x tick interval for number of mobile devices + elseif(argType == 5) + ret_val = {'AI_BASED','MAB','GAME_THEORY','PREDICTIVE','RANDOM'}; + elseif(argType == 6) + ret_val = {'ML-based','MAB-based','Game-based','SMA-based','random'}; + elseif(argType == 7) + ret_val=[6 3 11 11]; %position of figure + %ret_val=[6 3 9 9]; %position of figure + elseif(argType == 8) + ret_val = [13 12 12]; %font fize for x/y label, lengend and x/y axis + elseif(argType == 9) + ret_val = 'Number of Vehicles'; %Common text for x axis + elseif(argType == 10) + ret_val = 100; %min number of mobile device + elseif(argType == 11) + ret_val = 100; %step size of mobile device count + elseif(argType == 12) + ret_val = 1800; %max number of mobile device + elseif(argType == 17) + ret_val = 0; %return 1 if you want to add 10^n text at x axis + elseif(argType == 18) + ret_val = 1; %return 1 if you want to save figure as pdf + elseif(argType == 19) + ret_val = 1; %return 1 if you want to plot errors + elseif(argType == 20) + ret_val=0; %return 1 if graph is plotted colerful + elseif(argType == 21) + ret_val=[0.55 0 0]; %color of first line + elseif(argType == 22) + ret_val=[0 0.15 0.6]; %color of second line + elseif(argType == 23) + ret_val=[0 0.23 0]; %color of third line + elseif(argType == 24) + ret_val=[0.6 0 0.6]; %color of fourth line + elseif(argType == 25) + ret_val=[0.08 0.08 0.08]; %color of fifth line + elseif(argType == 26) + ret_val=[0 0.8 0.8]; %color of sixth line + elseif(argType == 27) + ret_val=[0.8 0.4 0]; %color of seventh line + elseif(argType == 28) + ret_val=[0.8 0.8 0]; %color of eighth line + elseif(argType == 40) + ret_val={'-k*','-ko','-ks','-kv','-kp','-kd','-kx','-kh'}; %line style (marker) of the colerless line + elseif(argType == 50) + ret_val={'-k*','-ko','-ks','-kv','-kp','-kd','-kx','-kh'}; %line style (marker) of the colerfull line + end +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotApDelay.m b/scripts/sample_app5/matlab/plotApDelay.m new file mode 100644 index 0000000..1c4fda6 --- /dev/null +++ b/scripts/sample_app5/matlab/plotApDelay.m @@ -0,0 +1,113 @@ +function [] = plotApDelay() + folderPath = getConfiguration(1); + numOfSimulations = getConfiguration(3); + stepOfxAxis = getConfiguration(4); + startOfMobileDeviceLoop = getConfiguration(10); + stepOfMobileDeviceLoop = getConfiguration(11); + endOfMobileDeviceLoop = getConfiguration(12); + numOfMobileDevices = (endOfMobileDeviceLoop - startOfMobileDeviceLoop)/stepOfMobileDeviceLoop + 1; + placeTypes = {'AP 1 (60 km/h)','Ap 4 (40 km/h)','AP 11 (20 km/h)'}; + + results = zeros(size(placeTypes,2),numOfMobileDevices); + + for s=1:numOfSimulations + indexCounter = 1; + for i=startOfMobileDeviceLoop:stepOfMobileDeviceLoop:endOfMobileDeviceLoop + try + filePath1 = strcat(folderPath,'\ite',int2str(s),'\SIMRESULT_ITS_SCENARIO_AI_BASED_',int2str(i),'DEVICES_AP_UPLOAD_DELAY.log'); + filePath2 = strcat(folderPath,'\ite',int2str(s),'\SIMRESULT_ITS_SCENARIO_AI_BASED_',int2str(i),'DEVICES_AP_DOWNLOAD_DELAY.log'); + readData1 = dlmread(filePath1,';',60,0); + readData2 = dlmread(filePath2,';',60,0); + + for j=1:size(placeTypes,2) + results(j,indexCounter) = results(j,indexCounter) + mean(readData1(:,j+1)) + mean(readData2(:,j+1)); + end + catch err + error(err) + end + indexCounter = indexCounter + 1; + end + end + results = results/numOfSimulations; + + types = zeros(1,numOfMobileDevices); + for i=1:numOfMobileDevices + types(i)=startOfMobileDeviceLoop+((i-1)*stepOfMobileDeviceLoop); + end + + hFig = figure; + pos=getConfiguration(7); + fontSizeArray = getConfiguration(8); + set(hFig, 'Units','centimeters'); + set(hFig, 'Position',pos); + set(0,'DefaultAxesFontName','Times New Roman'); + set(0,'DefaultTextFontName','Times New Roman'); + set(0,'DefaultAxesFontSize',fontSizeArray(3)); + + if(getConfiguration(20) == 1) + for i=stepOfxAxis:stepOfxAxis:numOfMobileDevices + xIndex=startOfMobileDeviceLoop+((i-1)*stepOfMobileDeviceLoop); + + markers = {':k*',':ko',':ks',':kv'}; + for j=1:size(placeTypes,2) + plot(xIndex, results(j,i),char(markers(j)),'MarkerFaceColor',getConfiguration(20+j),'color',getConfiguration(20+j)); + hold on; + end + end + + for j=1:size(placeTypes,2) + plot(types, results(j,:),':k','color',getConfiguration(20+j),'LineWidth',1.5); + hold on; + end + + set(gca,'color','none'); + else + markers = {'-k*','-ko','-ks','-kv'}; + for j=1:size(placeTypes,2) + plot(types, results(j,:),char(markers(j)),'MarkerFaceColor','w','LineWidth',1.4); + hold on; + end + + %set(gcf, 'Position',getConfiguration(28)); + end + + lgnd = legend(placeTypes,'Location','NorthWest'); + if(getConfiguration(20) == 1) + set(lgnd,'color','none'); + end + + if(getConfiguration(20) == 1) + set(lgnd,'color','none'); + end + + if(getConfiguration(17) == 0) + manualXAxisCoefficent = 1; + end + + hold off; + axis square + xlabel(getConfiguration(9)); + set(gca,'XTick', startOfMobileDeviceLoop + stepOfMobileDeviceLoop:(stepOfxAxis*stepOfMobileDeviceLoop):endOfMobileDeviceLoop); + set(gca,'XTickLabel', startOfMobileDeviceLoop + stepOfMobileDeviceLoop/manualXAxisCoefficent:(stepOfxAxis*stepOfMobileDeviceLoop)/manualXAxisCoefficent:endOfMobileDeviceLoop/manualXAxisCoefficent); + ylabel('Average Network Delay (sec)'); + set(gca,'XLim',[startOfMobileDeviceLoop-5 endOfMobileDeviceLoop+5]); + + if(getConfiguration(17) == 1) + xlim = get(gca,'XLim'); + ylim = get(gca,'YLim'); + text(1.02 * xlim(2), 0.165 * ylim(2), 'x 10^2'); + end + + set(get(gca,'Xlabel'),'FontSize',fontSizeArray(1)); + set(get(gca,'Ylabel'),'FontSize',fontSizeArray(1)); + set(lgnd,'FontSize',fontSizeArray(2)); + + if(getConfiguration(18) == 1) + set(hFig, 'PaperUnits', 'centimeters'); + set(hFig, 'PaperPositionMode', 'manual'); + set(hFig, 'PaperPosition',[0 0 pos(3) pos(4)]); + set(gcf, 'PaperSize', [pos(3) pos(4)]); %Keep the same paper size + filename = strcat(folderPath,'\apDelay'); + saveas(gcf, filename, 'pdf'); + end +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotAvgFailedTask.m b/scripts/sample_app5/matlab/plotAvgFailedTask.m new file mode 100644 index 0000000..c961a65 --- /dev/null +++ b/scripts/sample_app5/matlab/plotAvgFailedTask.m @@ -0,0 +1,8 @@ +function [] = plotAvgFailedTask() + + plotGenericLine(1, 2, 'Average Failed Tasks (%)', 'ALL_APPS', 'NorthWest', 1); + plotGenericLine(1, 2, 'Failed Tasks for Danger Assessment App (%)', 'DANGER_ASSESSMENT', 'NorthWest', 1); + plotGenericLine(1, 2, 'Failed Tasks for Navigation App (%)', 'TRAFFIC_MANAGEMENT', 'NorthWest', 1); + plotGenericLine(1, 2, 'Failed Tasks for Infotainment App (%)', 'INFOTAINMENT', 'NorthWest', 1); + +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotAvgNetworkDelay.m b/scripts/sample_app5/matlab/plotAvgNetworkDelay.m new file mode 100644 index 0000000..4019e76 --- /dev/null +++ b/scripts/sample_app5/matlab/plotAvgNetworkDelay.m @@ -0,0 +1,11 @@ +function [] = plotAvgNetworkDelay() + plotGenericLine(1, 7, 'Average Network Delay (sec)', 'ALL_APPS', 'NorthWest', 0); + + plotGenericLine(5, 1, 'Average WLAN Delay (sec)', 'ALL_APPS', 'NorthWest', 0); + + plotGenericLine(5, 2, 'Average MAN Delay (sec)', 'ALL_APPS', 'NorthWest', 0); + + plotGenericLine(5, 3, 'Average WAN Delay (sec)', 'ALL_APPS', 'NorthWest', 0, 1, 1); + + plotGenericLine(5, 4, 'Average GSM Delay (sec)', 'ALL_APPS', 'NorthWest', 0, 1, 1, 0, [4, 1700]); +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotAvgProcessingTime.m b/scripts/sample_app5/matlab/plotAvgProcessingTime.m new file mode 100644 index 0000000..ad3f585 --- /dev/null +++ b/scripts/sample_app5/matlab/plotAvgProcessingTime.m @@ -0,0 +1,9 @@ +function [] = plotAvgProcessingTime() + + plotGenericLine(1, 6, 'Average Processing Time (sec)', 'ALL_APPS', 'NorthWest', 0); + + plotGenericLine(2, 6, 'Processing Time on RSU (sec)', 'ALL_APPS', 'NorthWest', 0); + + plotGenericLine(3, 6, 'Processing Time on Cloud (sec)', 'ALL_APPS', 'NorthWest', 0); + +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotAvgQoE.m b/scripts/sample_app5/matlab/plotAvgQoE.m new file mode 100644 index 0000000..f93954c --- /dev/null +++ b/scripts/sample_app5/matlab/plotAvgQoE.m @@ -0,0 +1,8 @@ +function [] = plotAvgQoE() + + plotGenericLine(1, 13, 'Average QoE (%)', 'ALL_APPS', 'SouthWest', 0); + plotGenericLine(1, 13, 'QoE for Danger Assessment App (%)', 'DANGER_ASSESSMENT', 'SouthWest', 0); + plotGenericLine(1, 13, 'QoE for Navigation App (%)', 'TRAFFIC_MANAGEMENT', 'SouthWest', 0); + plotGenericLine(1, 13, 'QoE for Infotainment App (%)', 'INFOTAINMENT', 'SouthWest', 0); + +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotAvgServiceTime.m b/scripts/sample_app5/matlab/plotAvgServiceTime.m new file mode 100644 index 0000000..4a1679c --- /dev/null +++ b/scripts/sample_app5/matlab/plotAvgServiceTime.m @@ -0,0 +1,9 @@ +function [] = plotAvgServiceTime() + + plotGenericLine(1, 5, 'Average Service Time (sec)', 'ALL_APPS', 'NorthWest', 0); + + plotGenericLine(2, 5, 'Service Time on RSU (sec)', 'ALL_APPS', 'NorthWest', 0); + + plotGenericLine(3, 5, 'Service Time on Cloud (sec)', 'ALL_APPS', 'NorthWest', 0); + +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotAvgVmUtilization.m b/scripts/sample_app5/matlab/plotAvgVmUtilization.m new file mode 100644 index 0000000..39c8e84 --- /dev/null +++ b/scripts/sample_app5/matlab/plotAvgVmUtilization.m @@ -0,0 +1,7 @@ +function [] = plotAvgVmUtilization() + + plotGenericLine(2, 8, 'Average VM Utilization of RSU (%)', 'ALL_APPS', 'NorthWest', 0); + + plotGenericLine(3, 8, 'Average VM Utilization of Cloud (%)', 'ALL_APPS', 'NorthWest', 0); + +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotDelayReasonAsBar.m b/scripts/sample_app5/matlab/plotDelayReasonAsBar.m new file mode 100644 index 0000000..24904d7 --- /dev/null +++ b/scripts/sample_app5/matlab/plotDelayReasonAsBar.m @@ -0,0 +1,91 @@ +function [] = plotDelayReasonAsBar(isEdge) + folderPath = getConfiguration(1); + numOfSimulations = getConfiguration(3); + stepOfxAxis = 3;%getConfiguration(4); + startOfMobileDeviceLoop = getConfiguration(10); + stepOfMobileDeviceLoop = getConfiguration(11); + endOfMobileDeviceLoop = getConfiguration(12); + numOfMobileDevices = (endOfMobileDeviceLoop - startOfMobileDeviceLoop)/stepOfMobileDeviceLoop + 1; + + all_results = zeros(numOfSimulations, numOfMobileDevices, 2); + + if ~exist('isEdge','var') + isEdge = 1; + end + + for s=1:numOfSimulations + for j=1:numOfMobileDevices + try + mobileDeviceNumber = startOfMobileDeviceLoop + stepOfMobileDeviceLoop * (j-1); + filePath = strcat(folderPath,'\ite',int2str(s),'\SIMRESULT_ITS_SCENARIO_AI_BASED_',int2str(mobileDeviceNumber),'DEVICES_ALL_APPS_GENERIC.log'); + + readData = dlmread(filePath,';',1,0); + value1 = 0; + value2 = 0; + if(isEdge == 1) + value1 = readData(2,5); + value2 = readData(2,6); + else + value1 = readData(3,5); + value2 = readData(3,6); + end + + all_results(s,j,1) = value2; + all_results(s,j,2) = value1 - value2; + catch err + error(err) + end + end + end + + if(numOfSimulations == 1) + results = all_results; + else + results = mean(all_results); %still 3d matrix but 1xMxN format + end + + results = squeeze(results); %remove singleton dimensions + + hFig=figure; + pos=getConfiguration(7); + set(hFig, 'Units','centimeters'); + set(hFig, 'Position',pos); + set(0,'DefaultAxesFontName','Times New Roman'); + set(0,'DefaultTextFontName','Times New Roman'); + set(0,'DefaultAxesFontSize',11); + set(0,'DefaultTextFontSize',12); + + b = bar(results,'stacked'); + %set(b(1),'LineStyle','--'); + + if(isEdge == 1) + lgnd = legend(b,{'processing time','WLAN delay'},'Location','NorthWest'); + ylabel({'Service Time on Edge (sec)'}); + filename = 'edge_delay_reason'; + else + lgnd = legend(b,{'processing time','WAN delay'},'Location','NorthWest'); + ylabel({'Service Time on Cloud(sec)'}); + filename = 'cloud_delay_reason'; + end + + set(b,{'FaceColor'},{[.45 .45 .45];[.90 .90 .90]}); + + axis square + xlabel(getConfiguration(9)); + set(gca,'XTick', stepOfxAxis:stepOfxAxis:numOfMobileDevices); + set(gca,'XTickLabel', (startOfMobileDeviceLoop*stepOfxAxis):(stepOfxAxis*stepOfMobileDeviceLoop):endOfMobileDeviceLoop); + set(gca,'XLim',[0 numOfMobileDevices+1]) + + set(get(gca,'Xlabel'),'FontSize',12) + set(get(gca,'Ylabel'),'FontSize',12) + set(lgnd,'FontSize',12) + + if(getConfiguration(18) == 1) + set(hFig, 'PaperUnits', 'centimeters'); + set(hFig, 'PaperPositionMode', 'manual'); + set(hFig, 'PaperPosition',[0 0 pos(3) pos(4)]); + set(gcf, 'PaperSize', [pos(3) pos(4)]); %Keep the same paper size + filename = strcat(folderPath,'\',filename); + saveas(gcf, filename, 'pdf'); + end +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotGenericLine.m b/scripts/sample_app5/matlab/plotGenericLine.m new file mode 100644 index 0000000..260ec22 --- /dev/null +++ b/scripts/sample_app5/matlab/plotGenericLine.m @@ -0,0 +1,198 @@ +function [] = plotGenericLine(rowOfset, columnOfset, yLabel, appType, legendPos, calculatePercentage, divisor, ignoreZeroValues, hideLowerValues, hideXAxis) + folderPath = getConfiguration(1); + numOfSimulations = getConfiguration(3); + stepOfxAxis = getConfiguration(4); + scenarioType = getConfiguration(5); + startOfMobileDeviceLoop = getConfiguration(10); + stepOfMobileDeviceLoop = getConfiguration(11); + endOfMobileDeviceLoop = getConfiguration(12); + numOfMobileDevices = (endOfMobileDeviceLoop - startOfMobileDeviceLoop)/stepOfMobileDeviceLoop + 1; + + all_results = zeros(numOfSimulations, size(scenarioType,2), numOfMobileDevices); + min_results = zeros(size(scenarioType,2), numOfMobileDevices); + max_results = zeros(size(scenarioType,2), numOfMobileDevices); + + if ~exist('appType','var') + appType = 'ALL_APPS'; + end + + if ~exist('divisor','var') + divisor = 1; + end + + if ~exist('ignoreZeroValues','var') + ignoreZeroValues = 0; + end + + if ~exist('hideLowerValues','var') + hideLowerValues = 0; + end + + if exist('hideXAxis','var') + hideXAxisStartValue = hideXAxis(2); + hideXAxisIndex = hideXAxis(1); + end + + for s=1:numOfSimulations + for i=1:size(scenarioType,2) + for j=1:numOfMobileDevices + try + mobileDeviceNumber = startOfMobileDeviceLoop + stepOfMobileDeviceLoop * (j-1); + filePath = strcat(folderPath,'\ite',int2str(s),'\SIMRESULT_ITS_SCENARIO_',char(scenarioType(i)),'_',int2str(mobileDeviceNumber),'DEVICES_',appType,'_GENERIC.log'); + + readData = dlmread(filePath,';',rowOfset,0); + value = readData(1,columnOfset); + if(calculatePercentage==1) + readData = dlmread(filePath,';',1,0); + totalTask = readData(1,1)+readData(1,2); + value = (100 * value) / totalTask; + end + + all_results(s,i,j) = value; + catch err + error(err) + end + end + end + end + + if(numOfSimulations == 1) + results = all_results; + else + if(ignoreZeroValues == 1) + results = sum(all_results,1) ./ sum(all_results~=0,1); + %TODO cahnge NaN to 0 + else + results = mean(all_results); %still 3d matrix but 1xMxN format + end + end + + results = squeeze(results); %remove singleton dimensions + + for i=1:size(scenarioType,2) + for j=1:numOfMobileDevices + if(results(i,j) < hideLowerValues) + results(i,j) = NaN; + else + results(i,j) = results(i,j) / divisor; + end + end + end + + if exist('hideXAxis','var') + for j=1:numOfMobileDevices + if(j*stepOfMobileDeviceLoop+startOfMobileDeviceLoop > hideXAxisStartValue) + results(hideXAxisIndex,j) = NaN; + end + end + end + + for i=1:size(scenarioType,2) + for j=1:numOfMobileDevices + x=results(i,j); % Create Data + SEM = std(x)/sqrt(length(x)); % Standard Error + ts = tinv([0.05 0.95],length(x)-1); % T-Score + CI = mean(x) + ts*SEM; % Confidence Intervals + + if(CI(1) < 0) + CI(1) = 0; + end + + if(CI(2) < 0) + CI(2) = 0; + end + + min_results(i,j) = results(i,j) - CI(1); + max_results(i,j) = CI(2) - results(i,j); + end + end + + types = zeros(1,numOfMobileDevices); + for i=1:numOfMobileDevices + types(i)=startOfMobileDeviceLoop+((i-1)*stepOfMobileDeviceLoop); + end + + hFig = figure; + pos=getConfiguration(7); + fontSizeArray = getConfiguration(8); + set(hFig, 'Units','centimeters'); + set(hFig, 'Position',pos); + set(0,'DefaultAxesFontName','Times New Roman'); + set(0,'DefaultTextFontName','Times New Roman'); + set(0,'DefaultAxesFontSize',fontSizeArray(3)); + + if(getConfiguration(20) == 1) + for i=1:1:numOfMobileDevices + xIndex=startOfMobileDeviceLoop+((i-1)*stepOfMobileDeviceLoop); + + markers = getConfiguration(50); + for j=1:size(scenarioType,2) + plot(xIndex, results(j,i),char(markers(j)),'MarkerFaceColor',getConfiguration(20+j),'color',getConfiguration(20+j)); + hold on; + end + end + + for j=1:size(scenarioType,2) + if(getConfiguration(19) == 1) + errorbar(types, results(j,:), min_results(j,:),max_results(j,:),'-k','color',getConfiguration(20+j),'LineWidth',1); + else + plot(types, results(j,:),'-k','color',getConfiguration(20+j),'LineWidth',1); + end + hold on; + end + + set(gca,'color','none'); + else + markers = getConfiguration(40); + for j=1:size(scenarioType,2) + if(getConfiguration(19) == 1) + errorbar(types, results(j,:),min_results(j,:),max_results(j,:),char(markers(j)),'MarkerFaceColor','w','LineWidth',1); + else + plot(types, results(j,:),char(markers(j)),'MarkerFaceColor','w'); + end + hold on; + end + + end + + legends = getConfiguration(6); + lgnd = legend(legends,'Location',legendPos); + %lgnd.Position=[0.21,0.8,0.2,0.01]; + if(getConfiguration(20) == 1) + set(lgnd,'color','none'); + end + + xCoefficent = 100; + if(getConfiguration(17) == 0) + xCoefficent = 1; + end + + hold off; + axis square + xlabel(getConfiguration(9)); + step = stepOfxAxis*stepOfMobileDeviceLoop; + set(gca,'XTick', step:step:endOfMobileDeviceLoop); + set(gca,'XTickLabel', step/xCoefficent:step/xCoefficent:endOfMobileDeviceLoop/xCoefficent); + ylabel(yLabel); + set(gca,'XLim',[startOfMobileDeviceLoop-5 endOfMobileDeviceLoop+5]); + + if(getConfiguration(17) == 1) + xlim = get(gca,'XLim'); + ylim = get(gca,'YLim'); + text(1.02 * xlim(2), 0.165 * ylim(2), 'x 10^2'); + end + + + set(get(gca,'Xlabel'),'FontSize',fontSizeArray(1)); + set(get(gca,'Ylabel'),'FontSize',fontSizeArray(1)); + set(lgnd,'FontSize',fontSizeArray(2)); + + if(getConfiguration(18) == 1) + set(hFig, 'PaperUnits', 'centimeters'); + set(hFig, 'PaperPositionMode', 'manual'); + set(hFig, 'PaperPosition',[0 0 pos(3) pos(4)]); + set(gcf, 'PaperSize', [pos(3) pos(4)]); %Keep the same paper size + filename = strcat(folderPath,'\',int2str(rowOfset),'_',int2str(columnOfset),'_',appType); + saveas(gcf, filename, 'pdf'); + end +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotGenericPie.m b/scripts/sample_app5/matlab/plotGenericPie.m new file mode 100644 index 0000000..acb7885 --- /dev/null +++ b/scripts/sample_app5/matlab/plotGenericPie.m @@ -0,0 +1,78 @@ +function [] = plotGenericPie(vmType, appType, threshold) + folderPath = "D:\git-repos\PhD\EdgeCloudSim\sim_results"; + scenarioType = getConfiguration(5); + startOfMobileDeviceLoop = 2000; + stepOfMobileDeviceLoop = 2000; + endOfMobileDeviceLoop = 2000; + numOfMobileDevices = (endOfMobileDeviceLoop - startOfMobileDeviceLoop)/stepOfMobileDeviceLoop + 1; + + if ~exist('appType','var') + appType = 1; + end + + if ~exist('vmType','var') + vmType = 'edge'; + end + + total = zeros(1,size(scenarioType,2)); + found = zeros(1,size(scenarioType,2)); + + for s=1:size(scenarioType,2) + for j=1:numOfMobileDevices + try + mobileDeviceNumber = startOfMobileDeviceLoop + stepOfMobileDeviceLoop * (j-1); + filePath = strcat(folderPath,'\ite11\SIMRESULT_ITS_SCENARIO_',char(scenarioType(s)),'_',int2str(mobileDeviceNumber),'DEVICES_SUCCESS.log'); + + readData = dlmread(filePath,';',1,0); + for k=1:size(readData,1) + if(readData(k,7) == appType && ((strcmp(vmType,'edge') == 1 && readData(k,3) == 3) || (strcmp(vmType,'cloud') == 1 && readData(k,3) ~= 3) || strcmp(vmType,'all')==1)) + if(readData(k,12) - readData(k,11) > threshold) + found(s) = found(s) + 1; + end + total(s) = total(s) + 1; + end + end + catch err + error(err) + end + end + end + + hFig = figure; + pos=getConfiguration(7); + fontSizeArray = getConfiguration(8); + set(hFig, 'Units','centimeters'); + set(hFig, 'Position',pos); + set(0,'DefaultAxesFontName','Times New Roman'); + set(0,'DefaultTextFontName','Times New Roman'); + set(0,'DefaultAxesFontSize',fontSizeArray(3)); + + if(getConfiguration(20) == 1) + %result = found ./ total .* 100; + p = pie(found); + hold on; + end + + txt = reshape(getConfiguration(6),[size(scenarioType,2) 1]); + pText = findobj(p,'Type','text'); + percentValues = get(pText,'String'); + combinedtxt = strcat(txt,' (',percentValues,')'); + + for i=1:size(scenarioType,2) + pText(i).String = combinedtxt(i); + end + + set(pText,'fontsize',fontSizeArray(1)) + + hold off; + axis square + + if(getConfiguration(18) == 1) + set(hFig, 'PaperUnits', 'centimeters'); + set(hFig, 'PaperPositionMode', 'manual'); + set(hFig, 'PaperPosition',[0 0 pos(3) pos(4)]); + set(gcf, 'PaperSize', [pos(3) pos(4)]); %Keep the same paper size + filename = strcat(folderPath,'\',int2str(rowOfset),'_',int2str(columnOfset),'_',appType); + saveas(gcf, filename, 'pdf'); + end +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotGenericScatter.m b/scripts/sample_app5/matlab/plotGenericScatter.m new file mode 100644 index 0000000..53b41be --- /dev/null +++ b/scripts/sample_app5/matlab/plotGenericScatter.m @@ -0,0 +1,96 @@ +function [] = plotGenericScatter(yLabel, xLabel, legendPos, vmType, appType, drawLine) + folderPath = "D:\git-repos\PhD\EdgeCloudSim\sim_results"; + scenarioType = getConfiguration(5); + simulationTime = getConfiguration(2); + startOfMobileDeviceLoop = 2000; + stepOfMobileDeviceLoop = 2000; + endOfMobileDeviceLoop = 2000; + numOfMobileDevices = (endOfMobileDeviceLoop - startOfMobileDeviceLoop)/stepOfMobileDeviceLoop + 1; + + if ~exist('appType','var') + appType = 1; + end + + if ~exist('vmType','var') + vmType = 'edge'; + end + + result_x = NaN(size(scenarioType,2), 5000); + result_y = NaN(size(result_x,1), size(result_x,2)); + %result_sz = NaN(size(result_x,1), size(result_x,2)); + + for s=1:size(scenarioType,2) + index = 1; + firstDeviceId = -1; + for j=1:numOfMobileDevices + try + mobileDeviceNumber = startOfMobileDeviceLoop + stepOfMobileDeviceLoop * (j-1); + filePath = strcat(folderPath,'\ite11\SIMRESULT_ITS_SCENARIO_',char(scenarioType(s)),'_',int2str(mobileDeviceNumber),'DEVICES_SUCCESS.log'); + + readData = dlmread(filePath,';',1,0); + for k=1:size(readData,1) + if(readData(k,7) == appType && ((strcmp(vmType,'edge') == 1 && readData(k,3) == 3) || (strcmp(vmType,'cloud') == 1 && readData(k,3) ~= 3) || strcmp(vmType,'all')==1)) + if(firstDeviceId == -1) + firstDeviceId = readData(k,2); + end + if(readData(k,2) == firstDeviceId) % && readData(k,11) - readData(k,10) < 2 + result_y(s, index) = readData(k,12) - readData(k,11); + result_x(s, index) = readData(k,12) / 60; + %result_sz(s, index) = j*10; + index = index + 1; + end + end + end + catch err + error(err) + end + end + end + + hFig = figure; + pos=getConfiguration(7); + fontSizeArray = getConfiguration(8); + set(hFig, 'Units','centimeters'); + set(hFig, 'Position',pos); + set(0,'DefaultAxesFontName','Times New Roman'); + set(0,'DefaultTextFontName','Times New Roman'); + set(0,'DefaultAxesFontSize',fontSizeArray(3)); + + if(getConfiguration(20) == 1) + for i=1:size(scenarioType,2) + scatter(result_x(i,:), result_y(i,:)); + hold on; + end + + if exist('drawLine','var') + y = [drawLine, drawLine]; + x = [0, simulationTime]; + plot(x,y); + end + end + + legends = getConfiguration(6); + lgnd = legend(legends,'Location',legendPos); + %lgnd.Position=[0.21,0.8,0.2,0.01]; + if(getConfiguration(20) == 1) + set(lgnd,'color','none'); + end + + hold off; + axis square + xlabel(xLabel); + ylabel(yLabel); + + set(get(gca,'Xlabel'),'FontSize',fontSizeArray(1)); + set(get(gca,'Ylabel'),'FontSize',fontSizeArray(1)); + set(lgnd,'FontSize',fontSizeArray(2)); + + if(getConfiguration(18) == 1) + set(hFig, 'PaperUnits', 'centimeters'); + set(hFig, 'PaperPositionMode', 'manual'); + set(hFig, 'PaperPosition',[0 0 pos(3) pos(4)]); + set(gcf, 'PaperSize', [pos(3) pos(4)]); %Keep the same paper size + filename = strcat(folderPath,'\',int2str(rowOfset),'_',int2str(columnOfset),'_',appType); + saveas(gcf, filename, 'pdf'); + end +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotLocation.m b/scripts/sample_app5/matlab/plotLocation.m new file mode 100644 index 0000000..ac47ab4 --- /dev/null +++ b/scripts/sample_app5/matlab/plotLocation.m @@ -0,0 +1,66 @@ +function [] = plotLocation() + folderPath = getConfiguration(1); + numOfSimulations = getConfiguration(3); + stepOfxAxis = getConfiguration(4); + startOfMobileDeviceLoop = 500; + stepOfMobileDeviceLoop = 500; + endOfMobileDeviceLoop = 1500; + numOfMobileDevices = (endOfMobileDeviceLoop - startOfMobileDeviceLoop)/stepOfMobileDeviceLoop + 1; + PlaceCount = 40; + + results = zeros(numOfMobileDevices, PlaceCount); + + for s=1:numOfSimulations + indexCounter = 1; + for i=startOfMobileDeviceLoop:stepOfMobileDeviceLoop:endOfMobileDeviceLoop + try + filePath = strcat(folderPath,'\ite',int2str(s),'\SIMRESULT_ITS_SCENARIO_AI_BASED_',int2str(i),'DEVICES_LOCATION.log'); + readData = dlmread(filePath,';',1,0); + + for j=1:PlaceCount + results(indexCounter,j) = results(indexCounter,j) + mean(readData(:,j+1)); + end + catch err + error(err) + end + indexCounter = indexCounter + 1; + end + end + results = results/numOfSimulations; + + xValues = {}; + yValues = {}; + + indexCounter = 1; + for i=startOfMobileDeviceLoop:stepOfMobileDeviceLoop:endOfMobileDeviceLoop + xValues(indexCounter) = {int2str(i)}; + indexCounter = indexCounter + 1; + end + for i=1:PlaceCount + yValues(i) = {int2str(i)} + end + + hFig=figure; + %pos=getConfiguration(7); + pos=[10 3 24 6]; + set(hFig, 'Units','centimeters'); + set(hFig, 'Position',pos); + + C = [0,172,0;2,171,0;5,171,0;7,171,0;10,171,0;12,171,0;15,171,0;17,171,0;20,171,0;22,171,0;25,170,0;27,170,0;30,170,0;32,170,0;35,170,0;37,170,0;40,170,0;42,170,0;45,170,0;47,169,0;50,169,0;52,169,0;55,169,0;57,169,0;60,169,0;62,169,0;65,169,0;67,169,0;70,168,0;72,168,0;75,168,0;77,168,0;80,168,0;82,168,0;85,168,0;87,168,0;90,168,0;92,168,0;95,167,0;97,167,0;100,167,0;102,167,0;105,167,0;107,167,0;110,167,0;112,167,0;115,167,0;117,166,0;120,166,0;122,166,0;125,166,0;127,166,0;130,166,0;132,166,0;135,166,0;137,166,0;140,165,0;142,165,0;145,165,0;147,165,0;150,165,0;152,165,0;155,165,0;157,165,0;159,164,0;160,164,0;161,163,0;162,162,0;163,162,0;163,161,0;164,160,0;165,159,0;166,159,0;167,158,0;168,157,0;168,157,0;169,156,0;170,155,0;171,154,0;172,154,0;172,153,0;173,152,0;174,152,0;175,151,0;176,150,0;176,149,0;177,149,0;178,148,0;179,147,0;180,147,0;181,146,0;181,145,0;182,144,0;183,144,0;184,143,0;185,142,0;185,142,0;186,141,0;187,140,0;188,139,0;189,139,0;189,138,0;190,137,0;191,137,0;192,136,0;193,135,0;193,134,0;194,134,0;195,133,0;196,132,0;197,132,0;198,131,0;198,130,0;199,129,0;200,129,0;201,128,0;202,127,0;202,127,0;203,126,0;204,125,0;205,124,0;206,124,0;206,123,0;207,122,0;208,122,0;209,121,0;210,120,0;211,119,0;211,119,0;211,118,0;211,117,0;210,116,0;210,115,0;210,114,0;210,113,0;210,112,0;210,111,0;209,110,0;209,109,0;209,108,0;209,107,0;209,106,0;208,105,0;208,104,0;208,103,0;208,102,0;208,102,0;208,101,0;207,100,0;207,99,0;207,98,0;207,97,0;207,96,0;207,95,0;206,94,0;206,93,0;206,92,0;206,91,0;206,90,0;206,89,0;205,88,0;205,87,0;205,86,0;205,85,0;205,84,0;205,84,0;204,83,0;204,82,0;204,81,0;204,80,0;204,79,0;204,78,0;203,77,0;203,76,0;203,75,0;203,74,0;203,73,0;203,72,0;202,71,0;202,70,0;202,69,0;202,68,0;202,67,0;202,67,0;201,66,0;201,65,0;201,64,0;201,63,0;201,62,0;201,61,0;200,60,0;200,59,0;199,58,0;198,57,0;197,56,0;196,55,0;195,54,0;194,53,0;193,53,0;192,52,0;191,51,0;190,50,0;189,49,0;188,48,0;187,47,0;186,46,0;185,45,0;184,44,0;183,43,0;182,42,0;181,41,0;180,41,0;179,40,0;177,39,0;176,38,0;175,37,0;174,36,0;173,35,0;172,34,0;171,33,0;170,32,0;169,31,0;168,30,0;167,29,0;166,29,0;165,28,0;164,27,0;163,26,0;162,25,0;161,24,0;160,23,0;159,22,0;158,21,0;157,20,0;156,19,0;155,18,0;153,18,0;152,17,0;151,16,0;150,15,0;149,14,0;148,13,0;147,12,0;146,11,0;145,10,0;144,9,0;143,8,0;142,7,0;141,6,0;140,6,0;139,5,0;138,4,0;137,3,0;136,2,0;135,1,0;134,0,0]; + + h = heatmap(yValues, xValues, results, 'Colormap', colormap(C/255),'FontName','Times New Roman','FontSize',11); + + h.Title = 'Mean number of vehicles per places'; + h.XLabel = 'Place IDs'; + h.YLabel = '#Vehicle in simulation'; + + if(getConfiguration(18) == 1) + set(hFig, 'PaperUnits', 'centimeters'); + set(hFig, 'PaperPositionMode', 'manual'); + set(hFig, 'PaperPosition',[0 0 pos(3) pos(4)]); + set(gcf, 'PaperSize', [pos(3) pos(4)]); %Keep the same paper size + filename = strcat(folderPath,'\position'); + saveas(gcf, filename, 'pdf'); + end + +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotTaskFailureReason.m b/scripts/sample_app5/matlab/plotTaskFailureReason.m new file mode 100644 index 0000000..8da0bd8 --- /dev/null +++ b/scripts/sample_app5/matlab/plotTaskFailureReason.m @@ -0,0 +1,15 @@ +function [] = plotTaskFailureReason() + + plotGenericLine(1, 10, 'Failed Task due to VM Capacity (%)', 'ALL_APPS', 'NorthWest', 1); + + plotGenericLine(1, 11, 'Failed Task due to Mobility (%)', 'ALL_APPS', 'NorthWest', 1); + + plotGenericLine(5, 5, 'Failed Tasks due to WLAN (%)', 'ALL_APPS', 'NorthWest', 1); + + plotGenericLine(5, 6, 'Failed Tasks due to MAN failure (%)', 'ALL_APPS', 'NorthWest', 1); + + plotGenericLine(5, 7, 'Failed Tasks due to WAN failure (%)', 'ALL_APPS', 'NorthWest', 1); + + plotGenericLine(5, 8, 'Failed Tasks due to GSM failure (%)', 'ALL_APPS', 'NorthEast', 1); + +end \ No newline at end of file diff --git a/scripts/sample_app5/matlab/plotTimeComplexity.m b/scripts/sample_app5/matlab/plotTimeComplexity.m new file mode 100644 index 0000000..626f665 --- /dev/null +++ b/scripts/sample_app5/matlab/plotTimeComplexity.m @@ -0,0 +1,7 @@ +function [] = plotTimeComplexity() + + plotGenericLine(6, 1, 'Simulation Time (minute)', 'ALL_APPS', 'NorthWest', 0, 60); + + plotGenericLine(6, 2, 'Orchestration Algorithm Overhead (micro second)', 'ALL_APPS', 'NorthEast', 0, 1000); + +end \ No newline at end of file diff --git a/scripts/sample_app5/run_scenarios.sh b/scripts/sample_app5/run_scenarios.sh new file mode 100644 index 0000000..6ccec24 --- /dev/null +++ b/scripts/sample_app5/run_scenarios.sh @@ -0,0 +1,75 @@ +#!/bin/bash +if [ "$#" -ne 2 ]; then + echo "Missing arguments! Please provide number of parallel processes and number of iterations." + echo "Usage: '$0 4 10'" + exit 1 +fi + +re='^[0-9]+$' +if ! [[ $1 =~ $re ]] ; then + echo "$1 is not an integer! Please provide number of parallel processes." + echo "Usage: '$0 4 10'" + exit 1 +fi + +if ! [[ $2 =~ $re ]] ; then + echo "$1 is not an integer! Please provide number of iterations." + echo "Usage: '$0 4 10'" + exit 1 +fi + +script_root_path="$(dirname "$(readlink -f "$0")")" +root_out_folder=${script_root_path}/output +num_of_processes=$1 +iterationNumber=$2 +process_counter=0 + +date=$(date '+%d-%m-%Y_%H-%M') +simulation_out_folder=${root_out_folder}/${date} +mkdir -p $simulation_out_folder + +simulations=$(cat ${script_root_path}/simulation.list) + +rm -rf ${script_root_path}/tmp_runner* + +for sim_args in $simulations +do + scenario_name=$(echo $sim_args | cut -d ';' -f1) + edge_devices_file=$(echo $sim_args | cut -d ';' -f2) + applications_file=$(echo $sim_args | cut -d ';' -f3) + mkdir -p $simulation_out_folder/${scenario_name} + echo "STARTED" > $simulation_out_folder/${scenario_name}/progress.log + + for (( i=1; i<=$iterationNumber; i++ )) + do + process_id=$(($process_counter % $num_of_processes)) + process_counter=$(($process_counter + 1)) + + echo "${script_root_path}/runner.sh $simulation_out_folder $scenario_name $edge_devices_file $applications_file ${i}" >> "${simulation_out_folder}/tmp_runner${process_id}.sh" + done +done + +#num_of_cores=$(grep -c ^processor /proc/cpuinfo) + +for (( i=0; i<$num_of_processes; i++ )) +do + chmod +x ${simulation_out_folder}/tmp_runner${i}.sh + ${simulation_out_folder}/tmp_runner${i}.sh & +# pid=$! +# cpu=$(($i % $num_of_cores)) +# taskset -cp $cpu,$cpu $pid +done + +echo "###############################################################" +echo " SIMULARIONS ARE STARTED!" +echo "###############################################################" +echo "You can follow the progress via the following command" +echo "tail -f /progress.log" +echo "e.g." +echo "tail -f output/${date}/${scenario_name}/progress.log" +echo "###############################################################" +echo "You can inspect each iteration via the following command" +echo "tail -f /ite[n].log" +echo "e.g." +echo "tail -f output/${date}/${scenario_name}/ite1.log" +echo "###############################################################" diff --git a/scripts/sample_app5/runner.sh b/scripts/sample_app5/runner.sh new file mode 100644 index 0000000..b56610d --- /dev/null +++ b/scripts/sample_app5/runner.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +script_root_path="$(dirname "$(readlink -f "$0")")" +simulation_out_folder=$1 +scenario_name=$2 +edge_devices_file=$3 +applications_file=$4 +iteration_number=$5 + +scenario_out_folder=${simulation_out_folder}/${scenario_name}/ite${iteration_number} +scenario_conf_file=${script_root_path}/config/${scenario_name}.properties +scenario_edge_devices_file=${script_root_path}/config/${edge_devices_file} +scenario_applications_file=${script_root_path}/config/${applications_file} + +mkdir -p $scenario_out_folder +java -classpath '../../bin:../../lib/cloudsim-4.0.jar:../../lib/commons-math3-3.6.1.jar:../../lib/colt.jar:../../lib/weka.jar:../../lib/mtj-1.0.4.jar' -Djava.library.path=../../lib/native/linux edu.boun.edgecloudsim.applications.vec_ai_app.VehicularMainApp $scenario_conf_file $scenario_edge_devices_file $scenario_applications_file $scenario_out_folder $iteration_number > ${scenario_out_folder}.log + +if [ $? -eq 0 ]; then + echo "ite${iteration_number} OK" >> ${simulation_out_folder}/${scenario_name}/progress.log +else + echo "ite${iteration_number} FAIL !!!" >> ${simulation_out_folder}/${scenario_name}/progress.log +fi + +#tar -czf ${scenario_out_folder}.tar.gz -C $simulation_out_folder/${scenario_name} ite${iteration_number} +#rm -rf $scenario_out_folder diff --git a/scripts/sample_app5/simulation.list b/scripts/sample_app5/simulation.list new file mode 100644 index 0000000..3a4122a --- /dev/null +++ b/scripts/sample_app5/simulation.list @@ -0,0 +1 @@ +default_config;edge_devices.xml;applications.xml \ No newline at end of file diff --git a/scripts/sample_app5/stop_scenarios.sh b/scripts/sample_app5/stop_scenarios.sh new file mode 100644 index 0000000..bb36b99 --- /dev/null +++ b/scripts/sample_app5/stop_scenarios.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +echo "This script kills all java processes including Eclipse etc." +read -p "Do you want to continue[y/n]? " REPLY + +if [ "$REPLY" = "y" ] +then + while pgrep java >/dev/null 2>&1 + do + killall java + sleep 1 + done +fi + +echo "Operation completed. bye..." diff --git a/src/edu/boun/edgecloudsim/applications/sample_app1/MainApp.java b/src/edu/boun/edgecloudsim/applications/sample_app1/MainApp.java index fa17b12..6e47080 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app1/MainApp.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app1/MainApp.java @@ -32,7 +32,7 @@ public class MainApp { //disable console output of cloudsim library Log.disable(); - //enable console ourput and file output of this application + //enable console output and file output of this application SimLogger.enablePrintLog(); int iterationNumber = 1; diff --git a/src/edu/boun/edgecloudsim/applications/sample_app2/MainApp.java b/src/edu/boun/edgecloudsim/applications/sample_app2/MainApp.java index b88a31d..8ee4f43 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app2/MainApp.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app2/MainApp.java @@ -24,17 +24,17 @@ import edu.boun.edgecloudsim.utils.SimLogger; import edu.boun.edgecloudsim.utils.SimUtils; public class MainApp { - + /** * Creates main() to run this example */ public static void main(String[] args) { //disable console output of cloudsim library Log.disable(); - - //enable console ourput and file output of this application + + //enable console output and file output of this application SimLogger.enablePrintLog(); - + int iterationNumber = 1; String configFile = ""; String outputFolder = ""; @@ -61,12 +61,12 @@ public class MainApp { SimLogger.printLine("cannot initialize simulation settings!"); System.exit(0); } - + if(SS.getFileLoggingEnabled()){ SimLogger.enableFileLog(); SimUtils.cleanOutputFolder(outputFolder); } - + DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); Date SimulationStartDate = Calendar.getInstance().getTime(); String now = df.format(SimulationStartDate); @@ -88,7 +88,7 @@ public class MainApp { SimLogger.printLine("Scenario: " + simScenario + " - Policy: " + orchestratorPolicy + " - #iteration: " + iterationNumber); SimLogger.printLine("Duration: " + SS.getSimulationTime()/60 + " min (warm up period: "+ SS.getWarmUpPeriod()/60 +" min) - #devices: " + j); SimLogger.getInstance().simStarted(outputFolder,"SIMRESULT_" + simScenario + "_" + orchestratorPolicy + "_" + j + "DEVICES"); - + try { // First step: Initialize the CloudSim package. It should be called @@ -96,16 +96,16 @@ public class MainApp { int num_user = 2; // number of grid users Calendar calendar = Calendar.getInstance(); boolean trace_flag = false; // mean trace events - + // Initialize the CloudSim library CloudSim.init(num_user, calendar, trace_flag, 0.01); - + // Generate EdgeCloudsim Scenario Factory ScenarioFactory sampleFactory = new SampleScenarioFactory(j,SS.getSimulationTime(), orchestratorPolicy, simScenario); - + // Generate EdgeCloudSim Simulation Manager SimManager manager = new SimManager(sampleFactory, j, simScenario, orchestratorPolicy); - + // Start simulation manager.startSimulation(); } @@ -115,7 +115,7 @@ public class MainApp { e.printStackTrace(); System.exit(0); } - + Date ScenarioEndDate = Calendar.getInstance().getTime(); now = df.format(ScenarioEndDate); SimLogger.printLine("Scenario finished at " + now + ". It took " + SimUtils.getTimeDifference(ScenarioStartDate,ScenarioEndDate)); diff --git a/src/edu/boun/edgecloudsim/applications/sample_app2/SampleEdgeOrchestrator.java b/src/edu/boun/edgecloudsim/applications/sample_app2/SampleEdgeOrchestrator.java index c1baa03..4d98dd5 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app2/SampleEdgeOrchestrator.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app2/SampleEdgeOrchestrator.java @@ -91,12 +91,12 @@ public class SampleEdgeOrchestrator extends EdgeOrchestrator { result = SimSettings.GENERIC_EDGE_DEVICE_ID; } else { - SimLogger.printLine("Unknow edge orchestrator policy! Terminating simulation..."); + SimLogger.printLine("Unknown edge orchestrator policy! Terminating simulation..."); System.exit(0); } } else { - SimLogger.printLine("Unknow simulation scenario! Terminating simulation..."); + SimLogger.printLine("Unknown simulation scenario! Terminating simulation..."); System.exit(0); } return result; diff --git a/src/edu/boun/edgecloudsim/applications/sample_app2/SampleMobileDeviceManager.java b/src/edu/boun/edgecloudsim/applications/sample_app2/SampleMobileDeviceManager.java index 4d808e1..fe0a776 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app2/SampleMobileDeviceManager.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app2/SampleMobileDeviceManager.java @@ -298,7 +298,8 @@ public class SampleMobileDeviceManager extends MobileDeviceManager { task.setSubmittedLocation(currentLocation); //add related task to log list - SimLogger.getInstance().addLog(task.getCloudletId(), + SimLogger.getInstance().addLog(task.getMobileDeviceId(), + task.getCloudletId(), task.getTaskType(), (int)task.getCloudletLength(), (int)task.getCloudletFileSize(), diff --git a/src/edu/boun/edgecloudsim/applications/sample_app2/SampleNetworkModel.java b/src/edu/boun/edgecloudsim/applications/sample_app2/SampleNetworkModel.java index 19ecf6e..6a5c63f 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app2/SampleNetworkModel.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app2/SampleNetworkModel.java @@ -36,7 +36,7 @@ public class SampleNetworkModel extends NetworkModel { private int[] wanClients; private int[] wlanClients; - private double lastMM1QueeuUpdateTime; + private double lastMM1QueueUpdateTime; private double ManPoissonMeanForDownload; //seconds private double ManPoissonMeanForUpload; //seconds @@ -194,7 +194,7 @@ public class SampleNetworkModel extends NetworkModel { SimSettings SS = SimSettings.getInstance(); for(int taskIndex=0; taskIndex 15) ? 0 : result; } @@ -412,8 +412,8 @@ public class SampleNetworkModel extends NetworkModel { } public void updateMM1QueeuModel(){ - double lastInterval = CloudSim.clock() - lastMM1QueeuUpdateTime; - lastMM1QueeuUpdateTime = CloudSim.clock(); + double lastInterval = CloudSim.clock() - lastMM1QueueUpdateTime; + lastMM1QueueUpdateTime = CloudSim.clock(); if(numOfManTaskForDownload != 0){ ManPoissonMeanForDownload = lastInterval / (numOfManTaskForDownload / (double)numberOfMobileDevices); diff --git a/src/edu/boun/edgecloudsim/applications/sample_app3/MainApp.java b/src/edu/boun/edgecloudsim/applications/sample_app3/MainApp.java index e319b99..a27dab9 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app3/MainApp.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app3/MainApp.java @@ -32,7 +32,7 @@ public class MainApp { //disable console output of cloudsim library Log.disable(); - //enable console ourput and file output of this application + //enable console output and file output of this application SimLogger.enablePrintLog(); int iterationNumber = 1; diff --git a/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileDeviceManager.java b/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileDeviceManager.java index 6eebe35..2d1cf1f 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileDeviceManager.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileDeviceManager.java @@ -191,7 +191,8 @@ public class SampleMobileDeviceManager extends MobileDeviceManager { task.setSubmittedLocation(currentLocation); //add related task to log list - SimLogger.getInstance().addLog(task.getCloudletId(), + SimLogger.getInstance().addLog(task.getMobileDeviceId(), + task.getCloudletId(), task.getTaskType(), (int)task.getCloudletLength(), (int)task.getCloudletFileSize(), diff --git a/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileServerManager.java b/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileServerManager.java index 8757969..da6e7a7 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileServerManager.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileServerManager.java @@ -65,7 +65,7 @@ public class SampleMobileServerManager extends MobileServerManager{ } @Override - public void createVmList(int brockerId) { + public void createVmList(int brokerId) { //VMs should have unique IDs, so create Mobile VMs after Edge+Cloud VMs int vmCounter=SimSettings.getInstance().getNumOfEdgeVMs() + SimSettings.getInstance().getNumOfCloudVMs(); @@ -82,7 +82,7 @@ public class SampleMobileServerManager extends MobileServerManager{ long bandwidth = 0; //VM Parameters - MobileVM vm = new MobileVM(vmCounter, brockerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); + MobileVM vm = new MobileVM(vmCounter, brokerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); vmList.get(i).add(vm); vmCounter++; } @@ -166,7 +166,7 @@ public class SampleMobileServerManager extends MobileServerManager{ //4. Create Hosts with its id and list of PEs and add them to the list of machines MobileHost host = new MobileHost( //Hosts should have unique IDs, so create Mobile Hosts after Edge+Cloud Hosts - i+SimSettings.getInstance().getNumOfEdgeHosts()+SimSettings.getInstance().getNumOfCoudHost(), + i+SimSettings.getInstance().getNumOfEdgeHosts()+SimSettings.getInstance().getNumOfCloudHost(), new RamProvisionerSimple(ram), new BwProvisionerSimple(bandwidth), //kbps storage, diff --git a/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyEdgeOrchestrator.java b/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyEdgeOrchestrator.java index d4df2f3..188b46f 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyEdgeOrchestrator.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyEdgeOrchestrator.java @@ -96,16 +96,16 @@ public class FuzzyEdgeOrchestrator extends EdgeOrchestrator { for(int hostIndex=0; hostIndex vmArray = SimManager.getInstance().getEdgeServerManager().getVmList(hostIndex); - double totalUtlization=0; + double totalUtilization=0; for(int vmIndex=0; vmIndex 15) ? 0 : result; } diff --git a/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyMainApp.java b/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyMainApp.java index 45722bc..4697efb 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyMainApp.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyMainApp.java @@ -32,7 +32,7 @@ public class FuzzyMainApp { //disable console output of cloudsim library Log.disable(); - //enable console ourput and file output of this application + //enable console output and file output of this application SimLogger.enablePrintLog(); int iterationNumber = 1; diff --git a/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyMobileDeviceManager.java b/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyMobileDeviceManager.java index e3eb421..951230e 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyMobileDeviceManager.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyMobileDeviceManager.java @@ -286,7 +286,8 @@ public class FuzzyMobileDeviceManager extends MobileDeviceManager { task.setSubmittedLocation(currentLocation); //add related task to log list - SimLogger.getInstance().addLog(task.getCloudletId(), + SimLogger.getInstance().addLog(task.getMobileDeviceId(), + task.getCloudletId(), task.getTaskType(), (int)task.getCloudletLength(), (int)task.getCloudletFileSize(), diff --git a/src/edu/boun/edgecloudsim/applications/sample_app4/README.md b/src/edu/boun/edgecloudsim/applications/sample_app4/README.md index 2c16668..af6e711 100755 --- a/src/edu/boun/edgecloudsim/applications/sample_app4/README.md +++ b/src/edu/boun/edgecloudsim/applications/sample_app4/README.md @@ -1,8 +1,6 @@ # Sample Application 4 -This application includes the source code which is used in our paper submitted to IEEE Transactions on Network and Service Management [[1]](https://www.comsoc.org/publications/journals/ieee-tnsm). - -The digital object identifier of the paper will be provide after it is published! +This application includes the source code which is used in our paper submitted to IEEE Transactions on Network and Service Management [[1]](https://ieeexplore.ieee.org/abstract/document/8651335/). ## Fuzzy Logic Based Workload Orchestrator @@ -28,7 +26,7 @@ In this application we introduce a fuzzy logic based workload orchestrator. In o A university campus environment is simulated in this application. The students demand services from the edge servers within the campus while moving around the predesignated locations such as the classroom buildings, cafeteria, dormitories, and administrative offices. The individuals are assumed to carry and/or wear the mobile gadgets which continuously run applications that in turn create a traffic due to offloading of the tasks. There exists certain number of edge servers located in the campus such that they provide coverage for edge computing requests. A user is connected to the nearest edge server via WLAN whereas the edge servers are interconnected by MAN. Also, the standard cloud infrastructure can be accessed over WAN. In this setting, it is possible for the user to offload a task to (i) Nearest edge server (we call this the local edge server) (ii) a neighboring edge server within the campus connected by AN (we call this the remote edge server), and (iii) to the global cloud servers. In our work, this decision is handled by the workload orchestrator.

- +

Figure 2: A university campus scenario representing multiple locations.

@@ -36,4 +34,4 @@ A university campus environment is simulated in this application. The students d ## References -**[1]** IEEE Transactions on Network and Service Management, [Online]. Available: https://www.comsoc.org/publications/journals/ieee-tnsm. [Accessed: 21- Jan- 2019]. +**[1]** C. Sonmez, A. Ozgovde and C. Ersoy, "[Fuzzy Workload Orchestration for Edge Computing](https://ieeexplore.ieee.org/abstract/document/8651335/)," in *IEEE Transactions on Network and Service Management*, vol. 16, no. 2, pp. 769-782, June 2019. diff --git a/src/edu/boun/edgecloudsim/applications/sample_app5/GameTheoryHelper.java b/src/edu/boun/edgecloudsim/applications/sample_app5/GameTheoryHelper.java new file mode 100644 index 0000000..22bdd2e --- /dev/null +++ b/src/edu/boun/edgecloudsim/applications/sample_app5/GameTheoryHelper.java @@ -0,0 +1,74 @@ +package edu.boun.edgecloudsim.applications.sample_app5; + +public class GameTheoryHelper { + + private static double PRICING_FACTOR = 0.6; + private double MAX_TASK_ARRIVAL_RATE; + private double MIN_TASK_ARRIVAL_RATE; + + //the offloading probability vector p + private double[] pVector; + + //the task arrival rate vector + private double[] arrivalRateVector; + + public GameTheoryHelper(double minTaskArrivalRate, double maxTaskArrivalRate, int numOfVehicles) { + MAX_TASK_ARRIVAL_RATE = maxTaskArrivalRate; + MIN_TASK_ARRIVAL_RATE = minTaskArrivalRate; + + pVector = new double[numOfVehicles]; + for (int i = 0; i < pVector.length; i++) + pVector[i] = 0.33; + + arrivalRateVector = new double[numOfVehicles]; + for (int i = 0; i < arrivalRateVector.length; i++) + arrivalRateVector[i] = 0.5; + } + + /** + * This method is used to find the best choice via Nash equilibrium strategy. + * + * @param vehicleID vehicle id + * @param taskArrivalRate task arrival rate + * @param expectedEdgeDelay expected delay for edge offloading + * @param expectedCloudDelay expected delay for cloud offloading + * @return double probability of offloading to cloud + */ + public synchronized double getPi(int vehicleID, double taskArrivalRate, double expectedEdgeDelay, double expectedCloudDelay, double maxDelay) { + pVector[vehicleID] = (expectedEdgeDelay - expectedCloudDelay) / (2 * PRICING_FACTOR * maxDelay * (1 - multiplyArray(vehicleID))); + arrivalRateVector[vehicleID] = normalizeTaskArrivalRate(taskArrivalRate); + + if(pVector[vehicleID] <= 0) + pVector[vehicleID] = 0.01; + else if(pVector[vehicleID] >= 1) + pVector[vehicleID] = 0.99; + + //SimLogger.printLine("P" + vehicleID + ": " + pVector[vehicleID]); + + return pVector[vehicleID]; + } + + /** + * This method normalizes the task arrival rate between 0-1. + * + * @param taskArrivalRate task arrival rate + * @return double normalized task length + */ + private double normalizeTaskArrivalRate(double taskArrivalRate) { + double result = (taskArrivalRate - MIN_TASK_ARRIVAL_RATE) / (MAX_TASK_ARRIVAL_RATE - MIN_TASK_ARRIVAL_RATE); + return Math.max(Math.min(result,1),0); + } + + private double multiplyArray(int excludedIndex) { + double pro = 1; + for (int i = 0; i < pVector.length && i != excludedIndex; i++) + pro *= (1 - arrivalRateVector[i] * pVector[i]); + + if(pro == Double.POSITIVE_INFINITY) + pro = 0.99; + else if(pro == Double.NEGATIVE_INFINITY) + pro = 0.01; + + return pro; + } +} diff --git a/src/edu/boun/edgecloudsim/applications/sample_app5/MultiArmedBanditHelper.java b/src/edu/boun/edgecloudsim/applications/sample_app5/MultiArmedBanditHelper.java new file mode 100644 index 0000000..8a7ea68 --- /dev/null +++ b/src/edu/boun/edgecloudsim/applications/sample_app5/MultiArmedBanditHelper.java @@ -0,0 +1,115 @@ +package edu.boun.edgecloudsim.applications.sample_app5; + +import edu.boun.edgecloudsim.edge_client.Task; +import edu.boun.edgecloudsim.utils.SimLogger; + +public class MultiArmedBanditHelper { + private static final double Beta = 1; + + private double MAX_TASK_LENGTH; + private double MIN_TASK_LENGTH; + + private int[] K_tn = {0, 0, 0}; //number of task offloaded to EDGE_DATACENTER, CLOUD_DATACENTER_VIA_RSU, CLOUD_DATACENTER_VIA_GSM + private double[] U_tn = {0, 0, 0}; //empirical delay performance of the related datacenters + private int t = 1; //round + private boolean isInitialized; + + public MultiArmedBanditHelper(double minTaskLength, double maxTaskLength) { + MIN_TASK_LENGTH = minTaskLength; + MAX_TASK_LENGTH = maxTaskLength; + isInitialized = false; + } + + public synchronized boolean isInitialized(){ + return isInitialized; + } + + /** + * @param expectedDelays expected delay for each WLAN, WAN and GSM + * @param taskLength task length + */ + public synchronized void initialize(double[] expectedDelays, double taskLength) { + for(int i=0; i=0; i--){ + statForPreviousWindow[i+1].cloudViaRsuStat.numOfCompletedTasks = statForPreviousWindow[i].cloudViaRsuStat.numOfCompletedTasks; + statForPreviousWindow[i+1].cloudViaRsuStat.numOfFailedTasks = statForPreviousWindow[i].cloudViaRsuStat.numOfFailedTasks; + statForPreviousWindow[i+1].cloudViaRsuStat.totalServiceTime = statForPreviousWindow[i].cloudViaRsuStat.totalServiceTime; + + statForPreviousWindow[i+1].cloudViaGsmStat.numOfCompletedTasks = statForPreviousWindow[i].cloudViaGsmStat.numOfCompletedTasks; + statForPreviousWindow[i+1].cloudViaGsmStat.numOfFailedTasks = statForPreviousWindow[i].cloudViaGsmStat.numOfFailedTasks; + statForPreviousWindow[i+1].cloudViaGsmStat.totalServiceTime = statForPreviousWindow[i].cloudViaGsmStat.totalServiceTime; + + statForPreviousWindow[i+1].edgeStat.numOfCompletedTasks = statForPreviousWindow[i].edgeStat.numOfCompletedTasks; + statForPreviousWindow[i+1].edgeStat.numOfFailedTasks = statForPreviousWindow[i].edgeStat.numOfFailedTasks; + statForPreviousWindow[i+1].edgeStat.totalServiceTime = statForPreviousWindow[i].edgeStat.totalServiceTime; + } + + statForPreviousWindow[0].cloudViaRsuStat.numOfCompletedTasks = statForCurrentWindow.cloudViaRsuStat.numOfCompletedTasks; + statForPreviousWindow[0].cloudViaRsuStat.numOfFailedTasks = statForCurrentWindow.cloudViaRsuStat.numOfFailedTasks; + statForPreviousWindow[0].cloudViaRsuStat.totalServiceTime = statForCurrentWindow.cloudViaRsuStat.totalServiceTime; + statForCurrentWindow.cloudViaRsuStat.numOfCompletedTasks = 0; + statForCurrentWindow.cloudViaRsuStat.numOfFailedTasks = 0; + statForCurrentWindow.cloudViaRsuStat.totalServiceTime = 0; + + statForPreviousWindow[0].cloudViaGsmStat.numOfCompletedTasks = statForCurrentWindow.cloudViaGsmStat.numOfCompletedTasks; + statForPreviousWindow[0].cloudViaGsmStat.numOfFailedTasks = statForCurrentWindow.cloudViaGsmStat.numOfFailedTasks; + statForPreviousWindow[0].cloudViaGsmStat.totalServiceTime = statForCurrentWindow.cloudViaGsmStat.totalServiceTime; + statForCurrentWindow.cloudViaGsmStat.numOfCompletedTasks = 0; + statForCurrentWindow.cloudViaGsmStat.numOfFailedTasks = 0; + statForCurrentWindow.cloudViaGsmStat.totalServiceTime = 0; + + statForPreviousWindow[0].edgeStat.numOfCompletedTasks = statForCurrentWindow.edgeStat.numOfCompletedTasks; + statForPreviousWindow[0].edgeStat.numOfFailedTasks = statForCurrentWindow.edgeStat.numOfFailedTasks; + statForPreviousWindow[0].edgeStat.totalServiceTime = statForCurrentWindow.edgeStat.totalServiceTime; + statForCurrentWindow.edgeStat.numOfCompletedTasks = 0; + statForCurrentWindow.edgeStat.numOfFailedTasks = 0; + statForCurrentWindow.edgeStat.totalServiceTime = 0; + } +} diff --git a/src/edu/boun/edgecloudsim/applications/sample_app5/OrchestratorTrainerLogger.java b/src/edu/boun/edgecloudsim/applications/sample_app5/OrchestratorTrainerLogger.java new file mode 100644 index 0000000..6c30c8e --- /dev/null +++ b/src/edu/boun/edgecloudsim/applications/sample_app5/OrchestratorTrainerLogger.java @@ -0,0 +1,227 @@ +package edu.boun.edgecloudsim.applications.sample_app5; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.cloudbus.cloudsim.core.CloudSim; + +import edu.boun.edgecloudsim.core.SimManager; +import edu.boun.edgecloudsim.core.SimSettings; +import edu.boun.edgecloudsim.edge_client.Task; +import edu.boun.edgecloudsim.edge_server.EdgeVM; +import edu.boun.edgecloudsim.utils.SimLogger; + +public class OrchestratorTrainerLogger { + private static final double STAT_WINDOW = 1; //sec + private static final String DELIMITER = ","; + private Map trainerMap; + private List[] TaskOffloadStats; + + private BufferedWriter learnerBW = null; + + class TrainerItem { + int selectedDatacenter; + int numOffloadedTask; + double avgEdgeUtilization; + double wanUploadDelay; + double wanDownloadDelay; + double gsmUploadDelay; + double gsmDownloadDelay; + double wlanUploadDelay; + double wlanDownloadDelay; + + TrainerItem(int selectedDatacenter, + int numOffloadedTask, double avgEdgeUtilization, + double wanUploadDelay, double wanDownloadDelay, + double gsmUploadDelay, double gsmDownloadDelay, + double wlanUploadDelay, double wlanDownloadDelay) + { + this.selectedDatacenter = selectedDatacenter; + this.avgEdgeUtilization = avgEdgeUtilization; + this.numOffloadedTask = numOffloadedTask; + this.wanUploadDelay = wanUploadDelay; + this.wanDownloadDelay = wanDownloadDelay; + this.gsmUploadDelay = gsmUploadDelay; + this.gsmDownloadDelay = gsmDownloadDelay; + this.wlanUploadDelay = wlanUploadDelay; + this.wlanDownloadDelay = wlanDownloadDelay; + } + } + + @SuppressWarnings("unchecked") + public OrchestratorTrainerLogger() { + trainerMap = new HashMap(); + + TaskOffloadStats = (ArrayList[])new ArrayList[3]; + TaskOffloadStats[0] = new ArrayList(); + TaskOffloadStats[1] = new ArrayList(); + TaskOffloadStats[2] = new ArrayList(); + } + + public void openTrainerOutputFile() { + try { + int numOfMobileDevices = SimManager.getInstance().getNumOfMobileDevice(); + String learnerOutputFile = SimLogger.getInstance().getOutputFolder() + + "/" + numOfMobileDevices + "_learnerOutputFile.cvs"; + File learnerFile = new File(learnerOutputFile); + FileWriter learnerFW = new FileWriter(learnerFile); + learnerBW = new BufferedWriter(learnerFW); + + String line = "Decision" + + DELIMITER + "Result" + + DELIMITER + "ServiceTime" + + DELIMITER + "ProcessingTime" + + DELIMITER + "VehicleLocation" + + DELIMITER + "SelectedHostID" + + DELIMITER + "TaskLength" + + DELIMITER + "TaskInput" + + DELIMITER + "TaskOutput" + + DELIMITER + "WANUploadDelay" + + DELIMITER + "WANDownloadDelay" + + DELIMITER + "GSMUploadDelay" + + DELIMITER + "GSMDownloadDelay" + + DELIMITER + "WLANUploadDelay" + + DELIMITER + "WLANDownloadDelay" + + DELIMITER + "AvgEdgeUtilization" + + DELIMITER + "NumOffloadedTask"; + + //for(int i=1; i<=SimSettings.getInstance().getNumOfEdgeHosts(); i++) + // line += DELIMITER + "Avg Edge(" + i + ") Utilization"; + + learnerBW.write(line); + learnerBW.newLine(); + + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + } + public void closeTrainerOutputFile() { + try { + learnerBW.close(); + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + } + + public void saveStat(TrainerItem trainerItem, Task task, + boolean result, double serviceTime) { + String line = ""; + + switch(trainerItem.selectedDatacenter){ + case VehicularEdgeOrchestrator.EDGE_DATACENTER: + line = "EDGE"; + break; + case VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_RSU: + line = "CLOUD_VIA_RSU"; + break; + case VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_GSM: + line = "CLOUD_VIA_GSM"; + break; + default: + SimLogger.printLine("Unknown datacenter type"); + System.exit(1); + break; + } + + int submittedLocation = task.getSubmittedLocation().getServingWlanId(); + Double processingTime = task.getFinishTime()-task.getExecStartTime(); + + line += DELIMITER + (result == true ? "success" : "fail") + + DELIMITER + Double.toString(serviceTime) + + DELIMITER + Double.toString(processingTime) + + DELIMITER + Integer.toString(submittedLocation) + + DELIMITER + Integer.toString(task.getAssociatedHostId()) + + DELIMITER + Long.toString(task.getCloudletLength()) + + DELIMITER + Long.toString(task.getCloudletFileSize()) + + DELIMITER + Long.toString(task.getCloudletOutputSize()) + + DELIMITER + Double.toString(trainerItem.wanUploadDelay) + + DELIMITER + Double.toString(trainerItem.wanDownloadDelay) + + DELIMITER + Double.toString(trainerItem.gsmUploadDelay) + + DELIMITER + Double.toString(trainerItem.gsmDownloadDelay) + + DELIMITER + Double.toString(trainerItem.wlanUploadDelay) + + DELIMITER + Double.toString(trainerItem.wlanDownloadDelay) + + DELIMITER + Double.toString(trainerItem.avgEdgeUtilization) + + DELIMITER + Integer.toString(trainerItem.numOffloadedTask); + + //for(int i=0; i vmArray = SimManager.getInstance().getEdgeServerManager().getVmList(hostIndex); + + double utilization=0; + for(int vmIndex=0; vmIndex iter = TaskOffloadStats[datacenterIdx].iterator(); iter.hasNext(); ) { + if (iter.next() + STAT_WINDOW < time) + iter.remove(); + else + break; + } + TaskOffloadStats[datacenterIdx].add(time); + } + + public synchronized int getOffloadStat(int datacenterIdx) { + return TaskOffloadStats[datacenterIdx].size(); + } +} diff --git a/src/edu/boun/edgecloudsim/applications/sample_app5/README.md b/src/edu/boun/edgecloudsim/applications/sample_app5/README.md new file mode 100644 index 0000000..7d5ddd8 --- /dev/null +++ b/src/edu/boun/edgecloudsim/applications/sample_app5/README.md @@ -0,0 +1,55 @@ +# Sample Application 5 + +This application includes the source code which is used in our paper submitted to IEEE Transactions on Intelligent Transportation Systems [[1]](https://ieeexplore.ieee.org/abstract/document/9208723/). + +## Vehicular Edge Computing + +The concept of Internet of Vehicle (IoV), its pioneering applications, and the services for the future smart highways can benefit from the computation offloading concept over a multi-tier architecture consisting of the connected vehicles, road side units (RSUs), and cloud computing elements as shown in Figure 6.1. The vehicles are located in the first tier, which can be considered as the data generation layer. They also have computational resources which are provided by their on board units (OBUs). If required, some of the operations can be executed locally by the OBUs at this tier. The second tier consists of the RSUs that can provide fast access to limited resources. The edge servers are located in this tier. Finally, the third tier includes traditional cloud computing elements. + +

+ +

+ Figure 1: Multi-tier VEC architecture for vehicular networks. +

+

+ + +## Machine Learning-Based Workload Orchestrator + +In this application we introduce a machine learning (ML) based workload orchestrator. the ML-based orchestrator performs a two-stage process as shown in Figure 2. In the first stage, a classifier model predicts whether the results of the offloading options are successful or not for each target device. In the second stage, a regression model estimates the service time of the related options. Finally, the target device which promises the lowest service time is selected. + +

+ +

+ Figure 2: Two stage ML-based vehicular edge orchestrator. +

+

+ +We experimented with multiple classifiers, including naive Bayes (NB), support vector machine (SVM) and multi layer perceptron (MLP) models. The MLP was chosen as the best classifier based on the performance comparison of these models. A demonstrative example of a two-stage ML-based vehicular edge orchestrator is illustrated in Fig. 4. As shown in Figure 3, offloading to the edge and cloud via cellular network (CN) options are predicted to be successful in the first stage; hence they are selected as the initial candidates. The cloud via CN option is determined as the best candidate in the second stage since it promises better service time value than the edge option. + +

+ +

+ Figure 3: Demonstrative example of the ML-based orchestrator stages. +

+

+ + +## Why Machine Learning? + +Orchestrating the dynamic and heterogeneous resources in the VEC systems is a challenging task. The vehicular workload orchestrator promises to offload the incoming tasks (workload) to the optimal computing unit to improve the system performance. Since the service requests are created one after the other in a dynamic fashion, workload orchestration is an online problem and cannot be solved by the formal optimization tools like CPLEX and Gurobi. We propose an ML-based workload orchestrator for multi-access multi-tier VEC to maximize the percentage of satisfied services by dynamically changing network conditions and server utilization. It can handle the uncertain nonlinear systems efficiently by considering multiple criteria. + +## Simulated Environment + +The road and mobility model used in the simulations is implemented on EdgeCloudSim, as shown in Figure 6.9. To simulate the vehicular mobility more realistically, the road is divided into segments, and a dynamic velocity value for the vehicle position is used. Therefore, the speed of the vehicles varies at each segment to differentiate the traffic density on the road. The hotspot locations, which are shown with red color, occur due to the traffic jam. 100 to 1800 vehicles are distributed to random locations when the simulation is started. Then they move in a single direction with a predefined speed with respect to the crossed segment. The road is modeled as a circular route to keep the number of vehicles the same during the simulation. + +

+ +

+ Figure 4: Vehicular mobility model in the simulation. +

+

+ + +## References +**[1]** C. Sonmez, A. Ozgovde and C. Ersoy, "[Machine Learning-Based Workload Orchestrator for Vehicular Edge Computing](https://ieeexplore.ieee.org/abstract/document/9208723/)," in *IEEE Transactions on Intelligent Transportation Systems*, doi: 10.1109/TITS.2020.3024233. diff --git a/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularCpuUtilizationModel.java b/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularCpuUtilizationModel.java new file mode 100644 index 0000000..8a1bee2 --- /dev/null +++ b/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularCpuUtilizationModel.java @@ -0,0 +1,67 @@ +/* + * Title: EdgeCloudSim - Custom VM Cpu Utilization Model + * + * Description: + * CpuUtilizationModel_Custom implements UtilizationModel and used for + * VM CPU utilization model. In CloudSim, the CPU utilization of the VM + * is a simple counter. We provide more realistic utilization model + * which decide CPU utilization of each application by using the + * values defined in the applications.xml file. For those who wants to + * add another VM Cpu Utilization Model to EdgeCloudSim should provide + * another concrete instance of UtilizationModel via ScenarioFactory + * + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * Copyright (c) 2017, Bogazici University, Istanbul, Turkey + */ + +package edu.boun.edgecloudsim.applications.sample_app5; + +import org.cloudbus.cloudsim.UtilizationModel; + +import edu.boun.edgecloudsim.core.SimSettings; +import edu.boun.edgecloudsim.edge_client.Task; +import edu.boun.edgecloudsim.utils.SimLogger; + +public class VehicularCpuUtilizationModel implements UtilizationModel { + private Task task; + + public VehicularCpuUtilizationModel(){ + } + + /* + * (non-Javadoc) + * @see cloudsim.power.UtilizationModel#getUtilization(double) + */ + @Override + public double getUtilization(double time) { + int datacenterId = task.getAssociatedDatacenterId(); + int index = 0; + + if(datacenterId == VehicularEdgeOrchestrator.EDGE_DATACENTER) + index = 9; + else if(datacenterId == VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_GSM || + datacenterId == VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_RSU) + index = 10; + + return SimSettings.getInstance().getTaskLookUpTable()[task.getTaskType()][index]; + } + + public void setTask(Task _task){ + task=_task; + } + + public double predictUtilization(SimSettings.VM_TYPES _vmType){ + int index = 0; + if(_vmType == SimSettings.VM_TYPES.EDGE_VM) + index = 9; + else if(_vmType == SimSettings.VM_TYPES.CLOUD_VM) + index = 10; + else if(_vmType == SimSettings.VM_TYPES.MOBILE_VM) + index = 11; + else{ + SimLogger.printLine("Unknown VM Type! Terminating simulation..."); + System.exit(1); + } + return SimSettings.getInstance().getTaskLookUpTable()[task.getTaskType()][index]; + } +} diff --git a/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularEdgeOrchestrator.java b/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularEdgeOrchestrator.java new file mode 100644 index 0000000..76ab625 --- /dev/null +++ b/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularEdgeOrchestrator.java @@ -0,0 +1,465 @@ +/* + * Title: EdgeCloudSim - Edge Orchestrator implementation + * + * Description: + * VehicularEdgeOrchestrator decides which tier (mobile, edge or cloud) + * to offload and picks proper VM to execute incoming tasks + * + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * Copyright (c) 2017, Bogazici University, Istanbul, Turkey + */ + +package edu.boun.edgecloudsim.applications.sample_app5; + +import java.util.stream.DoubleStream; + +import org.cloudbus.cloudsim.Vm; +import org.cloudbus.cloudsim.core.CloudSim; +import org.cloudbus.cloudsim.core.SimEvent; + +import edu.boun.edgecloudsim.core.SimManager; +import edu.boun.edgecloudsim.core.SimSettings; +import edu.boun.edgecloudsim.core.SimSettings.NETWORK_DELAY_TYPES; +import edu.boun.edgecloudsim.edge_orchestrator.EdgeOrchestrator; +import edu.boun.edgecloudsim.edge_client.Task; +import edu.boun.edgecloudsim.utils.SimLogger; +import edu.boun.edgecloudsim.utils.SimUtils; + +public class VehicularEdgeOrchestrator extends EdgeOrchestrator { + private static final int BASE = 100000; //start from base in order not to conflict cloudsim tag! + private static final int UPDATE_PREDICTION_WINDOW = BASE+1; + + public static final int CLOUD_DATACENTER_VIA_GSM = 1; + public static final int CLOUD_DATACENTER_VIA_RSU = 2; + public static final int EDGE_DATACENTER = 3; + + private int cloudVmCounter; + private int edgeVmCounter; + private int numOfMobileDevice; + + private OrchestratorStatisticLogger statisticLogger; + private OrchestratorTrainerLogger trainerLogger; + + private MultiArmedBanditHelper MAB; + private GameTheoryHelper GTH; + + public VehicularEdgeOrchestrator(int _numOfMobileDevices, String _policy, String _simScenario) { + super(_policy, _simScenario); + this.numOfMobileDevice = _numOfMobileDevices; + } + + @Override + public void initialize() { + cloudVmCounter = 0; + edgeVmCounter = 0; + + statisticLogger = new OrchestratorStatisticLogger(); + trainerLogger = new OrchestratorTrainerLogger(); + + double lookupTable[][] = SimSettings.getInstance().getTaskLookUpTable(); + //assume the first app has the lowest and the last app has the highest task length value + double minTaskLength = lookupTable[0][7]; + double maxTaskLength = lookupTable[lookupTable.length-1][7]; + MAB = new MultiArmedBanditHelper(minTaskLength, maxTaskLength); + + //assume the first app has the lowest and the last app has the highest task arrival rate + //double minTaskArrivalRate = lookupTable[0][2]; + //double maxTaskArrivalRate = lookupTable[lookupTable.length-1][2]; + GTH = new GameTheoryHelper(0, 20, numOfMobileDevice); + } + + @Override + public int getDeviceToOffload(Task task) { + int result = 0; + + double avgEdgeUtilization = SimManager.getInstance().getEdgeServerManager().getAvgUtilization(); + double avgCloudUtilization = SimManager.getInstance().getCloudServerManager().getAvgUtilization(); + + VehicularNetworkModel networkModel = (VehicularNetworkModel)SimManager.getInstance().getNetworkModel(); + double wanUploadDelay = networkModel.estimateUploadDelay(NETWORK_DELAY_TYPES.WAN_DELAY, task); + double wanDownloadDelay = networkModel.estimateDownloadDelay(NETWORK_DELAY_TYPES.WAN_DELAY, task); + + double gsmUploadDelay = networkModel.estimateUploadDelay(NETWORK_DELAY_TYPES.GSM_DELAY, task); + double gsmDownloadDelay = networkModel.estimateDownloadDelay(NETWORK_DELAY_TYPES.GSM_DELAY, task); + + double wlanUploadDelay = networkModel.estimateUploadDelay(NETWORK_DELAY_TYPES.WLAN_DELAY, task); + double wlanDownloadDelay =networkModel.estimateDownloadDelay(NETWORK_DELAY_TYPES.WLAN_DELAY, task); + + int options[] = { + EDGE_DATACENTER, + CLOUD_DATACENTER_VIA_RSU, + CLOUD_DATACENTER_VIA_GSM + }; + + if(policy.startsWith("AI_") || policy.equals("MAB") || policy.equals("GAME_THEORY")) { + if(wanUploadDelay == 0) + wanUploadDelay = WekaWrapper.MAX_WAN_DELAY; + + if(wanDownloadDelay == 0) + wanDownloadDelay = WekaWrapper.MAX_WAN_DELAY; + + if(gsmUploadDelay == 0) + gsmUploadDelay = WekaWrapper.MAX_GSM_DELAY; + + if(gsmDownloadDelay == 0) + gsmDownloadDelay = WekaWrapper.MAX_GSM_DELAY; + + if(wlanUploadDelay == 0) + wlanUploadDelay = WekaWrapper.MAX_WLAN_DELAY; + + if(wlanDownloadDelay == 0) + wlanDownloadDelay = WekaWrapper.MAX_WLAN_DELAY; + } + + if (policy.equals("AI_BASED")) { + WekaWrapper weka = WekaWrapper.getInstance(); + + boolean predictedResultForEdge = weka.handleClassification(EDGE_DATACENTER, + new double[] {trainerLogger.getOffloadStat(EDGE_DATACENTER-1), + task.getCloudletLength(), wlanUploadDelay, + wlanDownloadDelay, avgEdgeUtilization}); + + boolean predictedResultForCloudViaRSU = weka.handleClassification(CLOUD_DATACENTER_VIA_RSU, + new double[] {trainerLogger.getOffloadStat(CLOUD_DATACENTER_VIA_RSU-1), + wanUploadDelay, wanDownloadDelay}); + + boolean predictedResultForCloudViaGSM = weka.handleClassification(CLOUD_DATACENTER_VIA_GSM, + new double[] {trainerLogger.getOffloadStat(CLOUD_DATACENTER_VIA_GSM-1), + gsmUploadDelay, gsmDownloadDelay}); + + double predictedServiceTimeForEdge = Double.MAX_VALUE; + double predictedServiceTimeForCloudViaRSU = Double.MAX_VALUE; + double predictedServiceTimeForCloudViaGSM = Double.MAX_VALUE; + + if(predictedResultForEdge) + predictedServiceTimeForEdge = weka.handleRegression(EDGE_DATACENTER, + new double[] {task.getCloudletLength(), avgEdgeUtilization}); + + if(predictedResultForCloudViaRSU) + predictedServiceTimeForCloudViaRSU = weka.handleRegression(CLOUD_DATACENTER_VIA_RSU, + new double[] {task.getCloudletLength(), wanUploadDelay, wanDownloadDelay}); + + if(predictedResultForCloudViaGSM) + predictedServiceTimeForCloudViaGSM = weka.handleRegression(CLOUD_DATACENTER_VIA_GSM, + new double[] {task.getCloudletLength(), gsmUploadDelay, gsmDownloadDelay}); + + if(!predictedResultForEdge && !predictedResultForCloudViaRSU && !predictedResultForCloudViaGSM) { + double probabilities[] = {0.33, 0.34, 0.33}; + + double randomNumber = SimUtils.getRandomDoubleNumber(0, 1); + double lastPercentagte = 0; + boolean resultFound = false; + for(int i=0; i SimSettings.getInstance().getWarmUpPeriod()) { + /* + * failureRate_i = 100 * numOfFailedTask / (numOfFailedTask + numOfSuccessfulTask) + */ + double failureRates[] = { + statisticLogger.getFailureRate(options[0]), + statisticLogger.getFailureRate(options[1]), + statisticLogger.getFailureRate(options[2]) + }; + + double serviceTimes[] = { + statisticLogger.getServiceTime(options[0]), + statisticLogger.getServiceTime(options[1]), + statisticLogger.getServiceTime(options[2]) + }; + + double failureRateScores[] = {0, 0, 0}; + double serviceTimeScores[] = {0, 0, 0}; + + //scores are calculated inversely by failure rate and service time + //lower failure rate and service time is better + for(int i=0; i 0.3) + probabilities[i] = failureRateScores[i] / DoubleStream.of(failureRateScores).sum(); + else + probabilities[i] = serviceTimeScores[i] / DoubleStream.of(serviceTimeScores).sum(); + } + } + + double randomNumber = SimUtils.getRandomDoubleNumber(0.01, 0.99); + double lastPercentagte = 0; + boolean resultFound = false; + for(int i=0; i hostList, int dataCenterIndex) { + return new EdgeVmAllocationPolicy_Custom(hostList,dataCenterIndex); + } + + public void startDatacenters() throws Exception{ + //create random number generator for each place + Document doc = SimSettings.getInstance().getEdgeDevicesDocument(); + NodeList datacenterList = doc.getElementsByTagName("datacenter"); + for (int i = 0; i < datacenterList.getLength(); i++) { + Node datacenterNode = datacenterList.item(i); + Element datacenterElement = (Element) datacenterNode; + localDatacenters.add(createDatacenter(i, datacenterElement)); + } + } + + public void createVmList(int brockerId){ + int hostCounter=0; + int vmCounter=0; + + //Create VMs for each hosts + Document doc = SimSettings.getInstance().getEdgeDevicesDocument(); + NodeList datacenterList = doc.getElementsByTagName("datacenter"); + for (int i = 0; i < datacenterList.getLength(); i++) { + Node datacenterNode = datacenterList.item(i); + Element datacenterElement = (Element) datacenterNode; + NodeList hostNodeList = datacenterElement.getElementsByTagName("host"); + for (int j = 0; j < hostNodeList.getLength(); j++) { + + vmList.add(hostCounter, new ArrayList()); + + Node hostNode = hostNodeList.item(j); + Element hostElement = (Element) hostNode; + NodeList vmNodeList = hostElement.getElementsByTagName("VM"); + for (int k = 0; k < vmNodeList.getLength(); k++) { + Node vmNode = vmNodeList.item(k); + Element vmElement = (Element) vmNode; + + String vmm = vmElement.getAttribute("vmm"); + int numOfCores = Integer.parseInt(vmElement.getElementsByTagName("core").item(0).getTextContent()); + double mips = Double.parseDouble(vmElement.getElementsByTagName("mips").item(0).getTextContent()); + int ram = Integer.parseInt(vmElement.getElementsByTagName("ram").item(0).getTextContent()); + long storage = Long.parseLong(vmElement.getElementsByTagName("storage").item(0).getTextContent()); + long bandwidth = SimSettings.getInstance().getWlanBandwidth() / (hostNodeList.getLength()+vmNodeList.getLength()); + + //VM Parameters + EdgeVM vm = new EdgeVM(vmCounter, brockerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); + vmList.get(hostCounter).add(vm); + vmCounter++; + } + + hostCounter++; + } + } + } + + public void terminateDatacenters(){ + for (Datacenter datacenter : localDatacenters) { + datacenter.shutdownEntity(); + } + } + + //average utilization of all VMs + public double getAvgUtilization(){ + double totalUtilization = 0; + int hostCounter = 0; + int vmCounter = 0; + + // for each datacenter... + for(int i= 0; i list = localDatacenters.get(i).getHostList(); + // for each host... + for (int hostIndex=0; hostIndex < list.size(); hostIndex++) { + List vmArray = SimManager.getInstance().getEdgeServerManager().getVmList(hostCounter); + //for each vm... + for(int vmIndex=0; vmIndex hostList=createHosts(datacenterElement); + + String name = "EdgeDatacenter_" + Integer.toString(index); + double time_zone = 3.0; // time zone this resource located + LinkedList storageList = new LinkedList(); //we are not adding SAN devices by now + + // 5. Create a DatacenterCharacteristics object that stores the + // properties of a data center: architecture, OS, list of + // Machines, allocation policy: time- or space-shared, time zone + // and its price (G$/Pe time unit). + DatacenterCharacteristics characteristics = new DatacenterCharacteristics( + arch, os, vmm, hostList, time_zone, costPerSec, costPerMem, costPerStorage, costPerBw); + + // 6. Finally, we need to create a PowerDatacenter object. + Datacenter datacenter = null; + + VmAllocationPolicy vm_policy = getVmAllocationPolicy(hostList,index); + datacenter = new Datacenter(name, characteristics, vm_policy, storageList, 0); + + return datacenter; + } + + private List createHosts(Element datacenterElement){ + + // Here are the steps needed to create a PowerDatacenter: + // 1. We need to create a list to store one or more Machines + List hostList = new ArrayList(); + + Element location = (Element)datacenterElement.getElementsByTagName("location").item(0); + String attractiveness = location.getElementsByTagName("attractiveness").item(0).getTextContent(); + int wlan_id = Integer.parseInt(location.getElementsByTagName("wlan_id").item(0).getTextContent()); + int x_pos = Integer.parseInt(location.getElementsByTagName("x_pos").item(0).getTextContent()); + int y_pos = Integer.parseInt(location.getElementsByTagName("y_pos").item(0).getTextContent()); + int placeTypeIndex = Integer.parseInt(attractiveness); + + NodeList hostNodeList = datacenterElement.getElementsByTagName("host"); + for (int j = 0; j < hostNodeList.getLength(); j++) { + Node hostNode = hostNodeList.item(j); + + Element hostElement = (Element) hostNode; + int numOfCores = Integer.parseInt(hostElement.getElementsByTagName("core").item(0).getTextContent()); + double mips = Double.parseDouble(hostElement.getElementsByTagName("mips").item(0).getTextContent()); + int ram = Integer.parseInt(hostElement.getElementsByTagName("ram").item(0).getTextContent()); + long storage = Long.parseLong(hostElement.getElementsByTagName("storage").item(0).getTextContent()); + long bandwidth = SimSettings.getInstance().getWlanBandwidth() / hostNodeList.getLength(); + + // 2. A Machine contains one or more PEs or CPUs/Cores. Therefore, should + // create a list to store these PEs before creating + // a Machine. + List peList = new ArrayList(); + + // 3. Create PEs and add these into the list. + //for a quad-core machine, a list of 4 PEs is required: + for(int i=0; i(); + + //Each mobile device utilizes an app type (task type) + taskTypeOfDevices = new int[numberOfMobileDevices]; + for(int i=0; i " + interval + " for device " + i + " time "); + virtualTime += interval; + + if(virtualTime > activePeriodStartTime + activePeriod){ + activePeriodStartTime = activePeriodStartTime + activePeriod + idlePeriod; + virtualTime = activePeriodStartTime; + continue; + } + + long inputFileSize = (long)SimSettings.getInstance().getTaskLookUpTable()[randomTaskType][5]; + long inputFileSizeBias = inputFileSize / 10; + + long outputFileSize =(long)SimSettings.getInstance().getTaskLookUpTable()[randomTaskType][6]; + long outputFileSizeBias = outputFileSize / 10; + + long length = (long)SimSettings.getInstance().getTaskLookUpTable()[randomTaskType][7]; + long lengthBias = length / 10; + + int pesNumber = (int)SimSettings.getInstance().getTaskLookUpTable()[randomTaskType][8]; + + inputFileSize = SimUtils.getRandomLongNumber(inputFileSize - inputFileSizeBias, inputFileSize + inputFileSizeBias); + outputFileSize = SimUtils.getRandomLongNumber(outputFileSize - outputFileSizeBias, outputFileSize + outputFileSizeBias); + length = SimUtils.getRandomLongNumber(length - lengthBias, length + lengthBias); + + taskList.add(new TaskProperty(virtualTime, i, randomTaskType, pesNumber, length, inputFileSize, outputFileSize)); + } + } + } + + @Override + public int getTaskTypeOfDevice(int deviceId) { + // TODO Auto-generated method stub + return taskTypeOfDevices[deviceId]; + } + +} \ No newline at end of file diff --git a/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularMainApp.java b/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularMainApp.java new file mode 100644 index 0000000..4b069c2 --- /dev/null +++ b/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularMainApp.java @@ -0,0 +1,150 @@ +/* + * Title: EdgeCloudSim - Sample Application + * + * Description: Sample application for Vehicular App + * + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * Copyright (c) 2017, Bogazici University, Istanbul, Turkey + */ + +package edu.boun.edgecloudsim.applications.sample_app5; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +import org.cloudbus.cloudsim.Log; +import org.cloudbus.cloudsim.core.CloudSim; + +import edu.boun.edgecloudsim.core.ScenarioFactory; +import edu.boun.edgecloudsim.core.SimManager; +import edu.boun.edgecloudsim.core.SimSettings; +import edu.boun.edgecloudsim.utils.SimLogger; +import edu.boun.edgecloudsim.utils.SimUtils; + +public class VehicularMainApp { + + /** + * Creates main() to run this example + */ + public static void main(String[] args) { + //disable console output of cloudsim library + Log.disable(); + + //enable console output and file output of this application + SimLogger.enablePrintLog(); + + int iterationNumber = 1; + String configFile = ""; + String outputFolder = ""; + String edgeDevicesFile = ""; + String applicationsFile = ""; + if (args.length == 5){ + configFile = args[0]; + edgeDevicesFile = args[1]; + applicationsFile = args[2]; + outputFolder = args[3]; + iterationNumber = Integer.parseInt(args[4]); + } + else{ + SimLogger.printLine("Simulation setting file, output folder and iteration number are not provided! Using default ones..."); + String configName = "default"; + configFile = "scripts/sample_app5/config/" + configName + "_config.properties"; + applicationsFile = "scripts/sample_app5/config/applications.xml"; + edgeDevicesFile = "scripts/sample_app5/config/edge_devices.xml"; + outputFolder = "sim_results/ite" + iterationNumber; + } + + //load settings from configuration file + SimSettings SS = SimSettings.getInstance(); + if(SS.initialize(configFile, edgeDevicesFile, applicationsFile) == false) { + SimLogger.printLine("cannot initialize simulation settings!"); + System.exit(1); + } + + if(SS.getFileLoggingEnabled()){ + SimUtils.cleanOutputFolder(outputFolder); + SimLogger.enableFileLog(); + } + + DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); + Date SimulationStartDate = Calendar.getInstance().getTime(); + String now = df.format(SimulationStartDate); + SimLogger.printLine("Simulation started at " + now); + SimLogger.printLine("----------------------------------------------------------------------"); + + String wekaModelsFolder = configFile.substring(0, configFile.lastIndexOf('/')) + "/weka/"; + WekaWrapper.getInstance().initialize("MultilayerPerceptron", "LinearRegression", wekaModelsFolder); + + for(int i=SS.getMinNumOfMobileDev(); i<=SS.getMaxNumOfMobileDev(); i+=SS.getMobileDevCounterSize()) + for(int s=0; s 0) + { + SimLogger.getInstance().setDownloadDelay(task.getCloudletId(), gsmDelay, delayType); + schedule(getId(), gsmDelay, RESPONSE_RECEIVED_BY_MOBILE_DEVICE, task); + } + else + { + SimLogger.getInstance().failedDueToBandwidth(task.getCloudletId(), CloudSim.clock(), delayType); + edgeOrchestrator.taskFailed(task); + } + } + else if(task.getAssociatedDatacenterId() == VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_RSU) { + NETWORK_DELAY_TYPES delayType = NETWORK_DELAY_TYPES.WAN_DELAY; + double wanDelay = networkModel.getDownloadDelay(delayType, task); + if(wanDelay > 0) + { + SimLogger.getInstance().setDownloadDelay(task.getCloudletId(), wanDelay, delayType); + schedule(getId(), wanDelay, RESPONSE_RECEIVED_BY_EDGE_DEVICE, task); + } + else + { + SimLogger.getInstance().failedDueToBandwidth(task.getCloudletId(), CloudSim.clock(), delayType); + edgeOrchestrator.taskFailed(task); + } + } + else if(task.getAssociatedDatacenterId() == VehicularEdgeOrchestrator.EDGE_DATACENTER) { + Location currentLocation = SimManager.getInstance().getMobilityModel().getLocation(task.getMobileDeviceId(),CloudSim.clock()); + if(task.getSubmittedLocation().getServingWlanId() == currentLocation.getServingWlanId()) + { + NETWORK_DELAY_TYPES delayType = NETWORK_DELAY_TYPES.WLAN_DELAY; + double wlanDelay = networkModel.getDownloadDelay(delayType, task); + if(wlanDelay > 0) + { + Location futureLocation = SimManager.getInstance().getMobilityModel().getLocation(task.getMobileDeviceId(),CloudSim.clock()+wlanDelay); + if(task.getSubmittedLocation().getServingWlanId() == futureLocation.getServingWlanId()) + { + SimLogger.getInstance().setDownloadDelay(task.getCloudletId(), wlanDelay, delayType); + schedule(getId(), wlanDelay, RESPONSE_RECEIVED_BY_MOBILE_DEVICE, task); + } + else + { + SimLogger.getInstance().failedDueToMobility(task.getCloudletId(), CloudSim.clock()); + //no need to record failed task due to the mobility + //edgeOrchestrator.taskFailed(task); + } + } + else + { + SimLogger.getInstance().failedDueToBandwidth(task.getCloudletId(), CloudSim.clock(), delayType); + edgeOrchestrator.taskFailed(task); + } + } + else + { + NETWORK_DELAY_TYPES delayType = NETWORK_DELAY_TYPES.MAN_DELAY; + double manDelay = networkModel.getDownloadDelay(delayType, task); + if(manDelay > 0) + { + SimLogger.getInstance().setDownloadDelay(task.getCloudletId(), manDelay, delayType); + schedule(getId(), manDelay, RESPONSE_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_MOBILE_DEVICE, task); + } + else + { + SimLogger.getInstance().failedDueToBandwidth(task.getCloudletId(), CloudSim.clock(), delayType); + edgeOrchestrator.taskFailed(task); + } + } + } + else { + SimLogger.printLine("Unknown datacenter id! Terminating simulation..."); + System.exit(1); + } + + } + + protected void processOtherEvent(SimEvent ev) { + if (ev == null) { + SimLogger.printLine(getName() + ".processOtherEvent(): " + "Error - an event is null! Terminating simulation..."); + System.exit(1); + return; + } + + VehicularNetworkModel networkModel = (VehicularNetworkModel)SimManager.getInstance().getNetworkModel(); + VehicularEdgeOrchestrator edgeOrchestrator = (VehicularEdgeOrchestrator)SimManager.getInstance().getEdgeOrchestrator(); + + switch (ev.getTag()) { + case UPDATE_MM1_QUEUE_MODEL: + { + ((VehicularNetworkModel)networkModel).updateMM1QueeuModel(); + schedule(getId(), MM1_QUEUE_MODEL_UPDATE_INTERVAL, UPDATE_MM1_QUEUE_MODEL); + + break; + } + case SET_DELAY_LOG: + { + int[] indices = {0,6,10}; + double apUploadDelays[] = new double[indices.length]; + double apDownloadDelays[] = new double[indices.length]; + for(int i=0; i0){ + SimLogger.getInstance().setUploadDelay(task.getCloudletId(), wanDelay, delayType); + schedule(getId(), wanDelay, REQUEST_RECEIVED_BY_CLOUD, task); + } + else + { + //SimLogger.printLine("Task #" + task.getCloudletId() + " cannot assign to any VM"); + SimLogger.getInstance().rejectedDueToBandwidth( + task.getCloudletId(), + CloudSim.clock(), + SimSettings.VM_TYPES.CLOUD_VM.ordinal(), + delayType); + + edgeOrchestrator.taskFailed(task); + } + break; + } + case REQUEST_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_NEIGHBOR: + { + Task task = (Task) ev.getData(); + NETWORK_DELAY_TYPES delayType = NETWORK_DELAY_TYPES.MAN_DELAY; + + double manDelay = networkModel.getUploadDelay(delayType, task); + if(manDelay>0){ + SimLogger.getInstance().setUploadDelay(task.getCloudletId(), manDelay, delayType); + schedule(getId(), manDelay, REQUEST_RECEIVED_BY_EDGE_DEVICE, task); + } + else + { + //SimLogger.printLine("Task #" + task.getCloudletId() + " cannot assign to any VM"); + SimLogger.getInstance().rejectedDueToBandwidth( + task.getCloudletId(), + CloudSim.clock(), + SimSettings.VM_TYPES.EDGE_VM.ordinal(), + delayType); + + edgeOrchestrator.taskFailed(task); + } + break; + } + case RESPONSE_RECEIVED_BY_EDGE_DEVICE: + { + Task task = (Task) ev.getData(); + Location currentLocation = SimManager.getInstance().getMobilityModel().getLocation(task.getMobileDeviceId(),CloudSim.clock()); + if(task.getSubmittedLocation().getServingWlanId() == currentLocation.getServingWlanId()) + { + scheduleNow(getId(), RESPONSE_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_MOBILE_DEVICE, task); + } + else + { + NETWORK_DELAY_TYPES delayType = NETWORK_DELAY_TYPES.MAN_DELAY; + double manDelay = networkModel.getDownloadDelay(delayType, task); + if(manDelay > 0) + { + SimLogger.getInstance().setDownloadDelay(task.getCloudletId(), manDelay, delayType); + schedule(getId(), manDelay, RESPONSE_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_MOBILE_DEVICE, task); + } + else + { + SimLogger.getInstance().failedDueToBandwidth(task.getCloudletId(), CloudSim.clock(), delayType); + edgeOrchestrator.taskFailed(task); + } + } + + break; + } + case RESPONSE_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_MOBILE_DEVICE: + { + Task task = (Task) ev.getData(); + NETWORK_DELAY_TYPES delayType = NETWORK_DELAY_TYPES.WLAN_DELAY; + + //SimLogger.printLine(CloudSim.clock() + ": " + getName() + ": task #" + task.getCloudletId() + " received from edge"); + double wlanDelay = networkModel.getDownloadDelay(delayType, task); + + if(wlanDelay > 0) + { + Location currentLocation = SimManager.getInstance().getMobilityModel().getLocation(task.getMobileDeviceId(),CloudSim.clock()); + Location futureLocation = SimManager.getInstance().getMobilityModel().getLocation(task.getMobileDeviceId(),CloudSim.clock()+wlanDelay); + + if(currentLocation.getServingWlanId() == futureLocation.getServingWlanId()) + { + SimLogger.getInstance().setDownloadDelay(task.getCloudletId(), wlanDelay, delayType); + schedule(getId(), wlanDelay, RESPONSE_RECEIVED_BY_MOBILE_DEVICE, task);} + else + { + SimLogger.getInstance().failedDueToMobility(task.getCloudletId(), CloudSim.clock()); + //no need to record failed task due to the mobility + //edgeOrchestrator.taskFailed(task); + } + } + else + { + SimLogger.getInstance().failedDueToBandwidth(task.getCloudletId(), CloudSim.clock(), delayType); + edgeOrchestrator.taskFailed(task); + } + break; + } + case RESPONSE_RECEIVED_BY_MOBILE_DEVICE: + { + Task task = (Task) ev.getData(); + + String taskName = SimSettings.getInstance().getTaskName(task.getTaskType()); + double taskProperty[] = SimSettings.getInstance().getTaskProperties(taskName); + double serviceTime = CloudSim.clock() - task.getCreationTime(); + double delaySensitivity = taskProperty[12]; + double maxDelayRequirement = taskProperty[13]; + + double QoE = 100; + if(serviceTime > maxDelayRequirement){ + QoE = (Math.min(2*maxDelayRequirement,serviceTime) - maxDelayRequirement) / maxDelayRequirement; + QoE = 100 * (1-QoE) * (1-delaySensitivity); + } + + SimLogger.getInstance().setQoE(task.getCloudletId(),QoE); + + edgeOrchestrator.taskCompleted(task, serviceTime); + + //SimLogger.printLine(CloudSim.clock() + ": " + getName() + ": Cloudlet " + cloudlet.getCloudletId() + " is received"); + SimLogger.getInstance().taskEnded(task.getCloudletId(), CloudSim.clock()); + + break; + } + default: + SimLogger.printLine(getName() + ".processOtherEvent(): " + "Error - event unknown by this DatacenterBroker. Terminating simulation..."); + System.exit(1); + break; + } + } + + public synchronized void submitTask(TaskProperty edgeTask) { + VehicularNetworkModel networkModel = (VehicularNetworkModel)SimManager.getInstance().getNetworkModel(); + VehicularEdgeOrchestrator edgeOrchestrator = (VehicularEdgeOrchestrator)SimManager.getInstance().getEdgeOrchestrator(); + + //create a task + Task task = createTask(edgeTask); + + Location currentLocation = SimManager.getInstance().getMobilityModel(). + getLocation(task.getMobileDeviceId(),CloudSim.clock()); + + //set location of the mobile device which generates this task + task.setSubmittedLocation(currentLocation); + + //add related task to log list + SimLogger.getInstance().addLog(task.getMobileDeviceId(), + task.getCloudletId(), + task.getTaskType(), + (int)task.getCloudletLength(), + (int)task.getCloudletFileSize(), + (int)task.getCloudletOutputSize()); + + long startTime = System.nanoTime(); + int nextHopId = SimManager.getInstance().getEdgeOrchestrator().getDeviceToOffload(task); + long estimatedTime = System.nanoTime() - startTime; + + SimLogger.getInstance().setOrchestratorOverhead(task.getCloudletId(), estimatedTime); + + double delay = 0; + VM_TYPES vmType = null; + NETWORK_DELAY_TYPES delayType = null; + + if(nextHopId == VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_GSM){ + vmType = VM_TYPES.CLOUD_VM; + delayType = NETWORK_DELAY_TYPES.GSM_DELAY; + delay = networkModel.getUploadDelay(delayType, task); + } + //task is sent to cloud over RSU via 2 hops + else if(nextHopId == VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_RSU){ + vmType = VM_TYPES.CLOUD_VM; + delayType = NETWORK_DELAY_TYPES.WLAN_DELAY; + delay = networkModel.getUploadDelay(delayType, task); + } + //task is sent to best edge device via 2 hops (unless the best edge is the nearest one) + else if(nextHopId == VehicularEdgeOrchestrator.EDGE_DATACENTER){ + vmType = VM_TYPES.EDGE_VM; + delayType = NETWORK_DELAY_TYPES.WLAN_DELAY; + delay = networkModel.getUploadDelay(delayType, task); + } + else { + SimLogger.printLine("Unknown nextHopId! Terminating simulation..."); + System.exit(1); + } + + task.setAssociatedDatacenterId(nextHopId); + + if(delay>0){ + //set related host id + schedule(getId(), delay, READY_TO_SELECT_VM, task); + + SimLogger.getInstance().taskStarted(task.getCloudletId(), CloudSim.clock()); + SimLogger.getInstance().setUploadDelay(task.getCloudletId(), delay, delayType); + } + else + { + //SimLogger.printLine("Task #" + task.getCloudletId() + " cannot assign to any VM"); + SimLogger.getInstance().rejectedDueToBandwidth(task.getCloudletId(), CloudSim.clock(), vmType.ordinal(), delayType); + + edgeOrchestrator.taskFailed(task); + } + } + + private void submitTaskToVm(Task task, SimSettings.VM_TYPES vmType) { + VehicularEdgeOrchestrator edgeOrchestrator = (VehicularEdgeOrchestrator)SimManager.getInstance().getEdgeOrchestrator(); + + Vm targetVM = null; + if(vmType == VM_TYPES.EDGE_VM) { + int numberOfHost = SimSettings.getInstance().getNumOfEdgeHosts(); + for (int hostIndex = 0; hostIndex < numberOfHost; hostIndex++) { + List vmArray = SimManager.getInstance().getEdgeServerManager().getVmList(hostIndex); + for (int vmIndex = 0; vmIndex < vmArray.size(); vmIndex++) { + if(vmArray.get(vmIndex).getId() == task.getAssociatedVmId()) { + targetVM = vmArray.get(vmIndex); + break; + } + } + if(targetVM != null) + break; + } + } + else if(vmType == VM_TYPES.CLOUD_VM) { + List list = SimManager.getInstance().getCloudServerManager().getDatacenter().getHostList(); + for (int hostIndex = 0; hostIndex < list.size(); hostIndex++) { + List vmArray = SimManager.getInstance().getCloudServerManager().getVmList(hostIndex); + for (int vmIndex = 0; vmIndex < vmArray.size(); vmIndex++) { + if(vmArray.get(vmIndex).getId() == task.getAssociatedVmId()) { + targetVM = vmArray.get(vmIndex); + break; + } + } + if(targetVM != null) + break; + } + } + else { + SimLogger.printLine("Unknown vm type! Terminating simulation..."); + System.exit(1); + } + + double targetVmCapacity = (double) 100 - targetVM.getCloudletScheduler().getTotalUtilizationOfCpu(CloudSim.clock()); + + double requiredCapacity = ((VehicularCpuUtilizationModel) task.getUtilizationModelCpu()).predictUtilization(vmType); + + if (requiredCapacity > targetVmCapacity) { + SimLogger.getInstance().rejectedDueToVMCapacity(task.getCloudletId(), CloudSim.clock(), vmType.ordinal()); + edgeOrchestrator.taskFailed(task); + } else { + // SimLogger.printLine(CloudSim.clock() + ": Cloudlet#" + task.getCloudletId() + + // " is submitted to VM#" + task.getVmId()); + schedule(getVmsToDatacentersMap().get(task.getVmId()), 0, CloudSimTags.CLOUDLET_SUBMIT, task); + + SimLogger.getInstance().taskAssigned(task.getCloudletId(), task.getAssociatedDatacenterId(), + task.getAssociatedHostId(), task.getAssociatedVmId(), vmType.ordinal()); + } + } + + private Task createTask(TaskProperty edgeTask){ + UtilizationModel utilizationModel = new UtilizationModelFull(); /*UtilizationModelStochastic*/ + UtilizationModel utilizationModelCPU = getCpuUtilizationModel(); + + Task task = new Task(edgeTask.getMobileDeviceId(), ++taskIdCounter, + edgeTask.getLength(), edgeTask.getPesNumber(), + edgeTask.getInputFileSize(), edgeTask.getOutputFileSize(), + utilizationModelCPU, utilizationModel, utilizationModel); + + //set the owner of this task + task.setUserId(this.getId()); + task.setTaskType(edgeTask.getTaskType()); + + if (utilizationModelCPU instanceof VehicularCpuUtilizationModel) { + ((VehicularCpuUtilizationModel)utilizationModelCPU).setTask(task); + } + + return task; + } +} diff --git a/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularMobileServerManager.java b/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularMobileServerManager.java new file mode 100644 index 0000000..4688a08 --- /dev/null +++ b/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularMobileServerManager.java @@ -0,0 +1,184 @@ +/* + * Title: EdgeCloudSim - Mobile Server Manager + * + * Description: + * VehicularDefaultMobileServerManager is responsible for creating + * mobile datacenters, hosts and VMs. + * + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * Copyright (c) 2017, Bogazici University, Istanbul, Turkey + */ + +package edu.boun.edgecloudsim.applications.sample_app5; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.cloudbus.cloudsim.CloudletSchedulerTimeShared; +import org.cloudbus.cloudsim.Datacenter; +import org.cloudbus.cloudsim.DatacenterCharacteristics; +import org.cloudbus.cloudsim.Host; +import org.cloudbus.cloudsim.Pe; +import org.cloudbus.cloudsim.Storage; +import org.cloudbus.cloudsim.VmAllocationPolicy; +import org.cloudbus.cloudsim.VmSchedulerSpaceShared; +import org.cloudbus.cloudsim.core.CloudSim; +import org.cloudbus.cloudsim.provisioners.BwProvisionerSimple; +import org.cloudbus.cloudsim.provisioners.PeProvisionerSimple; +import org.cloudbus.cloudsim.provisioners.RamProvisionerSimple; + +import edu.boun.edgecloudsim.core.SimManager; +import edu.boun.edgecloudsim.core.SimSettings; +import edu.boun.edgecloudsim.edge_client.mobile_processing_unit.MobileHost; +import edu.boun.edgecloudsim.edge_client.mobile_processing_unit.MobileServerManager; +import edu.boun.edgecloudsim.edge_client.mobile_processing_unit.MobileVM; +import edu.boun.edgecloudsim.edge_client.mobile_processing_unit.MobileVmAllocationPolicy_Custom; + +public class VehicularMobileServerManager extends MobileServerManager{ + private int numOfMobileDevices=0; + + public VehicularMobileServerManager(int _numOfMobileDevices) { + numOfMobileDevices=_numOfMobileDevices; + } + + @Override + public void initialize() { + } + + @Override + public VmAllocationPolicy getVmAllocationPolicy(List list, int dataCenterIndex) { + return new MobileVmAllocationPolicy_Custom(list, dataCenterIndex); + } + + @Override + public void startDatacenters() throws Exception { + //in the initial version, each mobile device has a separate datacenter + //however, this approach encounters with out of memory (oom) problem. + //therefore, we use single datacenter for all mobile devices! + localDatacenter = createDatacenter(SimSettings.MOBILE_DATACENTER_ID); + } + + @Override + public void terminateDatacenters() { + localDatacenter.shutdownEntity(); + } + + @Override + public void createVmList(int brockerId) { + //VMs should have unique IDs, so create Mobile VMs after Edge+Cloud VMs + int vmCounter=SimSettings.getInstance().getNumOfEdgeVMs() + SimSettings.getInstance().getNumOfCloudVMs(); + + //Create VMs for each hosts + //Note that each mobile device has one host with one VM! + for (int i = 0; i < numOfMobileDevices; i++) { + vmList.add(i, new ArrayList()); + + String vmm = "Xen"; + int numOfCores = SimSettings.getInstance().getCoreForMobileVM(); + double mips = SimSettings.getInstance().getMipsForMobileVM(); + int ram = SimSettings.getInstance().getRamForMobileVM(); + long storage = SimSettings.getInstance().getStorageForMobileVM(); + long bandwidth = 0; + + //VM Parameters + MobileVM vm = new MobileVM(vmCounter, brockerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); + vmList.get(i).add(vm); + vmCounter++; + } + } + + @Override + public double getAvgUtilization() { + double totalUtilization = 0; + double vmCounter = 0; + + List list = localDatacenter.getHostList(); + // for each host... + for (int hostIndex=0; hostIndex < list.size(); hostIndex++) { + List vmArray = SimManager.getInstance().getMobileServerManager().getVmList(hostIndex); + //for each vm... + for(int vmIndex=0; vmIndex hostList=createHosts(); + + String name = "MobileDatacenter_" + Integer.toString(index); + double time_zone = 3.0; // time zone this resource located + LinkedList storageList = new LinkedList(); //we are not adding SAN devices by now + + // 5. Create a DatacenterCharacteristics object that stores the + // properties of a data center: architecture, OS, list of + // Machines, allocation policy: time- or space-shared, time zone + // and its price (G$/Pe time unit). + DatacenterCharacteristics characteristics = new DatacenterCharacteristics( + arch, os, vmm, hostList, time_zone, costPerSec, costPerMem, costPerStorage, costPerBw); + + // 6. Finally, we need to create a PowerDatacenter object. + Datacenter datacenter = null; + + VmAllocationPolicy vm_policy = getVmAllocationPolicy(hostList,index); + datacenter = new Datacenter(name, characteristics, vm_policy, storageList, 0); + + return datacenter; + } + + private List createHosts(){ + // Here are the steps needed to create a PowerDatacenter: + // 1. We need to create a list to store one or more Machines + List hostList = new ArrayList(); + + for (int i = 0; i < numOfMobileDevices; i++) { + + int numOfCores = SimSettings.getInstance().getCoreForMobileVM(); + double mips = SimSettings.getInstance().getMipsForMobileVM(); + int ram = SimSettings.getInstance().getRamForMobileVM(); + long storage = SimSettings.getInstance().getStorageForMobileVM(); + long bandwidth = 0; + + // 2. A Machine contains one or more PEs or CPUs/Cores. Therefore, should + // create a list to store these PEs before creating + // a Machine. + List peList = new ArrayList(); + + // 3. Create PEs and add these into the list. + //for a quad-core machine, a list of 4 PEs is required: + for(int j=0; j timeToDriveLocationArray[locationIndex]) { + remainingTime -= timeToDriveLocationArray[locationIndex]; + locationIndex = (locationIndex+1) % locationTypes.length; + } + + ofset = locationIndex * lengthOfSegment; + } + + int x_pos = (int) (ofset + ( (SPEED_FOR_PLACES[locationTypes[locationIndex]] * remainingTime) / (double)3.6)); + + return new Location(locationTypes[locationIndex], locationIndex, x_pos, 0); + } + +} diff --git a/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularNetworkModel.java b/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularNetworkModel.java new file mode 100644 index 0000000..8f36d15 --- /dev/null +++ b/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularNetworkModel.java @@ -0,0 +1,487 @@ +/* + * Title: EdgeCloudSim - Network model implementation + * + * Description: + * VehicularNetworkModel implements MMPP/M/1 queue model for + * WLAN, MAN, WAN and GSM based communication + * + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * Copyright (c) 2017, Bogazici University, Istanbul, Turkey + */ + +package edu.boun.edgecloudsim.applications.sample_app5; + +import org.cloudbus.cloudsim.core.CloudSim; + +import edu.boun.edgecloudsim.core.SimSettings; +import edu.boun.edgecloudsim.core.SimSettings.NETWORK_DELAY_TYPES; +import edu.boun.edgecloudsim.edge_client.Task; +import edu.boun.edgecloudsim.network.NetworkModel; +import edu.boun.edgecloudsim.utils.Location; +import edu.boun.edgecloudsim.utils.SimLogger; + +public class VehicularNetworkModel extends NetworkModel { + public static double maxWlanDelay = 0; + public static double maxWanDelay = 0; + public static double maxGsmDelay = 0; + + private class MMPPWrapper { + private double currentPoissonMean; + private double currentTaskSize; + + //record last values used for successful packet transmission + private double lastPoissonMean; + private double lastTaskSize; + + //record last n task statistics during MM1_QUEUE_MODEL_UPDATE_INTEVAL seconds to simulate mmpp/m/1 queue model + private double numOfTasks; + private double totalTaskSize; + + public MMPPWrapper() { + currentPoissonMean = 0; + currentTaskSize = 0; + + lastPoissonMean = 0; + lastTaskSize = 0; + + numOfTasks = 0; + totalTaskSize = 0; + } + + public double getPoissonMean() { + return currentPoissonMean; + } + + public double getTaskSize() { + return currentTaskSize; + } + + public void increaseMM1StatValues(double taskSize) { + numOfTasks++; + totalTaskSize += taskSize; + } + + public void initializeMM1QueueValues(double poissonMean, double taskSize, double bandwidth) { + currentPoissonMean = poissonMean; + currentTaskSize = taskSize; + + lastPoissonMean = poissonMean; + lastTaskSize = taskSize; + + double avgTaskSize = taskSize * 8; //convert from KB to Kb + double lamda = ((double)1/(double)poissonMean); //task per seconds + double mu = bandwidth /*Kbps*/ / avgTaskSize /*Kb*/; //task per seconds + + if(mu <= lamda) { + SimLogger.printLine("Error in initializeMM1QueueValues function:" + + "MU is smallar than LAMDA! Check your simulation settings."); + System.exit(1); + } + } + + public void updateLastSuccessfulMM1QueueValues() { + lastPoissonMean = currentPoissonMean; + lastTaskSize = currentTaskSize; + } + + public void updateMM1Values(double interval, double optionalBackgroundDataCount, double optionalBackgroundDataSize) { + if(numOfTasks == 0) { + currentPoissonMean = lastPoissonMean; + currentTaskSize = lastTaskSize; + } + else { + double poissonMean = interval / (numOfTasks + optionalBackgroundDataCount); + double taskSize = (totalTaskSize + optionalBackgroundDataSize) / (numOfTasks + optionalBackgroundDataCount); + + if(CloudSim.clock() > SimSettings.getInstance().getWarmUpPeriod() && poissonMean > currentPoissonMean) + poissonMean = (poissonMean + currentPoissonMean * 3) / 4; + + currentPoissonMean = poissonMean; + currentTaskSize = taskSize; + } + + numOfTasks = 0; + totalTaskSize = 0; + } + } + + private static double MAN_CONTROL_MESSAGE_PER_SECONDS = 10; + private static double MAN_CONTROL_MESSAGE_SIZE = 25; //100 KB + + private double lastMM1QueeuUpdateTime; + + private MMPPWrapper[] wlanMMPPForDownload; + private MMPPWrapper[] wlanMMPPForUpload; + + private MMPPWrapper manMMPPForDownload; + private MMPPWrapper manMMPPForUpload; + + private MMPPWrapper wanMMPPForDownload; + private MMPPWrapper wanMMPPForUpload; + + private MMPPWrapper gsmMMPPForDownload; + private MMPPWrapper gsmMMPPForUpload; + + public VehicularNetworkModel(int _numberOfMobileDevices, String _simScenario, String _orchestratorPolicy) { + super(_numberOfMobileDevices, _simScenario); + lastMM1QueeuUpdateTime = SimSettings.CLIENT_ACTIVITY_START_TIME; + } + + @Override + public void initialize() { + SimSettings SS = SimSettings.getInstance(); + + int numOfApp = SimSettings.getInstance().getTaskLookUpTable().length; + int numOfAccessPoint = SimSettings.getInstance().getNumOfEdgeDatacenters(); + + wlanMMPPForDownload = new MMPPWrapper[numOfAccessPoint]; + wlanMMPPForUpload = new MMPPWrapper[numOfAccessPoint]; + for(int apIndex=0; apIndex 100) { + SimLogger.printLine("Usage percantage of task " + taskIndex + " is invalid (" + + percentageOfAppUsage + ")! Terminating simulation..."); + System.exit(1); + } + + weightedTaskInputSize += taskInputSize * (percentageOfAppUsage / (double)100); + weightedTaskOutputSize += taskOutputSize * (percentageOfAppUsage / (double)100); + + weightedTaskPerSecond += ((double)1 / poissonOfApp) * (percentageOfAppUsage / (double)100); + } + + for(int apIndex=0; apIndex 7.5 || result < 0 ) ? 0 : result; + } + + private double getWlanDownloadDelay(double taskSize, int accessPointId, boolean justEstimate) { + double bw = SimSettings.getInstance().getWlanBandwidth(); + + double result = calculateMM1(taskSize, bw, wlanMMPPForDownload[accessPointId],justEstimate); + + if(maxWlanDelay < result) + maxWlanDelay = result; + + return result; + } + + private double getWlanUploadDelay(double taskSize, int accessPointId, boolean justEstimate) { + double bw = SimSettings.getInstance().getWlanBandwidth(); + + double result = calculateMM1(taskSize, bw, wlanMMPPForUpload[accessPointId], justEstimate); + + if(maxWlanDelay < result) + maxWlanDelay = result; + + return result; + } + + private double getManDownloadDelay(double taskSize, boolean justEstimate) { + double bw = SimSettings.getInstance().getManBandwidth(); + + double result = calculateMM1(taskSize, bw, manMMPPForDownload, justEstimate); + + return result; + } + + private double getManUploadDelay(double taskSize, boolean justEstimate) { + double bw = SimSettings.getInstance().getManBandwidth(); + + double result = calculateMM1(taskSize, bw, manMMPPForUpload, justEstimate); + + return result; + } + + private double getWanDownloadDelay(double taskSize, boolean justEstimate) { + double bw = SimSettings.getInstance().getWanBandwidth(); + + double result = calculateMM1(taskSize, bw, wanMMPPForDownload, justEstimate); + + if(maxWanDelay < result) + maxWanDelay = result; + + return result; + } + + private double getWanUploadDelay(double taskSize, boolean justEstimate) { + double bw = SimSettings.getInstance().getWanBandwidth(); + + double result = calculateMM1(taskSize, bw, wanMMPPForUpload, justEstimate); + + if(maxWanDelay < result) + maxWanDelay = result; + + return result; + } + + private double getGsmDownloadDelay(double taskSize, boolean justEstimate) { + double bw = SimSettings.getInstance().getGsmBandwidth(); + + double result = calculateMM1(taskSize, bw, gsmMMPPForDownload, justEstimate); + + if(maxGsmDelay < result) + maxGsmDelay = result; + + return result; + } + + private double getGsmUploadDelay(double taskSize, boolean justEstimate) { + double bw = SimSettings.getInstance().getGsmBandwidth(); + + double result = calculateMM1(taskSize, bw, gsmMMPPForUpload, justEstimate); + + if(maxGsmDelay < result) + maxGsmDelay = result; + + return result; + } + + public void updateMM1QueeuModel(){ + int numOfAccessPoint = SimSettings.getInstance().getNumOfEdgeDatacenters(); + + double lastInterval = CloudSim.clock() - lastMM1QueeuUpdateTime; + lastMM1QueeuUpdateTime = CloudSim.clock(); + + //GENERATE BACKGROUD TRAFFIC ON MAN RESOURCE + //assume that each edge server sends/receives control + //message to/from edge orchestrator periodically + double numOfControlMessagePerInterval = lastInterval * + (double)numberOfMobileDevices * MAN_CONTROL_MESSAGE_PER_SECONDS; + + double sizeOfControlMessages = (double)numberOfMobileDevices * MAN_CONTROL_MESSAGE_SIZE; + + //UPDATE MM1 QUEUE MODEL VARIABLES to simulate mmpp/m/1 queue model + //for wlan: + for(int i = 0; i< numOfAccessPoint; i++){ + wlanMMPPForDownload[i].updateMM1Values(lastInterval, 0, 0); + wlanMMPPForUpload[i].updateMM1Values(lastInterval, 0, 0); + + if(getWlanDownloadDelay(0, i, true) != 0) + wlanMMPPForDownload[i].updateLastSuccessfulMM1QueueValues(); + if(getWlanUploadDelay(0, i, true) != 0) + wlanMMPPForUpload[i].updateLastSuccessfulMM1QueueValues(); + } + + //for man: + manMMPPForDownload.updateMM1Values(lastInterval, numOfControlMessagePerInterval, sizeOfControlMessages); + manMMPPForUpload.updateMM1Values(lastInterval, numOfControlMessagePerInterval, sizeOfControlMessages); + if(getManDownloadDelay(0, true) != 0) + manMMPPForDownload.updateLastSuccessfulMM1QueueValues(); + if(getManUploadDelay(0, true) != 0) + manMMPPForUpload.updateLastSuccessfulMM1QueueValues(); + + //for wan: + wanMMPPForDownload.updateMM1Values(lastInterval, 0, 0); + wanMMPPForUpload.updateMM1Values(lastInterval, 0, 0); + if(getWanDownloadDelay(0, true) != 0) + wanMMPPForDownload.updateLastSuccessfulMM1QueueValues(); + if(getWanUploadDelay(0, true) != 0) + wanMMPPForUpload.updateLastSuccessfulMM1QueueValues(); + + //for gsm: + gsmMMPPForDownload.updateMM1Values(lastInterval, 0, 0); + gsmMMPPForUpload.updateMM1Values(lastInterval, 0, 0); + if(getGsmDownloadDelay(0, true) != 0) + gsmMMPPForDownload.updateLastSuccessfulMM1QueueValues(); + if(getGsmUploadDelay(0, true) != 0) + gsmMMPPForUpload.updateLastSuccessfulMM1QueueValues(); + + // for(int i = 0; i< numOfAccessPoint; i++){ + // SimLogger.printLine(CloudSim.clock() + ": MM1 Queue Model is updated"); + // SimLogger.printLine("WlanPoissonMeanForDownload[" + i + "] - avgWlanTaskOutputSize[" + i + "]: " + // + String.format("%.3f", wlanMMPPForDownload[i].getPoissonMean()) + " - " + // + String.format("%.3f", wlanMMPPForDownload[i].getTaskSize())); + // SimLogger.printLine("WlanPoissonMeanForUpload[" + i + "] - avgWlanTaskInputSize[" + i + "]: " + // + String.format("%.3f", wlanMMPPForUpload[i].getPoissonMean()) + " - " + // + String.format("%.3f", wlanMMPPForUpload[i].getTaskSize())); + // } + // SimLogger.printLine("ManPoissonMeanForDownload - avgManTaskOutputSize: " + // + String.format("%.3f", manMMPPForDownload.getPoissonMean()) + " - " + // + String.format("%.3f", manMMPPForDownload.getTaskSize())); + // SimLogger.printLine("ManPoissonMeanForUpload - avgManTaskInputSize: " + // + String.format("%.3f", manMMPPForUpload.getPoissonMean()) + " - " + // + String.format("%.3f", manMMPPForUpload.getTaskSize())); + // SimLogger.printLine("WanPoissonMeanForDownload - avgWanTaskOutputSize: " + // + String.format("%.3f", wanMMPPForDownload.getPoissonMean()) + " - " + // + String.format("%.3f", wanMMPPForDownload.getTaskSize())); + // SimLogger.printLine("WanPoissonMeanForUpload - avgWanTaskInputSize: " + // + String.format("%.3f", wanMMPPForUpload.getPoissonMean()) + " - " + // + String.format("%.3f", wanMMPPForUpload.getTaskSize())); + // SimLogger.printLine("GsmPoissonMeanForDownload - avgGsmTaskOutputSize: " + // + String.format("%.3f", gsmMMPPForDownload.getPoissonMean()) + " - " + // + String.format("%.3f", gsmMMPPForDownload.getTaskSize())); + // SimLogger.printLine("GsmPoissonMeanForUpload - avgGsmTaskInputSize: " + // + String.format("%.3f", gsmMMPPForUpload.getPoissonMean()) + " - " + // + String.format("%.3f", gsmMMPPForUpload.getTaskSize())); + // SimLogger.printLine("------------------------------------------------"); + + } +} diff --git a/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularScenarioFactory.java b/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularScenarioFactory.java new file mode 100644 index 0000000..2ad8393 --- /dev/null +++ b/src/edu/boun/edgecloudsim/applications/sample_app5/VehicularScenarioFactory.java @@ -0,0 +1,78 @@ +/* + * Title: EdgeCloudSim - Scenario Factory + * + * Description: VehicularScenarioFactory provides the default + * instances of required abstract classes + * + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * Copyright (c) 2017, Bogazici University, Istanbul, Turkey + */ + +package edu.boun.edgecloudsim.applications.sample_app5; + +import edu.boun.edgecloudsim.cloud_server.CloudServerManager; +import edu.boun.edgecloudsim.cloud_server.DefaultCloudServerManager; +import edu.boun.edgecloudsim.core.ScenarioFactory; +import edu.boun.edgecloudsim.edge_orchestrator.EdgeOrchestrator; +import edu.boun.edgecloudsim.edge_server.EdgeServerManager; +import edu.boun.edgecloudsim.edge_client.MobileDeviceManager; +import edu.boun.edgecloudsim.edge_client.mobile_processing_unit.MobileServerManager; +import edu.boun.edgecloudsim.mobility.MobilityModel; +import edu.boun.edgecloudsim.task_generator.LoadGeneratorModel; +import edu.boun.edgecloudsim.network.NetworkModel; + +public class VehicularScenarioFactory implements ScenarioFactory { + private int numOfMobileDevice; + private double simulationTime; + private String orchestratorPolicy; + private String simScenario; + + VehicularScenarioFactory(int _numOfMobileDevice, + double _simulationTime, + String _orchestratorPolicy, + String _simScenario){ + orchestratorPolicy = _orchestratorPolicy; + numOfMobileDevice = _numOfMobileDevice; + simulationTime = _simulationTime; + simScenario = _simScenario; + } + + @Override + public LoadGeneratorModel getLoadGeneratorModel() { + return new VehicularLoadGenerator(numOfMobileDevice, simulationTime, simScenario); + } + + @Override + public EdgeOrchestrator getEdgeOrchestrator() { + return new VehicularEdgeOrchestrator(numOfMobileDevice, orchestratorPolicy, simScenario); + } + + @Override + public MobilityModel getMobilityModel() { + return new VehicularMobilityModel(numOfMobileDevice,simulationTime); + } + + @Override + public NetworkModel getNetworkModel() { + return new VehicularNetworkModel(numOfMobileDevice, simScenario, orchestratorPolicy); + } + + @Override + public EdgeServerManager getEdgeServerManager() { + return new VehicularEdgeServerManager(); + } + @Override + public CloudServerManager getCloudServerManager() { + return new DefaultCloudServerManager(); + } + + @Override + public MobileDeviceManager getMobileDeviceManager() throws Exception { + return new VehicularMobileDeviceManager(); + } + + @Override + public MobileServerManager getMobileServerManager() { + return new VehicularMobileServerManager(numOfMobileDevice); + } +} diff --git a/src/edu/boun/edgecloudsim/applications/sample_app5/WekaWrapper.java b/src/edu/boun/edgecloudsim/applications/sample_app5/WekaWrapper.java new file mode 100644 index 0000000..9f749b5 --- /dev/null +++ b/src/edu/boun/edgecloudsim/applications/sample_app5/WekaWrapper.java @@ -0,0 +1,219 @@ +package edu.boun.edgecloudsim.applications.sample_app5; + +import java.util.ArrayList; + +import edu.boun.edgecloudsim.utils.SimLogger; +import weka.classifiers.AbstractClassifier; +import weka.classifiers.bayes.NaiveBayes; +import weka.classifiers.functions.LinearRegression; +import weka.classifiers.functions.MultilayerPerceptron; +import weka.classifiers.functions.SMO; +import weka.classifiers.functions.SMOreg; +import weka.core.Attribute; +import weka.core.DenseInstance; +import weka.core.Instance; +import weka.core.Instances; + +public class WekaWrapper { + public static final double MAX_WLAN_DELAY = 9; //sec + public static final double MAX_WAN_DELAY = 7; //sec + public static final double MAX_GSM_DELAY = 8; //sec + + private static final String[] EDGE_REGRESSION_ATTRIBUTES = {"TaskLength","AvgEdgeUtilization","ServiceTime"}; + private static final double[] EDGE_REGRESSION_MEAN_VALS = {5756, 18}; + private static final double[] EDGE_REGRESSION_STD_VALS = {4737, 7}; + + private static final String[] EDGE_CLASSIFIER_ATTRIBUTES = {"NumOffloadedTask","TaskLength","WLANUploadDelay","WLANDownloadDelay","AvgEdgeUtilization"}; + private static final double[] EDGE_CLASSIFIER_MEAN_VALS = {130, 5756, 0.024192, 0.022952, 18}; + private static final double[] EDGE_CLASSIFIER_STD_VALS = {47, 4737, 0.025628, 0.010798, 7}; + + + private static final String[] CLOUD_RSU_REGRESSION_ATTRIBUTES = {"TaskLength","WANUploadDelay","WANDownloadDelay","ServiceTime"}; + private static final double[] CLOUD_RSU_REGRESSION_MEAN_VALS = {9718, 0.171074, 0.164998}; + private static final double[] CLOUD_RSU_REGRESSION_STD_VALS = {5873, 0.096208, 0.068551}; + + private static final String[] CLOUD_RSU_CLASSIFIER_ATTRIBUTES = {"NumOffloadedTask","WANUploadDelay","WANDownloadDelay"}; + private static final double[] CLOUD_RSU_CLASSIFIER_MEAN_VALS = {111, 0.171074, 0.164998}; + private static final double[] CLOUD_RSU_CLASSIFIER_STD_VALS = {40, 0.096208, 0.068551}; + + + private static final String[] CLOUD_GSM_REGRESSION_ATTRIBUTES = {"TaskLength","GSMUploadDelay","GSMDownloadDelay","ServiceTime"}; + private static final double[] CLOUD_GSM_REGRESSION_MEAN_VALS = {9718, 0.205794, 0.197476}; + private static final double[] CLOUD_GSM_REGRESSION_STD_VALS = {5873, 0.179551, 0.148067}; + + private static final String[] CLOUD_GSM_CLASSIFIER_ATTRIBUTES = {"NumOffloadedTask","GSMUploadDelay","GSMDownloadDelay"}; + private static final double[] CLOUD_GSM_CLASSIFIER_MEAN_VALS = {50, 0.205794, 0.197476}; + private static final double[] CLOUD_GSM_CLASSIFIER_STD_VALS = {18, 0.179551, 0.148067}; + + private static final String[] CLASSIFIER_CLASSES = {"fail","success"}; + + private AbstractClassifier classifier_edge, classifier_cloud_rsu, classifier_cloud_gsm; + private AbstractClassifier regression_edge, regression_cloud_rsu, regression_cloud_gsm; + + private static WekaWrapper singleton = new WekaWrapper(); + + /* + * A private Constructor prevents any other class from instantiating. + */ + private WekaWrapper() { + + } + + /* Static 'instance' method */ + public static WekaWrapper getInstance() { + return singleton; + } + + /* + * Possible Values for ClassifierType: + * - NaiveBayes + * - SMO + * - LibSVM + * - MultilayerPerceptron + * + * Possible Values for RegressionType: + * - LinearRegression + * - SMOreg + */ + public void initialize(String ClassifierType, String RegressionType, String ModelFolder) { + try { + if(ClassifierType.equals("NaiveBayes")) { + classifier_edge = (NaiveBayes) weka.core.SerializationHelper.read(ModelFolder + "nb_edge.model"); + classifier_cloud_rsu = (NaiveBayes) weka.core.SerializationHelper.read(ModelFolder + "nb_cloud_rsu.model"); + classifier_cloud_gsm = (NaiveBayes) weka.core.SerializationHelper.read(ModelFolder + "nb_cloud_gsm.model"); + } + else if(ClassifierType.equals("SMO")){ + classifier_edge = (SMO) weka.core.SerializationHelper.read(ModelFolder + "smo_edge.model"); + classifier_cloud_rsu = (SMO) weka.core.SerializationHelper.read(ModelFolder + "smo_cloud_rsu.model"); + classifier_cloud_gsm = (SMO) weka.core.SerializationHelper.read(ModelFolder + "smo_cloud_gsm.model"); + } + else if(ClassifierType.equals("MultilayerPerceptron")){ + classifier_edge = (MultilayerPerceptron) weka.core.SerializationHelper.read(ModelFolder + "mlp_edge.model"); + classifier_cloud_rsu = (MultilayerPerceptron) weka.core.SerializationHelper.read(ModelFolder + "mlp_cloud_rsu.model"); + classifier_cloud_gsm = (MultilayerPerceptron) weka.core.SerializationHelper.read(ModelFolder + "mlp_cloud_gsm.model"); + } + + if(RegressionType.equals("LinearRegression")){ + regression_edge = (LinearRegression) weka.core.SerializationHelper.read(ModelFolder + "lr_edge.model"); + regression_cloud_rsu = (LinearRegression) weka.core.SerializationHelper.read(ModelFolder + "lr_cloud_rsu.model"); + regression_cloud_gsm = (LinearRegression) weka.core.SerializationHelper.read(ModelFolder + "lr_cloud_gsm.model"); + } + else if(RegressionType.equals("SMOreg")){ + regression_edge = (SMOreg) weka.core.SerializationHelper.read(ModelFolder + "smoreg_edge.model"); + regression_cloud_rsu = (SMOreg) weka.core.SerializationHelper.read(ModelFolder + "smoreg_cloud_rsu.model"); + regression_cloud_gsm = (SMOreg) weka.core.SerializationHelper.read(ModelFolder + "smoreg_cloud_gsm.model"); + } + } + catch (Exception e) { + SimLogger.printLine("cannot serialize weka objects!"); + System.exit(1); + } + } + + public double handleRegression(int targetDatacenter, double[] values) { + double result = 0; + + try { + if(targetDatacenter == VehicularEdgeOrchestrator.EDGE_DATACENTER) { + Instance data = getRegressionData("edge", values, + EDGE_REGRESSION_ATTRIBUTES, + EDGE_REGRESSION_MEAN_VALS, + EDGE_REGRESSION_STD_VALS); + result = regression_edge.classifyInstance(data); + } + else if(targetDatacenter == VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_RSU) { + Instance data = getRegressionData("cloud_rsu", values, + CLOUD_RSU_REGRESSION_ATTRIBUTES, + CLOUD_RSU_REGRESSION_MEAN_VALS, + CLOUD_RSU_REGRESSION_STD_VALS); + result = regression_cloud_rsu.classifyInstance(data); + } + else if(targetDatacenter == VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_GSM) { + Instance data = getRegressionData("cloud_gsm", values, + CLOUD_GSM_REGRESSION_ATTRIBUTES, + CLOUD_GSM_REGRESSION_MEAN_VALS, + CLOUD_GSM_REGRESSION_STD_VALS); + result = regression_cloud_gsm.classifyInstance(data); + } + } + catch (Exception e) { + SimLogger.printLine("cannot handle regression!"); + System.exit(1); + } + + return result; + } + + public boolean handleClassification(int targetDatacenter, double[] values) { + boolean result = false; + + try { + if(targetDatacenter == VehicularEdgeOrchestrator.EDGE_DATACENTER) { + Instance data = getClassificationData("edge", values, + EDGE_CLASSIFIER_ATTRIBUTES, + EDGE_CLASSIFIER_MEAN_VALS, + EDGE_CLASSIFIER_STD_VALS); + result = (classifier_edge.classifyInstance(data) == 1) ? true : false; + } + else if(targetDatacenter == VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_RSU) { + Instance data = getClassificationData("cloud_rsu", values, + CLOUD_RSU_CLASSIFIER_ATTRIBUTES, + CLOUD_RSU_CLASSIFIER_MEAN_VALS, + CLOUD_RSU_CLASSIFIER_STD_VALS); + result = (classifier_cloud_rsu.classifyInstance(data) == 1) ? true : false; + } + else if(targetDatacenter == VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_GSM) { + Instance data = getClassificationData("cloud_gsm", values, + CLOUD_GSM_CLASSIFIER_ATTRIBUTES, + CLOUD_GSM_CLASSIFIER_MEAN_VALS, + CLOUD_GSM_CLASSIFIER_STD_VALS); + result = (classifier_cloud_gsm.classifyInstance(data) == 1) ? true : false; + } + } + catch (Exception e) { + SimLogger.printLine("cannot handle classification!"); + System.exit(1); + } + + return result; + } + + private Instance getRegressionData(String relation, double[] values, String[] attributes, double[] meanVals, double[] stdVals) { + ArrayList atts = new ArrayList(); + for(int i=0; i atts = new ArrayList(); + ArrayList classVal = new ArrayList(); + for(int i=0; i mipsShareAllocated = new ArrayList(); for(int i= 0; i()); for(int j = 0; j < SimSettings.getInstance().getNumOfCloudVMsPerHost(); j++){ String vmm = "Xen"; @@ -69,7 +69,7 @@ public class DefaultCloudServerManager extends CloudServerManager{ long bandwidth = 0; //VM Parameters - CloudVM vm = new CloudVM(vmCounter, brockerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); + CloudVM vm = new CloudVM(vmCounter, brokerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); vmList.get(i).add(vm); vmCounter++; } @@ -131,7 +131,7 @@ public class DefaultCloudServerManager extends CloudServerManager{ // 1. We need to create a list to store one or more Machines List hostList = new ArrayList(); - for (int i = 0; i < SimSettings.getInstance().getNumOfCoudHost(); i++) { + for (int i = 0; i < SimSettings.getInstance().getNumOfCloudHost(); i++) { int numOfVMPerHost = SimSettings.getInstance().getNumOfCloudVMsPerHost(); int numOfCores = SimSettings.getInstance().getCoreForCloudVM() * numOfVMPerHost; double mips = SimSettings.getInstance().getMipsForCloudVM() * numOfVMPerHost; diff --git a/src/edu/boun/edgecloudsim/core/SimManager.java b/src/edu/boun/edgecloudsim/core/SimManager.java index 1f0fa3b..750df1f 100644 --- a/src/edu/boun/edgecloudsim/core/SimManager.java +++ b/src/edu/boun/edgecloudsim/core/SimManager.java @@ -16,7 +16,6 @@ import java.io.IOException; import java.util.List; import org.cloudbus.cloudsim.Host; -import org.cloudbus.cloudsim.Log; import org.cloudbus.cloudsim.core.CloudSim; import org.cloudbus.cloudsim.core.SimEntity; import org.cloudbus.cloudsim.core.SimEvent; @@ -185,7 +184,7 @@ public class SimManager extends SimEntity { } } - for(int i= 0; i= 0 && index < taskLookUpTable.length) + result = taskLookUpTable[index]; + + return result; + } + public String getTaskName(int taskType) { return taskNames[taskType]; } - - private void isAttribtuePresent(Element element, String key) { - String value = element.getAttribute(key); - if (value.isEmpty() || value == null){ - throw new IllegalArgumentException("Attribure '" + key + "' is not found in '" + element.getNodeName() +"'"); - } + + private void isAttributePresent(Element element, String key) { + String value = element.getAttribute(key); + if (value.isEmpty() || value == null){ + throw new IllegalArgumentException("Attribute '" + key + "' is not found in '" + element.getNodeName() +"'"); + } } private void isElementPresent(Element element, String key) { try { String value = element.getElementsByTagName(key).item(0).getTextContent(); - if (value.isEmpty() || value == null){ - throw new IllegalArgumentException("Element '" + key + "' is not found in '" + element.getNodeName() +"'"); - } + if (value.isEmpty() || value == null){ + throw new IllegalArgumentException("Element '" + key + "' is not found in '" + element.getNodeName() +"'"); + } } catch (Exception e) { throw new IllegalArgumentException("Element '" + key + "' is not found in '" + element.getNodeName() +"'"); } } - - private void parseApplicatinosXML(String filePath) + + private Boolean checkElement(Element element, String key) { + Boolean result = true; + try { + String value = element.getElementsByTagName(key).item(0).getTextContent(); + if (value.isEmpty() || value == null){ + result = false; + } + } catch (Exception e) { + result = false; + } + + return result; + } + + private void parseApplicationsXML(String filePath) { Document doc = null; try { @@ -519,64 +617,55 @@ public class SimSettings { doc = dBuilder.parse(devicesFile); doc.getDocumentElement().normalize(); + String mandatoryAttributes[] = { + "usage_percentage", //usage percentage [0-100] + "prob_cloud_selection", //prob. of selecting cloud [0-100] + "poisson_interarrival", //poisson mean (sec) + "active_period", //active period (sec) + "idle_period", //idle period (sec) + "data_upload", //avg data upload (KB) + "data_download", //avg data download (KB) + "task_length", //avg task length (MI) + "required_core", //required # of core + "vm_utilization_on_edge", //vm utilization on edge vm [0-100] + "vm_utilization_on_cloud", //vm utilization on cloud vm [0-100] + "vm_utilization_on_mobile", //vm utilization on mobile vm [0-100] + "delay_sensitivity"}; //delay_sensitivity [0-1] + + String optionalAttributes[] = { + "max_delay_requirement"}; //maximum delay requirement (sec) + NodeList appList = doc.getElementsByTagName("application"); - taskLookUpTable = new double[appList.getLength()][13]; + taskLookUpTable = new double[appList.getLength()] + [mandatoryAttributes.length + optionalAttributes.length]; + taskNames = new String[appList.getLength()]; for (int i = 0; i < appList.getLength(); i++) { Node appNode = appList.item(i); - - Element appElement = (Element) appNode; - isAttribtuePresent(appElement, "name"); - isElementPresent(appElement, "usage_percentage"); - isElementPresent(appElement, "prob_cloud_selection"); - isElementPresent(appElement, "poisson_interarrival"); - isElementPresent(appElement, "active_period"); - isElementPresent(appElement, "idle_period"); - isElementPresent(appElement, "data_upload"); - isElementPresent(appElement, "data_download"); - isElementPresent(appElement, "task_length"); - isElementPresent(appElement, "required_core"); - isElementPresent(appElement, "vm_utilization_on_edge"); - isElementPresent(appElement, "vm_utilization_on_cloud"); - isElementPresent(appElement, "vm_utilization_on_mobile"); - isElementPresent(appElement, "delay_sensitivity"); + Element appElement = (Element) appNode; + isAttributePresent(appElement, "name"); String taskName = appElement.getAttribute("name"); taskNames[i] = taskName; - - double usage_percentage = Double.parseDouble(appElement.getElementsByTagName("usage_percentage").item(0).getTextContent()); - double prob_cloud_selection = Double.parseDouble(appElement.getElementsByTagName("prob_cloud_selection").item(0).getTextContent()); - double poisson_interarrival = Double.parseDouble(appElement.getElementsByTagName("poisson_interarrival").item(0).getTextContent()); - double active_period = Double.parseDouble(appElement.getElementsByTagName("active_period").item(0).getTextContent()); - double idle_period = Double.parseDouble(appElement.getElementsByTagName("idle_period").item(0).getTextContent()); - double data_upload = Double.parseDouble(appElement.getElementsByTagName("data_upload").item(0).getTextContent()); - double data_download = Double.parseDouble(appElement.getElementsByTagName("data_download").item(0).getTextContent()); - double task_length = Double.parseDouble(appElement.getElementsByTagName("task_length").item(0).getTextContent()); - double required_core = Double.parseDouble(appElement.getElementsByTagName("required_core").item(0).getTextContent()); - double vm_utilization_on_edge = Double.parseDouble(appElement.getElementsByTagName("vm_utilization_on_edge").item(0).getTextContent()); - double vm_utilization_on_cloud = Double.parseDouble(appElement.getElementsByTagName("vm_utilization_on_cloud").item(0).getTextContent()); - double vm_utilization_on_mobile = Double.parseDouble(appElement.getElementsByTagName("vm_utilization_on_mobile").item(0).getTextContent()); - double delay_sensitivity = Double.parseDouble(appElement.getElementsByTagName("delay_sensitivity").item(0).getTextContent()); - - taskLookUpTable[i][0] = usage_percentage; //usage percentage [0-100] - taskLookUpTable[i][1] = prob_cloud_selection; //prob. of selecting cloud [0-100] - taskLookUpTable[i][2] = poisson_interarrival; //poisson mean (sec) - taskLookUpTable[i][3] = active_period; //active period (sec) - taskLookUpTable[i][4] = idle_period; //idle period (sec) - taskLookUpTable[i][5] = data_upload; //avg data upload (KB) - taskLookUpTable[i][6] = data_download; //avg data download (KB) - taskLookUpTable[i][7] = task_length; //avg task length (MI) - taskLookUpTable[i][8] = required_core; //required # of core - taskLookUpTable[i][9] = vm_utilization_on_edge; //vm utilization on edge vm [0-100] - taskLookUpTable[i][10] = vm_utilization_on_cloud; //vm utilization on cloud vm [0-100] - taskLookUpTable[i][11] = vm_utilization_on_mobile; //vm utilization on mobile vm [0-100] - taskLookUpTable[i][12] = delay_sensitivity; //delay_sensitivity [0-1] + + for(int m=0; m 0){ networkModel.uploadStarted(currentLocation, nextHopId); - schedule(getId(), WlanDelay, REQUEST_RECIVED_BY_EDGE_DEVICE, task); + schedule(getId(), WlanDelay, REQUEST_RECEIVED_BY_EDGE_DEVICE, task); SimLogger.getInstance().taskStarted(task.getCloudletId(), CloudSim.clock()); SimLogger.getInstance().setUploadDelay(task.getCloudletId(), WlanDelay, NETWORK_DELAY_TYPES.WLAN_DELAY); } @@ -226,7 +227,7 @@ public class DefaultMobileDeviceManager extends MobileDeviceManager { } else { SimLogger.printLine("Unknown nextHopId! Terminating simulation..."); - System.exit(0); + System.exit(1); } } diff --git a/src/edu/boun/edgecloudsim/edge_client/Task.java b/src/edu/boun/edgecloudsim/edge_client/Task.java index 57ce7ee..7c95da0 100644 --- a/src/edu/boun/edgecloudsim/edge_client/Task.java +++ b/src/edu/boun/edgecloudsim/edge_client/Task.java @@ -13,11 +13,13 @@ package edu.boun.edgecloudsim.edge_client; import org.cloudbus.cloudsim.Cloudlet; import org.cloudbus.cloudsim.UtilizationModel; +import org.cloudbus.cloudsim.core.CloudSim; import edu.boun.edgecloudsim.utils.Location; public class Task extends Cloudlet { private Location submittedLocation; + private double creationTime; private int type; private int mobileDeviceId; private int hostIndex; @@ -34,6 +36,7 @@ public class Task extends Cloudlet { utilizationModelBw); mobileDeviceId = _mobileDeviceId; + creationTime = CloudSim.clock(); } @@ -80,4 +83,8 @@ public class Task extends Cloudlet { public int getTaskType(){ return type; } + + public double getCreationTime() { + return creationTime; + } } diff --git a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/DefaultMobileServerManager.java b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/DefaultMobileServerManager.java index d8109b6..14b834d 100644 --- a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/DefaultMobileServerManager.java +++ b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/DefaultMobileServerManager.java @@ -46,7 +46,7 @@ public class DefaultMobileServerManager extends MobileServerManager{ } @Override - public void createVmList(int brockerId) { + public void createVmList(int brokerId) { //local computation is not supported in default Mobile Device Manager } diff --git a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileHost.java b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileHost.java index 22f8df1..e5f6dc9 100644 --- a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileHost.java +++ b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileHost.java @@ -8,7 +8,7 @@ * CloudSim. It is assumed that the mobile devices operate Hosts * and VMs like a server. That is why the class names are similar * to other Cloud and Edge components (to provide consistency). - * + * * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * Copyright (c) 2017, Bogazici University, Istanbul, Turkey */ diff --git a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileServerManager.java b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileServerManager.java index b64ba18..c1d5ace 100644 --- a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileServerManager.java +++ b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileServerManager.java @@ -69,7 +69,7 @@ public abstract class MobileServerManager { /* * Creates VM List */ - public abstract void createVmList(int brockerId); + public abstract void createVmList(int brokerId); /* * returns average utilization of all VMs diff --git a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileVmAllocationPolicy_Custom.java b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileVmAllocationPolicy_Custom.java index 2aae6bb..b7f03b2 100644 --- a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileVmAllocationPolicy_Custom.java +++ b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileVmAllocationPolicy_Custom.java @@ -58,7 +58,7 @@ public class MobileVmAllocationPolicy_Custom extends VmAllocationPolicy { Host host = getHostList().get(hostIndex); result = host.vmCreate(vm); - if (result) { // if vm were succesfully created in the host + if (result) { // if vm were successfully created in the host getVmTable().put(vm.getUid(), host); createdVmNum++; Log.formatLine("%.2f: Mobile VM #" + vm.getId() + " has been allocated to the host #" + host.getId(),CloudSim.clock()); @@ -72,7 +72,7 @@ public class MobileVmAllocationPolicy_Custom extends VmAllocationPolicy { @Override public boolean allocateHostForVm(Vm vm, Host host) { - if (host.vmCreate(vm)) { // if vm has been succesfully created in the host + if (host.vmCreate(vm)) { // if vm has been successfully created in the host getVmTable().put(vm.getUid(), host); createdVmNum++; diff --git a/src/edu/boun/edgecloudsim/edge_orchestrator/EdgeOrchestrator.java b/src/edu/boun/edgecloudsim/edge_orchestrator/EdgeOrchestrator.java index 7b8e7d5..4dcc5a1 100644 --- a/src/edu/boun/edgecloudsim/edge_orchestrator/EdgeOrchestrator.java +++ b/src/edu/boun/edgecloudsim/edge_orchestrator/EdgeOrchestrator.java @@ -5,7 +5,7 @@ * EdgeOrchestrator is an abstract class which is used for selecting VM * for each client requests. For those who wants to add a custom * Edge Orchestrator to EdgeCloudSim should extend this class and provide - * a concreate instance via ScenarioFactory + * a concrete instance via ScenarioFactory * * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * Copyright (c) 2017, Bogazici University, Istanbul, Turkey @@ -27,7 +27,14 @@ public abstract class EdgeOrchestrator extends SimEntity{ policy = _policy; simScenario = _simScenario; } - + + /* + * Default Constructor: Creates an empty EdgeOrchestrator + */ + public EdgeOrchestrator() { + super("EdgeOrchestrator"); + } + /* * initialize edge orchestrator if needed */ diff --git a/src/edu/boun/edgecloudsim/edge_server/DefaultEdgeServerManager.java b/src/edu/boun/edgecloudsim/edge_server/DefaultEdgeServerManager.java index 7a6b9d0..29fec87 100644 --- a/src/edu/boun/edgecloudsim/edge_server/DefaultEdgeServerManager.java +++ b/src/edu/boun/edgecloudsim/edge_server/DefaultEdgeServerManager.java @@ -63,7 +63,7 @@ public class DefaultEdgeServerManager extends EdgeServerManager{ } } - public void createVmList(int brockerId){ + public void createVmList(int brokerId){ int hostCounter=0; int vmCounter=0; @@ -93,7 +93,7 @@ public class DefaultEdgeServerManager extends EdgeServerManager{ long bandwidth = SimSettings.getInstance().getWlanBandwidth() / (hostNodeList.getLength()+vmNodeList.getLength()); //VM Parameters - EdgeVM vm = new EdgeVM(vmCounter, brockerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); + EdgeVM vm = new EdgeVM(vmCounter, brokerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); vmList.get(hostCounter).add(vm); vmCounter++; } diff --git a/src/edu/boun/edgecloudsim/edge_server/EdgeServerManager.java b/src/edu/boun/edgecloudsim/edge_server/EdgeServerManager.java index 6e2938e..e43b49d 100644 --- a/src/edu/boun/edgecloudsim/edge_server/EdgeServerManager.java +++ b/src/edu/boun/edgecloudsim/edge_server/EdgeServerManager.java @@ -62,7 +62,7 @@ public abstract class EdgeServerManager { /* * Creates VM List */ - public abstract void createVmList(int brockerId); + public abstract void createVmList(int brokerId); /* * returns average utilization of all VMs diff --git a/src/edu/boun/edgecloudsim/edge_server/EdgeVM.java b/src/edu/boun/edgecloudsim/edge_server/EdgeVM.java index c5fa84a..2cb259a 100644 --- a/src/edu/boun/edgecloudsim/edge_server/EdgeVM.java +++ b/src/edu/boun/edgecloudsim/edge_server/EdgeVM.java @@ -10,6 +10,9 @@ package edu.boun.edgecloudsim.edge_server; +import java.util.ArrayList; +import java.util.List; + import org.cloudbus.cloudsim.CloudletScheduler; import org.cloudbus.cloudsim.Vm; @@ -28,4 +31,20 @@ public class EdgeVM extends Vm { public SimSettings.VM_TYPES getVmType(){ return type; } + + /** + * dynamically reconfigures the mips value of a VM in CloudSim + * + * @param mips new mips value for this VM. + */ + public void reconfigureMips(double mips){ + super.setMips(mips); + super.getHost().getVmScheduler().deallocatePesForVm(this); + + List mipsShareAllocated = new ArrayList(); + for(int i= 0; i e = treeMap.floorEntry(time); if(e == null){ - SimLogger.printLine("impossible is occured! no location is found for the device '" + deviceId + "' at " + time); - System.exit(0); + SimLogger.printLine("impossible is occurred! no location is found for the device '" + deviceId + "' at " + time); + System.exit(1); } return e.getValue(); diff --git a/src/edu/boun/edgecloudsim/network/MM1Queue.java b/src/edu/boun/edgecloudsim/network/MM1Queue.java index 5ab1fb0..81761c7 100644 --- a/src/edu/boun/edgecloudsim/network/MM1Queue.java +++ b/src/edu/boun/edgecloudsim/network/MM1Queue.java @@ -24,7 +24,7 @@ public class MM1Queue extends NetworkModel { private double avgTaskInputSize; //bytes private double avgTaskOutputSize; //bytes private int maxNumOfClientsInPlace; - + public MM1Queue(int _numberOfMobileDevices, String _simScenario) { super(_numberOfMobileDevices, _simScenario); } @@ -37,7 +37,7 @@ public class MM1Queue extends NetworkModel { avgTaskInputSize=0; avgTaskOutputSize=0; maxNumOfClientsInPlace=0; - + //Calculate interarrival time and task sizes double numOfTaskType = 0; SimSettings SS = SimSettings.getInstance(); @@ -45,26 +45,26 @@ public class MM1Queue extends NetworkModel { double weight = SS.getTaskLookUpTable()[i][0]/(double)100; if(weight != 0) { WlanPoissonMean += (SS.getTaskLookUpTable()[i][2])*weight; - + double percentageOfCloudCommunication = SS.getTaskLookUpTable()[i][1]; WanPoissonMean += (WlanPoissonMean)*((double)100/percentageOfCloudCommunication)*weight; - + avgTaskInputSize += SS.getTaskLookUpTable()[i][5]*weight; - + avgTaskOutputSize += SS.getTaskLookUpTable()[i][6]*weight; - + numOfTaskType++; } } - + WlanPoissonMean = WlanPoissonMean/numOfTaskType; avgTaskInputSize = avgTaskInputSize/numOfTaskType; avgTaskOutputSize = avgTaskOutputSize/numOfTaskType; } - /** - * source device is always mobile device in our simulation scenarios! - */ + /** + * source device is always mobile device in our simulation scenarios! + */ @Override public double getUploadDelay(int sourceDeviceId, int destDeviceId, Task task) { double delay = 0; @@ -86,13 +86,13 @@ public class MM1Queue extends NetworkModel { else if (destDeviceId == SimSettings.GENERIC_EDGE_DEVICE_ID) { delay = getWlanUploadDelay(accessPointLocation, CloudSim.clock()); } - + return delay; } - /** - * destination device is always mobile device in our simulation scenarios! - */ + /** + * destination device is always mobile device in our simulation scenarios! + */ @Override public double getDownloadDelay(int sourceDeviceId, int destDeviceId, Task task) { //Special Case -> edge orchestrator to edge device @@ -103,7 +103,7 @@ public class MM1Queue extends NetworkModel { double delay = 0; Location accessPointLocation = SimManager.getInstance().getMobilityModel().getLocation(destDeviceId,CloudSim.clock()); - + //cloud server to mobile device if(sourceDeviceId == SimSettings.CLOUD_DATACENTER_ID){ double wlanDelay = getWlanDownloadDelay(accessPointLocation, CloudSim.clock()); @@ -114,57 +114,57 @@ public class MM1Queue extends NetworkModel { //edge device (wifi access point) to mobile device else{ delay = getWlanDownloadDelay(accessPointLocation, CloudSim.clock()); - + EdgeHost host = (EdgeHost)(SimManager. getInstance(). getEdgeServerManager(). getDatacenterList().get(sourceDeviceId). getHostList().get(0)); - + //if source device id is the edge server which is located in another location, add internal lan delay - //in our scenasrio, serving wlan ID is equal to the host id, because there is only one host in one place + //in our scenario, serving wlan ID is equal to the host id, because there is only one host in one place if(host.getLocation().getServingWlanId() != accessPointLocation.getServingWlanId()) delay += (SimSettings.getInstance().getInternalLanDelay() * 2); } - + return delay; } - + public int getMaxNumOfClientsInPlace(){ return maxNumOfClientsInPlace; } - + private int getDeviceCount(Location deviceLocation, double time){ int deviceCount = 0; - + for(int i=0; i 5) ? -1 : result; } - + private double getWlanDownloadDelay(Location accessPointLocation, double time) { return calculateMM1(0, SimSettings.getInstance().getWlanBandwidth(), @@ -172,7 +172,7 @@ public class MM1Queue extends NetworkModel { avgTaskOutputSize, getDeviceCount(accessPointLocation, time)); } - + private double getWlanUploadDelay(Location accessPointLocation, double time) { return calculateMM1(0, SimSettings.getInstance().getWlanBandwidth(), @@ -180,17 +180,17 @@ public class MM1Queue extends NetworkModel { avgTaskInputSize, getDeviceCount(accessPointLocation, time)); } - + private double getWanDownloadDelay(Location accessPointLocation, double time) { - return calculateMM1(SimSettings.getInstance().getWanPropogationDelay(), + return calculateMM1(SimSettings.getInstance().getWanPropagationDelay(), SimSettings.getInstance().getWanBandwidth(), WanPoissonMean, avgTaskOutputSize, getDeviceCount(accessPointLocation, time)); } - + private double getWanUploadDelay(Location accessPointLocation, double time) { - return calculateMM1(SimSettings.getInstance().getWanPropogationDelay(), + return calculateMM1(SimSettings.getInstance().getWanPropagationDelay(), SimSettings.getInstance().getWanBandwidth(), WanPoissonMean, avgTaskInputSize, @@ -200,24 +200,24 @@ public class MM1Queue extends NetworkModel { @Override public void uploadStarted(Location accessPointLocation, int destDeviceId) { // TODO Auto-generated method stub - + } @Override public void uploadFinished(Location accessPointLocation, int destDeviceId) { // TODO Auto-generated method stub - + } @Override public void downloadStarted(Location accessPointLocation, int sourceDeviceId) { // TODO Auto-generated method stub - + } @Override public void downloadFinished(Location accessPointLocation, int sourceDeviceId) { // TODO Auto-generated method stub - + } } diff --git a/src/edu/boun/edgecloudsim/network/NetworkModel.java b/src/edu/boun/edgecloudsim/network/NetworkModel.java index 0937d53..6b56888 100644 --- a/src/edu/boun/edgecloudsim/network/NetworkModel.java +++ b/src/edu/boun/edgecloudsim/network/NetworkModel.java @@ -5,7 +5,7 @@ * NetworkModel is an abstract class which is used for calculating the * network delay from device to device. For those who wants to add a * custom Network Model to EdgeCloudSim should extend this class and - * provide a concreate instance via ScenarioFactory + * provide a concrete instance via ScenarioFactory * * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * Copyright (c) 2017, Bogazici University, Istanbul, Turkey @@ -24,26 +24,26 @@ public abstract class NetworkModel { numberOfMobileDevices=_numberOfMobileDevices; simScenario = _simScenario; }; - + /** - * initializes custom network model - */ + * initializes custom network model + */ public abstract void initialize(); - - /** - * calculates the upload delay from source to destination device - */ + + /** + * calculates the upload delay from source to destination device + */ public abstract double getUploadDelay(int sourceDeviceId, int destDeviceId, Task task); - - /** - * calculates the download delay from source to destination device - */ + + /** + * calculates the download delay from source to destination device + */ public abstract double getDownloadDelay(int sourceDeviceId, int destDeviceId, Task task); - - /** - * Mobile device manager should inform network manager about the network operation - * This information may be important for some network delay models - */ + + /** + * Mobile device manager should inform network manager about the network operation + * This information may be important for some network delay models + */ public abstract void uploadStarted(Location accessPointLocation, int destDeviceId); public abstract void uploadFinished(Location accessPointLocation, int destDeviceId); public abstract void downloadStarted(Location accessPointLocation, int sourceDeviceId); diff --git a/src/edu/boun/edgecloudsim/task_generator/IdleActiveLoadGenerator.java b/src/edu/boun/edgecloudsim/task_generator/IdleActiveLoadGenerator.java index 5a65ac8..4130a4b 100644 --- a/src/edu/boun/edgecloudsim/task_generator/IdleActiveLoadGenerator.java +++ b/src/edu/boun/edgecloudsim/task_generator/IdleActiveLoadGenerator.java @@ -59,7 +59,7 @@ public class IdleActiveLoadGenerator extends LoadGeneratorModel{ } } if(randomTaskType == -1){ - SimLogger.printLine("Impossible is occured! no random task type!"); + SimLogger.printLine("Impossible is occurred! no random task type!"); continue; } @@ -78,7 +78,7 @@ public class IdleActiveLoadGenerator extends LoadGeneratorModel{ double interval = rng.sample(); if(interval <= 0){ - SimLogger.printLine("Impossible is occured! interval is " + interval + " for device " + i + " time " + virtualTime); + SimLogger.printLine("Impossible is occurred! interval is " + interval + " for device " + i + " time " + virtualTime); continue; } //SimLogger.printLine(virtualTime + " -> " + interval + " for device " + i + " time "); diff --git a/src/edu/boun/edgecloudsim/task_generator/LoadGeneratorModel.java b/src/edu/boun/edgecloudsim/task_generator/LoadGeneratorModel.java index 72fd06a..feaaba8 100644 --- a/src/edu/boun/edgecloudsim/task_generator/LoadGeneratorModel.java +++ b/src/edu/boun/edgecloudsim/task_generator/LoadGeneratorModel.java @@ -5,7 +5,7 @@ * LoadGeneratorModel is an abstract class which is used for * deciding task generation pattern via a task list. For those who * wants to add a custom Load Generator Model to EdgeCloudSim should - * extend this class and provide a concreate instance via ScenarioFactory + * extend this class and provide a concrete instance via ScenarioFactory * * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * Copyright (c) 2017, Bogazici University, Istanbul, Turkey @@ -29,6 +29,12 @@ public abstract class LoadGeneratorModel { simScenario=_simScenario; }; + /* + * Default Constructor: Creates an empty LoadGeneratorModel + */ + public LoadGeneratorModel() { + } + /* * each task has a virtual start time * it will be used while generating task diff --git a/src/edu/boun/edgecloudsim/utils/Location.java b/src/edu/boun/edgecloudsim/utils/Location.java index 9c322cf..f25e3b7 100644 --- a/src/edu/boun/edgecloudsim/utils/Location.java +++ b/src/edu/boun/edgecloudsim/utils/Location.java @@ -21,6 +21,12 @@ public class Location { yPos = _yPos; } + /* + * Default Constructor: Creates an empty Location + */ + public Location() { + } + @Override public boolean equals(Object other){ boolean result = false; diff --git a/src/edu/boun/edgecloudsim/utils/PoissonDistr.java b/src/edu/boun/edgecloudsim/utils/PoissonDistr.java index 84b60a5..7821a54 100644 --- a/src/edu/boun/edgecloudsim/utils/PoissonDistr.java +++ b/src/edu/boun/edgecloudsim/utils/PoissonDistr.java @@ -20,31 +20,31 @@ public class PoissonDistr { Poisson poisson; RandomEngine engine; - /** - * Creates a new exponential number generator. - * - * @param mean the mean for the distribution. - */ - public PoissonDistr(double mean) { + /** + * Creates a new exponential number generator. + * + * @param mean the mean for the distribution. + */ + public PoissonDistr(double mean) { engine = new MersenneTwister(new Date()); poisson = new Poisson(mean, engine); - //always sleep for some milliseconds in order not to have same seed for iterative PoissonDistr contruction + //always sleep for some milliseconds in order not to have same seed for iterative PoissonDistr construction try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { - SimLogger.printLine("impossible is occured! Poisson random number cannot be created!"); + SimLogger.printLine("impossible is occurred! Poisson random number cannot be created!"); e.printStackTrace(); - System.exit(0); + System.exit(1); } - } + } - /** - * Generate a new random number. - * - * @return the next random number in the sequence - */ - public double sample() { - return poisson.nextDouble(); - } + /** + * Generate a new random number. + * + * @return the next random number in the sequence + */ + public double sample() { + return poisson.nextDouble(); + } } diff --git a/src/edu/boun/edgecloudsim/utils/SimLogger.java b/src/edu/boun/edgecloudsim/utils/SimLogger.java index 0478e2d..ff5d22a 100644 --- a/src/edu/boun/edgecloudsim/utils/SimLogger.java +++ b/src/edu/boun/edgecloudsim/utils/SimLogger.java @@ -8,6 +8,21 @@ * If you need more results or another file format, you should modify * this class. * + * IMPORTANT NOTES: + * EdgeCloudSim is designed to perform file logging operations with + * a low memory consumption. Deep file logging is performed whenever + * a task is completed. This may cause too many file IO operation and + * increase the time consumption! + * + * The basic results are kept in the memory, and saved to the files + * at the end of the simulation. So, basic file logging does + * bring too much overhead to the time complexity. + * + * In the earlier versions (v3 and older), EdgeCloudSim keeps all the + * task results in the memory and save them to the files when the + * simulation ends. Since this approach increases memory consumption + * too much, we sacrificed the time complexity. + * * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * Copyright (c) 2017, Bogazici University, Istanbul, Turkey */ @@ -31,21 +46,88 @@ import edu.boun.edgecloudsim.utils.SimLogger.NETWORK_ERRORS; public class SimLogger { public static enum TASK_STATUS { - CREATED, UPLOADING, PROCESSING, DOWNLOADING, COMLETED, REJECTED_DUE_TO_VM_CAPACITY, REJECTED_DUE_TO_BANDWIDTH, UNFINISHED_DUE_TO_BANDWIDTH, UNFINISHED_DUE_TO_MOBILITY + CREATED, UPLOADING, PROCESSING, DOWNLOADING, COMLETED, + REJECTED_DUE_TO_VM_CAPACITY, REJECTED_DUE_TO_BANDWIDTH, + UNFINISHED_DUE_TO_BANDWIDTH, UNFINISHED_DUE_TO_MOBILITY, + REJECTED_DUE_TO_WLAN_COVERAGE } public static enum NETWORK_ERRORS { - LAN_ERROR, MAN_ERROR, WAN_ERROR, NONE + LAN_ERROR, MAN_ERROR, WAN_ERROR, GSM_ERROR, NONE } + private long startTime; + private long endTime; private static boolean fileLogEnabled; private static boolean printLogEnabled; private String filePrefix; private String outputFolder; private Map taskMap; private LinkedList vmLoadList; + private LinkedList apDelayList; private static SimLogger singleton = new SimLogger(); + + private int numOfAppTypes; + + private File successFile = null, failFile = null; + private FileWriter successFW = null, failFW = null; + private BufferedWriter successBW = null, failBW = null; + + // extract following values for each app type. + // last index is average of all app types + private int[] uncompletedTask = null; + private int[] uncompletedTaskOnCloud = null; + private int[] uncompletedTaskOnEdge = null; + private int[] uncompletedTaskOnMobile = null; + + private int[] completedTask = null; + private int[] completedTaskOnCloud = null; + private int[] completedTaskOnEdge = null; + private int[] completedTaskOnMobile = null; + + private int[] failedTask = null; + private int[] failedTaskOnCloud = null; + private int[] failedTaskOnEdge = null; + private int[] failedTaskOnMobile = null; + + private double[] networkDelay = null; + private double[] gsmDelay = null; + private double[] wanDelay = null; + private double[] manDelay = null; + private double[] lanDelay = null; + + private double[] gsmUsage = null; + private double[] wanUsage = null; + private double[] manUsage = null; + private double[] lanUsage = null; + + private double[] serviceTime = null; + private double[] serviceTimeOnCloud = null; + private double[] serviceTimeOnEdge = null; + private double[] serviceTimeOnMobile = null; + + private double[] processingTime = null; + private double[] processingTimeOnCloud = null; + private double[] processingTimeOnEdge = null; + private double[] processingTimeOnMobile = null; + + private int[] failedTaskDueToVmCapacity = null; + private int[] failedTaskDueToVmCapacityOnCloud = null; + private int[] failedTaskDueToVmCapacityOnEdge = null; + private int[] failedTaskDueToVmCapacityOnMobile = null; + + private double[] cost = null; + private double[] QoE = null; + private int[] failedTaskDuetoBw = null; + private int[] failedTaskDuetoLanBw = null; + private int[] failedTaskDuetoManBw = null; + private int[] failedTaskDuetoWanBw = null; + private int[] failedTaskDuetoGsmBw = null; + private int[] failedTaskDuetoMobility = null; + private int[] refectedTaskDuetoWlanRange = null; + + private double[] orchestratorOverhead = null; /* * A private Constructor prevents any other class from instantiating. @@ -72,9 +154,17 @@ public class SimLogger { return fileLogEnabled; } + public static void disableFileLog() { + fileLogEnabled = false; + } + public static void disablePrintLog() { printLogEnabled = false; } + + public String getOutputFolder() { + return outputFolder; + } private void appendToFile(BufferedWriter bw, String line) throws IOException { bw.write(line); @@ -92,16 +182,93 @@ public class SimLogger { } public void simStarted(String outFolder, String fileName) { + startTime = System.currentTimeMillis(); filePrefix = fileName; outputFolder = outFolder; taskMap = new HashMap(); vmLoadList = new LinkedList(); + apDelayList = new LinkedList(); + + numOfAppTypes = SimSettings.getInstance().getTaskLookUpTable().length; + + if (SimSettings.getInstance().getDeepFileLoggingEnabled()) { + try { + successFile = new File(outputFolder, filePrefix + "_SUCCESS.log"); + successFW = new FileWriter(successFile, true); + successBW = new BufferedWriter(successFW); + + failFile = new File(outputFolder, filePrefix + "_FAIL.log"); + failFW = new FileWriter(failFile, true); + failBW = new BufferedWriter(failFW); + + appendToFile(successBW, "#auto generated file!"); + appendToFile(failBW, "#auto generated file!"); + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + } + + // extract following values for each app type. + // last index is average of all app types + uncompletedTask = new int[numOfAppTypes + 1]; + uncompletedTaskOnCloud = new int[numOfAppTypes + 1]; + uncompletedTaskOnEdge = new int[numOfAppTypes + 1]; + uncompletedTaskOnMobile = new int[numOfAppTypes + 1]; + + completedTask = new int[numOfAppTypes + 1]; + completedTaskOnCloud = new int[numOfAppTypes + 1]; + completedTaskOnEdge = new int[numOfAppTypes + 1]; + completedTaskOnMobile = new int[numOfAppTypes + 1]; + + failedTask = new int[numOfAppTypes + 1]; + failedTaskOnCloud = new int[numOfAppTypes + 1]; + failedTaskOnEdge = new int[numOfAppTypes + 1]; + failedTaskOnMobile = new int[numOfAppTypes + 1]; + + networkDelay = new double[numOfAppTypes + 1]; + gsmDelay = new double[numOfAppTypes + 1]; + wanDelay = new double[numOfAppTypes + 1]; + manDelay = new double[numOfAppTypes + 1]; + lanDelay = new double[numOfAppTypes + 1]; + + gsmUsage = new double[numOfAppTypes + 1]; + wanUsage = new double[numOfAppTypes + 1]; + manUsage = new double[numOfAppTypes + 1]; + lanUsage = new double[numOfAppTypes + 1]; + + serviceTime = new double[numOfAppTypes + 1]; + serviceTimeOnCloud = new double[numOfAppTypes + 1]; + serviceTimeOnEdge = new double[numOfAppTypes + 1]; + serviceTimeOnMobile = new double[numOfAppTypes + 1]; + + processingTime = new double[numOfAppTypes + 1]; + processingTimeOnCloud = new double[numOfAppTypes + 1]; + processingTimeOnEdge = new double[numOfAppTypes + 1]; + processingTimeOnMobile = new double[numOfAppTypes + 1]; + + failedTaskDueToVmCapacity = new int[numOfAppTypes + 1]; + failedTaskDueToVmCapacityOnCloud = new int[numOfAppTypes + 1]; + failedTaskDueToVmCapacityOnEdge = new int[numOfAppTypes + 1]; + failedTaskDueToVmCapacityOnMobile = new int[numOfAppTypes + 1]; + + cost = new double[numOfAppTypes + 1]; + QoE = new double[numOfAppTypes + 1]; + failedTaskDuetoBw = new int[numOfAppTypes + 1]; + failedTaskDuetoLanBw = new int[numOfAppTypes + 1]; + failedTaskDuetoManBw = new int[numOfAppTypes + 1]; + failedTaskDuetoWanBw = new int[numOfAppTypes + 1]; + failedTaskDuetoGsmBw = new int[numOfAppTypes + 1]; + failedTaskDuetoMobility = new int[numOfAppTypes + 1]; + refectedTaskDuetoWlanRange = new int[numOfAppTypes + 1]; + + orchestratorOverhead = new double[numOfAppTypes + 1]; } - public void addLog(int taskId, int taskType, int taskLenght, int taskInputType, - int taskOutputSize) { + public void addLog(int deviceId, int taskId, int taskType, + int taskLenght, int taskInputType, int taskOutputSize) { // printLine(taskId+"->"+taskStartTime); - taskMap.put(taskId, new LogItem(taskType, taskLenght, taskInputType, taskOutputSize)); + taskMap.put(taskId, new LogItem(deviceId, taskType, taskLenght, taskInputType, taskOutputSize)); } public void taskStarted(int taskId, double time) { @@ -126,34 +293,57 @@ public class SimLogger { public void taskEnded(int taskId, double time) { taskMap.get(taskId).taskEnded(time); + recordLog(taskId); } public void rejectedDueToVMCapacity(int taskId, double time, int vmType) { taskMap.get(taskId).taskRejectedDueToVMCapacity(time, vmType); + recordLog(taskId); } + public void rejectedDueToWlanCoverage(int taskId, double time, int vmType) { + taskMap.get(taskId).taskRejectedDueToWlanCoverage(time, vmType); + recordLog(taskId); + } + public void rejectedDueToBandwidth(int taskId, double time, int vmType, NETWORK_DELAY_TYPES delayType) { taskMap.get(taskId).taskRejectedDueToBandwidth(time, vmType, delayType); + recordLog(taskId); } public void failedDueToBandwidth(int taskId, double time, NETWORK_DELAY_TYPES delayType) { taskMap.get(taskId).taskFailedDueToBandwidth(time, delayType); + recordLog(taskId); } public void failedDueToMobility(int taskId, double time) { taskMap.get(taskId).taskFailedDueToMobility(time); + recordLog(taskId); + } + + public void setQoE(int taskId, double QoE){ + taskMap.get(taskId).setQoE(QoE); + } + + public void setOrchestratorOverhead(int taskId, double overhead){ + taskMap.get(taskId).setOrchestratorOverhead(overhead); } public void addVmUtilizationLog(double time, double loadOnEdge, double loadOnCloud, double loadOnMobile) { - vmLoadList.add(new VmLoadLogItem(time, loadOnEdge, loadOnCloud, loadOnMobile)); + if(SimSettings.getInstance().getLocationLogInterval() != 0) + vmLoadList.add(new VmLoadLogItem(time, loadOnEdge, loadOnCloud, loadOnMobile)); } + public void addApDelayLog(double time, double[] apUploadDelays, double[] apDownloadDelays) { + if(SimSettings.getInstance().getApDelayLogInterval() != 0) + apDelayList.add(new ApDelayLogItem(time, apUploadDelays, apDownloadDelays)); + } + public void simStopped() throws IOException { - int numOfAppTypes = SimSettings.getInstance().getTaskLookUpTable().length; - - File successFile = null, failFile = null, vmLoadFile = null, locationFile = null; - FileWriter successFW = null, failFW = null, vmLoadFW = null, locationFW = null; - BufferedWriter successBW = null, failBW = null, vmLoadBW = null, locationBW = null; + endTime = System.currentTimeMillis(); + File vmLoadFile = null, locationFile = null, apUploadDelayFile = null, apDownloadDelayFile = null; + FileWriter vmLoadFW = null, locationFW = null, apUploadDelayFW = null, apDownloadDelayFW = null; + BufferedWriter vmLoadBW = null, locationBW = null, apUploadDelayBW = null, apDownloadDelayBW = null; // Save generic results to file for each app type. last index is average // of all app types @@ -161,66 +351,8 @@ public class SimLogger { FileWriter[] genericFWs = new FileWriter[numOfAppTypes + 1]; BufferedWriter[] genericBWs = new BufferedWriter[numOfAppTypes + 1]; - // extract following values for each app type. last index is average of - // all app types - int[] uncompletedTask = new int[numOfAppTypes + 1]; - int[] uncompletedTaskOnCloud = new int[numOfAppTypes + 1]; - int[] uncompletedTaskOnEdge = new int[numOfAppTypes + 1]; - int[] uncompletedTaskOnMobile = new int[numOfAppTypes + 1]; - - int[] completedTask = new int[numOfAppTypes + 1]; - int[] completedTaskOnCloud = new int[numOfAppTypes + 1]; - int[] completedTaskOnEdge = new int[numOfAppTypes + 1]; - int[] completedTaskOnMobile = new int[numOfAppTypes + 1]; - - int[] failedTask = new int[numOfAppTypes + 1]; - int[] failedTaskOnCloud = new int[numOfAppTypes + 1]; - int[] failedTaskOnEdge = new int[numOfAppTypes + 1]; - int[] failedTaskOnMobile = new int[numOfAppTypes + 1]; - - double[] networkDelay = new double[numOfAppTypes + 1]; - double[] wanDelay = new double[numOfAppTypes + 1]; - double[] manDelay = new double[numOfAppTypes + 1]; - double[] lanDelay = new double[numOfAppTypes + 1]; - - double[] wanUsage = new double[numOfAppTypes + 1]; - double[] manUsage = new double[numOfAppTypes + 1]; - double[] lanUsage = new double[numOfAppTypes + 1]; - - double[] serviceTime = new double[numOfAppTypes + 1]; - double[] serviceTimeOnCloud = new double[numOfAppTypes + 1]; - double[] serviceTimeOnEdge = new double[numOfAppTypes + 1]; - double[] serviceTimeOnMobile = new double[numOfAppTypes + 1]; - - double[] processingTime = new double[numOfAppTypes + 1]; - double[] processingTimeOnCloud = new double[numOfAppTypes + 1]; - double[] processingTimeOnEdge = new double[numOfAppTypes + 1]; - double[] processingTimeOnMobile = new double[numOfAppTypes + 1]; - - int[] failedTaskDueToVmCapacity = new int[numOfAppTypes + 1]; - int[] failedTaskDueToVmCapacityOnCloud = new int[numOfAppTypes + 1]; - int[] failedTaskDueToVmCapacityOnEdge = new int[numOfAppTypes + 1]; - int[] failedTaskDueToVmCapacityOnMobile = new int[numOfAppTypes + 1]; - - double[] cost = new double[numOfAppTypes + 1]; - int[] failedTaskDuetoBw = new int[numOfAppTypes + 1]; - int[] failedTaskDuetoLanBw = new int[numOfAppTypes + 1]; - int[] failedTaskDuetoManBw = new int[numOfAppTypes + 1]; - int[] failedTaskDuetoWanBw = new int[numOfAppTypes + 1]; - int[] failedTaskDuetoMobility = new int[numOfAppTypes + 1]; - // open all files and prepare them for write if (fileLogEnabled) { - if (SimSettings.getInstance().getDeepFileLoggingEnabled()) { - successFile = new File(outputFolder, filePrefix + "_SUCCESS.log"); - successFW = new FileWriter(successFile, true); - successBW = new BufferedWriter(successFW); - - failFile = new File(outputFolder, filePrefix + "_FAIL.log"); - failFW = new FileWriter(failFile, true); - failBW = new BufferedWriter(failFW); - } - vmLoadFile = new File(outputFolder, filePrefix + "_VM_LOAD.log"); vmLoadFW = new FileWriter(vmLoadFile, true); vmLoadBW = new BufferedWriter(vmLoadFW); @@ -229,12 +361,19 @@ public class SimLogger { locationFW = new FileWriter(locationFile, true); locationBW = new BufferedWriter(locationFW); + apUploadDelayFile = new File(outputFolder, filePrefix + "_AP_UPLOAD_DELAY.log"); + apUploadDelayFW = new FileWriter(apUploadDelayFile, true); + apUploadDelayBW = new BufferedWriter(apUploadDelayFW); + + apDownloadDelayFile = new File(outputFolder, filePrefix + "_AP_DOWNLOAD_DELAY.log"); + apDownloadDelayFW = new FileWriter(apDownloadDelayFile, true); + apDownloadDelayBW = new BufferedWriter(apDownloadDelayFW); + for (int i = 0; i < numOfAppTypes + 1; i++) { String fileName = "ALL_APPS_GENERIC.log"; if (i < numOfAppTypes) { - // if related app is not used in this simulation, just - // discard it + // if related app is not used in this simulation, just discard it if (SimSettings.getInstance().getTaskLookUpTable()[i][0] == 0) continue; @@ -247,121 +386,23 @@ public class SimLogger { appendToFile(genericBWs[i], "#auto generated file!"); } - if (SimSettings.getInstance().getDeepFileLoggingEnabled()) { - appendToFile(successBW, "#auto generated file!"); - appendToFile(failBW, "#auto generated file!"); - } - appendToFile(vmLoadBW, "#auto generated file!"); appendToFile(locationBW, "#auto generated file!"); + appendToFile(apUploadDelayBW, "#auto generated file!"); + appendToFile(apDownloadDelayBW, "#auto generated file!"); } - // extract the result of each task and write it to the file if required + //the tasks in the map is not completed yet! for (Map.Entry entry : taskMap.entrySet()) { - Integer key = entry.getKey(); LogItem value = entry.getValue(); - if (value.isInWarmUpPeriod()) - continue; - - if (value.getStatus() == SimLogger.TASK_STATUS.COMLETED) { - completedTask[value.getTaskType()]++; - - if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) - completedTaskOnCloud[value.getTaskType()]++; - else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) - completedTaskOnMobile[value.getTaskType()]++; - else - completedTaskOnEdge[value.getTaskType()]++; - } - else if(value.getStatus() == SimLogger.TASK_STATUS.CREATED || - value.getStatus() == SimLogger.TASK_STATUS.UPLOADING || - value.getStatus() == SimLogger.TASK_STATUS.PROCESSING || - value.getStatus() == SimLogger.TASK_STATUS.DOWNLOADING) - { - uncompletedTask[value.getTaskType()]++; - if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) - uncompletedTaskOnCloud[value.getTaskType()]++; - else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) - uncompletedTaskOnMobile[value.getTaskType()]++; - else - uncompletedTaskOnEdge[value.getTaskType()]++; - } - else { - failedTask[value.getTaskType()]++; - - if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) - failedTaskOnCloud[value.getTaskType()]++; - else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) - failedTaskOnMobile[value.getTaskType()]++; - else - failedTaskOnEdge[value.getTaskType()]++; - } - - if (value.getStatus() == SimLogger.TASK_STATUS.COMLETED) { - cost[value.getTaskType()] += value.getCost(); - serviceTime[value.getTaskType()] += value.getServiceTime(); - networkDelay[value.getTaskType()] += value.getNetworkDelay(); - processingTime[value.getTaskType()] += (value.getServiceTime() - value.getNetworkDelay()); - - if(value.getNetworkDelay(NETWORK_DELAY_TYPES.WLAN_DELAY) != 0) { - lanUsage[value.getTaskType()]++; - lanDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.WLAN_DELAY); - } - if(value.getNetworkDelay(NETWORK_DELAY_TYPES.MAN_DELAY) != 0) { - manUsage[value.getTaskType()]++; - manDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.MAN_DELAY); - } - if(value.getNetworkDelay(NETWORK_DELAY_TYPES.WAN_DELAY) != 0) { - wanUsage[value.getTaskType()]++; - wanDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.WAN_DELAY); - } - - - if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) { - serviceTimeOnCloud[value.getTaskType()] += value.getServiceTime(); - processingTimeOnCloud[value.getTaskType()] += (value.getServiceTime() - value.getNetworkDelay()); - } - else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) { - serviceTimeOnMobile[value.getTaskType()] += value.getServiceTime(); - processingTimeOnMobile[value.getTaskType()] += value.getServiceTime(); - } - else { - serviceTimeOnEdge[value.getTaskType()] += value.getServiceTime(); - processingTimeOnEdge[value.getTaskType()] += (value.getServiceTime() - value.getNetworkDelay()); - } - - if (fileLogEnabled && SimSettings.getInstance().getDeepFileLoggingEnabled()) - appendToFile(successBW, value.toString(key)); - } else if (value.getStatus() == SimLogger.TASK_STATUS.REJECTED_DUE_TO_VM_CAPACITY) { - failedTaskDueToVmCapacity[value.getTaskType()]++; - - if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) - failedTaskDueToVmCapacityOnCloud[value.getTaskType()]++; - else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) - failedTaskDueToVmCapacityOnMobile[value.getTaskType()]++; - else - failedTaskDueToVmCapacityOnEdge[value.getTaskType()]++; - - if (fileLogEnabled && SimSettings.getInstance().getDeepFileLoggingEnabled()) - appendToFile(failBW, value.toString(key)); - } else if (value.getStatus() == SimLogger.TASK_STATUS.REJECTED_DUE_TO_BANDWIDTH - || value.getStatus() == SimLogger.TASK_STATUS.UNFINISHED_DUE_TO_BANDWIDTH) { - failedTaskDuetoBw[value.getTaskType()]++; - if (value.getNetworkError() == NETWORK_ERRORS.LAN_ERROR) - failedTaskDuetoLanBw[value.getTaskType()]++; - else if (value.getNetworkError() == NETWORK_ERRORS.MAN_ERROR) - failedTaskDuetoManBw[value.getTaskType()]++; - else if (value.getNetworkError() == NETWORK_ERRORS.WAN_ERROR) - failedTaskDuetoWanBw[value.getTaskType()]++; - - if (fileLogEnabled && SimSettings.getInstance().getDeepFileLoggingEnabled()) - appendToFile(failBW, value.toString(key)); - } else if (value.getStatus() == SimLogger.TASK_STATUS.UNFINISHED_DUE_TO_MOBILITY) { - failedTaskDuetoMobility[value.getTaskType()]++; - if (fileLogEnabled && SimSettings.getInstance().getDeepFileLoggingEnabled()) - appendToFile(failBW, value.toString(key)); - } + uncompletedTask[value.getTaskType()]++; + if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) + uncompletedTaskOnCloud[value.getTaskType()]++; + else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) + uncompletedTaskOnMobile[value.getTaskType()]++; + else + uncompletedTaskOnEdge[value.getTaskType()]++; } // calculate total values @@ -384,10 +425,12 @@ public class SimLogger { lanDelay[numOfAppTypes] = DoubleStream.of(lanDelay).sum(); manDelay[numOfAppTypes] = DoubleStream.of(manDelay).sum(); wanDelay[numOfAppTypes] = DoubleStream.of(wanDelay).sum(); + gsmDelay[numOfAppTypes] = DoubleStream.of(gsmDelay).sum(); lanUsage[numOfAppTypes] = DoubleStream.of(lanUsage).sum(); manUsage[numOfAppTypes] = DoubleStream.of(manUsage).sum(); wanUsage[numOfAppTypes] = DoubleStream.of(wanUsage).sum(); + gsmUsage[numOfAppTypes] = DoubleStream.of(gsmUsage).sum(); serviceTime[numOfAppTypes] = DoubleStream.of(serviceTime).sum(); serviceTimeOnCloud[numOfAppTypes] = DoubleStream.of(serviceTimeOnCloud).sum(); @@ -405,12 +448,17 @@ public class SimLogger { failedTaskDueToVmCapacityOnMobile[numOfAppTypes] = IntStream.of(failedTaskDueToVmCapacityOnMobile).sum(); cost[numOfAppTypes] = DoubleStream.of(cost).sum(); + QoE[numOfAppTypes] = DoubleStream.of(QoE).sum(); failedTaskDuetoBw[numOfAppTypes] = IntStream.of(failedTaskDuetoBw).sum(); + failedTaskDuetoGsmBw[numOfAppTypes] = IntStream.of(failedTaskDuetoGsmBw).sum(); failedTaskDuetoWanBw[numOfAppTypes] = IntStream.of(failedTaskDuetoWanBw).sum(); failedTaskDuetoManBw[numOfAppTypes] = IntStream.of(failedTaskDuetoManBw).sum(); failedTaskDuetoLanBw[numOfAppTypes] = IntStream.of(failedTaskDuetoLanBw).sum(); failedTaskDuetoMobility[numOfAppTypes] = IntStream.of(failedTaskDuetoMobility).sum(); + refectedTaskDuetoWlanRange[numOfAppTypes] = IntStream.of(refectedTaskDuetoWlanRange).sum(); + orchestratorOverhead[numOfAppTypes] = DoubleStream.of(orchestratorOverhead).sum(); + // calculate server load double totalVmLoadOnEdge = 0; double totalVmLoadOnCloud = 0; @@ -419,39 +467,47 @@ public class SimLogger { totalVmLoadOnEdge += entry.getEdgeLoad(); totalVmLoadOnCloud += entry.getCloudLoad(); totalVmLoadOnMobile += entry.getMobileLoad(); - if (fileLogEnabled) + if (fileLogEnabled && SimSettings.getInstance().getVmLoadLogInterval() != 0) appendToFile(vmLoadBW, entry.toString()); } if (fileLogEnabled) { - // write location info to file - for (int t = 1; t < (SimSettings.getInstance().getSimulationTime() - / SimSettings.getInstance().getVmLocationLogInterval()); t++) { - int[] locationInfo = new int[SimSettings.getInstance().getNumOfPlaceTypes()]; - Double time = t * SimSettings.getInstance().getVmLocationLogInterval(); + // write location info to file for each location + // assuming each location has only one access point + double locationLogInterval = SimSettings.getInstance().getLocationLogInterval(); + if(locationLogInterval != 0) { + for (int t = 1; t < (SimSettings.getInstance().getSimulationTime() / locationLogInterval); t++) { + int[] locationInfo = new int[SimSettings.getInstance().getNumOfEdgeDatacenters()]; + Double time = t * SimSettings.getInstance().getLocationLogInterval(); + + if (time < SimSettings.CLIENT_ACTIVITY_START_TIME) + continue; - if (time < SimSettings.getInstance().getWarmUpPeriod()) - continue; + for (int i = 0; i < SimManager.getInstance().getNumOfMobileDevice(); i++) { + Location loc = SimManager.getInstance().getMobilityModel().getLocation(i, time); + locationInfo[loc.getServingWlanId()]++; + } - for (int i = 0; i < SimManager.getInstance().getNumOfMobileDevice(); i++) { + locationBW.write(time.toString()); + for (int i = 0; i < locationInfo.length; i++) + locationBW.write(SimSettings.DELIMITER + locationInfo[i]); - Location loc = SimManager.getInstance().getMobilityModel().getLocation(i, time); - int placeTypeIndex = loc.getPlaceTypeIndex(); - locationInfo[placeTypeIndex]++; + locationBW.newLine(); + } + } + + // write delay info to file for each access point + if(SimSettings.getInstance().getApDelayLogInterval() != 0) { + for (ApDelayLogItem entry : apDelayList) { + appendToFile(apUploadDelayBW, entry.getUploadStat()); + appendToFile(apDownloadDelayBW, entry.getDownloadStat()); } - - locationBW.write(time.toString()); - for (int i = 0; i < locationInfo.length; i++) - locationBW.write(SimSettings.DELIMITER + locationInfo[i]); - - locationBW.newLine(); } for (int i = 0; i < numOfAppTypes + 1; i++) { if (i < numOfAppTypes) { - // if related app is not used in this simulation, just - // discard it + // if related app is not used in this simulation, just discard it if (SimSettings.getInstance().getTaskLookUpTable()[i][0] == 0) continue; } @@ -465,6 +521,8 @@ public class SimLogger { double _vmLoadOnClould = (vmLoadList.size() == 0) ? 0.0 : (totalVmLoadOnCloud / (double) vmLoadList.size()); double _vmLoadOnMobile = (vmLoadList.size() == 0) ? 0.0 : (totalVmLoadOnMobile / (double) vmLoadList.size()); double _cost = (completedTask[i] == 0) ? 0.0 : (cost[i] / (double) completedTask[i]); + double _QoE1 = (completedTask[i] == 0) ? 0.0 : (QoE[i] / (double) completedTask[i]); + double _QoE2 = (completedTask[i] == 0) ? 0.0 : (QoE[i] / (double) (failedTask[i] + completedTask[i])); double _lanDelay = (lanUsage[i] == 0) ? 0.0 : (lanDelay[i] / (double) lanUsage[i]); @@ -472,7 +530,9 @@ public class SimLogger { : (manDelay[i] / (double) manUsage[i]); double _wanDelay = (wanUsage[i] == 0) ? 0.0 : (wanDelay[i] / (double) wanUsage[i]); - + double _gsmDelay = (gsmUsage[i] == 0) ? 0.0 + : (gsmDelay[i] / (double) gsmUsage[i]); + // write generic results String genericResult1 = Integer.toString(completedTask[i]) + SimSettings.DELIMITER + Integer.toString(failedTask[i]) + SimSettings.DELIMITER @@ -484,7 +544,10 @@ public class SimLogger { + Double.toString(0) + SimSettings.DELIMITER + Double.toString(_cost) + SimSettings.DELIMITER + Integer.toString(failedTaskDueToVmCapacity[i]) + SimSettings.DELIMITER - + Integer.toString(failedTaskDuetoMobility[i]); + + Integer.toString(failedTaskDuetoMobility[i]) + SimSettings.DELIMITER + + Double.toString(_QoE1) + SimSettings.DELIMITER + + Double.toString(_QoE2) + SimSettings.DELIMITER + + Integer.toString(refectedTaskDuetoWlanRange[i]); // check if the divisor is zero in order to avoid division by zero problem double _serviceTimeOnEdge = (completedTaskOnEdge[i] == 0) ? 0.0 @@ -534,16 +597,48 @@ public class SimLogger { String genericResult5 = Double.toString(_lanDelay) + SimSettings.DELIMITER + Double.toString(_manDelay) + SimSettings.DELIMITER + Double.toString(_wanDelay) + SimSettings.DELIMITER - + 0 + SimSettings.DELIMITER //for future use + + Double.toString(_gsmDelay) + SimSettings.DELIMITER + Integer.toString(failedTaskDuetoLanBw[i]) + SimSettings.DELIMITER + Integer.toString(failedTaskDuetoManBw[i]) + SimSettings.DELIMITER - + Integer.toString(failedTaskDuetoWanBw[i]); + + Integer.toString(failedTaskDuetoWanBw[i]) + SimSettings.DELIMITER + + Integer.toString(failedTaskDuetoGsmBw[i]); + + //performance related values + double _orchestratorOverhead = orchestratorOverhead[i] / (double) (failedTask[i] + completedTask[i]); + + String genericResult6 = Long.toString((endTime-startTime)/60) + SimSettings.DELIMITER + + Double.toString(_orchestratorOverhead); + appendToFile(genericBWs[i], genericResult1); appendToFile(genericBWs[i], genericResult2); appendToFile(genericBWs[i], genericResult3); appendToFile(genericBWs[i], genericResult4); appendToFile(genericBWs[i], genericResult5); + + //append performance related values only to ALL_ALLPS file + if(i == numOfAppTypes) { + appendToFile(genericBWs[i], genericResult6); + } + else { + printLine(SimSettings.getInstance().getTaskName(i)); + printLine("# of tasks (Edge/Cloud): " + + (failedTask[i] + completedTask[i]) + "(" + + (failedTaskOnEdge[i] + completedTaskOnEdge[i]) + "/" + + (failedTaskOnCloud[i]+ completedTaskOnCloud[i]) + ")" ); + + printLine("# of failed tasks (Edge/Cloud): " + + failedTask[i] + "(" + + failedTaskOnEdge[i] + "/" + + failedTaskOnCloud[i] + ")"); + + printLine("# of completed tasks (Edge/Cloud): " + + completedTask[i] + "(" + + completedTaskOnEdge[i] + "/" + + completedTaskOnCloud[i] + ")"); + + printLine("---------------------------------------"); + } } // close open files @@ -553,6 +648,8 @@ public class SimLogger { } vmLoadBW.close(); locationBW.close(); + apUploadDelayBW.close(); + apDownloadDelayBW.close(); for (int i = 0; i < numOfAppTypes + 1; i++) { if (i < numOfAppTypes) { // if related app is not used in this simulation, just @@ -562,6 +659,7 @@ public class SimLogger { } genericBWs[i].close(); } + } // printout important results @@ -595,12 +693,14 @@ public class SimLogger { + failedTaskDueToVmCapacityOnCloud[numOfAppTypes] + "/" + failedTaskDueToVmCapacityOnMobile[numOfAppTypes] + ")"); - printLine("# of failed tasks due to Mobility/Network(WLAN/MAN/WAN): " + printLine("# of failed tasks due to Mobility/WLAN Range/Network(WLAN/MAN/WAN/GSM): " + failedTaskDuetoMobility[numOfAppTypes] + + "/" + refectedTaskDuetoWlanRange[numOfAppTypes] + "/" + failedTaskDuetoBw[numOfAppTypes] + "(" + failedTaskDuetoLanBw[numOfAppTypes] + "/" + failedTaskDuetoManBw[numOfAppTypes] - + "/" + failedTaskDuetoWanBw[numOfAppTypes] + ")"); + + "/" + failedTaskDuetoWanBw[numOfAppTypes] + + "/" + failedTaskDuetoGsmBw[numOfAppTypes] + ")"); printLine("percentage of failed tasks: " + String.format("%.6f", ((double) failedTask[numOfAppTypes] * (double) 100) @@ -634,18 +734,128 @@ public class SimLogger { + ", " + "MAN delay: " + String.format("%.6f", manDelay[numOfAppTypes] / (double) manUsage[numOfAppTypes]) + ", " + "WAN delay: " - + String.format("%.6f", wanDelay[numOfAppTypes] / (double) wanUsage[numOfAppTypes]) + ")"); + + String.format("%.6f", wanDelay[numOfAppTypes] / (double) wanUsage[numOfAppTypes]) + + ", " + "GSM delay: " + + String.format("%.6f", gsmDelay[numOfAppTypes] / (double) gsmUsage[numOfAppTypes]) + ")"); printLine("average server utilization Edge/Cloud/Mobile: " + String.format("%.6f", totalVmLoadOnEdge / (double) vmLoadList.size()) + "/" + String.format("%.6f", totalVmLoadOnCloud / (double) vmLoadList.size()) + "/" + String.format("%.6f", totalVmLoadOnMobile / (double) vmLoadList.size())); - + printLine("average cost: " + cost[numOfAppTypes] / completedTask[numOfAppTypes] + "$"); + printLine("average overhead: " + orchestratorOverhead[numOfAppTypes] / (failedTask[numOfAppTypes] + completedTask[numOfAppTypes]) + " ns"); + printLine("average QoE (for all): " + QoE[numOfAppTypes] / (failedTask[numOfAppTypes] + completedTask[numOfAppTypes]) + "%"); + printLine("average QoE (for executed): " + QoE[numOfAppTypes] / completedTask[numOfAppTypes] + "%"); // clear related collections (map list etc.) taskMap.clear(); vmLoadList.clear(); + apDelayList.clear(); + } + + private void recordLog(int taskId){ + LogItem value = taskMap.remove(taskId); + + if (value.isInWarmUpPeriod()) + return; + + if (value.getStatus() == SimLogger.TASK_STATUS.COMLETED) { + completedTask[value.getTaskType()]++; + + if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) + completedTaskOnCloud[value.getTaskType()]++; + else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) + completedTaskOnMobile[value.getTaskType()]++; + else + completedTaskOnEdge[value.getTaskType()]++; + } + else { + failedTask[value.getTaskType()]++; + + if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) + failedTaskOnCloud[value.getTaskType()]++; + else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) + failedTaskOnMobile[value.getTaskType()]++; + else + failedTaskOnEdge[value.getTaskType()]++; + } + + if (value.getStatus() == SimLogger.TASK_STATUS.COMLETED) { + cost[value.getTaskType()] += value.getCost(); + QoE[value.getTaskType()] += value.getQoE(); + serviceTime[value.getTaskType()] += value.getServiceTime(); + networkDelay[value.getTaskType()] += value.getNetworkDelay(); + processingTime[value.getTaskType()] += (value.getServiceTime() - value.getNetworkDelay()); + orchestratorOverhead[value.getTaskType()] += value.getOrchestratorOverhead(); + + if(value.getNetworkDelay(NETWORK_DELAY_TYPES.WLAN_DELAY) != 0) { + lanUsage[value.getTaskType()]++; + lanDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.WLAN_DELAY); + } + if(value.getNetworkDelay(NETWORK_DELAY_TYPES.MAN_DELAY) != 0) { + manUsage[value.getTaskType()]++; + manDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.MAN_DELAY); + } + if(value.getNetworkDelay(NETWORK_DELAY_TYPES.WAN_DELAY) != 0) { + wanUsage[value.getTaskType()]++; + wanDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.WAN_DELAY); + } + if(value.getNetworkDelay(NETWORK_DELAY_TYPES.GSM_DELAY) != 0) { + gsmUsage[value.getTaskType()]++; + gsmDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.GSM_DELAY); + } + + if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) { + serviceTimeOnCloud[value.getTaskType()] += value.getServiceTime(); + processingTimeOnCloud[value.getTaskType()] += (value.getServiceTime() - value.getNetworkDelay()); + } + else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) { + serviceTimeOnMobile[value.getTaskType()] += value.getServiceTime(); + processingTimeOnMobile[value.getTaskType()] += value.getServiceTime(); + } + else { + serviceTimeOnEdge[value.getTaskType()] += value.getServiceTime(); + processingTimeOnEdge[value.getTaskType()] += (value.getServiceTime() - value.getNetworkDelay()); + } + } else if (value.getStatus() == SimLogger.TASK_STATUS.REJECTED_DUE_TO_VM_CAPACITY) { + failedTaskDueToVmCapacity[value.getTaskType()]++; + + if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) + failedTaskDueToVmCapacityOnCloud[value.getTaskType()]++; + else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) + failedTaskDueToVmCapacityOnMobile[value.getTaskType()]++; + else + failedTaskDueToVmCapacityOnEdge[value.getTaskType()]++; + } else if (value.getStatus() == SimLogger.TASK_STATUS.REJECTED_DUE_TO_BANDWIDTH + || value.getStatus() == SimLogger.TASK_STATUS.UNFINISHED_DUE_TO_BANDWIDTH) { + failedTaskDuetoBw[value.getTaskType()]++; + if (value.getNetworkError() == NETWORK_ERRORS.LAN_ERROR) + failedTaskDuetoLanBw[value.getTaskType()]++; + else if (value.getNetworkError() == NETWORK_ERRORS.MAN_ERROR) + failedTaskDuetoManBw[value.getTaskType()]++; + else if (value.getNetworkError() == NETWORK_ERRORS.WAN_ERROR) + failedTaskDuetoWanBw[value.getTaskType()]++; + else if (value.getNetworkError() == NETWORK_ERRORS.GSM_ERROR) + failedTaskDuetoGsmBw[value.getTaskType()]++; + } else if (value.getStatus() == SimLogger.TASK_STATUS.UNFINISHED_DUE_TO_MOBILITY) { + failedTaskDuetoMobility[value.getTaskType()]++; + } else if (value.getStatus() == SimLogger.TASK_STATUS.REJECTED_DUE_TO_WLAN_COVERAGE) { + refectedTaskDuetoWlanRange[value.getTaskType()]++;; + } + + //if deep file logging is enabled, record every task result + if (SimSettings.getInstance().getDeepFileLoggingEnabled()){ + try { + if (value.getStatus() == SimLogger.TASK_STATUS.COMLETED) + appendToFile(successBW, value.toString(taskId)); + else + appendToFile(failBW, value.toString(taskId)); + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + } } } @@ -682,9 +892,38 @@ class VmLoadLogItem { } } +class ApDelayLogItem { + private double time; + private double apUploadDelays[]; + double[] apDownloadDelays; + + ApDelayLogItem(double _time, double[] _apUploadDelays, double[] _apDownloadDelays){ + time = _time; + apUploadDelays = _apUploadDelays; + apDownloadDelays = _apDownloadDelays; + } + + public String getUploadStat() { + String result = Double.toString(time); + for(int i=0; i0) result += diffInDays + ((diffInDays>1 == true) ? " Days " : " Day "); if(diffInHours>0) @@ -79,7 +82,7 @@ public class SimUtils { result += diffInSeconds % 60 + ((diffInSeconds>1 == true) ? " Seconds" : " Second"); if(diffInMilli>0 && result.isEmpty()) result += diffInMilli + ((diffInMilli>1 == true) ? " Milli Seconds" : " Milli Second"); - + return result; } } diff --git a/src/edu/boun/edgecloudsim/utils/TaskProperty.java b/src/edu/boun/edgecloudsim/utils/TaskProperty.java index fe77a11..e5b9a70 100644 --- a/src/edu/boun/edgecloudsim/utils/TaskProperty.java +++ b/src/edu/boun/edgecloudsim/utils/TaskProperty.java @@ -15,59 +15,69 @@ import org.apache.commons.math3.distribution.ExponentialDistribution; import edu.boun.edgecloudsim.core.SimSettings; public class TaskProperty { - private double startTime; - private long length, inputFileSize, outputFileSize; - private int taskType; - private int pesNumber; - private int mobileDeviceId; - - public TaskProperty(double _startTime, int _mobileDeviceId, int _taskType, int _pesNumber, long _length, long _inputFileSize, long _outputFileSize) { - startTime=_startTime; - mobileDeviceId=_mobileDeviceId; - taskType=_taskType; - pesNumber = _pesNumber; - length = _length; - outputFileSize = _inputFileSize; - inputFileSize = _outputFileSize; - } - - public TaskProperty(int _mobileDeviceId, int _taskType, double _startTime, ExponentialDistribution[][] expRngList) { - mobileDeviceId=_mobileDeviceId; - startTime=_startTime; - taskType=_taskType; - - inputFileSize = (long)expRngList[_taskType][0].sample(); - outputFileSize =(long)expRngList[_taskType][1].sample(); - length = (long)expRngList[_taskType][2].sample(); - - pesNumber = (int)SimSettings.getInstance().getTaskLookUpTable()[_taskType][8]; - } - - public double getStartTime(){ - return startTime; - } - - public long getLength(){ - return length; - } - - public long getInputFileSize(){ - return inputFileSize; - } - - public long getOutputFileSize(){ - return outputFileSize; - } + private double startTime; + private long length, inputFileSize, outputFileSize; + private int taskType; + private int pesNumber; + private int mobileDeviceId; - public int getTaskType(){ - return taskType; - } - - public int getPesNumber(){ - return pesNumber; - } - - public int getMobileDeviceId(){ - return mobileDeviceId; - } + public TaskProperty(double _startTime, int _mobileDeviceId, int _taskType, int _pesNumber, long _length, long _inputFileSize, long _outputFileSize) { + startTime=_startTime; + mobileDeviceId=_mobileDeviceId; + taskType=_taskType; + pesNumber = _pesNumber; + length = _length; + outputFileSize = _inputFileSize; + inputFileSize = _outputFileSize; + } + + public TaskProperty(int _mobileDeviceId, int _taskType, double _startTime, ExponentialDistribution[][] expRngList) { + mobileDeviceId=_mobileDeviceId; + startTime=_startTime; + taskType=_taskType; + + inputFileSize = (long)expRngList[_taskType][0].sample(); + outputFileSize =(long)expRngList[_taskType][1].sample(); + length = (long)expRngList[_taskType][2].sample(); + + pesNumber = (int)SimSettings.getInstance().getTaskLookUpTable()[_taskType][8]; + } + + public TaskProperty(int mobileDeviceId, double startTime, ExponentialDistribution[] expRngList) { + this.mobileDeviceId = mobileDeviceId; + this.startTime = startTime; + taskType = 0; + inputFileSize = (long)expRngList[0].sample(); + outputFileSize = (long)expRngList[1].sample(); + length = (long) expRngList[2].sample(); + pesNumber = (int)SimSettings.getInstance().getTaskLookUpTable()[0][8]; + } + + public double getStartTime(){ + return startTime; + } + + public long getLength(){ + return length; + } + + public long getInputFileSize(){ + return inputFileSize; + } + + public long getOutputFileSize(){ + return outputFileSize; + } + + public int getTaskType(){ + return taskType; + } + + public int getPesNumber(){ + return pesNumber; + } + + public int getMobileDeviceId(){ + return mobileDeviceId; + } }