|
@@ -7,6 +7,8 @@ from kernel.main import ModelverseKernel as MvK
|
|
|
from pypdevs.DEVS import AtomicDEVS, CoupledDEVS
|
|
|
from pypdevs.simulator import Simulator
|
|
|
|
|
|
+import json
|
|
|
+
|
|
|
def translate(operation):
|
|
|
return {
|
|
|
"CN": "create_node",
|
|
@@ -105,19 +107,99 @@ class ModelverseState(AtomicDEVS):
|
|
|
def timeAdvance(self):
|
|
|
return self.state.timer
|
|
|
|
|
|
+class MvKState(object):
|
|
|
+ def __init__(self):
|
|
|
+ self.mvk = MvK()
|
|
|
+
|
|
|
class ModelverseKernel(AtomicDEVS):
|
|
|
def __init__(self):
|
|
|
AtomicDEVS.__init__(self, "MvK")
|
|
|
- self.mvk = MvK()
|
|
|
+ self.state = MvKState()
|
|
|
+
|
|
|
+ self.from_mvi = self.addInPort("from_MvI")
|
|
|
+ self.from_mvs = self.addInPort("from_MvS")
|
|
|
+ self.to_mvi = self.addOutPort("to_MvI")
|
|
|
+ self.to_mvs = self.addOutPort("to_MvS")
|
|
|
+
|
|
|
+ def extTransition(self, inputs):
|
|
|
+ if self.from_mvi in inputs:
|
|
|
+ # Got input from MvI, so we queue it
|
|
|
+ elif self.from_mvs in inputs:
|
|
|
+ # Got input from MvS, so we can continue processing
|
|
|
+
|
|
|
+ return self.state
|
|
|
+
|
|
|
+class MvIState():
|
|
|
+ def __init__(self):
|
|
|
+ self.operations = []
|
|
|
+ self.output = []
|
|
|
|
|
|
class ModelverseInterface(AtomicDEVS):
|
|
|
def __init__(self):
|
|
|
AtomicDEVS.__init__(self, "MvI")
|
|
|
+ self.state = MvIState()
|
|
|
|
|
|
-class Network(AtomicDEVS):
|
|
|
+ self.to_mvk = self.addOutPort("to_MvK")
|
|
|
+ self.from_mvk = self.addInPort("from_MvK")
|
|
|
+
|
|
|
+ def intTransition(self):
|
|
|
+ self.state.operations = []
|
|
|
+ return self.state
|
|
|
+
|
|
|
+ def extTransition(self, inputs):
|
|
|
+ for inp in inputs[self.from_mvk]:
|
|
|
+ self.state.output.append(inp)
|
|
|
+ return self.state
|
|
|
+
|
|
|
+ def outputFnc(self):
|
|
|
+ return {self.to_mvk: [json.dumps(self.state.operations)]}
|
|
|
+
|
|
|
+class NetworkState(object):
|
|
|
def __init__(self):
|
|
|
+ self.processing = []
|
|
|
+ self.timer = float("inf")
|
|
|
+
|
|
|
+class Network(AtomicDEVS):
|
|
|
+ def __init__(self, latency, bytes_per_second):
|
|
|
AtomicDEVS.__init__(self, "Network")
|
|
|
+ self.state = NetworkState()
|
|
|
+
|
|
|
+ self.input_port = self.addInPort("input_port")
|
|
|
+ self.output_port = self.addOutPort("output_port")
|
|
|
+
|
|
|
+ self.latency = latency
|
|
|
+ self.bytes_per_second = bytes_per_second
|
|
|
+
|
|
|
+ def intTransition(self):
|
|
|
+ self.state.processing.pop(0)
|
|
|
+ if self.state.processing:
|
|
|
+ self.state.timer = len(self.state.processing[0]) / self.bytes_per_second + self.latency
|
|
|
+ else:
|
|
|
+ self.state.timer = float("inf")
|
|
|
+ return self.state
|
|
|
+
|
|
|
+ def extTransition(self, inputs):
|
|
|
+ self.state.timer -= self.elapsed
|
|
|
+ self.state.processing.extend(inputs[self.input_port])
|
|
|
+ return self.state
|
|
|
+
|
|
|
+ def outputFnc(self):
|
|
|
+ return {self.output_port: [self.state.processing[0]]}
|
|
|
+
|
|
|
+ def timeAdvance(self):
|
|
|
+ return self.state.timer
|
|
|
|
|
|
class System(CoupledDEVS):
|
|
|
def __init__(self):
|
|
|
CoupledDEVS.__init__(self, "System")
|
|
|
+
|
|
|
+ self.mvi = self.addSubModel(ModelverseInterface())
|
|
|
+ self.mvk = self.addSubModel(ModelverseKernel())
|
|
|
+ self.mvs = self.addSubModel(ModelverseState())
|
|
|
+ self.mvi2mvk = self.addSubModel(Network(mvi2mvk_latency, mvi2mvk_bandwidth))
|
|
|
+ self.mvk2mvs = self.addSubModel(Network(mvk2mvs_latency, mvk2mvs_bandwidth))
|
|
|
+ self.mvs2mvk = self.addSubModel(Network(mvs2mvk_latency, mvs2mvk_bandwidth))
|
|
|
+ self.mvk2mvi = self.addSubModel(Network(mvk2mvi_latency, mvk2mvi_bandwidth))
|
|
|
+
|
|
|
+ self.connectPorts(self.mvi.to_mvk, self.mvi2mvk.input_port)
|
|
|
+ self.connectPorts(self.mvi2mvk.output_port, self.mvk.from_mvi)
|