Ejemplo n.º 1
0
    def test_pluggable_inputs(self):
        algorithm_problems = set()
        for pluggable_name in local_pluggables(PluggableType.ALGORITHM):
            configuration = get_pluggable_configuration(PluggableType.ALGORITHM, pluggable_name)
            if isinstance(configuration, dict):
                algorithm_problems.update(configuration.get('problems', []))

        err_msgs = []
        all_problems = set()
        for pluggable_name in local_pluggables(PluggableType.INPUT):
            cls = get_pluggable_class(PluggableType.INPUT, pluggable_name)
            configuration = get_pluggable_configuration(PluggableType.INPUT, pluggable_name)
            missing_problems = []
            if isinstance(configuration, dict):
                problem_names = configuration.get('problems', [])
                all_problems.update(problem_names)
                for problem_name in problem_names:
                    if problem_name not in algorithm_problems:
                        missing_problems.append(problem_name)

            if len(missing_problems) > 0:
                err_msgs.append("{}: No algorithm declares the problems {}.".format(cls, missing_problems))

        invalid_problems = list(set(AlgorithmInput._PROBLEM_SET).difference(all_problems))
        if len(invalid_problems) > 0:
            err_msgs.append("Base Class AlgorithmInput contains problems {} that don't belong to any Input class.".format(invalid_problems))

        if len(err_msgs) > 0:
            self.fail('\n'.join(err_msgs))
Ejemplo n.º 2
0
    def _update_dependencies(self, section_name, sections_to_be_deleted,
                             pluggable_dependencies):
        # remove dependency pluggable type from sections to be deleted
        if section_name in sections_to_be_deleted:
            sections_to_be_deleted.remove(section_name)

        # update sections with dependencies recursevely
        for pluggable_type_dict in pluggable_dependencies:
            pluggable_type = pluggable_type_dict.get('pluggable_type')
            if pluggable_type is None:
                continue

            pluggable_name = None
            pluggable_defaults = pluggable_type_dict.get('default')
            if pluggable_defaults is not None:
                pluggable_name = pluggable_defaults.get(JSONSchema.NAME)

            if pluggable_name is not None:
                if pluggable_type not in self._sections:
                    self.set_section_property(pluggable_type, JSONSchema.NAME,
                                              pluggable_name)
                    # update default values for new dependency pluggable types
                    default_properties = self.get_section_default_properties(
                        pluggable_type)
                    if isinstance(default_properties, dict):
                        self.set_section_properties(pluggable_type,
                                                    default_properties)

                config = get_pluggable_configuration(pluggable_type,
                                                     pluggable_name)
                self._update_dependencies(pluggable_type,
                                          sections_to_be_deleted,
                                          config.get('depends', []))
Ejemplo n.º 3
0
    def _update_dependency_schemas(self, pluggable_dependencies, input_parser):
        # update schema with dependencies recursevely
        for pluggable_type_dict in pluggable_dependencies:
            pluggable_type = pluggable_type_dict.get('pluggable_type')
            if pluggable_type is None:
                continue

            pluggable_name = None
            pluggable_defaults = pluggable_type_dict.get('default')
            default_properties = {}
            if pluggable_defaults is not None:
                for key, value in pluggable_defaults.items():
                    if key == JSONSchema.NAME:
                        pluggable_name = value
                    else:
                        default_properties[key] = value

            default_name = pluggable_name
            pluggable_name = input_parser.get_section_property(pluggable_type, JSONSchema.NAME, pluggable_name)
            if default_name is None:
                default_name = pluggable_name

            # update dependency schema
            self._update_pluggable_schema(pluggable_type, pluggable_name, default_name)
            for property_name in self._schema['properties'][pluggable_type]['properties'].keys():
                if property_name in default_properties:
                    self._schema['properties'][pluggable_type]['properties'][property_name]['default'] = default_properties[property_name]

            if pluggable_name is not None:
                config = get_pluggable_configuration(pluggable_type, pluggable_name)
                self._update_dependency_schemas(config.get('depends', []), input_parser)
