Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into fusion_variations
Browse files Browse the repository at this point in the history
  • Loading branch information
hhorii committed Feb 16, 2021
2 parents 8271be5 + d58737a commit 5e21688
Show file tree
Hide file tree
Showing 72 changed files with 4,088 additions and 553 deletions.
3 changes: 2 additions & 1 deletion docs/apidocs/aer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ Qiskit Aer API Reference
:maxdepth: 1

aer_provider
aer_extensions
aer_library
aer_noise
aer_pulse
aer_utils
aer_extensions
6 changes: 6 additions & 0 deletions docs/apidocs/aer_library.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.. _aer-library:

.. automodule:: qiskit.providers.aer.library
:no-members:
:no-inherited-members:
:no-special-members:
1 change: 1 addition & 0 deletions qiskit/providers/aer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
from .aerjob import AerJob
from .aererror import AerError
from .backends import *
from . import library
from . import pulse
from . import noise
from . import utils
Expand Down
23 changes: 18 additions & 5 deletions qiskit/providers/aer/backends/qasm_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,14 @@ class QasmSimulator(AerBackend):
'mcr', 'mcswap', 'unitary', 'diagonal', 'multiplexer',
'initialize', 'delay', 'pauli', 'mcx_gray',
# Custom instructions
'kraus', 'roerror', 'snapshot'
'kraus', 'roerror', 'snapshot', 'save_expval', 'save_expval_var',
'save_probabilities', 'save_probabilities_dict',
'save_density_matrix', 'save_statevector'
]),
'custom_instructions': sorted(['roerror', 'kraus', 'snapshot']),
'custom_instructions': sorted([
'roerror', 'kraus', 'snapshot', 'save_expval', 'save_expval_var',
'save_probabilities', 'save_probabilities_dict',
'save_density_matrix', 'save_statevector']),
'gates': []
}

