diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 6ca1602b0..ef6f667b1 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -74,10 +74,10 @@ jobs:
- name: Run tests
run: |
- pl-device-test --device=qiskit.basicaer --tb=short --skip-ops --analytic=False --shots=20000 --device-kwargs backend=qasm_simulator
- pl-device-test --device=qiskit.aer --tb=short --skip-ops --analytic=False --shots=20000 --device-kwargs backend=qasm_simulator
- pl-device-test --device=qiskit.aer --tb=short --skip-ops --analytic=True --device-kwargs backend=statevector_simulator
- pl-device-test --device=qiskit.aer --tb=short --skip-ops --analytic=True --device-kwargs backend=unitary_simulator
+ pl-device-test --device=qiskit.basicaer --tb=short --skip-ops --shots=20000 --device-kwargs backend=qasm_simulator
+ pl-device-test --device=qiskit.aer --tb=short --skip-ops --shots=20000 --device-kwargs backend=qasm_simulator
+ pl-device-test --device=qiskit.aer --tb=short --skip-ops --shots=None --device-kwargs backend=statevector_simulator
+ pl-device-test --device=qiskit.aer --tb=short --skip-ops --shots=None --device-kwargs backend=unitary_simulator
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
diff --git a/doc/conf.py b/doc/conf.py
index 4089fb0e0..5c1acfc66 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -409,8 +409,9 @@
#autodoc_default_flags = ['members']
autosummary_generate = True
-from directives import CustomDeviceGalleryItemDirective, CustomDemoGalleryItemDirective
+from directives import UsageDetails, CustomDeviceGalleryItemDirective, CustomDemoGalleryItemDirective
def setup(app):
app.add_directive('devicegalleryitem', CustomDeviceGalleryItemDirective)
app.add_directive('demogalleryitem', CustomDemoGalleryItemDirective)
+ app.add_directive("usagedetails", UsageDetails)
diff --git a/doc/directives.py b/doc/directives.py
index 99462acb9..f1d1b2913 100644
--- a/doc/directives.py
+++ b/doc/directives.py
@@ -20,6 +20,42 @@
import os
+USAGE_DETAILS_TEMPLATE = """
+.. raw:: html
+
+
+
+
+{content}
+
+.. raw:: html
+
+
+"""
+
+
+class UsageDetails(Directive):
+ """Create a collapsed Usage Details section in the documentation."""
+
+ # defines the parameter the directive expects
+ # directives.unchanged means you get the raw value from RST
+ required_arguments = 0
+ optional_arguments = 0
+ final_argument_whitespace = False
+ has_content = True
+
+ def run(self):
+ rst = USAGE_DETAILS_TEMPLATE.format(content="\n".join(self.content))
+ string_list = StringList(rst.split('\n'))
+ node = nodes.section()
+ self.state.nested_parse(string_list, self.content_offset, node)
+ return [node]
+
+
GALLERY_TEMPLATE = """
.. raw:: html
diff --git a/pennylane_qiskit/aer.py b/pennylane_qiskit/aer.py
index d82872476..f00d8f575 100644
--- a/pennylane_qiskit/aer.py
+++ b/pennylane_qiskit/aer.py
@@ -38,16 +38,14 @@ class AerDevice(QiskitDevice):
or iterable that contains unique labels for the subsystems as numbers (i.e., ``[-1, 0, 2]``)
or strings (``['ancilla', 'q1', 'q2']``).
backend (str): the desired backend
- shots (int): number of circuit evaluations/random samples used
- to estimate expectation values and variances of observables
+ shots (int or None): number of circuit evaluations/random samples used
+ to estimate expectation values and variances of observables. For statevector backends,
+ setting to ``None`` results in computing statistics like expectation values and variances analytically.
Keyword Args:
name (str): The name of the circuit. Default ``'circuit'``.
compile_backend (BaseBackend): The backend used for compilation. If you wish
to simulate a device compliant circuit, you can specify a backend here.
- analytic (bool): For statevector backends, determines if the
- expectation values and variances are to be computed analytically.
- Default value is ``False``.
noise_model (NoiseModel): NoiseModel Object from ``qiskit.providers.aer.noise``
"""
diff --git a/pennylane_qiskit/basic_aer.py b/pennylane_qiskit/basic_aer.py
index 84b58e182..814b235d6 100644
--- a/pennylane_qiskit/basic_aer.py
+++ b/pennylane_qiskit/basic_aer.py
@@ -38,16 +38,14 @@ class BasicAerDevice(QiskitDevice):
or iterable that contains unique labels for the subsystems as numbers (i.e., ``[-1, 0, 2]``)
or strings (``['ancilla', 'q1', 'q2']``).
backend (str): the desired backend
- shots (int): number of circuit evaluations/random samples used
- to estimate expectation values and variances of observables
+ shots (int or None): number of circuit evaluations/random samples used
+ to estimate expectation values and variances of observables. For statevector backends,
+ setting to ``None`` results in computing statistics like expectation values and variances analytically.
Keyword Args:
name (str): The name of the circuit. Default ``'circuit'``.
compile_backend (BaseBackend): The backend used for compilation. If you wish
to simulate a device compliant circuit, you can specify a backend here.
- analytic (bool): For statevector backends, determines if the
- expectation values and variances are to be computed analytically.
- Default value is ``False``.
"""
short_name = "qiskit.basicaer"
diff --git a/pennylane_qiskit/qiskit_device.py b/pennylane_qiskit/qiskit_device.py
index efebd5562..f5171c6e2 100644
--- a/pennylane_qiskit/qiskit_device.py
+++ b/pennylane_qiskit/qiskit_device.py
@@ -75,16 +75,14 @@ class QiskitDevice(QubitDevice, abc.ABC):
or strings (``['ancilla', 'q1', 'q2']``).
provider (Provider): The Qiskit simulation provider
backend (str): the desired backend
- shots (int): Number of circuit evaluations/random samples used
- to estimate expectation values of observables.
+ shots (int or None): number of circuit evaluations/random samples used
+ to estimate expectation values and variances of observables. For statevector backends,
+ setting to ``None`` results in computing statistics like expectation values and variances analytically.
Keyword Args:
name (str): The name of the circuit. Default ``'circuit'``.
compile_backend (BaseBackend): The backend used for compilation. If you wish
to simulate a device compliant circuit, you can specify a backend here.
- analytic (bool): For statevector backends, determines if the
- expectation values and variances are to be computed analytically.
- Default value is ``False``.
"""
name = "Qiskit PennyLane plugin"
pennylane_requires = ">=0.12.0"
@@ -113,16 +111,12 @@ def __init__(self, wires, provider, backend, shots=1024, **kwargs):
super().__init__(wires=wires, shots=shots)
# Keep track if the user specified analytic to be True
- user_specified_analytic = "analytic" in kwargs and kwargs["analytic"]
- self.analytic = kwargs.pop("analytic", False)
+ if shots is None and backend not in self._state_backends:
- if self.analytic and backend not in self._state_backends:
+ # Raise a warning if no shots were specified for a hardware device
+ warnings.warn(self.hw_analytic_warning_message.format(backend), UserWarning)
- if user_specified_analytic:
- # Raise a warning if the analytic attribute was set to True
- warnings.warn(self.hw_analytic_warning_message.format(backend), UserWarning)
-
- self.analytic = False
+ self.shots = 1024
self._backend = None
diff --git a/requirements.txt b/requirements.txt
index ee1f33052..477160fbe 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,5 @@
qiskit>=0.23.4
-pennylane>=0.14.0
+git+https://github.com/PennyLaneAI/pennylane.git
numpy
networkx>=2.2;python_version>'3.5'
networkx>=2.2,<2.4;python_version=='3.5'
diff --git a/tests/conftest.py b/tests/conftest.py
index b8de9e138..c96c33b4f 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -26,8 +26,8 @@
@pytest.fixture
-def tol(analytic):
- if analytic:
+def tol(shots):
+ if shots is None:
return {"atol": 0.01, "rtol": 0}
return {"atol": 0.05, "rtol": 0.1}
@@ -42,16 +42,19 @@ def _init_state(n):
return _init_state
+
@pytest.fixture
def skip_unitary(backend):
if backend == "unitary_simulator":
pytest.skip("This test does not support the unitary simulator backend.")
+
@pytest.fixture
def run_only_for_unitary(backend):
if backend != "unitary_simulator":
pytest.skip("This test only supports the unitary simulator.")
+
@pytest.fixture(params=state_backends + hw_backends)
def backend(request):
return request.param
@@ -68,22 +71,22 @@ def hardware_backend(request):
@pytest.fixture(params=[AerDevice, BasicAerDevice])
-def device(request, backend, shots, analytic):
- if backend not in state_backends and analytic == True:
+def device(request, backend, shots):
+ if backend not in state_backends and shots is None:
pytest.skip("Hardware simulators do not support analytic mode")
def _device(n, device_options=None):
if device_options is None:
device_options = {}
- return request.param(wires=n, backend=backend, shots=shots, analytic=analytic, **device_options)
+ return request.param(wires=n, backend=backend, shots=shots, **device_options)
return _device
@pytest.fixture(params=[AerDevice, BasicAerDevice])
-def state_vector_device(request, statevector_backend, shots, analytic):
+def state_vector_device(request, statevector_backend, shots):
def _device(n):
- return request.param(wires=n, backend=statevector_backend, shots=shots, analytic=analytic)
+ return request.param(wires=n, backend=statevector_backend, shots=shots)
return _device
@@ -94,20 +97,20 @@ def mock_device(monkeypatch):
with monkeypatch.context() as m:
dev = qml.Device
- m.setattr(dev, '__abstractmethods__', frozenset())
+ m.setattr(dev, "__abstractmethods__", frozenset())
yield qml.Device()
@pytest.fixture(scope="function")
def recorder():
- return qml._queuing.OperationRecorder()
+ return qml.tape.OperationRecorder()
@pytest.fixture(scope="function")
def qubit_device_single_wire():
- return qml.device('default.qubit', wires=1)
+ return qml.device("default.qubit", wires=1)
@pytest.fixture(scope="function")
def qubit_device_2_wires():
- return qml.device('default.qubit', wires=2)
+ return qml.device("default.qubit", wires=2)
diff --git a/tests/test_apply.py b/tests/test_apply.py
index b54e28ac9..38b47baaa 100644
--- a/tests/test_apply.py
+++ b/tests/test_apply.py
@@ -42,25 +42,18 @@
)
-single_qubit_operations = [
- qml.PauliX,
- qml.PauliY,
- qml.PauliZ,
- qml.Hadamard,
- qml.S,
- qml.T
-]
+single_qubit_operations = [qml.PauliX, qml.PauliY, qml.PauliZ, qml.Hadamard, qml.S, qml.T]
single_qubit_operations_param = [qml.PhaseShift, qml.RX, qml.RY, qml.RZ]
two_qubit = [qml.CNOT, qml.SWAP, qml.CZ]
two_qubit_param = [qml.CRZ]
three_qubit = [qml.Toffoli, qml.CSWAP]
-@pytest.mark.parametrize("analytic", [True])
-@pytest.mark.parametrize("shots", [8192])
+
+@pytest.mark.parametrize("shots", [None])
@pytest.mark.usefixtures("skip_unitary")
class TestAnalyticApply:
- """Test application of PennyLane operations with analytic attribute set to True."""
+ """Test application of PennyLane operations with analytic calculation."""
def test_qubit_state_vector(self, init_state, device, tol):
"""Test that the QubitStateVector operation produces the expected
@@ -149,8 +142,8 @@ def test_three_qubit_operations_no_parameters(self, init_state, device, operatio
expected = np.abs(applied_operation.matrix @ state) ** 2
assert np.allclose(res, expected, **tol)
-@pytest.mark.parametrize("analytic", [True])
-@pytest.mark.parametrize("shots", [8192])
+
+@pytest.mark.parametrize("shots", [None])
@pytest.mark.usefixtures("run_only_for_unitary")
class TestStateApplyUnitarySimulator:
"""Test application of PennyLane operations to the unitary simulator."""
@@ -161,14 +154,17 @@ def test_invalid_qubit(self, init_state, device):
dev = device(1)
state = init_state(1)
- with pytest.raises(qml.DeviceError, match="The QubitStateVector operation is not supported on the unitary simulator backend"):
+ with pytest.raises(
+ qml.DeviceError,
+ match="The QubitStateVector operation is not supported on the unitary simulator backend",
+ ):
dev.apply([qml.QubitStateVector(state, wires=[0])])
+
@pytest.mark.parametrize("shots", [8192])
-@pytest.mark.parametrize("analytic", [False])
@pytest.mark.usefixtures("skip_unitary")
class TestNonAnalyticApply:
- """Test application of PennyLane operations with the analytic attribute set to False."""
+ """Test application of PennyLane operations with non-analytic calculation."""
def test_qubit_state_vector(self, init_state, device, tol):
"""Test that the QubitStateVector operation produces the expected
@@ -302,4 +298,3 @@ def test_three_qubit_no_parameters(self, init_state, device, operation, tol):
res = np.fromiter(dev.probability(), dtype=np.float64)
expected = np.abs(applied_operation.matrix @ state) ** 2
assert np.allclose(res, expected, **tol)
-
diff --git a/tests/test_converter.py b/tests/test_converter.py
index 0aa838f35..41f394325 100644
--- a/tests/test_converter.py
+++ b/tests/test_converter.py
@@ -21,11 +21,11 @@
class TestConverter:
"""Tests the converter function that allows converting QuantumCircuit objects
- to Pennylane templates."""
+ to Pennylane templates."""
def test_quantum_circuit_init_by_specifying_rotation_in_circuit(self, recorder):
"""Tests the load method for a QuantumCircuit initialized using separately defined
- quantum and classical registers."""
+ quantum and classical registers."""
angle = 0.5
@@ -41,7 +41,7 @@ def test_quantum_circuit_init_by_specifying_rotation_in_circuit(self, recorder):
quantum_circuit()
assert len(recorder.queue) == 1
- assert recorder.queue[0].name == 'RZ'
+ assert recorder.queue[0].name == "RZ"
assert recorder.queue[0].parameters == [angle]
assert recorder.queue[0].wires == Wires([0])
@@ -49,7 +49,7 @@ def test_quantum_circuit_by_passing_parameters(self, recorder):
"""Tests the load method for a QuantumCircuit initialized by passing the number
of registers required."""
- theta = Parameter('θ')
+ theta = Parameter("θ")
angle = 0.5
qc = QuantumCircuit(3, 1)
@@ -61,7 +61,7 @@ def test_quantum_circuit_by_passing_parameters(self, recorder):
quantum_circuit(params={theta: angle})
assert len(recorder.queue) == 1
- assert recorder.queue[0].name == 'RZ'
+ assert recorder.queue[0].name == "RZ"
assert recorder.queue[0].parameters == [angle]
assert recorder.queue[0].wires == Wires([0])
@@ -69,7 +69,7 @@ def test_loaded_quantum_circuit_and_further_pennylane_operations(self, recorder)
"""Tests that a loaded quantum circuit can be used around other PennyLane
templates in a circuit."""
- theta = Parameter('θ')
+ theta = Parameter("θ")
angle = 0.5
qc = QuantumCircuit(3, 1)
@@ -83,13 +83,13 @@ def test_loaded_quantum_circuit_and_further_pennylane_operations(self, recorder)
qml.Hadamard(0)
assert len(recorder.queue) == 3
- assert recorder.queue[0].name == 'PauliZ'
+ assert recorder.queue[0].name == "PauliZ"
assert recorder.queue[0].parameters == []
assert recorder.queue[0].wires == Wires([0])
- assert recorder.queue[1].name == 'RZ'
+ assert recorder.queue[1].name == "RZ"
assert recorder.queue[1].parameters == [angle]
assert recorder.queue[1].wires == Wires([0])
- assert recorder.queue[2].name == 'Hadamard'
+ assert recorder.queue[2].name == "Hadamard"
assert recorder.queue[2].parameters == []
assert recorder.queue[2].wires == Wires([0])
@@ -99,8 +99,8 @@ def test_quantum_circuit_with_multiple_parameters(self, recorder):
angle1 = 0.5
angle2 = 0.3
- phi = Parameter('φ')
- theta = Parameter('θ')
+ phi = Parameter("φ")
+ theta = Parameter("θ")
qc = QuantumCircuit(3, 1)
qc.rx(phi, 1)
@@ -112,10 +112,10 @@ def test_quantum_circuit_with_multiple_parameters(self, recorder):
quantum_circuit(params={phi: angle1, theta: angle2})
assert len(recorder.queue) == 2
- assert recorder.queue[0].name == 'RX'
+ assert recorder.queue[0].name == "RX"
assert recorder.queue[0].parameters == [angle1]
assert recorder.queue[0].wires == Wires([1])
- assert recorder.queue[1].name == 'RZ'
+ assert recorder.queue[1].name == "RZ"
assert recorder.queue[1].parameters == [angle2]
assert recorder.queue[1].wires == Wires([0])
@@ -127,9 +127,9 @@ def test_quantum_circuit_with_gate_requiring_multiple_parameters(self, recorder)
angle2 = 0.3
angle3 = 0.1
- phi = Parameter('φ')
- lam = Parameter('λ')
- theta = Parameter('θ')
+ phi = Parameter("φ")
+ lam = Parameter("λ")
+ theta = Parameter("θ")
qc = QuantumCircuit(3, 1)
qc.u(phi, lam, theta, [0])
@@ -139,7 +139,7 @@ def test_quantum_circuit_with_gate_requiring_multiple_parameters(self, recorder)
with recorder:
quantum_circuit(params={phi: angle1, lam: angle2, theta: angle3})
- assert recorder.queue[0].name == 'U3'
+ assert recorder.queue[0].name == "U3"
assert len(recorder.queue[0].parameters) == 3
assert recorder.queue[0].parameters == [0.5, 0.3, 0.1]
assert recorder.queue[0].wires == Wires([0])
@@ -148,7 +148,7 @@ def test_quantum_circuit_loaded_multiple_times_with_different_arguments(self, re
"""Tests that a loaded quantum circuit can be called multiple times with
different arguments."""
- theta = Parameter('θ')
+ theta = Parameter("θ")
angle1 = 0.5
angle2 = -0.5
angle3 = 0
@@ -164,20 +164,20 @@ def test_quantum_circuit_loaded_multiple_times_with_different_arguments(self, re
quantum_circuit(params={theta: angle3})
assert len(recorder.queue) == 3
- assert recorder.queue[0].name == 'RZ'
+ assert recorder.queue[0].name == "RZ"
assert recorder.queue[0].parameters == [angle1]
assert recorder.queue[0].wires == Wires([0])
- assert recorder.queue[1].name == 'RZ'
+ assert recorder.queue[1].name == "RZ"
assert recorder.queue[1].parameters == [angle2]
assert recorder.queue[1].wires == Wires([0])
- assert recorder.queue[2].name == 'RZ'
+ assert recorder.queue[2].name == "RZ"
assert recorder.queue[2].parameters == [angle3]
assert recorder.queue[2].wires == Wires([0])
def test_quantum_circuit_with_bound_parameters(self, recorder):
"""Tests loading a quantum circuit that already had bound parameters."""
- theta = Parameter('θ')
+ theta = Parameter("θ")
qc = QuantumCircuit(3, 1)
qc.rz(theta, [0])
@@ -189,14 +189,14 @@ def test_quantum_circuit_with_bound_parameters(self, recorder):
quantum_circuit()
assert len(recorder.queue) == 1
- assert recorder.queue[0].name == 'RZ'
+ assert recorder.queue[0].name == "RZ"
assert recorder.queue[0].parameters == [0.5]
assert recorder.queue[0].wires == Wires([0])
def test_pass_parameters_to_bind(self, recorder):
"""Tests parameter binding by passing parameters when loading a quantum circuit."""
- theta = Parameter('θ')
+ theta = Parameter("θ")
qc = QuantumCircuit(3, 1)
qc.rz(theta, [0])
@@ -207,37 +207,38 @@ def test_pass_parameters_to_bind(self, recorder):
quantum_circuit(params={theta: 0.5})
assert len(recorder.queue) == 1
- assert recorder.queue[0].name == 'RZ'
+ assert recorder.queue[0].name == "RZ"
assert recorder.queue[0].parameters == [0.5]
assert recorder.queue[0].wires == Wires([0])
-
def test_parameter_was_not_bound(self, recorder):
"""Tests that loading raises an error when parameters were not bound."""
- theta = Parameter('θ')
+ theta = Parameter("θ")
qc = QuantumCircuit(3, 1)
qc.rz(theta, [0])
quantum_circuit = load(qc)
- with pytest.raises(ValueError, match='The parameter {} was not bound correctly.'.format(theta)):
+ with pytest.raises(
+ ValueError, match="The parameter {} was not bound correctly.".format(theta)
+ ):
with recorder:
quantum_circuit(params={})
def test_invalid_parameter_expression(self, recorder):
"""Tests that an operation with multiple parameters raises an error."""
- theta = Parameter('θ')
- phi = Parameter('φ')
+ theta = Parameter("θ")
+ phi = Parameter("φ")
qc = QuantumCircuit(3, 1)
- qc.rz(theta*phi, [0])
+ qc.rz(theta * phi, [0])
quantum_circuit = load(qc)
- with pytest.raises(ValueError, match='PennyLane does not support expressions'):
+ with pytest.raises(ValueError, match="PennyLane does not support expressions"):
with recorder:
quantum_circuit(params={theta: 0, phi: 1})
@@ -245,8 +246,8 @@ def test_extra_parameters_were_passed(self, recorder):
"""Tests that loading raises an error when extra parameters were
passed."""
- theta = Parameter('θ')
- phi = Parameter('φ')
+ theta = Parameter("θ")
+ phi = Parameter("φ")
x = np.tensor(0.5, requires_grad=False)
y = np.tensor(0.3, requires_grad=False)
@@ -258,7 +259,10 @@ def test_extra_parameters_were_passed(self, recorder):
with recorder:
quantum_circuit(params={theta: x, phi: y})
- @pytest.mark.parametrize("qiskit_operation, pennylane_name", [(QuantumCircuit.crx, "CRX"), (QuantumCircuit.crz, "CRZ"), (QuantumCircuit.cry, "CRY")])
+ @pytest.mark.parametrize(
+ "qiskit_operation, pennylane_name",
+ [(QuantumCircuit.crx, "CRX"), (QuantumCircuit.crz, "CRZ"), (QuantumCircuit.cry, "CRY")],
+ )
def test_controlled_rotations(self, qiskit_operation, pennylane_name, recorder):
"""Tests loading a circuit with two qubit controlled rotations (except
for CRY)."""
@@ -268,7 +272,6 @@ def test_controlled_rotations(self, qiskit_operation, pennylane_name, recorder):
qiskit_operation(qc, 0.5, q2[0], q2[1])
-
quantum_circuit = load(qc)
with recorder:
@@ -298,27 +301,27 @@ def test_one_qubit_operations_supported_by_pennylane(self, recorder):
assert len(recorder.queue) == 6
- assert recorder.queue[0].name == 'PauliX'
+ assert recorder.queue[0].name == "PauliX"
assert recorder.queue[0].parameters == []
assert recorder.queue[0].wires == Wires(single_wire)
- assert recorder.queue[1].name == 'PauliY'
+ assert recorder.queue[1].name == "PauliY"
assert recorder.queue[1].parameters == []
assert recorder.queue[1].wires == Wires(single_wire)
- assert recorder.queue[2].name == 'PauliZ'
+ assert recorder.queue[2].name == "PauliZ"
assert recorder.queue[2].parameters == []
assert recorder.queue[2].wires == Wires(single_wire)
- assert recorder.queue[3].name == 'Hadamard'
+ assert recorder.queue[3].name == "Hadamard"
assert recorder.queue[3].parameters == []
assert recorder.queue[3].wires == Wires(single_wire)
- assert recorder.queue[4].name == 'S'
+ assert recorder.queue[4].name == "S"
assert recorder.queue[4].parameters == []
assert recorder.queue[4].wires == Wires(single_wire)
- assert recorder.queue[5].name == 'T'
+ assert recorder.queue[5].name == "T"
assert recorder.queue[5].parameters == []
assert recorder.queue[5].wires == Wires(single_wire)
@@ -345,23 +348,23 @@ def test_one_qubit_parametrized_operations_supported_by_pennylane(self, recorder
with recorder:
quantum_circuit()
- assert recorder.queue[0].name == 'PhaseShift'
+ assert recorder.queue[0].name == "PhaseShift"
assert recorder.queue[0].parameters == [angle]
assert recorder.queue[0].wires == Wires(single_wire)
- assert recorder.queue[1].name == 'RX'
+ assert recorder.queue[1].name == "RX"
assert recorder.queue[1].parameters == [angle]
assert recorder.queue[1].wires == Wires(single_wire)
- assert recorder.queue[2].name == 'RY'
+ assert recorder.queue[2].name == "RY"
assert recorder.queue[2].parameters == [angle]
assert recorder.queue[2].wires == Wires(single_wire)
- assert recorder.queue[3].name == 'RZ'
+ assert recorder.queue[3].name == "RZ"
assert recorder.queue[3].parameters == [angle]
assert recorder.queue[3].wires == Wires(single_wire)
- assert recorder.queue[4].name == 'U3'
+ assert recorder.queue[4].name == "U3"
assert len(recorder.queue[4].parameters) == 3
assert recorder.queue[4].parameters == [0.3, 0.4, 0.2]
assert recorder.queue[4].wires == Wires([0])
@@ -373,17 +376,13 @@ def test_two_qubit_operations_supported_by_pennylane(self, recorder):
qc = QuantumCircuit(2, 1)
- unitary_op = [[1, 0, 0, 0],
- [0, 0, 1j, 0],
- [0, 1j, 0, 0],
- [0, 0, 0, 1]]
+ unitary_op = [[1, 0, 0, 0], [0, 0, 1j, 0], [0, 1j, 0, 0], [0, 0, 0, 1]]
iswap_op = Operator(unitary_op)
-
qc.cx(*two_wires)
qc.cz(*two_wires)
qc.swap(*two_wires)
- qc.unitary(iswap_op, [0, 1], label='iswap')
+ qc.unitary(iswap_op, [0, 1], label="iswap")
quantum_circuit = load(qc)
with recorder:
@@ -391,19 +390,19 @@ def test_two_qubit_operations_supported_by_pennylane(self, recorder):
assert len(recorder.queue) == 4
- assert recorder.queue[0].name == 'CNOT'
+ assert recorder.queue[0].name == "CNOT"
assert recorder.queue[0].parameters == []
assert recorder.queue[0].wires == Wires(two_wires)
- assert recorder.queue[1].name == 'CZ'
+ assert recorder.queue[1].name == "CZ"
assert recorder.queue[1].parameters == []
assert recorder.queue[1].wires == Wires(two_wires)
- assert recorder.queue[2].name == 'SWAP'
+ assert recorder.queue[2].name == "SWAP"
assert recorder.queue[2].parameters == []
assert recorder.queue[2].wires == Wires(two_wires)
- assert recorder.queue[3].name == 'QubitUnitary'
+ assert recorder.queue[3].name == "QubitUnitary"
assert len(recorder.queue[3].parameters) == 1
assert np.array_equal(recorder.queue[3].parameters[0], np.array(unitary_op))
assert recorder.queue[3].wires == Wires(two_wires)
@@ -424,7 +423,7 @@ def test_two_qubit_parametrized_operations_supported_by_pennylane(self, recorder
assert len(recorder.queue) == 1
- assert recorder.queue[0].name == 'CRZ'
+ assert recorder.queue[0].name == "CRZ"
assert recorder.queue[0].parameters == [angle]
assert recorder.queue[0].wires == Wires(two_wires)
@@ -441,11 +440,11 @@ def test_three_qubit_operations_supported_by_pennylane(self, recorder):
with recorder:
quantum_circuit()
- assert recorder.queue[0].name == 'CSWAP'
+ assert recorder.queue[0].name == "CSWAP"
assert recorder.queue[0].parameters == []
assert recorder.queue[0].wires == Wires(three_wires)
- assert recorder.queue[1].name == 'Toffoli'
+ assert recorder.queue[1].name == "Toffoli"
assert len(recorder.queue[1].parameters) == 0
assert recorder.queue[1].wires == Wires(three_wires)
@@ -465,7 +464,7 @@ def test_wires_two_different_quantum_registers(self, recorder):
with recorder:
quantum_circuit()
- assert recorder.queue[0].name == 'CSWAP'
+ assert recorder.queue[0].name == "CSWAP"
assert recorder.queue[0].parameters == []
assert recorder.queue[0].wires == Wires(three_wires)
@@ -486,7 +485,7 @@ def test_wires_quantum_circuit_init_with_two_different_quantum_registers(self, r
with recorder:
quantum_circuit(wires=three_wires)
- assert recorder.queue[0].name == 'CSWAP'
+ assert recorder.queue[0].name == "CSWAP"
assert recorder.queue[0].parameters == []
assert recorder.queue[0].wires == Wires(three_wires)
@@ -506,7 +505,7 @@ def test_wires_pass_different_wires_than_for_circuit(self, recorder):
with recorder:
quantum_circuit(wires=three_wires)
- assert recorder.queue[0].name == 'CSWAP'
+ assert recorder.queue[0].name == "CSWAP"
assert recorder.queue[0].parameters == []
assert recorder.queue[0].wires == Wires(three_wires)
@@ -522,17 +521,17 @@ def test_operations_sdg_and_tdg(self, recorder):
with recorder:
quantum_circuit()
- assert recorder.queue[0].name == 'S.inv'
+ assert recorder.queue[0].name == "S.inv"
assert len(recorder.queue[0].parameters) == 0
assert recorder.queue[0].wires == Wires([0])
- assert recorder.queue[1].name == 'T.inv'
+ assert recorder.queue[1].name == "T.inv"
assert len(recorder.queue[1].parameters) == 0
assert recorder.queue[1].wires == Wires([0])
def test_operation_transformed_into_qubit_unitary(self, recorder):
"""Tests loading a circuit with operations that can be converted,
- but not natively supported by PennyLane."""
+ but not natively supported by PennyLane."""
qc = QuantumCircuit(3, 1)
@@ -542,14 +541,14 @@ def test_operation_transformed_into_qubit_unitary(self, recorder):
with recorder:
quantum_circuit()
- assert recorder.queue[0].name == 'QubitUnitary'
+ assert recorder.queue[0].name == "QubitUnitary"
assert len(recorder.queue[0].parameters) == 1
assert np.array_equal(recorder.queue[0].parameters[0], ex.CHGate().to_matrix())
assert recorder.queue[0].wires == Wires([0, 1])
def test_qiskit_gates_to_be_deprecated(self, recorder):
"""Tests the Qiskit gates that will be deprecated in an upcoming Qiskit version.
-
+
This test case can be removed once the gates are finally deprecated.
"""
qc = QuantumCircuit(1, 1)
@@ -574,15 +573,15 @@ def test_qiskit_gates_to_be_deprecated(self, recorder):
with recorder:
quantum_circuit()
- assert recorder.queue[0].name == 'U1'
+ assert recorder.queue[0].name == "U1"
assert recorder.queue[0].parameters == [0.1]
assert recorder.queue[0].wires == Wires(single_wire)
- assert recorder.queue[1].name == 'U2'
+ assert recorder.queue[1].name == "U2"
assert recorder.queue[1].parameters == [0.1, 0.2]
assert recorder.queue[1].wires == Wires(single_wire)
- assert recorder.queue[2].name == 'U3'
+ assert recorder.queue[2].name == "U3"
assert recorder.queue[2].parameters == [0.1, 0.2, 0.3]
assert recorder.queue[2].wires == Wires(single_wire)
@@ -606,7 +605,7 @@ def test_quantum_circuit_error_passing_parameters_not_required(self, recorder):
"""Tests the load method raises a QiskitError if arguments
that are not required were passed."""
- theta = Parameter('θ')
+ theta = Parameter("θ")
angle = np.tensor(0.5, requires_grad=False)
qc = QuantumCircuit(3, 1)
@@ -622,14 +621,16 @@ def test_quantum_circuit_error_parameter_not_bound(self, recorder):
"""Tests the load method for a QuantumCircuit raises a ValueError,
if one of the parameters was not bound correctly."""
- theta = Parameter('θ')
+ theta = Parameter("θ")
qc = QuantumCircuit(3, 1)
qc.rz(theta, [0])
quantum_circuit = load(qc)
- with pytest.raises(ValueError, match="The parameter {} was not bound correctly.".format(theta)):
+ with pytest.raises(
+ ValueError, match="The parameter {} was not bound correctly.".format(theta)
+ ):
with recorder:
quantum_circuit()
@@ -660,9 +661,11 @@ def test_wires_error_too_few_wires_specified(self, recorder):
quantum_circuit = load(qc)
- with pytest.raises(qml.QuantumFunctionError, match='The specified number of wires - {} - does not match the'
- ' number of wires the loaded quantum circuit acts on.'.
- format(len(only_two_wires))):
+ with pytest.raises(
+ qml.QuantumFunctionError,
+ match="The specified number of wires - {} - does not match the"
+ " number of wires the loaded quantum circuit acts on.".format(len(only_two_wires)),
+ ):
with recorder:
quantum_circuit(wires=only_two_wires)
@@ -681,9 +684,13 @@ def test_wires_error_too_many_wires_specified(self, recorder):
quantum_circuit = load(qc)
- with pytest.raises(qml.QuantumFunctionError, match="The specified number of wires - {} - does not match the"
- " number of wires the loaded quantum circuit acts on.".
- format(len(more_than_three_wires))):
+ with pytest.raises(
+ qml.QuantumFunctionError,
+ match="The specified number of wires - {} - does not match the"
+ " number of wires the loaded quantum circuit acts on.".format(
+ len(more_than_three_wires)
+ ),
+ ):
with recorder:
quantum_circuit(wires=more_than_three_wires)
@@ -698,7 +705,7 @@ def test_map_wires(self, recorder):
qc = QuantumCircuit(1)
qc_wires = [(q.register.name, q.index) for q in qc.qubits]
- assert map_wires(qc_wires, wires) == {0: ('q', 0)}
+ assert map_wires(qc_wires, wires) == {0: ("q", 0)}
def test_map_wires_instantiate_quantum_circuit_with_registers(self, recorder):
"""Tests the map_wires function for wires of a quantum circuit instantiated
@@ -743,9 +750,11 @@ def test_map_wires_exception_mismatch_in_number_of_wires(self, recorder):
qc = QuantumCircuit(1)
qc_wires = [(q.register.name, q.index) for q in qc.qubits]
- with pytest.raises(qml.QuantumFunctionError, match='The specified number of wires - {} - does not match '
- 'the number of wires the loaded quantum circuit acts on.'
- .format(len(wires))):
+ with pytest.raises(
+ qml.QuantumFunctionError,
+ match="The specified number of wires - {} - does not match "
+ "the number of wires the loaded quantum circuit acts on.".format(len(wires)),
+ ):
map_wires(wires, qc_wires)
@@ -766,25 +775,30 @@ def test_barrier_not_supported(self, recorder):
# check that only one warning was raised
assert len(record) == 1
# check that the message matches
- assert record[0].message.args[0] == "pennylane_qiskit.converter: The Barrier instruction is not supported by" \
- " PennyLane, and has not been added to the template."
+ assert (
+ record[0].message.args[0]
+ == "pennylane_qiskit.converter: The Barrier instruction is not supported by"
+ " PennyLane, and has not been added to the template."
+ )
class TestConverterQasm:
"""Tests that the converter.load function allows conversion from qasm."""
- qft_qasm = 'OPENQASM 2.0;' \
- 'include "qelib1.inc";' \
- 'qreg q[4];' \
- 'creg c[4];' \
- 'x q[0]; ' \
- 'x q[2];' \
- 'barrier q;' \
- 'h q[0];' \
- 'h q[1];' \
- 'h q[2];' \
- 'h q[3];' \
- 'measure q -> c;'
+ qft_qasm = (
+ "OPENQASM 2.0;"
+ 'include "qelib1.inc";'
+ "qreg q[4];"
+ "creg c[4];"
+ "x q[0]; "
+ "x q[2];"
+ "barrier q;"
+ "h q[0];"
+ "h q[1];"
+ "h q[2];"
+ "h q[3];"
+ "measure q -> c;"
+ )
@pytest.mark.skipif(sys.version_info < (3, 6), reason="tmpdir fixture requires Python >=3.6")
def test_qasm_from_file(self, tmpdir, recorder):
@@ -802,54 +816,60 @@ def test_qasm_from_file(self, tmpdir, recorder):
assert len(recorder.queue) == 6
- assert recorder.queue[0].name == 'PauliX'
+ assert recorder.queue[0].name == "PauliX"
assert recorder.queue[0].parameters == []
assert recorder.queue[0].wires == Wires([0])
- assert recorder.queue[1].name == 'PauliX'
+ assert recorder.queue[1].name == "PauliX"
assert recorder.queue[1].parameters == []
assert recorder.queue[1].wires == Wires([2])
- assert recorder.queue[2].name == 'Hadamard'
+ assert recorder.queue[2].name == "Hadamard"
assert recorder.queue[2].parameters == []
assert recorder.queue[2].wires == Wires([0])
- assert recorder.queue[3].name == 'Hadamard'
+ assert recorder.queue[3].name == "Hadamard"
assert recorder.queue[3].parameters == []
assert recorder.queue[3].wires == Wires([1])
- assert recorder.queue[4].name == 'Hadamard'
+ assert recorder.queue[4].name == "Hadamard"
assert recorder.queue[4].parameters == []
assert recorder.queue[4].wires == Wires([2])
- assert recorder.queue[5].name == 'Hadamard'
+ assert recorder.queue[5].name == "Hadamard"
assert recorder.queue[5].parameters == []
assert recorder.queue[5].wires == Wires([3])
assert len(record) == 5
# check that the message matches
- assert record[0].message.args[0] == "pennylane_qiskit.converter: The {} instruction is not supported by" \
- " PennyLane, and has not been added to the template."\
- .format('Barrier')
- assert record[1].message.args[0] == "pennylane_qiskit.converter: The {} instruction is not supported by" \
- " PennyLane, and has not been added to the template."\
- .format('Measure')
+ assert record[0].message.args[
+ 0
+ ] == "pennylane_qiskit.converter: The {} instruction is not supported by" " PennyLane, and has not been added to the template.".format(
+ "Barrier"
+ )
+ assert record[1].message.args[
+ 0
+ ] == "pennylane_qiskit.converter: The {} instruction is not supported by" " PennyLane, and has not been added to the template.".format(
+ "Measure"
+ )
def test_qasm_file_not_found_error(self):
"""Tests that an error is propagated, when a non-existing file is specified for parsing."""
- qft_qasm = 'some_qasm_file.qasm'
+ qft_qasm = "some_qasm_file.qasm"
with pytest.raises(FileNotFoundError):
load_qasm_from_file(qft_qasm)
def test_qasm_(self, recorder):
"""Tests that a QuantumCircuit object is deserialized from a qasm string."""
- qasm_string = 'include "qelib1.inc";' \
- 'qreg q[4];' \
- 'creg c[4];' \
- 'x q[0];' \
- 'cx q[2],q[0];'\
- 'measure q -> c;'
+ qasm_string = (
+ 'include "qelib1.inc";'
+ "qreg q[4];"
+ "creg c[4];"
+ "x q[0];"
+ "cx q[2],q[0];"
+ "measure q -> c;"
+ )
quantum_circuit = load_qasm(qasm_string)
@@ -859,17 +879,16 @@ def test_qasm_(self, recorder):
assert len(recorder.queue) == 2
- assert recorder.queue[0].name == 'PauliX'
+ assert recorder.queue[0].name == "PauliX"
assert recorder.queue[0].parameters == []
assert recorder.queue[0].wires == Wires([0])
- assert recorder.queue[1].name == 'CNOT'
+ assert recorder.queue[1].name == "CNOT"
assert recorder.queue[1].parameters == []
assert recorder.queue[1].wires == Wires([2, 0])
class TestConverterIntegration:
-
def test_use_loaded_circuit_in_qnode(self, qubit_device_2_wires):
"""Tests loading a converted template in a QNode."""
@@ -896,7 +915,7 @@ def test_load_circuit_inside_of_qnode(self, qubit_device_2_wires):
"""Tests loading a QuantumCircuit inside of the QNode circuit
definition."""
- theta = Parameter('θ')
+ theta = Parameter("θ")
angle = 0.5
qc = QuantumCircuit(2)
@@ -912,13 +931,12 @@ def circuit_native_pennylane():
qml.RZ(angle, wires=0)
return qml.expval(qml.PauliZ(0))
- assert circuit_loaded_qiskit_circuit() == \
- circuit_native_pennylane()
+ assert circuit_loaded_qiskit_circuit() == circuit_native_pennylane()
def test_passing_parameter_into_qnode(self, qubit_device_2_wires):
"""Tests passing a circuit parameter into the QNode."""
- theta = Parameter('θ')
+ theta = Parameter("θ")
rotation_angle = 0.5
qc = QuantumCircuit(2)
@@ -934,15 +952,16 @@ def circuit_native_pennylane(angle):
qml.RZ(angle, wires=0)
return qml.expval(qml.PauliZ(0))
- assert circuit_loaded_qiskit_circuit(rotation_angle) == \
- circuit_native_pennylane(rotation_angle)
+ assert circuit_loaded_qiskit_circuit(rotation_angle) == circuit_native_pennylane(
+ rotation_angle
+ )
def test_one_parameter_in_qc_one_passed_into_qnode(self, qubit_device_2_wires):
"""Tests passing a parameter by pre-defining it and then
- passing another to the QNode."""
+ passing another to the QNode."""
- theta = Parameter('θ')
- phi = Parameter('φ')
+ theta = Parameter("θ")
+ phi = Parameter("φ")
rotation_angle1 = 0.5
rotation_angle2 = 0.3
@@ -961,13 +980,14 @@ def circuit_native_pennylane(angle):
qml.RX(rotation_angle2, wires=0)
return qml.expval(qml.PauliZ(0))
- assert circuit_loaded_qiskit_circuit(rotation_angle1) == \
- circuit_native_pennylane(rotation_angle1)
+ assert circuit_loaded_qiskit_circuit(rotation_angle1) == circuit_native_pennylane(
+ rotation_angle1
+ )
def test_initialize_with_qubit_state_vector(self, qubit_device_single_wire):
"""Tests the QuantumCircuit.initialize method in a QNode."""
- prob_amplitudes = [1/np.sqrt(2), 1/np.sqrt(2)]
+ prob_amplitudes = [1 / np.sqrt(2), 1 / np.sqrt(2)]
qreg = QuantumRegister(2)
qc = QuantumCircuit(qreg)
@@ -985,9 +1005,9 @@ def circuit_native_pennylane():
assert circuit_loaded_qiskit_circuit() == circuit_native_pennylane()
- @pytest.mark.parametrize("analytic", [True])
+ @pytest.mark.parametrize("shots", [None])
@pytest.mark.parametrize("theta,phi,varphi", list(zip(THETA, PHI, VARPHI)))
- def test_gradient(self, theta, phi, varphi, analytic, tol):
+ def test_gradient(self, theta, phi, varphi, shots, tol):
"""Test that the gradient works correctly"""
qc = QuantumCircuit(3)
qiskit_params = [Parameter("param_{}".format(i)) for i in range(3)]
@@ -1001,7 +1021,7 @@ def test_gradient(self, theta, phi, varphi, analytic, tol):
# convert to a PennyLane circuit
qc_pl = qml.from_qiskit(qc)
- dev = qml.device("default.qubit", wires=3, analytic=analytic)
+ dev = qml.device("default.qubit", wires=3, shots=shots)
@qml.qnode(dev)
def circuit(params):
@@ -1014,13 +1034,13 @@ def circuit(params):
expected = [
np.cos(theta) * np.sin(phi) * np.sin(varphi),
np.sin(theta) * np.cos(phi) * np.sin(varphi),
- np.sin(theta) * np.sin(phi) * np.cos(varphi)
+ np.sin(theta) * np.sin(phi) * np.cos(varphi),
]
assert np.allclose(res, expected, **tol)
- @pytest.mark.parametrize("analytic", [True])
- def test_differentiable_param_is_array(self, analytic, tol):
+ @pytest.mark.parametrize("shots", [None])
+ def test_differentiable_param_is_array(self, shots, tol):
"""Test that extracting the differentiable parameters works correctly
for arrays"""
qc = QuantumCircuit(3)
@@ -1040,7 +1060,7 @@ def test_differentiable_param_is_array(self, analytic, tol):
# convert to a PennyLane circuit
qc_pl = qml.from_qiskit(qc)
- dev = qml.device("default.qubit", wires=3, analytic=analytic)
+ dev = qml.device("default.qubit", wires=3, shots=shots)
@qml.qnode(dev)
def circuit(params):
@@ -1053,7 +1073,7 @@ def circuit(params):
expected = [
np.cos(theta) * np.sin(phi) * np.sin(varphi),
np.sin(theta) * np.cos(phi) * np.sin(varphi),
- np.sin(theta) * np.sin(phi) * np.cos(varphi)
+ np.sin(theta) * np.sin(phi) * np.cos(varphi),
]
assert np.allclose(res, expected, **tol)
diff --git a/tests/test_expval.py b/tests/test_expval.py
index df396e799..d81dd682c 100644
--- a/tests/test_expval.py
+++ b/tests/test_expval.py
@@ -14,8 +14,7 @@
@pytest.mark.parametrize("theta, phi", list(zip(THETA, PHI)))
-@pytest.mark.parametrize("analytic", [True, False])
-@pytest.mark.parametrize("shots", [8192])
+@pytest.mark.parametrize("shots", [None, 8192])
@pytest.mark.usefixtures("skip_unitary")
class TestExpval:
"""Test expectation values"""
@@ -28,12 +27,8 @@ def test_identity_expectation(self, theta, phi, device, shots, tol):
O2 = qml.Identity(wires=[1])
dev.apply(
- [
- qml.RX(theta, wires=[0]),
- qml.RX(phi, wires=[1]),
- qml.CNOT(wires=[0, 1])
- ],
- rotations=[*O1.diagonalizing_gates(), *O2.diagonalizing_gates()]
+ [qml.RX(theta, wires=[0]), qml.RX(phi, wires=[1]), qml.CNOT(wires=[0, 1])],
+ rotations=[*O1.diagonalizing_gates(), *O2.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -48,12 +43,8 @@ def test_pauliz_expectation(self, theta, phi, device, shots, tol):
O2 = qml.PauliZ(wires=[1])
dev.apply(
- [
- qml.RX(theta, wires=[0]),
- qml.RX(phi, wires=[1]),
- qml.CNOT(wires=[0, 1])
- ],
- rotations=[*O1.diagonalizing_gates(), *O2.diagonalizing_gates()]
+ [qml.RX(theta, wires=[0]), qml.RX(phi, wires=[1]), qml.CNOT(wires=[0, 1])],
+ rotations=[*O1.diagonalizing_gates(), *O2.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -68,12 +59,8 @@ def test_paulix_expectation(self, theta, phi, device, shots, tol):
O2 = qml.PauliX(wires=[1])
dev.apply(
- [
- qml.RY(theta, wires=[0]),
- qml.RY(phi, wires=[1]),
- qml.CNOT(wires=[0, 1])
- ],
- rotations=[*O1.diagonalizing_gates(), *O2.diagonalizing_gates()]
+ [qml.RY(theta, wires=[0]), qml.RY(phi, wires=[1]), qml.CNOT(wires=[0, 1])],
+ rotations=[*O1.diagonalizing_gates(), *O2.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -88,12 +75,8 @@ def test_pauliy_expectation(self, theta, phi, device, shots, tol):
O2 = qml.PauliY(wires=[1])
dev.apply(
- [
- qml.RX(theta, wires=[0]),
- qml.RX(phi, wires=[1]),
- qml.CNOT(wires=[0, 1])
- ],
- rotations=[*O1.diagonalizing_gates(), *O2.diagonalizing_gates()]
+ [qml.RX(theta, wires=[0]), qml.RX(phi, wires=[1]), qml.CNOT(wires=[0, 1])],
+ rotations=[*O1.diagonalizing_gates(), *O2.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -108,12 +91,8 @@ def test_hadamard_expectation(self, theta, phi, device, shots, tol):
O2 = qml.Hadamard(wires=[1])
dev.apply(
- [
- qml.RY(theta, wires=[0]),
- qml.RY(phi, wires=[1]),
- qml.CNOT(wires=[0, 1])
- ],
- rotations=[*O1.diagonalizing_gates(), *O2.diagonalizing_gates()]
+ [qml.RY(theta, wires=[0]), qml.RY(phi, wires=[1]), qml.CNOT(wires=[0, 1])],
+ rotations=[*O1.diagonalizing_gates(), *O2.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -131,12 +110,8 @@ def test_hermitian_expectation(self, theta, phi, device, shots, tol):
O2 = qml.Hermitian(A, wires=[1])
dev.apply(
- [
- qml.RY(theta, wires=[0]),
- qml.RY(phi, wires=[1]),
- qml.CNOT(wires=[0, 1])
- ],
- rotations=[*O1.diagonalizing_gates(), *O2.diagonalizing_gates()]
+ [qml.RY(theta, wires=[0]), qml.RY(phi, wires=[1]), qml.CNOT(wires=[0, 1])],
+ rotations=[*O1.diagonalizing_gates(), *O2.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -167,12 +142,8 @@ def test_multi_qubit_hermitian_expectation(self, theta, phi, device, shots, tol)
O1 = qml.Hermitian(A, wires=[0, 1])
dev.apply(
- [
- qml.RY(theta, wires=[0]),
- qml.RY(phi, wires=[1]),
- qml.CNOT(wires=[0, 1])
- ],
- rotations=[*O1.diagonalizing_gates()]
+ [qml.RY(theta, wires=[0]), qml.RY(phi, wires=[1]), qml.CNOT(wires=[0, 1])],
+ rotations=[*O1.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -192,8 +163,7 @@ def test_multi_qubit_hermitian_expectation(self, theta, phi, device, shots, tol)
@pytest.mark.parametrize("theta,phi,varphi", list(zip(THETA, PHI, VARPHI)))
-@pytest.mark.parametrize("analytic", [True, False])
-@pytest.mark.parametrize("shots", [8192])
+@pytest.mark.parametrize("shots", [None, 8192])
class TestTensorExpval:
"""Test tensor expectation values"""
@@ -209,9 +179,9 @@ def test_paulix_pauliy(self, theta, phi, varphi, device, shots, tol):
qml.RX(phi, wires=[1]),
qml.RX(varphi, wires=[2]),
qml.CNOT(wires=[0, 1]),
- qml.CNOT(wires=[1, 2])
+ qml.CNOT(wires=[1, 2]),
],
- rotations=obs.diagonalizing_gates()
+ rotations=obs.diagonalizing_gates(),
)
dev._samples = dev.generate_samples()
@@ -233,15 +203,15 @@ def test_pauliz_identity(self, theta, phi, varphi, device, shots, tol):
qml.RX(phi, wires=[1]),
qml.RX(varphi, wires=[2]),
qml.CNOT(wires=[0, 1]),
- qml.CNOT(wires=[1, 2])
+ qml.CNOT(wires=[1, 2]),
],
- rotations=obs.diagonalizing_gates()
+ rotations=obs.diagonalizing_gates(),
)
dev._samples = dev.generate_samples()
res = dev.expval(obs)
- expected = np.cos(varphi)*np.cos(phi)
+ expected = np.cos(varphi) * np.cos(phi)
assert np.allclose(res, expected, **tol)
@@ -257,9 +227,9 @@ def test_pauliz_hadamard_pauliy(self, theta, phi, varphi, device, shots, tol):
qml.RX(phi, wires=[1]),
qml.RX(varphi, wires=[2]),
qml.CNOT(wires=[0, 1]),
- qml.CNOT(wires=[1, 2])
+ qml.CNOT(wires=[1, 2]),
],
- rotations=obs.diagonalizing_gates()
+ rotations=obs.diagonalizing_gates(),
)
dev._samples = dev.generate_samples()
@@ -289,9 +259,9 @@ def test_hermitian(self, theta, phi, varphi, device, shots, tol):
qml.RX(phi, wires=[1]),
qml.RX(varphi, wires=[2]),
qml.CNOT(wires=[0, 1]),
- qml.CNOT(wires=[1, 2])
+ qml.CNOT(wires=[1, 2]),
],
- rotations=obs.diagonalizing_gates()
+ rotations=obs.diagonalizing_gates(),
)
dev._samples = dev.generate_samples()
@@ -309,8 +279,7 @@ def test_hermitian_hermitian(self, theta, phi, varphi, device, shots, tol):
"""Test that a tensor product involving two Hermitian matrices works
correctly"""
dev = device(3)
- A1 = np.array([[1, 2],
- [2, 4]])
+ A1 = np.array([[1, 2], [2, 4]])
A2 = np.array(
[
@@ -328,9 +297,9 @@ def test_hermitian_hermitian(self, theta, phi, varphi, device, shots, tol):
qml.RX(phi, wires=[1]),
qml.RX(varphi, wires=[2]),
qml.CNOT(wires=[0, 1]),
- qml.CNOT(wires=[1, 2])
+ qml.CNOT(wires=[1, 2]),
],
- rotations=obs.diagonalizing_gates()
+ rotations=obs.diagonalizing_gates(),
)
dev._samples = dev.generate_samples()
@@ -340,7 +309,8 @@ def test_hermitian_hermitian(self, theta, phi, varphi, device, shots, tol):
+ 4 * np.cos(phi) * np.sin(theta)
+ 3 * np.cos(varphi) * (-10 + 4 * np.cos(phi) * np.sin(theta) - 3 * np.sin(phi))
- 3 * np.sin(phi)
- - 2 * (5 + np.cos(phi) * (6 + 4 * np.sin(theta)) + (-3 + 8 * np.sin(theta)) * np.sin(phi))
+ - 2
+ * (5 + np.cos(phi) * (6 + 4 * np.sin(theta)) + (-3 + 8 * np.sin(theta)) * np.sin(phi))
* np.sin(varphi)
+ np.cos(theta)
* (
@@ -366,7 +336,7 @@ def test_hermitian_identity_expectation(self, theta, phi, varphi, device, shots,
qml.RY(phi, wires=[1]),
qml.CNOT(wires=[0, 1]),
],
- rotations=obs.diagonalizing_gates()
+ rotations=obs.diagonalizing_gates(),
)
dev._samples = dev.generate_samples()
diff --git a/tests/test_ibmq.py b/tests/test_ibmq.py
index 2c4eb2486..c3ab7558d 100644
--- a/tests/test_ibmq.py
+++ b/tests/test_ibmq.py
@@ -30,6 +30,7 @@ def test_load_from_env(token, monkeypatch):
dev = IBMQDevice(wires=1)
assert dev.provider.credentials.is_ibmq()
+
def test_load_kwargs_takes_precedence(token, monkeypatch):
"""Test that with a potentially valid token stored as an environment
variable, passing the token as a keyword argument takes precedence."""
@@ -37,6 +38,7 @@ def test_load_kwargs_takes_precedence(token, monkeypatch):
dev = IBMQDevice(wires=1, ibmqx_token=token)
assert dev.provider.credentials.is_ibmq()
+
def test_account_already_loaded(token):
"""Test loading an IBMQ device using
an already loaded account"""
@@ -44,6 +46,7 @@ def test_account_already_loaded(token):
dev = IBMQDevice(wires=1)
assert dev.provider.credentials.is_ibmq()
+
class MockQiskitDeviceInit:
"""A mocked version of the QiskitDevice __init__ method which
is called on by the IBMQDevice"""
@@ -53,6 +56,7 @@ def mocked_init(self, wires, provider, backend, shots, **kwargs):
called with."""
self.provider = provider
+
def test_custom_provider(monkeypatch):
"""Tests that a custom provider can be passed when creating an IBMQ
device."""
@@ -60,20 +64,22 @@ def test_custom_provider(monkeypatch):
mock_qiskit_device = MockQiskitDeviceInit()
with monkeypatch.context() as m:
- m.setattr(ibmq.QiskitDevice, "__init__",mock_qiskit_device.mocked_init)
+ m.setattr(ibmq.QiskitDevice, "__init__", mock_qiskit_device.mocked_init)
m.setattr(ibmq.IBMQ, "enable_account", lambda *args, **kwargs: None)
# Here mocking to a value such that it is not None
m.setattr(ibmq.IBMQ, "active_account", lambda *args, **kwargs: True)
- dev = IBMQDevice(wires=2, backend='ibmq_qasm_simulator', provider=mock_provider)
+ dev = IBMQDevice(wires=2, backend="ibmq_qasm_simulator", provider=mock_provider)
assert mock_qiskit_device.provider == mock_provider
+
def mock_get_provider(*args, **kwargs):
"""A mock function for the get_provider Qiskit function to record the
arguments which it was called with."""
return (args, kwargs)
+
def test_default_provider(monkeypatch):
"""Tests that the default provider is used when no custom provider was
specified."""
@@ -86,10 +92,11 @@ def test_default_provider(monkeypatch):
# Here mocking to a value such that it is not None
m.setattr(ibmq.IBMQ, "active_account", lambda *args, **kwargs: True)
- dev = IBMQDevice(wires=2, backend='ibmq_qasm_simulator')
+ dev = IBMQDevice(wires=2, backend="ibmq_qasm_simulator")
assert mock_qiskit_device.provider[0] == ()
- assert mock_qiskit_device.provider[1] == {'hub': 'ibm-q', 'group': 'open', 'project': 'main'}
+ assert mock_qiskit_device.provider[1] == {"hub": "ibm-q", "group": "open", "project": "main"}
+
def test_custom_provider_hub_group_project(monkeypatch):
"""Tests that the custom arguments passed during device instantiation are
@@ -107,10 +114,20 @@ def test_custom_provider_hub_group_project(monkeypatch):
# Here mocking to a value such that it is not None
m.setattr(ibmq.IBMQ, "active_account", lambda *args, **kwargs: True)
- dev = IBMQDevice(wires=2, backend='ibmq_qasm_simulator', hub=custom_hub, group=custom_group, project=custom_project)
+ dev = IBMQDevice(
+ wires=2,
+ backend="ibmq_qasm_simulator",
+ hub=custom_hub,
+ group=custom_group,
+ project=custom_project,
+ )
assert mock_qiskit_device.provider[0] == ()
- assert mock_qiskit_device.provider[1] == {'hub': custom_hub, 'group': custom_group, 'project': custom_project}
+ assert mock_qiskit_device.provider[1] == {
+ "hub": custom_hub,
+ "group": custom_group,
+ "project": custom_project,
+ }
def test_load_from_disk(token):
@@ -129,7 +146,6 @@ def test_account_error(monkeypatch):
IBMQDevice(wires=1)
-@pytest.mark.parametrize("analytic", [False])
@pytest.mark.parametrize("shots", [1000])
def test_simple_circuit(token, tol, shots):
IBMQ.enable_account(token)
@@ -150,13 +166,12 @@ def circuit(theta, phi):
assert np.allclose(res, expected, **tol)
-@pytest.mark.parametrize("analytic", [False])
@pytest.mark.parametrize("shots", [1000])
def test_probability(token, tol, shots):
"""Test that the probs function works."""
IBMQ.enable_account(token)
dev = IBMQDevice(wires=2, backend="ibmq_qasm_simulator", shots=shots)
- dev_analytic = qml.device("default.qubit", wires=2, analytic=True)
+ dev_analytic = qml.device("default.qubit", wires=2, shots=None)
x = [0.2, 0.5]
diff --git a/tests/test_integration.py b/tests/test_integration.py
index f4f6ceb1d..3c91380f4 100644
--- a/tests/test_integration.py
+++ b/tests/test_integration.py
@@ -41,18 +41,19 @@ def test_args(self):
with pytest.raises(TypeError, match="missing 1 required positional argument"):
qml.device("qiskit.aer")
- with pytest.raises(qml.DeviceError, match="specified number of shots needs to be at least 1"):
+ with pytest.raises(
+ qml.DeviceError, match="specified number of shots needs to be at least 1"
+ ):
qml.device("qiskit.aer", backend="qasm_simulator", wires=1, shots=0)
@pytest.mark.parametrize("d", pldevices)
- @pytest.mark.parametrize("analytic", [True, False])
- @pytest.mark.parametrize("shots", [8192])
- def test_one_qubit_circuit(self, shots, analytic, d, backend, tol):
+ @pytest.mark.parametrize("shots", [None, 8192])
+ def test_one_qubit_circuit(self, shots, d, backend, tol):
"""Test that devices provide correct result for a simple circuit"""
- if backend not in state_backends and analytic:
+ if backend not in state_backends and shots is None:
pytest.skip("Hardware simulators do not support analytic mode")
- dev = qml.device(d[0], wires=1, backend=backend, shots=shots, analytic=analytic)
+ dev = qml.device(d[0], wires=1, backend=backend, shots=shots)
a = 0.543
b = 0.123
@@ -69,12 +70,10 @@ def circuit(x, y, z):
assert np.allclose(circuit(a, b, c), np.cos(a) * np.sin(b), **tol)
@pytest.mark.parametrize("d", pldevices)
- @pytest.mark.parametrize("analytic", [False])
@pytest.mark.parametrize("shots", [8192])
- def test_one_qubit_circuit(self, shots, analytic, d, backend, tol):
- """Integration test for the Basisstate and Rot operations for when analytic
- is False"""
- dev = qml.device(d[0], wires=1, backend=backend, shots=shots, analytic=analytic)
+ def test_one_qubit_circuit(self, shots, d, backend, tol):
+ """Integration test for the BasisState and Rot operations for non-analytic mode."""
+ dev = qml.device(d[0], wires=1, backend=backend, shots=shots)
a = 0
b = 0
@@ -105,11 +104,11 @@ def ansatz(weights):
return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
dev_qsk = qml.device(
- "qiskit.aer",
- wires=n_qubits,
- shots=1000,
- backend="qasm_simulator",
- )
+ "qiskit.aer",
+ wires=n_qubits,
+ shots=1000,
+ backend="qasm_simulator",
+ )
weights = np.random.random((depth, n_qubits)).flatten()
@@ -119,6 +118,7 @@ def ansatz(weights):
exp_sampled(weights)
grad_shift(weights)
+
class TestKeywordArguments:
"""Test keyword argument logic is correct"""
@@ -135,9 +135,11 @@ def test_noise_model_qasm_simulator(self, monkeypatch):
cache = []
with monkeypatch.context() as m:
- m.setattr(aer.QasmSimulator, "set_options", lambda *args, **kwargs: cache.append(kwargs))
+ m.setattr(
+ aer.QasmSimulator, "set_options", lambda *args, **kwargs: cache.append(kwargs)
+ )
dev = qml.device("qiskit.aer", wires=2, noise_model="test value")
- assert cache[0] == {'noise_model': 'test value'}
+ assert cache[0] == {"noise_model": "test value"}
def test_invalid_noise_model(self):
"""Test that the noise model argument causes an exception to be raised
@@ -147,7 +149,7 @@ def test_invalid_noise_model(self):
def test_overflow_kwargs(self):
"""Test all overflow kwargs are extracted for the AerDevice"""
- dev = qml.device('qiskit.aer', wires=2, k1="v1", k2="v2")
+ dev = qml.device("qiskit.aer", wires=2, k1="v1", k2="v2")
assert dev.run_args["k1"] == "v1"
assert dev.run_args["k2"] == "v2"
@@ -156,23 +158,20 @@ class TestLoadIntegration:
"""Integration tests for the PennyLane load function. This test ensures that the PennyLane-Qiskit
specific load functions integrate properly with the PennyLane-Qiskit plugin."""
- hadamard_qasm = 'OPENQASM 2.0;' \
- 'include "qelib1.inc";' \
- 'qreg q[1];' \
- 'h q[0];'
+ hadamard_qasm = "OPENQASM 2.0;" 'include "qelib1.inc";' "qreg q[1];" "h q[0];"
def test_load_qiskit_circuit(self):
"""Test that the default load function works correctly."""
- theta = qiskit.circuit.Parameter('θ')
+ theta = qiskit.circuit.Parameter("θ")
qc = qiskit.QuantumCircuit(2)
qc.rx(theta, 0)
- my_template = qml.load(qc, format='qiskit')
+ my_template = qml.load(qc, format="qiskit")
- dev = qml.device('default.qubit', wires=2)
+ dev = qml.device("default.qubit", wires=2)
- angles = np.array([0.53896774, 0.79503606, 0.27826503, 0.])
+ angles = np.array([0.53896774, 0.79503606, 0.27826503, 0.0])
@qml.qnode(dev)
def loaded_quantum_circuit(angle):
@@ -190,7 +189,7 @@ def quantum_circuit(angle):
def test_load_from_qasm_string(self):
"""Test that quantum circuits can be loaded from a qasm string."""
- dev = qml.device('default.qubit', wires=2)
+ dev = qml.device("default.qubit", wires=2)
@qml.qnode(dev)
def loaded_quantum_circuit():
@@ -214,7 +213,7 @@ def test_load_qasm_from_file(self, tmpdir):
hadamard = qml.from_qasm_file(apply_hadamard)
- dev = qml.device('default.qubit', wires=2)
+ dev = qml.device("default.qubit", wires=2)
@qml.qnode(dev)
def loaded_quantum_circuit():
@@ -232,9 +231,8 @@ def quantum_circuit():
class TestPLOperations:
"""Integration tests for checking certain PennyLane specific operations."""
- @pytest.mark.parametrize("shots", [1000])
- @pytest.mark.parametrize("analytic", [True, False])
- def test_rotation(self, init_state, state_vector_device, shots, analytic, tol):
+ @pytest.mark.parametrize("shots", [None, 1000])
+ def test_rotation(self, init_state, state_vector_device, shots, tol):
"""Test that the QubitStateVector and Rot operations are decomposed using a
Qiskit device with statevector backend"""
@@ -267,11 +265,12 @@ def qubitstatevector_and_rot():
qubitstatevector_and_rot()
- assert np.allclose(np.abs(dev.state) ** 2, np.abs(rz(c) @ ry(b) @ rz(a) @ state) ** 2, **tol)
+ assert np.allclose(
+ np.abs(dev.state) ** 2, np.abs(rz(c) @ ry(b) @ rz(a) @ state) ** 2, **tol
+ )
- @pytest.mark.parametrize("shots", [1000])
- @pytest.mark.parametrize("analytic", [True, False])
- def test_basisstate(self, init_state, state_vector_device, shots, analytic, tol):
+ @pytest.mark.parametrize("shots", [None, 1000])
+ def test_basisstate(self, init_state, state_vector_device, shots, tol):
"""Test that the Basisstate is decomposed using a Qiskit device with
statevector backend"""
@@ -285,14 +284,13 @@ def basisstate():
basisstate()
- expected_state = np.zeros(2**dev.num_wires)
+ expected_state = np.zeros(2 ** dev.num_wires)
expected_state[2] = 1
assert np.allclose(np.abs(dev.state) ** 2, np.abs(expected_state) ** 2, **tol)
- @pytest.mark.parametrize("shots", [1000])
- @pytest.mark.parametrize("analytic", [True, False])
- def test_basisstate_init_all_zero_states(self, init_state, state_vector_device, shots, analytic, tol):
+ @pytest.mark.parametrize("shots", [None, 1000])
+ def test_basisstate_init_all_zero_states(self, init_state, state_vector_device, shots, tol):
"""Test that the Basisstate that receives the all zero state is decomposed using
a Qiskit device with statevector backend"""
@@ -306,7 +304,7 @@ def basisstate():
basisstate()
- expected_state = np.zeros(2**dev.num_wires)
+ expected_state = np.zeros(2 ** dev.num_wires)
expected_state[0] = 1
assert np.allclose(np.abs(dev.state) ** 2, np.abs(expected_state) ** 2, **tol)
@@ -386,7 +384,7 @@ def circuit(phi=None):
phi = tensor([[0.04439891, 0.14490549, 3.29725643, 2.51240058]])
- with qml._queuing.OperationRecorder() as rec:
+ with qml.tape.OperationRecorder() as rec:
circuit(phi=phi)
for i in range(phi.shape[1]):
@@ -410,8 +408,7 @@ def circuit(phi=None):
phi = tensor([[0.04439891, 0.14490549, 3.29725643]])
-
- with qml._queuing.OperationRecorder() as rec:
+ with qml.tape.OperationRecorder() as rec:
circuit(phi=phi)
# Test the rotation applied
@@ -425,17 +422,18 @@ def circuit(phi=None):
assert isinstance(rec.queue[0].parameters[2], tensor)
+
class TestInverses:
"""Integration tests checking that the inverse of the operations are applied."""
def test_inverse_of_operation(self):
"""Test that the inverse of operations works as expected
by comparing a simple circuit with default.qubit."""
- dev = qml.device('default.qubit', wires=2)
+ dev = qml.device("default.qubit", wires=2)
- dev2 = qml.device('qiskit.aer', backend='statevector_simulator', shots=5, wires=2, analytic=True)
+ dev2 = qml.device("qiskit.aer", backend="statevector_simulator", shots=None, wires=2)
- angles = np.array([0.53896774, 0.79503606, 0.27826503, 0.])
+ angles = np.array([0.53896774, 0.79503606, 0.27826503, 0.0])
@qml.qnode(dev)
def circuit_with_inverses(angle):
@@ -452,18 +450,19 @@ def circuit_with_inverses_default_qubit(angle):
for x in angles:
assert np.allclose(circuit_with_inverses(x), circuit_with_inverses_default_qubit(x))
+
class TestNoise:
"""Integration test for the noise models."""
def test_noise_applied(self):
"""Test that the qiskit noise model is applied correctly"""
noise_model = aer.noise.NoiseModel()
- bit_flip = aer.noise.pauli_error([('X', 1), ('I', 0)])
+ bit_flip = aer.noise.pauli_error([("X", 1), ("I", 0)])
# Create a noise model where the RX operation always flips the bit
noise_model.add_all_qubit_quantum_error(bit_flip, ["rx"])
- dev = qml.device('qiskit.aer', wires=2, noise_model=noise_model)
+ dev = qml.device("qiskit.aer", wires=2, noise_model=noise_model)
@qml.qnode(dev)
def circuit():
diff --git a/tests/test_inverses.py b/tests/test_inverses.py
index 621a500bf..5edfe3a10 100644
--- a/tests/test_inverses.py
+++ b/tests/test_inverses.py
@@ -13,21 +13,24 @@ class TestInverses:
"""Tests that the inverse of the operations are applied."""
# This test is ran against the state |0> with one Z expval
- @pytest.mark.parametrize("name,expected_output", [
- ("PauliX", -1),
- ("PauliY", -1),
- ("PauliZ", 1),
- ("Hadamard", 0),
- ("S", 1),
- ("T", 1),
- ])
+ @pytest.mark.parametrize(
+ "name,expected_output",
+ [
+ ("PauliX", -1),
+ ("PauliY", -1),
+ ("PauliZ", 1),
+ ("Hadamard", 0),
+ ("S", 1),
+ ("T", 1),
+ ],
+ )
def test_supported_gate_inverse_single_wire_no_parameters(self, name, expected_output):
"""Tests the inverse of supported gates that act on a single wire that are not
parameterized"""
op = getattr(qml.ops, name)
- dev = qml.device('qiskit.aer', backend='statevector_simulator', wires=2, analytic=True)
+ dev = qml.device("qiskit.aer", backend="statevector_simulator", wires=2, shots=None)
@qml.qnode(dev)
def circuit():
@@ -37,37 +40,43 @@ def circuit():
assert np.isclose(circuit(), expected_output, atol=tol, rtol=0)
# This test is ran against the state |Phi+> with two Z expvals
- @pytest.mark.parametrize("name,expected_output", [
- ("CNOT", [-1/2, 1]),
- ("SWAP", [-1/2, -1/2]),
- ("CZ", [-1/2, -1/2]),
- ])
+ @pytest.mark.parametrize(
+ "name,expected_output",
+ [
+ ("CNOT", [-1 / 2, 1]),
+ ("SWAP", [-1 / 2, -1 / 2]),
+ ("CZ", [-1 / 2, -1 / 2]),
+ ],
+ )
def test_supported_gate_inverse_two_wires_no_parameters(self, name, expected_output):
"""Tests the inverse of supported gates that act on two wires that are not parameterized"""
op = getattr(qml.ops, name)
- dev = qml.device('qiskit.aer', backend='statevector_simulator', wires=2, analytic=True)
+ dev = qml.device("qiskit.aer", backend="statevector_simulator", wires=2, shots=None)
assert dev.supports_operation(name)
@qml.qnode(dev)
def circuit():
- qml.QubitStateVector(np.array([1/2, 0, 0, math.sqrt(3)/2]), wires=[0, 1])
+ qml.QubitStateVector(np.array([1 / 2, 0, 0, math.sqrt(3) / 2]), wires=[0, 1])
op(wires=[0, 1]).inv()
return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))
assert np.allclose(circuit(), expected_output, atol=tol, rtol=0)
- @pytest.mark.parametrize("name,expected_output", [
- ("CSWAP", [-1, -1, 1]),
- ])
+ @pytest.mark.parametrize(
+ "name,expected_output",
+ [
+ ("CSWAP", [-1, -1, 1]),
+ ],
+ )
def test_supported_gate_inverse_three_wires_no_parameters(self, name, expected_output):
"""Tests the inverse of supported gates that act on three wires that are not parameterized"""
op = getattr(qml.ops, name)
- dev = qml.device('qiskit.aer', backend='statevector_simulator', wires=3, analytic=True)
+ dev = qml.device("qiskit.aer", backend="statevector_simulator", wires=3, shots=None)
assert dev.supports_operation(name)
@@ -80,22 +89,47 @@ def circuit():
assert np.allclose(circuit(), expected_output, atol=tol, rtol=0)
# This test is ran on the state |0> with one Z expvals
- @pytest.mark.parametrize("name,par,expected_output", [
- ("PhaseShift", [math.pi/2], 1),
- ("PhaseShift", [-math.pi/4], 1),
- ("RX", [math.pi/2], 0),
- ("RX", [-math.pi/4], 1/math.sqrt(2)),
- ("RY", [math.pi/2], 0),
- ("RY", [-math.pi/4], 1/math.sqrt(2)),
- ("RZ", [math.pi/2], 1),
- ("RZ", [-math.pi/4], 1),
- ("QubitUnitary", [np.array([[1j/math.sqrt(2), 1j/math.sqrt(2)], [1j/math.sqrt(2), -1j/math.sqrt(2)]])], 0),
- ("QubitUnitary", [np.array([[-1j/math.sqrt(2), 1j/math.sqrt(2)], [1j/math.sqrt(2), 1j/math.sqrt(2)]])], 0),
- ])
+ @pytest.mark.parametrize(
+ "name,par,expected_output",
+ [
+ ("PhaseShift", [math.pi / 2], 1),
+ ("PhaseShift", [-math.pi / 4], 1),
+ ("RX", [math.pi / 2], 0),
+ ("RX", [-math.pi / 4], 1 / math.sqrt(2)),
+ ("RY", [math.pi / 2], 0),
+ ("RY", [-math.pi / 4], 1 / math.sqrt(2)),
+ ("RZ", [math.pi / 2], 1),
+ ("RZ", [-math.pi / 4], 1),
+ (
+ "QubitUnitary",
+ [
+ np.array(
+ [
+ [1j / math.sqrt(2), 1j / math.sqrt(2)],
+ [1j / math.sqrt(2), -1j / math.sqrt(2)],
+ ]
+ )
+ ],
+ 0,
+ ),
+ (
+ "QubitUnitary",
+ [
+ np.array(
+ [
+ [-1j / math.sqrt(2), 1j / math.sqrt(2)],
+ [1j / math.sqrt(2), 1j / math.sqrt(2)],
+ ]
+ )
+ ],
+ 0,
+ ),
+ ],
+ )
def test_supported_gate_inverse_single_wire_with_parameters(self, name, par, expected_output):
"""Test the inverse of single gates with parameters"""
- dev = qml.device('qiskit.aer', backend='statevector_simulator', wires=2, analytic=True)
+ dev = qml.device("qiskit.aer", backend="statevector_simulator", wires=2, shots=None)
op = getattr(qml.ops, name)
@@ -109,17 +143,46 @@ def circuit():
assert np.isclose(circuit(), expected_output, atol=tol, rtol=0)
# This test is ran against the state 1/2|00>+sqrt(3)/2|11> with two Z expvals
- @pytest.mark.parametrize("name,par,expected_output", [
- ("CRZ", [0], [-1/2, -1/2]),
- ("CRZ", [-math.pi], [-1/2, -1/2]),
- ("CRZ", [math.pi/2], [-1/2, -1/2]),
- ("QubitUnitary", [np.array([[1, 0, 0, 0], [0, 1/math.sqrt(2), 1/math.sqrt(2), 0], [0, 1/math.sqrt(2), -1/math.sqrt(2), 0], [0, 0, 0, 1]])], [-1/2, -1/2]),
- ("QubitUnitary", [np.array([[-1, 0, 0, 0], [0, 1/math.sqrt(2), 1/math.sqrt(2), 0], [0, 1/math.sqrt(2), -1/math.sqrt(2), 0], [0, 0, 0, -1]])], [-1/2, -1/2]),
- ])
+ @pytest.mark.parametrize(
+ "name,par,expected_output",
+ [
+ ("CRZ", [0], [-1 / 2, -1 / 2]),
+ ("CRZ", [-math.pi], [-1 / 2, -1 / 2]),
+ ("CRZ", [math.pi / 2], [-1 / 2, -1 / 2]),
+ (
+ "QubitUnitary",
+ [
+ np.array(
+ [
+ [1, 0, 0, 0],
+ [0, 1 / math.sqrt(2), 1 / math.sqrt(2), 0],
+ [0, 1 / math.sqrt(2), -1 / math.sqrt(2), 0],
+ [0, 0, 0, 1],
+ ]
+ )
+ ],
+ [-1 / 2, -1 / 2],
+ ),
+ (
+ "QubitUnitary",
+ [
+ np.array(
+ [
+ [-1, 0, 0, 0],
+ [0, 1 / math.sqrt(2), 1 / math.sqrt(2), 0],
+ [0, 1 / math.sqrt(2), -1 / math.sqrt(2), 0],
+ [0, 0, 0, -1],
+ ]
+ )
+ ],
+ [-1 / 2, -1 / 2],
+ ),
+ ],
+ )
def test_supported_gate_inverse_two_wires_with_parameters(self, name, par, expected_output):
"""Tests the inverse of supported gates that act on two wires that are parameterized"""
- dev = qml.device('qiskit.aer', backend='statevector_simulator', wires=2, analytic=True)
+ dev = qml.device("qiskit.aer", backend="statevector_simulator", wires=2, shots=None)
op = getattr(qml.ops, name)
@@ -127,24 +190,27 @@ def test_supported_gate_inverse_two_wires_with_parameters(self, name, par, expec
@qml.qnode(dev)
def circuit():
- qml.QubitStateVector(np.array([1/2, 0, 0, math.sqrt(3)/2]), wires=[0, 1])
+ qml.QubitStateVector(np.array([1 / 2, 0, 0, math.sqrt(3) / 2]), wires=[0, 1])
op(*np.negative(par), wires=[0, 1]).inv()
return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))
assert np.allclose(circuit(), expected_output, atol=tol, rtol=0)
- @pytest.mark.parametrize("name,par,expected_output", [
- ("Rot", [math.pi/2, 0, 0], 1),
- ("Rot", [0, math.pi/2, 0], 0),
- ("Rot", [0, 0, math.pi/2], 1),
- ("Rot", [math.pi/2, -math.pi/4, -math.pi/4], 1/math.sqrt(2)),
- ("Rot", [-math.pi/4, math.pi/2, math.pi/4], 0),
- ("Rot", [-math.pi/4, math.pi/4, math.pi/2], 1/math.sqrt(2)),
- ])
+ @pytest.mark.parametrize(
+ "name,par,expected_output",
+ [
+ ("Rot", [math.pi / 2, 0, 0], 1),
+ ("Rot", [0, math.pi / 2, 0], 0),
+ ("Rot", [0, 0, math.pi / 2], 1),
+ ("Rot", [math.pi / 2, -math.pi / 4, -math.pi / 4], 1 / math.sqrt(2)),
+ ("Rot", [-math.pi / 4, math.pi / 2, math.pi / 4], 0),
+ ("Rot", [-math.pi / 4, math.pi / 4, math.pi / 2], 1 / math.sqrt(2)),
+ ],
+ )
def test_unsupported_gate_inverses(self, name, par, expected_output):
"""Test the inverse of single gates with parameters"""
- dev = qml.device('qiskit.aer', backend='statevector_simulator', wires=2, analytic=True)
+ dev = qml.device("qiskit.aer", backend="statevector_simulator", wires=2, shots=None)
op = getattr(qml.ops, name)
@@ -155,13 +221,13 @@ def circuit():
assert np.isclose(circuit(), expected_output, atol=tol, rtol=0)
- @pytest.mark.parametrize("par", [np.pi/i for i in range(1, 5)])
+ @pytest.mark.parametrize("par", [np.pi / i for i in range(1, 5)])
def test_s_gate_inverses(self, par):
"""Tests the inverse of the S gate"""
- dev = qml.device('qiskit.aer', backend='statevector_simulator', wires=2, analytic=True)
+ dev = qml.device("qiskit.aer", backend="statevector_simulator", wires=2, shots=None)
- expected_output = -0.5 * 1j * cmath.exp(-1j*par)*(-1 + cmath.exp(2j*par))
+ expected_output = -0.5 * 1j * cmath.exp(-1j * par) * (-1 + cmath.exp(2j * par))
@qml.qnode(dev)
def circuit():
@@ -172,11 +238,11 @@ def circuit():
assert np.allclose(circuit(), expected_output, atol=tol, rtol=0)
- @pytest.mark.parametrize("par", [np.pi/i for i in range(1, 5)])
+ @pytest.mark.parametrize("par", [np.pi / i for i in range(1, 5)])
def test_t_gate_inverses(self, par):
"""Tests the inverse of the T gate"""
- dev = qml.device('qiskit.aer', backend='statevector_simulator', wires=2, analytic=True)
+ dev = qml.device("qiskit.aer", backend="statevector_simulator", wires=2, shots=None)
expected_output = -math.sin(par) / math.sqrt(2)
diff --git a/tests/test_qiskit_device.py b/tests/test_qiskit_device.py
index 51fb48898..bf8714985 100644
--- a/tests/test_qiskit_device.py
+++ b/tests/test_qiskit_device.py
@@ -7,15 +7,12 @@
test_transpile_options = [
{},
- {'optimization_level':2},
- {'optimization_level':2, 'seed_transpiler':22}
+ {"optimization_level": 2},
+ {"optimization_level": 2, "seed_transpiler": 22},
]
-test_device_options = [
- {},
- {'optimization_level':3},
- {'optimization_level':1}
-]
+test_device_options = [{}, {"optimization_level": 3}, {"optimization_level": 1}]
+
class TestProbabilities:
"""Tests for the probability function"""
@@ -23,16 +20,16 @@ class TestProbabilities:
def test_probability_no_results(self):
"""Test that the probabilities function returns
None if no job has yet been run."""
- dev = AerDevice(backend="statevector_simulator", wires=1, analytic=True)
+ dev = AerDevice(backend="statevector_simulator", wires=1, shots=None)
assert dev.probability() is None
-@pytest.mark.parametrize("analytic", [True])
-@pytest.mark.parametrize("wires", [1,2,3])
-@pytest.mark.parametrize("shots", [2])
+
+@pytest.mark.parametrize("wires", [1, 2, 3])
+@pytest.mark.parametrize("shots", [None])
@pytest.mark.parametrize("device_options", test_device_options)
@pytest.mark.transpile_args_test
class TestTranspilationOptionInitialization:
- """Tests for passing the transpilation options to qiskit at time of device
+ """Tests for passing the transpilation options to qiskit at time of device
initialization."""
def test_device_with_transpilation_options(self, device, wires, device_options):
@@ -48,33 +45,39 @@ def test_transpilation_option_update(self, device, wires, device_options, transp
dev.set_transpile_args(**transpile_options)
assert dev.transpile_args == transpile_options
+
class TestAnalyticWarningHWSimulator:
"""Tests the warnings for when the analytic attribute of a device is set to true"""
def test_warning_raised_for_hardware_backend_analytic_expval(self, hardware_backend, recorder):
"""Tests that a warning is raised if the analytic attribute is true on
- hardware simulators when calculating the expectation"""
+ hardware simulators when calculating the expectation"""
with pytest.warns(UserWarning) as record:
- dev = qml.device("qiskit.basicaer", backend=hardware_backend, wires=2, analytic=True)
+ dev = qml.device("qiskit.basicaer", backend=hardware_backend, wires=2, shots=None)
# check that only one warning was raised
assert len(record) == 1
# check that the message matches
- assert record[0].message.args[0] == "The analytic calculation of "\
- "expectations, variances and probabilities is only supported on "\
- "statevector backends, not on the {}. Such statistics obtained from this "\
- "device are estimates based on samples.".format(dev.backend)
-
- def test_no_warning_raised_for_software_backend_analytic_expval(self, statevector_backend, recorder, recwarn):
+ assert (
+ record[0].message.args[0] == "The analytic calculation of "
+ "expectations, variances and probabilities is only supported on "
+ "statevector backends, not on the {}. Such statistics obtained from this "
+ "device are estimates based on samples.".format(dev.backend)
+ )
+
+ def test_no_warning_raised_for_software_backend_analytic_expval(
+ self, statevector_backend, recorder, recwarn
+ ):
"""Tests that no warning is raised if the analytic attribute is true on
- statevector simulators when calculating the expectation"""
+ statevector simulators when calculating the expectation"""
- dev = qml.device("qiskit.basicaer", backend=statevector_backend, wires=2, analytic=True)
+ dev = qml.device("qiskit.basicaer", backend=statevector_backend, wires=2, shots=None)
# check that no warnings were raised
assert len(recwarn) == 0
+
class TestAerBackendOptions:
"""Test the backend options of Aer backends."""
@@ -82,13 +85,13 @@ def test_backend_options_cleaned(self):
"""Test that the backend options are cleared upon new Aer device
initialization."""
noise_model = noise.NoiseModel()
- bit_flip = noise.pauli_error([('X', 1), ('I', 0)])
+ bit_flip = noise.pauli_error([("X", 1), ("I", 0)])
# Create a noise model where the RX operation always flips the bit
noise_model.add_all_qubit_quantum_error(bit_flip, ["rx"])
- dev = qml.device('qiskit.aer', wires=2, noise_model=noise_model)
- assert 'noise_model' in dev.backend.options
+ dev = qml.device("qiskit.aer", wires=2, noise_model=noise_model)
+ assert "noise_model" in dev.backend.options
- dev2 = qml.device('qiskit.aer', wires=2)
- assert 'noise_model' not in dev2.backend.options
+ dev2 = qml.device("qiskit.aer", wires=2)
+ assert "noise_model" not in dev2.backend.options
diff --git a/tests/test_sample.py b/tests/test_sample.py
index c7dd9a1ef..fee7286d1 100644
--- a/tests/test_sample.py
+++ b/tests/test_sample.py
@@ -15,7 +15,6 @@
VARPHI = np.linspace(0.02, 1, 3)
-@pytest.mark.parametrize("analytic", [False])
@pytest.mark.parametrize("shots", [8192])
class TestSample:
"""Tests for the sample return type"""
@@ -33,7 +32,7 @@ def test_sample_values(self, device, shots, tol):
[
qml.RX(par, wires=[0]),
],
- rotations=[*observable.diagonalizing_gates()]
+ rotations=[*observable.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -58,7 +57,7 @@ def test_sample_values_hermitian(self, theta, device, shots, tol):
[
qml.RX(theta, wires=[0]),
],
- rotations=[*observable.diagonalizing_gates()]
+ rotations=[*observable.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -95,12 +94,8 @@ def test_sample_values_hermitian_multi_qubit(self, theta, device, shots, tol):
observable = qml.Hermitian(A, wires=[0, 1])
dev.apply(
- [
- qml.RX(theta, wires=[0]),
- qml.RY(2 * theta, wires=[1]),
- qml.CNOT(wires=[0, 1])
- ],
- rotations=[*observable.diagonalizing_gates()]
+ [qml.RX(theta, wires=[0]), qml.RY(2 * theta, wires=[1]), qml.CNOT(wires=[0, 1])],
+ rotations=[*observable.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -126,7 +121,6 @@ def test_sample_values_hermitian_multi_qubit(self, theta, device, shots, tol):
@pytest.mark.parametrize("theta, phi, varphi", list(zip(THETA, PHI, VARPHI)))
-@pytest.mark.parametrize("analytic", [False])
@pytest.mark.parametrize("shots", [8192])
class TestTensorSample:
"""Test tensor expectation values"""
@@ -143,9 +137,9 @@ def test_paulix_pauliy(self, theta, phi, varphi, device, shots, tol):
qml.RX(phi, wires=[1]),
qml.RX(varphi, wires=[2]),
qml.CNOT(wires=[0, 1]),
- qml.CNOT(wires=[1, 2])
+ qml.CNOT(wires=[1, 2]),
],
- rotations=[*observable.diagonalizing_gates()]
+ rotations=[*observable.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -182,9 +176,9 @@ def test_pauliz_hadamard_pauliy(self, theta, phi, varphi, device, shots, tol):
qml.RX(phi, wires=[1]),
qml.RX(varphi, wires=[2]),
qml.CNOT(wires=[0, 1]),
- qml.CNOT(wires=[1, 2])
+ qml.CNOT(wires=[1, 2]),
],
- rotations=[*observable.diagonalizing_gates()]
+ rotations=[*observable.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -227,9 +221,9 @@ def test_hermitian(self, theta, phi, varphi, device, shots, tol):
qml.RX(phi, wires=[1]),
qml.RX(varphi, wires=[2]),
qml.CNOT(wires=[0, 1]),
- qml.CNOT(wires=[1, 2])
+ qml.CNOT(wires=[1, 2]),
],
- rotations=[*observable.diagonalizing_gates()]
+ rotations=[*observable.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
diff --git a/tests/test_var.py b/tests/test_var.py
index 6b680275d..e82bbef2a 100644
--- a/tests/test_var.py
+++ b/tests/test_var.py
@@ -16,8 +16,7 @@
@pytest.mark.parametrize("theta, phi", list(zip(THETA, PHI)))
-@pytest.mark.parametrize("analytic", [True, False])
-@pytest.mark.parametrize("shots", [8192])
+@pytest.mark.parametrize("shots", [None, 8192])
class TestVar:
"""Tests for the variance"""
@@ -33,7 +32,7 @@ def test_var(self, theta, phi, device, shots, tol):
qml.RX(phi, wires=[0]),
qml.RY(theta, wires=[0]),
],
- rotations=[*observable.diagonalizing_gates()]
+ rotations=[*observable.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -57,7 +56,7 @@ def test_var_hermitian(self, theta, phi, device, shots, tol):
qml.RX(phi, wires=[0]),
qml.RY(theta, wires=[0]),
],
- rotations=[*observable.diagonalizing_gates()]
+ rotations=[*observable.diagonalizing_gates()],
)
dev._samples = dev.generate_samples()
@@ -74,8 +73,7 @@ def test_var_hermitian(self, theta, phi, device, shots, tol):
@pytest.mark.parametrize("theta, phi, varphi", list(zip(THETA, PHI, VARPHI)))
-@pytest.mark.parametrize("analytic", [True, False])
-@pytest.mark.parametrize("shots", [8192])
+@pytest.mark.parametrize("shots", [None, 8192])
class TestTensorVar:
"""Tests for variance of tensor observables"""
@@ -90,9 +88,9 @@ def test_paulix_pauliy(self, theta, phi, varphi, device, shots, tol):
qml.RX(phi, wires=[1]),
qml.RX(varphi, wires=[2]),
qml.CNOT(wires=[0, 1]),
- qml.CNOT(wires=[1, 2])
+ qml.CNOT(wires=[1, 2]),
],
- rotations=obs.diagonalizing_gates()
+ rotations=obs.diagonalizing_gates(),
)
dev._samples = dev.generate_samples()
@@ -120,9 +118,9 @@ def test_pauliz_hadamard_pauliy(self, theta, phi, varphi, device, shots, tol):
qml.RX(phi, wires=[1]),
qml.RX(varphi, wires=[2]),
qml.CNOT(wires=[0, 1]),
- qml.CNOT(wires=[1, 2])
+ qml.CNOT(wires=[1, 2]),
],
- rotations=obs.diagonalizing_gates()
+ rotations=obs.diagonalizing_gates(),
)
dev._samples = dev.generate_samples()
@@ -157,9 +155,9 @@ def test_hermitian(self, theta, phi, varphi, device, shots, tol):
qml.RX(phi, wires=[1]),
qml.RX(varphi, wires=[2]),
qml.CNOT(wires=[0, 1]),
- qml.CNOT(wires=[1, 2])
+ qml.CNOT(wires=[1, 2]),
],
- rotations=obs.diagonalizing_gates()
+ rotations=obs.diagonalizing_gates(),
)
dev._samples = dev.generate_samples()