示例#1
0
    def load_file(self, filename, parser_class, populate_defaults):
        from qiskit.aqua.parser import JSONSchema
        from qiskit.aqua import get_provider_from_backend, get_backends_from_provider
        if filename is None:
            return []
        try:
            self._parser = parser_class(filename)
            self._parser.parse()
            # before merging defaults attempts to find a provider for the backend
            provider = self._parser.get_section_property(
                JSONSchema.BACKEND, JSONSchema.PROVIDER)
            if provider is None:
                backend_name = self._parser.get_section_property(
                    JSONSchema.BACKEND, JSONSchema.NAME)
                if backend_name is not None:
                    self._parser.set_section_property(
                        JSONSchema.BACKEND, JSONSchema.PROVIDER,
                        get_provider_from_backend(backend_name))
            else:
                try:
                    if provider not in self.providers:
                        self._custom_providers[
                            provider] = get_backends_from_provider(provider)
                except Exception as e:
                    logger.debug(str(e))

            if populate_defaults:
                self._parser.validate_merge_defaults()
                self._parser.commit_changes()

            return self._parser.get_section_names()
        except:
            self._parser = None
            raise
    def load_model(self, filename, parser_class, populate_defaults):
        """ load a model """
        from qiskit.aqua.parser import JSONSchema
        from qiskit.aqua import get_provider_from_backend, get_backends_from_provider
        if filename is None:
            return []
        try:
            self._parser = parser_class(filename)
            self._parser.parse()
            # check if there was any data, if there is no data, just return empty file
            if not self.get_section_names():
                return []

            # before merging defaults attempts to find a provider for the backend
            provider = self._parser.get_section_property(
                JSONSchema.BACKEND, JSONSchema.PROVIDER)
            if provider is None:
                backend_name = \
                    self._parser.get_section_property(JSONSchema.BACKEND, JSONSchema.NAME)
                if backend_name is not None:
                    self._parser.set_section_property(
                        JSONSchema.BACKEND, JSONSchema.PROVIDER,
                        get_provider_from_backend(backend_name))
            else:
                try:
                    if provider not in self.providers:
                        self._custom_providers[
                            provider] = get_backends_from_provider(provider)
                except Exception as ex:  # pylint: disable=broad-except
                    logger.debug(str(ex))
        except Exception:
            self._parser = None
            raise

        try:
            if populate_defaults:
                self._parser.validate_merge_defaults()

            return self.get_section_names()
        finally:
            self._parser.commit_changes()