Ejemplo n.º 4
0
    def _update_pluggable_schema(self, pluggable_type, pluggable_name,
                                 default_name):
        config = {}
        try:
            if pluggable_type is not None and pluggable_name is not None:
                config = get_pluggable_configuration(pluggable_type,
                                                     pluggable_name)
        except:
            pass

        input_schema = config.get('input_schema', {})
        properties = input_schema.get('properties', {})
        properties[JSONSchema.NAME] = {'type': 'string'}
        required = input_schema.get('required', [])
        additionalProperties = input_schema.get('additionalProperties', True)
        if default_name is not None:
            properties[JSONSchema.NAME]['default'] = default_name
            required.append(JSONSchema.NAME)

        if pluggable_type not in self._schema['properties']:
            self._schema['properties'][pluggable_type] = {'type': 'object'}

        self._schema['properties'][pluggable_type]['properties'] = properties
        if len(required) > 0:
            self._schema['properties'][pluggable_type]['required'] = required
        elif 'required' in self._schema['properties'][pluggable_type]:
            del self._schema['properties'][pluggable_type]['required']

        self._schema['properties'][pluggable_type][
            'additionalProperties'] = additionalProperties
Ejemplo n.º 5
0
    def _validate_defaults_against_schema(self, dependency_pluggable_type,
                                          default_name, defaults):
        cls = get_pluggable_class(dependency_pluggable_type, default_name)
        default_config = get_pluggable_configuration(dependency_pluggable_type,
                                                     default_name)
        if not isinstance(default_config, dict):
            return ["{} configuration isn't a dictionary.".format(cls)]

        schema = default_config.get('input_schema')
        if not isinstance(default_config, dict):
            return [
                "{} configuration schema missing or isn't a dictionary.".
                format(cls)
            ]

        properties = schema.get('properties')
        if not isinstance(properties, dict):
            return [
                "{} configuration schema '{}' missing or isn't a dictionary.".
                format(cls, 'properties')
            ]

        err_msgs = []
        for default_property_name, default_property_value in defaults.items():
            prop = properties.get(default_property_name)
            if not isinstance(prop, dict):
                err_msgs.append("{} configuration schema '{}/{}' "
                                "missing or isn't a dictionary.".format(
                                    cls, 'properties', default_property_name))
        return err_msgs
Ejemplo n.º 6
0
    def get_input_problems(input_name):
        """ returns input problems """
        config = get_pluggable_configuration(PluggableType.INPUT, input_name)
        if 'problems' in config:
            return config['problems']

        return []
Ejemplo n.º 7
0
    def test_pluggable_configuration(self):
        """ pluggable configuration tests """
        err_msgs = []
        for pluggable_type in local_pluggables_types():
            for pluggable_name in local_pluggables(pluggable_type):
                cls = get_pluggable_class(pluggable_type, pluggable_name)
                configuration = get_pluggable_configuration(
                    pluggable_type, pluggable_name)
                if not isinstance(configuration, dict):
                    err_msgs.append(
                        "{} configuration isn't a dictionary.".format(cls))
                    continue

                if pluggable_type in [
                        PluggableType.ALGORITHM, PluggableType.INPUT
                ]:
                    if not configuration.get('problems', []):
                        err_msgs.append(
                            "{} missing or empty 'problems' section.".format(
                                cls))

                schema_found = False
                for configuration_name, configuration_value in configuration.items(
                ):
                    if configuration_name in ['problems', 'depends']:
                        if not isinstance(configuration_value, list):
                            err_msgs.append(
                                "{} configuration section:'{}' isn't a list.".
                                format(cls, configuration_name))
                            continue

                        if configuration_name == 'depends':
                            err_msgs.extend(
                                self._validate_depends(cls,
                                                       configuration_value))

                        continue

                    if configuration_name == 'input_schema':
                        schema_found = True
                        if not isinstance(configuration_value, dict):
                            err_msgs.append(
                                "{} configuration section:'{}' isn't a dictionary."
                                .format(cls, configuration_name))
                            continue

                        err_msgs.extend(
                            self._validate_schema(cls, configuration_value))
                        continue

                if not schema_found:
                    err_msgs.append(
                        "{} configuration missing schema.".format(cls))

        if err_msgs:
            self.fail('\n'.join(err_msgs))
