示例#1
0
    def _config_the_best_mode(self, operator, backend):

        if not isinstance(operator, (WeightedPauliOperator, MatrixOperator,
                                     TPBGroupedWeightedPauliOperator)):
            logger.debug("Unrecognized operator type, skip auto conversion.")
            return operator

        ret_op = operator
        if not is_statevector_backend(backend) and not (
                is_aer_provider(backend)
                and self._quantum_instance.run_config.shots == 1):
            if isinstance(operator, (WeightedPauliOperator, MatrixOperator)):
                logger.debug(
                    "When running with Qasm simulator, grouped pauli can "
                    "save number of measurements. "
                    "We convert the operator into grouped ones.")
                ret_op = op_converter.to_tpb_grouped_weighted_pauli_operator(
                    operator, TPBGroupedWeightedPauliOperator.sorted_grouping)
        else:
            if not is_aer_provider(backend):
                if not isinstance(operator, MatrixOperator):
                    logger.info(
                        "When running with non-Aer statevector simulator, "
                        "represent operator as a matrix could "
                        "achieve the better performance. We convert "
                        "the operator to matrix.")
                    ret_op = op_converter.to_matrix_operator(operator)
            else:
                if not isinstance(operator, WeightedPauliOperator):
                    logger.info("When running with Aer simulator, "
                                "represent operator as weighted paulis could "
                                "achieve the better performance. We convert "
                                "the operator to weighted paulis.")
                    ret_op = op_converter.to_weighted_pauli_operator(operator)
        return ret_op
示例#2
0
def run_on_backend(backend: Union[Backend, BaseBackend],
                   qobj: QasmQobj,
                   backend_options: Optional[Dict] = None,
                   noise_config: Optional[Dict] = None,
                   skip_qobj_validation: bool = False) -> BaseJob:
    """ run on backend """
    if skip_qobj_validation:
        if is_aer_provider(backend) or is_basicaer_provider(backend):
            if backend_options is not None:
                for option, value in backend_options.items():
                    if option == 'backend_options':
                        for key, val in value.items():
                            setattr(qobj.config, key, val)
                    else:
                        setattr(qobj.config, option, value)
            if is_aer_provider(backend) and \
                    noise_config is not None and \
                    'noise_model' in noise_config:
                qobj.config.noise_model = noise_config['noise_model']
            job = backend.run(qobj, validate=False)
        else:
            logger.info("Can't skip qobj validation for the %s provider.",
                        backend.provider().__class__.__name__)
            job = backend.run(qobj, **backend_options, **noise_config)
        return job
    else:
        job = backend.run(qobj, **backend_options, **noise_config)
        return job
示例#3
0
def run_on_backend(backend,
                   qobj,
                   backend_options=None,
                   noise_config=None,
                   skip_qobj_validation=False):
    """ run on backend """
    if skip_qobj_validation:
        if is_aer_provider(backend):
            if backend_options is not None:
                for option, value in backend_options.items():
                    if option == 'backend_options':
                        for key, val in value.items():
                            setattr(qobj.config, key, val)
                    else:
                        setattr(qobj.config, option, value)
            if noise_config is not None and 'noise_model' in noise_config:
                qobj.config.noise_model = noise_config['noise_model']
            job = backend.run(qobj, validate=False)
        elif is_basicaer_provider(backend):
            job_id = str(uuid.uuid4())
            backend._set_options(qobj_config=qobj.config, **backend_options)
            job = BasicAerJob(backend, job_id, backend._run_job, qobj)
            job._future = job._executor.submit(job._fn, job._job_id, job._qobj)
        else:
            logger.info("Can't skip qobj validation for the %s provider.",
                        backend.provider().__class__.__name__)
            job = backend.run(qobj, **backend_options, **noise_config)
        return job
    else:
        job = backend.run(qobj, **backend_options, **noise_config)
        return job
def run_on_backend(backend, qobj, backend_options=None,
                   noise_config=None, skip_qobj_validation=False):
    """ run on backend """
    if skip_qobj_validation:
        job_id = str(uuid.uuid4())
        if is_aer_provider(backend):
            from qiskit.providers.aer.aerjob import AerJob
            temp_backend_options = \
                backend_options['backend_options'] if backend_options != {} else None
            temp_noise_config = noise_config['noise_model'] if noise_config != {} else None
            job = AerJob(backend, job_id,
                         backend._run_job, qobj, temp_backend_options, temp_noise_config, False)
            job._future = job._executor.submit(job._fn, job._job_id, job._qobj, *job._args)
        elif is_basicaer_provider(backend):
            backend._set_options(qobj_config=qobj.config, **backend_options)
            job = BasicAerJob(backend, job_id, backend._run_job, qobj)
            job._future = job._executor.submit(job._fn, job._job_id, job._qobj)
        else:
            logger.info(
                "Can't skip qobj validation for the %s provider.",
                backend.provider().__class__.__name__)
            job = backend.run(qobj, **backend_options, **noise_config)
        return job
    else:
        job = backend.run(qobj, **backend_options, **noise_config)
        return job
示例#5
0
def run_on_backend(backend,
                   qobj,
                   backend_options=None,
                   noise_config=None,
                   skip_qobj_validation=False):
    if skip_qobj_validation:
        job_id = str(uuid.uuid4())
        if is_aer_provider(backend):
            from qiskit.providers.aer.aerjob import AerJob
            temp_backend_options = backend_options[
                'backend_options'] if backend_options != {} else None
            temp_noise_config = noise_config[
                'noise_model'] if noise_config != {} else None
            job = AerJob(backend, job_id, backend._run_job, qobj,
                         temp_backend_options, temp_noise_config, False)
            job._future = job._executor.submit(job._fn, job._job_id, job._qobj,
                                               *job._args)
        elif is_basicaer_provider(backend):
            backend._set_options(qobj_config=qobj.config, **backend_options)
            job = BasicAerJob(backend, job_id, backend._run_job, qobj)
            job._future = job._executor.submit(job._fn, job._job_id, job._qobj)
        elif is_ibmq_provider(backend):
            # TODO: IBMQJob performs validation during the constructor. the following lines does not
            # skip validation but run as is.
            from qiskit.providers.ibmq.ibmqjob import IBMQJob
            job = IBMQJob(backend, None, backend._api, qobj=qobj)
            job._future = job._executor.submit(job._submit_callback)
        else:
            logger.info(
                "Can't skip qobj validation for the third-party provider.")
            job = backend.run(qobj, **backend_options, **noise_config)
        return job
    else:
        job = backend.run(qobj, **backend_options, **noise_config)
        return job
