diff --git a/README.md b/README.md index c415f09..204153d 100644 --- a/README.md +++ b/README.md @@ -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_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_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..bfa2780 --- /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