Ejemplo n.º 8
0
    def _update_algorithm_input_schema(self):
        # find algorithm input
        default_name = self.get_property_default_value(PluggableType.INPUT.value, JSONSchema.NAME)
        input_name = self.get_section_property(PluggableType.INPUT.value,
                                               JSONSchema.NAME, default_name)
        if input_name is None:
            # find the first valid input for the problem
            problem_name = self.get_section_property(JSONSchema.PROBLEM, JSONSchema.NAME)
            if problem_name is None:
                problem_name = self.get_property_default_value(JSONSchema.PROBLEM,
                                                               JSONSchema.NAME)

            if problem_name is None:
                raise AquaError("No algorithm 'problem' section found on input.")

            for name in local_pluggables(PluggableType.INPUT):
                if problem_name in self.get_input_problems(name):
                    # set to the first input to solve the problem
                    input_name = name
                    break

        if input_name is None:
            # just remove from schema if none solves the problem
            if PluggableType.INPUT.value in self.json_schema.schema['properties']:
                del self.json_schema.schema['properties'][PluggableType.INPUT.value]
            return

        if default_name is None:
            default_name = input_name

        config = {}
        try:
            config = get_pluggable_configuration(PluggableType.INPUT, input_name)
        except Exception:  # pylint: disable=broad-except
            pass

        input_schema = config['input_schema'] if 'input_schema' in config else {}
        properties = input_schema['properties'] if 'properties' in input_schema else {}
        properties[JSONSchema.NAME] = {'type': 'string'}
        required = input_schema['required'] if 'required' in input_schema else []
        additional_properties = input_schema['additionalProperties'] \
            if 'additionalProperties' in input_schema else True
        if default_name is not None:
            properties[JSONSchema.NAME]['default'] = default_name
            required.append(JSONSchema.NAME)

        if PluggableType.INPUT.value not in self.json_schema.schema['properties']:
            self.json_schema.schema['properties'][PluggableType.INPUT.value] = {'type': 'object'}

        self.json_schema.schema['properties'][PluggableType.INPUT.value]['properties'] = properties
        self.json_schema.schema['properties'][PluggableType.INPUT.value]['required'] = required
        self.json_schema.schema['properties'][PluggableType.INPUT.value]['additionalProperties'] = \
            additional_properties
Ejemplo n.º 9
0
    def _get_dependency_sections(self, pluggable_type, pluggable_name):
        config = get_pluggable_configuration(pluggable_type, pluggable_name)
        dependency_sections = set()
        pluggable_dependencies = config.get('depends', [])
        for dependency_pluggable_type_dict in pluggable_dependencies:
            dependency_pluggable_type = dependency_pluggable_type_dict.get('pluggable_type')
            if dependency_pluggable_type is not None:
                dependency_sections.add(dependency_pluggable_type)
                dependency_pluggable_name = dependency_pluggable_type_dict.get('default', {}).get(JSONSchema.NAME)
                if dependency_pluggable_name is not None:
                    dependency_sections.update(self._get_dependency_sections(dependency_pluggable_type, dependency_pluggable_name))

        return dependency_sections
Ejemplo n.º 10
0
    def _merge_dependencies(self):
        algo_name = self.get_section_property(PluggableType.ALGORITHM.value,
                                              JSONSchema.NAME)
        if algo_name is None:
            return

        config = get_pluggable_configuration(PluggableType.ALGORITHM,
                                             algo_name)
        pluggable_dependencies = [] if 'depends' not in config else config[
            'depends']
        pluggable_defaults = {} if 'defaults' not in config else config[
            'defaults']
        for pluggable_type in local_pluggables_types():
            if pluggable_type not in [PluggableType.INPUT, PluggableType.ALGORITHM] and \
                    pluggable_type.value not in pluggable_dependencies:
                # remove pluggables from input that are not in the dependencies
                if pluggable_type.value in self._sections:
                    del self._sections[pluggable_type.value]

        section_names = self.get_section_names()
        for pluggable_type in pluggable_dependencies:
            pluggable_name = None
            new_properties = {}
            if pluggable_type in pluggable_defaults:
                for key, value in pluggable_defaults[pluggable_type].items():
                    if key == JSONSchema.NAME:
                        pluggable_name = pluggable_defaults[pluggable_type][
                            key]
                    else:
                        new_properties[key] = value

            if pluggable_name is None:
                continue

            if pluggable_type not in section_names:
                self.set_section(pluggable_type)

            if self.get_section_property(pluggable_type,
                                         JSONSchema.NAME) is None:
                self.set_section_property(pluggable_type, JSONSchema.NAME,
                                          pluggable_name)

            if pluggable_name == self.get_section_property(
                    pluggable_type, JSONSchema.NAME):
                properties = self.get_section_properties(pluggable_type)
                if new_properties:
                    new_properties.update(properties)
                else:
                    new_properties = properties

                self.set_section_properties(pluggable_type, new_properties)