示例#6
0
def run_on_backend(backend,
                   qobj,
                   backend_options=None,
                   noise_config=None,
                   skip_qobj_validation=False):
    if skip_qobj_validation:
        job_id = str(uuid.uuid4())
        if is_simulator_backend(backend):
            if is_aer_provider(backend):
                job = backend.run(qobj, **backend_options, **noise_config)
            else:
                job = SimulatorsJob(backend, job_id, backend._run_job, qobj)
                job._future = job._executor.submit(job._fn, job._job_id,
                                                   job._qobj)
        elif is_ibmq_provider(backend):
            job = IBMQJob(backend,
                          None,
                          backend._api,
                          not is_simulator_backend(backend),
                          qobj=qobj)
            job._future = job._executor.submit(job._fn, job._job_id, job._qobj)
        else:
            logger.info(
                "Can not skip qobj validation for the third-party provider.")
            job = backend.run(qobj, **backend_options, **noise_config)
        return job
    else:
        job = backend.run(qobj, **backend_options, **noise_config)
        return job
示例#7
0
    def _run(self):
        """
        Run the algorithm to compute the minimum eigenvalue.

        Returns:
            dict: Dictionary of results

        Raises:
            AquaError: wrong setting of operator and backend.
        """
        if self._auto_conversion:
            self._operator = \
                self._config_the_best_mode(self._operator, self._quantum_instance.backend)
            for i in range(len(self._aux_operators)):
                if not self._aux_operators[i].is_empty():
                    self._aux_operators[i] = \
                        self._config_the_best_mode(self._aux_operators[i],
                                                   self._quantum_instance.backend)

        # sanity check
        if isinstance(
                self._operator,
                MatrixOperator) and not self._quantum_instance.is_statevector:
            raise AquaError("Non-statevector simulator can not work "
                            "with `MatrixOperator`, either turn ON "
                            "auto_conversion or use the proper "
                            "combination between operator and backend.")

        self._use_simulator_snapshot_mode = (
            is_aer_provider(self._quantum_instance.backend)
            and self._quantum_instance.run_config.shots == 1
            and not self._quantum_instance.noise_config and isinstance(
                self._operator,
                (WeightedPauliOperator, TPBGroupedWeightedPauliOperator)))

        self._quantum_instance.circuit_summary = True

        self._eval_count = 0
        self._ret = self.find_minimum(initial_point=self.initial_point,
                                      var_form=self.var_form,
                                      cost_fn=self._energy_evaluation,
                                      optimizer=self.optimizer)
        if self._ret['num_optimizer_evals'] is not None and \
                self._eval_count >= self._ret['num_optimizer_evals']:
            self._eval_count = self._ret['num_optimizer_evals']
        self._eval_time = self._ret['eval_time']
        logger.info(
            'Optimization complete in %s seconds.\nFound opt_params %s in %s evals',
            self._eval_time, self._ret['opt_params'], self._eval_count)
        self._ret['eval_count'] = self._eval_count

        self._ret['energy'] = self.get_optimal_cost()
        self._ret['eigvals'] = np.asarray([self.get_optimal_cost()])
        self._ret['eigvecs'] = np.asarray([self.get_optimal_vector()])
        self._eval_aux_ops()

        self.cleanup_parameterized_circuits()
        return self._ret
示例#8
0
    def quantum_instance(self, quantum_instance: Union[QuantumInstance, BaseBackend]) -> None:
        """ set quantum_instance """
        super(VQE, self.__class__).quantum_instance.__set__(self, quantum_instance)

        self._circuit_sampler = CircuitSampler(
            self._quantum_instance,
            param_qobj=is_aer_provider(self._quantum_instance.backend))

        # Expectation was not passed by user, try to create one
        if not self._user_valid_expectation:
            self._try_set_expectation_value_from_factory()
示例#9
0
    def _run(self) -> 'VQSDResult':
        """
        Run the algorithm to compute the minimum eigenvalue.
        Returns:
            dict: dictionary of results
        Raises:
            AquaError: wrong setting of operator and backend.
        """
        if self.initial_state is None:
            raise AquaError("Initial state was never provided")

        self._initial_state = self.initial_state
        self._use_simulator_snapshot_mode = (
            is_aer_provider(self._quantum_instance.backend)
            and self._quantum_instance.run_config.shots == 1
            and not self._quantum_instance.noise_config)

        self._quantum_instance.circuit_summary = True

        self._eval_count = 0
        vqresult = self.find_minimum(initial_point=self.initial_point,
                                     var_form=self.var_form,
                                     cost_fn=self._cost_evaluation,
                                     optimizer=self.optimizer)

        # TODO remove all former dictionary logic
        self._ret = {}
        self._ret['num_optimizer_evals'] = vqresult.optimizer_evals
        self._ret['min_val'] = vqresult.optimal_value
        self._ret['opt_params'] = vqresult.optimal_point
        self._ret['eval_time'] = vqresult.optimizer_time

        if self._ret['num_optimizer_evals'] is not None and \
                self._eval_count >= self._ret['num_optimizer_evals']:
            self._eval_count = self._ret['num_optimizer_evals']
        self._eval_time = self._ret['eval_time']
        logger.info('Optimization complete in %s seconds.\nFound opt_params %s in %s evals',
                    self._eval_time, self._ret['opt_params'], self._eval_count)
        self._ret['eval_count'] = self._eval_count

        result = VQSDResult()
        result.combine(vqresult)
        result.eigenvalue = self.get_optimal_value()
        result.eigenstate = self.get_optimal_vector()
        result.cost_function_evals = self._eval_count

        self._ret['energy'] = self.get_optimal_cost()
        self._ret['eigvals'] = result.eigenvalue
        self._ret['eigvecs'] = result.eigenstate

        self.cleanup_parameterized_circuits()
        return result
