def _add_found_extension(self, obj, ext):
        """
            :obj: Found extension class
            :ext: matching extension item.
        """
        self.logger.debug('\tAdding %s %s', ext.name, obj.name)
        key = identifier(obj.name.lower())
        obj.kind = ext.name
        if key in self.extensions or key in self.aliases:
            raise LoaderError('{} {} already exists.'.format(
                ext.name, obj.name))
        # Extensions are tracked both, in a common extensions
        # dict, and in per-extension kind dict (as retrieving
        # extensions by kind is a common use case.
        self.extensions[key] = obj
        store = self._get_store(ext)
        store[key] = obj
        for alias in obj.aliases:
            alias_id = identifier(alias.name)
            if alias_id in self.extensions or alias_id in self.aliases:
                raise LoaderError('{} {} already exists.'.format(
                    ext.name, obj.name))
            self.aliases[alias_id] = alias

        # Update global aliases list. If a global alias is already in the list,
        # then make sure this extension is in the same parent/child hierarchy
        # as the one already found.
        for param in obj.parameters:
            if param.global_alias:
                if param.global_alias not in self.global_param_aliases:
                    ga = GlobalParameterAlias(param.global_alias)
                    ga.update(obj)
                    self.global_param_aliases[ga.name] = ga
                else:  # global alias already exists.
                    self.global_param_aliases[param.global_alias].update(obj)
    def _add_found_extension(self, obj, ext):
        """
            :obj: Found extension class
            :ext: matching extension item.
        """
        self.logger.debug('\tAdding %s %s', ext.name, obj.name)
        key = identifier(obj.name.lower())
        obj.kind = ext.name
        if key in self.extensions or key in self.aliases:
            raise LoaderError('{} {} already exists.'.format(ext.name, obj.name))
        # Extensions are tracked both, in a common extensions
        # dict, and in per-extension kind dict (as retrieving
        # extensions by kind is a common use case.
        self.extensions[key] = obj
        store = self._get_store(ext)
        store[key] = obj
        for alias in obj.aliases:
            alias_id = identifier(alias.name)
            if alias_id in self.extensions or alias_id in self.aliases:
                raise LoaderError('{} {} already exists.'.format(ext.name, obj.name))
            self.aliases[alias_id] = alias

        # Update global aliases list. If a global alias is already in the list,
        # then make sure this extension is in the same parent/child hierarchy
        # as the one already found.
        for param in obj.parameters:
            if param.global_alias:
                if param.global_alias not in self.global_param_aliases:
                    ga = GlobalParameterAlias(param.global_alias)
                    ga.update(obj)
                    self.global_param_aliases[ga.name] = ga
                else:  # global alias already exists.
                    self.global_param_aliases[param.global_alias].update(obj)
def get_instrument(inst):
    if isinstance(inst, Instrument):
        return inst
    for installed_inst in installed:
        if identifier(installed_inst.name) == identifier(inst):
            return installed_inst
    raise ValueError('Instrument {} is not installed'.format(inst))
def get_instrument(inst):
    if isinstance(inst, Instrument):
        return inst
    for installed_inst in installed:
        if identifier(installed_inst.name) == identifier(inst):
            return installed_inst
    raise ValueError('Instrument {} is not installed'.format(inst))
def is_installed(instrument):
    if isinstance(instrument, Instrument):
        if instrument in installed:
            return True
        if instrument.name in [i.name for i in installed]:
            return True
    elif isinstance(instrument, type):
        if instrument in [i.__class__ for i in installed]:
            return True
    else:  # assume string
        if identifier(instrument) in [identifier(i.name) for i in installed]:
            return True
    return False
