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

Add circuit-runner, sampler and custom VQE programs from Qiskit-Runtime #157

Merged
merged 108 commits into from
Jan 29, 2022
Merged
Show file tree
Hide file tree
Changes from 96 commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
80d4aa6
Small change.
rmoyard Nov 8, 2021
214c73c
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane-qiskit
rmoyard Nov 8, 2021
9966609
First commit
rmoyard Nov 10, 2021
ab18c94
Working circuit runner.
rmoyard Nov 10, 2021
ab0a0b8
Sampler
rmoyard Nov 12, 2021
932d3a3
Sampler
rmoyard Nov 15, 2021
cdea955
VQE is working.
rmoyard Nov 18, 2021
7fae255
Headers.
rmoyard Nov 18, 2021
c1c3d92
Merge branch 'master' into runtime
rmoyard Nov 24, 2021
3d49dcd
Merge branch 'runtime' of https://github.com/PennyLaneAI/pennylane-qi…
rmoyard Nov 24, 2021
435ba38
Update for batches.
rmoyard Nov 24, 2021
e3e8f8f
Merge branch 'master' into runtime
rmoyard Nov 24, 2021
8052111
Update docstrigs.
rmoyard Nov 24, 2021
0566bb6
CodeFactor.
rmoyard Nov 24, 2021
daacdf6
Add tests for runtime.
rmoyard Nov 24, 2021
5fb777f
Tests.
rmoyard Nov 24, 2021
9150ca3
Test.
rmoyard Nov 24, 2021
b2d3805
Test circuit runner.
rmoyard Nov 25, 2021
a099016
Test Sampler.
rmoyard Nov 25, 2021
4f6da61
Correct generate_samples
rmoyard Nov 25, 2021
279e6ea
Add entry points.
rmoyard Nov 25, 2021
a23243d
More shots.
rmoyard Nov 25, 2021
91553eb
Add token arg.
rmoyard Nov 25, 2021
74168e4
Change import
rmoyard Nov 25, 2021
bb237ed
Change Sampler sample.
rmoyard Nov 25, 2021
46975ce
Circuit runner kwargs test.
rmoyard Nov 25, 2021
c41d514
Shots kwargs
rmoyard Nov 25, 2021
e186e6b
Change import.
rmoyard Nov 26, 2021
b29b0a5
Add kwargs Sampler test.
rmoyard Nov 26, 2021
cb24721
Import.
rmoyard Nov 26, 2021
5fb9d98
Impport again.
rmoyard Nov 26, 2021
2b67ca4
Import change
rmoyard Nov 26, 2021
53b9bfc
Add test tracker.
rmoyard Nov 26, 2021
1edd0f3
Update track tests.
rmoyard Nov 26, 2021
f18f054
Update tracker runtime.
rmoyard Nov 26, 2021
4f70d76
Update tracker.
rmoyard Nov 26, 2021
ca2f0b8
Update.
rmoyard Nov 28, 2021
ce3e066
Codfactor changes.
rmoyard Nov 28, 2021
c08dae2
Update.
rmoyard Nov 29, 2021
4d1dab9
Update codefactor
rmoyard Nov 29, 2021
72a7370
More codefactor.
rmoyard Nov 29, 2021
3da46a5
Add callback
rmoyard Nov 29, 2021
30aa0a5
Update
rmoyard Nov 29, 2021
0b42e21
Move vqe
rmoyard Nov 30, 2021
1e819a0
Update.
rmoyard Nov 30, 2021
66c0863
Add test VQE.
rmoyard Nov 30, 2021
ee0e85c
Update.
rmoyard Nov 30, 2021
968a6d0
delete
rmoyard Nov 30, 2021
cc4e850
Update VQE test.
rmoyard Nov 30, 2021
4244a02
Add shots.
rmoyard Nov 30, 2021
bf61439
Update test
rmoyard Nov 30, 2021
b4c5322
Update delete
rmoyard Nov 30, 2021
cb136be
Unused import.
rmoyard Nov 30, 2021
b90b578
More iteration.
rmoyard Nov 30, 2021
755c5b6
m
rmoyard Nov 30, 2021
82ca03c
Change tol.
rmoyard Nov 30, 2021
f84f626
More VQE tests.
rmoyard Dec 1, 2021
769839e
Black
rmoyard Dec 1, 2021
815f914
Update.
rmoyard Dec 1, 2021
b0f1566
Update.
rmoyard Dec 1, 2021
7377184
Update
rmoyard Dec 1, 2021
6ceb4cb
Merge branch 'master' into runtime
rmoyard Dec 16, 2021
bd4a6cd
Update pennylane_qiskit/vqe/__init__.py
rmoyard Dec 16, 2021
8cc49b9
Update from review.
rmoyard Dec 16, 2021
1c5418c
Merge branch 'runtime' of https://github.com/PennyLaneAI/pennylane-qi…
rmoyard Dec 16, 2021
4060e86
Update tests.
rmoyard Dec 16, 2021
9371b5c
Typo.
rmoyard Dec 16, 2021
3fe12aa
Update from tests.
rmoyard Dec 17, 2021
e19a4fd
Merge branch 'master' into runtime
rmoyard Jan 6, 2022
f2c1e5f
Runtime updated.
rmoyard Jan 6, 2022
0f14fb8
Runtime updated.
rmoyard Jan 6, 2022
8a01df4
Update vqe
rmoyard Jan 7, 2022
b59109f
Update
rmoyard Jan 19, 2022
2f19bbe
Update from Antal review.
rmoyard Jan 20, 2022
225595b
Update
rmoyard Jan 20, 2022
ecacbda
Black.
rmoyard Jan 20, 2022
1836f54
More test.
rmoyard Jan 21, 2022
e8a1a00
Update parameters
rmoyard Jan 21, 2022
e770834
Codefactor update.
rmoyard Jan 21, 2022
c6691be
Update.
rmoyard Jan 21, 2022
2a017e8
Update.
rmoyard Jan 21, 2022
8919c9c
Change order jac.
rmoyard Jan 21, 2022
9b5845b
Typo.
rmoyard Jan 21, 2022
7a45f47
Params.
rmoyard Jan 21, 2022
43d4548
Update tests.
rmoyard Jan 24, 2022
3e0142e
ValueError.
rmoyard Jan 24, 2022
b41800e
print
rmoyard Jan 24, 2022
ea1ac2a
Update.
rmoyard Jan 24, 2022
da07dcf
Tol.
rmoyard Jan 24, 2022
5057ed8
Update review.
rmoyard Jan 25, 2022
273716b
Add doc.
rmoyard Jan 25, 2022
b26ccae
Unused variable.
rmoyard Jan 25, 2022
c2a82bc
Merge branch 'master' into runtime
rmoyard Jan 27, 2022
82e7a81
Update tests.
rmoyard Jan 27, 2022
d068d8c
Merge branch 'runtime' of https://github.com/PennyLaneAI/pennylane-qi…
rmoyard Jan 27, 2022
f90a191
Update params.
rmoyard Jan 27, 2022
7c5959d
Update review.
rmoyard Jan 27, 2022
66b3464
Readd mthree
rmoyard Jan 27, 2022
8706215
Typo.
rmoyard Jan 27, 2022
0fefc19
Path.
rmoyard Jan 28, 2022
49dafa3
Black
rmoyard Jan 28, 2022
796aad1
Change path.
rmoyard Jan 28, 2022
ecc609e
Update runtime_programs/vqe_runtime_program.py
antalszava Jan 28, 2022
dd16b51
Update doc/devices/runtime.rst
rmoyard Jan 28, 2022
d481b0b
Update review.
rmoyard Jan 28, 2022
75b535b
coverarc
antalszava Jan 28, 2022
f237431
coverarc omit + skip IBMQ and Runtime tests
antalszava Jan 28, 2022
81afdde
Changelog
rmoyard Jan 28, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions doc/devices/runtime.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
Qiskit Runtime Programs
=======================