示例#10
0
    def _check_quantum_instance_and_modes_consistent(self) -> None:
        """ Checks whether the statevector and param_qobj settings are compatible with the
        backend

        Raises:
            ValueError: statevector or param_qobj are True when not supported by backend.
        """
        if self._statevector and not is_statevector_backend(self.quantum_instance.backend):
            raise ValueError('Statevector mode for circuit sampling requires statevector '
                             'backend, not {}.'.format(self.quantum_instance.backend))

        if self._param_qobj and not is_aer_provider(self.quantum_instance.backend):
            raise ValueError('Parameterized Qobj mode requires Aer '
                             'backend, not {}.'.format(self.quantum_instance.backend))
示例#11
0
def run_on_backend(backend,
                   qobj,
                   backend_options=None,
                   noise_config=None,
                   skip_qobj_validation=False):
    """ run on backend """
    if skip_qobj_validation:
        job_id = str(uuid.uuid4())
        if is_aer_provider(backend):
            # pylint: disable=import-outside-toplevel
            try:
                from qiskit.providers.aer.aerjob import AerJob
            except ImportError as ex:
                raise MissingOptionalLibraryError(
                    libname='qiskit-aer',
                    name='run_on_backend',
                    pip_install='pip install qiskit-aer') from ex
            temp_backend_options = \
                backend_options['backend_options'] if backend_options != {} else None
            temp_noise_config = noise_config[
                'noise_model'] if noise_config != {} else None

            # Add new options
            if temp_backend_options is not None or temp_noise_config is not None:
                config = qobj.config.to_dict()
                if temp_backend_options is not None:
                    for key, val in temp_backend_options.items():
                        config[key] = val if not hasattr(
                            val, 'to_dict') else val.to_dict()
                if temp_noise_config is not None:
                    config['noise_model'] = temp_noise_config
                qobj.config = QasmQobjConfig.from_dict(config)

            job = AerJob(backend, job_id, backend._run, qobj)
            job.submit()
        elif is_basicaer_provider(backend):
            backend._set_options(qobj_config=qobj.config, **backend_options)
            job = BasicAerJob(backend, job_id, backend._run_job, qobj)
            job._future = job._executor.submit(job._fn, job._job_id, job._qobj)
        else:
            logger.info("Can't skip qobj validation for the %s provider.",
                        backend.provider().__class__.__name__)
            job = backend.run(qobj, **backend_options, **noise_config)
        return job
    else:
        job = backend.run(qobj, **backend_options, **noise_config)
        return job
示例#12
0
def compile_circuits(circuits,
                     backend,
                     backend_config=None,
                     compile_config=None,
                     run_config=None,
                     show_circuit_summary=False,
                     circuit_cache=None,
                     **kwargs):
    """
    An execution wrapper with Qiskit-Terra, with job auto recover capability.

    The autorecovery feature is only applied for non-simulator backend.
    This wraper will try to get the result no matter how long it costs.

    Args:
        circuits (QuantumCircuit or list[QuantumCircuit]): circuits to execute
        backend (BaseBackend): backend instance
        backend_config (dict, optional): configuration for backend
        compile_config (dict, optional): configuration for compilation
        run_config (RunConfig, optional): configuration for running a circuit
        show_circuit_summary (bool, optional): showing the summary of submitted circuits.
        circuit_cache (CircuitCache, optional): A CircuitCache to use when calling compile_and_run_circuits

    Returns:
        QasmObj: compiled qobj.

    Raises:
        AquaError: Any error except for JobError raised by Qiskit Terra
    """
    backend_config = backend_config or {}
    compile_config = compile_config or {}
    run_config = run_config or {}

    if backend is None or not isinstance(backend, BaseBackend):
        raise ValueError(
            'Backend is missing or not an instance of BaseBackend')

    if not isinstance(circuits, list):
        circuits = [circuits]

    if is_simulator_backend(backend):
        circuits = _avoid_empty_circuits(circuits)

    if MAX_CIRCUITS_PER_JOB is not None:
        max_circuits_per_job = int(MAX_CIRCUITS_PER_JOB)
    else:
        if is_local_backend(backend):
            max_circuits_per_job = sys.maxsize
        else:
            max_circuits_per_job = backend.configuration().max_experiments

    if circuit_cache is not None and circuit_cache.try_reusing_qobjs:
        # Check if all circuits are the same length.
        # If not, don't try to use the same qobj.experiment for all of them.
        if len(set([len(circ.data) for circ in circuits])) > 1:
            circuit_cache.try_reusing_qobjs = False
        else:  # Try setting up the reusable qobj
            # Compile and cache first circuit if cache is empty. The load method will try to reuse it
            if circuit_cache.qobjs is None:
                qobj, transpiled_circuits = _compile_wrapper([circuits[0]],
                                                             backend,
                                                             backend_config,
                                                             compile_config,
                                                             run_config)

                if is_aer_provider(backend):
                    qobj = _maybe_add_aer_expectation_instruction(qobj, kwargs)
                circuit_cache.cache_circuit(qobj, [circuits[0]], 0)

    qobjs = []
    transpiled_circuits = []
    chunks = int(np.ceil(len(circuits) / max_circuits_per_job))
    for i in range(chunks):
        sub_circuits = circuits[i * max_circuits_per_job:(i + 1) *
                                max_circuits_per_job]
        if circuit_cache is not None and circuit_cache.misses < circuit_cache.allowed_misses:
            try:
                if circuit_cache.cache_transpiled_circuits:
                    transpiled_sub_circuits = compiler.transpile(
                        sub_circuits, backend, **backend_config,
                        **compile_config)
                    qobj = circuit_cache.load_qobj_from_cache(
                        transpiled_sub_circuits, i, run_config=run_config)
                else:
                    qobj = circuit_cache.load_qobj_from_cache(
                        sub_circuits, i, run_config=run_config)
                if is_aer_provider(backend):
                    qobj = _maybe_add_aer_expectation_instruction(qobj, kwargs)
            # cache miss, fail gracefully
            except (TypeError, IndexError, FileNotFoundError, EOFError,
                    AquaError, AttributeError) as e:
                circuit_cache.try_reusing_qobjs = False  # Reusing Qobj didn't work
                if len(circuit_cache.qobjs) > 0:
                    logger.info(
                        'Circuit cache miss, recompiling. Cache miss reason: '
                        + repr(e))
                    circuit_cache.misses += 1
                else:
                    logger.info(
                        'Circuit cache is empty, compiling from scratch.')
                circuit_cache.clear_cache()
                qobj, transpiled_sub_circuits = _compile_wrapper(
                    sub_circuits, backend, backend_config, compile_config,
                    run_config)
                transpiled_circuits.extend(transpiled_sub_circuits)
                if is_aer_provider(backend):
                    qobj = _maybe_add_aer_expectation_instruction(qobj, kwargs)
                try:
                    circuit_cache.cache_circuit(qobj, sub_circuits, i)
                except (TypeError, IndexError, AquaError, AttributeError,
                        KeyError) as e:
                    try:
                        circuit_cache.cache_transpiled_circuits = True
                        circuit_cache.cache_circuit(qobj,
                                                    transpiled_sub_circuits, i)
                    except (TypeError, IndexError, AquaError, AttributeError,
                            KeyError) as e:
                        logger.info(
                            'Circuit could not be cached for reason: ' +
                            repr(e))
                        logger.info(
                            'Transpilation may be too aggressive. Try skipping transpiler.'
                        )

        else:
            qobj, transpiled_sub_circuits = _compile_wrapper(
                sub_circuits, backend, backend_config, compile_config,
                run_config)
            transpiled_circuits.extend(transpiled_sub_circuits)
            if is_aer_provider(backend):
                qobj = _maybe_add_aer_expectation_instruction(qobj, kwargs)

        qobjs.append(qobj)

    if logger.isEnabledFor(logging.DEBUG) and show_circuit_summary:
        logger.debug("==== Before transpiler ====")
        logger.debug(summarize_circuits(circuits))
        logger.debug("====  After transpiler ====")
        logger.debug(summarize_circuits(transpiled_circuits))

    return qobjs