示例#3
0
    def run_driver(self, params, backend=None):
        """
        Runs the Qiskit Chemistry driver

        Args:
            params (Union(dictionary, filename)): Chemistry input data
            backend (QuantumInstance or BaseBackend): the experimental settings
                to be used in place of backend name
         Raises:
            QiskitChemistryError: Missing Input
        """
        if params is None:
            raise QiskitChemistryError("Missing input.")

        self._operator = None
        self._chemistry_result = None
        self._qiskit_aqua = None
        self._hdf5_file = None
        self._parser = InputParser(params)
        self._parser.parse()

        # before merging defaults attempts to find a provider for the backend in case no
        # provider was passed
        if backend is None and \
                self._parser.get_section_property(JSONSchema.BACKEND, JSONSchema.PROVIDER) is None:
            backend_name = self._parser.get_section_property(
                JSONSchema.BACKEND, JSONSchema.NAME)
            if backend_name is not None:
                self._parser.set_section_property(
                    JSONSchema.BACKEND, JSONSchema.PROVIDER,
                    get_provider_from_backend(backend_name))

        # set provider and name in input file for proper backend schema dictionary build
        if isinstance(backend, BaseBackend):
            self._parser.backend = backend
            self._parser.add_section_properties(
                JSONSchema.BACKEND, {
                    JSONSchema.PROVIDER: get_provider_from_backend(backend),
                    JSONSchema.NAME: backend.name(),
                })

        self._parser.validate_merge_defaults()

        experiment_name = "-- no &NAME section found --"
        if JSONSchema.NAME in self._parser.get_section_names():
            name_sect = self._parser.get_section(JSONSchema.NAME)
            if name_sect is not None:
                experiment_name = str(name_sect)
        logger.info('Running chemistry problem from input file: %s',
                    self._parser.get_filename())
        logger.info('Experiment description: %s', experiment_name.rstrip())

        driver_name = self._parser.get_section_property(
            InputParser.DRIVER, JSONSchema.NAME)
        if driver_name is None:
            raise QiskitChemistryError(
                'Property "{0}" missing in section "{1}"'.format(
                    JSONSchema.NAME, InputParser.DRIVER))

        self._hdf5_file = \
            self._parser.get_section_property(InputParser.DRIVER, InputParser.HDF5_OUTPUT)

        if driver_name not in local_drivers():
            raise QiskitChemistryError(
                'Driver "{0}" missing in local drivers'.format(driver_name))

        work_path = None
        input_file = self._parser.get_filename()
        if input_file is not None:
            work_path = os.path.dirname(os.path.realpath(input_file))

        section = self._parser.get_section(driver_name)
        driver = get_driver_class(driver_name).init_from_input(section)
        driver.work_path = work_path
        molecule = driver.run()

        if work_path is not None and \
                self._hdf5_file is not None and not os.path.isabs(self._hdf5_file):
            self._hdf5_file = os.path.abspath(
                os.path.join(work_path, self._hdf5_file))

        molecule.log()

        if self._hdf5_file is not None:
            molecule.save(self._hdf5_file)
            logger.info("HDF5 file saved '%s'", self._hdf5_file)

        # Run the Hamiltonian to process the QMolecule and get an input for algorithms
        clazz = get_chemistry_operator_class(
            self._parser.get_section_property(InputParser.OPERATOR,
                                              JSONSchema.NAME))
        self._operator = clazz.init_params(
            self._parser.get_section_properties(InputParser.OPERATOR))
        qubit_op, aux_ops = self.operator.run(molecule)
        input_object = EnergyInput(qubit_op, aux_ops)

        logger.debug('Core computed substitution variables %s',
                     self.operator.molecule_info)
        result = self._parser.process_substitutions(
            self.operator.molecule_info)
        logger.debug('Substitutions %s', result)

        aqua_params = {}
        for section_name, section in self._parser.get_sections().items():
            if section_name == JSONSchema.NAME or \
               section_name == InputParser.DRIVER or \
               section_name == driver_name.lower() or \
               section_name == InputParser.OPERATOR or \
               not isinstance(section, dict):
                continue

            aqua_params[section_name] = copy.deepcopy(section)
            if JSONSchema.PROBLEM == section_name and \
                    InputParser.AUTO_SUBSTITUTIONS in aqua_params[section_name]:
                del aqua_params[section_name][InputParser.AUTO_SUBSTITUTIONS]

        self._qiskit_aqua = QiskitAqua(aqua_params, input_object, backend)