def is_installed(instrument):
    if isinstance(instrument, Instrument):
        if instrument in installed:
            return True
        if instrument.name in [i.name for i in installed]:
            return True
    elif isinstance(instrument, type):
        if instrument in [i.__class__ for i in installed]:
            return True
    else:  # assume string
        if identifier(instrument) in [identifier(i.name) for i in installed]:
            return True
    return False
    def _merge_config(self, config):
        """
        Merge the settings specified by the ``config`` dict-like object into current
        configuration.

        """
        if not isinstance(config, dict):
            raise ValueError('config must be a dict; found {}'.format(config.__class__.__name__))

        for k, v in config.iteritems():
            k = identifier(k)
            if k in self.ext_loader.global_param_aliases:
                self._resolve_global_alias(k, v)
            elif k in self._general_config_map:
                self._set_run_config_item(k, v)
            elif self.ext_loader.has_extension(k):
                self._set_extension_config(k, v)
            elif k == 'device_config':
                self._set_raw_dict(k, v)
            elif k in ['instrumentation', 'result_processors']:
                # Instrumentation can be enabled and disabled by individual
                # workloads, so we need to track it in two places: a list of
                # all instruments for the run (as they will all need to be
                # initialized and installed, and a list of only the "global"
                # instruments which can then be merged into instrumentation
                # lists of individual workload specs.
                self._set_raw_list('_global_{}'.format(k), v)
                self._set_raw_list(k, v)
            elif k in self.ignore_names:
                pass
            else:
                raise ConfigError('Unknown configuration option: {}'.format(k))
Esempio n. 8
0
    def _merge_config(self, config):
        """
        Merge the settings specified by the ``config`` dict-like object into current
        configuration.

        """
        if not isinstance(config, dict):
            raise ValueError('config must be a dict; found {}'.format(
                config.__class__.__name__))

        for k, v in config.iteritems():
            k = identifier(k)
            if k in self.ext_loader.global_param_aliases:
                self._resolve_global_alias(k, v)
            elif k in self._general_config_map:
                self._set_run_config_item(k, v)
            elif self.ext_loader.has_extension(k):
                self._set_extension_config(k, v)
            elif k == 'device_config':
                self._set_raw_dict(k, v)
            elif k in ['instrumentation', 'result_processors']:
                # Instrumentation can be enabled and disabled by individual
                # workloads, so we need to track it in two places: a list of
                # all instruments for the run (as they will all need to be
                # initialized and installed, and a list of only the "global"
                # instruments which can then be merged into instrumentation
                # lists of individual workload specs.
                self._set_raw_list('_global_{}'.format(k), v)
                self._set_raw_list(k, v)
            elif k in self.ignore_names:
                pass
            else:
                raise ConfigError('Unknown configuration option: {}'.format(k))
Esempio n. 9
0
 def update_from_dict(self, source):
     normalized_source = dict(
         (identifier(k), v) for k, v in source.iteritems())
     self._config = merge_dicts(self._config,
                                normalized_source,
                                list_duplicates='first',
                                match_types=False,
                                dict_type=OrderedDict)
     self._loaded = True