PennyLane-Qiskit supports running PennyLane on IBM Q hardware via the Qiskit runtime programs ``circuit-runner``
and ``sampler``. You can choose between those two runtime programs and also have the possibility to choose the
backend on which the circuits will be run. Those two devices inherit directly from the ``IBMQ`` device and work the
the same way, you can refer to the corresponding documentation for details about token and providers.
rmoyard marked this conversation as resolved.
Show resolved Hide resolved

You can use the ``circuit_runner`` and ``sampler`` devices by using their short names, for example:

.. code-block:: python

dev = qml.device('qiskit.ibmq.circuit_runner', wires=2, backend='ibmq_qasm_simulator', shots=8000, **kwargs)


.. code-block:: python

dev = qml.device('qiskit.ibmq.sampler', wires=2, backend='ibmq_qasm_simulator', shots=8000, **kwargs)


Custom Runtime Programs
~~~~~~~~~~~~~~~~~~~~~~~

Not all Qiskit runtime programs correspond to complete devices but rather solve specific problems (VQE, QAOA, etc...).
rmoyard marked this conversation as resolved.
Show resolved Hide resolved
We created a custom Qiskit runtime program for solving VQE problems in PennyLane ``runtime_programs\vqe_runtime_program.py``.
rmoyard marked this conversation as resolved.
Show resolved Hide resolved
In order to use this program you need to upload on IBMQ (only once), get the program ID and use the VQE runner.

