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
def construct_circuit(self, parameter, backend=None, use_simulator_operator_mode=False, statevector_mode=None, circuit_name_prefix=''): """Generate the circuits. Args: parameter (numpy.ndarray): parameters for variational form. backend (qiskit.BaseBackend, optional): backend object. use_simulator_operator_mode (bool, optional): is backend from AerProvider, if True and mode is paulis, single circuit is generated. statevector_mode (bool, optional): indicate which type of simulator are going to use. circuit_name_prefix (str, optional): a prefix of circuit name Returns: [QuantumCircuit]: the generated circuits with Hamiltonian. """ if backend is not None: warnings.warn("backend option is deprecated and it will be removed after 0.6, " "Use `statevector_mode` instead", DeprecationWarning) statevector_mode = is_statevector_backend(backend) else: if statevector_mode is None: raise AquaError("Either backend or statevector_mode need to be provided.") wave_function = self._var_form.construct_circuit(parameter) circuits = self._operator.construct_evaluation_circuit( use_simulator_operator_mode=use_simulator_operator_mode, wave_function=wave_function, statevector_mode=statevector_mode, circuit_name_prefix=circuit_name_prefix) return circuits
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))
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, }
def is_statevector(self): """Return True if backend is a statevector-type simulator.""" return is_statevector_backend(self._backend)
def build(operator: OperatorBase, backend: Optional[Union[Backend, BaseBackend, QuantumInstance]] = None, include_custom: bool = True) -> ExpectationBase: """ A factory method for convenient automatic selection of an Expectation based on the Operator to be converted and backend used to sample the expectation value. Args: operator: The Operator whose expectation value will be taken. backend: The backend which will be used to sample the expectation value. include_custom: Whether the factory will include the (Aer) specific custom expectations if their behavior against the backend might not be as expected. For instance when using Aer qasm_simulator with paulis the Aer snapshot can be used but the outcome lacks shot noise and hence does not intuitively behave overall as people might expect when choosing a qasm_simulator. It is however fast as long as the more state vector like behavior is acceptable. Returns: The expectation algorithm which best fits the Operator and backend. Raises: ValueError: If operator is not of a composition for which we know the best Expectation method. """ backend_to_check = backend.backend if isinstance(backend, QuantumInstance) else backend # pylint: disable=cyclic-import,import-outside-toplevel primitives = operator.primitive_strings() if primitives == {'Pauli'}: if backend_to_check is None: # If user has Aer but didn't specify a backend, use the Aer fast expectation if has_aer(): from qiskit import Aer backend_to_check = Aer.get_backend('qasm_simulator') # If user doesn't have Aer, use statevector_simulator # for < 16 qubits, and qasm with warning for more. else: if operator.num_qubits <= 16: backend_to_check = BasicAer.get_backend('statevector_simulator') else: logging.warning( '%d qubits is a very large expectation value. ' 'Consider installing Aer to use ' 'Aer\'s fast expectation, which will perform better here. We\'ll use ' 'the BasicAer qasm backend for this expectation to avoid having to ' 'construct the %dx%d operator matrix.', operator.num_qubits, 2 ** operator.num_qubits, 2 ** operator.num_qubits) backend_to_check = BasicAer.get_backend('qasm_simulator') # If the user specified Aer qasm backend and is using a # Pauli operator, use the Aer fast expectation if we are including such # custom behaviors. if is_aer_qasm(backend_to_check) and include_custom: return AerPauliExpectation() # If the user specified a statevector backend (either Aer or BasicAer), # use a converter to produce a # Matrix operator and compute using matmul elif is_statevector_backend(backend_to_check): if operator.num_qubits >= 16: logging.warning( 'Note: Using a statevector_simulator with %d qubits can be very expensive. ' 'Consider using the Aer qasm_simulator instead to take advantage of Aer\'s ' 'built-in fast Pauli Expectation', operator.num_qubits) return MatrixExpectation() # All other backends, including IBMQ, BasicAer QASM, go here. else: return PauliExpectation() elif primitives == {'Matrix'}: return MatrixExpectation() else: raise ValueError('Expectations of Mixed Operators not yet supported.')