def __init__(self, cfg=None): '''Performs configuration dictionary overlaying.''' self.syntax = merge_cls_dicts(self, 'syntax') # all in hierarchy self.cfg = ConfigDict(merge_cls_dicts(self, 'default')) if cfg: self.cfg.overlay(cfg) # apply user variables cfg_validate(self.cfg, self.syntax, type(self).__name__, warnings=False)
def __init__(self, cfg=None, **other_cfg): '''Initialises the landscape. This method should be overridden to perform any once-off setup that is required, such as generating a landscape map or sequence of test cases. :Warn: This initialiser is called *before* the system is constructed. Importantly, the members of `esec.context` have not been initialised and will raise exceptions if accessed. ''' self.syntax = merge_cls_dicts(self, 'syntax') # all in hierarchy self.cfg = ConfigDict(merge_cls_dicts(self, 'default')) if cfg is None: cfg = ConfigDict() elif not isinstance(cfg, ConfigDict): cfg = ConfigDict(cfg) self.cfg.overlay(cfg) for key, value in other_cfg.iteritems(): if key in self.syntax: self.cfg.set_by_name(key, value) elif key.partition('_')[0] in self.syntax: self.cfg.set_by_name(key.replace('_', '.'), value) cfg_validate(self.cfg, self.syntax, self.ltype + ':' + self.lname) # Initialise size properties self.size = self.cfg.size if self.size_equals_parameters and self.cfg.parameters: self.size.exact = self.cfg.parameters if self.size.exact: self.size.min = self.size.max = self.size.exact if self.size.min >= self.size.max: self.size.exact = self.size.max = self.size.min # Now check for any strict limits (ie parameters) cfg_strict_test(self.cfg, self.strict) # random seed? if not isinstance(self.cfg.random_seed, int): random.seed() self.cfg.random_seed = cfg.random_seed = random.randint( 0, sys.maxint) self.rand = Random(self.cfg.random_seed) # inversion? offset? self.invert = self.cfg.invert self.offset = self.cfg.offset # Autobind _eval_minimise or _eval_maximise. if not hasattr(self, 'eval'): if self.maximise == self.invert: setattr(self, 'eval', self._eval_minimise) else: setattr(self, 'eval', self._eval_maximise)
def __init__(self, cfg=None, **other_cfg): '''Initialises the landscape. This method should be overridden to perform any once-off setup that is required, such as generating a landscape map or sequence of test cases. :Warn: This initialiser is called *before* the system is constructed. Importantly, the members of `esec.context` have not been initialised and will raise exceptions if accessed. ''' self.syntax = merge_cls_dicts(self, 'syntax') # all in hierarchy self.cfg = ConfigDict(merge_cls_dicts(self, 'default')) if cfg is None: cfg = ConfigDict() elif not isinstance(cfg, ConfigDict): cfg = ConfigDict(cfg) self.cfg.overlay(cfg) for key, value in other_cfg.iteritems(): if key in self.syntax: self.cfg.set_by_name(key, value) elif key.partition('_')[0] in self.syntax: self.cfg.set_by_name(key.replace('_', '.'), value) cfg_validate(self.cfg, self.syntax, self.ltype + ':' + self.lname) # Initialise size properties self.size = self.cfg.size if self.size_equals_parameters and self.cfg.parameters: self.size.exact = self.cfg.parameters if self.size.exact: self.size.min = self.size.max = self.size.exact if self.size.min >= self.size.max: self.size.exact = self.size.max = self.size.min # Now check for any strict limits (ie parameters) cfg_strict_test(self.cfg, self.strict) # random seed? if not isinstance(self.cfg.random_seed, int): random.seed() self.cfg.random_seed = cfg.random_seed = random.randint(0, sys.maxint) self.rand = Random(self.cfg.random_seed) # inversion? offset? self.invert = self.cfg.invert self.offset = self.cfg.offset # Autobind _eval_minimise or _eval_maximise. if not hasattr(self, 'eval'): if self.maximise == self.invert: setattr(self, 'eval', self._eval_minimise) else: setattr(self, 'eval', self._eval_maximise)
def __init__(self, cfg, eval_default): '''Initialises a new `Species` instance. :Parameters: cfg : dict, `ConfigDict` The set of configuration options applying to this species. No syntax is provided by the `Species` base class, but derived classes may require certain parameters. eval_default : evaluator The default evaluator for `Individual` instances of this species. Evaluators provide a method `eval` taking a single individual as a parameter. ''' # Merge syntax and default details self.syntax = utils.merge_cls_dicts(self, 'syntax') self.cfg = ConfigDict(utils.merge_cls_dicts(self, 'default')) # Now apply user cfg details and test against syntax self.cfg.overlay(cfg) utils.cfg_validate(self.cfg, self.syntax, type(self), warnings=False) # Store default evaluator self._eval_default = eval_default '''The default evaluator for individuals of this species type.''' # Initialise public_context if necessary if not hasattr(self, 'public_context'): self.public_context = { } '''Items to include in a system's execution context. This typically contains references to the initialisers provided by the species.''' # Set some default properties to imitiate Individual self.species = self '''Provided to make `Species` and `Individual` trivially compatible. :see: Individual.species ''' self._eval = eval_default '''Provided to make `Species` and `Individual` trivially compatible. :see: Individual._eval ''' self.statistic = { } '''Provided to make `Species` and `Individual` trivially
def __init__(self, cfg, eval_default): '''Initialises a new `Species` instance. :Parameters: cfg : dict, `ConfigDict` The set of configuration options applying to this species. No syntax is provided by the `Species` base class, but derived classes may require certain parameters. eval_default : evaluator The default evaluator for `Individual` instances of this species. Evaluators provide a method `eval` taking a single individual as a parameter. ''' # Merge syntax and default details self.syntax = utils.merge_cls_dicts(self, 'syntax') self.cfg = ConfigDict(utils.merge_cls_dicts(self, 'default')) # Now apply user cfg details and test against syntax self.cfg.overlay(cfg) utils.cfg_validate(self.cfg, self.syntax, type(self), warnings=False) # Store default evaluator self._eval_default = eval_default '''The default evaluator for individuals of this species type.''' # Initialise public_context if necessary if not hasattr(self, 'public_context'): self.public_context = {} '''Items to include in a system's execution context. This typically contains references to the initialisers provided by the species.''' # Set some default properties to imitiate Individual self.species = self '''Provided to make `Species` and `Individual` trivially compatible. :see: Individual.species ''' self._eval = eval_default '''Provided to make `Species` and `Individual` trivially compatible. :see: Individual._eval ''' self.statistic = {} '''Provided to make `Species` and `Individual` trivially
def __init__(self, cfg): '''Initialises a new experiment with configuration dictionary `cfg`. `cfg` must match the syntax given in `syntax`. :Exceptions: - `ValueError`: Unusable values were passed in ``monitor`` or ``landscape``. See `syntax` for a description of what constitutes a valid value. - `ESDLCompilerError`: One or more errors occurred while compiling the provided system. Access the ``validation_result`` member of the exception object for specific information about each error. :Note: All exceptions are re-raised by this constructor. Apart from `KeyboardInterrupt`, exceptions raised after the monitor is available are passed to the `MonitorBase.on_exception` handler first. ''' # Configuration processing... self.cfg = ConfigDict(self.default) # Overlay the supplied cfg onto defaults self.cfg.overlay(cfg) # -- Validate cfg against syntax cfg_validate(self.cfg, self.syntax, 'Experiment', warnings=True) # hide the user provided cfg with validated self.cfg cfg = self.cfg # -- Monitor -- self.monitor = self._load(cfg, 'monitor', MonitorBase, 'should_terminate') if not MonitorBase.isinstance(self.monitor): raise TypeError('No monitor provided.') cfg.monitor = self.monitor try: # random seed? try: self.random_seed = int(cfg.random_seed) except TypeError: random.seed() self.random_seed = cfg.random_seed = random.randrange(0, sys.maxint) # -- Landscape (of type and name) -- self.lscape = self._load(cfg, 'landscape', landscape.Landscape, 'eval') cfg.landscape = self.lscape # -- Pass full configuration to monitor -- self.monitor.notify('Experiment', 'Configuration', cfg) # -- System -- self.system = System(cfg, self.lscape, self.monitor) # -- Pass compiled system and landscape to monitor -- self.monitor.notify('Experiment', 'System', self.system) if self.lscape: self.monitor.notify('Experiment', 'Landscape', self.lscape) except KeyboardInterrupt: raise except: ex = sys.exc_info() ex_type, ex_value = ex[0], ex[1] if ex_type is EvaluatorError: ex_type, ex_value, ex_trace = ex_value.args elif ex_type is ESDLCompilerError: ex_trace = '\n'.join(str(i) for i in ex_value.validation_result.all) elif ex_type is ExceptionGroup: ex_trace = '\n'.join(str(i) for i in ex_value.exceptions) else: ex_trace = ''.join(traceback.format_exception(*ex)) self.monitor.on_exception(self, ex_type, ex_value, ex_trace) raise
def __init__(self, cfg, lscape=None, monitor=None): # Merge syntax and default details self.syntax = merge_cls_dicts(self, 'syntax') self.cfg = ConfigDict(merge_cls_dicts(self, 'default')) # Merge in all globally defined ESDL functions for key, value in GLOBAL_ESDL_FUNCTIONS.iteritems(): self.cfg.system[key.lower()] = value # Now apply user cfg details and test against syntax self.cfg.overlay(cfg) # If no default evaluator has been provided, use `lscape` cfg_validate(self.cfg, self.syntax, type(self), warnings=False) # Initialise empty members self._code = None self._code_string = None self.monitor = None self.selector = None self.selector_current = None self._in_step = False self._next_block = [] self._block_cache = {} # Compile code self.definition = self.cfg.system.definition self._context = context = { 'config': self.cfg, 'rand': random.Random(cfg.random_seed), 'notify': self._do_notify } # Add species settings to context for cls in SPECIES: inst = context[cls.name] = cls(self.cfg, lscape) try: for key, value in inst.public_context.iteritems(): context[key.lower()] = value except AttributeError: pass # Add external values to context for key, value in self.cfg.system.iteritems(): if isinstance(key, str): key_lower = key.lower() if key_lower in context: warn("Overriding variable/function '%s'" % key_lower) context[key_lower] = value else: warn('System dictionary contains non-string key %r' % key) model, self.validation_result = compileESDL(self.definition, context) if not self.validation_result: raise ESDLCompilerError(self.validation_result, "Errors occurred while compiling system.") self._code_string, internal_context = emit(model, out=None, optimise_level=0, profile='_profiler' in context) internal_context['_yield'] = lambda name, group: self.monitor.on_yield(self, name, group) internal_context['_alias'] = GroupAlias for key, value in internal_context.iteritems(): if key in context: warn("Variable/function '%s' is overridden by internal value" % key) context[key] = value esec.context._context.context = context esec.context._context.config = context['config'] esec.context._context.rand = context['rand'] esec.context._context.notify = context['notify'] self.monitor = monitor or MonitorBase() self.selector = self.cfg['selector'] or [name for name in model.block_names if name != model.INIT_BLOCK_NAME] self.selector_current = iter(self.selector) for func in model.externals.iterkeys(): if func not in context: context[func] = OnIndividual(func) self._code = compile(self._code_string, 'ESDL Definition', 'exec')