示例#13
0
    def update_backend_schema(self, input_parser):
        """
        Updates backend schema
        """
        if JSONSchema.BACKEND not in self._schema['properties']:
            return

        # Updates defaults provider/backend
        default_provider_name = None
        default_backend_name = None
        orig_backend_properties = self._original_schema.get(
            'properties', {}).get(JSONSchema.BACKEND, {}).get('properties')
        if orig_backend_properties is not None:
            default_provider_name = orig_backend_properties.get(
                JSONSchema.PROVIDER, {}).get('default')
            default_backend_name = orig_backend_properties.get(
                JSONSchema.NAME, {}).get('default')

        providers = get_local_providers()
        if default_provider_name is None or default_provider_name not in providers:
            # use first provider available
            providers_items = providers.items()
            provider_tuple = next(
                iter(providers_items)) if len(providers_items) > 0 else ('',
                                                                         [])
            default_provider_name = provider_tuple[0]

        if default_backend_name is None or default_backend_name not in providers.get(
                default_provider_name, []):
            # use first backend available in provider
            default_backend_name = providers.get(
                default_provider_name)[0] if len(
                    providers.get(default_provider_name, [])) > 0 else ''

        self._schema['properties'][JSONSchema.BACKEND] = {
            'type': 'object',
            'properties': {
                JSONSchema.PROVIDER: {
                    'type': 'string',
                    'default': default_provider_name
                },
                JSONSchema.NAME: {
                    'type': 'string',
                    'default': default_backend_name
                },
            },
            'required': [JSONSchema.PROVIDER, JSONSchema.NAME],
            'additionalProperties': False,
        }
        provider_name = input_parser.get_section_property(
            JSONSchema.BACKEND, JSONSchema.PROVIDER, default_provider_name)
        backend_names = get_backends_from_provider(provider_name)
        backend_name = input_parser.get_section_property(
            JSONSchema.BACKEND, JSONSchema.NAME, default_backend_name)
        if backend_name not in backend_names:
            # use first backend available in provider
            backend_name = backend_names[0] if len(backend_names) > 0 else ''

        backend = get_backend_from_provider(provider_name, backend_name)
        config = backend.configuration()

        # Include shots in schema only if not a statevector backend.
        # For statevector, shots will be set to 1, in QiskitAqua
        if not is_statevector_backend(backend):
            self._schema['properties'][
                JSONSchema.BACKEND]['properties']['shots'] = {
                    'type': 'integer',
                    'minimum': 1,
                }
            default_shots = 1024
            # ensure default_shots <= max_shots
            if config.max_shots:
                default_shots = min(default_shots, config.max_shots)
                self._schema['properties'][JSONSchema.BACKEND]['properties'][
                    'shots']['maximum'] = config.max_shots

            self._schema['properties'][JSONSchema.BACKEND]['properties'][
                'shots']['default'] = default_shots

        self._schema['properties'][
            JSONSchema.BACKEND]['properties']['skip_transpiler'] = {
                'type': 'boolean',
                'default': False,
            }

        coupling_map_devices = []
        noise_model_devices = []
        check_coupling_map = is_simulator_backend(backend)
        check_noise_model = is_aer_provider(
            backend) and not is_aer_statevector_backend(backend)
        try:
            if (check_coupling_map or check_noise_model) and has_ibmq():
                backend_names = get_backends_from_provider('qiskit.IBMQ')
                for backend_name in backend_names:
                    ibmq_backend = get_backend_from_provider(
                        'qiskit.IBMQ', backend_name)
                    if is_simulator_backend(ibmq_backend):
                        continue
                    if check_noise_model:
                        noise_model_devices.append('qiskit.IBMQ:' +
                                                   backend_name)
                    if check_coupling_map and ibmq_backend.configuration(
                    ).coupling_map:
                        coupling_map_devices.append('qiskit.IBMQ:' +
                                                    backend_name)
        except Exception as e:
            logger.debug("Failed to load IBMQ backends. Error {}".format(
                str(e)))

        # Includes 'coupling map' and 'coupling_map_from_device' in schema only if a simulator backend.
        # Actual devices have a coupling map based on the physical configuration of the device.
        # The user can configure the coupling map so its the same as the coupling map
        # of a given device in order to better simulate running on the device.
        # Property 'coupling_map_from_device' is a list of provider:name backends that are
        # real devices e.g qiskit.IBMQ:ibmqx5.
        # If property 'coupling_map', an array, is provided, it overrides coupling_map_from_device,
        # the latter defaults to 'None'. So in total no coupling map is a default, i.e. all to all coupling is possible.
        if is_simulator_backend(backend):
            self._schema['properties'][
                JSONSchema.BACKEND]['properties']['coupling_map'] = {
                    'type': ['array', 'null'],
                    'default': None,
                }
            if len(coupling_map_devices) > 0:
                coupling_map_devices.append(None)
                self._schema['properties'][JSONSchema.BACKEND]['properties'][
                    'coupling_map_from_device'] = {
                        'type': ['string', 'null'],
                        'default': None,
                        'oneOf': [{
                            'enum': coupling_map_devices
                        }],
                    }

        # noise model that can be setup for Aer simulator so as to model noise of an actual device.
        if len(noise_model_devices) > 0:
            noise_model_devices.append(None)
            self._schema['properties'][
                JSONSchema.BACKEND]['properties']['noise_model'] = {
                    'type': ['string', 'null'],
                    'default': None,
                    'oneOf': [{
                        'enum': noise_model_devices
                    }],
                }

        # If a noise model is supplied then the basis gates is set as per the noise model
        # unless basis gates is not None in which case it overrides noise model and a warning msg is logged.
        # as it is an advanced use case.
        self._schema['properties'][
            JSONSchema.BACKEND]['properties']['basis_gates'] = {
                'type': ['array', 'null'],
                'default': None,
            }

        # TODO: Not sure if we want to continue with initial_layout in declarative form.
        # It requires knowledge of circuit registers etc. Perhaps its best to leave this detail to programming API.
        self._schema['properties'][
            JSONSchema.BACKEND]['properties']['initial_layout'] = {
                'type': ['object', 'null'],
                'default': None,
            }

        # The same default and minimum as current RunConfig values
        self._schema['properties'][
            JSONSchema.BACKEND]['properties']['max_credits'] = {
                'type': 'integer',
                'default': 10,
                'minimum': 3,
                'maximum': 10,
            }

        # Timeout and wait are for remote backends where we have to connect over network
        if not is_local_backend(backend):
            self._schema['properties'][
                JSONSchema.BACKEND]['properties']['timeout'] = {
                    "type": ["number", "null"],
                    'default': None,
                }
            self._schema['properties'][
                JSONSchema.BACKEND]['properties']['wait'] = {
                    'type': 'number',
                    'default': 5.0,
                    'minimum': 0.0,
                }
