Initial commit
This commit is contained in:
commit
66a6860316
407 changed files with 1254365 additions and 0 deletions
338
test/testmodels/experiment.py
Normal file
338
test/testmodels/experiment.py
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
#! /bin/env python
|
||||
#import stacktracer
|
||||
#stacktracer.trace_start("trace.html",interval=1,auto=True) # Set auto flag to always update file!
|
||||
|
||||
try:
|
||||
from mpi4py import MPI
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
import models
|
||||
import sys
|
||||
from pypdevs.simulator import Simulator, loadCheckpoint
|
||||
|
||||
mn = sys.argv[1]
|
||||
args = {}
|
||||
args["setTerminationTime"] = [40]
|
||||
args["setVerbose"] = ["output/" + mn.partition("_local")[0]]
|
||||
run = True
|
||||
|
||||
def counter(t, m):
|
||||
return m.processor2.coupled[0].state.counter != float('inf')
|
||||
|
||||
def counter_pull(t, m):
|
||||
s = m.processor1.coupled[0].getState(t)
|
||||
print(s.counter)
|
||||
return s.counter != float('inf')
|
||||
|
||||
if mn == "confluent":
|
||||
model = models.Chain(1.00)
|
||||
elif mn == "confluent_local":
|
||||
model = models.Chain_local(1.00)
|
||||
elif mn == "rollback":
|
||||
args["setTerminationTime"] = [20000]
|
||||
model = models.Chain_bad()
|
||||
elif mn == "normal_long":
|
||||
args["setTerminationTime"] = [20000]
|
||||
#args["setVerbose"] = [False]
|
||||
model = models.Chain(0.66)
|
||||
elif mn == "normal_long_local":
|
||||
args["setTerminationTime"] = [20000]
|
||||
#args["setVerbose"] = [False]
|
||||
model = models.Chain_local(0.66)
|
||||
elif mn == "dualdepth":
|
||||
model = models.DualDepth(0.66)
|
||||
elif mn == "dualdepth_local":
|
||||
model = models.DualDepth_local(0.66)
|
||||
elif mn == "dual":
|
||||
model = models.DualChain(0.66)
|
||||
elif mn == "dual_local":
|
||||
model = models.DualChain_local(0.66)
|
||||
elif mn == "dual_mp":
|
||||
model = models.DualChainMP(0.66)
|
||||
elif mn == "dual_mp_local":
|
||||
model = models.DualChainMP_local(0.66)
|
||||
elif mn == "local":
|
||||
model = models.Local()
|
||||
elif mn == "local_local":
|
||||
model = models.Local()
|
||||
elif mn == "longtime":
|
||||
model = models.Chain(0.66)
|
||||
args["setTerminationTime"] = [200]
|
||||
elif mn == "longtime_local":
|
||||
model = models.Chain_local(0.66)
|
||||
args["setTerminationTime"] = [200]
|
||||
elif mn == "atomic_local":
|
||||
model = models.Generator()
|
||||
elif mn == "multi":
|
||||
model = models.Chain(0.50)
|
||||
elif mn == "multi_local":
|
||||
model = models.Chain_local(0.50)
|
||||
elif mn == "multinested":
|
||||
model = models.MultiNested()
|
||||
args["setTerminationTime"] = [10]
|
||||
elif mn == "nested_local":
|
||||
model = models.Nested_local()
|
||||
args["setTerminationTime"] = [20]
|
||||
elif mn == "nested_realtime_local":
|
||||
model = models.Nested_local()
|
||||
args["setTerminationTime"] = [20]
|
||||
args["setRealTime"] = [True]
|
||||
args["setRealTimePorts"] = [{}]
|
||||
args["setRealTimePlatformThreads"] = []
|
||||
elif mn == "remotedc":
|
||||
model = models.RemoteDC()
|
||||
elif mn == "remotedc_long":
|
||||
args["setTerminationTime"] = [200]
|
||||
model = models.RemoteDC()
|
||||
elif mn == "normal":
|
||||
model = models.Chain(0.66)
|
||||
elif mn == "allocate":
|
||||
args["setTerminationTime"] = [10000]
|
||||
args["setGreedyAllocator"] = []
|
||||
#args["setDrawModel"] = [True, "model.dot", False]
|
||||
model = models.Chain(0.66)
|
||||
elif mn == "normal_local":
|
||||
model = models.Chain_local(0.66)
|
||||
elif mn == "zeroLookahead":
|
||||
model = models.Chain(0.00)
|
||||
elif mn == "zeroLookahead_local":
|
||||
model = models.Chain_local(0.00)
|
||||
elif mn == "stateStop":
|
||||
model = models.Chain(0.66)
|
||||
args["setTerminationModel"] = [model.processor2.coupled[0]]
|
||||
args["setTerminationCondition"] = [counter]
|
||||
del args["setTerminationTime"]
|
||||
elif mn == "stateStop_local":
|
||||
model = models.Chain_local(0.66)
|
||||
args["setTerminationModel"] = [model.processor2.coupled[0]]
|
||||
args["setTerminationCondition"] = [counter]
|
||||
del args["setTerminationTime"]
|
||||
elif mn == "checkpoint":
|
||||
model = models.Chain(0.66)
|
||||
args["setTerminationTime"] = [2000]
|
||||
args["setCheckpointing"] = ["testing", 1]
|
||||
if loadCheckpoint("testing") is not None:
|
||||
run = False
|
||||
elif mn == "checkpoint_long":
|
||||
model = models.Chain(0.66)
|
||||
args["setTerminationTime"] = [20000]
|
||||
args["setCheckpointing"] = ["testing", 1]
|
||||
if loadCheckpoint("testing") is not None:
|
||||
run = False
|
||||
elif mn == "checkpoint_long_local":
|
||||
model = models.Chain_local(0.66)
|
||||
args["setTerminationTime"] = [20000]
|
||||
args["setCheckpointing"] = ["testing", 1]
|
||||
if loadCheckpoint("testing") is not None:
|
||||
run = False
|
||||
elif mn == "autodist":
|
||||
model = models.AutoDistChain(3, totalAtomics=500, iterations=1)
|
||||
elif mn == "autodist_original":
|
||||
from mpi4py import MPI
|
||||
model = models.AutoDistChain(MPI.COMM_WORLD.Get_size(), totalAtomics=500, iterations=1)
|
||||
elif mn == "autodist_checkpoint":
|
||||
from mpi4py import MPI
|
||||
model = models.AutoDistChain(MPI.COMM_WORLD.Get_size(), totalAtomics=500, iterations=1)
|
||||
args["setTerminationTime"] = [200]
|
||||
args["setShowProgress"] = []
|
||||
args["setCheckpointing"] = ["testing", 1]
|
||||
if loadCheckpoint("testing") is not None:
|
||||
run = False
|
||||
elif mn == "relocation":
|
||||
model = models.Chain(0.66)
|
||||
args["setTerminationTime"] = [2000]
|
||||
args["setRelocationDirectives"] = [[[500, model.processor1.coupled[0], 0], [1000, model.processor1.coupled[0], 2]]]
|
||||
args["setGVTInterval"] = [1]
|
||||
elif mn == "relocation_activity":
|
||||
model = models.Chain(0.66)
|
||||
args["setTerminationTime"] = [20000]
|
||||
args["setActivityRelocatorBasicBoundary"] = [1.2]
|
||||
del args["setVerbose"]
|
||||
args["setGVTInterval"] = [2]
|
||||
elif mn == "relocation_noactivity":
|
||||
model = models.Chain(0.66)
|
||||
args["setTerminationTime"] = [20000]
|
||||
del args["setVerbose"]
|
||||
args["setGVTInterval"] = [2]
|
||||
elif mn == "boundary":
|
||||
model = models.Boundary()
|
||||
args["setTerminationTime"] = [2000]
|
||||
args["setRelocationDirectives"] = [[[100, 2, 0]]]
|
||||
args["setGVTInterval"] = [1]
|
||||
elif mn == "relocation_faster":
|
||||
model = models.Chain(0.66)
|
||||
del args["setVerbose"]
|
||||
args["setTerminationTime"] = [20000]
|
||||
args["setRelocationDirectives"] = [[[0, model.processor1.coupled[0], 1], [0, model.processor2.coupled[0], 2], [0, model.processor2.coupled[1], 2]]]
|
||||
elif mn.startswith("realtime"):
|
||||
from trafficLightModel import *
|
||||
model = TrafficSystem(name="trafficSystem")
|
||||
refs = {"INTERRUPT": model.trafficLight.INTERRUPT}
|
||||
args["setVerbose"] = ["output/realtime"]
|
||||
args["setTerminationTime"] = [35]
|
||||
if "0.5" in mn:
|
||||
scale = 0.5
|
||||
elif "2.0" in mn:
|
||||
scale = 2.0
|
||||
else:
|
||||
scale = 1.0
|
||||
args["setRealTime"] = [True, scale]
|
||||
args["setRealTimeInputFile"] = ["testmodels/input"]
|
||||
args["setRealTimePorts"] = [refs]
|
||||
if mn.startswith("realtime_thread"):
|
||||
args["setRealTimePlatformThreads"] = []
|
||||
elif mn.startswith("realtime_loop"):
|
||||
args["setRealTimePlatformGameLoop"] = []
|
||||
elif mn.startswith("realtime_tk"):
|
||||
from Tkinter import *
|
||||
myTk = Tk()
|
||||
args["setRealTimePlatformTk"] = [myTk]
|
||||
else:
|
||||
print("Unknown subsystem requested")
|
||||
sys.exit(1)
|
||||
elif mn == "progress":
|
||||
model = models.Chain(0.66)
|
||||
args["setShowProgress"] = []
|
||||
args["setTerminationTime"] = [2000]
|
||||
elif mn == "progress_local":
|
||||
model = models.Chain_local(0.66)
|
||||
args["setShowProgress"] = []
|
||||
args["setTerminationTime"] = [2000]
|
||||
elif mn == "trace":
|
||||
model = models.Binary()
|
||||
args["setVCD"] = ["devstrace.vcd"]
|
||||
args["setXML"] = ["devstrace.xml"]
|
||||
elif mn == "trace_local":
|
||||
model = models.Binary_local()
|
||||
args["setVCD"] = ["devstrace.vcd"]
|
||||
args["setXML"] = ["devstrace.xml"]
|
||||
elif mn == "fetch":
|
||||
model = models.Chain(0.66)
|
||||
args["setFetchAllAfterSimulation"] = []
|
||||
elif mn == "draw":
|
||||
model = models.Chain(0.66)
|
||||
args["setDrawModel"] = [True]
|
||||
elif mn == "draw_local":
|
||||
model = models.Chain_local(0.66)
|
||||
args["setDrawModel"] = [True]
|
||||
elif mn == "auto_allocate":
|
||||
# Take the local variant, as this does not contain location info
|
||||
model = models.Chain_local(0.66)
|
||||
args["setDrawModel"] = [True]
|
||||
args["setAutoAllocator"] = []
|
||||
elif mn == "multiinputs":
|
||||
model = models.MultipleInputs()
|
||||
elif mn == "multiinputs_local":
|
||||
model = models.MultipleInputs_local()
|
||||
elif mn == "doublelayer_local":
|
||||
model = models.DoubleLayerRoot()
|
||||
elif mn == "dynamicstructure_local":
|
||||
model = models.DSDEVSRoot()
|
||||
args["setDSDEVS"] = [True]
|
||||
elif mn == "dynamicstructure_realtime_local":
|
||||
model = models.DSDEVSRoot()
|
||||
args["setRealTime"] = [True]
|
||||
args["setRealTimePorts"] = [{}]
|
||||
args["setRealTimePlatformThreads"] = []
|
||||
args["setDSDEVS"] = [True]
|
||||
elif mn == "classicDEVS_local":
|
||||
model = models.ClassicCoupled()
|
||||
args["setClassicDEVS"] = [True]
|
||||
elif mn == "classicDEVSconnect_local":
|
||||
model = models.AllConnectClassic()
|
||||
args["setClassicDEVS"] = [True]
|
||||
elif mn == "random":
|
||||
model = models.RandomCoupled()
|
||||
elif mn == "random_local":
|
||||
model = models.RandomCoupled_local()
|
||||
elif mn == "stateStop_pull":
|
||||
model = models.Chain(0.66)
|
||||
args["setTerminationCondition"] = [counter_pull]
|
||||
del args["setTerminationTime"]
|
||||
elif mn.startswith("reinit"):
|
||||
model = models.AutoDistChain(3, totalAtomics=500, iterations=1)
|
||||
if "local" in mn:
|
||||
model.forceSequential()
|
||||
sim = Simulator(model)
|
||||
sim.setAllowLocalReinit(True)
|
||||
sim.setTerminationTime(40)
|
||||
sim.setVerbose("output/reinit1")
|
||||
sim.simulate()
|
||||
sim.reinit()
|
||||
sim.setVerbose("output/reinit2")
|
||||
sim.setModelStateAttr(model.generator.generator, "value", 2)
|
||||
sim.simulate()
|
||||
sim.reinit()
|
||||
sim.setVerbose("output/reinit3")
|
||||
sim.setModelStateAttr(model.generator.generator, "value", 3)
|
||||
sim.simulate()
|
||||
run = False
|
||||
elif mn.startswith("multisim"):
|
||||
if "local" in mn:
|
||||
sim = Simulator(models.Chain_local(0.66))
|
||||
else:
|
||||
sim = Simulator(models.Chain(0.66))
|
||||
sim.setVerbose("output/normal")
|
||||
sim.setTerminationTime(40)
|
||||
sim.simulate()
|
||||
|
||||
if "local" in mn:
|
||||
sim2 = Simulator(models.DualDepth_local(0.66))
|
||||
else:
|
||||
sim2 = Simulator(models.DualDepth(0.66))
|
||||
sim2.setVerbose("output/dualdepth")
|
||||
sim2.setTerminationTime(40)
|
||||
sim2.simulate()
|
||||
run = False
|
||||
elif mn.startswith("continue"):
|
||||
if "local" in mn:
|
||||
sim = Simulator(models.Chain_local(0.66))
|
||||
else:
|
||||
sim = Simulator(models.Chain(0.66))
|
||||
sim.setVerbose("output/run1")
|
||||
sim.setTerminationTime(100.0)
|
||||
sim.simulate()
|
||||
sim.setModelStateAttr(sim.model.generator.generator, "value", 2)
|
||||
sim.setVerbose("output/run2")
|
||||
sim.setTerminationTime(200.0)
|
||||
sim.simulate()
|
||||
run = False
|
||||
elif mn.startswith("z"):
|
||||
if "local" in mn:
|
||||
model = models.ZChain_local()
|
||||
else:
|
||||
model = models.ZChain()
|
||||
|
||||
if run:
|
||||
sim = Simulator(model)
|
||||
for arg in args.keys():
|
||||
function = getattr(sim, arg)
|
||||
function(*args[arg])
|
||||
sim.simulate()
|
||||
if mn.startswith("realtime_loop"):
|
||||
# Start a game loop ourselves
|
||||
import time
|
||||
start_time = time.time()
|
||||
while time.time() < start_time + 35.5 * scale:
|
||||
before = time.time()
|
||||
sim.realtime_loop_call()
|
||||
time.sleep(0.001 - (before - time.time()))
|
||||
elif mn.startswith("realtime_tk"):
|
||||
myTk.after(int(35000 * scale), myTk.quit)
|
||||
myTk.mainloop()
|
||||
elif mn.startswith("realtime_thread"):
|
||||
import time
|
||||
time.sleep((35+0.2) * scale)
|
||||
elif "realtime" in mn:
|
||||
import time
|
||||
time.sleep(args["setTerminationTime"][0])
|
||||
elif mn == "fetch":
|
||||
f = open(args["setVerbose"][0], 'w')
|
||||
f.write("Generator: " + str(model.generator.generator.state) + "\n")
|
||||
f.write("Processor1.Processor1: " + str(model.processor1.coupled[0].state) + "\n")
|
||||
f.write("Processor1.Processor2: " + str(model.processor1.coupled[1].state) + "\n")
|
||||
f.write("Processor2.Processor1: " + str(model.processor2.coupled[0].state) + "\n")
|
||||
f.write("Processor2.Processor2: " + str(model.processor2.coupled[1].state) + "\n")
|
||||
f.write("Processor2.Processor3: " + str(model.processor2.coupled[2].state) + "\n")
|
||||
f.close()
|
||||
109
test/testmodels/injecting.py
Normal file
109
test/testmodels/injecting.py
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
from pypdevs.DEVS import AtomicDEVS, CoupledDEVS
|
||||
from pypdevs.simulator import Simulator
|
||||
|
||||
class Root(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Root")
|
||||
self.listener_A = self.addInPort("listener_A")
|
||||
self.output_A = self.addOutPort("output_A")
|
||||
self.mini = self.addSubModel(Mini())
|
||||
|
||||
self.connectPorts(self.listener_A, self.mini.listener_B)
|
||||
self.connectPorts(self.mini.output_B, self.output_A)
|
||||
|
||||
class Mini(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Mini")
|
||||
self.listener_B = self.addInPort("listener_B")
|
||||
self.output_B = self.addOutPort("output_B")
|
||||
self.model_one = self.addSubModel(Proc("C"))
|
||||
self.model_two = self.addSubModel(Proc("D"))
|
||||
|
||||
self.connectPorts(self.listener_B, self.model_one.inport)
|
||||
self.connectPorts(self.listener_B, self.model_two.inport)
|
||||
self.connectPorts(self.model_one.outport, self.output_B)
|
||||
|
||||
class Proc(AtomicDEVS):
|
||||
def __init__(self, name):
|
||||
AtomicDEVS.__init__(self, "Proc_%s" % name)
|
||||
self.inport = self.addInPort("listener_%s" % name)
|
||||
self.outport = self.addOutPort("output_%s" % name)
|
||||
self.state = None
|
||||
|
||||
def intTransition(self):
|
||||
return None
|
||||
|
||||
def extTransition(self, inputs):
|
||||
return inputs[self.inport][0]
|
||||
|
||||
def outputFnc(self):
|
||||
return {self.outport: [self.state]}
|
||||
|
||||
def timeAdvance(self):
|
||||
return 0.0 if self.state else float('inf')
|
||||
|
||||
model = Root()
|
||||
sim = Simulator(model)
|
||||
sim.setRealTime(True)
|
||||
sim.setRealTimePorts({"input_A": model.listener_A,
|
||||
"input_B": model.mini.listener_B,
|
||||
"input_C": model.mini.model_one.inport,
|
||||
"input_D": model.mini.model_two.inport,
|
||||
"output_A": model.output_A,
|
||||
"output_B": model.mini.output_B,
|
||||
"output_C": model.mini.model_one.outport,
|
||||
"output_D": model.mini.model_two.outport})
|
||||
sim.setRealTimePlatformThreads()
|
||||
|
||||
def output_on_A(evt):
|
||||
global on_A
|
||||
on_A = evt[0]
|
||||
|
||||
def output_on_B(evt):
|
||||
global on_B
|
||||
on_B = evt[0]
|
||||
|
||||
sim.setListenPorts(model.output_A, output_on_A)
|
||||
sim.setListenPorts(model.mini.output_B, output_on_B)
|
||||
|
||||
sim.simulate()
|
||||
|
||||
import time
|
||||
|
||||
on_A = None
|
||||
on_B = None
|
||||
sim.realtime_interrupt("input_A 1")
|
||||
time.sleep(1)
|
||||
|
||||
if not (on_A == "1" and on_B == "1"):
|
||||
raise Exception("Expected input on A or B output port")
|
||||
on_A = None
|
||||
on_B = None
|
||||
|
||||
sim.realtime_interrupt("input_B 2")
|
||||
time.sleep(1)
|
||||
|
||||
if not (on_A == "2" and on_B == "2"):
|
||||
print(on_A)
|
||||
print(type(on_A))
|
||||
print(on_B)
|
||||
print(type(on_B))
|
||||
raise Exception("Expected input on A and B output port")
|
||||
on_A = None
|
||||
on_B = None
|
||||
|
||||
sim.realtime_interrupt("input_C 3")
|
||||
time.sleep(1)
|
||||
|
||||
if not (on_A == "3" and on_B == "3"):
|
||||
print(on_A)
|
||||
print(on_B)
|
||||
raise Exception("Expected input on A or B output port")
|
||||
on_A = None
|
||||
on_B = None
|
||||
|
||||
sim.realtime_interrupt("input_D 4")
|
||||
time.sleep(1)
|
||||
|
||||
if not (on_A == None and on_B == None):
|
||||
raise Exception("Didn't expect input on A or B output port")
|
||||
3
test/testmodels/input
Normal file
3
test/testmodels/input
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
10 INTERRUPT toManual
|
||||
20 INTERRUPT toAutonomous
|
||||
30 INTERRUPT toManual
|
||||
939
test/testmodels/models.py
Normal file
939
test/testmodels/models.py
Normal file
|
|
@ -0,0 +1,939 @@
|
|||
import sys
|
||||
import os.path
|
||||
|
||||
from pypdevs.infinity import *
|
||||
from pypdevs.DEVS import AtomicDEVS, CoupledDEVS
|
||||
|
||||
class Event(object):
|
||||
def __init__(self, eventSize):
|
||||
self.eventSize = eventSize
|
||||
|
||||
def __str__(self):
|
||||
return "Eventsize = " + str(self.eventSize)
|
||||
|
||||
class ModelState(object):
|
||||
def __init__(self):
|
||||
self.counter = INFINITY
|
||||
self.event = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.counter)
|
||||
|
||||
def toXML(self):
|
||||
return "<counter>" + str(self.counter) + "</counter>"
|
||||
|
||||
class ProcessorNPP(AtomicDEVS):
|
||||
def __init__(self, name = "Processor", t_event1 = 1):
|
||||
AtomicDEVS.__init__(self, name)
|
||||
self.t_event1 = t_event1
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
self.state = ModelState()
|
||||
|
||||
def timeAdvance(self):
|
||||
return self.state.counter
|
||||
|
||||
def intTransition(self):
|
||||
self.state.counter -= self.timeAdvance()
|
||||
if self.state.counter == 0:
|
||||
self.state.counter = INFINITY
|
||||
self.state.event = None
|
||||
return self.state
|
||||
|
||||
def extTransition(self, inputs):
|
||||
self.state.counter -= self.elapsed
|
||||
ev1 = inputs[self.inport][0]
|
||||
if ev1 != None:
|
||||
self.state.event = ev1
|
||||
self.state.counter = self.t_event1
|
||||
return self.state
|
||||
|
||||
def outputFnc(self):
|
||||
output = {}
|
||||
mini = self.state.counter
|
||||
if self.state.counter == mini:
|
||||
output[self.outport] = [self.state.event]
|
||||
return output
|
||||
|
||||
class RemoteDCProcessor(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "RemoteDCProcessor")
|
||||
mod = self.addSubModel(CoupledProcessor(1, 1), 2)
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
self.connectPorts(self.inport, mod.inport)
|
||||
self.connectPorts(mod.outport, self.outport)
|
||||
|
||||
class Processor(AtomicDEVS):
|
||||
def __init__(self, name = "Processor", t_event1 = 1):
|
||||
AtomicDEVS.__init__(self, name)
|
||||
self.t_event1 = t_event1
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
self.state = ModelState()
|
||||
|
||||
def timeAdvance(self):
|
||||
return self.state.counter
|
||||
|
||||
def intTransition(self):
|
||||
self.state.counter -= self.timeAdvance()
|
||||
if self.state.counter == 0:
|
||||
self.state.counter = INFINITY
|
||||
self.state.event = None
|
||||
return self.state
|
||||
|
||||
def extTransition(self, inputs):
|
||||
self.state.counter -= self.elapsed
|
||||
ev1 = inputs[self.inport][0]
|
||||
if ev1 != None:
|
||||
self.state.event = ev1
|
||||
self.state.counter = self.t_event1
|
||||
return self.state
|
||||
|
||||
def outputFnc(self):
|
||||
mini = self.state.counter
|
||||
if self.state.counter == mini:
|
||||
return {self.outport: [self.state.event]}
|
||||
else:
|
||||
return {}
|
||||
|
||||
class HeavyProcessor(AtomicDEVS):
|
||||
def __init__(self, name = "Processor", t_event1 = 1, iterations = 0):
|
||||
AtomicDEVS.__init__(self, name)
|
||||
self.t_event1 = t_event1
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
self.state = ModelState()
|
||||
self.iterations = iterations
|
||||
|
||||
def timeAdvance(self):
|
||||
return self.state.counter
|
||||
|
||||
def intTransition(self):
|
||||
self.state.counter -= self.timeAdvance()
|
||||
# Do lots of work now
|
||||
stupidcounter = 0
|
||||
for _ in xrange(self.iterations):
|
||||
pass
|
||||
if self.state.counter == 0:
|
||||
self.state.counter = INFINITY
|
||||
self.state.event = None
|
||||
return self.state
|
||||
|
||||
def extTransition(self, inputs):
|
||||
self.state.counter -= self.elapsed
|
||||
ev1 = inputs[self.inport][0]
|
||||
stupidcounter = 0
|
||||
for _ in xrange(self.iterations):
|
||||
pass
|
||||
if ev1 != None:
|
||||
self.state.event = ev1
|
||||
self.state.counter = self.t_event1
|
||||
return self.state
|
||||
|
||||
def outputFnc(self):
|
||||
mini = self.state.counter
|
||||
stupidcounter = 0
|
||||
for _ in xrange(self.iterations):
|
||||
pass
|
||||
if self.state.counter == mini:
|
||||
return {self.outport: [self.state.event]}
|
||||
|
||||
class NestedProcessor(Processor):
|
||||
def __init__(self, name = "NestedProcessor"):
|
||||
Processor.__init__(self, name)
|
||||
self.state.processed = 0
|
||||
self.state.event = Event(5)
|
||||
|
||||
def extTransition(self, inputs):
|
||||
self.state = Processor.extTransition(self, inputs)
|
||||
self.state.processed += 1
|
||||
return self.state
|
||||
|
||||
def timeAdvance(self):
|
||||
from pypdevs.simulator import Simulator
|
||||
model = CoupledGenerator()
|
||||
sim = Simulator(model)
|
||||
sim.setTerminationTime(self.state.processed)
|
||||
#sim.setVerbose(True)
|
||||
sim.simulate()
|
||||
result = max(sim.model.generator.state.generated, 1)
|
||||
return result
|
||||
|
||||
class Generator(AtomicDEVS):
|
||||
def __init__(self, name = "Generator", t_gen_event1 = 1.0, binary = False):
|
||||
AtomicDEVS.__init__(self, name)
|
||||
self.state = ModelState()
|
||||
# Add an extra variable
|
||||
self.state.generated = 0
|
||||
self.state.counter = t_gen_event1
|
||||
self.state.value = 1
|
||||
self.t_gen_event1 = t_gen_event1
|
||||
self.outport = self.addOutPort("outport")
|
||||
self.inport = self.addInPort("inport")
|
||||
self.binary = binary
|
||||
|
||||
def timeAdvance(self):
|
||||
return self.state.counter
|
||||
|
||||
def intTransition(self):
|
||||
self.state.generated += 1
|
||||
return self.state
|
||||
|
||||
def extTransition(self, inputs):
|
||||
self.state.counter -= self.elapsed
|
||||
return self.state
|
||||
|
||||
def outputFnc(self):
|
||||
if self.binary:
|
||||
return {self.outport: ["b1"]}
|
||||
else:
|
||||
return {self.outport: [Event(self.state.value)]}
|
||||
|
||||
class GeneratorNPP(AtomicDEVS):
|
||||
def __init__(self, name = "Generator", t_gen_event1 = 1.0):
|
||||
AtomicDEVS.__init__(self, name)
|
||||
self.state = ModelState()
|
||||
# Add an extra variable
|
||||
self.state.generated = 0
|
||||
self.state.counter = t_gen_event1
|
||||
self.t_gen_event1 = t_gen_event1
|
||||
self.outport = self.addOutPort("outport")
|
||||
self.inport = self.addInPort("inport")
|
||||
|
||||
def timeAdvance(self):
|
||||
return self.state.counter
|
||||
|
||||
def intTransition(self):
|
||||
self.state.generated += 1
|
||||
return self.state
|
||||
|
||||
def extTransition(self, inputs):
|
||||
self.state.counter -= self.elapsed
|
||||
return self.state
|
||||
|
||||
def outputFnc(self):
|
||||
return {self.outport: [Event(1)]}
|
||||
|
||||
class CoupledGenerator(CoupledDEVS):
|
||||
def __init__(self, t_gen_event1 = 1, binary = False):
|
||||
CoupledDEVS.__init__(self, "CoupledGenerator")
|
||||
self.generator = self.addSubModel(Generator("Generator", t_gen_event1, binary))
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
|
||||
self.connectPorts(self.inport, self.generator.inport)
|
||||
self.connectPorts(self.generator.outport, self.outport)
|
||||
|
||||
class CoupledGeneratorNPP(CoupledDEVS):
|
||||
def __init__(self, t_gen_event1 = 1):
|
||||
CoupledDEVS.__init__(self, "CoupledGenerator")
|
||||
self.generator = self.addSubModel(GeneratorNPP("Generator", t_gen_event1))
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
|
||||
self.connectPorts(self.inport, self.generator.inport)
|
||||
self.connectPorts(self.generator.outport, self.outport)
|
||||
|
||||
class CoupledHeavyProcessor(CoupledDEVS):
|
||||
def __init__(self, t_event1_P1, levels, iterations, name = None):
|
||||
if name == None:
|
||||
name = "CoupledHeavyProcessor_" + str(levels)
|
||||
CoupledDEVS.__init__(self, name)
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
|
||||
self.coupled = []
|
||||
for i in range(levels):
|
||||
self.coupled.append(self.addSubModel(HeavyProcessor("Processor" + str(i), t_event1_P1, iterations)))
|
||||
for i in range(levels-1):
|
||||
self.connectPorts(self.coupled[i].outport, self.coupled[i+1].inport)
|
||||
self.connectPorts(self.inport, self.coupled[0].inport)
|
||||
self.connectPorts(self.coupled[-1].outport, self.outport)
|
||||
|
||||
class CoupledProcessorNPP(CoupledDEVS):
|
||||
def __init__(self, t_event1_P1, levels):
|
||||
CoupledDEVS.__init__(self, "CoupledProcessor_" + str(levels))
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
|
||||
self.coupled = []
|
||||
for i in range(levels):
|
||||
self.coupled.append(self.addSubModel(ProcessorNPP("Processor" + str(i), t_event1_P1)))
|
||||
for i in range(levels-1):
|
||||
self.connectPorts(self.coupled[i].outport, self.coupled[i+1].inport)
|
||||
self.connectPorts(self.inport, self.coupled[0].inport)
|
||||
self.connectPorts(self.coupled[-1].outport, self.outport)
|
||||
|
||||
class CoupledProcessor(CoupledDEVS):
|
||||
def __init__(self, t_event1_P1, levels):
|
||||
CoupledDEVS.__init__(self, "CoupledProcessor_" + str(levels))
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
|
||||
self.coupled = []
|
||||
for i in range(levels):
|
||||
self.coupled.append(self.addSubModel(Processor("Processor" + str(i), t_event1_P1)))
|
||||
for i in range(levels-1):
|
||||
self.connectPorts(self.coupled[i].outport, self.coupled[i+1].inport)
|
||||
self.connectPorts(self.inport, self.coupled[0].inport)
|
||||
self.connectPorts(self.coupled[-1].outport, self.outport)
|
||||
|
||||
class CoupledProcessorMP(CoupledDEVS):
|
||||
def __init__(self, t_event1_P1):
|
||||
CoupledDEVS.__init__(self, "CoupledProcessorMP")
|
||||
self.inport = self.addInPort("inport")
|
||||
|
||||
p1 = self.addSubModel(Processor("Processor1", t_event1_P1))
|
||||
p2 = self.addSubModel(Processor("Processor2", t_event1_P1))
|
||||
p3 = self.addSubModel(Processor("Processor3", t_event1_P1))
|
||||
p4 = self.addSubModel(Processor("Processor4", t_event1_P1))
|
||||
self.connectPorts(self.inport, p1.inport)
|
||||
self.connectPorts(self.inport, p3.inport)
|
||||
self.connectPorts(p1.outport, p2.inport)
|
||||
self.connectPorts(p3.outport, p4.inport)
|
||||
|
||||
class Binary(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Binary")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0, True))
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(0.6, 2), 2)
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(0.30, 3), 1)
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
|
||||
class Binary_local(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Binary")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0, True))
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(0.6, 2))
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(0.30, 3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
|
||||
class Chain_local(CoupledDEVS):
|
||||
def __init__(self, ta):
|
||||
CoupledDEVS.__init__(self, "Chain")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0))
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(ta, 2))
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(0.30, 3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
|
||||
class Chain(CoupledDEVS):
|
||||
def __init__(self, ta):
|
||||
CoupledDEVS.__init__(self, "Chain")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0), 1)
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(ta, 2), 2)
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(0.30, 3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
|
||||
class Boundary(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Boundary")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0), 1)
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(0.60, 2), 2)
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(0.30, 4), 3)
|
||||
self.processor3 = self.addSubModel(CoupledProcessor(0.30, 3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor3.inport)
|
||||
self.connectPorts(self.processor2.outport, self.processor3.inport)
|
||||
|
||||
class Two(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Two")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0), 1)
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(0.30, 3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
|
||||
class DualChain_local(CoupledDEVS):
|
||||
def __init__(self, ta):
|
||||
CoupledDEVS.__init__(self, "DualChain")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0))
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(ta, 2))
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(0.30, 3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.generator.outport, self.processor2.inport)
|
||||
|
||||
class DualChain(CoupledDEVS):
|
||||
def __init__(self, ta):
|
||||
CoupledDEVS.__init__(self, "DualChain")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0), 1)
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(ta, 2), 2)
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(0.30, 3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.generator.outport, self.processor2.inport)
|
||||
|
||||
class DualChainMP_local(CoupledDEVS):
|
||||
def __init__(self, ta):
|
||||
CoupledDEVS.__init__(self, "DualChainMP")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0))
|
||||
self.processor1 = self.addSubModel(CoupledProcessorMP(0.66))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
|
||||
class DualChainMP(CoupledDEVS):
|
||||
def __init__(self, ta):
|
||||
CoupledDEVS.__init__(self, "DualChainMP")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0), 1)
|
||||
self.processor1 = self.addSubModel(CoupledProcessorMP(0.66), 2)
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
|
||||
class DualDepthProcessor_local(CoupledDEVS):
|
||||
def __init__(self, ta):
|
||||
CoupledDEVS.__init__(self, "DualDepthProcessor")
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(ta, 1))
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(ta, 2))
|
||||
self.connectPorts(self.inport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
self.connectPorts(self.processor2.outport, self.outport)
|
||||
|
||||
class DualDepthProcessor(CoupledDEVS):
|
||||
def __init__(self, ta):
|
||||
CoupledDEVS.__init__(self, "DualDepthProcessor")
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(ta, 1), 2)
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(ta, 2))
|
||||
self.connectPorts(self.inport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
self.connectPorts(self.processor2.outport, self.outport)
|
||||
|
||||
class DualDepth_local(CoupledDEVS):
|
||||
def __init__(self, ta):
|
||||
CoupledDEVS.__init__(self, "DualDepth")
|
||||
self.generator = self.addSubModel(Generator("Generator", 1.0))
|
||||
self.processor = self.addSubModel(DualDepthProcessor_local(ta))
|
||||
self.connectPorts(self.generator.outport, self.processor.inport)
|
||||
|
||||
class DualDepth(CoupledDEVS):
|
||||
def __init__(self, ta):
|
||||
CoupledDEVS.__init__(self, "DualDepth")
|
||||
self.generator = self.addSubModel(Generator("Generator", 1.0))
|
||||
self.processor = self.addSubModel(DualDepthProcessor(ta), 1)
|
||||
self.connectPorts(self.generator.outport, self.processor.inport)
|
||||
|
||||
class Nested_local(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Nested")
|
||||
self.generator = self.addSubModel(Generator("Generator", 1))
|
||||
self.processor = self.addSubModel(NestedProcessor("NProcessor"))
|
||||
self.connectPorts(self.generator.outport, self.processor.inport)
|
||||
|
||||
class MultiNested(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "MultiNested")
|
||||
self.generator = self.addSubModel(Generator("Generator", 1))
|
||||
self.processor1 = self.addSubModel(NestedProcessor("NProcessor1"), 1)
|
||||
self.processor2 = self.addSubModel(NestedProcessor("NProcessor2"), 2)
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
|
||||
class Local(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Local")
|
||||
self.generator = self.addSubModel(Generator("Generator", 1))
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(1, 2))
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(1, 3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
|
||||
class OptimizableChain(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "OptimizableChain")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0))
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(0.66, 2), 1)
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(0.30, 3), 2)
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
|
||||
class HugeOptimizableChain(CoupledDEVS):
|
||||
def __init__(self, iterations):
|
||||
CoupledDEVS.__init__(self, "HugeOptimizableChain")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0))
|
||||
self.processor0 = self.addSubModel(CoupledHeavyProcessor(0.77, 10, iterations))
|
||||
self.processor1 = self.addSubModel(CoupledHeavyProcessor(0.66, 10, iterations), 1)
|
||||
self.processor2 = self.addSubModel(CoupledHeavyProcessor(0.30, 10, iterations), 2)
|
||||
self.connectPorts(self.generator.outport, self.processor0.inport)
|
||||
self.connectPorts(self.processor0.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor0.outport, self.processor2.inport)
|
||||
|
||||
class HugeOptimizableLocalChain(CoupledDEVS):
|
||||
def __init__(self, iterations):
|
||||
CoupledDEVS.__init__(self, "HugeOptimizableChain")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0))
|
||||
self.processor0 = self.addSubModel(CoupledHeavyProcessor(0.77, 10, iterations))
|
||||
self.processor1 = self.addSubModel(CoupledHeavyProcessor(0.66, 10, iterations))
|
||||
self.processor2 = self.addSubModel(CoupledHeavyProcessor(0.30, 10, iterations))
|
||||
self.connectPorts(self.generator.outport, self.processor0.inport)
|
||||
self.connectPorts(self.processor0.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor0.outport, self.processor2.inport)
|
||||
|
||||
class LocalLong(CoupledDEVS):
|
||||
def __init__(self, name):
|
||||
CoupledDEVS.__init__(self, name)
|
||||
self.generator = self.addSubModel(Generator("Generator", 1))
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(0.66, 20))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
|
||||
class ParallelChain(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "ParallelChain")
|
||||
self.processor1 = self.addSubModel(LocalLong('Local1'), 1)
|
||||
self.processor2 = self.addSubModel(LocalLong('Local2'), 2)
|
||||
|
||||
class ParallelLocalChain(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "ParallelLocalChain")
|
||||
self.processor1 = self.addSubModel(LocalLong('Local1'))
|
||||
self.processor2 = self.addSubModel(LocalLong('Local2'))
|
||||
|
||||
class ChainNoPeekPoke(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "ChainNoPeekPoke")
|
||||
self.generator = self.addSubModel(CoupledGeneratorNPP(1.0))
|
||||
self.processor1 = self.addSubModel(CoupledProcessorNPP(0.66, 2))
|
||||
self.processor2 = self.addSubModel(CoupledProcessorNPP(0.30, 3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
|
||||
class ChainPeekPoke(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "ChainPeekPoke")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0))
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(0.66, 2))
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(0.30, 3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
|
||||
class AutoDistChain(CoupledDEVS):
|
||||
def __init__(self, nodes, totalAtomics, iterations):
|
||||
CoupledDEVS.__init__(self, "AutoDistChain")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0))
|
||||
self.processors = []
|
||||
have = 0
|
||||
ta = 0.66
|
||||
for i in range(nodes):
|
||||
shouldhave = (float(i+1) / nodes) * totalAtomics
|
||||
num = int(shouldhave - have)
|
||||
have += num
|
||||
if i == 0:
|
||||
self.processors.append(self.addSubModel(CoupledHeavyProcessor(ta, num, iterations, "HeavyProcessor_" + str(i))))
|
||||
else:
|
||||
self.processors.append(self.addSubModel(CoupledHeavyProcessor(ta, num, iterations, "HeavyProcessor_" + str(i)), i))
|
||||
self.connectPorts(self.generator.outport, self.processors[0].inport)
|
||||
for i in range(len(self.processors)-1):
|
||||
self.connectPorts(self.processors[i].outport, self.processors[i+1].inport)
|
||||
|
||||
class RemoteDC(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Root")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0))
|
||||
self.processor1 = self.addSubModel(RemoteDCProcessor(), 1)
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(0.30, 3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
|
||||
class MultipleInputs(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "MultipleInputs")
|
||||
self.generator = self.addSubModel(Generator(1.0))
|
||||
self.processors1 = []
|
||||
for i in xrange(5):
|
||||
self.processors1.append(self.addSubModel(Processor("1-" + str(i), 0.3), 1))
|
||||
self.connectPorts(self.generator.outport, self.processors1[-1].inport)
|
||||
self.processors2 = []
|
||||
for i in xrange(2):
|
||||
self.processors2.append(self.addSubModel(Processor("2-" + str(i), 0.3), 2))
|
||||
for s in self.processors1:
|
||||
self.connectPorts(s.outport, self.processors2[-1].inport)
|
||||
|
||||
class MultipleInputs_local(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "MultipleInputs")
|
||||
self.generator = self.addSubModel(Generator(1.0))
|
||||
self.processors1 = []
|
||||
for i in xrange(5):
|
||||
self.processors1.append(self.addSubModel(Processor("1-" + str(i), 0.3)))
|
||||
self.connectPorts(self.generator.outport, self.processors1[-1].inport)
|
||||
self.processors2 = []
|
||||
for i in xrange(2):
|
||||
self.processors2.append(self.addSubModel(Processor("2-" + str(i), 0.3)))
|
||||
for s in self.processors1:
|
||||
self.connectPorts(s.outport, self.processors2[-1].inport)
|
||||
|
||||
class DoubleLayer1(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Layer1")
|
||||
self.inport = self.addInPort("inport")
|
||||
self.processor = self.addSubModel(Processor("Processor", 0.3))
|
||||
self.connectPorts(self.inport, self.processor.inport)
|
||||
|
||||
class DoubleLayer2(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Layer2")
|
||||
self.lower = self.addSubModel(DoubleLayer1())
|
||||
self.inport1 = self.addInPort("inport1")
|
||||
self.inport2 = self.addInPort("inport2")
|
||||
self.connectPorts(self.inport1, self.lower.inport)
|
||||
self.connectPorts(self.inport2, self.lower.inport)
|
||||
|
||||
class DoubleLayerRoot(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Root")
|
||||
self.lower = self.addSubModel(DoubleLayer2())
|
||||
self.generator = self.addSubModel(Generator("Generator", 1))
|
||||
self.connectPorts(self.generator.outport, self.lower.inport1)
|
||||
self.connectPorts(self.generator.outport, self.lower.inport2)
|
||||
|
||||
class DSDEVSRoot(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Root")
|
||||
self.submodel = self.addSubModel(GeneratorDS())
|
||||
self.submodel2 = self.addSubModel(Processor())
|
||||
self.submodel3 = self.addSubModel(Processor())
|
||||
self.connectPorts(self.submodel.outport, self.submodel2.inport)
|
||||
self.connectPorts(self.submodel2.outport, self.submodel3.inport)
|
||||
self.connectPorts(self.submodel.outport, self.submodel3.inport)
|
||||
|
||||
def modelTransition(self, state):
|
||||
self.removeSubModel(self.submodel2)
|
||||
self.submodel2 = self.addSubModel(Processor())
|
||||
self.connectPorts(self.submodel2.outport, self.submodel3.inport)
|
||||
self.submodel4 = self.addSubModel(CoupledProcessor(0.2, 3))
|
||||
self.connectPorts(self.submodel3.outport, self.submodel4.inport)
|
||||
self.submodelX = self.addSubModel(ElapsedNothing())
|
||||
return False
|
||||
|
||||
class ElapsedNothing(AtomicDEVS):
|
||||
def __init__(self):
|
||||
AtomicDEVS.__init__(self, "ElapsedNothing")
|
||||
self.elapsed = 0.3
|
||||
self.state = 1
|
||||
|
||||
def intTransition(self):
|
||||
return 0
|
||||
|
||||
def timeAdvance(self):
|
||||
return self.state if self.state > 0 else float('inf')
|
||||
|
||||
class GeneratorDS(Generator):
|
||||
def __init__(self):
|
||||
Generator.__init__(self, "GEN")
|
||||
self.elapsed = 0.5
|
||||
|
||||
def outputFnc(self):
|
||||
if self.state.generated < 1:
|
||||
return Generator.outputFnc(self)
|
||||
else:
|
||||
return {}
|
||||
|
||||
def modelTransition(self, state):
|
||||
if self.state.generated == 1:
|
||||
self.removePort(self.outport)
|
||||
del self.outport
|
||||
return self.state.generated == 1
|
||||
|
||||
class ClassicGenerator(AtomicDEVS):
|
||||
def __init__(self):
|
||||
AtomicDEVS.__init__(self, "Generator")
|
||||
self.state = None
|
||||
self.outport = self.addOutPort("outport")
|
||||
|
||||
def intTransition(self):
|
||||
return None
|
||||
|
||||
def outputFnc(self):
|
||||
return {self.outport: 1}
|
||||
|
||||
def timeAdvance(self):
|
||||
return 1
|
||||
|
||||
class ClassicProcessor(AtomicDEVS):
|
||||
def __init__(self, name):
|
||||
AtomicDEVS.__init__(self, "Processor_%s" % name)
|
||||
self.state = None
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
|
||||
def intTransition(self):
|
||||
return None
|
||||
|
||||
def outputFnc(self):
|
||||
return {self.outport: self.state}
|
||||
|
||||
def extTransition(self, inputs):
|
||||
self.state = inputs[self.inport]
|
||||
return self.state
|
||||
|
||||
def timeAdvance(self):
|
||||
return (1.0 if self.state is not None else INFINITY)
|
||||
|
||||
class ClassicCoupledProcessor(CoupledDEVS):
|
||||
def __init__(self, it, namecounter):
|
||||
CoupledDEVS.__init__(self, "CoupledProcessor_%s_%s" % (it, namecounter))
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
if it != 0:
|
||||
self.subproc = self.addSubModel(ClassicCoupledProcessor(it-1, 0))
|
||||
else:
|
||||
self.subproc = self.addSubModel(ClassicProcessor(0))
|
||||
self.subproc2 = self.addSubModel(ClassicProcessor(1))
|
||||
if it != 0:
|
||||
self.subproc3 = self.addSubModel(ClassicCoupledProcessor(it-1, 2))
|
||||
else:
|
||||
self.subproc3 = self.addSubModel(ClassicProcessor(2))
|
||||
self.connectPorts(self.inport, self.subproc.inport)
|
||||
self.connectPorts(self.subproc.outport, self.subproc2.inport)
|
||||
self.connectPorts(self.subproc2.outport, self.subproc3.inport)
|
||||
self.connectPorts(self.subproc3.outport, self.outport)
|
||||
|
||||
def select(self, immChildren):
|
||||
if self.subproc3 in immChildren:
|
||||
return self.subproc3
|
||||
elif self.subproc2 in immChildren:
|
||||
return self.subproc2
|
||||
elif self.subproc in immChildren:
|
||||
return self.subproc
|
||||
else:
|
||||
return immChildren[0]
|
||||
|
||||
class ClassicCoupled(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Coupled")
|
||||
self.generator = self.addSubModel(ClassicGenerator())
|
||||
self.processor = self.addSubModel(ClassicCoupledProcessor(3, 0))
|
||||
self.connectPorts(self.generator.outport, self.processor.inport)
|
||||
|
||||
def select(self, immChildren):
|
||||
if self.processor in immChildren:
|
||||
return self.processor
|
||||
else:
|
||||
return immChildren[0]
|
||||
|
||||
class RandomProcessorState(object):
|
||||
def __init__(self, seed):
|
||||
from pypdevs.randomGenerator import RandomGenerator
|
||||
self.randomGenerator = RandomGenerator(seed)
|
||||
self.queue = []
|
||||
self.proctime = self.randomGenerator.uniform(0.3, 3.0)
|
||||
|
||||
def __str__(self):
|
||||
return "Random Processor State -- " + str(self.proctime)
|
||||
|
||||
class RandomProcessor(AtomicDEVS):
|
||||
def __init__(self, seed):
|
||||
AtomicDEVS.__init__(self, "RandomProcessor_" + str(seed))
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
self.state = RandomProcessorState(seed)
|
||||
|
||||
def intTransition(self):
|
||||
self.state.queue = self.state.queue[1:]
|
||||
self.state.proctime = self.state.randomGenerator.uniform(0.3, 3.0)
|
||||
return self.state
|
||||
|
||||
def extTransition(self, inputs):
|
||||
if self.state.queue:
|
||||
self.state.proctime -= self.elapsed
|
||||
self.state.queue.extend(inputs[self.inport])
|
||||
return self.state
|
||||
|
||||
def outputFnc(self):
|
||||
return {self.outport: [self.state.queue[0]]}
|
||||
|
||||
def timeAdvance(self):
|
||||
if self.state.queue:
|
||||
return self.state.proctime
|
||||
else:
|
||||
return INFINITY
|
||||
|
||||
class RandomCoupled(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Coupled")
|
||||
self.generator = self.addSubModel(Generator())
|
||||
self.processor1 = self.addSubModel(RandomProcessor(1), 1)
|
||||
self.processor2 = self.addSubModel(RandomProcessor(2), 2)
|
||||
self.processor3 = self.addSubModel(RandomProcessor(3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
self.connectPorts(self.processor2.outport, self.processor3.inport)
|
||||
|
||||
class RandomCoupled_local(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Coupled")
|
||||
self.generator = self.addSubModel(Generator())
|
||||
self.processor1 = self.addSubModel(RandomProcessor(1))
|
||||
self.processor2 = self.addSubModel(RandomProcessor(2))
|
||||
self.processor3 = self.addSubModel(RandomProcessor(3))
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
self.connectPorts(self.processor2.outport, self.processor3.inport)
|
||||
|
||||
class Chain_bad(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Chain")
|
||||
self.generator = self.addSubModel(CoupledGenerator(1.0), 0)
|
||||
self.processor1 = self.addSubModel(CoupledProcessor(0.66, 2), 1)
|
||||
self.processor2 = self.addSubModel(CoupledProcessor(0.66, 3), 2)
|
||||
self.processor3 = self.addSubModel(CoupledProcessor(0.66, 4), 1)
|
||||
self.processor4 = self.addSubModel(CoupledProcessor(0.66, 5), 0)
|
||||
self.processor5 = self.addSubModel(CoupledProcessor(0.30, 6), 2)
|
||||
self.connectPorts(self.generator.outport, self.processor1.inport)
|
||||
self.connectPorts(self.processor1.outport, self.processor2.inport)
|
||||
self.connectPorts(self.processor2.outport, self.processor3.inport)
|
||||
self.connectPorts(self.processor3.outport, self.processor4.inport)
|
||||
self.connectPorts(self.processor4.outport, self.processor5.inport)
|
||||
|
||||
class GeneratorClassic(AtomicDEVS):
|
||||
def __init__(self):
|
||||
AtomicDEVS.__init__(self, "Gen")
|
||||
self.outport = self.addOutPort("outport")
|
||||
self.state = True
|
||||
|
||||
def intTransition(self):
|
||||
return False
|
||||
|
||||
def outputFnc(self):
|
||||
return {self.outport: 3}
|
||||
|
||||
def timeAdvance(self):
|
||||
return 1.0 if self.state else INFINITY
|
||||
|
||||
class ProcessorClassic1(AtomicDEVS):
|
||||
def __init__(self):
|
||||
AtomicDEVS.__init__(self, "P1")
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
self.state = None
|
||||
|
||||
def intTransition(self):
|
||||
return None
|
||||
|
||||
def extTransition(self, inputs):
|
||||
return inputs[self.inport]
|
||||
|
||||
def outputFnc(self):
|
||||
return {self.outport: self.state}
|
||||
|
||||
def timeAdvance(self):
|
||||
return 1.0 if self.state is not None else INFINITY
|
||||
|
||||
class ProcessorClassic2(AtomicDEVS):
|
||||
def __init__(self):
|
||||
AtomicDEVS.__init__(self, "P2")
|
||||
self.inport1 = self.addInPort("inport1")
|
||||
self.inport2 = self.addInPort("inport2")
|
||||
self.outport = self.addOutPort("outport")
|
||||
self.state = (None, None)
|
||||
|
||||
def intTransition(self):
|
||||
return (None, None)
|
||||
|
||||
def extTransition(self, inputs):
|
||||
inp1 = inputs.get(self.inport1, None)
|
||||
inp2 = inputs.get(self.inport2, None)
|
||||
return (inp1, inp2)
|
||||
|
||||
def outputFnc(self):
|
||||
return {self.outport: self.state}
|
||||
|
||||
def timeAdvance(self):
|
||||
return 1.0 if self.state[0] is not None or self.state[1] is not None else INFINITY
|
||||
|
||||
class ProcessorClassicO2(AtomicDEVS):
|
||||
def __init__(self):
|
||||
AtomicDEVS.__init__(self, "PO2")
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport1 = self.addOutPort("outport1")
|
||||
self.outport2 = self.addOutPort("outport2")
|
||||
self.state = None
|
||||
|
||||
def intTransition(self):
|
||||
return None
|
||||
|
||||
def extTransition(self, inputs):
|
||||
return inputs[self.inport]
|
||||
|
||||
def outputFnc(self):
|
||||
return {self.outport1: self.state, self.outport2: self.state}
|
||||
|
||||
def timeAdvance(self):
|
||||
return 1.0 if self.state is not None else INFINITY
|
||||
|
||||
class ProcessorCoupledClassic(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Coupled")
|
||||
self.inport1 = self.addInPort("inport1")
|
||||
self.inport2 = self.addInPort("inport2")
|
||||
self.outport = self.addOutPort("outport")
|
||||
|
||||
self.proc1 = self.addSubModel(ProcessorClassic1())
|
||||
self.proc2 = self.addSubModel(ProcessorClassic1())
|
||||
|
||||
self.connectPorts(self.inport1, self.proc1.inport)
|
||||
self.connectPorts(self.inport2, self.proc2.inport)
|
||||
self.connectPorts(self.proc1.outport, self.outport)
|
||||
self.connectPorts(self.proc2.outport, self.outport)
|
||||
|
||||
class AllConnectClassic(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "Root")
|
||||
self.model1 = self.addSubModel(GeneratorClassic())
|
||||
self.model2 = self.addSubModel(ProcessorCoupledClassic())
|
||||
self.model3 = self.addSubModel(ProcessorClassic2())
|
||||
self.model4 = self.addSubModel(ProcessorClassic1())
|
||||
self.model5 = self.addSubModel(ProcessorClassicO2())
|
||||
self.connectPorts(self.model1.outport, self.model2.inport1)
|
||||
self.connectPorts(self.model1.outport, self.model2.inport2)
|
||||
self.connectPorts(self.model2.outport, self.model3.inport1)
|
||||
self.connectPorts(self.model2.outport, self.model3.inport2)
|
||||
self.connectPorts(self.model3.outport, self.model5.inport)
|
||||
self.connectPorts(self.model2.outport, self.model4.inport)
|
||||
self.connectPorts(self.model4.outport, self.model5.inport)
|
||||
|
||||
def trans1(inp):
|
||||
inp.eventSize += 1
|
||||
return inp
|
||||
|
||||
def trans2(inp):
|
||||
inp.eventSize = 0
|
||||
return inp
|
||||
|
||||
class ZCoupledProcessor(CoupledDEVS):
|
||||
def __init__(self, num):
|
||||
CoupledDEVS.__init__(self, "CoupledProcessor_" + str(num))
|
||||
self.inport = self.addInPort("inport")
|
||||
self.outport = self.addOutPort("outport")
|
||||
|
||||
self.coupled = []
|
||||
levels = 4
|
||||
for i in range(levels):
|
||||
self.coupled.append(self.addSubModel(Processor("Processor" + str(i), 1.0)))
|
||||
for i in range(levels-1):
|
||||
self.connectPorts(self.coupled[i].outport, self.coupled[i+1].inport, trans1)
|
||||
self.connectPorts(self.inport, self.coupled[0].inport)
|
||||
self.connectPorts(self.coupled[-1].outport, self.outport)
|
||||
|
||||
class ZChain_local(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "ROOT")
|
||||
self.gen = self.addSubModel(Generator())
|
||||
self.proc1 = self.addSubModel(ZCoupledProcessor(1))
|
||||
self.proc2 = self.addSubModel(ZCoupledProcessor(2))
|
||||
|
||||
self.connectPorts(self.gen.outport, self.proc1.inport)
|
||||
self.connectPorts(self.gen.outport, self.proc2.inport, trans2)
|
||||
|
||||
class ZChain(CoupledDEVS):
|
||||
def __init__(self):
|
||||
CoupledDEVS.__init__(self, "ROOT")
|
||||
self.gen = self.addSubModel(Generator())
|
||||
self.proc1 = self.addSubModel(ZCoupledProcessor(1), 1)
|
||||
self.proc2 = self.addSubModel(ZCoupledProcessor(2), 2)
|
||||
|
||||
self.connectPorts(self.gen.outport, self.proc1.inport)
|
||||
self.connectPorts(self.gen.outport, self.proc2.inport, trans2)
|
||||
38
test/testmodels/reinit.py
Normal file
38
test/testmodels/reinit.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#! /bin/env python
|
||||
import time
|
||||
start = time.clock()
|
||||
print("Starting at time " + str(start))
|
||||
from mpi4py import MPI
|
||||
|
||||
import models
|
||||
import sys
|
||||
from pypdevs.simulator import Simulator, loadCheckpoint
|
||||
|
||||
model = models.AutoDistChain(3, totalAtomics=500, iterations=1)
|
||||
|
||||
sim = Simulator(model)
|
||||
sim.setAllowLocalReinit(True)
|
||||
sim.setTerminationTime(40)
|
||||
sim.setVerbose("output/reinit1")
|
||||
sim1start = time.clock()
|
||||
print("Sim 1 started at " + str(sim1start))
|
||||
sim.simulate()
|
||||
sim.setReinitStateAttr(model.generator.generator, "value", 2)
|
||||
sim2start = time.clock()
|
||||
sim.setRemoveTracers()
|
||||
sim.setVerbose("output/reinit2")
|
||||
print("Sim 2 started at " + str(sim2start))
|
||||
sim.simulate()
|
||||
sim.setReinitStateAttr(model.generator.generator, "value", 3)
|
||||
sim3start = time.clock()
|
||||
print("Sim 3 started at " + str(sim3start))
|
||||
sim.setRemoveTracers()
|
||||
sim.setVerbose("output/reinit3")
|
||||
sim.simulate()
|
||||
sim3stop = time.clock()
|
||||
|
||||
print("Total runtimes: ")
|
||||
print("Init: " + str(sim1start - start))
|
||||
print("Sim 1: " + str(sim2start - sim1start))
|
||||
print("Sim 2: " + str(sim3start - sim2start))
|
||||
print("Sim 3: " + str(sim3stop - sim3start))
|
||||
101
test/testmodels/stacktracer.py
Normal file
101
test/testmodels/stacktracer.py
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
"""Stack tracer for multi-threaded applications.
|
||||
|
||||
|
||||
Usage:
|
||||
|
||||
import stacktracer
|
||||
stacktracer.trace_start("trace.html",interval=5,auto=True) # Set auto flag to always update file!
|
||||
....
|
||||
stacktracer.trace_stop()
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
from pygments import highlight
|
||||
from pygments.lexers import PythonLexer
|
||||
from pygments.formatters import HtmlFormatter
|
||||
|
||||
# Taken from http://bzimmer.ziclix.com/2008/12/17/python-thread-dumps/
|
||||
|
||||
def stacktraces():
|
||||
code = []
|
||||
for threadId, stack in sys._current_frames().items():
|
||||
code.append("\n# ThreadID: %s" % threadId)
|
||||
for filename, lineno, name, line in traceback.extract_stack(stack):
|
||||
code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
|
||||
if line:
|
||||
code.append(" %s" % (line.strip()))
|
||||
|
||||
return highlight("\n".join(code), PythonLexer(), HtmlFormatter(
|
||||
full=False,
|
||||
# style="native",
|
||||
noclasses=True,
|
||||
))
|
||||
|
||||
|
||||
# This part was made by nagylzs
|
||||
import os
|
||||
import time
|
||||
import threading
|
||||
|
||||
class TraceDumper(threading.Thread):
|
||||
"""Dump stack traces into a given file periodically."""
|
||||
def __init__(self,fpath,interval,auto):
|
||||
"""
|
||||
@param fpath: File path to output HTML (stack trace file)
|
||||
@param auto: Set flag (True) to update trace continuously.
|
||||
Clear flag (False) to update only if file not exists.
|
||||
(Then delete the file to force update.)
|
||||
@param interval: In seconds: how often to update the trace file.
|
||||
"""
|
||||
assert(interval>0.1)
|
||||
self.auto = auto
|
||||
self.interval = interval
|
||||
self.fpath = os.path.abspath(fpath)
|
||||
self.stop_requested = threading.Event()
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
def run(self):
|
||||
while not self.stop_requested.isSet():
|
||||
time.sleep(self.interval)
|
||||
if self.auto or not os.path.isfile(self.fpath):
|
||||
self.stacktraces()
|
||||
|
||||
def stop(self):
|
||||
self.stop_requested.set()
|
||||
self.join()
|
||||
try:
|
||||
if os.path.isfile(self.fpath):
|
||||
os.unlink(self.fpath)
|
||||
except:
|
||||
pass
|
||||
|
||||
def stacktraces(self):
|
||||
fout = file(self.fpath,"wb+")
|
||||
try:
|
||||
fout.write(stacktraces())
|
||||
finally:
|
||||
fout.close()
|
||||
|
||||
|
||||
_tracer = None
|
||||
def trace_start(fpath,interval=5,auto=True):
|
||||
"""Start tracing into the given file."""
|
||||
global _tracer
|
||||
if _tracer is None:
|
||||
_tracer = TraceDumper(fpath,interval,auto)
|
||||
_tracer.setDaemon(True)
|
||||
_tracer.start()
|
||||
else:
|
||||
raise Exception("Already tracing to %s"%_tracer.fpath)
|
||||
|
||||
def trace_stop():
|
||||
"""Stop tracing."""
|
||||
global _tracer
|
||||
if _tracer is None:
|
||||
raise Exception("Not tracing, cannot stop.")
|
||||
else:
|
||||
_trace.stop()
|
||||
_trace = None
|
||||
339
test/testmodels/trafficLightModel.py
Normal file
339
test/testmodels/trafficLightModel.py
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
# -*- coding: Latin-1 -*-
|
||||
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
||||
# trafficLight.py --- simple Traffic Light example
|
||||
# --------------------------------
|
||||
# October 2005
|
||||
# Hans Vangheluwe
|
||||
# McGill University (Montréal)
|
||||
# --------------------------------
|
||||
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
||||
|
||||
# Add the directory where pydevs lives to Python's import path
|
||||
import sys
|
||||
|
||||
# Import code for DEVS model representation:
|
||||
from pypdevs.infinity import *
|
||||
from pypdevs.DEVS import *
|
||||
|
||||
# Import for uniform random number generators
|
||||
from random import uniform
|
||||
from random import randint
|
||||
|
||||
# ====================================================================== #
|
||||
|
||||
class TrafficLightMode:
|
||||
|
||||
"""Encapsulates the system's state
|
||||
"""
|
||||
|
||||
###
|
||||
def __init__(self, current="red"):
|
||||
"""Constructor (parameterizable).
|
||||
"""
|
||||
self.set(current)
|
||||
|
||||
def set(self, value="red"):
|
||||
self.__colour=value
|
||||
|
||||
def get(self):
|
||||
return self.__colour
|
||||
|
||||
def __str__(self):
|
||||
return self.get()
|
||||
|
||||
class TrafficLight(AtomicDEVS):
|
||||
"""A traffic light
|
||||
"""
|
||||
|
||||
###
|
||||
def __init__(self, name=None):
|
||||
"""Constructor (parameterizable).
|
||||
"""
|
||||
|
||||
# Always call parent class' constructor FIRST:
|
||||
AtomicDEVS.__init__(self, name)
|
||||
|
||||
# STATE:
|
||||
# Define 'state' attribute (initial sate):
|
||||
self.state = TrafficLightMode("red")
|
||||
|
||||
# PORTS:
|
||||
# Declare as many input and output ports as desired
|
||||
# (usually store returned references in local variables):
|
||||
self.INTERRUPT = self.addInPort(name="INTERRUPT")
|
||||
self.OBSERVED = self.addOutPort(name="OBSERVED")
|
||||
|
||||
###
|
||||
def extTransition(self, inputs):
|
||||
"""External Transition Function."""
|
||||
|
||||
# Compute the new state 'Snew' based (typically) on current
|
||||
# State, Elapsed time parameters and calls to 'self.peek(self.IN)'.
|
||||
#input = self.peek(self.INTERRUPT)
|
||||
input = inputs[self.INTERRUPT][0]
|
||||
|
||||
state = self.state.get()
|
||||
|
||||
if input == "toManual":
|
||||
if state == "manual":
|
||||
# staying in manual mode
|
||||
return TrafficLightMode("manual")
|
||||
if state in ("red", "green", "yellow"):
|
||||
return TrafficLightMode("manual")
|
||||
else:
|
||||
raise DEVSException(\
|
||||
"unknown state <%s> in TrafficLight external transition function"\
|
||||
% state)
|
||||
|
||||
if input == "toAutonomous":
|
||||
if state == "manual":
|
||||
return TrafficLightMode("red")
|
||||
else:
|
||||
raise DEVSException(\
|
||||
"unknown state <%s> in TrafficLight external transition function"\
|
||||
% state)
|
||||
|
||||
raise DEVSException(\
|
||||
"unknown input <%s> in TrafficLight external transition function"\
|
||||
% input)
|
||||
|
||||
###
|
||||
def intTransition(self):
|
||||
"""Internal Transition Function.
|
||||
"""
|
||||
|
||||
state = self.state.get()
|
||||
|
||||
if state == "red":
|
||||
return TrafficLightMode("green")
|
||||
elif state == "green":
|
||||
return TrafficLightMode("yellow")
|
||||
elif state == "yellow":
|
||||
return TrafficLightMode("red")
|
||||
else:
|
||||
raise DEVSException(\
|
||||
"unknown state <%s> in TrafficLight internal transition function"\
|
||||
% state)
|
||||
|
||||
###
|
||||
def outputFnc(self):
|
||||
"""Output Funtion.
|
||||
"""
|
||||
|
||||
# A colourblind observer sees "grey" instead of "red" or "green".
|
||||
|
||||
# BEWARE: ouput is based on the OLD state
|
||||
# and is produced BEFORE making the transition.
|
||||
# We'll encode an "observation" of the state the
|
||||
# system will transition to !
|
||||
|
||||
# Send messages (events) to a subset of the atomic-DEVS'
|
||||
# output ports by means of the 'poke' method, i.e.:
|
||||
# The content of the messages is based (typically) on current State.
|
||||
|
||||
state = self.state.get()
|
||||
|
||||
if state == "red":
|
||||
return {self.OBSERVED: ["grey"]}
|
||||
#self.poke(self.OBSERVED, "grey")
|
||||
# NOT self.poke(self.OBSERVED, "grey")
|
||||
elif state == "green":
|
||||
return {self.OBSERVED: ["yellow"]}
|
||||
#self.poke(self.OBSERVED, "yellow")
|
||||
# NOT self.poke(self.OBSERVED, "grey")
|
||||
elif state == "yellow":
|
||||
return {self.OBSERVED: ["grey"]}
|
||||
#self.poke(self.OBSERVED, "grey")
|
||||
# NOT self.poke(self.OBSERVED, "yellow")
|
||||
else:
|
||||
raise DEVSException(\
|
||||
"unknown state <%s> in TrafficLight external transition function"\
|
||||
% state)
|
||||
|
||||
###
|
||||
def timeAdvance(self):
|
||||
"""Time-Advance Function.
|
||||
"""
|
||||
|
||||
# Compute 'ta', the time to the next scheduled internal transition,
|
||||
# based (typically) on current State.
|
||||
|
||||
state = self.state.get()
|
||||
|
||||
if state == "red":
|
||||
return 3
|
||||
elif state == "green":
|
||||
return 2
|
||||
elif state == "yellow":
|
||||
return 1
|
||||
elif state == "manual":
|
||||
return INFINITY
|
||||
else:
|
||||
raise DEVSException(\
|
||||
"unknown state <%s> in TrafficLight time advance transition function"\
|
||||
% state)
|
||||
|
||||
# ====================================================================== #
|
||||
|
||||
class PolicemanMode:
|
||||
|
||||
"""Encapsulates the Policeman's state
|
||||
"""
|
||||
|
||||
###
|
||||
def __init__(self, current="idle"):
|
||||
"""Constructor (parameterizable).
|
||||
"""
|
||||
self.set(current)
|
||||
|
||||
def set(self, value="idle"):
|
||||
self.__mode=value
|
||||
|
||||
def get(self):
|
||||
return self.__mode
|
||||
|
||||
def __str__(self):
|
||||
return self.get()
|
||||
|
||||
class Policeman(AtomicDEVS):
|
||||
"""A policeman producing "toManual" and "toAutonomous" events:
|
||||
"toManual" when going from "idle" to "working" mode
|
||||
"toAutonomous" when going from "working" to "idle" mode
|
||||
"""
|
||||
|
||||
###
|
||||
def __init__(self, name=None):
|
||||
"""Constructor (parameterizable).
|
||||
"""
|
||||
|
||||
# Always call parent class' constructor FIRST:
|
||||
AtomicDEVS.__init__(self, name)
|
||||
|
||||
# STATE:
|
||||
# Define 'state' attribute (initial sate):
|
||||
self.state = PolicemanMode("idle")
|
||||
|
||||
# ELAPSED TIME:
|
||||
# Initialize 'elapsed time' attribute if required
|
||||
# (by default, value is 0.0):
|
||||
self.elapsed = 0
|
||||
|
||||
# PORTS:
|
||||
# Declare as many input and output ports as desired
|
||||
# (usually store returned references in local variables):
|
||||
self.OUT = self.addOutPort(name="OUT")
|
||||
|
||||
###
|
||||
# Autonomous system (no input ports),
|
||||
# so no External Transition Function required
|
||||
#
|
||||
|
||||
###
|
||||
def intTransition(self):
|
||||
"""Internal Transition Function.
|
||||
The policeman works forever, so only one mode.
|
||||
"""
|
||||
|
||||
state = self.state.get()
|
||||
|
||||
if state == "idle":
|
||||
return PolicemanMode("working")
|
||||
elif state == "working":
|
||||
return PolicemanMode("idle")
|
||||
else:
|
||||
raise DEVSException(\
|
||||
"unknown state <%s> in Policeman internal transition function"\
|
||||
% state)
|
||||
|
||||
###
|
||||
def outputFnc(self):
|
||||
"""Output Funtion.
|
||||
"""
|
||||
|
||||
# Send messages (events) to a subset of the atomic-DEVS'
|
||||
# output ports by means of the 'poke' method, i.e.:
|
||||
# The content of the messages is based (typically) on current State.
|
||||
|
||||
state = self.state.get()
|
||||
|
||||
if state == "idle":
|
||||
return {self.OUT: ["toManual"]}
|
||||
#self.poke(self.OUT, "toManual")
|
||||
elif state == "working":
|
||||
return {self.OUT: ["toAutonomous"]}
|
||||
#self.poke(self.OUT, "toAutonomous")
|
||||
else:
|
||||
raise DEVSException(\
|
||||
"unknown state <%s> in Policeman output function"\
|
||||
% state)
|
||||
|
||||
###
|
||||
def timeAdvance(self):
|
||||
"""Time-Advance Function.
|
||||
"""
|
||||
|
||||
# Compute 'ta', the time to the next scheduled internal transition,
|
||||
# based (typically) on current State.
|
||||
|
||||
state = self.state.get()
|
||||
|
||||
if state == "idle":
|
||||
return 200
|
||||
elif state == "working":
|
||||
return 100
|
||||
else:
|
||||
raise DEVSException(\
|
||||
"unknown state <%s> in Policeman time advance function"\
|
||||
% state)
|
||||
|
||||
# ====================================================================== #
|
||||
|
||||
class TrafficSystem(CoupledDEVS):
|
||||
|
||||
def __init__(self, name=None):
|
||||
""" A simple traffic system consisting of a Policeman and a TrafficLight.
|
||||
"""
|
||||
|
||||
# Always call parent class' constructor FIRST:
|
||||
CoupledDEVS.__init__(self, name)
|
||||
|
||||
# Declare the coupled model's output ports:
|
||||
# Autonomous, so no output ports
|
||||
#self.OUT = self.addOutPort(name="OUT")
|
||||
|
||||
# Declare the coupled model's sub-models:
|
||||
|
||||
# The Policeman generating interrupts
|
||||
self.policeman = self.addSubModel(Policeman(name="policeman"))
|
||||
|
||||
# The TrafficLight
|
||||
self.trafficLight = self.addSubModel(TrafficLight(name="trafficLight"))
|
||||
|
||||
# Only connect ...
|
||||
self.connectPorts(self.policeman.OUT, self.trafficLight.INTERRUPT)
|
||||
#self.connectPorts(self.trafficLight.OBSERVED, self.OUT)
|
||||
|
||||
def select(self, immList):
|
||||
"""Give the Policeman highest priority.
|
||||
Note how the technique used below can
|
||||
be generalized to encode priorities based on model type.
|
||||
To distinguish between models of the same type,
|
||||
the name or unique ID should be used.
|
||||
"""
|
||||
# return the first Policeman instance in the immList
|
||||
for i in range(len(immList)):
|
||||
#if immList[i].__class__ == TrafficLight:
|
||||
if immList[i].__class__ == Policeman:
|
||||
return immList[i]
|
||||
|
||||
# if no Policeman instances found, return the last entry
|
||||
return immList[-1]
|
||||
|
||||
# Alternative: randomly choose among imminent submodels
|
||||
#return immList[randint(0,len(immList))]
|
||||
|
||||
# If the select method is not defined, the immList[0]
|
||||
# will be chosen by default.
|
||||
|
||||
# ====================================================================== #
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue