-
Notifications
You must be signed in to change notification settings - Fork 33
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 support for generating subexperiments with LO's translated to a native gate set #517
Open
caleb-johnson
wants to merge
24
commits into
main
Choose a base branch
from
translate-sampled-gates
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
4b819c7
Add support for generating subexperiments with LO's translated to a n…
caleb-johnson b89583c
Improve release note
caleb-johnson 679fb73
Don't include basis gates in the equiv library
caleb-johnson 43ed255
ruff
caleb-johnson 7a5fe8a
Minor code clarity update
caleb-johnson aab23a2
Merge branch 'main' of github.com:Qiskit-Extensions/circuit-knitting-…
caleb-johnson c654f6a
Bug in RXGate. Add to roundtrip tests.
caleb-johnson 73bccc4
Sample standard gate set 50% of time
caleb-johnson 0472093
black
caleb-johnson fa0578c
theta name
caleb-johnson 819cc90
Change name of kwarg.
caleb-johnson 367e19c
black
caleb-johnson f286131
Rename how-to
caleb-johnson c881fbc
don't use defaultdict
caleb-johnson 8d1745d
Update circuit_knitting/cutting/qpd/decompose.py
caleb-johnson ba8b744
fix tests
caleb-johnson 4b796a9
Merge branch 'translate-sampled-gates' of github.com:Qiskit-Extension…
caleb-johnson b8351d1
Merge branch 'main' of github.com:Qiskit-Extensions/circuit-knitting-…
caleb-johnson 6395205
Implement translation as a function. Use regular dictionaries under h…
caleb-johnson 9cf2372
Rename equivalence --> translation
caleb-johnson f7e8cb1
style
caleb-johnson 4448506
Clean up bugs
caleb-johnson 4aac71f
Allow modern type hints for py38 users
caleb-johnson 41b5881
Merge branch 'main' of github.com:Qiskit-Extensions/circuit-knitting-…
caleb-johnson File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
# This code is a Qiskit project. | ||
|
||
# (C) Copyright IBM 2024. | ||
|
||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
|
||
""" | ||
Equivalence utilities. | ||
|
||
.. currentmodule:: circuit_knitting.cutting.qpd.equivalence | ||
|
||
.. autosummary:: | ||
:toctree: ../stubs/ | ||
|
||
""" | ||
from __future__ import annotations | ||
|
||
from collections.abc import Callable | ||
|
||
import numpy as np | ||
from qiskit.circuit import QuantumCircuit, QuantumRegister, Gate | ||
from qiskit.circuit.library.standard_gates import ( | ||
RZGate, | ||
XGate, | ||
YGate, | ||
ZGate, | ||
HGate, | ||
SGate, | ||
SdgGate, | ||
SXGate, | ||
SXdgGate, | ||
TGate, | ||
TdgGate, | ||
RXGate, | ||
RYGate, | ||
PhaseGate, | ||
) | ||
|
||
|
||
_equivalence_from_gate_funcs: dict[str, Callable[[Gate], QuantumCircuit]] = {} | ||
|
||
|
||
def _register_gate(*args): | ||
def g(f): | ||
for name in args: | ||
_equivalence_from_gate_funcs[name] = f | ||
return f | ||
|
||
return g | ||
|
||
|
||
def translate_qpd_gate(gate: Gate, basis_gate_set: str, /) -> QuantumCircuit: | ||
""" | ||
Translate a ``gate`` into a given basis gate set. | ||
|
||
This function is designed to handle only the gates to which a :class:`.QPDBasis` can | ||
decompose; therefore, not every Qiskit gate is supported by this function. | ||
|
||
Args: | ||
gate: The gate to translate | ||
|
||
Returns: | ||
A :class:`qiskit.QuantumCircuit` implementing the gate in the given basis gate set. | ||
|
||
Raises: | ||
ValueError: Unsupported basis gate set | ||
ValueError: Unsupported gate | ||
""" | ||
# We otherwise ignore this arg for now since our only two equivalences are equivalent :) | ||
if basis_gate_set not in {"heron", "eagle"}: | ||
raise ValueError(f"Unknown basis gate set: {basis_gate_set}") | ||
try: | ||
f = _equivalence_from_gate_funcs[gate.name] | ||
except KeyError as exc: | ||
raise ValueError(f"Cannot translate gate: {gate.name}") from exc | ||
else: | ||
return f(gate) | ||
|
||
|
||
# XGate | ||
@_register_gate("x") | ||
def _(gate: XGate): | ||
q = QuantumRegister(1, "q") | ||
def_x = QuantumCircuit(q) | ||
def_x.append(gate, [0], []) | ||
return def_x | ||
|
||
|
||
# SXGate | ||
@_register_gate("sx") | ||
def _(gate: SXGate): | ||
q = QuantumRegister(1, "q") | ||
def_sx = QuantumCircuit(q) | ||
def_sx.append(gate, [0], []) | ||
return def_sx | ||
|
||
|
||
# RZGate | ||
@_register_gate("rz") | ||
def _(gate: RZGate): | ||
q = QuantumRegister(1, "q") | ||
def_rz = QuantumCircuit(q) | ||
def_rz.append(gate, [0], []) | ||
return def_rz | ||
|
||
|
||
# YGate | ||
@_register_gate("y") | ||
def _(_: YGate): | ||
q = QuantumRegister(1, "q") | ||
def_y = QuantumCircuit(q) | ||
for inst in [RZGate(np.pi), XGate()]: | ||
def_y.append(inst, [0], []) | ||
return def_y | ||
|
||
|
||
# ZGate | ||
@_register_gate("z") | ||
def _(_: ZGate): | ||
q = QuantumRegister(1, "q") | ||
def_z = QuantumCircuit(q) | ||
def_z.append(RZGate(np.pi), [0], []) | ||
return def_z | ||
|
||
|
||
# HGate | ||
@_register_gate("h") | ||
def _(_: HGate): | ||
q = QuantumRegister(1, "q") | ||
def_h = QuantumCircuit(q) | ||
for inst in [RZGate(np.pi / 2), SXGate(), RZGate(np.pi / 2)]: | ||
def_h.append(inst, [0], []) | ||
return def_h | ||
|
||
|
||
# SGate | ||
@_register_gate("s") | ||
def _(_: SGate): | ||
q = QuantumRegister(1, "q") | ||
def_s = QuantumCircuit(q) | ||
def_s.append(RZGate(np.pi / 2), [0], []) | ||
return def_s | ||
|
||
|
||
# SdgGate | ||
@_register_gate("sdg") | ||
def _(_: SdgGate): | ||
q = QuantumRegister(1, "q") | ||
def_sdg = QuantumCircuit(q) | ||
def_sdg.append(RZGate(-np.pi / 2), [0], []) | ||
return def_sdg | ||
|
||
|
||
# SXdgGate | ||
@_register_gate("sxdg") | ||
def _(_: SXdgGate): | ||
q = QuantumRegister(1, "q") | ||
def_sxdg = QuantumCircuit(q) | ||
for inst in [ | ||
RZGate(np.pi / 2), | ||
RZGate(np.pi / 2), | ||
SXGate(), | ||
RZGate(np.pi / 2), | ||
RZGate(np.pi / 2), | ||
]: | ||
def_sxdg.append(inst, [0], []) | ||
return def_sxdg | ||
|
||
|
||
# TGate | ||
@_register_gate("t") | ||
def _(_: TGate): | ||
q = QuantumRegister(1, "q") | ||
def_t = QuantumCircuit(q) | ||
def_t.append(RZGate(np.pi / 4), [0], []) | ||
return def_t | ||
|
||
|
||
# TdgGate | ||
@_register_gate("tdg") | ||
def _(_: TdgGate): | ||
q = QuantumRegister(1, "q") | ||
def_tdg = QuantumCircuit(q) | ||
def_tdg.append(RZGate(-np.pi / 4), [0], []) | ||
return def_tdg | ||
|
||
|
||
# RXGate | ||
@_register_gate("rx") | ||
def _(gate: RXGate): | ||
q = QuantumRegister(1, "q") | ||
def_rx = QuantumCircuit(q) | ||
param = gate.params[0] | ||
for inst in [ | ||
RZGate(np.pi / 2), | ||
SXGate(), | ||
RZGate(param + np.pi), | ||
SXGate(), | ||
RZGate(5 * np.pi / 2), | ||
]: | ||
def_rx.append(inst, [0], []) | ||
return def_rx | ||
|
||
|
||
# RYGate | ||
@_register_gate("ry") | ||
def _(gate: RYGate): | ||
q = QuantumRegister(1, "q") | ||
def_ry = QuantumCircuit(q) | ||
param = gate.params[0] | ||
for inst in [SXGate(), RZGate(param + np.pi), SXGate(), RZGate(3 * np.pi)]: | ||
def_ry.append(inst, [0], []) | ||
|
||
|
||
# PhaseGate | ||
@_register_gate("p") | ||
def _(gate: PhaseGate): | ||
q = QuantumRegister(1, "q") | ||
def_p = QuantumCircuit(q) | ||
param = gate.params[0] | ||
def_p.append(RZGate(param), [0], []) | ||
return def_p |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anything that comes out of
QPDBasis
can be translated except our measurement objects. Those never need to be translated