示例#14
0
def compile_and_run_circuits(circuits,
                             backend,
                             backend_config=None,
                             compile_config=None,
                             run_config=None,
                             qjob_config=None,
                             backend_options=None,
                             noise_config=None,
                             show_circuit_summary=False,
                             has_shared_circuits=False,
                             circuit_cache=None,
                             skip_qobj_validation=False,
                             **kwargs):
    """
    An execution wrapper with Qiskit-Terra, with job auto recover capability.

    The autorecovery feature is only applied for non-simulator backend.
    This wraper will try to get the result no matter how long it costs.

    Args:
        circuits (QuantumCircuit or list[QuantumCircuit]): circuits to execute
        backend (BaseBackend): backend instance
        backend_config (dict, optional): configuration for backend
        compile_config (dict, optional): configuration for compilation
        run_config (RunConfig, optional): configuration for running a circuit
        qjob_config (dict, optional): configuration for quantum job object
        backend_options (dict, optional): configuration for simulator
        noise_config (dict, optional): configuration for noise model
        show_circuit_summary (bool, optional): showing the summary of submitted circuits.
        has_shared_circuits (bool, optional): use the 0-th circuits as initial state for other circuits.
        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

    Returns:
        Result: Result object

    Raises:
        AquaError: Any error except for JobError raised by Qiskit Terra
    """
    backend_config = backend_config or {}
    compile_config = compile_config or {}
    run_config = run_config or {}
    qjob_config = qjob_config or {}
    backend_options = backend_options or {}
    noise_config = noise_config or {}

    if backend is None or not isinstance(backend, BaseBackend):
        raise ValueError(
            'Backend is missing or not an instance of BaseBackend')

    if not isinstance(circuits, list):
        circuits = [circuits]

    if is_simulator_backend(backend):
        circuits = _avoid_empty_circuits(circuits)

    if has_shared_circuits:
        return _reuse_shared_circuits(circuits, backend, backend_config,
                                      compile_config, run_config, qjob_config,
                                      backend_options)

    with_autorecover = False if is_simulator_backend(backend) else True

    if MAX_CIRCUITS_PER_JOB is not None:
        max_circuits_per_job = int(MAX_CIRCUITS_PER_JOB)
    else:
        if is_local_backend(backend):
            max_circuits_per_job = sys.maxsize
        else:
            max_circuits_per_job = backend.configuration().max_experiments

    if circuit_cache is not None and circuit_cache.try_reusing_qobjs:
        # Check if all circuits are the same length.
        # If not, don't try to use the same qobj.experiment for all of them.
        if len(set([len(circ.data) for circ in circuits])) > 1:
            circuit_cache.try_reusing_qobjs = False
        else:  # Try setting up the reusable qobj
            # Compile and cache first circuit if cache is empty. The load method will try to reuse it
            if circuit_cache.qobjs is None:
                qobj, _ = _compile_wrapper([circuits[0]], backend,
                                           backend_config, compile_config,
                                           run_config)
                if is_aer_provider(backend):
                    qobj = _maybe_add_aer_expectation_instruction(qobj, kwargs)
                circuit_cache.cache_circuit(qobj, [circuits[0]], 0)

    qobjs = []
    jobs = []
    job_ids = []
    transpiled_circuits = []
    chunks = int(np.ceil(len(circuits) / max_circuits_per_job))
    for i in range(chunks):
        sub_circuits = circuits[i * max_circuits_per_job:(i + 1) *
                                max_circuits_per_job]
        if circuit_cache is not None and circuit_cache.misses < circuit_cache.allowed_misses:
            try:
                if circuit_cache.cache_transpiled_circuits:
                    transpiled_sub_circuits = compiler.transpile(
                        sub_circuits, backend, **backend_config,
                        **compile_config)
                    qobj = circuit_cache.load_qobj_from_cache(
                        transpiled_sub_circuits, i, run_config=run_config)
                else:
                    qobj = circuit_cache.load_qobj_from_cache(
                        sub_circuits, i, run_config=run_config)
                if is_aer_provider(backend):
                    qobj = _maybe_add_aer_expectation_instruction(qobj, kwargs)
            # cache miss, fail gracefully
            except (TypeError, IndexError, FileNotFoundError, EOFError,
                    AquaError, AttributeError) as e:
                circuit_cache.try_reusing_qobjs = False  # Reusing Qobj didn't work
                if len(circuit_cache.qobjs) > 0:
                    logger.info(
                        'Circuit cache miss, recompiling. Cache miss reason: '
                        + repr(e))
                    circuit_cache.misses += 1
                else:
                    logger.info(
                        'Circuit cache is empty, compiling from scratch.')
                circuit_cache.clear_cache()
                qobj, transpiled_sub_circuits = _compile_wrapper(
                    sub_circuits, backend, backend_config, compile_config,
                    run_config)
                transpiled_circuits.extend(transpiled_sub_circuits)
                if is_aer_provider(backend):
                    qobj = _maybe_add_aer_expectation_instruction(qobj, kwargs)
                try:
                    circuit_cache.cache_circuit(qobj, sub_circuits, i)
                except (TypeError, IndexError, AquaError, AttributeError,
                        KeyError) as e:
                    try:
                        circuit_cache.cache_transpiled_circuits = True
                        circuit_cache.cache_circuit(qobj,
                                                    transpiled_sub_circuits, i)
                    except (TypeError, IndexError, AquaError, AttributeError,
                            KeyError) as e:
                        logger.info(
                            'Circuit could not be cached for reason: ' +
                            repr(e))
                        logger.info(
                            'Transpilation may be too aggressive. Try skipping transpiler.'
                        )

        else:
            qobj, transpiled_sub_circuits = _compile_wrapper(
                sub_circuits, backend, backend_config, compile_config,
                run_config)
            transpiled_circuits.extend(transpiled_sub_circuits)
            if is_aer_provider(backend):
                qobj = _maybe_add_aer_expectation_instruction(qobj, kwargs)

        # assure get job ids
        while True:
            job = run_on_backend(backend,
                                 qobj,
                                 backend_options=backend_options,
                                 noise_config=noise_config,
                                 skip_qobj_validation=skip_qobj_validation)
            try:
                job_id = job.job_id()
                break
            except JobError as e:
                logger.warning(
                    "FAILURE: the {}-th chunk of circuits, can not get job id, "
                    "Resubmit the qobj to get job id. "
                    "Terra job error: {} ".format(i, e))
            except Exception as e:
                logger.warning(
                    "FAILURE: the {}-th chunk of circuits, can not get job id, "
                    "Resubmit the qobj to get job id. "
                    "Error: {} ".format(i, e))
        job_ids.append(job_id)
        jobs.append(job)
        qobjs.append(qobj)

    if logger.isEnabledFor(logging.DEBUG) and show_circuit_summary:
        logger.debug("==== Before transpiler ====")
        logger.debug(summarize_circuits(circuits))
        logger.debug("====  After transpiler ====")
        logger.debug(summarize_circuits(transpiled_circuits))

    results = []
    if with_autorecover:
        logger.info("Backend status: {}".format(backend.status()))
        logger.info(
            "There are {} circuits and they are chunked into {} chunks, "
            "each with {} circutis (max.).".format(len(circuits), chunks,
                                                   max_circuits_per_job))
        logger.info("All job ids:\n{}".format(job_ids))
        for idx in range(len(jobs)):
            while True:
                job = jobs[idx]
                job_id = job_ids[idx]
                logger.info("Running {}-th chunk circuits, job id: {}".format(
                    idx, job_id))
                # try to get result if possible
                try:
                    result = job.result(**qjob_config)
                    if result.success:
                        results.append(result)
                        logger.info("COMPLETED the {}-th chunk of circuits, "
                                    "job id: {}".format(idx, job_id))
                        break
                    else:
                        logger.warning("FAILURE: the {}-th chunk of circuits, "
                                       "job id: {}".format(idx, job_id))
                except JobError as e:
                    # if terra raise any error, which means something wrong, re-run it
                    logger.warning(
                        "FAILURE: the {}-th chunk of circuits, job id: {} "
                        "Terra job error: {} ".format(idx, job_id, e))
                except Exception as e:
                    raise AquaError(
                        "FAILURE: the {}-th chunk of circuits, job id: {} "
                        "Unknown error: {} ".format(idx, job_id, e)) from e

                # something wrong here, querying the status to check how to handle it.
                # keep qeurying it until getting the status.
                while True:
                    try:
                        job_status = job.status()
                        break
                    except JobError as e:
                        logger.warning("FAILURE: job id: {}, "
                                       "status: 'FAIL_TO_GET_STATUS' "
                                       "Terra job error: {}".format(job_id, e))
                        time.sleep(5)
                    except Exception as e:
                        raise AquaError("FAILURE: job id: {}, "
                                        "status: 'FAIL_TO_GET_STATUS' "
                                        "Unknown error: ({})".format(
                                            job_id, e)) from e

                logger.info("Job status: {}".format(job_status))

                # handle the failure job based on job status
                if job_status == JobStatus.DONE:
                    logger.info(
                        "Job ({}) is completed anyway, retrieve result "
                        "from backend.".format(job_id))
                    job = backend.retrieve_job(job_id)
                elif job_status == JobStatus.RUNNING or job_status == JobStatus.QUEUED:
                    logger.info("Job ({}) is {}, but encounter an exception, "
                                "recover it from backend.".format(
                                    job_id, job_status))
                    job = backend.retrieve_job(job_id)
                else:
                    logger.info(
                        "Fail to run Job ({}), resubmit it.".format(job_id))
                    qobj = qobjs[idx]
                    #  assure job get its id
                    while True:
                        job = run_on_backend(
                            backend,
                            qobj,
                            backend_options=backend_options,
                            noise_config=noise_config,
                            skip_qobj_validation=skip_qobj_validation)
                        try:
                            job_id = job.job_id()
                            break
                        except JobError as e:
                            logger.warning(
                                "FAILURE: the {}-th chunk of circuits, "
                                "can not get job id. Resubmit the qobj to get job id. "
                                "Terra job error: {} ".format(idx, e))
                        except Exception as e:
                            logger.warning(
                                "FAILURE: the {}-th chunk of circuits, "
                                "can not get job id, Resubmit the qobj to get job id. "
                                "Unknown error: {} ".format(idx, e))
                    jobs[idx] = job
                    job_ids[idx] = job_id
    else:
        results = []
        for job in jobs:
            results.append(job.result(**qjob_config))

    result = _combine_result_objects(results) if len(results) != 0 else None

    return result
