Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example added BasicSim docs that shows default shots #549

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,16 @@

### Documentation 📝

* The documentation for `qiskit.basicsim` and `qiskit.aer` device have been updated with a mention that
they must be used in finite-shot mode.
[(#549)](https://github.com/PennyLaneAI/pennylane-qiskit/pull/549)

### Bug fixes 🐛

* The `qiskit.basicsim` and `qiskit.aer` device (with the `aer_simulator` backend) now raise a warning
when `shots=None` and change the number of shots to `shots=1024`.
[(#549)](https://github.com/PennyLaneAI/pennylane-qiskit/pull/549)

### Contributors ✍️

This release contains contributions from (in alphabetical order):
Expand Down
3 changes: 3 additions & 0 deletions doc/devices/aer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ You can instantiate a ``'qiskit.aer'`` device for PennyLane with:
import pennylane as qml
dev = qml.device('qiskit.aer', wires=2)

This device must be used in finite-shots mode with the ``aer_simulator`` backend. If ``shots=None`` in this setting,
it will be overwritten to ``shots=1024``.

This device can then be used just like other devices for the definition and evaluation of QNodes within PennyLane.
A simple quantum function that returns the expectation value of a measurement and depends on three classical input
parameters would look like:
Expand Down
3 changes: 2 additions & 1 deletion doc/devices/basicsim.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ that can be accessed in this plugin through:

This device uses the Qiskit ``BasicSimulator`` backend from the
`basic_provider <https://docs.quantum.ibm.com/api/qiskit/providers_basic_provider>`_ module in Qiskit.
This device must be used in finite-shots mode. If ``shots=None``, it will be overwritten to ``shots=1024``.

.. note::

The `Qiskit Aer <https://qiskit.github.io/qiskit-aer/>`_ device
provides a fast simulator that is also capable of simulating
noise. It is available as :ref:`"qiskit.aer" <aer device page>`, but the backend must be
installed separately with ``pip install qiskit-aer``.


6 changes: 3 additions & 3 deletions pennylane_qiskit/basic_aer.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class BasicAerDevice(QiskitDevice):

short_name = "qiskit.basicaer"

def __init__(self, wires, shots=1024, backend="qasm_simulator", **kwargs):
def __init__(self, wires, shots=None, backend="qasm_simulator", **kwargs):

max_ver = Version("0.46", partial=True)

Expand Down Expand Up @@ -93,10 +93,10 @@ class BasicSimulatorDevice(QiskitDevice):
analytic_warning_message = (
"The plugin does not currently support analytic calculation of expectations, variances "
"and probabilities with the BasicProvider backend {}. Such statistics obtained from this "
"device are estimates based on samples."
"device are estimates based on samples. The simulation will be run with shots=1024."
)

def __init__(self, wires, shots=1024, backend="basic_simulator", **kwargs):
def __init__(self, wires, shots=None, backend="basic_simulator", **kwargs):

min_version = Version("1.0.0")

Expand Down
1 change: 1 addition & 0 deletions pennylane_qiskit/qiskit_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class QiskitDevice(QubitDevice, abc.ABC):
"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."
"The simulation will be run with shots=1024."
)

_eigs = {}
Expand Down
56 changes: 44 additions & 12 deletions tests/test_qiskit_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ class TestSupportForV1andV2:
)
def test_v1_and_v2_mocked(self, dev_backend):
"""Test that device initializes with no error mocked"""
dev = qml.device("qiskit.remote", wires=10, backend=dev_backend, use_primitives=True)
dev = qml.device(
"qiskit.remote", wires=10, backend=dev_backend, use_primitives=True
)
assert dev._backend == dev_backend

@pytest.mark.parametrize(
Expand All @@ -120,7 +122,9 @@ def test_v1_and_v2_mocked(self, dev_backend):
)
def test_v1_and_v2_manila(self, dev_backend):
"""Test that device initializes with no error with V1 and V2 backends by Qiskit"""
dev = qml.device("qiskit.remote", wires=5, backend=dev_backend, use_primitives=True)
dev = qml.device(
"qiskit.remote", wires=5, backend=dev_backend, use_primitives=True
)

@qml.qnode(dev)
def circuit(x):
Expand Down Expand Up @@ -156,7 +160,9 @@ def test_device_with_transpilation_options(self, device, wires, device_options):
assert dev.transpile_args == device_options

@pytest.mark.parametrize("transpile_options", test_transpile_options)
def test_transpilation_option_update(self, device, wires, device_options, transpile_options):
def test_transpilation_option_update(
self, device, wires, device_options, transpile_options
):
"""Test that the transpilation options are updated as expected."""
dev = device(wires, device_options)
assert dev.transpile_args == device_options
Expand All @@ -167,22 +173,46 @@ def test_transpilation_option_update(self, device, wires, device_options, transp
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, recorder):
testcases_warning_raised_for_hardware_backend_analytic_expval = [
(
"qiskit.aer",
"aer_simulator",
(
"The analytic calculation of expectations, variances and "
"probabilities is only supported on statevector backends, not on the aer_simulator. "
"Such statistics obtained from this device are estimates based on samples."
"The simulation will be run with shots=1024."
),
),
(
"qiskit.basicsim",
"basic_simulator",
(
"The plugin does not currently support analytic calculation of expectations, variances "
"and probabilities with the BasicProvider backend basic_simulator. Such statistics obtained from this "
"device are estimates based on samples. The simulation will be run with shots=1024."
),
),
]

@pytest.mark.parametrize(
"device_backend_msg",
testcases_warning_raised_for_hardware_backend_analytic_expval,
)
def test_warning_raised_for_hardware_backend_analytic_expval(
self, device_backend_msg, recorder
):
isaacdevlugt marked this conversation as resolved.
Show resolved Hide resolved
"""Tests that a warning is raised if the analytic attribute is true on
hardware simulators when calculating the expectation"""

with pytest.warns(UserWarning) as record:
dev = qml.device("qiskit.aer", backend="aer_simulator", wires=2, shots=None)
shortname, backend, msg = device_backend_msg
dev = qml.device(shortname, backend=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 "
f"statevector backends, not on the {dev.backend.name}. Such statistics obtained from this "
"device are estimates based on samples."
)
assert record[0].message.args[0] == msg

@pytest.mark.parametrize("method", ["unitary", "statevector"])
def test_no_warning_raised_for_software_backend_analytic_expval(
Expand All @@ -191,7 +221,9 @@ def test_no_warning_raised_for_software_backend_analytic_expval(
"""Tests that no warning is raised if the analytic attribute is true on
statevector simulators when calculating the expectation"""

_ = qml.device("qiskit.aer", backend="aer_simulator", method=method, wires=2, shots=None)
_ = qml.device(
"qiskit.aer", backend="aer_simulator", method=method, wires=2, shots=None
)

# check that no warnings were raised
assert len(recwarn) == 0
Expand Down