.. code-block:: python

from pennylane_qiskit import upload_vqe_runner, vqe_runner

IBMQ.enable_account(token)

program_id = upload_vqe_runner(hub="ibm-q", group="open", project="main")

def vqe_circuit(params):
qml.RX(params[0], wires=0)
qml.RY(params[1], wires=0)

coeffs = [1, 1]
obs = [qml.PauliX(0), qml.PauliZ(0)]
hamiltonian = qml.Hamiltonian(coeffs, obs)

job = vqe_runner(
program_id=program_id,
backend="ibmq_qasm_simulator",
hamiltonian=hamiltonian,
ansatz=vqe_circuit,
x0=[3.97507603, 3.00854038],
shots=shots,
rmoyard marked this conversation as resolved.
Show resolved Hide resolved
optimizer="SPSA",
optimizer_config={"maxiter": 40},
rmoyard marked this conversation as resolved.
Show resolved Hide resolved
kwargs={"hub": "ibm-q", "group": "open", "project": "main"},
)

More details on Qiskit runtime programs in the `IBMQ runtime documentation <https://qiskit.org/documentation/apidoc/ibmq_runtime.html>`_.
11 changes: 11 additions & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ Currently, there are three different devices available:
:description: Allows integration with qiskit's hardware backends, and hardware-specific simulators.
:link: devices/ibmq.html

.. devicegalleryitem::
:name: 'qiskit.ibmq.circuit_runner'
:description: Allows integration with qiskit's circuit runner runtime program.
:link: devices/runtime.html

.. devicegalleryitem::
:name: 'qiskit.ibmq.sampler'
:description: Allows integration with qiskit's sampler runtime program.
:link: devices/runtime.html

.. raw:: html

<div style='clear:both'></div>
Expand Down Expand Up @@ -112,6 +122,7 @@ hardware access.
devices/aer
devices/basicaer
devices/ibmq
devices/runtime

.. toctree::
:maxdepth: 1
Expand Down
3 changes: 3 additions & 0 deletions pennylane_qiskit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@
from .basic_aer import BasicAerDevice
from .converter import load, load_qasm, load_qasm_from_file
from .ibmq import IBMQDevice
from .runtime_devices import IBMQCircuitRunnerDevice
from .runtime_devices import IBMQSamplerDevice
from .vqe_runtime_runner import vqe_runner, upload_vqe_runner, delete_vqe_runner
90 changes: 49 additions & 41 deletions pennylane_qiskit/ibmq.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,52 +58,14 @@ class IBMQDevice(QiskitDevice):
short_name = "qiskit.ibmq"

def __init__(self, wires, provider=None, backend="ibmq_qasm_simulator", shots=1024, **kwargs):
token = kwargs.get("ibmqx_token", None) or os.getenv("IBMQX_TOKEN")
url = kwargs.get("ibmqx_url", None) or os.getenv("IBMQX_URL")

# Specify a single hub, group and project
# Connection to IBMQ
connect(kwargs)

rmoyard marked this conversation as resolved.
Show resolved Hide resolved
hub = kwargs.get("hub", "ibm-q")
group = kwargs.get("group", "open")
project = kwargs.get("project", "main")

