diff --git a/qiskit/providers/aer/backends/qasm_simulator.py b/qiskit/providers/aer/backends/qasm_simulator.py index 56a8ba75fd..f390054850 100644 --- a/qiskit/providers/aer/backends/qasm_simulator.py +++ b/qiskit/providers/aer/backends/qasm_simulator.py @@ -295,14 +295,14 @@ class QasmSimulator(AerBackend): 'initialize', 'delay', 'pauli', 'mcx_gray', # Custom instructions 'kraus', 'roerror', 'snapshot', 'save_expval', 'save_expval_var', - 'save_probabilities', 'save_probabilities_dict', + 'save_probabilities', 'save_probabilities_dict', 'save_state', 'save_density_matrix', 'save_statevector', 'save_amplitudes', 'save_amplitudes_sq', 'save_stabilizer' ]), 'custom_instructions': sorted([ 'roerror', 'kraus', 'snapshot', 'save_expval', 'save_expval_var', 'save_probabilities', 'save_probabilities_dict', - 'save_density_matrix', 'save_statevector', + 'save_state', 'save_density_matrix', 'save_statevector', 'save_amplitudes', 'save_amplitudes_sq', 'save_stabilizer']), 'gates': [] } @@ -481,7 +481,7 @@ def _method_configuration(method=None): config.custom_instructions = sorted([ 'roerror', 'snapshot', 'kraus', 'superop', 'save_expval', 'save_expval_var', 'save_probabilities', 'save_probabilities_dict', 'save_density_matrix', - 'save_amplitudes_sq']) + 'save_amplitudes_sq', 'save_state']) config.basis_gates = sorted([ 'u1', 'u2', 'u3', 'u', 'p', 'r', 'rx', 'ry', 'rz', 'id', 'x', 'y', 'z', 'h', 's', 'sdg', 'sx', 't', 'tdg', 'swap', 'cx', @@ -511,7 +511,7 @@ def _method_configuration(method=None): config.custom_instructions = sorted([ 'roerror', 'snapshot', 'save_expval', 'save_expval_var', 'save_probabilities', 'save_probabilities_dict', - 'save_amplitudes_sq', 'save_stabilizer']) + 'save_amplitudes_sq', 'save_stabilizer', 'save_state']) config.basis_gates = sorted([ 'id', 'x', 'y', 'z', 'h', 's', 'sdg', 'sx', 'cx', 'cy', 'cz', 'swap', 'delay', diff --git a/qiskit/providers/aer/backends/statevector_simulator.py b/qiskit/providers/aer/backends/statevector_simulator.py index f83788bc77..7791db02b8 100644 --- a/qiskit/providers/aer/backends/statevector_simulator.py +++ b/qiskit/providers/aer/backends/statevector_simulator.py @@ -130,7 +130,7 @@ class StatevectorSimulator(AerBackend): 'initialize', 'kraus', 'roerror', 'delay', 'pauli', 'save_expval', 'save_density_matrix', 'save_statevector', 'save_probs', 'save_probs_ket', 'save_amplitudes', - 'save_amplitudes_sq' + 'save_amplitudes_sq', 'save_state' ], 'gates': [] } diff --git a/qiskit/providers/aer/backends/unitary_simulator.py b/qiskit/providers/aer/backends/unitary_simulator.py index 7f141c1291..abed526b3c 100644 --- a/qiskit/providers/aer/backends/unitary_simulator.py +++ b/qiskit/providers/aer/backends/unitary_simulator.py @@ -133,7 +133,7 @@ class UnitarySimulator(AerBackend): 'rzz', 'rzx', 'ccx', 'cswap', 'mcx', 'mcy', 'mcz', 'mcsx', 'mcp', 'mcu1', 'mcu2', 'mcu3', 'mcrx', 'mcry', 'mcrz', 'mcr', 'mcswap', 'unitary', 'diagonal', 'multiplexer', 'delay', 'pauli', - 'save_unitary' + 'save_unitary', 'save_state' ], 'gates': [] } diff --git a/qiskit/providers/aer/library/__init__.py b/qiskit/providers/aer/library/__init__.py index 6eb2848230..61742e881a 100644 --- a/qiskit/providers/aer/library/__init__.py +++ b/qiskit/providers/aer/library/__init__.py @@ -33,6 +33,7 @@ .. autosummary:: :toctree: ../stubs/ + SaveState SaveExpectationValue SaveExpectationValueVariance SaveProbabilities @@ -53,6 +54,7 @@ .. autosummary:: :toctree: ../stubs/ + save_state save_expectation_value save_expectation_value_variance save_probabilities @@ -95,12 +97,14 @@ state. """ -__all__ = ['SaveExpectationValue', 'SaveExpectationValueVariance', +__all__ = ['SaveState', + 'SaveExpectationValue', 'SaveExpectationValueVariance', 'SaveProbabilities', 'SaveProbabilitiesDict', 'SaveStatevector', 'SaveStatevectorDict', 'SaveDensityMatrix', 'SaveAmplitudes', 'SaveAmplitudesSquared', 'SaveUnitary', 'SaveStabilizer'] +from .save_state import SaveState, save_state from .save_expectation_value import ( SaveExpectationValue, save_expectation_value, SaveExpectationValueVariance, save_expectation_value_variance) @@ -111,5 +115,5 @@ from .save_density_matrix import SaveDensityMatrix, save_density_matrix from .save_amplitudes import (SaveAmplitudes, save_amplitudes, SaveAmplitudesSquared, save_amplitudes_squared) -from .save_stabilizer import (SaveStabilizer, save_stabilizer) -from .save_unitary import (SaveUnitary, save_unitary) +from .save_stabilizer import SaveStabilizer, save_stabilizer +from .save_unitary import SaveUnitary, save_unitary diff --git a/qiskit/providers/aer/library/save_state.py b/qiskit/providers/aer/library/save_state.py new file mode 100644 index 0000000000..ce22b6208b --- /dev/null +++ b/qiskit/providers/aer/library/save_state.py @@ -0,0 +1,85 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2018, 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +""" +Simulator instruction to save simulator state. +""" + +from qiskit.circuit import QuantumCircuit +from .save_data import SaveSingleData, default_qubits + + +class SaveState(SaveSingleData): + """Save simulator state + + The format of the saved state depends on the simulation method used. + """ + def __init__(self, num_qubits, + label=None, + pershot=False, + conditional=False): + """Create new instruction to save the simualtor state. + + The format of the saved state depends on the simulation method used. + + Args: + num_qubits (int): the number of qubits of the + label (str or None): Optional, the key for retrieving saved data + from results. If None the key will be the + state type of the simulator. + pershot (bool): if True save a list of states for each + shot of the simulation rather than a single + state [Default: False]. + conditional (bool): if True save data conditional on the current + classical register values [Default: False]. + + .. note:: + + This save instruction must always be performed on the full width of + qubits in a circuit, otherwise an exception will be raised during + simulation. + """ + if label is None: + label = '_method_' + super().__init__('save_state', num_qubits, label, + pershot=pershot, + conditional=conditional) + + +def save_state(self, label=None, pershot=False, conditional=False): + """Save the current simulator quantum state. + + Args: + label (str or None): Optional, the key for retrieving saved data + from results. If None the key will be the + state type of the simulator. + pershot (bool): if True save a list of statevectors for each + shot of the simulation [Default: False]. + conditional (bool): if True save pershot data conditional on the + current classical register values + [Default: False]. + + Returns: + QuantumCircuit: with attached instruction. + + .. note: + + This instruction is always defined across all qubits in a circuit. + """ + qubits = default_qubits(self) + instr = SaveState(len(qubits), + label=label, + pershot=pershot, + conditional=conditional) + return self.append(instr, qubits) + + +QuantumCircuit.save_state = save_state