Przeglądaj źródła

fixed problem with dLI model, added basic dot language generator

Snej69420 11 miesięcy temu
rodzic
commit
93a0a4374d
2 zmienionych plików z 38 dodań i 7 usunięć
  1. 35 6
      devstone/pythonpdevs/devstone.py
  2. 3 1
      devstone/pythonpdevs/main.py

+ 35 - 6
devstone/pythonpdevs/devstone.py

@@ -6,6 +6,7 @@ from pypdevs.DEVS import AtomicDEVS, CoupledDEVS
 from pypdevs.infinity import INFINITY
 from pypdevs.simulator import Simulator
 
+from graphviz import Source
 
 class DelayedAtomic(AtomicDEVS):
     def __init__(self, name: str, int_delay: float, ext_delay: float, add_out_port: bool = False, prep_time=0.0, mode:str = ""):
@@ -172,6 +173,35 @@ class DEVStoneWrapper(CoupledDEVS, ABC):
         result.append(coupled)
         return "".join(result)
 
+    def dot(self, output: bool=False) -> None:
+        result = ("\n\ndigraph {\n\tlayout=dot;"
+                  "\n\tnodesep=0.25;"
+                  "\n\tranksep=0.2;"
+                  "\n\trankdir=LR;"
+                  "\n\tsplines=ortho;\n")
+        result += f"\tCoupled_{self.depth}[shape=box, label=\"C_{self.depth}\"];\n"
+        coupled = self.component_set[0]
+        result += f"\t{coupled.name}[shape=box, label=\"{'C_' + '_'.join(coupled.name.split('_')[1:3])}\"];\n"
+
+        for model in self.models:
+            result += f"\t{model.name}[shape=ellipse, label=\"{'A_' + '_'.join(model.name.split('_')[1:3])}\"];\n"
+
+        for connections in self.i_in.outline:
+            result += f"\tCoupled_{self.depth}:i_in -> {str(connections).split('.')[2]}:{connections.name};\n"
+
+        for model in self.models:
+            if not hasattr(model, "o_out"):
+                continue
+            for connections in model.o_out.outline:
+                result += f"\t{model.name}:o_out -> {str(connections).split('.')[2]}:{connections.name};\n"
+        result += "}\n"
+
+        src = Source(result)
+        src.view(filename=f'graph_coupled_{self.depth}')  # Opens in default PDF viewer
+
+        if output:
+            print(result)
+
     @abstractmethod
     def gen_coupled(self):
         """ :return a coupled method with i_in and o_out ports"""
@@ -368,7 +398,7 @@ class HI2LI(DEVStoneWrapper):
                   prep_time=self.prep_time, stats=self.stats)
 
 
-class Fertilizer(AtomicDEVS):
+class DynamicGenerator(AtomicDEVS):
     def __init__(self, name: str, period: float = 1.0, repeat: int = 1):
         super().__init__(name)
         self.period = period
@@ -413,7 +443,7 @@ class dLI(DEVStoneWrapper):
             assert isinstance(self.component_set[idx], AtomicDEVS)
             self.connectPorts(self.i_in, self.component_set[idx].i_in)
 
-        self.generator = self.addSubModel(Fertilizer(self.name + "_gen", repeat=self.max_gen))
+        self.generator = self.addSubModel(DynamicGenerator(self.name + "_gen", repeat=self.max_gen))
 
     def gen_coupled(self):
         return dLI("Coupled_%d" % (self.depth - 1), self.depth - 1, self.width, self.int_delay, self.ext_delay,
@@ -422,7 +452,6 @@ class dLI(DEVStoneWrapper):
     def modelTransition(self, state):
         if state.get("generate", True) and self.depth > 1:
             # print("model", self.name)
-            self.connectPorts(self.i_in, self.component_set[0].i_in)
             name = "Atomic_%d_%d" % (self.depth - 1, self.width) if self.depth > 1 else "Atomic_0_%d" % self.width
             if self.stats:
                 new_atom = DelayedAtomicStats(name, self.int_delay, self.ext_delay,
@@ -458,7 +487,7 @@ class dHI(DEVStoneWrapper):
             self.connectPorts(self.component_set[idx].o_out, self.component_set[idx + 1].i_in)
             self.connectPorts(self.i_in, self.component_set[idx].i_in)
 
-        self.generator = self.addSubModel(Fertilizer(self.name + "_gen", repeat=self.max_gen))
+        self.generator = self.addSubModel(DynamicGenerator(self.name + "_gen", repeat=self.max_gen))
 
     def gen_coupled(self):
         return dHI("Coupled_%d" % (self.depth - 1), self.depth - 1, self.width, self.int_delay, self.ext_delay,
@@ -474,8 +503,8 @@ class dHI(DEVStoneWrapper):
                 new_atom = DelayedAtomic(name, self.int_delay, self.ext_delay,
                                          add_out_port=self.add_atomic_out_ports, prep_time=self.prep_time, mode="LI-Dynamic")
 
-            last = self.component_set[-2]
-
+            last = self.models[-1]
+            print("last: ", last.name)
             self.models.append(self.addSubModel(new_atom))
             self.connectPorts(self.i_in, new_atom.i_in)
             if isinstance(last, AtomicDEVS) and hasattr(last, "o_out"):

+ 3 - 1
devstone/pythonpdevs/main.py

@@ -74,6 +74,7 @@ if __name__ == '__main__':
 
     env = DEVStoneEnvironment("DEVStoneEnvironment", devstone_model)
     model_created_time = time.time()
+    # print(devstone_model)
 
     sim = Simulator(env)
     if args.classic:
@@ -84,9 +85,10 @@ if __name__ == '__main__':
     # sim.setTerminationTime(10.0)
     # sim.setStateSaving("custom")
     engine_setup_time = time.time()
-
     sim.simulate()
     sim_time = time.time()
+    # print(devstone_model)
+    # devstone_model.dot()
 
     print("Model creation time: {}".format(model_created_time - start_time))
     print("Engine setup time: {}".format(engine_setup_time - model_created_time))