Exemple #1
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
    def __init__(self,
                 backend,
                 shots=1024,
                 seed=None,
                 max_credits=10,
                 basis_gates=None,
                 coupling_map=None,
                 initial_layout=None,
                 pass_manager=None,
                 seed_mapper=None,
                 backend_options=None,
                 noise_model=None,
                 timeout=None,
                 wait=5,
                 circuit_cache=None,
                 skip_qobj_validation=False):
        """Constructor.

        Args:
            backend (BaseBackend): instance of selected backend
            shots (int, optional): number of repetitions of each circuit, for sampling
            seed (int, optional): random seed for simulators
            max_credits (int, optional): maximum credits to use
            basis_gates (list[str], optional): list of basis gate names supported by the
                                                target. Default: ['u1','u2','u3','cx','id']
            coupling_map (list[list]): coupling map (perhaps custom) to target in mapping
            initial_layout (dict, optional): initial layout of qubits in mapping
            pass_manager (PassManager, optional): pass manager to handle how to compile the circuits
            seed_mapper (int, optional): the random seed for circuit mapper
            backend_options (dict, optional): all running options for backend, please refer to the provider.
            noise_model (qiskit.provider.aer.noise.noise_model.NoiseModel, optional): noise model for simulator
            timeout (float, optional): seconds to wait for job. If None, wait indefinitely.
            wait (float, optional): seconds between queries to result
            circuit_cache (CircuitCache, optional): A CircuitCache to use when calling compile_and_run_circuits
            skip_qobj_validation (bool, optional): Bypass Qobj validation to decrease submission time
        """
        self._backend = backend
        # setup run config
        run_config = RunConfig(shots=shots, max_credits=max_credits)
        if seed:
            run_config.seed = seed

        if getattr(run_config, 'shots', None) is not None:
            if self.is_statevector and run_config.shots != 1:
                logger.info(
                    "statevector backend only works with shot=1, change "
                    "shots from {} to 1.".format(run_config.shots))
                run_config.shots = 1

        self._run_config = run_config

        # setup backend config
        basis_gates = basis_gates or backend.configuration().basis_gates
        coupling_map = coupling_map or getattr(backend.configuration(),
                                               'coupling_map', None)
        self._backend_config = {
            'basis_gates': basis_gates,
            'coupling_map': coupling_map
        }

        # setup noise config
        noise_config = None
        if noise_model is not None:
            if is_aer_provider(self._backend):
                if not self.is_statevector:
                    noise_config = noise_model
                else:
                    logger.info(
                        "The noise model can be only used with Aer qasm simulator. "
                        "Change it to None.")
            else:
                logger.info(
                    "The noise model can be only used with Qiskit Aer. "
                    "Please install it.")
        self._noise_config = {} if noise_config is None else {
            'noise_model': noise_config
        }

        # setup compile config
        if initial_layout is not None and not isinstance(
                initial_layout, Layout):
            initial_layout = Layout(initial_layout)
        self._compile_config = {
            'pass_manager': pass_manager,
            'initial_layout': initial_layout,
            'seed_mapper': seed_mapper
        }

        # setup job config
        self._qjob_config = {'timeout': timeout} if self.is_local \
            else {'timeout': timeout, 'wait': wait}

        # setup backend options for run
        self._backend_options = {}
        if is_ibmq_provider(self._backend):
            logger.info(
                "backend_options can not used with the backends in IBMQ provider."
            )
        else:
            self._backend_options = {} if backend_options is None \
                else {'backend_options': backend_options}

        self._shared_circuits = False
        self._circuit_summary = False
        self._circuit_cache = circuit_cache
        self._skip_qobj_validation = skip_qobj_validation

        logger.info(self)
Exemple #3
0
def compile(circuits,
            backend,
            config=None,
            basis_gates=None,
            coupling_map=None,
            initial_layout=None,
            shots=1024,
            max_credits=10,
            seed=None,
            qobj_id=None,
            seed_mapper=None,
            pass_manager=None,
            memory=False):
    """Compile a list of circuits into a qobj.

    Args:
        circuits (QuantumCircuit or list[QuantumCircuit]): circuits to compile
        backend (BaseBackend): a backend to compile for
        config (dict): dictionary of parameters (e.g. noise) used by runner
        basis_gates (str): comma-separated basis gate set to compile to
        coupling_map (list): coupling map (perhaps custom) to target in mapping
        initial_layout (list): initial layout of qubits in mapping
        shots (int): number of repetitions of each circuit, for sampling
        max_credits (int): maximum credits to use
        seed (int): random seed for simulators
        seed_mapper (int): random seed for swapper mapper
        qobj_id (int): identifier for the generated qobj
        pass_manager (PassManager): a pass manger for the transpiler pipeline
        memory (bool): if True, per-shot measurement bitstrings are returned as well

    Returns:
        Qobj: the qobj to be run on the backends

    Raises:
        QiskitError: if the desired options are not supported by backend
    """
    if config:
        warnings.warn(
            'The `config` argument is deprecated and '
            'does not do anything', DeprecationWarning)

    circuits = transpiler.transpile(circuits, backend, basis_gates,
                                    coupling_map, initial_layout, seed_mapper,
                                    pass_manager)

    # step 4: Making a qobj
    run_config = RunConfig()

    if seed:
        run_config.seed = seed
    if shots:
        run_config.shots = shots
    if max_credits:
        run_config.max_credits = max_credits
    if memory:
        run_config.memory = memory
    qobj = circuits_to_qobj(circuits,
                            user_qobj_header=QobjHeader(),
                            run_config=run_config,
                            qobj_id=qobj_id)

    return qobj
Exemple #4
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)