-
Notifications
You must be signed in to change notification settings - Fork 21
🎨 Update of IonQ and Rigetti Devices #570
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
Changes from 15 commits
8f97eea
ea45fa2
33a23f5
60575ae
a0799c1
9831391
1031198
c44b965
0a2e568
64b96d3
8d54a14
3ac576f
e6279f7
58b8de4
a27e24f
bc53846
d9e8084
b13e824
db651b3
e300c9b
f1666f4
2eda174
371a77e
4c5666e
9645895
f2b5fee
4b1f0ee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ | |
|
||
from qiskit.providers.fake_provider import GenericBackendV2 | ||
|
||
from ..gatesets import get_ibm_eagle_gateset, get_ibm_falcon_gateset, get_ibm_heron_gateset | ||
from mqt.bench.targets.gatesets.ibm import get_ibm_eagle_gateset, get_ibm_falcon_gateset, get_ibm_heron_gateset | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change is unrelated to the PR and I actually would not make that change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adjusted it accordingly. |
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
burgholzer marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,54 +11,60 @@ | |
from __future__ import annotations | ||
|
||
from qiskit.circuit import Parameter | ||
from qiskit.circuit.library import Measure, RXGate, RXXGate, RYGate, RZGate | ||
from qiskit.circuit.library import Measure, RZGate | ||
from qiskit.transpiler import InstructionProperties, Target | ||
|
||
from mqt.bench.targets.gatesets.ionq import GPI2Gate, GPIGate, MSGate, ZZGate, add_ionq_equivalences | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would have a rather strong preference for relative imports. Tends to work better with editable installs and IDEs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adjusted it accordingly. |
||
|
||
|
||
def get_ionq_target(device_name: str) -> Target: | ||
"""Get the target device for a given IonQ device name.""" | ||
if device_name == "ionq_aria1": | ||
return get_ionq_aria1_target() | ||
if device_name == "ionq_harmony": | ||
return get_ionq_harmony_target() | ||
add_ionq_equivalences() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not yet quite sure this is the best place to put this. As there are multiple IonQ devices, this will inevitably get called multiple times. I think it would be good to ensure that this is only called once. And preferably, it would only be called when the target is used, not when it's constructed. We only want to add these right before the I'd also like to understand a little bit more about the lifecycle of the SessionEquivalenceLibrary. How long does it persist? Where does it enter the equation in the transpile call? Would moving to the StagedPassManager allow us to use a custom EL? |
||
if device_name == "ionq_aria_1": | ||
return get_ionq_aria_1_target() | ||
if device_name == "ionq_forte_1": | ||
return get_ionq_forte_1_target() | ||
msg = f"Unknown IonQ device: '{device_name}'" | ||
raise ValueError(msg) | ||
|
||
|
||
def get_ionq_aria1_target() -> Target: | ||
"""Get the target device for IonQ Aria1.""" | ||
def get_ionq_aria_1_target() -> Target: | ||
"""Get the target device for IonQ Aria 1.""" | ||
num_qubits = 25 | ||
return _build_ionq_target( | ||
num_qubits=num_qubits, | ||
description="ionq_aria1", | ||
description="ionq_aria_1", | ||
entangling_gate="MS", | ||
oneq_duration=135e-6, | ||
twoq_duration=600e-6, | ||
readout_duration=300e-6, | ||
oneq_fidelity=0.9829, | ||
twoq_fidelity=0.996, | ||
spam_fidelity=0.9993, | ||
oneq_fidelity=0.9998, | ||
twoq_fidelity=0.98720, | ||
spam_fidelity=0.99370, | ||
) | ||
|
||
|
||
def get_ionq_harmony_target() -> Target: | ||
"""Get the target device for IonQ Harmony.""" | ||
num_qubits = 11 | ||
def get_ionq_forte_1_target() -> Target: | ||
"""Get the target device for IonQ Forte 1.""" | ||
num_qubits = 36 | ||
return _build_ionq_target( | ||
num_qubits=num_qubits, | ||
description="ionq_harmony", | ||
oneq_duration=10e-6, | ||
twoq_duration=200e-6, | ||
readout_duration=130e-6, | ||
oneq_fidelity=0.9985, | ||
twoq_fidelity=0.9614, | ||
spam_fidelity=0.99752, | ||
description="ionq_forte_1", | ||
entangling_gate="ZZ", | ||
oneq_duration=130e-6, | ||
twoq_duration=970e-6, | ||
readout_duration=150e-6, | ||
oneq_fidelity=0.9998, | ||
twoq_fidelity=0.9932, | ||
spam_fidelity=0.9959, | ||
) | ||
|
||
|
||
def _build_ionq_target( | ||
*, | ||
num_qubits: int, | ||
description: str, | ||
entangling_gate: str, | ||
oneq_duration: float, | ||
twoq_duration: float, | ||
readout_duration: float, | ||
|
@@ -71,21 +77,19 @@ def _build_ionq_target( | |
|
||
theta = Parameter("theta") | ||
phi = Parameter("phi") | ||
lam = Parameter("lambda") | ||
alpha = Parameter("alpha") | ||
|
||
# === Add single-qubit gates === | ||
singleq_props = { | ||
(q,): InstructionProperties(duration=oneq_duration, error=1 - oneq_fidelity) for q in range(num_qubits) | ||
} | ||
rz_props = {(q,): InstructionProperties(duration=0.0, error=0.0) for q in range(num_qubits)} | ||
rz_props = {(q,): InstructionProperties(duration=0, error=0) for q in range(num_qubits)} | ||
measure_props = { | ||
(q,): InstructionProperties(duration=readout_duration, error=1 - spam_fidelity) for q in range(num_qubits) | ||
} | ||
|
||
target.add_instruction(RXGate(theta), singleq_props) | ||
target.add_instruction(RYGate(phi), singleq_props) | ||
target.add_instruction(RZGate(lam), rz_props) | ||
target.add_instruction(RZGate(theta), rz_props) | ||
target.add_instruction(GPIGate(theta), singleq_props) | ||
target.add_instruction(GPI2Gate(phi), singleq_props) | ||
target.add_instruction(Measure(), measure_props) | ||
|
||
# === Add two-qubit gates === | ||
|
@@ -94,5 +98,15 @@ def _build_ionq_target( | |
(q1, q2): InstructionProperties(duration=twoq_duration, error=1 - twoq_fidelity) for q1, q2 in connectivity | ||
} | ||
|
||
target.add_instruction(RXXGate(alpha), twoq_props) | ||
if entangling_gate == "MS": | ||
alpha = Parameter("alpha") | ||
beta = Parameter("beta") | ||
gamma = Parameter("gamma") | ||
target.add_instruction(MSGate(alpha, beta, gamma), twoq_props) | ||
elif entangling_gate == "ZZ": | ||
alpha = Parameter("alpha") | ||
target.add_instruction(ZZGate(alpha), twoq_props) | ||
else: | ||
msg = f"Unknown entangling gate: '{entangling_gate}'." | ||
raise ValueError(msg) | ||
return target |
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.
I believe the naming of these should be adjusted so that the last number indicates the number of qubits similar to IBM and IQM. The
1
here does not add any valueThere 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.
These are the specific device names and there is also an
Aria 2
. Therefore, I suggest to keep the name, but this is independent of the qubit number at the end - if you prefer that, I am happy to add it to all devices.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.
But aria 2 still uses the same layout and the same gateset if I am not mistaken.
Given how the device data is averaged anyway, I do not think there is too much value to this number.
If the gateset should really be different between these, then I would actually add the number to the gateset name and still append an underscore with the number of qubits for the device here.
Same holds for the Rigetti device.