示例#4
0
def build_algorithm_from_dict(params, algo_input=None, backend=None):
    """
        Construct algorithm as named in params, using params and algo_input as input data
        and returning a QuantumAlgorithm and QuantumInstance instance

        Args:
            params (dict): Dictionary of params for algo and dependent objects
            algo_input (AlgorithmInput): Main input data for algorithm. Optional, an algo may run entirely from params
            backend (BaseBackend): Backend object to be used in place of backend name

        Returns:
            Ready-to-run QuantumAlgorithm and QuantumInstance as specified in input parameters. Note that
            no QuantumInstance will be returned if none is specified - None will be returned instead.
        """
    _discover_on_demand()

    inputparser = InputParser(params)
    inputparser.parse()
    # before merging defaults attempts to find a provider for the backend in case no
    # provider was passed
    if backend is None and inputparser.get_section_property(
            JSONSchema.BACKEND, JSONSchema.PROVIDER) is None:
        backend_name = inputparser.get_section_property(
            JSONSchema.BACKEND, JSONSchema.NAME)
        if backend_name is not None:
            inputparser.set_section_property(
                JSONSchema.BACKEND, JSONSchema.PROVIDER,
                get_provider_from_backend(backend_name))

    inputparser.validate_merge_defaults()
    logger.debug('Algorithm Input: {}'.format(
        json.dumps(inputparser.get_sections(), sort_keys=True, indent=4)))

    algo_name = inputparser.get_section_property(PluggableType.ALGORITHM.value,
                                                 JSONSchema.NAME)
    if algo_name is None:
        raise AquaError('Missing algorithm name')

    if algo_name not in local_pluggables(PluggableType.ALGORITHM):
        raise AquaError(
            'Algorithm "{0}" missing in local algorithms'.format(algo_name))

    if algo_input is None:
        input_name = inputparser.get_section_property('input', JSONSchema.NAME)
        if input_name is not None:
            input_params = copy.deepcopy(
                inputparser.get_section_properties('input'))
            del input_params[JSONSchema.NAME]
            convert_json_to_dict(input_params)
            algo_input = get_pluggable_class(
                PluggableType.INPUT, input_name).from_params(input_params)

    algo_params = copy.deepcopy(inputparser.get_sections())
    algorithm = get_pluggable_class(PluggableType.ALGORITHM,
                                    algo_name).init_params(
                                        algo_params, algo_input)
    random_seed = inputparser.get_section_property(JSONSchema.PROBLEM,
                                                   'random_seed')
    algorithm.random_seed = random_seed
    quantum_instance = None
    # setup backend
    backend_provider = inputparser.get_section_property(
        JSONSchema.BACKEND, JSONSchema.PROVIDER)
    backend_name = inputparser.get_section_property(JSONSchema.BACKEND,
                                                    JSONSchema.NAME)
    if backend_provider is not None and backend_name is not None:  # quantum algorithm
        backend_cfg = {
            k: v
            for k, v in inputparser.get_section(JSONSchema.BACKEND).items()
            if k not in [JSONSchema.PROVIDER, JSONSchema.NAME]
        }
        # TODO, how to build the noise model from a dictionary?
        backend_cfg['seed_mapper'] = random_seed
        pass_manager = PassManager() if backend_cfg.pop(
            'skip_transpiler', False) else None
        if pass_manager is not None:
            backend_cfg['pass_manager'] = pass_manager

        if backend is None or not isinstance(backend, BaseBackend):
            backend = get_backend_from_provider(backend_provider, backend_name)
        backend_cfg['backend'] = backend

        # overwrite the basis_gates and coupling_map
        basis_gates = backend_cfg.pop('basis_gates', None)
        coupling_map = backend_cfg.pop('coupling_map', None)
        if backend.configuration().simulator:
            if basis_gates is not None:
                backend.configuration().basis_gates = basis_gates
            if coupling_map is not None:
                backend.configuration().coupling_map = coupling_map
        else:
            logger.warning(
                "Change basis_gates and coupling_map on a real device is disallowed."
            )

        shots = backend_cfg.pop('shots', 1024)
        seed = random_seed
        max_credits = backend_cfg.pop('max_credits', 10)
        memory = backend_cfg.pop('memory', False)
        run_config = RunConfig(shots=shots,
                               max_credits=max_credits,
                               memory=memory)
        if seed is not None:
            run_config.seed = seed
        backend_cfg['run_config'] = run_config

        backend_cfg['skip_qobj_validation'] = inputparser.get_section_property(
            JSONSchema.PROBLEM, 'skip_qobj_validation')
        use_caching = inputparser.get_section_property(JSONSchema.PROBLEM,
                                                       'circuit_caching')
        if use_caching:
            deepcopy_qobj = inputparser.get_section_property(
                JSONSchema.PROBLEM, 'skip_qobj_deepcopy')
            cache_file = inputparser.get_section_property(
                JSONSchema.PROBLEM, 'circuit_cache_file')
            backend_cfg['circuit_cache'] = CircuitCache(
                skip_qobj_deepcopy=deepcopy_qobj, cache_file=cache_file)

        quantum_instance = QuantumInstance(**backend_cfg)

    # Note that quantum_instance can be None if none is specified
    return algorithm, quantum_instance
