-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
272 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from yafs.population import Population | ||
import networkx as nx | ||
|
||
|
||
class SimpleDynamicChanges(Population): | ||
""" | ||
This implementation of a population algorithm statically assigns the generation of a source in a node of the topology. It is only invoked in the initialization. | ||
Extends: :mod: Population | ||
""" | ||
def __init__(self, *args, **kwargs): | ||
super(SimpleDynamicChanges, self).__init__(*args, **kwargs) | ||
self.run_times = 2 | ||
|
||
|
||
def initial_allocation(self,sim,app_name): | ||
|
||
#Assignment of SINK and SOURCE pure modules | ||
for id_entity in sim.topology.nodeAttributes: | ||
entity = sim.topology.nodeAttributes[id_entity] | ||
for ctrl in self.sink_control: | ||
#A node can have several sinks modules | ||
if entity["model"]==ctrl["model"]: | ||
#In this node there is a sink | ||
module = ctrl["module"] | ||
for number in range(ctrl["number"]): | ||
sim.deploy_sink(app_name, node=id_entity, module=module) | ||
#end for sink control | ||
|
||
for ctrl in self.src_control: | ||
# A node can have several source modules | ||
if entity["model"] == ctrl["model"]: | ||
msg = ctrl["message"] | ||
dst = ctrl["distribution"] | ||
param = ctrl["param"] | ||
for number in range(ctrl["number"]): | ||
idsrc = sim.deploy_source(app_name,id_node=id_entity,msg=msg,distribution=dst,param=param) | ||
# the idsrc can be used to control the deactivation of the process in a dynamic behaviour | ||
|
||
#end for src control | ||
|
||
#end assignments | ||
|
||
|
||
def run(self, sim): | ||
|
||
if self.run_times == 0: # We can stop the process according to any criteria | ||
sim.stop_process(sim.get_DES(self.name)) | ||
else: | ||
self.run_times -=1 | ||
# Run whatever you want | ||
print "Running Population-Evolution: %i" %self.run_times | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
""" | ||
@author: isaac | ||
""" | ||
import random | ||
|
||
import argparse | ||
|
||
from yafs.core import Sim | ||
from yafs.application import Application,Message | ||
|
||
from yafs.topology import Topology | ||
|
||
from simpleSelection import MinPath_RoundRobin | ||
from simplePlacement import CloudPlacement | ||
from evolutivePopulationTopology import SimpleDynamicChanges | ||
|
||
from yafs.utils import * | ||
from yafs.stats import Stats | ||
import time | ||
|
||
RANDOM_SEED = 1 | ||
|
||
def create_application(): | ||
# APLICATION | ||
a = Application(name="SimpleCase") | ||
|
||
# (S) --> (ServiceA) --> (A) | ||
a.set_modules([{"Sensor":{"Type":Application.TYPE_SOURCE}}, | ||
{"ServiceA": {"RAM": 10, "Type": Application.TYPE_MODULE}}, | ||
{"Actuator": {"Type": Application.TYPE_SINK}} | ||
]) | ||
""" | ||
Messages among MODULES (AppEdge in iFogSim) | ||
""" | ||
m_a = Message("M.A", "Sensor", "ServiceA", instructions=20*10^6, bytes=1000) | ||
m_b = Message("M.B", "ServiceA", "Actuator", instructions=30*10^6, bytes=500,broadcasting=True) | ||
|
||
""" | ||
Defining which messages will be dynamically generated # the generation is controlled by Population algorithm | ||
""" | ||
a.add_source_messages(m_a) | ||
|
||
""" | ||
MODULES/SERVICES: Definition of Generators and Consumers (AppEdges and TupleMappings in iFogSim) | ||
""" | ||
# MODULE SERVICES | ||
a.add_service_module("ServiceA", m_a, m_b, fractional_selectivity, threshold=1.0) | ||
|
||
return a | ||
|
||
|
||
|
||
def create_json_topology(): | ||
""" | ||
TOPOLOGY DEFINITION | ||
Some attributes of fog entities (nodes) are approximate | ||
""" | ||
|
||
## MANDATORY FIELDS | ||
topology_json = {} | ||
topology_json["entity"] = [] | ||
topology_json["link"] = [] | ||
|
||
cloud_dev = {"id": 0, "model": "cloud", "mytag":"cloud", "IPT": 5000 * 10 ^ 6, "RAM": 40000,"COST": 3,"WATT":20.0} | ||
sensor_dev1 = {"id": 1, "model": "sensor-device-1", "IPT": 100* 10 ^ 6, "RAM": 4000,"COST": 3,"WATT":40.0} | ||
sensor_dev2 = {"id": 2, "model": "sensor-device-2", "IPT": 100 * 10 ^ 6, "RAM": 4000, "COST": 3, "WATT": 40.0} | ||
sensor_dev3 = {"id": 3, "model": "sensor-device-3", "IPT": 100 * 10 ^ 6, "RAM": 4000, "COST": 3, "WATT": 40.0} | ||
actuator_dev = {"id": 4, "model": "actuator-device", "IPT": 100 * 10 ^ 6, "RAM": 4000,"COST": 3, "WATT": 40.0} | ||
|
||
link1 = {"s": 0, "d": 1, "BW": 1, "PR": 10} | ||
link2 = {"s": 0, "d": 4, "BW": 1, "PR": 1} | ||
|
||
topology_json["entity"].append(cloud_dev) | ||
topology_json["entity"].append(sensor_dev1) | ||
topology_json["entity"].append(sensor_dev2) | ||
topology_json["entity"].append(sensor_dev3) | ||
topology_json["entity"].append(actuator_dev) | ||
topology_json["link"].append(link1) | ||
topology_json["link"].append(link2) | ||
|
||
return topology_json | ||
|
||
|
||
|
||
# @profile | ||
def main(simulated_time): | ||
|
||
random.seed(RANDOM_SEED) | ||
|
||
""" | ||
TOPOLOGY from a json | ||
""" | ||
t = Topology() | ||
t_json = create_json_topology() | ||
t.load(t_json) | ||
t.write("network.gexf") | ||
|
||
""" | ||
APPLICATION | ||
""" | ||
app = create_application() | ||
|
||
""" | ||
PLACEMENT algorithm | ||
""" | ||
placement = CloudPlacement("onCloud") # it defines the deployed rules: module-device | ||
placement.scaleService({"ServiceA": 2}) | ||
|
||
""" | ||
POPULATION algorithm | ||
""" | ||
#In ifogsim, during the creation of the application, the Sensors are assigned to the topology, in this case no. As mentioned, YAFS differentiates the adaptive sensors and their topological assignment. | ||
#In their case, the use a statical assignment. | ||
pop = SimpleDynamicChanges("Dynamic",activation_dist=deterministicDistribution,time_shift=300) | ||
|
||
#, activation_dist = deterministicDistribution, time_shift = 100.0) | ||
#For each type of sink modules we set a deployment on some type of devices | ||
#A control sink consists on: | ||
# args: | ||
# model (str): identifies the device or devices where the sink is linked | ||
# number (int): quantity of sinks linked in each device | ||
# module (str): identifies the module from the app who receives the messages | ||
pop.set_sink_control({"model": "actuator-device","number":2,"module":app.get_sink_modules()}) | ||
|
||
#In addition, a source includes a distribution function: | ||
pop.set_src_control({"model": "sensor-device-1", "number":1,"message": app.get_message("M.A"), "distribution": deterministicDistribution,"param": {"time_shift": 100}}) | ||
|
||
|
||
""" | ||
Topology and Changes on the population dynamically | ||
Population, Placement can be run in simulation time according with a distribution function | ||
""" | ||
|
||
|
||
|
||
|
||
"""-- | ||
SELECTOR algorithm | ||
""" | ||
#Their "selector" is actually the shortest way, there is not type of orchestration algorithm. | ||
#This implementation is already created in selector.class,called: First_ShortestPath | ||
selectorPath = MinPath_RoundRobin() | ||
|
||
""" | ||
SIMULATION ENGINE | ||
""" | ||
|
||
stop_time = simulated_time | ||
s = Sim(t, default_results_path="Results_multiple") | ||
s.deploy_app(app, placement, pop, selectorPath) | ||
|
||
s.run(stop_time,show_progress_monitor=False) | ||
|
||
#s.draw_allocated_topology() # This implementation does not work when there is some node not linked | ||
|
||
if __name__ == '__main__': | ||
import logging.config | ||
import os | ||
|
||
logging.config.fileConfig(os.getcwd()+'/logging.ini') | ||
|
||
start_time = time.time() | ||
main(simulated_time=1000) | ||
|
||
print("\n--- %s seconds ---" % (time.time() - start_time)) | ||
|
||
### Finally, you can analyse the results: | ||
print "-"*20 | ||
print "Results:" | ||
print "-" * 20 | ||
m = Stats(defaultPath="Results_multiple") #Same name of the results | ||
time_loops = [["M.A", "M.B"]] | ||
m.showResults2(1000, time_loops=time_loops) | ||
print "\t- Network saturation -" | ||
print "\t\tAverage waiting messages : %i" % m.average_messages_not_transmitted() | ||
print "\t\tPeak of waiting messages : %i" % m.peak_messages_not_transmitted() | ||
print "\t\tTOTAL messages not transmitted: %i" % m.messages_not_transmitted() | ||
|
||
print "\n\t- Stats of each service deployed -" | ||
print m.get_df_modules() | ||
print m.get_df_service_utilization("ServiceA",1000) | ||
|
||
print "\n\t- Stats of each DEVICE -" | ||
#TODO |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.