Esempio n. 10
0
    def __init__(self, name, kind=None, mandatory=None, default=None, override=False,
                 allowed_values=None, description=None, constraint=None, global_alias=None, convert_types=True):
        """
        Create a new Parameter object.

        :param name: The name of the parameter. This will become an instance member of the
                     extension object to which the parameter is applied, so it must be a valid
                     python  identifier. This is the only mandatory parameter.
        :param kind: The type of parameter this is. This must be a callable that takes an arbitrary
                     object and converts it to the expected type, or raised ``ValueError`` if such
                     conversion is not possible. Most Python standard types -- ``str``, ``int``, ``bool``, etc. --
                     can be used here. This defaults to ``str`` if not specified.
        :param mandatory: If set to ``True``, then a non-``None`` value for this parameter *must* be
                          provided on extension object construction, otherwise ``ConfigError`` will be
                          raised.
        :param default: The default value for this parameter. If no value is specified on extension
                        construction, this value will be used instead. (Note: if this is specified and
                        is not ``None``, then ``mandatory`` parameter will be ignored).
        :param override: A ``bool`` that specifies whether a parameter of the same name further up the
                         hierarchy should be overridden. If this is ``False`` (the default), an exception
                         will be raised by the ``AttributeCollection`` instead.
        :param allowed_values: This should be the complete list of allowed values for this parameter.
                               Note: ``None`` value will always be allowed, even if it is not in this list.
                               If you want to disallow ``None``, set ``mandatory`` to ``True``.
        :param constraint: If specified, this must be a callable that takes the parameter value
                           as an argument and return a boolean indicating whether the constraint
                           has been satisfied. Alternatively, can be a two-tuple with said callable as
                           the first element and a string describing the constraint as the second.
        :param global_alias: This is an alternative alias for this parameter, unlike the name, this
                             alias will not be namespaced under the owning extension's name (hence the
                             global part). This is introduced primarily for backward compatibility -- so
                             that old extension settings names still work. This should not be used for
                             new parameters.

        :param convert_types: If ``True`` (the default), will automatically convert ``kind`` values from
                              native Python types to WA equivalents. This allows more ituitive interprestation
                              of parameter values, e.g. the string ``"false"`` being interpreted as ``False``
                              when specifed as the value for a boolean Parameter.

        """
        self.name = identifier(name)
        if kind is not None and not callable(kind):
            raise ValueError('Kind must be callable.')
        if convert_types and kind in self.kind_map:
            kind = self.kind_map[kind]
        self.kind = kind
        self.mandatory = mandatory
        self.default = default
        self.override = override
        self.allowed_values = allowed_values
        self.description = description
        if self.kind is None and not self.override:
            self.kind = str
        if constraint is not None and not callable(constraint) and not isinstance(constraint, tuple):
            raise ValueError('Constraint must be callable or a (callable, str) tuple.')
        self.constraint = constraint
        self.global_alias = global_alias
Esempio n. 11
0
    def __init__(self, name, kind=None, mandatory=None, default=None, override=False,
                 allowed_values=None, description=None, constraint=None, global_alias=None, convert_types=True):
        """
        Create a new Parameter object.

        :param name: The name of the parameter. This will become an instance member of the
                     extension object to which the parameter is applied, so it must be a valid
                     python  identifier. This is the only mandatory parameter.
        :param kind: The type of parameter this is. This must be a callable that takes an arbitrary
                     object and converts it to the expected type, or raised ``ValueError`` if such
                     conversion is not possible. Most Python standard types -- ``str``, ``int``, ``bool``, etc. --
                     can be used here. This defaults to ``str`` if not specified.
        :param mandatory: If set to ``True``, then a non-``None`` value for this parameter *must* be
                          provided on extension object construction, otherwise ``ConfigError`` will be
                          raised.
        :param default: The default value for this parameter. If no value is specified on extension
                        construction, this value will be used instead. (Note: if this is specified and
                        is not ``None``, then ``mandatory`` parameter will be ignored).
        :param override: A ``bool`` that specifies whether a parameter of the same name further up the
                         hierarchy should be overridden. If this is ``False`` (the default), an exception
                         will be raised by the ``AttributeCollection`` instead.
        :param allowed_values: This should be the complete list of allowed values for this parameter.
                               Note: ``None`` value will always be allowed, even if it is not in this list.
                               If you want to disallow ``None``, set ``mandatory`` to ``True``.
        :param constraint: If specified, this must be a callable that takes the parameter value
                           as an argument and return a boolean indicating whether the constraint
                           has been satisfied. Alternatively, can be a two-tuple with said callable as
                           the first element and a string describing the constraint as the second.
        :param global_alias: This is an alternative alias for this parameter, unlike the name, this
                             alias will not be namespaced under the owning extension's name (hence the
                             global part). This is introduced primarily for backward compatibility -- so
                             that old extension settings names still work. This should not be used for
                             new parameters.

        :param convert_types: If ``True`` (the default), will automatically convert ``kind`` values from
                              native Python types to WA equivalents. This allows more ituitive interprestation
                              of parameter values, e.g. the string ``"false"`` being interpreted as ``False``
                              when specifed as the value for a boolean Parameter.

        """
        self.name = identifier(name)
        if kind is not None and not callable(kind):
            raise ValueError('Kind must be callable.')
        if convert_types and kind in self.kind_map:
            kind = self.kind_map[kind]
        self.kind = kind
        self.mandatory = mandatory
        self.default = default
        self.override = override
        self.allowed_values = allowed_values
        self.description = description
        if self.kind is None and not self.override:
            self.kind = str
        if constraint is not None and not callable(constraint) and not isinstance(constraint, tuple):
            raise ValueError('Constraint must be callable or a (callable, str) tuple.')
        self.constraint = constraint
        self.global_alias = global_alias
 def _finalize_config_list(self, attr_name):
     """Note: the name is somewhat misleading. This finalizes a list
     form the specified configuration (e.g. "instrumentation"); internal
     representation is actually a dict, not a list..."""
     ext_config = {}
     raw_list = self._raw_config.get(attr_name, [])
     for extname in raw_list:
         default_config = self.ext_loader.get_default_config(extname)
         ext_config[extname] = self._raw_config.get(identifier(extname), default_config)
     list_name = '_global_{}'.format(attr_name)
     global_list = self._raw_config.get(list_name, [])
     setattr(self, list_name, global_list)
     setattr(self, attr_name, ext_config)
