def set_config(self, **kwargs): """Set configurations for the quantum instance.""" for k, v in kwargs.items(): if k in QuantumInstance._RUN_CONFIG: setattr(self._run_config, k, v) elif k in QuantumInstance._QJOB_CONFIG: self._qjob_config[k] = v elif k in QuantumInstance._COMPILE_CONFIG: self._compile_config[k] = v elif k in QuantumInstance._BACKEND_CONFIG: self._backend_config[k] = v elif k in QuantumInstance._BACKEND_OPTIONS: if not support_backend_options(self._backend): raise QiskitError( "backend_options can not be used with this backend " "{} ({}).".format(self.backend_name, _get_backend_provider( self._backend))) if k in QuantumInstance._BACKEND_OPTIONS_QASM_ONLY and self.is_statevector: raise QiskitError( "'{}' is only applicable for qasm simulator but " "statevector simulator is used as the backend.") if "backend_options" not in self._backend_options: self._backend_options["backend_options"] = {} self._backend_options["backend_options"][k] = v elif k in QuantumInstance._NOISE_CONFIG: if not is_simulator_backend( self._backend) or is_basicaer_provider(self._backend): raise QiskitError( "The noise model is not supported on the selected backend {} ({}) " "only certain backends, such as Aer qasm support " "noise.".format(self.backend_name, _get_backend_provider(self._backend))) self._noise_config[k] = v else: raise ValueError(f"unknown setting for the key ({k}).")
def is_simulator(self): """Return True if backend is a simulator.""" return is_simulator_backend(self._backend)
def __init__( self, backend, # run config shots: Optional[int] = None, seed_simulator: Optional[int] = None, max_credits: int = 10, # backend properties basis_gates: Optional[List[str]] = None, coupling_map=None, # transpile initial_layout=None, pass_manager=None, bound_pass_manager=None, seed_transpiler: Optional[int] = None, optimization_level: Optional[int] = None, # simulation backend_options: Optional[Dict] = None, noise_model=None, # job timeout: Optional[float] = None, wait: float = 5.0, # others skip_qobj_validation: bool = True, measurement_error_mitigation_cls: Optional[Callable] = None, cals_matrix_refresh_period: int = 30, measurement_error_mitigation_shots: Optional[int] = None, job_callback: Optional[Callable] = None, mit_pattern: Optional[List[List[int]]] = None, max_job_retries: int = 50, ) -> None: """ Quantum Instance holds a Qiskit Terra backend as well as configuration for circuit transpilation and execution. When provided to an Aqua algorithm the algorithm will execute the circuits it needs to run using the instance. Args: backend (Union['Backend', 'BaseBackend']): Instance of selected backend shots: Number of repetitions of each circuit, for sampling. If None, the shots are extracted from the backend. If the backend has none set, the default is 1024. seed_simulator: Random seed for simulators max_credits: Maximum credits to use basis_gates: List of basis gate names supported by the target. Defaults to basis gates of the backend. coupling_map (Optional[Union['CouplingMap', List[List]]]): Coupling map (perhaps custom) to target in mapping initial_layout (Optional[Union['Layout', Dict, List]]): Initial layout of qubits in mapping pass_manager (Optional['PassManager']): Pass manager to handle how to compile the circuits. To run only this pass manager and not the ``bound_pass_manager``, call the :meth:`~qiskit.utils.QuantumInstance.transpile` method with the argument ``pass_manager=quantum_instance.unbound_pass_manager``. bound_pass_manager (Optional['PassManager']): A second pass manager to apply on bound circuits only, that is, circuits without any free parameters. To only run this pass manager and not ``pass_manager`` call the :meth:`~qiskit.utils.QuantumInstance.transpile` method with the argument ``pass_manager=quantum_instance.bound_pass_manager``. manager should also be run. seed_transpiler: The random seed for circuit mapper optimization_level: How much optimization to perform on the circuits. Higher levels generate more optimized circuits, at the expense of longer transpilation time. backend_options: All running options for backend, please refer to the provider of the backend for information as to what options it supports. noise_model (Optional['NoiseModel']): noise model for simulator timeout: Seconds to wait for job. If None, wait indefinitely. wait: Seconds between queries for job result skip_qobj_validation: Bypass Qobj validation to decrease circuit processing time during submission to backend. measurement_error_mitigation_cls: The approach to mitigate measurement errors. The classes :class:`~qiskit.utils.mitigation.CompleteMeasFitter` or :class:`~qiskit.utils.mitigation.TensoredMeasFitter` from the :mod:`qiskit.utils.mitigation` module can be used here as exact values, not instances. ``TensoredMeasFitter`` doesn't support the ``subset_fitter`` method. cals_matrix_refresh_period: How often to refresh the calibration matrix in measurement mitigation. in minutes measurement_error_mitigation_shots: The number of shots number for building calibration matrix. If None, the main `shots` parameter value is used. job_callback: Optional user supplied callback which can be used to monitor job progress as jobs are submitted for processing by an Aqua algorithm. The callback is provided the following arguments: `job_id, job_status, queue_position, job` mit_pattern: Qubits on which to perform the TensoredMeasFitter measurement correction, divided to groups according to tensors. If `None` and `qr` is given then assumed to be performed over the entire `qr` as one group (default `None`). max_job_retries(int): positive non-zero number of trials for the job set (-1 for infinite trials) (default: 50) Raises: QiskitError: the shots exceeds the maximum number of shots QiskitError: set noise model but the backend does not support that QiskitError: set backend_options but the backend does not support that """ self._backend = backend self._backend_interface_version = _get_backend_interface_version(self._backend) self._pass_manager = pass_manager self._bound_pass_manager = bound_pass_manager # if the shots are none, try to get them from the backend if shots is None: from qiskit.providers.basebackend import BaseBackend # pylint: disable=cyclic-import from qiskit.providers.backend import Backend # pylint: disable=cyclic-import if isinstance(backend, (BaseBackend, Backend)): if hasattr(backend, "options"): # should always be true for V1 backend_shots = backend.options.get("shots", 1024) if shots != backend_shots: logger.info( "Overwriting the number of shots in the quantum instance with " "the settings from the backend." ) shots = backend_shots # safeguard if shots are still not set if shots is None: shots = 1024 # pylint: disable=cyclic-import from qiskit.assembler.run_config import RunConfig run_config = RunConfig(shots=shots, max_credits=max_credits) if seed_simulator is not None: run_config.seed_simulator = seed_simulator self._run_config = run_config # setup backend config if self._backend_interface_version <= 1: 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} else: self._backend_config = {} # setup compile config self._compile_config = { "initial_layout": initial_layout, "seed_transpiler": seed_transpiler, "optimization_level": optimization_level, } # setup job config self._qjob_config = ( {"timeout": timeout} if self.is_local else {"timeout": timeout, "wait": wait} ) # setup noise config self._noise_config = {} if noise_model is not None: if is_simulator_backend(self._backend) and not is_basicaer_provider(self._backend): self._noise_config = {"noise_model": noise_model} else: raise QiskitError( "The noise model is not supported " "on the selected backend {} ({}) " "only certain backends, such as Aer qasm simulator " "support noise.".format(self.backend_name, _get_backend_provider(self._backend)) ) # setup backend options for run self._backend_options = {} if backend_options is not None: if support_backend_options(self._backend): self._backend_options = {"backend_options": backend_options} else: raise QiskitError( "backend_options can not used with the backends in IBMQ provider." ) # setup measurement error mitigation self._meas_error_mitigation_cls = None if self.is_statevector: if measurement_error_mitigation_cls is not None: raise QiskitError( "Measurement error mitigation does not work with the statevector simulation." ) else: self._meas_error_mitigation_cls = measurement_error_mitigation_cls self._meas_error_mitigation_fitters: Dict[str, Tuple[np.ndarray, float]] = {} # TODO: support different fitting method in error mitigation? self._meas_error_mitigation_method = "least_squares" self._cals_matrix_refresh_period = cals_matrix_refresh_period self._meas_error_mitigation_shots = measurement_error_mitigation_shots self._mit_pattern = mit_pattern if self._meas_error_mitigation_cls is not None: logger.info( "The measurement error mitigation is enabled. " "It will automatically submit an additional job to help " "calibrate the result of other jobs. " "The current approach will submit a job with 2^N circuits " "to build the calibration matrix, " "where N is the number of measured qubits. " "Furthermore, Aqua will re-use the calibration matrix for %s minutes " "and re-build it after that.", self._cals_matrix_refresh_period, ) # setup others if is_ibmq_provider(self._backend): if skip_qobj_validation: logger.info( "skip_qobj_validation was set True but this setting is not " "supported by IBMQ provider and has been ignored." ) skip_qobj_validation = False self._skip_qobj_validation = skip_qobj_validation self._circuit_summary = False self._job_callback = job_callback self._time_taken = 0.0 self._max_job_retries = max_job_retries logger.info(self)