123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- import random
- import sys
- sys.path.append("../../src/")
- from DEVS import AtomicDEVS, CoupledDEVS
- from mpi4py import MPI
- class CircleNodeState(object):
- def __init__(self):
- self.event = None
- self.queue = []
- self.nr = 0
- self.generated = 0
- def copy(self):
- a = CircleNodeState()
- a.event = self.event
- a.queue = list(self.queue)
- a.nr = self.nr
- a.generated = self.generated
- return a
- def __hash__(self):
- return self.event + sum(self.queue)
- def __eq__(self, other):
- # For memoization
- if self.event == other.event and self.queue == other.queue and self.nr == other.nr and self.generated == other.generated:
- return True
- else:
- return False
- def __str__(self):
- return "%s (%s)" % (self.event, self.queue)
- class CircleNode(AtomicDEVS):
- def __init__(self, nr, count, multiplier):
- AtomicDEVS.__init__(self, "CircleNode" + str(nr))
- self.inport = self.addInPort("input")
- self.outport = self.addOutPort("output")
- self.state = CircleNodeState()
- #self.state.event = random.randint(2, 100)
- self.state.nr = nr
- self.state.generated = 0
- self.state.event = nr
- self.count = count
- self.multiplier = multiplier
- def intTransition(self):
- if 0.6 * self.count < self.state.nr < 0.7 * self.count:
- for _ in xrange(self.state.nr*self.multiplier):
- pass
- if self.state.queue:
- self.state.event = self.state.queue.pop()
- else:
- self.state.event = None
- self.state.generated += 1
- if self.state.generated == 10:
- self.state.nr = (self.state.nr + 1) % self.count
- self.state.generated = 0
- return self.state
- def extTransition(self, inputs):
- if self.state.event is None:
- self.state.event = inputs[self.inport][0]
- else:
- self.state.queue.append(inputs[self.inport][0])
- return self.state
- def timeAdvance(self):
- if self.state.event is None:
- return float('inf')
- else:
- #return self.state.event
- return 1.0
- def outputFnc(self):
- return {self.outport: [self.state.event]}
- class MovingCircle(CoupledDEVS):
- def __init__(self, count, multiplier):
- import math
- CoupledDEVS.__init__(self, "Circle")
- nodes = []
- try:
- from mpi4py import MPI
- pernode = float(count) / MPI.COMM_WORLD.Get_size()
- except ImportError:
- pernode = float(count)
- for i in range(count):
- nodes.append(self.addSubModel(CircleNode(i, count, multiplier), math.floor(i/pernode)))
- for index in range(len(nodes)):
- self.connectPorts(nodes[index-1].outport, nodes[index].inport)
- if __name__ == "__main__":
- random.seed(1)
- from simulator import Simulator
- model = MovingCircle(int(sys.argv[1]), int(sys.argv[2]))
- sim = Simulator(model)
- sim.setTerminationTime(int(sys.argv[3]))
- #sim.setVerbose(True)
- sim.setMessageCopy('none')
- sim.setStateSaving('custom')
- sim.setGVTInterval(1 if int(argv[1]) < 500 else 5)
- from allocator import MyAllocator
- sim.setInitialAllocator(MyAllocator())
- #sim.setDrawModel(True, 'model.dot', True)
- if sys.argv[4] == "True":
- sim.setActivityRelocatorBasicBoundary(1.1)
- sim.setMemoization(True)
- sim.setSchedulerSortedList()
- #sim.setActivityTracking(True)
- #sim.setShowProgress()
- sim.simulate()
|