Пример #1
0
 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)
Пример #2
0
 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)
Пример #3
0
    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)
Пример #4
0
 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)
Пример #5
0
 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
Пример #6
0
    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
Пример #7
0
    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
Пример #8
0
    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')