Skip to content

Commit

Permalink
Fixes a bug where backend_options would be passed to backends that …
Browse files Browse the repository at this point in the history
…don't support it. (#51)

* fix backend options argument

* update link in changelog

* added tests

* Update tests/test_integration.py
  • Loading branch information
josh146 authored Sep 14, 2019
1 parent 9aed690 commit 68f6969
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 28 deletions.
16 changes: 7 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
# Release 0.6.0-dev

### New features since last release

### Breaking changes

### Improvements

### Documentation
# Release 0.5.1

### Bug fixes

* Fixed a bug where backend keyword arguments, such as `backend_options`
and `noise_model`, were being passed to backends that did not support it.
[#51](https://github.com/XanaduAI/pennylane-qiskit/pull/51)

### Contributors

This release contains contributions from (in alphabetical order):

Josh Izaac

---

# Release 0.5.0
Expand Down
2 changes: 1 addition & 1 deletion pennylane_qiskit/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
Version number (major.minor.patch[-label])
"""

__version__ = "0.6.0-dev"
__version__ = "0.5.1"
17 changes: 3 additions & 14 deletions pennylane_qiskit/aer.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,30 +54,19 @@ class AerDevice(QiskitDevice):
Args:
wires (int): The number of qubits of the device
backend (str): the desired backend
noise_model (NoiseModel): NoiseModel Object from ``qiskit.providers.aer.noise``
shots (int): number of circuit evaluations/random samples used
to estimate expectation values and variances of observables
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.
noise_model (NoiseModel): NoiseModel Object from ``qiskit.providers.aer.noise``
"""

# pylint: disable=too-many-arguments

short_name = "qiskit.aer"

def __init__(self, wires, shots=1024, backend="qasm_simulator", noise_model=None, **kwargs):
super().__init__(wires, qiskit.Aer, backend=backend, shots=shots, **kwargs)
self._noise_model = noise_model

def run(self, qobj):
"""Run the compiled circuit, and query the result."""
self._current_job = self.backend.run(
qobj, noise_model=self._noise_model, backend_options=self.kwargs
)
result = self._current_job.result()

if self.backend_name in self._state_backends:
self._state = self._get_state(result)
def __init__(self, wires, shots=1024, backend="qasm_simulator", **kwargs):
super().__init__(wires, provider=qiskit.Aer, backend=backend, shots=shots, **kwargs)
2 changes: 2 additions & 0 deletions pennylane_qiskit/ibmq.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class IBMQDevice(QiskitDevice):
variable ``IBMQX_TOKEN`` is used.
ibmqx_url (str): The IBM Q URL. If not provided, the environment
variable ``IBMQX_URL`` is used, followed by the default URL.
noise_model (NoiseModel): NoiseModel Object from ``qiskit.providers.aer.noise``.
Only applicable for simulator backends.
"""

short_name = "qiskit.ibmq"
Expand Down
24 changes: 20 additions & 4 deletions pennylane_qiskit/qiskit_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import abc
from collections import OrderedDict
import functools
import inspect
import itertools

import numpy as np
Expand Down Expand Up @@ -138,9 +139,6 @@ def __init__(self, wires, provider, backend, shots=1024, **kwargs):

self.provider = provider
self.backend_name = backend
self.compile_backend = kwargs.get("compile_backend")
self.kwargs = kwargs

self._capabilities["backend"] = [b.name() for b in self.provider.backends()]

# check that backend exists
Expand Down Expand Up @@ -173,6 +171,24 @@ def __init__(self, wires, provider, backend, shots=1024, **kwargs):
# job execution options
self.memory = False # do not return samples, just counts

# determine if backend supports backend options and noise models,
# and properly put together backend run arguments
s = inspect.signature(b.run)
self.run_args = {}
self.compile_backend = None

if "compile_backend" in kwargs:
self.compile_backend = kwargs.pop("compile_backend")

if "noise_model" in kwargs:
if "noise_model" in s.parameters:
self.run_args["noise_model"] = kwargs.pop("noise_model")
else:
raise ValueError("Backend {} does not support noisy simulations".format(backend))

if "backend_options" in s.parameters:
self.run_args["backend_options"] = kwargs

self.reset()

@property
Expand Down Expand Up @@ -228,7 +244,7 @@ def compile(self):

def run(self, qobj):
"""Run the compiled circuit, and query the result."""
self._current_job = self.backend.run(qobj, backend_options=self.kwargs)
self._current_job = self.backend.run(qobj, **self.run_args)
result = self._current_job.result()

if self.backend_name in self._state_backends:
Expand Down
30 changes: 30 additions & 0 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,33 @@ def circuit(x, y, z):
return qml.expval(qml.PauliZ(0))

assert np.allclose(circuit(a, b, c), np.cos(a) * np.sin(b), **tol)


class TestKeywordArguments:
"""Test keyword argument logic is correct"""

@pytest.mark.parametrize("d", pldevices)
def test_compile_backend(self, d):
"""Test that the compile backend argument is properly
extracted"""
dev = qml.device(d[0], wires=2, compile_backend="test value")
assert dev.compile_backend == "test value"

def test_noise_model(self):
"""Test that the noise model argument is properly
extracted if the backend supports it"""
dev = qml.device("qiskit.aer", wires=2, noise_model="test value")
assert dev.run_args["noise_model"] == "test value"

def test_invalid_noise_model(self):
"""Test that the noise model argument causes an exception to be raised
if the backend does not support it"""
with pytest.raises(ValueError, match="does not support noisy simulations"):
dev = qml.device("qiskit.basicaer", wires=2, noise_model="test value")

@pytest.mark.parametrize("d", pldevices)
def test_overflow_backend_options(self, d):
"""Test all overflow backend options are extracted"""
dev = qml.device(d[0], wires=2, k1="v1", k2="v2")
assert dev.run_args["backend_options"]["k1"] == "v1"
assert dev.run_args["backend_options"]["k2"] == "v2"

0 comments on commit 68f6969

Please sign in to comment.