示例#15
0
    def _run(self) -> 'VQEResult':
        """Run the algorithm to compute the minimum eigenvalue.

        Returns:
            The result of the VQE algorithm as ``VQEResult``.

        Raises:
            AquaError: Wrong setting of operator and backend.
        """
        if self.operator is None:
            raise AquaError("The operator was never provided.")

        self._operator = self.operator
        self._aux_operators = self.aux_operators
        if self._auto_conversion:
            self._operator = \
                self._config_the_best_mode(self._operator, self._quantum_instance.backend)
            for i in range(len(self._aux_operators)):
                if self._aux_operators[i] is None:
                    continue
                if not self._aux_operators[i].is_empty():
                    self._aux_operators[i] = \
                        self._config_the_best_mode(self._aux_operators[i],
                                                   self._quantum_instance.backend)

        # sanity check
        if isinstance(
                self._operator,
                MatrixOperator) and not self._quantum_instance.is_statevector:
            raise AquaError("Non-statevector simulator can not work "
                            "with `MatrixOperator`, either turn ON "
                            "auto_conversion or use the proper "
                            "combination between operator and backend.")

        self._use_simulator_snapshot_mode = (
            is_aer_provider(self._quantum_instance.backend)
            and self._quantum_instance.run_config.shots == 1
            and not self._quantum_instance.noise_config and isinstance(
                self._operator,
                (WeightedPauliOperator, TPBGroupedWeightedPauliOperator)))

        self._quantum_instance.circuit_summary = True

        self._eval_count = 0
        vqresult = self.find_minimum(initial_point=self.initial_point,
                                     var_form=self.var_form,
                                     cost_fn=self._energy_evaluation,
                                     optimizer=self.optimizer)

        # TODO remove all former dictionary logic
        self._ret = {}
        self._ret['num_optimizer_evals'] = vqresult.optimizer_evals
        self._ret['min_val'] = vqresult.optimal_value
        self._ret['opt_params'] = vqresult.optimal_point
        self._ret['eval_time'] = vqresult.optimizer_time

        if self._ret['num_optimizer_evals'] is not None and \
                self._eval_count >= self._ret['num_optimizer_evals']:
            self._eval_count = self._ret['num_optimizer_evals']
        self._eval_time = self._ret['eval_time']
        logger.info(
            'Optimization complete in %s seconds.\nFound opt_params %s in %s evals',
            self._eval_time, self._ret['opt_params'], self._eval_count)
        self._ret['eval_count'] = self._eval_count

        self._ret['energy'] = self.get_optimal_cost()
        self._ret['eigvals'] = np.asarray([self._ret['energy']])
        self._ret['eigvecs'] = np.asarray([self.get_optimal_vector()])
        self._eval_aux_ops()

        result = VQEResult()
        result.combine(vqresult)
        result.eigenvalue = vqresult.optimal_value + 0j
        result.eigenstate = self.get_optimal_vector()
        if 'aux_ops' in self._ret:
            result.aux_operator_eigenvalues = self._ret['aux_ops'][0]
        result.cost_function_evals = self._eval_count

        self.cleanup_parameterized_circuits()
        return result
