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 compile_backend kwarg #398

Merged
merged 63 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from 61 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
f4f1ea8
Merge branch 'master' of github.com:PennyLaneAI/pennylane-qiskit
lillian542 Nov 20, 2023
03f1ceb
initial prototype device
lillian542 Nov 20, 2023
ce947ca
add use_primitives kwarg
lillian542 Nov 20, 2023
79bf3a0
reorganize circuit conversion part 1
lillian542 Nov 21, 2023
20b99c8
move circuit translation out of device
lillian542 Nov 21, 2023
609c76e
estimator execution
lillian542 Nov 21, 2023
b6af5a7
some small improvements for codefactor
lillian542 Nov 21, 2023
61c23a5
allow circuits with mixed MP types
lillian542 Nov 22, 2023
19d012b
move translation functions
lillian542 Nov 22, 2023
6ba938f
add support for broadcast_expand and session
lillian542 Nov 23, 2023
9ba2ff4
add kwargs for options
lillian542 Nov 24, 2023
79323dc
tidy up options and session
lillian542 Nov 24, 2023
16db026
warn if using non-primitive measurements
lillian542 Nov 29, 2023
13641b8
remove context manager for device session
lillian542 Nov 29, 2023
5f1c2d0
refactor handling of Options and kwargs
lillian542 Nov 30, 2023
1655821
cleaning up
lillian542 Dec 1, 2023
6f20fe5
fix 'c register already exists' hardware error
lillian542 Dec 5, 2023
4cecf29
change Options update interface
lillian542 Dec 6, 2023
d2550d9
don't allow options to override shots
lillian542 Dec 8, 2023
f82bbf3
don't use classical reg in estimator circuits
lillian542 Dec 8, 2023
f72d7df
update docstring
lillian542 Jan 22, 2024
540dc0e
add conversion tests
lillian542 Jan 22, 2024
3ec5951
add observable conversion test
lillian542 Jan 22, 2024
d8aaafc
fix bug in PauliOps converter
lillian542 Jan 22, 2024
533072d
add more conversion test functions
lillian542 Jan 22, 2024
123edee
remove Adjoint from supported ops and tidy up
lillian542 Jan 23, 2024
ecb8e3b
tests and little fixes
lillian542 Jan 23, 2024
f95591c
Merge branch 'master' into new_device_prototype
lillian542 Jan 23, 2024
845a2d6
add tests and black formatting
lillian542 Jan 24, 2024
33e4b3b
fix wire order bug for Estimator returns
lillian542 Jan 26, 2024
d3684e4
add tests
lillian542 Jan 26, 2024
719c315
remove error if device doesn't initialize
lillian542 Jan 26, 2024
24d1e72
try to get CI to run
lillian542 Jan 26, 2024
2f63a27
more CI stuff
lillian542 Jan 26, 2024
b309b42
try a thing
lillian542 Jan 26, 2024
bad5359
black formatting
lillian542 Jan 26, 2024
7b4b998
fix typo
lillian542 Jan 26, 2024
5315ce1
add missing skip-if-no-account
lillian542 Jan 26, 2024
6a958ca
update converter tests
lillian542 Jan 26, 2024
2512bf1
add mockers to allow tests to run in CI
lillian542 Jan 26, 2024
9dadc18
temporarily comment out integration tests
lillian542 Jan 26, 2024
674226f
get service from backend
lillian542 Jan 27, 2024
08f24e0
add mock service to mock backend
lillian542 Jan 27, 2024
aa7e07b
mock calls to Session in unit testing
lillian542 Jan 29, 2024
c417ca9
uncomment the other tests again
lillian542 Jan 29, 2024
27d0bd3
black formatting
lillian542 Jan 29, 2024
2479f95
newer black formatting
lillian542 Jan 29, 2024
e099f3a
add mocked tests for main execute method
lillian542 Jan 30, 2024
f1b0bf3
add MockSession to mocked execution tests
lillian542 Jan 30, 2024
41ec234
pylint
lillian542 Jan 30, 2024
3324794
add backend to MockSession calls
lillian542 Jan 30, 2024
ee5a712
mock tests for _execute methods
lillian542 Jan 30, 2024
b603871
black formatting
lillian542 Jan 31, 2024
d096c18
mock transpile for execute_runtime_service
lillian542 Jan 31, 2024
0c09d82
add name to MockedBackend
lillian542 Jan 31, 2024
963564e
add compile_backend kwarg
lillian542 Jan 31, 2024
3aaa32a
add tests
lillian542 Jan 31, 2024
bf64e35
black formatting
lillian542 Jan 31, 2024
e43263e
merge conflicts
austingmhuang Apr 19, 2024
72fc506
black
austingmhuang Apr 19, 2024
05ac1e1
Edit doc string
austingmhuang Apr 19, 2024
5983940
Update pennylane_qiskit/qiskit_device2.py
austingmhuang Apr 22, 2024
aea5be8
Update pennylane_qiskit/qiskit_device2.py
austingmhuang Apr 22, 2024
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
15 changes: 14 additions & 1 deletion pennylane_qiskit/qiskit_device2.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ class QiskitDevice2(Device):
for more details.
session (Session): a Qiskit Session to use for device execution. If none is provided, a session will
be created at each device execution.
compile_backend (Union[Backend, None]): the backend to be used for compiling the circuit that will be
sent to the backend device, to be set if the backend desired for compliation differs from the
backend used for execution. Defaults to None. If None, the primary backend will be used.
austingmhuang marked this conversation as resolved.
Show resolved Hide resolved
**kwargs: transpilation and runtime kwargs to be used for measurements without Qiskit Primitives.
If any values are defined both in ``options`` and in the remaining ``kwargs``, the value
provided in ``options`` will take precedence. These kwargs will be ignored for all Primitive-based
Expand All @@ -249,6 +252,7 @@ def __init__(
use_primitives=False,
options=None,
session=None,
compile_backend=None,
**kwargs,
):
if shots is None:
Expand All @@ -269,6 +273,7 @@ def __init__(
super().__init__(wires=wires, shots=shots)

self._backend = backend
self._compile_backend = compile_backend if compile_backend else backend

# ToDo: possibly things fail if this is not a QiskitRuntimeService - confirm and decide how to handle (SC 55725)
self._service = backend._service
Expand Down Expand Up @@ -302,6 +307,14 @@ def backend(self):
"""
return self._backend

@property
def compile_backend(self):
"""The compile_backend is a Qiskit backend object to be used for transpilation.
austingmhuang marked this conversation as resolved.
Show resolved Hide resolved
Returns:
qiskit.providers.backend: Qiskit backend object.
"""
return self._compile_backend

@property
def service(self):
"""The QiskitRuntimeService service.
Expand Down Expand Up @@ -445,7 +458,7 @@ def compile_circuits(self, circuits):
transpile_args = self.get_transpile_args(self._kwargs)

for i, circuit in enumerate(circuits):
compiled_circ = transpile(circuit, backend=self.backend, **transpile_args)
compiled_circ = transpile(circuit, backend=self.compile_backend, **transpile_args)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

compiled_circ.name = f"circ{i}"
compiled_circuits.append(compiled_circ)

Expand Down
64 changes: 58 additions & 6 deletions tests/test_base_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ def __init__(self, n_qubits):


class MockedBackend:
def __init__(self, num_qubits=10):
def __init__(self, num_qubits=10, name="mocked_backend"):
self._configuration = Configuration(num_qubits)
self.options = self._configuration
self._service = "SomeServiceProvider"
self.name = "mocked_backend"
self.name = name

def configuration(self):
return self._configuration
Expand Down Expand Up @@ -105,6 +105,21 @@ def options_for_testing():


class TestDeviceInitialization:
def test_compile_backend_kwarg(self):
"""Test that the compile_backend is set correctly if passed, and the main
backend is used otherwise"""

compile_backend = MockedBackend(name="compile_backend")
main_backend = MockedBackend(name="main_backend")

dev1 = QiskitDevice2(wires=5, backend=main_backend)
dev2 = QiskitDevice2(wires=5, backend=main_backend, compile_backend=compile_backend)

assert dev1._compile_backend == dev1._backend == main_backend

assert dev2._compile_backend != dev2._backend
assert dev2._compile_backend == compile_backend

@pytest.mark.parametrize("use_primitives", [True, False])
def test_use_primitives_kwarg(self, use_primitives):
"""Test the _use_primitives attribute is set on initialization"""
Expand Down Expand Up @@ -586,6 +601,15 @@ def test_backend_property(self):
assert test_dev.backend == test_dev._backend
assert test_dev.backend == backend

def test_compile_backend_property(self):
"""Test the compile_backend property"""

compile_backend = MockedBackend(name="compile_backend")
dev = QiskitDevice2(wires=5, backend=backend, compile_backend=compile_backend)

assert dev.compile_backend == dev._compile_backend
assert dev.compile_backend == compile_backend

def test_service_property(self):
"""Test the service property"""
assert test_dev.service == test_dev._service
Expand All @@ -610,14 +634,37 @@ class TestMockedExecution:
def test_get_transpile_args(self):
"""Test that get_transpile_args works as expected by filtering out
kwargs that don't match the Qiskit transpile signature"""

# independently
kwargs = {"random_kwarg": 3, "optimization_level": 3, "circuits": []}
assert QiskitDevice2.get_transpile_args(kwargs) == {"optimization_level": 3}

# on a device
transpile_args = {
"random_kwarg": 3,
"seed_transpiler": 42,
"optimization_level": 3,
"circuits": [],
}
compile_backend = MockedBackend(name="compile_backend")
dev = QiskitDevice2(
wires=5, backend=backend, compile_backend=compile_backend, **transpile_args
)
assert dev.get_transpile_args(dev._kwargs) == {
"optimization_level": 3,
"seed_transpiler": 42,
}

@patch("pennylane_qiskit.qiskit_device2.transpile")
def test_compile_circuits(self, transpile_mock):
@pytest.mark.parametrize("compile_backend", [None, MockedBackend(name="compile_backend")])
def test_compile_circuits(self, transpile_mock, compile_backend):
"""Tests compile_circuits with a mocked transpile function to avoid calling
a remote backend. This renders it fairly useless as a test, but makes CodeCov
pass."""
a remote backend. Confirm compile_backend and transpile_args are used."""

transpile_args = {"seed_transpiler": 42, "optimization_level": 2}
dev = QiskitDevice2(
wires=5, backend=backend, compile_backend=compile_backend, **transpile_args
)

transpile_mock.return_value = QuantumCircuit(2)

Expand All @@ -629,7 +676,12 @@ def test_compile_circuits(self, transpile_mock):
]
input_circuits = [circuit_to_qiskit(c, register_size=2) for c in circuits]

compiled_circuits = test_dev.compile_circuits(input_circuits)
with patch.object(dev, "get_transpile_args", return_value=transpile_args):
compiled_circuits = dev.compile_circuits(input_circuits)

transpile_mock.assert_called_with(
input_circuits[2], backend=dev.compile_backend, **transpile_args
)

assert len(compiled_circuits) == len(input_circuits)
for i, circuit in enumerate(compiled_circuits):
Expand Down
Loading