Esempio n. 13
0
 def _finalize_config_list(self, attr_name):
     """Note: the name is somewhat misleading. This finalizes a list
     form the specified configuration (e.g. "instrumentation"); internal
     representation is actually a dict, not a list..."""
     ext_config = {}
     raw_list = self._raw_config.get(attr_name, [])
     for extname in raw_list:
         default_config = self.ext_loader.get_default_config(extname)
         ext_config[extname] = self._raw_config.get(identifier(extname),
                                                    default_config)
     list_name = '_global_{}'.format(attr_name)
     global_list = self._raw_config.get(list_name, [])
     setattr(self, list_name, global_list)
     setattr(self, attr_name, ext_config)
Esempio n. 14
0
    def resolve_alias(self, alias_name):
        """
        Try to resolve the specified name as an extension alias. Returns a
        two-tuple, the first value of which is actual extension name, and the
        second is a dict of parameter values for this alias. If the name passed
        is already an extension name, then the result is ``(alias_name, {})``.

        """
        alias_name = identifier(alias_name.lower())
        if alias_name in self.extensions:
            return (alias_name, {})
        if alias_name in self.aliases:
            alias = self.aliases[alias_name]
            return (alias.extension_name, alias.params)
        raise NotFoundError('Could not find extension or alias "{}"'.format(alias_name))
    def resolve_alias(self, alias_name):
        """
        Try to resolve the specified name as an extension alias. Returns a
        two-tuple, the first value of which is actual extension name, and the
        second is a dict of parameter values for this alias. If the name passed
        is already an extension name, then the result is ``(alias_name, {})``.

        """
        alias_name = identifier(alias_name.lower())
        if alias_name in self.extensions:
            return (alias_name, {})
        if alias_name in self.aliases:
            alias = self.aliases[alias_name]
            return (alias.extension_name, alias.params)
        raise NotFoundError('Could not find extension or alias "{}"'.format(alias_name))
Esempio n. 16
0
    def update_result(self, context):  # pylint: disable=too-many-locals
        if not self.raw_output:
            self.logger.warning('Did not get run_benchmark output.')
            return
        raw_outfile = os.path.join(context.output_directory, 'telemetry_raw.out')
        with open(raw_outfile, 'w') as wfh:
            wfh.write(self.raw_output)
        context.add_artifact('telemetry-raw', raw_outfile, kind='raw')

        results, artifacts = parse_telemetry_results(raw_outfile)
        csv_outfile = os.path.join(context.output_directory, 'telemetry.csv')
        with open(csv_outfile, 'wb') as wfh:
            writer = csv.writer(wfh)
            writer.writerow(['kind', 'url', 'iteration', 'value', 'units'])
            for result in results:
                name_template = identifier('{}_{}_{{}}'.format(result.url, result.kind))
                writer.writerows(result.rows)

                for i, value in enumerate(result.values, 1):
                    context.add_metric(result.kind, value, units=result.units,
                                       classifiers={'url': result.url, 'time': i})

            context.add_artifact('telemetry', csv_outfile, kind='data')

        for idx, artifact in enumerate(artifacts):
            if is_zipfile(artifact):
                zf = ZipFile(artifact)
                for item in zf.infolist():
                    zf.extract(item, context.output_directory)
                    zf.close()
                    context.add_artifact('telemetry_trace_{}'.format(idx), path=item.filename, kind='data')
            else:  # not a zip archive
                wa_path = os.path.join(context.output_directory,
                                       os.path.basename(artifact))
                shutil.copy(artifact, wa_path)
                context.add_artifact('telemetry_artifact_{}'.format(idx), path=wa_path, kind='data')

        if self.extract_fps:
            self.logger.debug('Extracting FPS...')
            _extract_fps(context)
