1
0
mirror of https://github.com/gsi-upm/soil synced 2025-08-23 19:52:19 +00:00

Bug fixes and minor improvements

This commit is contained in:
J. Fernando Sánchez
2022-05-12 16:14:47 +02:00
parent affeeb9643
commit 2116fe6f38
9 changed files with 80 additions and 63 deletions

View File

@@ -1 +1 @@
0.20.1
0.20.3

View File

@@ -65,6 +65,10 @@ def main():
logger.info('Loading config file: {}'.format(args.file))
if args.pdb:
args.synchronous = True
try:
exporters = list(args.exporter or ['default', ])
if args.csv:

View File

@@ -169,11 +169,12 @@ class Environment(Model):
if agent_type:
state = defstate
a = agent_type(model=self,
unique_id=agent_id)
unique_id=agent_id
)
for (k, v) in getattr(a, 'defaults', {}).items():
if not hasattr(a, k) or getattr(a, k) is None:
setattr(a, k, v)
setattr(a, k, deepcopy(v))
for (k, v) in state.items():
setattr(a, k, v)
@@ -199,15 +200,15 @@ class Environment(Model):
def step(self):
super().step()
self.datacollector.collect(self)
self.schedule.step()
def run(self, until, *args, **kwargs):
self._save_state()
while self.schedule.next_time <= until and not math.isinf(self.schedule.next_time):
self.schedule.step(until=until)
while self.schedule.next_time < until:
self.step()
utils.logger.debug(f'Simulation step {self.schedule.time}/{until}. Next: {self.schedule.next_time}')
self.schedule.time = until
self._history.flush_cache()
def _save_state(self, now=None):

View File

@@ -145,9 +145,7 @@ class Simulation:
def _run_sync_or_async(self, parallel=False, *args, **kwargs):
if parallel and not os.environ.get('SENPY_DEBUG', None):
p = Pool()
func = partial(self.run_trial_exceptions,
*args,
**kwargs)
func = lambda x: self.run_trial_exceptions(trial_id=x, *args, **kwargs)
for i in p.imap_unordered(func, range(self.num_trials)):
if isinstance(i, Exception):
logger.error('Trial failed:\n\t%s', i.message)
@@ -155,7 +153,8 @@ class Simulation:
yield i
else:
for i in range(self.num_trials):
yield self.run_trial(*args,
yield self.run_trial(trial_id=i,
*args,
**kwargs)
def run_gen(self, *args, parallel=False, dry_run=False,
@@ -224,7 +223,7 @@ class Simulation:
'''Create an environment for a trial of the simulation'''
opts = self.environment_params.copy()
opts.update({
'name': trial_id,
'name': '{}_trial_{}'.format(self.name, trial_id),
'topology': self.topology.copy(),
'network_params': self.network_params,
'seed': '{}_trial_{}'.format(self.seed, trial_id),
@@ -241,12 +240,11 @@ class Simulation:
env = self.environment_class(**opts)
return env
def run_trial(self, until=None, log_level=logging.INFO, **opts):
def run_trial(self, trial_id=0, until=None, log_level=logging.INFO, **opts):
"""
Run a single trial of the simulation
"""
trial_id = '{}_trial_{}'.format(self.name, time.time()).replace('.', '-')
if log_level:
logger.setLevel(log_level)
# Set-up trial environment and graph

View File

@@ -6,9 +6,11 @@ from .utils import logger
from mesa import Agent
INFINITY = float('inf')
class When:
def __init__(self, time):
self._time = float(time)
self._time = time
def abs(self, time):
return self._time
@@ -40,48 +42,34 @@ class TimedActivation(BaseScheduler):
heappush(self._queue, (self.time, agent.unique_id))
super().add(agent)
def step(self, until: float =float('inf')) -> None:
def step(self) -> None:
"""
Executes agents in order, one at a time. After each step,
an agent will signal when it wants to be scheduled next.
"""
when = None
agent_id = None
unsched = []
until = until or float('inf')
if self.next_time == INFINITY:
return
self.time = self.next_time
when = self.time
while self._queue and self._queue[0][0] == self.time:
(when, agent_id) = heappop(self._queue)
logger.debug(f'Stepping agent {agent_id}')
when = (self._agents[agent_id].step() or Delta(1)).abs(self.time)
if when < self.time:
raise Exception("Cannot schedule an agent for a time in the past ({} < {})".format(when, self.time))
heappush(self._queue, (when, agent_id))
self.steps += 1
if not self._queue:
self.time = until
self.next_time = float('inf')
self.time = INFINITY
self.next_time = INFINITY
return
(when, agent_id) = self._queue[0]
self.next_time = self._queue[0][0]
if until and when > until:
self.time = until
self.next_time = when
return
self.time = when
next_time = float("inf")
while when == self.time:
heappop(self._queue)
logger.debug(f'Stepping agent {agent_id}')
when = (self._agents[agent_id].step() or Delta(1)).abs(self.time)
heappush(self._queue, (when, agent_id))
if when < next_time:
next_time = when
if not self._queue or self._queue[0][0] > self.time:
agent_id = None
break
else:
(when, agent_id) = self._queue[0]
if when and when < self.time:
raise Exception("Invalid scheduling time")
self.next_time = next_time
self.steps += 1