def run(self, duration=None, quiet=0): """ Run the simulation for some duration. duration -- specified simulation duration (default: forever) quiet -- don't print StopSimulation messages (default: off) """ # If the simulation is already finished, raise StopSimulation immediately # From this point it will propagate to the caller, that can catch it. if self._finished: raise StopSimulation("Simulation has already finished") waiters = self._waiters maxTime = None if duration: stop = _Waiter(None) stop.hasRun = 1 maxTime = _simulator._time + duration schedule((maxTime, stop)) cosim = self._cosim t = _simulator._time actives = {} tracing = _simulator._tracing tracefile = _simulator._tf exc = [] _pop = waiters.pop _append = waiters.append _extend = waiters.extend while 1: try: for s in _siglist: _extend(s._update()) del _siglist[:] while waiters: waiter = _pop() try: waiter.next(waiters, actives, exc) except StopIteration: continue if cosim: cosim._get() if _siglist or cosim._hasChange: cosim._put(t) continue elif _siglist: continue if actives: for wl in actives.values(): wl.purge() actives = {} # at this point it is safe to potentially suspend a simulation if exc: raise exc[0] # future events if _futureEvents: if t == maxTime: raise _SuspendSimulation( "Simulated %s timesteps" % duration) _futureEvents.sort(key=itemgetter(0)) t = _simulator._time = _futureEvents[0][0] if tracing: print("#%s" % t, file=tracefile) if cosim: cosim._put(t) while _futureEvents: newt, event = _futureEvents[0] if newt == t: if isinstance(event, _Waiter): _append(event) else: _extend(event.apply()) del _futureEvents[0] else: break else: raise StopSimulation("No more events") except _SuspendSimulation: if not quiet: _printExcInfo() if tracing: tracefile.flush() return 1 except StopSimulation: if not quiet: _printExcInfo() self._finalize() self._finished = True return 0 except Exception as e: if tracing: tracefile.flush() # if the exception came from a yield, make sure we can resume if exc and e is exc[0]: pass # don't finalize else: self._finalize() # now reraise the exepction raise
def run(self, duration=None, quiet=0, iter_limit=1000): """ Run the simulation for some duration. duration -- specified simulation duration (default: forever) quiet -- don't print StopSimulation messages (default: off) iter_limit -- step limit for not advancing time; used to detect combinatorial loops (default: 1000) """ # If the simulation is already finished, raise StopSimulation immediately # From this point it will propagate to the caller, that can catch it. if self._finished: raise StopSimulation("Simulation has already finished") waiters = self._waiters maxTime = None if duration: stop = _Waiter(None) stop.hasRun = 1 maxTime = _simulator._time + duration schedule((maxTime, stop)) cosims = self._cosims t = _simulator._time actives = {} tracing = _simulator._tracing tracefile = _simulator._tf exc = [] _pop = waiters.pop _append = waiters.append _extend = waiters.extend while 1: try: if last_t == t: same_t_count += 1 if same_t_count > iter_limit: raise StopSimulation("Iteration limit exceeded") else: last_t = t # Needed to prevent off-by-one same_t_count = 1 for s in _siglist: _extend(s._update()) del _siglist[:] while waiters: waiter = _pop() try: waiter.next(waiters, actives, exc) except StopIteration: continue if cosims: any_cosim_changes = False for cosim in cosims: any_cosim_changes = \ any_cosim_changes or cosim._hasChange for cosim in cosims: cosim._get() if _siglist or any_cosim_changes: # It should be safe to _put a cosim with no changes # because _put with the same values should be # idempotent. We need to _put them all here because # otherwise we can desync _get/_put. for cosim in cosims: cosim._put(t) continue elif _siglist: continue if actives: for wl in actives.values(): wl.purge() actives = {} # at this point it is safe to potentially suspend a simulation if exc: raise exc[0] # future events if _futureEvents: if t == maxTime: raise _SuspendSimulation("Simulated %s timesteps" % duration) _futureEvents.sort(key=itemgetter(0)) t = _simulator._time = _futureEvents[0][0] if tracing: print("#%s" % t, file=tracefile) if cosims: for cosim in cosims: cosim._put(t) while _futureEvents: newt, event = _futureEvents[0] if newt == t: if isinstance(event, _Waiter): _append(event) else: _extend(event.apply()) del _futureEvents[0] else: break else: raise StopSimulation("No more events") except _SuspendSimulation: if not quiet: _printExcInfo() if tracing: tracefile.flush() return 1 except StopSimulation: if not quiet: _printExcInfo() self._finalize() self._finished = True return 0 except Exception as e: if tracing: tracefile.flush() # if the exception came from a yield, make sure we can resume if exc and e is exc[0]: pass # don't finalize else: self._finalize() # now reraise the exepction raise
def run(self, duration=None, quiet=0): """ Run the simulation for some duration. duration -- specified simulation duration (default: forever) quiet -- don't print StopSimulation messages (default: off) """ # If the simulation is already finished, raise StopSimulation immediately # From this point it will propagate to the caller, that can catch it. if self._finished: raise StopSimulation("Simulation has already finished") waiters = self._waiters maxTime = None if duration: stop = _Waiter(None) stop.hasRun = 1 maxTime = _simulator._time + duration schedule((maxTime, stop)) cosim = self._cosim t = _simulator._time actives = {} tracing = _simulator._tracing tracefile = _simulator._tf exc = [] _pop = waiters.pop _append = waiters.append _extend = waiters.extend while 1: try: for s in _siglist: _extend(s._update()) del _siglist[:] while waiters: waiter = _pop() try: waiter.next(waiters, actives, exc) except StopIteration: continue if cosim: cosim._get() if _siglist or cosim._hasChange: cosim._put(t) continue elif _siglist: continue if actives: for wl in actives.values(): wl.purge() actives = {} # at this point it is safe to potentially suspend a simulation if exc: raise exc[0] # future events if _futureEvents: if t == maxTime: raise _SuspendSimulation("Simulated %s timesteps" % duration) _futureEvents.sort(key=itemgetter(0)) t = _simulator._time = _futureEvents[0][0] if tracing: print("#%s" % t, file=tracefile) if cosim: cosim._put(t) while _futureEvents: newt, event = _futureEvents[0] if newt == t: if isinstance(event, _Waiter): _append(event) else: _extend(event.apply()) del _futureEvents[0] else: break else: raise StopSimulation("No more events") except _SuspendSimulation: if not quiet: _printExcInfo() if tracing: tracefile.flush() return 1 except StopSimulation: if not quiet: _printExcInfo() self._finalize() self._finished = True return 0 except Exception as e: if tracing: tracefile.flush() # if the exception came from a yield, make sure we can resume if exc and e is exc[0]: pass # don't finalize else: self._finalize() # now reraise the exepction raise
def run(self, duration=None, quiet=0, iter_limit=1000): """ Run the simulation for some duration. duration -- specified simulation duration (default: forever) quiet -- don't print StopSimulation messages (default: off) iter_limit -- step limit for not advancing time; used to detect combinatorial loops (default: 1000) """ # If the simulation is already finished, raise StopSimulation immediately # From this point it will propagate to the caller, that can catch it. if self._finished: raise StopSimulation("Simulation has already finished") waiters = self._waiters maxTime = None if duration: stop = _Waiter(None) stop.hasRun = 1 maxTime = _simulator._time + duration schedule((maxTime, stop)) cosims = self._cosims t = _simulator._time actives = {} tracing = _simulator._tracing tracefile = _simulator._tf exc = [] _pop = waiters.pop _append = waiters.append _extend = waiters.extend while 1: try: if last_t == t: same_t_count += 1 if same_t_count > iter_limit: raise StopSimulation("Iteration limit exceeded") else: last_t = t # Needed to prevent off-by-one same_t_count = 1 for s in _siglist: _extend(s._update()) del _siglist[:] while waiters: waiter = _pop() try: waiter.next(waiters, actives, exc) except StopIteration: continue if cosims: any_cosim_changes = False for cosim in cosims: any_cosim_changes = \ any_cosim_changes or cosim._hasChange for cosim in cosims: cosim._get() if _siglist or any_cosim_changes: # It should be safe to _put a cosim with no changes # because _put with the same values should be # idempotent. We need to _put them all here because # otherwise we can desync _get/_put. for cosim in cosims: cosim._put(t) continue elif _siglist: continue if actives: for wl in actives.values(): wl.purge() actives = {} # at this point it is safe to potentially suspend a simulation if exc: raise exc[0] # future events if _futureEvents: if t == maxTime: raise _SuspendSimulation( "Simulated %s timesteps" % duration) _futureEvents.sort(key=itemgetter(0)) t = _simulator._time = _futureEvents[0][0] if tracing: print("#%s" % t, file=tracefile) if cosims: for cosim in cosims: cosim._put(t) while _futureEvents: newt, event = _futureEvents[0] if newt == t: if isinstance(event, _Waiter): _append(event) else: _extend(event.apply()) del _futureEvents[0] else: break else: raise StopSimulation("No more events") except _SuspendSimulation: if not quiet: _printExcInfo() if tracing: tracefile.flush() return 1 except StopSimulation: if not quiet: _printExcInfo() self._finalize() self._finished = True return 0 except Exception as e: if tracing: tracefile.flush() # if the exception came from a yield, make sure we can resume if exc and e is exc[0]: pass # don't finalize else: self._finalize() # now reraise the exepction raise