Esempio n. 17
0
 def _resolve_global_alias(self, name, value):
     ga = self.ext_loader.global_param_aliases[name]
     for param, ext in ga.iteritems():
         for name in [ext.name] + [a.name for a in ext.aliases]:
             self._load_default_config_if_necessary(name)
             self._raw_config[identifier(name)][param.name] = value
Esempio n. 18
0
 def on_run_init(self, context):  # pylint: disable=W0613
     if self.measure_energy:
         self.sensors = discover_sensors(self.device, ['energy'])
         for sensor in self.sensors:
             sensor.label = identifier(sensor.label).upper()
 def _load_default_config_if_necessary(self, name):
     name = identifier(name)
     if name not in self._raw_config:
         self._raw_config[name] = self.ext_loader.get_default_config(name)
 def _set_raw_list(self, name, value):
     old_value = self._raw_config.get(name, [])
     new_value = merge_lists(old_value, value, duplicates='last')
     self._raw_config[identifier(name)] = new_value
Esempio n. 21
0
 def on_run_init(self, context):  # pylint: disable=W0613
     if self.measure_energy:
         self.sensors = discover_sensors(self.device, ['energy'])
         for sensor in self.sensors:
             sensor.label = identifier(sensor.label).upper()
Esempio n. 22
0
 def update_from_dict(self, source):
     normalized_source = dict((identifier(k), v) for k, v in source.iteritems())
     self._config = merge_dicts(self._config, normalized_source, list_duplicates='first',
                                match_types=False, dict_type=OrderedDict)
     self._loaded = True
Esempio n. 23
0
def get_class_name(name, postfix=''):
    name = identifier(name)
    return ''.join(map(capitalize, name.split('_'))) + postfix
Esempio n. 24
0
def get_class_name(name, postfix=''):
    name = identifier(name)
    return ''.join(map(capitalize, name.split('_'))) + postfix
Esempio n. 25
0
 def _set_raw_dict(self, name, value, default_config=None):
     existing_config = self._raw_config.get(name, default_config or {})
     new_config = _merge_config_dicts(existing_config, value)
     self._raw_config[identifier(name)] = new_config
Esempio n. 26
0
 def _set_raw_list(self, name, value):
     old_value = self._raw_config.get(name, [])
     new_value = merge_lists(old_value, value, duplicates='last')
     self._raw_config[identifier(name)] = new_value
 def _resolve_global_alias(self, name, value):
     ga = self.ext_loader.global_param_aliases[name]
     for param, ext in ga.iteritems():
         for name in [ext.name] + [a.name for a in ext.aliases]:
             self._load_default_config_if_necessary(name)
             self._raw_config[identifier(name)][param.name] = value
Esempio n. 28
0
 def _load_default_config_if_necessary(self, name):
     name = identifier(name)
     if name not in self._raw_config:
         self._raw_config[name] = self.ext_loader.get_default_config(name)
 def _set_raw_dict(self, name, value, default_config=None):
     existing_config = self._raw_config.get(name, default_config or {})
     new_config = _merge_config_dicts(existing_config, value)
     self._raw_config[identifier(name)] = new_config