Esempio n. 1
0
    def __init__(self, config: ConfigDict) -> None:
        super().__init__()
        #: The configuration dictionary.
        self.config = config

        #: The pseudo-random number generator; an instance of
        #: :class:`random.Random`.
        self.rand = random.Random()
        seed = config.setdefault('sim.seed', None)
        self.rand.seed(seed, version=1)

        timescale_str = self.config.setdefault('sim.timescale', '1 s')

        #: Simulation timescale ``(magnitude, units)`` tuple. The current
        #: simulation time is ``now * timescale``.
        self.timescale = parse_time(timescale_str)

        duration = config.setdefault('sim.duration', '0 s')

        #: The intended simulation duration, in units of :attr:`timescale`.
        self.duration = scale_time(parse_time(duration), self.timescale)

        #: The simulation runs "until" this event. By default, this is the
        #: configured "sim.duration", but may be overridden by subclasses.
        self.until = self.duration

        #: From 'meta.sim.index', the simulation's index when running multiple
        #: related simulations or `None` for a standalone simulation.
        self.sim_index: Optional[int] = config.get('meta.sim.index')

        #: :class:`TraceManager` instance.
        self.tracemgr = TraceManager(self)
Esempio n. 2
0
 def __init__(self, config: ConfigDict) -> None:
     self.workspace: str = config.setdefault(
         'meta.sim.workspace', config.setdefault('sim.workspace',
                                                 os.curdir))
     self.overwrite: bool = config.setdefault('sim.workspace.overwrite',
                                              False)
     self.prev_dir: str = os.getcwd()
Esempio n. 3
0
def simulate_factors(
    base_config: ConfigDict,
    factors: List[ConfigFactor],
    top_type: Type['Component'],
    env_type: Type[SimEnvironment] = SimEnvironment,
    jobs: Optional[int] = None,
    config_filter: Optional[Callable[[ConfigDict], bool]] = None,
) -> List[ResultDict]:
    """Run multi-factor simulations in separate processes.

    The `factors` are used to compose specialized config dictionaries for the
    simulations.

    The :mod:`python:multiprocessing` module is used run each simulation with a
    separate Python process. This allows multi-factor simulations to run in
    parallel on all available CPU cores.

    :param dict base_config: Base configuration dictionary to be specialized.
    :param list factors: List of factors.
    :param top_type: The model's top-level Component subclass.
    :param env_type: :class:`SimEnvironment` subclass.
    :param int jobs: User specified number of concurent processes.
    :param function config_filter:
        A function which will be passed a config and returns a bool to filter.
    :returns: Sequence of result dictionaries for each simulation.

    """
    configs = list(factorial_config(base_config, factors, 'meta.sim.special'))
    ws = base_config.setdefault('sim.workspace', os.curdir)
    overwrite = base_config.setdefault('sim.workspace.overwrite', False)

    for index, config in enumerate(configs):
        config['meta.sim.index'] = index
        config['meta.sim.workspace'] = os.path.join(ws, str(index))
    if config_filter is not None:
        configs[:] = filter(config_filter, configs)
    if overwrite and os.path.relpath(ws) != os.curdir and os.path.isdir(ws):
        shutil.rmtree(ws)
    for c in configs:
        if c['meta.sim.index'] == 0:
            # return simulate(config=c, top_type=top_type, env_type=env_type)
            pass
    # return simulate_many([configs[96],configs[97],configs[79]], top_type, env_type, jobs)
    return simulate_many(configs, top_type, env_type, jobs)
Esempio n. 4
0
def _get_interval_period_s(config: ConfigDict) -> Union[int, float]:
    period_str: str = config.setdefault('sim.progress.update_period', '1 s')
    return scale_time(parse_time(period_str), (1, 's'))
Esempio n. 5
0
def simulate(
    config: ConfigDict,
    top_type: Type['Component'],
    env_type: Type[SimEnvironment] = SimEnvironment,
    reraise: bool = True,
    progress_manager=standalone_progress_manager,
) -> ResultDict:
    """Initialize, elaborate, and run a simulation.

     All exceptions are caught by `simulate()` so they can be logged and
     captured in the result file. By default, any unhandled exception caught by
     `simulate()` will be re-raised. Setting `reraise` to False prevents
     exceptions from propagating to the caller. Instead, the returned result
     dict will indicate if an exception occurred via the 'sim.exception' item.

    :param dict config: Configuration dictionary for the simulation.
    :param top_type: The model's top-level Component subclass.
    :param env_type: :class:`SimEnvironment` subclass.
    :param bool reraise: Should unhandled exceptions propogate to the caller.
    :returns:
        Dictionary containing the model-specific results of the simulation.
    """
    t0 = timeit.default_timer()
    result: ResultDict = {}
    result_file = config.setdefault('sim.result.file')
    config_file = config.setdefault('sim.config.file')
    try:
        with _Workspace(config):
            env = env_type(config)
            with closing(env.tracemgr):
                try:
                    top_type.pre_init(env)
                    env.tracemgr.flush()
                    with progress_manager(env):
                        top = top_type(parent=None, env=env)
                        top.elaborate()
                        env.tracemgr.flush()
                        env.run(until=env.until)
                        env.tracemgr.flush()
                        top.post_simulate()
                        env.tracemgr.flush()
                        top.get_result(result)
                except BaseException as e:
                    env.tracemgr.trace_exception()
                    result['sim.exception'] = repr(e)
                    raise
                else:
                    result['sim.exception'] = None
                finally:
                    env.tracemgr.flush()
                    result['config'] = config
                    result['sim.now'] = env.now
                    result['sim.time'] = env.time()
                    result['sim.runtime'] = timeit.default_timer() - t0
                    _dump_dict(config_file, config)
                    _dump_dict(result_file, result)
    except BaseException as e:
        if reraise:
            raise
        result.setdefault('config', config)
        result.setdefault('sim.runtime', timeit.default_timer() - t0)
        if result.get('sim.exception') is None:
            result['sim.exception'] = repr(e)
    if result.get('sim.exception') is not None:
        err_file = os.path.join(config['meta.sim.workspace'], 'err.yaml')
        _dump_dict(err_file, result['sim.exception'])

    return result