Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #4
0
    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