123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- AtomicDEVSBlock Initial {
- name = "Initial"
- initialState = """
- self.state, self.elapsed = True, 0.0
- """
- timeAdvance = """
- if self.state:
- return 0.0
- else:
- return float('inf')
- """
- outputFnc = """
- return {self.my_ports['control_out']: {}}
- """
- intTransition = """
- return False
- """
- extTransition = """
- return None
- """
- }
- OutputPort init_co {
- name = "control_out"
- }
- DEVSBlockToPort (Initial, init_co) {}
- AtomicDEVSBlock Finish {
- name = "Finish"
- initialState = """
- self.state, self.elapsed = None, 0.0
- """
- timeAdvance = """
- return float('inf')
- """
- outputFnc = """
- return {}
- """
- intTransition = """
- return None
- """
- extTransition = """
- return self.elapsed
- """
- }
- InputPort finish_ci {
- name = "control_in"
- }
- DEVSBlockToPort (Finish, finish_ci) {}
- AtomicDEVSBlock ResourceHandler {
- name = "ResourceHandler"
- initialState = """
- self.state, self.elapsed = {'resources': self.parameters[0], 'queue': []}, 0.0
- """
- timeAdvance = """
- if self.state['queue'] and self.state['resources']:
- # Can grant a resource
- return 0.0
- else:
- # No request queued, or no available resources to handle the request
- return float('inf')
- """
- outputFnc = """
- return {self.my_ports['resource_out']: {'id': self.state['queue'][0]}}
- """
- intTransition = """
- # Processed a request that could be processed
- self.state['resources'] -= 1
- del self.state['queue'][0]
- return self.state
- """
- extTransition = """
- for inp in inputs[self.my_ports['resource_in']]:
- if inp['type'] == 'request':
- # Queue the request
- self.state['queue'].append(inp['id'])
- elif inp['type'] == 'release':
- # Increment the number of available resources
- self.state['resources'] += 1
- return self.state
- """
- }
- InputPort rh_ri {
- name = "resource_in"
- }
- OutputPort rh_ro {
- name = "resource_out"
- }
- DEVSBlockToPort (ResourceHandler, rh_ri) {}
- DEVSBlockToPort (ResourceHandler, rh_ro) {}
- AtomicDEVSBlock Activity {
- name = "Activity"
- initialState = """
- class ActivityState(object):
- def __init__(self, name, distribution):
- self.timer = float('inf')
- self.mode = 'inactive'
- self.counter = 0
- self.name = name
- self.distribution = distribution
- def __str__(self):
- return str(vars(self))
- def random_sample(self):
- return self.distribution(self.counter)
- self.state, self.elapsed = ActivityState(self.parameters[0], self.parameters[1]), 0.0
- """
-
- timeAdvance = """
- return self.state.timer
- """
- outputFnc = """
- if self.state.mode == 'active':
- # Output the control token to the next model in line, and release the resources
- return {self.my_ports['control_out']: {}, self.my_ports['resource_out']: [{'type': 'release'}]}
- elif self.state.mode == 'request_resource':
- # Output a request for resources with a specified ID (used to find out whether this was our request)
- return {self.my_ports['resource_out']: [{'type': 'request', 'id': '%s-%s' % (self.state.name, self.state.counter)}]}
- else:
- return {}
- """
- intTransition = """
- self.state.timer -= self.timeAdvance()
- if self.state.mode == 'request_resource':
- # Go and request the required resource
- self.state.mode = 'wait_resource'
- self.state.timer = float('inf')
- elif self.state.mode == 'active':
- # Finished execution, so release resources
- self.state.mode = 'inactive'
- self.state.timer = 0.0
- self.state.timer = float('inf')
- self.state.counter += 1
- return self.state
- """
- extTransition = """
- self.state.timer -= self.elapsed
- if self.state.mode == 'inactive' and self.my_ports['control_in'] in inputs:
- # Got control token, so ask for the required resources
- self.state.mode = 'request_resource'
- self.state.timer = 0.0
- # NOTE this violates DEVS, though is easy to debug
- #print('Activate ' + str(self.state.name) + ' at time ' + str(self.time_last[0] + self.elapsed))
- elif self.state.mode == 'wait_resource' and self.my_ports['resource_in'] in inputs and inputs[self.my_ports['resource_in']]['id'] == '%s-%s' % (self.state.name, self.state.counter):
- # Got required resources, so start execution
- self.state.mode = 'active'
- self.state.timer = self.state.random_sample()
- return self.state
- """
- }
- InputPort act_ri {
- name = "resource_in"
- }
- OutputPort act_ro {
- name = "resource_out"
- }
- DEVSBlockToPort (Activity, act_ri) {}
- DEVSBlockToPort (Activity, act_ro) {}
- InputPort act_ci {
- name = "control_in"
- }
- OutputPort act_co {
- name = "control_out"
- }
- DEVSBlockToPort (Activity, act_ci) {}
- DEVSBlockToPort (Activity, act_co) {}
- AtomicDEVSBlock ParallelSplit {
- name = "ParallelSplit"
- initialState = """
- self.state, self.elapsed = False, 0.0
- """
- timeAdvance = """
- if self.state:
- return 0.0
- else:
- return float('inf')
- """
- outputFnc = """
- return {self.my_ports['control_out']: {}}
- """
- intTransition = """
- return False
- """
- extTransition = """
- return True
- """
- }
- InputPort split_ci {
- name = "control_in"
- }
- OutputPort split_co {
- name = "control_out"
- }
- DEVSBlockToPort (ParallelSplit, split_ci) {}
- DEVSBlockToPort (ParallelSplit, split_co) {}
- AtomicDEVSBlock Synchronization {
- name = "Synchronization"
- initialState = """
- self.state, self.elapsed = {'current': self.parameters[0], 'max': self.parameters[0]}, 0.0
- """
- timeAdvance = """
- if self.state['current'] == 0:
- return 0.0
- else:
- return float('inf')
- """
- outputFnc = """
- return {self.my_ports['control_out']: {}}
- """
- intTransition = """
- self.state['current'] = self.state['max']
- return self.state
- """
- extTransition = """
- self.state['current'] -= 1
- return self.state
- """
- }
- InputPort syn_ci {
- name = "control_in"
- }
- OutputPort syn_co {
- name = "control_out"
- }
- DEVSBlockToPort (Synchronization, syn_ci) {}
- DEVSBlockToPort (Synchronization, syn_co) {}
- AtomicDEVSBlock ExclusiveChoice {
- name = "ExclusiveChoice"
- initialState = """
- class ExclusiveChoiceState(object):
- def __init__(self, distribution):
- self.counter = 0
- self.choice = None
- self.distribution = distribution
- def __str__(self):
- return str(vars(self))
- def make_choice(self):
- return self.distribution(self.counter)
- self.state, self.elapsed = ExclusiveChoiceState(self.parameters[0]), 0.0
- """
- timeAdvance = """
- if self.state.choice is not None:
- return 0.0
- else:
- return float('inf')
- """
- outputFnc = """
- if self.state.choice == True:
- return {self.my_ports['control_out1']: {}}
- else:
- return {self.my_ports['control_out2']: {}}
- """
- intTransition = """
- self.state.choice = None
- self.state.counter += 1
- return self.state
- """
- extTransition = """
- # Got a control token, so have to make a choice
- self.state.choice = self.state.make_choice()
- return self.state
- """
- }
- InputPort xor_ci {
- name = "control_in"
- }
- OutputPort xor_co1 {
- name = "control_out1"
- }
- OutputPort xor_co2 {
- name = "control_out2"
- }
- DEVSBlockToPort (ExclusiveChoice, xor_ci) {}
- DEVSBlockToPort (ExclusiveChoice, xor_co1) {}
- DEVSBlockToPort (ExclusiveChoice, xor_co2) {}
- AtomicDEVSBlock SimpleMerge {
- name = "SimpleMerge"
- initialState = """
- self.state, self.elapsed = False, 0.0
- """
- timeAdvance = """
- if self.state:
- return 0.0
- else:
- return float('inf')
- """
- outputFnc = """
- return {self.my_ports['control_out']: {}}
- """
- intTransition = """
- return False
- """
- extTransition = """
- return True
- """
- }
- InputPort or_ci {
- name = "control_in"
- }
- OutputPort or_co {
- name = "control_out"
- }
- DEVSBlockToPort (SimpleMerge, or_ci) {}
- DEVSBlockToPort (SimpleMerge, or_co) {}
- AtomicDEVSBlock MultiInstance {
- name = "MultiInstance"
- initialState = """
- class MultiInstanceState(object):
- def __init__(self, name, num, distribution):
- self.spawned = num
- self.collected = 0
- self.counter = 0
- self.mode = 'inactive'
- self.running_tasks = []
- self.requested = []
- self.name = name
- self.distribution = distribution
- def __str__(self):
- return str(vars(self))
- def task_time(self):
- return self.distribution(self.counter)
- self.state, self.elapsed = MultiInstanceState(self.parameters[0], self.parameters[1], self.parameters[2]), 0.0
- """
- timeAdvance = """
- if self.state.mode == 'finish':
- return 0.0
- elif self.state.running_tasks:
- return self.state.running_tasks[0][0]
- elif self.state.mode == 'request_resources':
- return 0.0
- else:
- return float('inf')
- """
- outputFnc = """
- if self.state.mode == 'request_resources':
- # Request all resources in one go
- return {self.my_ports['resource_out']: [{'type': 'request', 'id': i} for i in self.state.requested]}
- elif self.state.mode == 'active':
- # Finished an instance, so release it
- return {self.my_ports['resource_out']: [{'type': 'release'}]}
- elif self.state.mode == 'finish':
- # Finished execution of all, so pass on token
- return {self.my_ports['control_out']: {}}
- else:
- return {}
- """
- intTransition = """
- ta = self.timeAdvance()
- for t in self.state.running_tasks:
- t[0] -= ta
- if self.state.mode == 'active':
- # Finished an instance, so pop it
- del self.state.running_tasks[0]
- self.state.collected += 1
- if self.state.collected == self.state.spawned:
- self.state.mode = 'finish'
- elif self.state.mode == 'request_resources':
- # Requested resources, so be ready for a response
- self.state.mode = 'active'
- elif self.state.mode == 'finish':
- self.state.mode = 'inactive'
- self.state.collected = 0
- self.state.counter += 1
- self.state.running_tasks = []
- return self.state
- """
- extTransition = """
- # Got input, so have to spawn #num of them
- for t in self.state.running_tasks:
- t[0] -= self.elapsed
- if self.state.mode == 'inactive' and self.my_ports['control_in'] in inputs:
- self.state.mode = 'request_resources'
- self.state.requested = ['%s-%s-%s' % (self.state.name, self.state.counter, i) for i in range(self.state.spawned)]
- if self.state.mode in ['active', 'release_resource'] and self.my_ports['resource_in'] in inputs:
- # Got a resource, so allocate it to an activity
- self.state.running_tasks.append([self.state.task_time(), self.state.requested.pop(0)])
- # NOTE this violates DEVS, though is easy to debug
- #print('Spawn ' + str(self.state.running_tasks[-1][1]) + ' at time ' + str(self.time_last[0] + self.elapsed))
- self.state.running_tasks.sort()
- return self.state
- """
- }
- InputPort mi_ci {
- name = "control_in"
- }
- OutputPort mi_co {
- name = "control_out"
- }
- InputPort mi_ri {
- name = "resource_in"
- }
- OutputPort mi_ro {
- name = "resource_out"
- }
- DEVSBlockToPort (MultiInstance, mi_ci) {}
- DEVSBlockToPort (MultiInstance, mi_co) {}
- DEVSBlockToPort (MultiInstance, mi_ri) {}
- DEVSBlockToPort (MultiInstance, mi_ro) {}
|