示例#5
0
    def _build_algorithm_from_dict(self, quantum_instance):
        _discover_on_demand()
        self._parser = InputParser(self._params)
        self._parser.parse()
        # before merging defaults attempts to find a provider for the backend in case no
        # provider was passed
        if quantum_instance is None and self._parser.get_section_property(
                JSONSchema.BACKEND, JSONSchema.PROVIDER) is None:
            backend_name = self._parser.get_section_property(
                JSONSchema.BACKEND, JSONSchema.NAME)
            if backend_name is not None:
                self._parser.set_section_property(
                    JSONSchema.BACKEND, JSONSchema.PROVIDER,
                    get_provider_from_backend(backend_name))

        self._parser.validate_merge_defaults()
        logger.debug('Algorithm Input: {}'.format(
            json.dumps(self._parser.get_sections(), sort_keys=True, indent=4)))

        algo_name = self._parser.get_section_property(
            PluggableType.ALGORITHM.value, JSONSchema.NAME)
        if algo_name is None:
            raise AquaError('Missing algorithm name')

        if algo_name not in local_pluggables(PluggableType.ALGORITHM):
            raise AquaError(
                'Algorithm "{0}" missing in local algorithms'.format(
                    algo_name))

        if self._algorithm_input is None:
            input_name = self._parser.get_section_property(
                'input', JSONSchema.NAME)
            if input_name is not None:
                input_params = copy.deepcopy(
                    self._parser.get_section_properties('input'))
                del input_params[JSONSchema.NAME]
                convert_json_to_dict(input_params)
                self._algorithm_input = get_pluggable_class(
                    PluggableType.INPUT, input_name).from_params(input_params)

        algo_params = copy.deepcopy(self._parser.get_sections())
        self._quantum_algorithm = get_pluggable_class(
            PluggableType.ALGORITHM,
            algo_name).init_params(algo_params, self._algorithm_input)
        random_seed = self._parser.get_section_property(
            JSONSchema.PROBLEM, 'random_seed')
        self._quantum_algorithm.random_seed = random_seed

        if isinstance(quantum_instance, QuantumInstance):
            self._quantum_instance = quantum_instance
            return

        backend = None
        if isinstance(quantum_instance, BaseBackend):
            backend = quantum_instance
        elif quantum_instance is not None:
            raise AquaError(
                'Invalid QuantumInstance or BaseBackend parameter {}.'.format(
                    quantum_instance))

        # setup backend
        backend_provider = self._parser.get_section_property(
            JSONSchema.BACKEND, JSONSchema.PROVIDER)
        backend_name = self._parser.get_section_property(
            JSONSchema.BACKEND, JSONSchema.NAME)
        if backend_provider is not None and backend_name is not None:  # quantum algorithm
            backend_cfg = {
                k: v
                for k, v in self._parser.get_section(
                    JSONSchema.BACKEND).items()
                if k not in [JSONSchema.PROVIDER, JSONSchema.NAME]
            }
            # TODO, how to build the noise model from a dictionary?
            backend_cfg['seed_mapper'] = random_seed
            pass_manager = PassManager() if backend_cfg.pop(
                'skip_transpiler', False) else None
            if pass_manager is not None:
                backend_cfg['pass_manager'] = pass_manager

            if backend is None:
                backend = get_backend_from_provider(backend_provider,
                                                    backend_name)

            backend_cfg['backend'] = backend

            # overwrite the basis_gates and coupling_map
            basis_gates = backend_cfg.pop('basis_gates', None)
            if isinstance(basis_gates, str):
                basis_gates = basis_gates.split(',')

            coupling_map = backend_cfg.pop('coupling_map', None)
            if backend.configuration().simulator:
                if basis_gates is not None:
                    backend.configuration().basis_gates = basis_gates
                if coupling_map is not None:
                    backend.configuration().coupling_map = coupling_map
            else:
                logger.warning(
                    "Change basis_gates and coupling_map on a real device is disallowed."
                )

            shots = backend_cfg.pop('shots', 1024)
            seed = random_seed
            max_credits = backend_cfg.pop('max_credits', 10)
            memory = backend_cfg.pop('memory', False)
            run_config = RunConfig(shots=shots,
                                   max_credits=max_credits,
                                   memory=memory)
            if seed is not None:
                run_config.seed = seed
            backend_cfg['run_config'] = run_config

            backend_cfg[
                'skip_qobj_validation'] = self._parser.get_section_property(
                    JSONSchema.PROBLEM, 'skip_qobj_validation')
            use_caching = self._parser.get_section_property(
                JSONSchema.PROBLEM, 'circuit_caching')
            if use_caching:
                deepcopy_qobj = self._parser.get_section_property(
                    JSONSchema.PROBLEM, 'skip_qobj_deepcopy')
                cache_file = self._parser.get_section_property(
                    JSONSchema.PROBLEM, 'circuit_cache_file')
                backend_cfg['circuit_cache'] = CircuitCache(
                    skip_qobj_deepcopy=deepcopy_qobj, cache_file=cache_file)

            self._quantum_instance = QuantumInstance(**backend_cfg)