Expand Down Expand Up @@ -471,7 +476,9 @@ def _method_configuration(method=None):
]:
config.n_qubits = config.n_qubits // 2
config.description = 'A C++ QasmQobj density matrix simulator with noise'
config.custom_instructions = sorted(['roerror', 'snapshot', 'kraus', 'superop'])
config.custom_instructions = sorted([
'roerror', 'snapshot', 'kraus', 'superop', 'save_expval', 'save_expval_var',
'save_probabilities', 'save_probabilities_dict', 'save_density_matrix'])
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',
Expand All @@ -482,6 +489,10 @@ def _method_configuration(method=None):
# Matrix product state method
elif method == 'matrix_product_state':
config.description = 'A C++ QasmQobj matrix product state simulator with noise'
config.custom_instructions = sorted([
'roerror', 'snapshot', 'kraus', 'save_expval', 'save_expval_var',
'save_probabilities', 'save_probabilities_dict',
'save_density_matrix', 'save_statevector'])
config.basis_gates = sorted([
'u1', 'u2', 'u3', 'u', 'p', 'cp', 'cx', 'cy', 'cz', 'id', 'x', 'y', 'z', 'h', 's',
'sdg', 'sx', 't', 'tdg', 'swap', 'ccx', 'unitary', 'roerror', 'delay',
Expand All @@ -493,7 +504,9 @@ def _method_configuration(method=None):
elif method == 'stabilizer':
config.n_qubits = 5000 # TODO: estimate from memory
config.description = 'A C++ QasmQobj Clifford stabilizer simulator with noise'
config.custom_instructions = sorted(['roerror', 'snapshot'])
config.custom_instructions = sorted([
'roerror', 'snapshot', 'save_expval', 'save_expval_var',
'save_probabilities', 'save_probabilities_dict'])
config.basis_gates = sorted([
'id', 'x', 'y', 'z', 'h', 's', 'sdg', 'sx', 'cx', 'cy', 'cz',
'swap', 'delay',
Expand All @@ -503,7 +516,7 @@ def _method_configuration(method=None):
elif method == 'extended_stabilizer':
config.n_qubits = 63 # TODO: estimate from memory
config.description = 'A C++ QasmQobj ranked stabilizer simulator with noise'
config.custom_instructions = sorted(['roerror', 'snapshot'])
config.custom_instructions = sorted(['roerror', 'snapshot', 'save_statevector'])
config.basis_gates = sorted([
'cx', 'cz', 'id', 'x', 'y', 'z', 'h', 's', 'sdg', 'sx', 'swap',
'u0', 'u1', 'p', 'ccx', 'ccz', 'delay'
Expand Down
4 changes: 3 additions & 1 deletion qiskit/providers/aer/backends/statevector_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ class StatevectorSimulator(AerBackend):
'rzz', 'rzx', 'ccx', 'cswap', 'mcx', 'mcy', 'mcz', 'mcsx',
'mcp', 'mcu1', 'mcu2', 'mcu3', 'mcrx', 'mcry', 'mcrz',
'mcr', 'mcswap', 'unitary', 'diagonal', 'multiplexer',
'initialize', 'kraus', 'roerror', 'delay', 'pauli'
'initialize', 'kraus', 'roerror', 'delay', 'pauli',
'save_expval', 'save_density_matrix', 'save_statevector',
'save_probs', 'save_probs_ket'
],
'gates': []
}
Expand Down
91 changes: 91 additions & 0 deletions qiskit/providers/aer/library/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# 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.

"""
=========================================================
Instruction Library (:mod:`qiskit.providers.aer.library`)
=========================================================
.. currentmodule:: qiskit.providers.aer.library
This library contains custom qiskit :class:`~qiskit.QuantumCircuit`
:class:`~qiskit.circuit.Instruction` subclasses that can be used
with the Aer circuit simulator backends.
Saving Simulator Data
=====================
The following classes can be used to directly save data from the
simulator to the returned result object.
Instruction Classes
-------------------
.. autosummary::
:toctree: ../stubs/
SaveExpectationValue
SaveExpectationValueVariance
SaveProbabilities
SaveProbabilitiesDict
SaveDensityMatrix
SaveStatevector
SaveStatevectorDict
Then can also be used using custom QuantumCircuit methods
QuantumCircuit Methods
----------------------
.. autosummary::
:toctree: ../stubs/
save_expectation_value
save_expectation_value_variance
save_probabilities
save_probabilities_dict
save_density_matrix
save_statevector
save_statevector_dict
.. note ::
**Pershot Data with Measurement Sampling Optimization**
When saving pershot data by using the ``pershot=True`` kwarg
in the above instructions, the resulting list may only contain
a single value rather than the number of shots. This
happens when a run circuit supports measurement sampling because
it is either
1. An ideal simulation with all measurements at the end.
2. A noisy simulation using the density matrix method with all
measurements at the end.
In both these cases only a single shot is actually simulated and
measurement samples for all shots are calculated from the final
state.
"""

__all__ = ['SaveExpectationValue', 'SaveExpectationValueVariance',
'SaveProbabilities', 'SaveProbabilitiesDict',
'SaveStatevector', 'SaveStatevectorDict', 'SaveDensityMatrix']

from .save_expectation_value import (
SaveExpectationValue, save_expectation_value,
SaveExpectationValueVariance, save_expectation_value_variance)
from .save_probabilities import (SaveProbabilities, save_probabilities,
SaveProbabilitiesDict, save_probabilities_dict)
from .save_statevector import (SaveStatevector, save_statevector,
SaveStatevectorDict, save_statevector_dict)
from .save_density_matrix import SaveDensityMatrix, save_density_matrix
185 changes: 185 additions & 0 deletions qiskit/providers/aer/library/save_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# 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 custom internal data to results.
"""

import copy

from qiskit.circuit import QuantumCircuit, QuantumRegister
# TEMP For compatiblity until Terra PR #5701 is merged
try:
from qiskit.circuit import Directive
except ImportError:
from qiskit.circuit import Instruction as Directive
from qiskit.extensions.exceptions import ExtensionError


class SaveData(Directive):
"""Pragma Instruction to save simulator data."""

_allowed_subtypes = set([
'single', 'c_single', 'list', 'c_list',
'average', 'c_average', 'accum', 'c_accum'
])

def __init__(self, name, key, num_qubits, subtype='single', params=None):
"""Create new save data instruction.
Args:
name (str): the name of hte save instruction.
key (str): the key for retrieving saved data from results.
num_qubits (int): the number of qubits for the snapshot type.
subtype (str): the data subtype for the instruction [Default: 'single'].
params (list or None): Optional, the parameters for instruction
[Default: None].
Raises:
ExtensionError: if the subtype string is invalid.
Additional Information:
The supported subtypes are 'single', 'list', 'c_list', 'average',
'c_average', 'accum', 'c_accum'.
"""
if params is None:
params = {}

if subtype not in self._allowed_subtypes:
raise ExtensionError(
"Invalid data subtype for SaveData instruction.")

if not isinstance(key, str):
raise ExtensionError("Invalid key for save data instruction, key must be a string.")

self._key = key
self._subtype = subtype
super().__init__(name, num_qubits, 0, params)

def assemble(self):
"""Return the QasmQobjInstruction for the intructions."""
instr = super().assemble()
# Use same fields as Snapshot instruction
# so we dont need to modify QasmQobjInstruction
instr.snapshot_type = self._subtype
instr.label = self._key
return instr

def inverse(self):
"""Special case. Return self."""
return copy.copy(self)


class SaveAverageData(SaveData):
"""Save averageble data"""
def __init__(self,
name,
key,
num_qubits,
unnormalized=False,
pershot=False,
conditional=False,
params=None):
"""Create new save data instruction.
Args:
name (str): the name of hte save instruction.
key (str): the key for retrieving saved data from results.
num_qubits (int): the number of qubits for the snapshot type.
unnormalized (bool): If True return save the unnormalized accumulated
or conditional accumulated data over all shot.
[Default: False].
pershot (bool): if True save a list of data for each shot of the
simulation rather than the average over all shots
[Default: False].
conditional (bool): if True save the average or pershot data
conditional on the current classical register
values [Default: False].
params (list or None): Optional, the parameters for instruction
[Default: None].
"""
if pershot:
subtype = 'list'
elif unnormalized:
subtype = 'accum'
else:
subtype = 'average'
if conditional:
subtype = 'c_' + subtype
super().__init__(name, key, num_qubits, subtype=subtype, params=params)


class SaveSingleData(SaveData):
"""Save non-averagable single data type."""

def __init__(self,
name,
key,
num_qubits,
pershot=False,
conditional=False,
params=None):
"""Create new save data instruction.
Args:
name (str): the name of the save instruction.
key (str): the key for retrieving saved data from results.
num_qubits (int): the number of qubits for the snapshot type.
pershot (bool): if True save a list of data for each shot of the
simulation [Default: False].
conditional (bool): if True save data conditional on the
current classical register values
[Default: False].
params (list or None): Optional, the parameters for instruction
[Default: None].
"""
subtype = 'list' if pershot else 'single'
if conditional:
subtype = 'c_' + subtype
super().__init__(name, key, num_qubits, subtype=subtype, params=params)


def default_qubits(circuit, qubits=None):
"""Helper method to return list of qubits.
Args:
circuit (QuantumCircuit): a quantum circuit.
qubits (list or QuantumRegister): Optional, qubits argument,
If None the returned list will be all qubits in the circuit.
[Default: None]
Raises:
ExtensionError: if default qubits fails.
Returns:
list: qubits list.
"""
# Convert label to string for backwards compatibility
# If no qubits are specified we add all qubits so it acts as a barrier
# This is needed for full register snapshots like statevector
if isinstance(qubits, QuantumRegister):
qubits = qubits[:]
if not qubits:
tuples = []
if isinstance(circuit, QuantumCircuit):
for register in circuit.qregs:
tuples.append(register)
if not tuples:
raise ExtensionError('no qubits for snapshot')
qubits = []
for tuple_element in tuples:
if isinstance(tuple_element, QuantumRegister):
for j in range(tuple_element.size):
qubits.append(tuple_element[j])
else:
qubits.append(tuple_element)

return qubits
Loading

0 comments on commit 5e21688

Please sign in to comment.