Ejemplo n.º 11
0
    def get_algorithm_problems(algo_name):
        """
        Get algorithm problem name list
        Args:
            algo_name (string): algorithm name

        Returns:
            Returns list of problem names
        """
        config = get_pluggable_configuration(PluggableType.ALGORITHM, algo_name)
        if 'problems' in config:
            return config['problems']

        return []
Ejemplo n.º 12
0
    def _update_dependency_sections(self, section_name):
        prop_name = self.get_section_property(section_name, JSONSchema.NAME)
        config = {} if prop_name is None else get_pluggable_configuration(section_name, prop_name)
        pluggable_dependencies = config.get('depends', [])
        if section_name == PluggableType.ALGORITHM.value:
            classical = config.get('classical', False)
            # update backend based on classical
            if classical:
                if JSONSchema.BACKEND in self._sections:
                    del self._sections[JSONSchema.BACKEND]
            else:
                if JSONSchema.BACKEND not in self._sections:
                    self.set_section_properties(JSONSchema.BACKEND, self.get_section_default_properties(JSONSchema.BACKEND))

        # update dependencies recursively
        self._update_dependencies(section_name, pluggable_dependencies)
Ejemplo n.º 13
0
    def update_pluggable_schemas(self, input_parser):
        """
        Updates schemas of all pluggables

        Args:
            input_parser (obj): input parser
        """
        # find algorithm
        default_algo_name = self.get_property_default_value(
            PluggableType.ALGORITHM.value, JSONSchema.NAME)
        algo_name = input_parser.get_section_property(
            PluggableType.ALGORITHM.value, JSONSchema.NAME, default_algo_name)

        # update algorithm scheme
        if algo_name is not None:
            self._update_pluggable_schema(PluggableType.ALGORITHM.value,
                                          algo_name, default_algo_name)

        # update algorithm dependencies scheme
        config = {} if algo_name is None else get_pluggable_configuration(
            PluggableType.ALGORITHM, algo_name)
        classical = config.get('classical', False)
        # update algorithm backend from schema if it is classical or not
        if classical:
            if JSONSchema.BACKEND in self._schema['properties']:
                del self._schema['properties'][JSONSchema.BACKEND]
        else:
            if JSONSchema.BACKEND not in self._schema['properties']:
                self._schema['properties'][
                    JSONSchema.BACKEND] = self._original_schema['properties'][
                        JSONSchema.BACKEND]
                self.update_backend_schema(input_parser)

        pluggable_dependencies = config.get('depends', [])

        # remove pluggables from schema that are not in the dependencies of algorithm
        pluggable_dependency_names = [
            item['pluggable_type'] for item in pluggable_dependencies
            if 'pluggable_type' in item
        ]
        for pluggable_type in local_pluggables_types():
            if pluggable_type not in [PluggableType.INPUT, PluggableType.ALGORITHM] and \
               pluggable_type.value not in pluggable_dependency_names and \
               pluggable_type.value in self._schema['properties']:
                del self._schema['properties'][pluggable_type.value]

        self._update_dependency_schemas(pluggable_dependencies, input_parser)
Ejemplo n.º 14
0
    def _update_dependencies(self, section_name, pluggable_dependencies):
        # update sections with dependencies recursevely
        for pluggable_type_dict in pluggable_dependencies:
            pluggable_type = pluggable_type_dict.get('pluggable_type')
            if pluggable_type is None:
                continue

            pluggable_name = pluggable_type_dict.get('default', {}).get(JSONSchema.NAME)
            if pluggable_name is not None:
                if pluggable_type not in self._sections:
                    # update default values for new dependency pluggable types
                    default_properties = self.get_section_default_properties(pluggable_type)
                    if isinstance(default_properties, dict):
                        self.set_section_properties(pluggable_type, default_properties)

                config = get_pluggable_configuration(pluggable_type, pluggable_name)
                self._update_dependencies(pluggable_type, config.get('depends', []))