示例#6
0
    def _run_driver_from_parser(self, p, save_json_algo_file):
        if p is None:
            raise QiskitChemistryError("Missing parser")

        # before merging defaults attempts to find a provider for the backend in case no
        # provider was passed
        if p.get_section_property(JSONSchema.BACKEND,
                                  JSONSchema.PROVIDER) is None:
            backend_name = p.get_section_property(JSONSchema.BACKEND,
                                                  JSONSchema.NAME)
            if backend_name is not None:
                p.set_section_property(JSONSchema.BACKEND, JSONSchema.PROVIDER,
                                       get_provider_from_backend(backend_name))

        p.validate_merge_defaults()
        # logger.debug('ALgorithm Input Schema: {}'.format(json.dumps(p..get_sections(), sort_keys=True, indent=4)))

        experiment_name = "-- no &NAME section found --"
        if JSONSchema.NAME in p.get_section_names():
            name_sect = p.get_section(JSONSchema.NAME)
            if name_sect is not None:
                experiment_name = str(name_sect)
        logger.info('Running chemistry problem from input file: {}'.format(
            p.get_filename()))
        logger.info('Experiment description: {}'.format(
            experiment_name.rstrip()))

        driver_name = p.get_section_property(InputParser.DRIVER,
                                             JSONSchema.NAME)
        if driver_name is None:
            raise QiskitChemistryError(
                'Property "{0}" missing in section "{1}"'.format(
                    JSONSchema.NAME, InputParser.DRIVER))

        hdf5_file = p.get_section_property(InputParser.DRIVER,
                                           QiskitChemistry.KEY_HDF5_OUTPUT)

        if driver_name not in local_drivers():
            raise QiskitChemistryError(
                'Driver "{0}" missing in local drivers'.format(driver_name))

        work_path = None
        input_file = p.get_filename()
        if input_file is not None:
            work_path = os.path.dirname(os.path.realpath(input_file))

        section = p.get_section(driver_name)
        driver = get_driver_class(driver_name).init_from_input(section)
        driver.work_path = work_path
        molecule = driver.run()

        if work_path is not None and hdf5_file is not None and not os.path.isabs(
                hdf5_file):
            hdf5_file = os.path.abspath(os.path.join(work_path, hdf5_file))

        molecule.log()

        if hdf5_file is not None:
            molecule._origin_driver_name = driver_name
            molecule._origin_driver_config = section if isinstance(
                section, str) else json.dumps(
                    section, sort_keys=True, indent=4)
            molecule.save(hdf5_file)
            text = "HDF5 file saved '{}'".format(hdf5_file)
            logger.info(text)
            if not save_json_algo_file:
                logger.info('Run ended with hdf5 file saved.')
                return QiskitChemistry._DRIVER_RUN_TO_HDF5, text

        # Run the Hamiltonian to process the QMolecule and get an input for algorithms
        cls = get_chemistry_operator_class(
            p.get_section_property(InputParser.OPERATOR, JSONSchema.NAME))
        self._core = cls.init_params(
            p.get_section_properties(InputParser.OPERATOR))
        input_object = self._core.run(molecule)

        logger.debug('Core computed substitution variables {}'.format(
            self._core.molecule_info))
        result = p.process_substitutions(self._core.molecule_info)
        logger.debug('Substitutions {}'.format(result))

        params = {}
        for section_name, section in p.get_sections().items():
            if section_name == JSONSchema.NAME or \
               section_name == InputParser.DRIVER or \
               section_name == driver_name.lower() or \
               section_name == InputParser.OPERATOR or \
               not isinstance(section, dict):
                continue

            params[section_name] = copy.deepcopy(section)
            if JSONSchema.PROBLEM == section_name and InputParser.AUTO_SUBSTITUTIONS in params[
                    section_name]:
                del params[section_name][InputParser.AUTO_SUBSTITUTIONS]

        return QiskitChemistry._DRIVER_RUN_TO_ALGO_INPUT, params, input_object