Sample application 5 used in IEEE Transactions on Intelligent Transportation Systems is added.
This commit is contained in:
parent
08341c3681
commit
6660de75b2
@ -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.
|
||||
|
BIN
doc/images/sample_app5/ml_details.png
Normal file
BIN
doc/images/sample_app5/ml_details.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 87 KiB |
BIN
doc/images/sample_app5/ml_stages.png
Normal file
BIN
doc/images/sample_app5/ml_stages.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
doc/images/sample_app5/road.png
Normal file
BIN
doc/images/sample_app5/road.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
doc/images/sample_app5/vec_architecture.png
Normal file
BIN
doc/images/sample_app5/vec_architecture.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
BIN
lib/mtj-1.0.4.jar
Normal file
BIN
lib/mtj-1.0.4.jar
Normal file
Binary file not shown.
BIN
lib/weka.jar
Normal file
BIN
lib/weka.jar
Normal file
Binary file not shown.
1
scripts/sample_app5/.gitignore
vendored
Normal file
1
scripts/sample_app5/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
output
|
1
scripts/sample_app5/ai_trainer/.gitignore
vendored
Normal file
1
scripts/sample_app5/ai_trainer/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.class
|
23
scripts/sample_app5/ai_trainer/README.md
Normal file
23
scripts/sample_app5/ai_trainer/README.md
Normal file
@ -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
|
208
scripts/sample_app5/ai_trainer/WekaModelCreator.java
Normal file
208
scripts/sample_app5/ai_trainer/WekaModelCreator.java
Normal file
@ -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; i<targets.length; i++) {
|
||||
handleClassify("train", targets[i], classifier, dataPath);
|
||||
handleRegression("train", targets[i], regressor, dataPath);
|
||||
}
|
||||
|
||||
System.out.println("######### EVALUATION FOR " + dataPath + " #########");
|
||||
for(int i=0; i<targets.length; i++) {
|
||||
handleClassify("evaluate", targets[i], classifier, dataPath);
|
||||
handleRegression("evaluate", targets[i], regressor, dataPath);
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleRegression(String action, String target, String method, String dataFolder) throws Exception {
|
||||
if(action.equals("train")) {
|
||||
DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
|
||||
Date startDate = Calendar.getInstance().getTime();
|
||||
String now = df.format(startDate);
|
||||
System.out.println("Training " + method + " for " + target + " started at " + now);
|
||||
|
||||
DataSource edgeRegressionSource = new DataSource(dataFolder + "/" + target + "_regression_train.arff");
|
||||
Instances edgeRegressionDataset = edgeRegressionSource.getDataSet();
|
||||
edgeRegressionDataset.setClassIndex(edgeRegressionDataset.numAttributes()-1);
|
||||
|
||||
if(method.equals("LinearRegression")) {
|
||||
LinearRegression lr = new LinearRegression();
|
||||
lr.buildClassifier(edgeRegressionDataset);
|
||||
weka.core.SerializationHelper.write(dataFolder + "/lr_" + target + ".model", lr);
|
||||
}
|
||||
else if(method.equals("SMOreg")) {
|
||||
SMOreg smoreg = new SMOreg();
|
||||
smoreg.buildClassifier(edgeRegressionDataset);
|
||||
weka.core.SerializationHelper.write(dataFolder + "/smoreg_" + target + ".model", smoreg);
|
||||
}
|
||||
|
||||
Date endDate = Calendar.getInstance().getTime();
|
||||
now = df.format(endDate);
|
||||
System.out.println("Training " + method + " for " + target + " fisished at " + now + ". It took " + getTimeDifference(startDate, endDate));
|
||||
}
|
||||
else if(action.equals("evaluate")) {
|
||||
System.out.println("Evaluation " + method + " for " + target + " started");
|
||||
|
||||
DataSource edgeRegressionSource = new DataSource(dataFolder + "/" + target + "_regression_test.arff");
|
||||
Instances edgeRegressionDataset = edgeRegressionSource.getDataSet();
|
||||
edgeRegressionDataset.setClassIndex(edgeRegressionDataset.numAttributes()-1);
|
||||
|
||||
if(method.equals("LinearRegression")) {
|
||||
LinearRegression lr = (LinearRegression) weka.core.SerializationHelper.read(dataFolder + "/lr_" + target + ".model");
|
||||
Evaluation lrEval = new Evaluation(edgeRegressionDataset);
|
||||
lrEval.evaluateModel(lr, edgeRegressionDataset);
|
||||
System.out.println("LinearRegression");
|
||||
System.out.println(lrEval.toSummaryString());
|
||||
}
|
||||
else if(method.equals("SMOreg")) {
|
||||
SMOreg smoreg = (SMOreg) weka.core.SerializationHelper.read(dataFolder + "/smoreg_" + target + ".model");
|
||||
Evaluation svmregEval = new Evaluation(edgeRegressionDataset);
|
||||
svmregEval.evaluateModel(smoreg, edgeRegressionDataset);
|
||||
System.out.println("SMOreg");
|
||||
System.out.println(svmregEval.toSummaryString());
|
||||
}
|
||||
|
||||
System.out.println("Evaluation " + method + " for " + target + " fisished");
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleClassify(String action, String target, String method, String dataFolder) throws Exception {
|
||||
if(action.equals("train")) {
|
||||
DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
|
||||
Date startDate = Calendar.getInstance().getTime();
|
||||
String now = df.format(startDate);
|
||||
System.out.println("Training " + method + " for " + target + " started at " + now);
|
||||
|
||||
DataSource classifierSource = new DataSource(dataFolder + "/" + target + "_classifier_train.arff");
|
||||
Instances classifierDataset = classifierSource.getDataSet();
|
||||
classifierDataset.setClassIndex(classifierDataset.numAttributes()-1);
|
||||
|
||||
if(method.equals("NaiveBayes")) {
|
||||
NaiveBayes nb = new NaiveBayes();
|
||||
nb.buildClassifier(classifierDataset);
|
||||
weka.core.SerializationHelper.write(dataFolder + "/nb_" + target + ".model", nb);
|
||||
}
|
||||
else if(method.equals("SMO")) {
|
||||
SMO smo = new SMO();
|
||||
smo.buildClassifier(classifierDataset);
|
||||
weka.core.SerializationHelper.write(dataFolder + "/smo_" + target + ".model", smo);
|
||||
}
|
||||
else if(method.equals("MultilayerPerceptron")) {
|
||||
MultilayerPerceptron mlp = new MultilayerPerceptron();
|
||||
mlp.setLearningRate(0.1);
|
||||
//mlp.setMomentum(0.2);
|
||||
mlp.setTrainingTime(1000);
|
||||
//mlp.setHiddenLayers("3");
|
||||
mlp.buildClassifier(classifierDataset);
|
||||
weka.core.SerializationHelper.write(dataFolder + "/mlp_" + target + ".model", mlp);
|
||||
}
|
||||
|
||||
Date endDate = Calendar.getInstance().getTime();
|
||||
now = df.format(endDate);
|
||||
System.out.println("Training " + method + " for " + target + " fisished at " + now + ". It took " + getTimeDifference(startDate, endDate));
|
||||
}
|
||||
else if(action.equals("evaluate")) {
|
||||
System.out.println("Evaluation " + method + " for " + target + " started");
|
||||
|
||||
DataSource edgeClassifierSource = new DataSource(dataFolder + "/" + target + "_classifier_test.arff");
|
||||
Instances classifierDataset = edgeClassifierSource.getDataSet();
|
||||
classifierDataset.setClassIndex(classifierDataset.numAttributes()-1);
|
||||
|
||||
if(method.equals("NaiveBayes")) {
|
||||
NaiveBayes nb = (NaiveBayes) weka.core.SerializationHelper.read(dataFolder + "/nb_" + target + ".model");
|
||||
Evaluation nbEval = new Evaluation(classifierDataset);
|
||||
nbEval.evaluateModel(nb, classifierDataset);
|
||||
System.out.println(nbEval.toSummaryString());
|
||||
System.out.println(nbEval.toMatrixString());
|
||||
System.out.println(nbEval.toClassDetailsString());
|
||||
}
|
||||
else if(method.equals("SMO")) {
|
||||
SMO smo = (SMO) weka.core.SerializationHelper.read(dataFolder + "/smo_" + target + ".model");
|
||||
Evaluation smoEval = new Evaluation(classifierDataset);
|
||||
smoEval.evaluateModel(smo, classifierDataset);
|
||||
System.out.println(smoEval.toSummaryString());
|
||||
System.out.println(smoEval.toMatrixString());
|
||||
System.out.println(smoEval.toClassDetailsString());
|
||||
}
|
||||
else if(method.equals("MultilayerPerceptron")) {
|
||||
MultilayerPerceptron mlp = (MultilayerPerceptron) weka.core.SerializationHelper.read(dataFolder + "/mlp_" + target + ".model");
|
||||
Evaluation mlpEval = new Evaluation(classifierDataset);
|
||||
mlpEval.evaluateModel(mlp, classifierDataset);
|
||||
System.out.println(mlpEval.toSummaryString());
|
||||
System.out.println(mlpEval.toMatrixString());
|
||||
System.out.println(mlpEval.toClassDetailsString());
|
||||
}
|
||||
|
||||
System.out.println("Evaluation " + method + " for " + target + " fisished");
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
|
||||
private static String getTimeDifference(Date startDate, Date endDate){
|
||||
String result = "";
|
||||
long duration = endDate.getTime() - startDate.getTime();
|
||||
|
||||
long diffInMilli = TimeUnit.MILLISECONDS.toMillis(duration);
|
||||
long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(duration);
|
||||
long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(duration);
|
||||
long diffInHours = TimeUnit.MILLISECONDS.toHours(duration);
|
||||
long diffInDays = TimeUnit.MILLISECONDS.toDays(duration);
|
||||
|
||||
if(diffInDays>0)
|
||||
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;
|
||||
}
|
||||
}
|
10
scripts/sample_app5/ai_trainer/config.json
Normal file
10
scripts/sample_app5/ai_trainer/config.json
Normal file
@ -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"
|
||||
}
|
133
scripts/sample_app5/ai_trainer/data_convertor.py
Normal file
133
scripts/sample_app5/ai_trainer/data_convertor.py
Normal file
@ -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 ("##############################################################")
|
||||
|
14
scripts/sample_app5/ai_trainer/generate_training_data.sh
Normal file
14
scripts/sample_app5/ai_trainer/generate_training_data.sh
Normal file
@ -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
|
4
scripts/sample_app5/ai_trainer/generate_weka_models.sh
Normal file
4
scripts/sample_app5/ai_trainer/generate_weka_models.sh
Normal file
@ -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
|
BIN
scripts/sample_app5/ai_trainer/json-simple-1.1.1.jar
Normal file
BIN
scripts/sample_app5/ai_trainer/json-simple-1.1.1.jar
Normal file
Binary file not shown.
4
scripts/sample_app5/compile.sh
Normal file
4
scripts/sample_app5/compile.sh
Normal file
@ -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
|
51
scripts/sample_app5/config/applications.xml
Normal file
51
scripts/sample_app5/config/applications.xml
Normal file
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0"?>
|
||||
<applications>
|
||||
<application name="TRAFFIC_MANAGEMENT">
|
||||
<usage_percentage>30</usage_percentage>
|
||||
<prob_cloud_selection>0</prob_cloud_selection>
|
||||
<delay_sensitivity>0.5</delay_sensitivity>
|
||||
<max_delay_requirement>0.5</max_delay_requirement>
|
||||
<poisson_interarrival>3</poisson_interarrival>
|
||||
<active_period>3600</active_period>
|
||||
<idle_period>1</idle_period>
|
||||
<data_upload>20</data_upload>
|
||||
<data_download>20</data_download>
|
||||
<task_length>3000</task_length>
|
||||
<required_core>1</required_core>
|
||||
<vm_utilization_on_edge>6</vm_utilization_on_edge>
|
||||
<vm_utilization_on_cloud>1.2</vm_utilization_on_cloud>
|
||||
<vm_utilization_on_mobile>0</vm_utilization_on_mobile>
|
||||
</application>
|
||||
<application name="DANGER_ASSESSMENT">
|
||||
<usage_percentage>35</usage_percentage>
|
||||
<prob_cloud_selection>0</prob_cloud_selection>
|
||||
<delay_sensitivity>0.8</delay_sensitivity>
|
||||
<max_delay_requirement>1</max_delay_requirement>
|
||||
<poisson_interarrival>5</poisson_interarrival>
|
||||
<active_period>3600</active_period>
|
||||
<idle_period>1</idle_period>
|
||||
<data_upload>40</data_upload>
|
||||
<data_download>20</data_download>
|
||||
<task_length>10000</task_length>
|
||||
<required_core>1</required_core>
|
||||
<vm_utilization_on_edge>20</vm_utilization_on_edge>
|
||||
<vm_utilization_on_cloud>4</vm_utilization_on_cloud>
|
||||
<vm_utilization_on_mobile>0</vm_utilization_on_mobile>
|
||||
</application>
|
||||
<application name="INFOTAINMENT">
|
||||
<usage_percentage>35</usage_percentage>
|
||||
<prob_cloud_selection>0</prob_cloud_selection>
|
||||
<delay_sensitivity>0.25</delay_sensitivity>
|
||||
<max_delay_requirement>1.5</max_delay_requirement>
|
||||
<poisson_interarrival>15</poisson_interarrival>
|
||||
<active_period>3600</active_period>
|
||||
<idle_period>1</idle_period>
|
||||
<data_upload>20</data_upload>
|
||||
<data_download>80</data_download>
|
||||
<task_length>20000</task_length>
|
||||
<required_core>1</required_core>
|
||||
<vm_utilization_on_edge>40</vm_utilization_on_edge>
|
||||
<vm_utilization_on_cloud>8</vm_utilization_on_cloud>
|
||||
<vm_utilization_on_mobile>0</vm_utilization_on_mobile>
|
||||
</application>
|
||||
</applications>
|
53
scripts/sample_app5/config/default_config.properties
Normal file
53
scripts/sample_app5/config/default_config.properties
Normal file
@ -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
|
1364
scripts/sample_app5/config/edge_devices.xml
Normal file
1364
scripts/sample_app5/config/edge_devices.xml
Normal file
File diff suppressed because it is too large
Load Diff
BIN
scripts/sample_app5/config/weka/lr_cloud_gsm.model
Normal file
BIN
scripts/sample_app5/config/weka/lr_cloud_gsm.model
Normal file
Binary file not shown.
BIN
scripts/sample_app5/config/weka/lr_cloud_rsu.model
Normal file
BIN
scripts/sample_app5/config/weka/lr_cloud_rsu.model
Normal file
Binary file not shown.
BIN
scripts/sample_app5/config/weka/lr_edge.model
Normal file
BIN
scripts/sample_app5/config/weka/lr_edge.model
Normal file
Binary file not shown.
BIN
scripts/sample_app5/config/weka/mlp_cloud_gsm.model
Normal file
BIN
scripts/sample_app5/config/weka/mlp_cloud_gsm.model
Normal file
Binary file not shown.
BIN
scripts/sample_app5/config/weka/mlp_cloud_rsu.model
Normal file
BIN
scripts/sample_app5/config/weka/mlp_cloud_rsu.model
Normal file
Binary file not shown.
BIN
scripts/sample_app5/config/weka/mlp_edge.model
Normal file
BIN
scripts/sample_app5/config/weka/mlp_edge.model
Normal file
Binary file not shown.
60
scripts/sample_app5/matlab/getConfiguration.m
Normal file
60
scripts/sample_app5/matlab/getConfiguration.m
Normal file
@ -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
|
113
scripts/sample_app5/matlab/plotApDelay.m
Normal file
113
scripts/sample_app5/matlab/plotApDelay.m
Normal file
@ -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
|
8
scripts/sample_app5/matlab/plotAvgFailedTask.m
Normal file
8
scripts/sample_app5/matlab/plotAvgFailedTask.m
Normal file
@ -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
|
11
scripts/sample_app5/matlab/plotAvgNetworkDelay.m
Normal file
11
scripts/sample_app5/matlab/plotAvgNetworkDelay.m
Normal file
@ -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
|
9
scripts/sample_app5/matlab/plotAvgProcessingTime.m
Normal file
9
scripts/sample_app5/matlab/plotAvgProcessingTime.m
Normal file
@ -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
|
8
scripts/sample_app5/matlab/plotAvgQoE.m
Normal file
8
scripts/sample_app5/matlab/plotAvgQoE.m
Normal file
@ -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
|
9
scripts/sample_app5/matlab/plotAvgServiceTime.m
Normal file
9
scripts/sample_app5/matlab/plotAvgServiceTime.m
Normal file
@ -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
|
7
scripts/sample_app5/matlab/plotAvgVmUtilization.m
Normal file
7
scripts/sample_app5/matlab/plotAvgVmUtilization.m
Normal file
@ -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
|
91
scripts/sample_app5/matlab/plotDelayReasonAsBar.m
Normal file
91
scripts/sample_app5/matlab/plotDelayReasonAsBar.m
Normal file
@ -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
|
198
scripts/sample_app5/matlab/plotGenericLine.m
Normal file
198
scripts/sample_app5/matlab/plotGenericLine.m
Normal file
@ -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
|
78
scripts/sample_app5/matlab/plotGenericPie.m
Normal file
78
scripts/sample_app5/matlab/plotGenericPie.m
Normal file
@ -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
|
96
scripts/sample_app5/matlab/plotGenericScatter.m
Normal file
96
scripts/sample_app5/matlab/plotGenericScatter.m
Normal file
@ -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
|
66
scripts/sample_app5/matlab/plotLocation.m
Normal file
66
scripts/sample_app5/matlab/plotLocation.m
Normal file
@ -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
|
15
scripts/sample_app5/matlab/plotTaskFailureReason.m
Normal file
15
scripts/sample_app5/matlab/plotTaskFailureReason.m
Normal file
@ -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
|
7
scripts/sample_app5/matlab/plotTimeComplexity.m
Normal file
7
scripts/sample_app5/matlab/plotTimeComplexity.m
Normal file
@ -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
|
75
scripts/sample_app5/run_scenarios.sh
Normal file
75
scripts/sample_app5/run_scenarios.sh
Normal file
@ -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 <scenario_folder>/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 <scenario_folder>/ite[n].log"
|
||||
echo "e.g."
|
||||
echo "tail -f output/${date}/${scenario_name}/ite1.log"
|
||||
echo "###############################################################"
|
25
scripts/sample_app5/runner.sh
Normal file
25
scripts/sample_app5/runner.sh
Normal file
@ -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
|
1
scripts/sample_app5/simulation.list
Normal file
1
scripts/sample_app5/simulation.list
Normal file
@ -0,0 +1 @@
|
||||
default_config;edge_devices.xml;applications.xml
|
15
scripts/sample_app5/stop_scenarios.sh
Normal file
15
scripts/sample_app5/stop_scenarios.sh
Normal file
@ -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..."
|
@ -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.
|
||||
|
||||
<p align="center">
|
||||
<img src="/doc/images/sample_app4/env.png" width="75%">
|
||||
<img src="/doc/images/sample_app4/env.png" width="55%">
|
||||
<p align="center">
|
||||
Figure 2: A university campus scenario representing multiple locations.
|
||||
</p>
|
||||
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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<K_tn.length; i++) {
|
||||
K_tn[i] = 1;
|
||||
U_tn[i] = expectedDelays[i] / taskLength;
|
||||
}
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to find the best choice via Upper Confidence Bound algorithm.
|
||||
*
|
||||
* @param taskLength task length
|
||||
* @return int selected datacenter type; 0=EDGE_DATACENTER, 1=CLOUD_DATACENTER_VIA_RSU, 2=CLOUD_DATACENTER_VIA_GSM
|
||||
*/
|
||||
public synchronized int runUCB(double taskLength) {
|
||||
int result = 0;
|
||||
double minUtilityFunctionValue = Double.MAX_VALUE;
|
||||
|
||||
for(int i=0; i<K_tn.length; i++) {
|
||||
double U_t = U_tn[i] - Math.sqrt((Beta * (1-normalizeTaskLength(taskLength)) * Math.log(t)) / K_tn[i]);
|
||||
if(U_t < minUtilityFunctionValue){
|
||||
minUtilityFunctionValue = U_t;
|
||||
result = i;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to find the best choice via Upper Confidence Bound algorithm.
|
||||
*
|
||||
* @param task offloaded task
|
||||
* @param serviceTime observed delay
|
||||
*/
|
||||
public synchronized void updateUCB(Task task, double serviceTime) {
|
||||
double taskLength = task.getCloudletLength();
|
||||
int choice = 0;
|
||||
switch (task.getAssociatedDatacenterId()) {
|
||||
case VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_GSM:
|
||||
choice = 2;
|
||||
break;
|
||||
case VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_RSU:
|
||||
choice = 1;
|
||||
break;
|
||||
case VehicularEdgeOrchestrator.EDGE_DATACENTER:
|
||||
choice = 0;
|
||||
break;
|
||||
default:
|
||||
SimLogger.printLine("Unknown datacenter id. Terminating simulation...");
|
||||
System.exit(1);
|
||||
break;
|
||||
}
|
||||
|
||||
if(serviceTime == 0) {
|
||||
if(task.getTaskType() == 0)
|
||||
serviceTime = 1.25;
|
||||
else if(task.getTaskType() == 1)
|
||||
serviceTime = 2;
|
||||
else
|
||||
serviceTime = 2.75;
|
||||
}
|
||||
|
||||
U_tn[choice] = (U_tn[choice] * K_tn[choice] + (serviceTime / taskLength)) / (K_tn[choice]);
|
||||
K_tn[choice] = K_tn[choice] + 1;
|
||||
|
||||
if(U_tn[choice] == Double.POSITIVE_INFINITY) {
|
||||
SimLogger.printLine("Unexpected MAB calculation! Utility function goes to infinity. Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
t++;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method normalizes the task length between 0-1.
|
||||
*
|
||||
* @param taskLength task length
|
||||
* @return double normalized task length
|
||||
*/
|
||||
private double normalizeTaskLength(double taskLength) {
|
||||
double result = (taskLength - MIN_TASK_LENGTH) / (MAX_TASK_LENGTH - MIN_TASK_LENGTH);
|
||||
return Math.max(Math.min(result,1),0);
|
||||
}
|
||||
}
|
@ -0,0 +1,193 @@
|
||||
package edu.boun.edgecloudsim.applications.sample_app5;
|
||||
|
||||
import edu.boun.edgecloudsim.edge_client.Task;
|
||||
import edu.boun.edgecloudsim.utils.SimLogger;
|
||||
|
||||
public class OrchestratorStatisticLogger {
|
||||
public static final int NUMBER_OF_HISTORY_WINDOW = 4;
|
||||
public static final double PREDICTION_WINDOW_UPDATE_INTERVAL = 0.125; //seconds
|
||||
|
||||
private StatisticWrapper statForPreviousWindow[];
|
||||
private StatisticWrapper statForCurrentWindow;
|
||||
|
||||
class StatItem {
|
||||
long numOfCompletedTasks;
|
||||
long numOfFailedTasks;
|
||||
double totalServiceTime;
|
||||
|
||||
double getFailureRate() {
|
||||
double failureRate = 0.1;
|
||||
if(numOfFailedTasks != 0)
|
||||
failureRate = ((double)100 * numOfFailedTasks) / (numOfCompletedTasks + numOfFailedTasks);
|
||||
|
||||
return failureRate;
|
||||
}
|
||||
|
||||
double getAvgServiceTime() {
|
||||
double serviceTime = 0.01;
|
||||
if(numOfCompletedTasks != 0)
|
||||
serviceTime = totalServiceTime/numOfCompletedTasks;
|
||||
|
||||
return serviceTime;
|
||||
}
|
||||
}
|
||||
|
||||
class StatisticWrapper {
|
||||
StatItem edgeStat;
|
||||
StatItem cloudViaRsuStat;
|
||||
StatItem cloudViaGsmStat;
|
||||
|
||||
double getFailureRate(int targetDatacenter) {
|
||||
double failureRate = 0;
|
||||
|
||||
switch (targetDatacenter) {
|
||||
case VehicularEdgeOrchestrator.EDGE_DATACENTER:
|
||||
failureRate = edgeStat.getFailureRate();
|
||||
break;
|
||||
case VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_RSU:
|
||||
failureRate = cloudViaRsuStat.getFailureRate();
|
||||
break;
|
||||
case VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_GSM:
|
||||
failureRate = cloudViaGsmStat.getFailureRate();
|
||||
break;
|
||||
default:
|
||||
SimLogger.printLine("Unknow target datacenter in predictive orchestration policy! Terminating simulation...");
|
||||
System.exit(1);
|
||||
break;
|
||||
}
|
||||
|
||||
return failureRate;
|
||||
}
|
||||
|
||||
double getAvgServiceTime(int targetDatacenter) {
|
||||
double serviceTime = 0.01;
|
||||
|
||||
switch (targetDatacenter) {
|
||||
case VehicularEdgeOrchestrator.EDGE_DATACENTER:
|
||||
serviceTime = edgeStat.getAvgServiceTime();
|
||||
break;
|
||||
case VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_RSU:
|
||||
serviceTime = cloudViaRsuStat.getAvgServiceTime();
|
||||
break;
|
||||
case VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_GSM:
|
||||
serviceTime = cloudViaGsmStat.getAvgServiceTime();
|
||||
break;
|
||||
default:
|
||||
SimLogger.printLine("Unknow target datacenter in predictive orchestration policy! Terminating simulation...");
|
||||
System.exit(1);
|
||||
break;
|
||||
}
|
||||
|
||||
return serviceTime;
|
||||
}
|
||||
}
|
||||
|
||||
public OrchestratorStatisticLogger() {
|
||||
statForCurrentWindow = new StatisticWrapper();
|
||||
statForCurrentWindow.cloudViaRsuStat = new StatItem();
|
||||
statForCurrentWindow.cloudViaGsmStat = new StatItem();
|
||||
statForCurrentWindow.edgeStat = new StatItem();
|
||||
|
||||
statForPreviousWindow = new StatisticWrapper[NUMBER_OF_HISTORY_WINDOW];
|
||||
for(int i = 0; i< NUMBER_OF_HISTORY_WINDOW; i++){
|
||||
statForPreviousWindow[i] = new StatisticWrapper();
|
||||
|
||||
statForPreviousWindow[i].cloudViaRsuStat = new StatItem();
|
||||
statForPreviousWindow[i].cloudViaGsmStat = new StatItem();
|
||||
statForPreviousWindow[i].edgeStat = new StatItem();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addSuccessStat(Task task, double serviceTime) {
|
||||
addStat(true, serviceTime, task.getAssociatedDatacenterId());
|
||||
}
|
||||
|
||||
public synchronized void addFailStat(Task task) {
|
||||
addStat(false, 0, task.getAssociatedDatacenterId());
|
||||
}
|
||||
|
||||
private synchronized void addStat(boolean isCompleted, double serviceTime, int targetDatacenter) {
|
||||
StatItem statItem = null;
|
||||
|
||||
switch (targetDatacenter) {
|
||||
case VehicularEdgeOrchestrator.EDGE_DATACENTER:
|
||||
statItem = statForCurrentWindow.edgeStat;
|
||||
break;
|
||||
case VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_RSU:
|
||||
statItem = statForCurrentWindow.cloudViaRsuStat;
|
||||
break;
|
||||
case VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_GSM:
|
||||
statItem = statForCurrentWindow.cloudViaGsmStat;
|
||||
break;
|
||||
default:
|
||||
SimLogger.printLine("Unknow target datacenter in predictive orchestration policy! Terminating simulation...");
|
||||
System.exit(1);
|
||||
break;
|
||||
}
|
||||
|
||||
if(isCompleted) {
|
||||
statItem.numOfCompletedTasks++;
|
||||
statItem.totalServiceTime += serviceTime;
|
||||
}
|
||||
else {
|
||||
statItem.numOfFailedTasks++;
|
||||
}
|
||||
}
|
||||
|
||||
public double getFailureRate(int targetDatacenter){
|
||||
double result = 0;
|
||||
|
||||
for (int i=0; i<NUMBER_OF_HISTORY_WINDOW; i++) {
|
||||
result += (statForPreviousWindow[i].getFailureRate(targetDatacenter) * (double)(NUMBER_OF_HISTORY_WINDOW - i));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public double getServiceTime(int targetDatacenter){
|
||||
double result = 0;
|
||||
|
||||
for (int i=0; i<NUMBER_OF_HISTORY_WINDOW; i++) {
|
||||
result += (statForPreviousWindow[i].getAvgServiceTime(targetDatacenter) * (double)(NUMBER_OF_HISTORY_WINDOW - i));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void switchNewStatWindow() {
|
||||
for(int i = NUMBER_OF_HISTORY_WINDOW -2; 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;
|
||||
}
|
||||
}
|
@ -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<Integer, TrainerItem> trainerMap;
|
||||
private List<Double>[] 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<Integer, TrainerItem>();
|
||||
|
||||
TaskOffloadStats = (ArrayList<Double>[])new ArrayList[3];
|
||||
TaskOffloadStats[0] = new ArrayList<Double>();
|
||||
TaskOffloadStats[1] = new ArrayList<Double>();
|
||||
TaskOffloadStats[2] = new ArrayList<Double>();
|
||||
}
|
||||
|
||||
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<trainerItem.edgeUtilizations.length; i++)
|
||||
// line += DELIMITER + Double.toString(trainerItem.edgeUtilizations[i]);
|
||||
|
||||
try {
|
||||
learnerBW.write(line);
|
||||
learnerBW.newLine();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void addStat(int id, int selectedDatacenter,
|
||||
double wanUploadDelay, double wanDownloadDelay,
|
||||
double gsmUploadDelay, double gsmDownloadDelay,
|
||||
double wlanUploadDelay, double wlanDownloadDelay){
|
||||
|
||||
addOffloadStat(selectedDatacenter-1);
|
||||
int numOffloadedTasks = getOffloadStat(selectedDatacenter-1);
|
||||
|
||||
int numberOfHost = SimSettings.getInstance().getNumOfEdgeHosts();
|
||||
double totalUtlization = 0;
|
||||
double[] edgeUtilizations = new double[numberOfHost];
|
||||
for(int hostIndex=0; hostIndex<numberOfHost; hostIndex++){
|
||||
List<EdgeVM> vmArray = SimManager.getInstance().getEdgeServerManager().getVmList(hostIndex);
|
||||
|
||||
double utilization=0;
|
||||
for(int vmIndex=0; vmIndex<vmArray.size(); vmIndex++){
|
||||
utilization += vmArray.get(vmIndex).getCloudletScheduler().getTotalUtilizationOfCpu(CloudSim.clock());
|
||||
}
|
||||
totalUtlization += utilization;
|
||||
|
||||
edgeUtilizations[hostIndex] = utilization / (double)(vmArray.size());
|
||||
}
|
||||
|
||||
double avgEdgeUtilization = totalUtlization / SimSettings.getInstance().getNumOfEdgeVMs();
|
||||
|
||||
trainerMap.put(id,
|
||||
new TrainerItem(selectedDatacenter,
|
||||
numOffloadedTasks, avgEdgeUtilization,
|
||||
wanUploadDelay, wanDownloadDelay,
|
||||
gsmUploadDelay, gsmDownloadDelay,
|
||||
wlanUploadDelay, wlanDownloadDelay
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public synchronized void addSuccessStat(Task task, double serviceTime) {
|
||||
TrainerItem trainerItem = trainerMap.remove(task.getCloudletId());
|
||||
saveStat(trainerItem, task, true, serviceTime);
|
||||
}
|
||||
|
||||
public synchronized void addFailStat(Task task) {
|
||||
TrainerItem trainerItem = trainerMap.remove(task.getCloudletId());
|
||||
saveStat(trainerItem, task, false, 0);
|
||||
}
|
||||
|
||||
public synchronized void addOffloadStat(int datacenterIdx) {
|
||||
double time = CloudSim.clock();
|
||||
for (Iterator<Double> 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();
|
||||
}
|
||||
}
|
55
src/edu/boun/edgecloudsim/applications/sample_app5/README.md
Normal file
55
src/edu/boun/edgecloudsim/applications/sample_app5/README.md
Normal file
@ -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.
|
||||
|
||||
<p align="center">
|
||||
<img src="/doc/images/sample_app5/vec_architecture.png" width="65%">
|
||||
<p align="center">
|
||||
Figure 1: Multi-tier VEC architecture for vehicular networks..
|
||||
</p>
|
||||
</p>
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
<p align="center">
|
||||
<img src="/doc/images/sample_app5/ml_stages.png" width="65%">
|
||||
<p align="center">
|
||||
Figure 2: Two stage ML-based vehicular edge orchestrator.
|
||||
</p>
|
||||
</p>
|
||||
|
||||
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.
|
||||
|
||||
<p align="center">
|
||||
<img src="/doc/images/sample_app5/ml_details.png" width="60%">
|
||||
<p align="center">
|
||||
Figure 3: Demonstrative example of the ML-based orchestrator stages.
|
||||
</p>
|
||||
</p>
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
<p align="center">
|
||||
<img src="/doc/images/sample_app5/road.png" width="50%">
|
||||
<p align="center">
|
||||
Figure 4: Vehicular mobility model in the simulation.
|
||||
</p>
|
||||
</p>
|
||||
|
||||
|
||||
## 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.
|
@ -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];
|
||||
}
|
||||
}
|
@ -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<probabilities.length; i++) {
|
||||
if(randomNumber <= probabilities[i] + lastPercentagte) {
|
||||
result = options[i];
|
||||
resultFound = true;
|
||||
break;
|
||||
}
|
||||
lastPercentagte += probabilities[i];
|
||||
}
|
||||
|
||||
if(!resultFound) {
|
||||
SimLogger.printLine("Unexpected probability calculation! Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
else if(predictedServiceTimeForEdge <= Math.min(predictedServiceTimeForCloudViaRSU, predictedServiceTimeForCloudViaGSM))
|
||||
result = EDGE_DATACENTER;
|
||||
else if(predictedServiceTimeForCloudViaRSU <= Math.min(predictedServiceTimeForEdge, predictedServiceTimeForCloudViaGSM))
|
||||
result = CLOUD_DATACENTER_VIA_RSU;
|
||||
else if(predictedServiceTimeForCloudViaGSM <= Math.min(predictedServiceTimeForEdge, predictedServiceTimeForCloudViaRSU))
|
||||
result = CLOUD_DATACENTER_VIA_GSM;
|
||||
else{
|
||||
SimLogger.printLine("Impossible occurred in AI based algorithm! Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
trainerLogger.addOffloadStat(result-1);
|
||||
}
|
||||
else if (policy.equals("AI_TRAINER")) {
|
||||
double probabilities[] = null;
|
||||
if(task.getTaskType() == 0)
|
||||
probabilities = new double[] {0.60, 0.23, 0.17};
|
||||
else if(task.getTaskType() == 1)
|
||||
probabilities = new double[] {0.30, 0.53, 0.17};
|
||||
else
|
||||
probabilities = new double[] {0.23, 0.60, 0.17};
|
||||
|
||||
double randomNumber = SimUtils.getRandomDoubleNumber(0, 1);
|
||||
double lastPercentagte = 0;
|
||||
boolean resultFound = false;
|
||||
for(int i=0; i<probabilities.length; i++) {
|
||||
if(randomNumber <= probabilities[i] + lastPercentagte) {
|
||||
result = options[i];
|
||||
resultFound = true;
|
||||
|
||||
trainerLogger.addStat(task.getCloudletId(), result,
|
||||
wanUploadDelay, wanDownloadDelay,
|
||||
gsmUploadDelay, gsmDownloadDelay,
|
||||
wlanUploadDelay, wlanDownloadDelay);
|
||||
|
||||
break;
|
||||
}
|
||||
lastPercentagte += probabilities[i];
|
||||
}
|
||||
|
||||
if(!resultFound) {
|
||||
SimLogger.printLine("Unexpected probability calculation for AI based orchestrator! Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
else if(policy.equals("RANDOM")){
|
||||
double probabilities[] = {0.33, 0.33, 0.34};
|
||||
|
||||
double randomNumber = SimUtils.getRandomDoubleNumber(0, 1);
|
||||
double lastPercentagte = 0;
|
||||
boolean resultFound = false;
|
||||
for(int i=0; i<probabilities.length; i++) {
|
||||
if(randomNumber <= probabilities[i] + lastPercentagte) {
|
||||
result = options[i];
|
||||
resultFound = true;
|
||||
break;
|
||||
}
|
||||
lastPercentagte += probabilities[i];
|
||||
}
|
||||
|
||||
if(!resultFound) {
|
||||
SimLogger.printLine("Unexpected probability calculation for random orchestrator! Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
else if (policy.equals("MAB")) {
|
||||
if(!MAB.isInitialized()){
|
||||
double expectedProcessingDealyOnCloud = task.getCloudletLength() /
|
||||
SimSettings.getInstance().getMipsForCloudVM();
|
||||
|
||||
//All Edge VMs are identical, just get MIPS value from the first VM
|
||||
double expectedProcessingDealyOnEdge = task.getCloudletLength() /
|
||||
SimManager.getInstance().getEdgeServerManager().getVmList(0).get(0).getMips();
|
||||
|
||||
double[] expectedDelays = {
|
||||
wlanUploadDelay + wlanDownloadDelay + expectedProcessingDealyOnEdge,
|
||||
wanUploadDelay + wanDownloadDelay + expectedProcessingDealyOnCloud,
|
||||
gsmUploadDelay + gsmDownloadDelay + expectedProcessingDealyOnCloud
|
||||
};
|
||||
|
||||
MAB.initialize(expectedDelays, task.getCloudletLength());
|
||||
}
|
||||
|
||||
result = options[MAB.runUCB(task.getCloudletLength())];
|
||||
}
|
||||
else if (policy.equals("GAME_THEORY")) {
|
||||
//All Edge VMs are identical, just get MIPS value from the first VM
|
||||
double expectedProcessingDealyOnEdge = task.getCloudletLength() /
|
||||
SimManager.getInstance().getEdgeServerManager().getVmList(0).get(0).getMips();
|
||||
|
||||
expectedProcessingDealyOnEdge *= 100 / (100 - avgEdgeUtilization);
|
||||
|
||||
double expectedEdgeDelay = expectedProcessingDealyOnEdge +
|
||||
wlanUploadDelay + wlanDownloadDelay;
|
||||
|
||||
|
||||
double expectedProcessingDealyOnCloud = task.getCloudletLength() /
|
||||
SimSettings.getInstance().getMipsForCloudVM();
|
||||
|
||||
expectedProcessingDealyOnCloud *= 100 / (100 - avgCloudUtilization);
|
||||
|
||||
boolean isGsmFaster = SimUtils.getRandomDoubleNumber(0, 1) < 0.5;
|
||||
double expectedCloudDelay = expectedProcessingDealyOnCloud +
|
||||
(isGsmFaster ? gsmUploadDelay : wanUploadDelay) +
|
||||
(isGsmFaster ? gsmDownloadDelay : wanDownloadDelay);
|
||||
|
||||
double taskArrivalRate = SimSettings.getInstance().getTaskLookUpTable()[task.getTaskType()][2];
|
||||
double maxDelay = SimSettings.getInstance().getTaskLookUpTable()[task.getTaskType()][13] * (double)6;
|
||||
|
||||
double Pi = GTH.getPi(task.getMobileDeviceId(), taskArrivalRate, expectedEdgeDelay, expectedCloudDelay, maxDelay);
|
||||
|
||||
double randomNumber = SimUtils.getRandomDoubleNumber(0, 1);
|
||||
|
||||
if(Pi < randomNumber)
|
||||
result = EDGE_DATACENTER;
|
||||
else
|
||||
result = (isGsmFaster ? CLOUD_DATACENTER_VIA_GSM : CLOUD_DATACENTER_VIA_RSU);
|
||||
}
|
||||
else if (policy.equals("PREDICTIVE")) {
|
||||
//initial probability of different computing paradigms
|
||||
double probabilities[] = {0.34, 0.33, 0.33};
|
||||
|
||||
//do not use predictive offloading during warm-up period
|
||||
if(CloudSim.clock() > 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<probabilities.length; i++) {
|
||||
/*
|
||||
* failureRateScore_i = 1 / (failureRate_i / sum(failureRate))
|
||||
* failureRateScore_i = sum(failureRate) / failureRate_i
|
||||
*/
|
||||
failureRateScores[i] = DoubleStream.of(failureRates).sum() / failureRates[i];
|
||||
/*
|
||||
* serviceTimeScore_i = 1 / (serviceTime_i / sum(serviceTime))
|
||||
* serviceTimeScore_i = sum(serviceTime) / serviceTime_i
|
||||
*/
|
||||
serviceTimeScores[i] = DoubleStream.of(serviceTimes).sum() / serviceTimes[i];
|
||||
}
|
||||
|
||||
for(int i=0; i<probabilities.length; i++) {
|
||||
if(DoubleStream.of(failureRates).sum() > 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<probabilities.length; i++) {
|
||||
if(randomNumber <= probabilities[i] + lastPercentagte) {
|
||||
result = options[i];
|
||||
resultFound = true;
|
||||
break;
|
||||
}
|
||||
lastPercentagte += probabilities[i];
|
||||
}
|
||||
|
||||
if(!resultFound) {
|
||||
SimLogger.printLine("Unexpected probability calculation for predictive orchestrator! Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
SimLogger.printLine("Unknow edge orchestrator policy! Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vm getVmToOffload(Task task, int deviceId) {
|
||||
Vm selectedVM = null;
|
||||
|
||||
if (deviceId == CLOUD_DATACENTER_VIA_GSM || deviceId == CLOUD_DATACENTER_VIA_RSU) {
|
||||
int numOfCloudHosts = SimSettings.getInstance().getNumOfCloudHost();
|
||||
int hostIndex = (cloudVmCounter / numOfCloudHosts) % numOfCloudHosts;
|
||||
int vmIndex = cloudVmCounter % SimSettings.getInstance().getNumOfCloudVMsPerHost();;
|
||||
|
||||
selectedVM = SimManager.getInstance().getCloudServerManager().getVmList(hostIndex).get(vmIndex);
|
||||
|
||||
cloudVmCounter++;
|
||||
cloudVmCounter = cloudVmCounter % SimSettings.getInstance().getNumOfCloudVMs();
|
||||
|
||||
}
|
||||
else if (deviceId == EDGE_DATACENTER) {
|
||||
int numOfEdgeVMs = SimSettings.getInstance().getNumOfEdgeVMs();
|
||||
int numOfEdgeHosts = SimSettings.getInstance().getNumOfEdgeHosts();
|
||||
int vmPerHost = numOfEdgeVMs / numOfEdgeHosts;
|
||||
|
||||
int hostIndex = (edgeVmCounter / vmPerHost) % numOfEdgeHosts;
|
||||
int vmIndex = edgeVmCounter % vmPerHost;
|
||||
|
||||
selectedVM = SimManager.getInstance().getEdgeServerManager().getVmList(hostIndex).get(vmIndex);
|
||||
|
||||
edgeVmCounter++;
|
||||
edgeVmCounter = edgeVmCounter % numOfEdgeVMs;
|
||||
}
|
||||
else {
|
||||
SimLogger.printLine("Unknow device id! Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
return selectedVM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startEntity() {
|
||||
if(policy.equals("PREDICTIVE")) {
|
||||
schedule(getId(), SimSettings.CLIENT_ACTIVITY_START_TIME +
|
||||
OrchestratorStatisticLogger.PREDICTION_WINDOW_UPDATE_INTERVAL,
|
||||
UPDATE_PREDICTION_WINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdownEntity() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void processEvent(SimEvent ev) {
|
||||
if (ev == null) {
|
||||
SimLogger.printLine(getName() + ".processOtherEvent(): " + "Error - an event is null! Terminating simulation...");
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ev.getTag()) {
|
||||
case UPDATE_PREDICTION_WINDOW:
|
||||
{
|
||||
statisticLogger.switchNewStatWindow();
|
||||
schedule(getId(), OrchestratorStatisticLogger.PREDICTION_WINDOW_UPDATE_INTERVAL,
|
||||
UPDATE_PREDICTION_WINDOW);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SimLogger.printLine(getName() + ": unknown event type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void processOtherEvent(SimEvent ev) {
|
||||
if (ev == null) {
|
||||
SimLogger.printLine(getName() + ".processOtherEvent(): " + "Error - an event is null! Terminating simulation...");
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void taskCompleted(Task task, double serviceTime) {
|
||||
if(policy.equals("AI_TRAINER"))
|
||||
trainerLogger.addSuccessStat(task, serviceTime);
|
||||
|
||||
if(policy.equals("PREDICTIVE"))
|
||||
statisticLogger.addSuccessStat(task, serviceTime);
|
||||
|
||||
if(policy.equals("MAB"))
|
||||
MAB.updateUCB(task, serviceTime);
|
||||
}
|
||||
|
||||
public void taskFailed(Task task) {
|
||||
if(policy.equals("AI_TRAINER"))
|
||||
trainerLogger.addFailStat(task);
|
||||
|
||||
if(policy.equals("PREDICTIVE"))
|
||||
statisticLogger.addFailStat(task);
|
||||
|
||||
if(policy.equals("MAB"))
|
||||
MAB.updateUCB(task, 0);
|
||||
}
|
||||
|
||||
public void openTrainerOutputFile() {
|
||||
trainerLogger.openTrainerOutputFile();
|
||||
}
|
||||
|
||||
public void closeTrainerOutputFile() {
|
||||
trainerLogger.closeTrainerOutputFile();
|
||||
}
|
||||
}
|
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Title: EdgeCloudSim - Edge Server Manager
|
||||
*
|
||||
* Description:
|
||||
* VehicularEdgeServerManager is responsible for creating
|
||||
* Edge datacenters and hosts/VMs running on it.
|
||||
*
|
||||
* 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 org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import edu.boun.edgecloudsim.core.SimManager;
|
||||
import edu.boun.edgecloudsim.core.SimSettings;
|
||||
import edu.boun.edgecloudsim.edge_server.EdgeHost;
|
||||
import edu.boun.edgecloudsim.edge_server.EdgeServerManager;
|
||||
import edu.boun.edgecloudsim.edge_server.EdgeVM;
|
||||
import edu.boun.edgecloudsim.edge_server.EdgeVmAllocationPolicy_Custom;
|
||||
import edu.boun.edgecloudsim.utils.Location;
|
||||
|
||||
public class VehicularEdgeServerManager extends EdgeServerManager{
|
||||
private int hostIdCounter;
|
||||
|
||||
public VehicularEdgeServerManager() {
|
||||
hostIdCounter = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public VmAllocationPolicy getVmAllocationPolicy(List<? extends Host> 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<EdgeVM>());
|
||||
|
||||
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<localDatacenters.size(); i++) {
|
||||
List<? extends Host> list = localDatacenters.get(i).getHostList();
|
||||
// for each host...
|
||||
for (int hostIndex=0; hostIndex < list.size(); hostIndex++) {
|
||||
List<EdgeVM> vmArray = SimManager.getInstance().getEdgeServerManager().getVmList(hostCounter);
|
||||
//for each vm...
|
||||
for(int vmIndex=0; vmIndex<vmArray.size(); vmIndex++){
|
||||
totalUtilization += vmArray.get(vmIndex).getCloudletScheduler().getTotalUtilizationOfCpu(CloudSim.clock());
|
||||
vmCounter++;
|
||||
}
|
||||
hostCounter++;
|
||||
}
|
||||
}
|
||||
return totalUtilization / (double)vmCounter;
|
||||
}
|
||||
|
||||
private Datacenter createDatacenter(int index, Element datacenterElement) throws Exception{
|
||||
String arch = datacenterElement.getAttribute("arch");
|
||||
String os = datacenterElement.getAttribute("os");
|
||||
String vmm = datacenterElement.getAttribute("vmm");
|
||||
double costPerBw = Double.parseDouble(datacenterElement.getElementsByTagName("costPerBw").item(0).getTextContent());
|
||||
double costPerSec = Double.parseDouble(datacenterElement.getElementsByTagName("costPerSec").item(0).getTextContent());
|
||||
double costPerMem = Double.parseDouble(datacenterElement.getElementsByTagName("costPerMem").item(0).getTextContent());
|
||||
double costPerStorage = Double.parseDouble(datacenterElement.getElementsByTagName("costPerStorage").item(0).getTextContent());
|
||||
|
||||
List<EdgeHost> hostList=createHosts(datacenterElement);
|
||||
|
||||
String name = "EdgeDatacenter_" + Integer.toString(index);
|
||||
double time_zone = 3.0; // time zone this resource located
|
||||
LinkedList<Storage> storageList = new LinkedList<Storage>(); //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<EdgeHost> 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<EdgeHost> hostList = new ArrayList<EdgeHost>();
|
||||
|
||||
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<Pe> peList = new ArrayList<Pe>();
|
||||
|
||||
// 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<numOfCores; i++){
|
||||
peList.add(new Pe(i, new PeProvisionerSimple(mips))); // need to store Pe id and MIPS Rating
|
||||
}
|
||||
|
||||
//4. Create Hosts with its id and list of PEs and add them to the list of machines
|
||||
EdgeHost host = new EdgeHost(
|
||||
hostIdCounter,
|
||||
new RamProvisionerSimple(ram),
|
||||
new BwProvisionerSimple(bandwidth), //kbps
|
||||
storage,
|
||||
peList,
|
||||
new VmSchedulerSpaceShared(peList)
|
||||
);
|
||||
|
||||
host.setPlace(new Location(placeTypeIndex, wlan_id, x_pos, y_pos));
|
||||
hostList.add(host);
|
||||
hostIdCounter++;
|
||||
}
|
||||
|
||||
return hostList;
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package edu.boun.edgecloudsim.applications.sample_app5;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.apache.commons.math3.distribution.ExponentialDistribution;
|
||||
|
||||
import edu.boun.edgecloudsim.core.SimSettings;
|
||||
import edu.boun.edgecloudsim.task_generator.LoadGeneratorModel;
|
||||
import edu.boun.edgecloudsim.utils.TaskProperty;
|
||||
import edu.boun.edgecloudsim.utils.SimLogger;
|
||||
import edu.boun.edgecloudsim.utils.SimUtils;
|
||||
|
||||
public class VehicularLoadGenerator extends LoadGeneratorModel{
|
||||
int taskTypeOfDevices[];
|
||||
|
||||
public VehicularLoadGenerator(int _numberOfMobileDevices, double _simulationTime, String _simScenario) {
|
||||
super(_numberOfMobileDevices, _simulationTime, _simScenario);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initializeModel() {
|
||||
taskList = new ArrayList<TaskProperty>();
|
||||
|
||||
//Each mobile device utilizes an app type (task type)
|
||||
taskTypeOfDevices = new int[numberOfMobileDevices];
|
||||
for(int i=0; i<numberOfMobileDevices; i++) {
|
||||
int randomTaskType = -1;
|
||||
double taskTypeSelector = SimUtils.getRandomDoubleNumber(0,100);
|
||||
double taskTypePercentage = 0;
|
||||
for (int j=0; j<SimSettings.getInstance().getTaskLookUpTable().length; j++) {
|
||||
taskTypePercentage += SimSettings.getInstance().getTaskLookUpTable()[j][0];
|
||||
if(taskTypeSelector <= taskTypePercentage){
|
||||
randomTaskType = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(randomTaskType == -1){
|
||||
SimLogger.printLine("Impossible is occurred! no random task type!");
|
||||
continue;
|
||||
}
|
||||
|
||||
taskTypeOfDevices[i] = randomTaskType;
|
||||
|
||||
double poissonMean = SimSettings.getInstance().getTaskLookUpTable()[randomTaskType][2];
|
||||
double activePeriod = SimSettings.getInstance().getTaskLookUpTable()[randomTaskType][3];
|
||||
double idlePeriod = SimSettings.getInstance().getTaskLookUpTable()[randomTaskType][4];
|
||||
double activePeriodStartTime = SimUtils.getRandomDoubleNumber(
|
||||
SimSettings.CLIENT_ACTIVITY_START_TIME,
|
||||
SimSettings.CLIENT_ACTIVITY_START_TIME * 2); //active period starts shortly after the simulation started (e.g. 10 seconds)
|
||||
double virtualTime = activePeriodStartTime;
|
||||
|
||||
ExponentialDistribution rng = new ExponentialDistribution(poissonMean);
|
||||
//ExponentialDistribution rng[] = new ExponentialDistribution[10];
|
||||
//for(int j=0; j<10; j++)
|
||||
// rng[j] = new ExponentialDistribution(poissonMean * ((double)1 + (double)j * (double) 0.12));
|
||||
|
||||
while(virtualTime < simulationTime) {
|
||||
//int index = Math.min(9, (int)virtualTime / 15);
|
||||
//double interval = rng[9-index].sample();
|
||||
double interval = rng.sample();
|
||||
|
||||
if(interval <= 0){
|
||||
SimLogger.printLine("Impossible is occurred! interval is " + interval + " for device " + i + " time " + virtualTime);
|
||||
continue;
|
||||
}
|
||||
//SimLogger.printLine(virtualTime + " -> " + 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];
|
||||
}
|
||||
|
||||
}
|
@ -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<SS.getSimulationScenarios().length; s++)
|
||||
for(int p=0; p<SS.getOrchestratorPolicies().length; p++)
|
||||
mainHelper(outputFolder, SS.getSimulationScenarios()[s], SS.getOrchestratorPolicies()[p], iterationNumber, i);
|
||||
|
||||
Date SimulationEndDate = Calendar.getInstance().getTime();
|
||||
now = df.format(SimulationEndDate);
|
||||
SimLogger.printLine("Simulation finished at " + now + ". It took " + SimUtils.getTimeDifference(SimulationStartDate,SimulationEndDate));
|
||||
}
|
||||
|
||||
public static void mainHelper(String outputFolder, String simulationScenario, String orchestratorPolicy, int iterationNumber, int numOfMobileDevice){
|
||||
DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
|
||||
Date ScenarioStartDate = Calendar.getInstance().getTime();
|
||||
String now = df.format(ScenarioStartDate);
|
||||
SimSettings SS = SimSettings.getInstance();
|
||||
|
||||
SimLogger.printLine("Scenario started at " + now);
|
||||
SimLogger.printLine("Scenario: " + simulationScenario + " - Policy: " + orchestratorPolicy + " - #iteration: " + iterationNumber);
|
||||
SimLogger.printLine("Duration: " + SS.getSimulationTime()/60 + " min (warm up period: "+ SS.getWarmUpPeriod()/60 +" min) - #devices: " + numOfMobileDevice);
|
||||
SimLogger.getInstance().simStarted(outputFolder, "SIMRESULT_" + simulationScenario + "_" + orchestratorPolicy + "_" + numOfMobileDevice + "DEVICES");
|
||||
|
||||
try
|
||||
{
|
||||
// First step: Initialize the CloudSim package. It should be called
|
||||
// before creating any entities.
|
||||
int num_user = 2; // number of grid users
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
boolean trace_flag = false; // mean trace events
|
||||
|
||||
// Initialize the CloudSim library
|
||||
CloudSim.init(num_user, calendar, trace_flag, 0.01);
|
||||
|
||||
// Generate EdgeCloudsim Scenario Factory
|
||||
ScenarioFactory sampleFactory = new VehicularScenarioFactory(numOfMobileDevice, SS.getSimulationTime(), orchestratorPolicy, simulationScenario);
|
||||
|
||||
// Generate EdgeCloudSim Simulation Manager
|
||||
SimManager manager = new SimManager(sampleFactory, numOfMobileDevice, simulationScenario, orchestratorPolicy);
|
||||
|
||||
if(orchestratorPolicy.equals("AI_TRAINER")){
|
||||
SimLogger.disableFileLog();
|
||||
((VehicularEdgeOrchestrator)manager.getEdgeOrchestrator()).openTrainerOutputFile();
|
||||
}
|
||||
|
||||
// Start simulation
|
||||
manager.startSimulation();
|
||||
|
||||
//SimLogger.printLine("maxWanDelay: " + ((VehicularNetworkModel)manager.getNetworkModel()).maxWanDelay);
|
||||
//SimLogger.printLine("maxGsmDelay: " + ((VehicularNetworkModel)manager.getNetworkModel()).maxGsmDelay);
|
||||
//SimLogger.printLine("maxWlanDelay: " + ((VehicularNetworkModel)manager.getNetworkModel()).maxWlanDelay);
|
||||
|
||||
if(orchestratorPolicy.equals("AI_TRAINER"))
|
||||
((VehicularEdgeOrchestrator)manager.getEdgeOrchestrator()).closeTrainerOutputFile();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
SimLogger.printLine("The simulation has been terminated due to an unexpected error");
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Date ScenarioEndDate = Calendar.getInstance().getTime();
|
||||
now = df.format(ScenarioEndDate);
|
||||
SimLogger.printLine("Scenario finished at " + now + ". It took " + SimUtils.getTimeDifference(ScenarioStartDate,ScenarioEndDate));
|
||||
SimLogger.printLine("----------------------------------------------------------------------");
|
||||
|
||||
//suggest garbage collector to run in order to decrease heap memory
|
||||
System.gc();
|
||||
}//End of scenarios loop
|
||||
}
|
@ -0,0 +1,569 @@
|
||||
/*
|
||||
* Title: EdgeCloudSim - Mobile Device Manager
|
||||
*
|
||||
* Description:
|
||||
* VehicularMobileDeviceManager is responsible for submitting the tasks to the related
|
||||
* device by using the VehicularEdgeOrchestrator. It also takes proper actions
|
||||
* when the execution of the tasks are finished.
|
||||
*
|
||||
* 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.List;
|
||||
|
||||
import org.cloudbus.cloudsim.Host;
|
||||
import org.cloudbus.cloudsim.UtilizationModel;
|
||||
import org.cloudbus.cloudsim.UtilizationModelFull;
|
||||
import org.cloudbus.cloudsim.Vm;
|
||||
import org.cloudbus.cloudsim.core.CloudSim;
|
||||
import org.cloudbus.cloudsim.core.CloudSimTags;
|
||||
import org.cloudbus.cloudsim.core.SimEvent;
|
||||
|
||||
import edu.boun.edgecloudsim.applications.sample_app5.VehicularEdgeOrchestrator;
|
||||
import edu.boun.edgecloudsim.cloud_server.CloudVM;
|
||||
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.core.SimSettings.VM_TYPES;
|
||||
import edu.boun.edgecloudsim.edge_client.MobileDeviceManager;
|
||||
import edu.boun.edgecloudsim.edge_client.Task;
|
||||
import edu.boun.edgecloudsim.edge_server.EdgeHost;
|
||||
import edu.boun.edgecloudsim.edge_server.EdgeVM;
|
||||
import edu.boun.edgecloudsim.utils.TaskProperty;
|
||||
import edu.boun.edgecloudsim.utils.Location;
|
||||
import edu.boun.edgecloudsim.utils.SimLogger;
|
||||
|
||||
public class VehicularMobileDeviceManager extends MobileDeviceManager {
|
||||
private static final int BASE = 100000; //start from base in order not to conflict cloudsim tag!
|
||||
private static final int UPDATE_MM1_QUEUE_MODEL = BASE + 1;
|
||||
private static final int SET_DELAY_LOG = BASE + 2;
|
||||
private static final int READY_TO_SELECT_VM = BASE + 3;
|
||||
private static final int REQUEST_RECEIVED_BY_CLOUD = BASE + 4;
|
||||
private static final int REQUEST_RECEIVED_BY_MOBILE_DEVICE = BASE + 5;
|
||||
private static final int REQUEST_RECEIVED_BY_EDGE_DEVICE = BASE + 6;
|
||||
private static final int REQUEST_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_CLOUD = BASE + 7;
|
||||
private static final int REQUEST_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_NEIGHBOR = BASE + 8;
|
||||
private static final int RESPONSE_RECEIVED_BY_MOBILE_DEVICE = BASE + 9;
|
||||
private static final int RESPONSE_RECEIVED_BY_EDGE_DEVICE = BASE + 10;
|
||||
private static final int RESPONSE_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_MOBILE_DEVICE = BASE + 11;
|
||||
|
||||
private static final double MM1_QUEUE_MODEL_UPDATE_INTERVAL = 0.5; //seconds
|
||||
private int taskIdCounter=0;
|
||||
|
||||
public VehicularMobileDeviceManager() throws Exception{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public UtilizationModel getCpuUtilizationModel() {
|
||||
return new VehicularCpuUtilizationModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startEntity() {
|
||||
super.startEntity();
|
||||
schedule(getId(), SimSettings.CLIENT_ACTIVITY_START_TIME +
|
||||
MM1_QUEUE_MODEL_UPDATE_INTERVAL, UPDATE_MM1_QUEUE_MODEL);
|
||||
|
||||
if(SimSettings.getInstance().getApDelayLogInterval() != 0)
|
||||
schedule(getId(), SimSettings.getInstance().getApDelayLogInterval(), SET_DELAY_LOG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit cloudlets to the created VMs.
|
||||
*
|
||||
* @pre $none
|
||||
* @post $none
|
||||
*/
|
||||
protected void submitCloudlets() {
|
||||
//do nothing!
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a cloudlet return event.
|
||||
*
|
||||
* @param ev a SimEvent object
|
||||
* @pre ev != $null
|
||||
* @post $none
|
||||
*/
|
||||
protected void processCloudletReturn(SimEvent ev) {
|
||||
VehicularNetworkModel networkModel = (VehicularNetworkModel)SimManager.getInstance().getNetworkModel();
|
||||
VehicularEdgeOrchestrator edgeOrchestrator = (VehicularEdgeOrchestrator)SimManager.getInstance().getEdgeOrchestrator();
|
||||
|
||||
Task task = (Task) ev.getData();
|
||||
|
||||
SimLogger.getInstance().taskExecuted(task.getCloudletId());
|
||||
|
||||
if(task.getAssociatedDatacenterId() == VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_GSM) {
|
||||
NETWORK_DELAY_TYPES delayType = NETWORK_DELAY_TYPES.GSM_DELAY;
|
||||
double gsmDelay = networkModel.getDownloadDelay(delayType, task);
|
||||
if(gsmDelay > 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; i<indices.length; i++){
|
||||
apUploadDelays[i] = networkModel.estimateWlanUploadDelay(indices[i]);
|
||||
apDownloadDelays[i] = networkModel.estimateWlanDownloadDelay(indices[i]);
|
||||
}
|
||||
SimLogger.getInstance().addApDelayLog(CloudSim.clock(), apUploadDelays, apDownloadDelays);
|
||||
|
||||
schedule(getId(), SimSettings.getInstance().getVmLoadLogInterval(), SET_DELAY_LOG);
|
||||
break;
|
||||
}
|
||||
case READY_TO_SELECT_VM:
|
||||
{
|
||||
Task task = (Task) ev.getData();
|
||||
|
||||
int nextHopId = task.getAssociatedDatacenterId();
|
||||
int nextEvent = 0;
|
||||
VM_TYPES vmType = null;
|
||||
|
||||
if(nextHopId == VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_GSM){
|
||||
nextEvent = REQUEST_RECEIVED_BY_CLOUD;
|
||||
vmType = VM_TYPES.CLOUD_VM;
|
||||
}
|
||||
//task is sent to cloud over RSU via 2 hops
|
||||
else if(nextHopId == VehicularEdgeOrchestrator.CLOUD_DATACENTER_VIA_RSU){
|
||||
nextEvent = REQUEST_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_CLOUD;
|
||||
vmType = VM_TYPES.CLOUD_VM;
|
||||
}
|
||||
//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;
|
||||
}
|
||||
else {
|
||||
SimLogger.printLine("Unknown nextHopId! Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
Vm selectedVM = SimManager.getInstance().getEdgeOrchestrator().getVmToOffload(task, nextHopId);
|
||||
|
||||
if(selectedVM != null) {
|
||||
//set related host id
|
||||
task.setAssociatedHostId(selectedVM.getHost().getId());
|
||||
|
||||
//set related vm id
|
||||
task.setAssociatedVmId(selectedVM.getId());
|
||||
|
||||
//bind task to related VM
|
||||
getCloudletList().add(task);
|
||||
bindCloudletToVm(task.getCloudletId(), selectedVM.getId());
|
||||
getCloudletList().clear();
|
||||
|
||||
if(selectedVM instanceof EdgeVM) {
|
||||
EdgeHost host = (EdgeHost)(selectedVM.getHost());
|
||||
|
||||
//if nearest edge device is selected
|
||||
if(host.getLocation().getServingWlanId() == task.getSubmittedLocation().getServingWlanId())
|
||||
nextEvent = REQUEST_RECEIVED_BY_EDGE_DEVICE;
|
||||
else
|
||||
nextEvent = REQUEST_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_NEIGHBOR;
|
||||
}
|
||||
|
||||
scheduleNow(getId(), nextEvent, task);
|
||||
}
|
||||
else {
|
||||
//SimLogger.printLine("Task #" + task.getCloudletId() + " cannot assign to any VM");
|
||||
SimLogger.getInstance().rejectedDueToVMCapacity(task.getCloudletId(), CloudSim.clock(), vmType.ordinal());
|
||||
edgeOrchestrator.taskFailed(task);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case REQUEST_RECEIVED_BY_CLOUD:
|
||||
{
|
||||
Task task = (Task) ev.getData();
|
||||
submitTaskToVm(task, SimSettings.VM_TYPES.CLOUD_VM);
|
||||
break;
|
||||
}
|
||||
case REQUEST_RECEIVED_BY_EDGE_DEVICE:
|
||||
{
|
||||
Task task = (Task) ev.getData();
|
||||
submitTaskToVm(task, SimSettings.VM_TYPES.EDGE_VM);
|
||||
break;
|
||||
}
|
||||
case REQUEST_RECEIVED_BY_MOBILE_DEVICE:
|
||||
{
|
||||
Task task = (Task) ev.getData();
|
||||
submitTaskToVm(task, SimSettings.VM_TYPES.MOBILE_VM);
|
||||
break;
|
||||
}
|
||||
case REQUEST_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_CLOUD:
|
||||
{
|
||||
Task task = (Task) ev.getData();
|
||||
NETWORK_DELAY_TYPES delayType = NETWORK_DELAY_TYPES.WAN_DELAY;
|
||||
|
||||
double wanDelay = networkModel.getUploadDelay(delayType, task);
|
||||
if(wanDelay>0){
|
||||
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<EdgeVM> 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<Host> list = SimManager.getInstance().getCloudServerManager().getDatacenter().getHostList();
|
||||
for (int hostIndex = 0; hostIndex < list.size(); hostIndex++) {
|
||||
List<CloudVM> 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;
|
||||
}
|
||||
}
|
@ -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<? extends Host> 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<MobileVM>());
|
||||
|
||||
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<? extends Host> list = localDatacenter.getHostList();
|
||||
// for each host...
|
||||
for (int hostIndex=0; hostIndex < list.size(); hostIndex++) {
|
||||
List<MobileVM> vmArray = SimManager.getInstance().getMobileServerManager().getVmList(hostIndex);
|
||||
//for each vm...
|
||||
for(int vmIndex=0; vmIndex<vmArray.size(); vmIndex++){
|
||||
totalUtilization += vmArray.get(vmIndex).getCloudletScheduler().getTotalUtilizationOfCpu(CloudSim.clock());
|
||||
vmCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
return totalUtilization / vmCounter;
|
||||
}
|
||||
|
||||
|
||||
private Datacenter createDatacenter(int index) throws Exception{
|
||||
String arch = "x86";
|
||||
String os = "Linux";
|
||||
String vmm = "Xen";
|
||||
double costPerBw = 0;
|
||||
double costPerSec = 0;
|
||||
double costPerMem = 0;
|
||||
double costPerStorage = 0;
|
||||
|
||||
List<MobileHost> hostList=createHosts();
|
||||
|
||||
String name = "MobileDatacenter_" + Integer.toString(index);
|
||||
double time_zone = 3.0; // time zone this resource located
|
||||
LinkedList<Storage> storageList = new LinkedList<Storage>(); //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<MobileHost> createHosts(){
|
||||
// Here are the steps needed to create a PowerDatacenter:
|
||||
// 1. We need to create a list to store one or more Machines
|
||||
List<MobileHost> hostList = new ArrayList<MobileHost>();
|
||||
|
||||
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<Pe> peList = new ArrayList<Pe>();
|
||||
|
||||
// 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<numOfCores; j++){
|
||||
peList.add(new Pe(j, new PeProvisionerSimple(mips))); // need to store Pe id and MIPS Rating
|
||||
}
|
||||
|
||||
//4. Create Hosts with its id and list of PEs and add them to the list of machines
|
||||
MobileHost host = new MobileHost(
|
||||
//Hosts should have unique IDs, so create Mobile Hosts after Edge+Cloud Hosts
|
||||
i+SimSettings.getInstance().getNumOfEdgeHosts()+SimSettings.getInstance().getNumOfCloudHost(),
|
||||
new RamProvisionerSimple(ram),
|
||||
new BwProvisionerSimple(bandwidth), //kbps
|
||||
storage,
|
||||
peList,
|
||||
new VmSchedulerSpaceShared(peList)
|
||||
);
|
||||
|
||||
host.setMobileDeviceId(i);
|
||||
hostList.add(host);
|
||||
}
|
||||
|
||||
return hostList;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Title: EdgeCloudSim - Mobility model implementation
|
||||
*
|
||||
* Description:
|
||||
* VehicularMobilityModel implements basic vehicular mobility model
|
||||
*
|
||||
* 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.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import edu.boun.edgecloudsim.core.SimSettings;
|
||||
import edu.boun.edgecloudsim.mobility.MobilityModel;
|
||||
import edu.boun.edgecloudsim.utils.Location;
|
||||
import edu.boun.edgecloudsim.utils.SimUtils;
|
||||
|
||||
public class VehicularMobilityModel extends MobilityModel {
|
||||
private final double SPEED_FOR_PLACES[] = {20, 40, 60}; //km per hour
|
||||
|
||||
private int lengthOfSegment;
|
||||
private double totalTimeForLoop; //seconds
|
||||
private int[] locationTypes;
|
||||
|
||||
//prepare following arrays to decrease computation on getLocation() function
|
||||
//NOTE: if the number of clients is high, keeping following values in RAM
|
||||
// may be expensive. In that case sacrifice computational resources!
|
||||
private int[] initialLocationIndexArray;
|
||||
private int[] initialPositionArray; //in meters unit
|
||||
private double[] timeToDriveLocationArray;//in seconds unit
|
||||
private double[] timeToReachNextLocationArray; //in seconds unit
|
||||
|
||||
public VehicularMobilityModel(int _numberOfMobileDevices, double _simulationTime) {
|
||||
super(_numberOfMobileDevices, _simulationTime);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
//Find total length of the road
|
||||
Document doc = SimSettings.getInstance().getEdgeDevicesDocument();
|
||||
NodeList datacenterList = doc.getElementsByTagName("datacenter");
|
||||
Element location = (Element)((Element)datacenterList.item(0)).getElementsByTagName("location").item(0);
|
||||
int x_pos = Integer.parseInt(location.getElementsByTagName("x_pos").item(0).getTextContent());
|
||||
lengthOfSegment = x_pos * 2; //assume that all segments have the same length
|
||||
int totalLengthOfRoad = lengthOfSegment * datacenterList.getLength();
|
||||
|
||||
//prepare locationTypes array to store attractiveness level of the locations
|
||||
locationTypes = new int[datacenterList.getLength()];
|
||||
timeToDriveLocationArray = new double[datacenterList.getLength()];
|
||||
for(int i=0; i<datacenterList.getLength(); i++) {
|
||||
Node datacenterNode = datacenterList.item(i);
|
||||
Element datacenterElement = (Element) datacenterNode;
|
||||
Element locationElement = (Element)datacenterElement.getElementsByTagName("location").item(0);
|
||||
locationTypes[i] = Integer.parseInt(locationElement.getElementsByTagName("attractiveness").item(0).getTextContent());
|
||||
|
||||
//(3600 * lengthOfSegment) / (SPEED_FOR_PLACES[x] * 1000);
|
||||
timeToDriveLocationArray[i] = ((double)3.6 * (double)lengthOfSegment) /
|
||||
(SPEED_FOR_PLACES[locationTypes[i]]);
|
||||
|
||||
//find the time required to loop in the road
|
||||
totalTimeForLoop += timeToDriveLocationArray[i];
|
||||
}
|
||||
|
||||
//assign a random x position as an initial position for each device
|
||||
initialPositionArray = new int[numberOfMobileDevices];
|
||||
initialLocationIndexArray = new int[numberOfMobileDevices];
|
||||
timeToReachNextLocationArray = new double[numberOfMobileDevices];
|
||||
for(int i=0; i<numberOfMobileDevices; i++) {
|
||||
initialPositionArray[i] = SimUtils.getRandomNumber(0, totalLengthOfRoad-1);
|
||||
initialLocationIndexArray[i] = initialPositionArray[i] / lengthOfSegment;
|
||||
timeToReachNextLocationArray[i] = ((double)3.6 *
|
||||
(double)(lengthOfSegment - (initialPositionArray[i] % lengthOfSegment))) /
|
||||
(SPEED_FOR_PLACES[locationTypes[initialLocationIndexArray[i]]]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation(int deviceId, double time) {
|
||||
int ofset = 0;
|
||||
double remainingTime = 0;
|
||||
|
||||
int locationIndex = initialLocationIndexArray[deviceId];
|
||||
double timeToReachNextLocation = timeToReachNextLocationArray[deviceId];
|
||||
|
||||
if(time < timeToReachNextLocation){
|
||||
ofset = initialPositionArray[deviceId];
|
||||
remainingTime = time;
|
||||
}
|
||||
else{
|
||||
remainingTime = (time - timeToReachNextLocation) % totalTimeForLoop;
|
||||
locationIndex = (locationIndex+1) % locationTypes.length;
|
||||
|
||||
while(remainingTime > 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);
|
||||
}
|
||||
|
||||
}
|
@ -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<numOfAccessPoint; apIndex++) {
|
||||
wlanMMPPForDownload[apIndex] = new MMPPWrapper();
|
||||
wlanMMPPForUpload[apIndex] = new MMPPWrapper();
|
||||
}
|
||||
|
||||
manMMPPForDownload = new MMPPWrapper();
|
||||
manMMPPForUpload = new MMPPWrapper();
|
||||
|
||||
wanMMPPForDownload = new MMPPWrapper();
|
||||
wanMMPPForUpload = new MMPPWrapper();
|
||||
|
||||
gsmMMPPForDownload = new MMPPWrapper();
|
||||
gsmMMPPForUpload = new MMPPWrapper();
|
||||
|
||||
//Approximate usage of the access technologies for the first MMPP time slot
|
||||
double probOfWlanComm = 0.40;
|
||||
double probOfWanComm = 0.15;
|
||||
double probOfGsmComm = 0.10;
|
||||
double probOfManComm = 0.35;
|
||||
|
||||
double weightedTaskPerSecond = 0;
|
||||
double weightedTaskInputSize = 0;
|
||||
double weightedTaskOutputSize = 0;
|
||||
|
||||
//Calculate interarrival time and task sizes
|
||||
for(int taskIndex=0; taskIndex<numOfApp; taskIndex++) {
|
||||
double percentageOfAppUsage = SS.getTaskLookUpTable()[taskIndex][0];
|
||||
double poissonOfApp = SS.getTaskLookUpTable()[taskIndex][2];
|
||||
double taskInputSize = SS.getTaskLookUpTable()[taskIndex][5];
|
||||
double taskOutputSize = SS.getTaskLookUpTable()[taskIndex][6];
|
||||
|
||||
if(percentageOfAppUsage <= 0 && percentageOfAppUsage > 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<numOfAccessPoint; apIndex++) {
|
||||
double poisson = (double)1 / (weightedTaskPerSecond * (numberOfMobileDevices/numOfAccessPoint) * probOfWlanComm);
|
||||
wlanMMPPForDownload[apIndex].initializeMM1QueueValues(poisson, weightedTaskOutputSize, SimSettings.getInstance().getWlanBandwidth());
|
||||
wlanMMPPForUpload[apIndex].initializeMM1QueueValues(poisson, weightedTaskInputSize, SimSettings.getInstance().getWlanBandwidth());
|
||||
}
|
||||
|
||||
double poisson = (double)1 / (weightedTaskPerSecond * numberOfMobileDevices * probOfManComm);
|
||||
manMMPPForDownload.initializeMM1QueueValues(poisson, weightedTaskOutputSize, SimSettings.getInstance().getManBandwidth());
|
||||
manMMPPForUpload.initializeMM1QueueValues(poisson, weightedTaskInputSize, SimSettings.getInstance().getManBandwidth());
|
||||
|
||||
poisson = (double)1 / (weightedTaskPerSecond * numberOfMobileDevices * probOfWanComm);
|
||||
wanMMPPForDownload.initializeMM1QueueValues(poisson, weightedTaskOutputSize, SimSettings.getInstance().getWanBandwidth());
|
||||
wanMMPPForUpload.initializeMM1QueueValues(poisson, weightedTaskInputSize, SimSettings.getInstance().getWanBandwidth());
|
||||
|
||||
poisson = (double)1 / (weightedTaskPerSecond * numberOfMobileDevices * probOfGsmComm);
|
||||
gsmMMPPForDownload.initializeMM1QueueValues(poisson, weightedTaskOutputSize, SimSettings.getInstance().getGsmBandwidth());
|
||||
gsmMMPPForUpload.initializeMM1QueueValues(poisson, weightedTaskInputSize, SimSettings.getInstance().getGsmBandwidth());
|
||||
}
|
||||
|
||||
/**
|
||||
* source device is always mobile device in our simulation scenarios!
|
||||
*/
|
||||
@Override
|
||||
public double getUploadDelay(int sourceDeviceId, int destDeviceId, Task task) {
|
||||
SimLogger.printLine("getUploadDelay is not used in this scenario! Terminating simulation...");
|
||||
System.exit(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* destination device is always mobile device in our simulation scenarios!
|
||||
*/
|
||||
@Override
|
||||
public double getDownloadDelay(int sourceDeviceId, int destDeviceId, Task task) {
|
||||
SimLogger.printLine("getDownloadDelay is not used in this scenario! Terminating simulation...");
|
||||
System.exit(1);
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public void uploadStarted(Location accessPointLocation, int destDeviceId) {
|
||||
SimLogger.printLine("uploadStarted is not used in this scenario! Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadFinished(Location accessPointLocation, int destDeviceId) {
|
||||
SimLogger.printLine("uploadFinished is not used in this scenario! Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downloadStarted(Location accessPointLocation, int sourceDeviceId) {
|
||||
SimLogger.printLine("downloadStarted is not used in this scenario! Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downloadFinished(Location accessPointLocation, int sourceDeviceId) {
|
||||
SimLogger.printLine("downloadFinished is not used in this scenario! Terminating simulation...");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
public double estimateWlanDownloadDelay(int apId){
|
||||
return getWlanDownloadDelay(0,apId,true);
|
||||
}
|
||||
|
||||
public double estimateWlanUploadDelay(int apId){
|
||||
return getWlanUploadDelay(0,apId,true);
|
||||
}
|
||||
|
||||
public double estimateUploadDelay(NETWORK_DELAY_TYPES delayType, Task task) {
|
||||
return getDelay(delayType, task, false, true);
|
||||
}
|
||||
|
||||
public double estimateDownloadDelay(NETWORK_DELAY_TYPES delayType, Task task) {
|
||||
return getDelay(delayType, task, true, true);
|
||||
}
|
||||
|
||||
public double getUploadDelay(NETWORK_DELAY_TYPES delayType, Task task) {
|
||||
return getDelay(delayType, task, false, false);
|
||||
}
|
||||
|
||||
public double getDownloadDelay(NETWORK_DELAY_TYPES delayType, Task task) {
|
||||
return getDelay(delayType, task, true, false);
|
||||
}
|
||||
|
||||
private double getDelay(NETWORK_DELAY_TYPES delayType, Task task, boolean forDownload, boolean justEstimate) {
|
||||
double delay = 0;
|
||||
|
||||
if(delayType == NETWORK_DELAY_TYPES.GSM_DELAY){
|
||||
if(forDownload)
|
||||
delay = getGsmDownloadDelay(task.getCloudletOutputSize(), justEstimate);
|
||||
else
|
||||
delay = getGsmUploadDelay(task.getCloudletFileSize(), justEstimate);
|
||||
|
||||
if(delay != 0)
|
||||
delay += SimSettings.getInstance().getGsmPropagationDelay();
|
||||
}
|
||||
else if(delayType == NETWORK_DELAY_TYPES.WLAN_DELAY){
|
||||
if(forDownload)
|
||||
delay = getWlanDownloadDelay(task.getCloudletOutputSize(), task.getSubmittedLocation().getServingWlanId(), justEstimate);
|
||||
else
|
||||
delay = getWlanUploadDelay(task.getCloudletFileSize(), task.getSubmittedLocation().getServingWlanId(),justEstimate);
|
||||
}
|
||||
else if(delayType == NETWORK_DELAY_TYPES.WAN_DELAY){
|
||||
if(forDownload)
|
||||
delay = getWanDownloadDelay(task.getCloudletOutputSize(), justEstimate);
|
||||
else
|
||||
delay = getWanUploadDelay(task.getCloudletFileSize(), justEstimate);
|
||||
|
||||
if(delay != 0)
|
||||
delay += SimSettings.getInstance().getWanPropagationDelay();
|
||||
}
|
||||
else if(delayType == NETWORK_DELAY_TYPES.MAN_DELAY){
|
||||
if(forDownload)
|
||||
delay = getManDownloadDelay(task.getCloudletOutputSize(), justEstimate);
|
||||
else
|
||||
delay = getManUploadDelay(task.getCloudletFileSize(), justEstimate);
|
||||
|
||||
if(delay != 0)
|
||||
delay += SimSettings.getInstance().getInternalLanDelay();
|
||||
}
|
||||
|
||||
return delay;
|
||||
}
|
||||
|
||||
private double calculateMM1(double taskSize, double bandwidth /*Kbps*/, MMPPWrapper mmppWrapper, boolean justEstimate){
|
||||
double mu=0, lamda=0;
|
||||
double PoissonMean = mmppWrapper.getPoissonMean();
|
||||
double avgTaskSize = mmppWrapper.getTaskSize(); /*KB*/
|
||||
|
||||
if(!justEstimate)
|
||||
mmppWrapper.increaseMM1StatValues(taskSize);
|
||||
|
||||
avgTaskSize = avgTaskSize * 8; //convert from KB to Kb
|
||||
|
||||
lamda = ((double)1/(double)PoissonMean); //task per seconds
|
||||
mu = bandwidth /*Kbps*/ / avgTaskSize /*Kb*/; //task per seconds
|
||||
double result = (double)1 / (mu-lamda);
|
||||
|
||||
return (result > 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("------------------------------------------------");
|
||||
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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<Attribute> atts = new ArrayList<Attribute>();
|
||||
for(int i=0; i<attributes.length; i++)
|
||||
atts.add(new Attribute(attributes[i]));
|
||||
|
||||
Instances dataRaw = new Instances(relation,atts,0);
|
||||
double[] instanceValue1 = new double[dataRaw.numAttributes()];
|
||||
for(int i=0; i<values.length; i++)
|
||||
instanceValue1[i] = (values[i] - meanVals[i]) / stdVals[i];
|
||||
|
||||
dataRaw.add(new DenseInstance(1.0, instanceValue1));
|
||||
dataRaw.setClassIndex(dataRaw.numAttributes()-1);
|
||||
|
||||
return dataRaw.get(0);
|
||||
}
|
||||
|
||||
public Instance getClassificationData(String relation, double[] values, String[] attributes, double[] meanVals, double[] stdVals) {
|
||||
ArrayList<Attribute> atts = new ArrayList<Attribute>();
|
||||
ArrayList<String> classVal = new ArrayList<String>();
|
||||
for(int i=0; i<CLASSIFIER_CLASSES.length; i++)
|
||||
classVal.add(CLASSIFIER_CLASSES[i]);
|
||||
|
||||
for(int i=0; i<attributes.length; i++)
|
||||
atts.add(new Attribute(attributes[i]));
|
||||
|
||||
atts.add(new Attribute("class",classVal));
|
||||
|
||||
Instances dataRaw = new Instances(relation,atts,0);
|
||||
|
||||
double[] instanceValue1 = new double[dataRaw.numAttributes()];
|
||||
for(int i=0; i<values.length; i++)
|
||||
instanceValue1[i] = (values[i] - meanVals[i]) / stdVals[i];
|
||||
|
||||
dataRaw.add(new DenseInstance(1.0, instanceValue1));
|
||||
dataRaw.setClassIndex(dataRaw.numAttributes()-1);
|
||||
|
||||
return dataRaw.get(0);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user