def compile_circuits(circuits, backend, backend_config=None, compile_config=None, run_config=None,
                     show_circuit_summary=False, circuit_cache=None, **kwargs):
    """
    An execution wrapper with Qiskit-Terra, with job auto recover capability.

    The autorecovery feature is only applied for non-simulator backend.
    This wrapper will try to get the result no matter how long it costs.

    Args:
        circuits (QuantumCircuit or list[QuantumCircuit]): circuits to execute
        backend (BaseBackend): backend instance
        backend_config (dict, optional): configuration for backend
        compile_config (dict, optional): configuration for compilation
        run_config (RunConfig, optional): configuration for running a circuit
        show_circuit_summary (bool, optional): showing the summary of submitted circuits.
        circuit_cache (CircuitCache, optional): A CircuitCache to use
                    when calling compile_and_run_circuits
        kwargs (optional): special aer instructions to evaluation the expectation of a hamiltonian

    Returns:
        QasmObj: compiled qobj.

    Raises:
        ValueError: backend type is wrong or not given
        ValueError: no circuit in the circuits

    """
    backend_config = backend_config or {}
    compile_config = compile_config or {}
    run_config = run_config or {}

    if backend is None or not isinstance(backend, BaseBackend):
        raise ValueError('Backend is missing or not an instance of BaseBackend')

    if not isinstance(circuits, list):
        circuits = [circuits]

    if not circuits:
        raise ValueError("The input circuit is empty.")

    if is_simulator_backend(backend):
        circuits = _avoid_empty_circuits(circuits)

    if circuit_cache is not None and circuit_cache.try_reusing_qobjs:
        # Check if all circuits are the same length.
        # If not, don't try to use the same qobj.experiment for all of them.
        if len({len(circ.data) for circ in circuits}) > 1:
            circuit_cache.try_reusing_qobjs = False
        else:  # Try setting up the reusable qobj
            # Compile and cache first circuit if cache is empty.
            # The load method will try to reuse it
            if circuit_cache.qobjs is None:
                qobj, _ = _compile_wrapper([circuits[0]], backend, backend_config,
                                           compile_config, run_config)

                if is_aer_provider(backend):
                    qobj = _maybe_add_aer_expectation_instruction(qobj, kwargs)
                circuit_cache.cache_circuit(qobj, [circuits[0]], 0)

    transpiled_circuits = None
    if circuit_cache is not None and circuit_cache.misses < circuit_cache.allowed_misses:
        try:
            if circuit_cache.cache_transpiled_circuits:
                transpiled_circuits = compiler.transpile(circuits, backend, **backend_config,
                                                         **compile_config)
                qobj = circuit_cache.load_qobj_from_cache(transpiled_circuits,
                                                          0, run_config=run_config)
            else:
                qobj = circuit_cache.load_qobj_from_cache(circuits, 0, run_config=run_config)

            if is_aer_provider(backend):
                qobj = _maybe_add_aer_expectation_instruction(qobj, kwargs)
        # cache miss, fail gracefully
        except (TypeError, IndexError, FileNotFoundError, EOFError, AquaError, AttributeError) as e:
            circuit_cache.try_reusing_qobjs = False  # Reusing Qobj didn't work
            if circuit_cache.qobjs:
                logger.info('Circuit cache miss, recompiling. Cache miss reason: %s', repr(e))
                circuit_cache.misses += 1
            else:
                logger.info('Circuit cache is empty, compiling from scratch.')
            circuit_cache.clear_cache()

            qobj, transpiled_circuits = _compile_wrapper(circuits, backend, backend_config,
                                                         compile_config, run_config)
            if is_aer_provider(backend):
                qobj = _maybe_add_aer_expectation_instruction(qobj, kwargs)
            try:
                circuit_cache.cache_circuit(qobj, circuits, 0)
            except (TypeError, IndexError, AquaError, AttributeError, KeyError):
                try:
                    circuit_cache.cache_transpiled_circuits = True
                    circuit_cache.cache_circuit(qobj, transpiled_circuits, 0)
                except (TypeError, IndexError, AquaError, AttributeError, KeyError) as e:
                    logger.info('Circuit could not be cached for reason: %s', repr(e))
                    logger.info('Transpilation may be too aggressive. Try skipping transpiler.')

    else:
        qobj, transpiled_circuits = _compile_wrapper(circuits, backend,
                                                     backend_config, compile_config,
                                                     run_config)
        if is_aer_provider(backend):
            qobj = _maybe_add_aer_expectation_instruction(qobj, kwargs)

    if logger.isEnabledFor(logging.DEBUG) and show_circuit_summary:
        logger.debug("==== Before transpiler ====")
        logger.debug(summarize_circuits(circuits))
        if transpiled_circuits is not None:
            logger.debug("====  After transpiler ====")
            logger.debug(summarize_circuits(transpiled_circuits))

    return qobj