Ejemplo n.º 15
0
    def _merge_dependencies(self):
        algo_name = self.get_section_property(PluggableType.ALGORITHM.value,
                                              JSONSchema.NAME)
        if algo_name is None:
            return

        config = get_pluggable_configuration(PluggableType.ALGORITHM,
                                             algo_name)
        pluggable_dependencies = config.get('depends', [])

        section_names = self.get_section_names()
        for pluggable_type_dict in pluggable_dependencies:
            pluggable_type = pluggable_type_dict.get('pluggable_type')
            if pluggable_type is None:
                continue

            pluggable_name = None
            pluggable_defaults = pluggable_type_dict.get('default')
            new_properties = {}
            if pluggable_defaults is not None:
                for key, value in pluggable_defaults.items():
                    if key == JSONSchema.NAME:
                        pluggable_name = value
                    else:
                        new_properties[key] = value

            if pluggable_name is None:
                continue

            if pluggable_type not in section_names:
                self.set_section(pluggable_type)

            if self.get_section_property(pluggable_type,
                                         JSONSchema.NAME) is None:
                self.set_section_property(pluggable_type, JSONSchema.NAME,
                                          pluggable_name)

            if pluggable_name == self.get_section_property(
                    pluggable_type, JSONSchema.NAME):
                properties = self.get_section_properties(pluggable_type)
                if new_properties:
                    new_properties.update(properties)
                else:
                    new_properties = properties

                self.set_section_properties(pluggable_type, new_properties)
Ejemplo n.º 16
0
    def _update_dependency_sections(self):
        algo_name = self.get_section_property(PluggableType.ALGORITHM.value,
                                              JSONSchema.NAME)
        config = {} if algo_name is None else get_pluggable_configuration(
            PluggableType.ALGORITHM, algo_name)
        classical = config['classical'] if 'classical' in config else False
        pluggable_dependencies = [] if 'depends' not in config else config[
            'depends']
        pluggable_defaults = {} if 'defaults' not in config else config[
            'defaults']
        for pluggable_type in local_pluggables_types():
            # remove pluggables from input that are not in the dependencies
            if pluggable_type not in [PluggableType.INPUT, PluggableType.ALGORITHM] and \
                    pluggable_type.value not in pluggable_dependencies and \
                    pluggable_type.value in self._sections:
                del self._sections[pluggable_type.value]

        for pluggable_type in pluggable_dependencies:
            pluggable_name = None
            if pluggable_type in pluggable_defaults:
                if JSONSchema.NAME in pluggable_defaults[pluggable_type]:
                    pluggable_name = pluggable_defaults[pluggable_type][
                        JSONSchema.NAME]

            if pluggable_name is not None and pluggable_type not in self._sections:
                self.set_section_property(pluggable_type, JSONSchema.NAME,
                                          pluggable_name)
                # update default values for new dependency pluggable types
                self.set_section_properties(
                    pluggable_type,
                    self.get_section_default_properties(pluggable_type))

        # update backend based on classical
        if classical:
            if JSONSchema.BACKEND in self._sections:
                del self._sections[JSONSchema.BACKEND]
        else:
            if JSONSchema.BACKEND not in self._sections:
                self.set_section_properties(
                    JSONSchema.BACKEND,
                    self.get_section_default_properties(JSONSchema.BACKEND))

        # reorder sections
        self._sections = self._order_sections(self._sections)
Ejemplo n.º 17
0
    def _load_data(self):
        if self._data_loaded:
            return

        from qiskit.aqua import (local_pluggables_types, local_pluggables,
                                 get_pluggable_configuration)

        self._schema_property_titles = OrderedDict()
        self._sections = OrderedDict()
        for pluggable_type in sorted(local_pluggables_types(),
                                     key=lambda x: x.value):
            self._sections[pluggable_type.value] = OrderedDict()
            self._schema_property_titles[pluggable_type.value] = OrderedDict()
            for pluggable_name in sorted(local_pluggables(pluggable_type)):
                config = copy.deepcopy(
                    get_pluggable_configuration(pluggable_type,
                                                pluggable_name))
                self._populate_section(pluggable_type.value, pluggable_name,
                                       config)

        self._data_loaded = True