# TODO: remove "no cover" when #173 is resolved
if token is not None: # pragma: no cover
# token was provided by the user, so attempt to enable an
# IBM Q account manually
def login():
ibmq_kwargs = {"url": url} if url is not None else {}
IBMQ.enable_account(token, **ibmq_kwargs)

active_account = IBMQ.active_account()
if active_account is None:
login()
else:
# There is already an active account:
# If the token is the same, do nothing.
# If the token is different, authenticate with the new account.
if active_account["token"] != token:
IBMQ.disable_account()
login()
else:
# check if an IBM Q account is already active.
#
# * IBMQ v2 credentials stored in active_account().
# If no accounts are active, it returns None.

if IBMQ.active_account() is None:
# no active account
try:
# attempt to load a v2 account stored on disk
IBMQ.load_account()
except IBMQAccountError:
# attempt to enable an account manually using
# a provided token
raise IBMQAccountError(
"No active IBM Q account, and no IBM Q token provided."
) from None

# IBM Q account is now enabled

# get a provider
p = provider or IBMQ.get_provider(hub=hub, group=group, project=project)

Expand All @@ -129,3 +91,49 @@ def _track_run(self): # pragma: no cover
}
self.tracker.update(job_time=job_time)
self.tracker.record()


def connect(kwargs):
"""Function that allows connection to IBMQ.

Args:
kwargs(dict): dictionary that contains the token and the url"""

token = kwargs.get("ibmqx_token", None) or os.getenv("IBMQX_TOKEN")
url = kwargs.get("ibmqx_url", None) or os.getenv("IBMQX_URL")

# TODO: remove "no cover" when #173 is resolved
if token is not None: # pragma: no cover
# token was provided by the user, so attempt to enable an
# IBM Q account manually
def login():
ibmq_kwargs = {"url": url} if url is not None else {}
IBMQ.enable_account(token, **ibmq_kwargs)

active_account = IBMQ.active_account()
if active_account is None:
login()
else:
# There is already an active account:
# If the token is the same, do nothing.
# If the token is different, authenticate with the new account.
if active_account["token"] != token:
IBMQ.disable_account()
login()
else:
# check if an IBM Q account is already active.
#
# * IBMQ v2 credentials stored in active_account().
# If no accounts are active, it returns None.

if IBMQ.active_account() is None:
# no active account
try:
# attempt to load a v2 account stored on disk
IBMQ.load_account()
except IBMQAccountError:
# attempt to enable an account manually using
# a provided token
raise IBMQAccountError(
"No active IBM Q account, and no IBM Q token provided."
) from None
20 changes: 16 additions & 4 deletions pennylane_qiskit/qiskit_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ def create_circuit_object(self, operations, **kwargs):
self._circuit.save_state()

def apply(self, operations, **kwargs):

self.create_circuit_object(operations, **kwargs)

# These operations need to run for all devices
Expand Down Expand Up @@ -377,13 +376,19 @@ def analytic_probability(self, wires=None):
prob = self.marginal_prob(np.abs(self._state) ** 2, wires)
return prob

def batch_execute(self, circuits):
def compile_circuits(self, circuits):
r"""Compiles multiple circuits one after the other.

compiled_circuits = []
Args:
circuits (list[.tapes.QuantumTape]): the circuits to be compiled

Returns:
list[QuantumCircuit]: the list of compiled circuits
"""
# Compile each circuit object
for circuit in circuits:
compiled_circuits = []

for circuit in circuits:
# We need to reset the device here, else it will
# not start the next computation in the zero state
self.reset()
Expand All @@ -393,6 +398,13 @@ def batch_execute(self, circuits):
compiled_circ.name = f"circ{len(compiled_circuits)}"
compiled_circuits.append(compiled_circ)

return compiled_circuits

def batch_execute(self, circuits):
# pylint: disable=missing-function-docstring

compiled_circuits = self.compile_circuits(circuits)

# Send the batch of circuit objects using backend.run
self._current_job = self.backend.run(compiled_circuits, shots=self.shots, **self.run_args)
result = self._current_job.result()
Expand Down
Loading