示例#17
0
    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)
    def __init__(self, backend, run_config=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
            run_config (RunConfig): the run config see https://github.com/Qiskit/qiskit-terra/blob/master/qiskit/qobj/run_config.py
            initial_layout (dict): initial layout of qubits in mapping
            pass_manager (PassManager): pass manager to handle how to compile the circuits
            seed_mapper (int): the random seed for circuit mapper
            backend_options (dict): all config setting for backend
            noise_model (qiskit.provider.aer.noise.noise_model.NoiseModel): noise model for simulator
            timeout (float or None): seconds to wait for job. If None, wait indefinitely.
            wait (float): seconds between queries to result
            circuit_cache (CircuitCache): A CircuitCache to use when calling compile_and_run_circuits
            skip_qobj_validation (bool): Bypass Qobj validation to decrease submission time
        """
        self._backend = backend
        # setup run config
        if run_config is None:
            run_config = RunConfig(shots=1024, max_credits=10, memory=False)

        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

        if getattr(run_config, 'memory', None) is not None:
            if not self.is_simulator and run_config.memory is True:
                logger.info("The memory flag only supports simulator rather than real device. "
                            "Change it to from {} to False.".format(run_config.memory))
                run_config.memory = False
        self._run_config = run_config

        # setup backend config
        coupling_map = getattr(backend.configuration(), 'coupling_map', None)
        # TODO: basis gates will be [str] rather than comma-separated str
        basis_gates = backend.configuration().basis_gates
        if isinstance(basis_gates, list):
            basis_gates = ','.join(basis_gates)

        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
        self._compile_config = {
            'pass_manager': pass_manager,
            'initial_layout': initial_layout,
            'seed_mapper': seed_mapper,
            'qobj_id': None
        }

        # 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 isinstance(self._backend.provider(), IBMQProvider):
            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)