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

Enable qpu.backend for IonQ backends #81

Merged
merged 15 commits into from
Nov 2, 2023
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

### Improvements 🛠

* Use new `backend` field to specify `qpu`.
[(#81)](https://github.com/PennyLaneAI/PennyLane-IonQ/pull/81)

### Breaking changes 💔

### Deprecations 👋
Expand All @@ -16,6 +19,8 @@

This release contains contributions from (in alphabetical order):

Spencer Churchill

---
# Release 0.32.0

Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ You can instantiate the IonQ devices for PennyLane as follows:

import pennylane as qml
dev1 = qml.device('ionq.simulator', wires=2, shots=1000)
dev2 = qml.device('ionq.qpu', wires=2, shots=1000)
dev2 = qml.device('ionq.qpu', backend='aria-1', wires=2, shots=1000)

These devices can then be used just like other devices for the definition and evaluation of
quantum circuits within PennyLane. For more details and ideas, see the
Expand All @@ -119,7 +119,7 @@ to the `PennyLane documentation <https://pennylane.readthedocs.io>`_.
Contributing
============

We welcome contributionssimply fork the PennyLane-IonQ repository, and then make a
We welcome contributions-simply fork the PennyLane-IonQ repository, and then make a
`pull request <https://help.github.com/articles/about-pull-requests/>`_ containing your contribution.
All contributers to PennyLane-IonQ will be listed as contributors on the releases.

Expand Down
7 changes: 4 additions & 3 deletions doc/devices.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,17 @@ directly in PennyLane by specifying ``"ionq.simulator"``:
Trapped-Ion QPU
---------------

This device provides access to IonQ's trapped-ion QPU.
This device provides access to IonQ's trapped-ion QPUs.
Once the plugin has been installed, you can use this device
directly in PennyLane by specifying ``"ionq.qpu"``:
directly in PennyLane by specifying ``"ionq.qpu"`` with a
``"backend"`` from `available backends <https://docs.ionq.com/#tag/jobs>`_:

.. code-block:: python

import pennylane as qml
from pennylane_ionq import ops

dev = qml.device("ionq.qpu", wires=2)
dev = qml.device("ionq.qpu", backend="harmony", wires=2)

@qml.qnode(dev)
def circuit(x, y):
Expand Down
33 changes: 27 additions & 6 deletions pennylane_ionq/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
"""
This module contains the device class for constructing IonQ devices for PennyLane.
"""
import itertools
import functools
import warnings
import os, warnings

Check notice on line 17 in pennylane_ionq/device.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_ionq/device.py#L17

Unused import os (unused-import)
from time import sleep

import numpy as np
Expand Down Expand Up @@ -137,7 +135,11 @@
warnings.warn("Circuit is empty. Empty circuits return failures. Submitting anyway.")

for i, operation in enumerate(operations):
if i > 0 and operation.name in {"BasisState", "QubitStateVector", "StatePrep"}:
if i > 0 and operation.name in {
"BasisState",
"QubitStateVector",
"StatePrep",
}:
raise DeviceError(
f"The operation {operation.name} is only supported at the beginning of a circuit."
)
Expand Down Expand Up @@ -269,6 +271,7 @@
or iterable that contains unique labels for the subsystems as numbers (i.e., ``[-1, 0, 2]``)
or strings (``['ancilla', 'q1', 'q2']``).
gateset (str): the target gateset, either ``"qis"`` or ``"native"``.
backend (str): Optional specifier for an IonQ backend. Can be ``"harmony"``, ``"aria-1"``, etc.
shots (int, list[int]): Number of circuit evaluations/random samples used to estimate
expectation values of observables. If ``None``, the device calculates probability, expectation values,
and variances analytically. If an integer, it specifies the number of samples to estimate these quantities.
Expand All @@ -279,8 +282,26 @@
name = "IonQ QPU PennyLane plugin"
short_name = "ionq.qpu"

def __init__(self, wires, *, target="qpu", gateset="qis", shots=1024, api_key=None):
super().__init__(wires=wires, target=target, gateset=gateset, shots=shots, api_key=api_key)
def __init__(
self,
wires,
*,
target="qpu",
backend=None,
gateset="qis",
shots=1024,
api_key=None,
):
self.backend = backend
if self.backend is not None:
target += "." + self.backend
super().__init__(
wires=wires,
target=target,
gateset=gateset,
shots=shots,
api_key=api_key,
)

def generate_samples(self):
"""Generates samples from the qpu.
Expand Down
6 changes: 2 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,11 @@
"maintainer_email": "[email protected]",
"url": "http://xanadu.ai",
"license": "Apache License 2.0",
"packages": [
"pennylane_ionq"
],
"packages": ["pennylane_ionq"],
"entry_points": {
"pennylane.plugins": [
"ionq.simulator = pennylane_ionq:SimulatorDevice",
"ionq.qpu = pennylane_ionq:QPUDevice"
"ionq.qpu = pennylane_ionq:QPUDevice",
]
},
"description": "PennyLane plugin for IonQ",
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
# List of all devices that do *not* support analytic expectation
# value computation. This generally includes hardware devices
# and hardware simulators.
hw_devices = [SimulatorDevice]
hw_devices = [SimulatorDevice, QPUDevice]

# List of all device shortnames
shortnames = [d.short_name for d in analytic_devices + hw_devices]
Expand Down
23 changes: 18 additions & 5 deletions tests/test_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ def mock_submit_job(*args):
dev.apply([])

def test_failedcircuit(self, monkeypatch):

monkeypatch.setattr(
requests, "post", lambda url, timeout, data, headers: (url, data, headers)
)
Expand Down Expand Up @@ -182,6 +181,23 @@ def test_prob_no_results(self, d):
dev = qml.device(d, wires=1, shots=1)
assert dev.prob is None

@pytest.mark.parametrize(
"backend", ["harmony", "aria-1", "aria-2", "forte-1", None]
)
def test_backend_initialization(self, backend):
"""Test that the device initializes with the correct backend."""
if backend:
dev = qml.device(
"ionq.qpu",
wires=2,
shots=1000,
backend=backend,
)
assert dev.backend == backend
else:
dev = qml.device("ionq.qpu", wires=2, shots=1000)
assert dev.backend == None


class TestJobAttribute:
"""Tests job creation with mocked submission."""
Expand Down Expand Up @@ -246,7 +262,7 @@ def mock_submit_job(*args):
pass
lillian542 marked this conversation as resolved.
Show resolved Hide resolved

mocker.patch("pennylane_ionq.device.IonQDevice._submit_job", mock_submit_job)
dev = IonQDevice(wires=(0,1,2), gateset="native")
dev = IonQDevice(wires=(0, 1, 2), gateset="native")

with qml.tape.QuantumTape() as tape:
GPI(0.1, wires=[0])
Expand Down Expand Up @@ -275,6 +291,3 @@ def mock_submit_job(*args):
"targets": [1, 2],
"phases": [0.2, 0.3],
}



Loading