Source code for icarus.runner
#!/usr/bin/env python
"""Launches a simulation campaign and save results.
"""
import sys
import os
import signal
import functools
import logging
import multiprocessing as mp
from icarus.util import Settings, config_logging
from icarus.registry import RESULTS_WRITER
from icarus.orchestration import Orchestrator
__all__ = ['run', 'handler']
logger = logging.getLogger('main')
[docs]def handler(settings, orch, output, signum=None, frame=None):
"""Signal handler
This function is called when the simulator receive SIGTERM, SIGHUP, SIGKILL
or SIGQUIT from the OS.
Its function is simply to write on a file the partial results.
Parameters
----------
settings : Settings
The simulator settings
orch : Orchestrator
The instance of the orchestrator
output : str
The output file
"""
logger.error('Received signal %d. Terminating' % signum)
RESULTS_WRITER[settings.RESULTS_FORMAT](orch.results, output)
logger.info('Saved intermediate results to file %s' % os.path.abspath(output))
orch.stop()
sys.exit(-signum)
def _validate_settings(settings, freeze=True):
"""Validate settings. If everything is OK freeze them"""
if 'EXPERIMENT_QUEUE' not in settings:
logger.error('No EXPERIMENT_QUEUE setting found. Exiting')
sys.exit(-1)
if not 'PARALLEL_EXECUTION' in settings:
settings.PARALLEL_EXECUTION = False
logger.warning('PARALLEL_EXECUTION setting not specified. Set to False')
elif settings.PARALLEL_EXECUTION:
if 'N_PROCESSES' not in settings:
n_proc = mp.cpu_count()
settings.N_PROCESSES = n_proc
logger.warning('N_PROCESSES setting not specified. Set to %s'
% str(n_proc))
if 'N_REPLICATIONS' not in settings:
n_replications = 1
settings.N_REPLICATIONS = n_replications
logger.warning('N_REPLICATIONS setting not specified. Set to %s'
% str(n_replications))
if 'RESULTS_FORMAT' not in settings:
res_format = 'PICKLE'
settings.RESULTS_FORMAT = res_format
logger.warning('RESULTS_FORMAT setting not specified. Set to %s'
% res_format)
if 'LOG_LEVEL' not in settings:
log_level = 'INFO'
settings.LOG_LEVEL = log_level
logger.warning('LOG_LEVEL setting not specified. Set to %s'
% log_level)
if freeze:
settings.freeze()
[docs]def run(config_file, output, config_override):
"""
Run function. It starts the simulator.
experiments
Parameters
----------
config : str
Path of the configuration file
output : str
The file name where results will be saved
config_override : dict, optional
Configuration parameters overriding parameters in the file
"""
# Read settings from file and save them in icarus.conf.settings
settings = Settings()
settings.read_from(config_file)
if config_override:
for k, v in config_override.items():
try:
v = eval(v)
except NameError:
pass
settings.set(k, v)
# Config logger
config_logging(settings.LOG_LEVEL if 'LOG_LEVEL' in settings else 'INFO')
# Validate settings
_validate_settings(settings, freeze=True)
# set up orchestration
orch = Orchestrator(settings)
for sig in (signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT, signal.SIGABRT):
signal.signal(sig, functools.partial(handler, settings, orch, output))
logger.info('Launching orchestrator')
orch.run()
logger.info('Orchestrator finished')
results = orch.results
RESULTS_WRITER[settings.RESULTS_FORMAT](results, output)
logger.info('Saved results to file %s' % os.path.abspath(output))