model.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import sys
  2. sys.path.append("../../src/")
  3. from infinity import INFINITY
  4. from simulator import Simulator
  5. from DEVS import *
  6. import random
  7. class Event(object):
  8. def __init__(self, eventSize):
  9. self.eventSize = eventSize
  10. def copy(self):
  11. return Event(self.eventSize)
  12. class ProcessorState(object):
  13. def __init__(self):
  14. self.event1_counter = INFINITY
  15. self.event1 = None
  16. self.queue = []
  17. def copy(self):
  18. a = ProcessorState()
  19. a.event1_counter = self.event1_counter
  20. a.event1 = None if self.event1 is None else self.event1.copy()
  21. a.queue = [i.copy() for i in self.queue]
  22. return a
  23. class Processor(AtomicDEVS):
  24. def __init__(self, name, randomta):
  25. AtomicDEVS.__init__(self, name)
  26. self.recv_event1 = self.addInPort("in_event1")
  27. self.send_event1 = self.addOutPort("out_event1")
  28. self.state = ProcessorState()
  29. self.randomta = randomta
  30. def timeAdvance(self):
  31. return self.state.event1_counter
  32. def intTransition(self):
  33. self.state.event1_counter -= self.timeAdvance()
  34. if self.state.event1_counter == 0 and self.state.queue == []:
  35. self.state.event1_counter = INFINITY
  36. self.state.event1 = None
  37. else:
  38. self.state.event1 = self.state.queue.pop()
  39. self.state.event1_counter = round(random.uniform(0.75, 1.25), 4) if self.randomta else 1.0
  40. return self.state
  41. def extTransition(self, inputs):
  42. self.state.event1_counter -= self.elapsed
  43. #Only one element, so exploit this
  44. ev1 = inputs[self.recv_event1][0]
  45. if self.state.event1 is not None:
  46. self.state.queue.append(ev1)
  47. else:
  48. self.state.event1 = ev1
  49. self.state.event1_counter = round(random.uniform(0.75, 1.25), 4) if self.randomta else 1.0
  50. return self.state
  51. def outputFnc(self):
  52. return {self.send_event1: [self.state.event1]}
  53. class GeneratorState(object):
  54. def __init__(self):
  55. pass
  56. def copy(self):
  57. return GeneratorState()
  58. class Generator(AtomicDEVS):
  59. def __init__(self):
  60. AtomicDEVS.__init__(self, "Generator")
  61. self.state = GeneratorState()
  62. self.send_event1 = self.addOutPort("out_event1")
  63. def timeAdvance(self):
  64. return 1
  65. def intTransition(self):
  66. return self.state
  67. def outputFnc(self):
  68. return {self.send_event1: [Event(1)]}
  69. class CoupledRecursion(CoupledDEVS):
  70. def __init__(self, width, depth, randomta):
  71. CoupledDEVS.__init__(self, "Coupled" + str(depth))
  72. self.recv_event1 = self.addInPort("in_event1")
  73. self.send_event1 = self.addOutPort("out_event1")
  74. if depth > 1:
  75. self.recurse = self.addSubModel(CoupledRecursion(width, depth-1, randomta))
  76. self.connectPorts(self.recv_event1, self.recurse.recv_event1)
  77. for i in range(width):
  78. processor = self.addSubModel(Processor("Processor%s_%s" % (depth, i), randomta))
  79. if i == 0:
  80. if depth > 1:
  81. self.connectPorts(self.recurse.send_event1, processor.recv_event1)
  82. else:
  83. self.connectPorts(self.recv_event1, processor.recv_event1)
  84. else:
  85. self.connectPorts(prev.send_event1, processor.recv_event1)
  86. prev = processor
  87. self.connectPorts(prev.send_event1, self.send_event1)
  88. class DEVStone(CoupledDEVS):
  89. def __init__(self, width, depth, randomta):
  90. random.seed(1)
  91. CoupledDEVS.__init__(self, "DEVStone")
  92. self.generator1 = self.addSubModel(Generator(), 0)
  93. self.generator2 = self.addSubModel(Generator(), 1)
  94. self.generator3 = self.addSubModel(Generator(), 2)
  95. self.recurse1 = self.addSubModel(CoupledRecursion(width, depth, randomta), 0)
  96. self.recurse2 = self.addSubModel(CoupledRecursion(width, depth, randomta), 1)
  97. self.recurse3 = self.addSubModel(CoupledRecursion(width, depth, randomta), 2)
  98. self.connectPorts(self.generator1.send_event1, self.recurse1.recv_event1)
  99. self.connectPorts(self.generator2.send_event1, self.recurse2.recv_event1)
  100. self.connectPorts(self.generator3.send_event1, self.recurse3.recv_event1)