Ejemplo n.º 18
0
    def _update_dependency_sections(self, section_name):
        sections_to_be_deleted = []
        prop_name = self.get_section_property(section_name, JSONSchema.NAME)
        config = {} if prop_name is None else get_pluggable_configuration(
            section_name, prop_name)
        pluggable_dependencies = config.get('depends', [])
        if section_name == PluggableType.ALGORITHM.value:
            sections_to_be_deleted = [
                name for name in self.get_section_names()
                if name != PluggableType.INPUT.value
                and self.is_pluggable_section(name)
            ]

            classical = config.get('classical', False)
            # update backend based on classical
            if classical:
                if JSONSchema.BACKEND in self._sections:
                    del self._sections[JSONSchema.BACKEND]
            else:
                if JSONSchema.BACKEND not in self._sections:
                    self.set_section_properties(
                        JSONSchema.BACKEND,
                        self.get_section_default_properties(
                            JSONSchema.BACKEND))

        # update dependencies recursively
        self._update_dependencies(section_name, sections_to_be_deleted,
                                  pluggable_dependencies)

        # remove pluggable sections not in algorithm dependency list
        for name in sections_to_be_deleted:
            if name in self._sections:
                del self._sections[name]

        # reorder sections
        self._sections = self._order_sections(self._sections)
Ejemplo n.º 19
0
    def update_pluggable_input_schemas(self, input_parser):
        """
        Updates schemas of all pluggables

        Args:
            input_parser (obj): input parser
        """
        # find algorithm
        default_algo_name = self.get_property_default_value(
            PluggableType.ALGORITHM.value, JSONSchema.NAME)
        algo_name = input_parser.get_section_property(
            PluggableType.ALGORITHM.value, JSONSchema.NAME, default_algo_name)

        # update algorithm scheme
        if algo_name is not None:
            self._update_pluggable_input_schema(PluggableType.ALGORITHM.value,
                                                algo_name, default_algo_name)

        # update algorithm depoendencies scheme
        config = {} if algo_name is None else get_pluggable_configuration(
            PluggableType.ALGORITHM, algo_name)
        classical = config['classical'] if 'classical' in config else False
        pluggable_dependencies = [] if 'depends' not in config else config[
            'depends']
        pluggable_defaults = {} if 'defaults' not in config else config[
            'defaults']
        pluggable_types = local_pluggables_types()
        for pluggable_type in pluggable_types:
            if pluggable_type not in [PluggableType.INPUT, PluggableType.ALGORITHM] and \
                    pluggable_type.value not in pluggable_dependencies:
                # remove pluggables from schema that ate not in the dependencies
                if pluggable_type.value in self._schema['properties']:
                    del self._schema['properties'][pluggable_type.value]

        # update algorithm backend from schema if it is classical or not
        if classical:
            if JSONSchema.BACKEND in self._schema['properties']:
                del self._schema['properties'][JSONSchema.BACKEND]
        else:
            if JSONSchema.BACKEND not in self._schema['properties']:
                self._schema['properties'][
                    JSONSchema.BACKEND] = self._original_schema['properties'][
                        JSONSchema.BACKEND]

        # update schema with dependencies
        for pluggable_type in pluggable_dependencies:
            pluggable_name = None
            default_properties = {}
            if pluggable_type in pluggable_defaults:
                for key, value in pluggable_defaults[pluggable_type].items():
                    if key == JSONSchema.NAME:
                        pluggable_name = pluggable_defaults[pluggable_type][
                            key]
                    else:
                        default_properties[key] = value

            default_name = pluggable_name
            pluggable_name = input_parser.get_section_property(
                pluggable_type, JSONSchema.NAME, pluggable_name)

            # update dependency schema
            self._update_pluggable_input_schema(pluggable_type, pluggable_name,
                                                default_name)
            for property_name in self._schema['properties'][pluggable_type][
                    'properties'].keys():
                if property_name in default_properties:
                    self._schema['properties'][pluggable_type]['properties'][
                        property_name]['default'] = default_properties[
                            property_name]