-
Notifications
You must be signed in to change notification settings - Fork 8
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
Use dynamic quantum architecture (DQA) for circuit decomposition/routing #139
Conversation
# connectivity consists of all arity-2 gate loci in the DQA | ||
connectivity = tuple( | ||
get_qid_locus(locus) | ||
for gate_info in architecture.gates.values() | ||
for locus in gate_info.loci | ||
if len(locus) == 2 | ||
) | ||
operations: dict[type[cirq.Gate], list[tuple[NamedQid, ...]]] = { | ||
cirq_op: [ | ||
tuple( | ||
( | ||
NamedQid(qb, dimension=2) | ||
if qb.startswith(cls.QUBIT_NAME_PREFIX) | ||
else NamedQid(qb, dimension=cls.RESONATOR_DIMENSION) | ||
) | ||
for qb in args | ||
) | ||
for args in qubits | ||
] | ||
for iqm_op, qubits in architecture.operations.items() | ||
for cirq_op in _IQM_CIRQ_OP_MAP[iqm_op] | ||
} | ||
return cls(qubits, connectivity, operations=operations, resonators=resonators) | ||
|
||
def to_architecture(self) -> QuantumArchitectureSpecification: | ||
"""Returns the architecture specification object created based on device metadata.""" | ||
qubits = tuple(qb.name for qb in self._qubit_set) | ||
resonators = tuple(qb.name for qb in self.resonator_set) | ||
connectivity = tuple(tuple(qb.name for qb in edge) for edge in self.nx_graph.edges()) | ||
operations: dict[str, list[tuple[str, ...]]] = { | ||
iqm_op: [tuple(qb.name for qb in args) for args in qubits] | ||
for cirq_op, qubits in self.operations.items() | ||
for iqm_op, cirq_ops in _IQM_CIRQ_OP_MAP.items() | ||
if cirq_op in cirq_ops | ||
cirq_op: [get_qid_locus(locus) for locus in gate_info.loci] | ||
for gate_name, gate_info in architecture.gates.items() | ||
for cirq_op in _IQM_CIRQ_OP_MAP[gate_name] |
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.
operations
contains the full locus info for all gates, but it's not used for routing as far as I can tell.
connectivity
is used (in the form of IQMDevice._metadata.nx_graph
), but it does not represent any single 2q gate type (seems like the router assumes there is just one 2q gate).
Also, connectivity
here will contain duplicate loci/edges. When it's converted into a graph the duplicates vanish.
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.
Right. As discussed, this problem already existed before this PR and is due to Cirq limitations. Probably can't solve it here. We can still look into a solution for it, but probably the PR should not be blocked from being merged because of this.
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.
Does this connectivity work for Deneb-style devices? Where the router should not have the MOVE gate edges. If connectivity will turn into a an nx_graph
does it makes sense to make labeled edges where the labels correspond to gates? Or is that something the router cannot work with either?
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.
The connectivity (nx_graph
) should be the same as before this PR, assuming we compare an "equivalent" DQA and QuantumArchitectureSpecification. So my understanding is that it should work for Deneb same as before this PR.
I think labeled edges for gates wouldn't be used by the router, because the documentation says that the graph is "The connectivity graph of physical qubits.": https://quantumai.google/reference/python/cirq/RouteCQC
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.
So the connectivity is used to build the nx_graph
this is used in route_circuit
by removing the resonators from it and then using Cirq's routing pass. After that, the MOVE gates are added. So there is no notion of gates in the route_circuit
but the case of MOVE gates is handled through the resonator.
Co-authored-by: Ville Bergholm <[email protected]>
# connectivity consists of all arity-2 gate loci in the DQA | ||
connectivity = tuple( | ||
get_qid_locus(locus) | ||
for gate_info in architecture.gates.values() | ||
for locus in gate_info.loci | ||
if len(locus) == 2 | ||
) | ||
operations: dict[type[cirq.Gate], list[tuple[NamedQid, ...]]] = { | ||
cirq_op: [ | ||
tuple( | ||
( | ||
NamedQid(qb, dimension=2) | ||
if qb.startswith(cls.QUBIT_NAME_PREFIX) | ||
else NamedQid(qb, dimension=cls.RESONATOR_DIMENSION) | ||
) | ||
for qb in args | ||
) | ||
for args in qubits | ||
] | ||
for iqm_op, qubits in architecture.operations.items() | ||
for cirq_op in _IQM_CIRQ_OP_MAP[iqm_op] | ||
} | ||
return cls(qubits, connectivity, operations=operations, resonators=resonators) | ||
|
||
def to_architecture(self) -> QuantumArchitectureSpecification: | ||
"""Returns the architecture specification object created based on device metadata.""" | ||
qubits = tuple(qb.name for qb in self._qubit_set) | ||
resonators = tuple(qb.name for qb in self.resonator_set) | ||
connectivity = tuple(tuple(qb.name for qb in edge) for edge in self.nx_graph.edges()) | ||
operations: dict[str, list[tuple[str, ...]]] = { | ||
iqm_op: [tuple(qb.name for qb in args) for args in qubits] | ||
for cirq_op, qubits in self.operations.items() | ||
for iqm_op, cirq_ops in _IQM_CIRQ_OP_MAP.items() | ||
if cirq_op in cirq_ops | ||
cirq_op: [get_qid_locus(locus) for locus in gate_info.loci] | ||
for gate_name, gate_info in architecture.gates.items() | ||
for cirq_op in _IQM_CIRQ_OP_MAP[gate_name] |
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.
Does this connectivity work for Deneb-style devices? Where the router should not have the MOVE gate edges. If connectivity will turn into a an nx_graph
does it makes sense to make labeled edges where the labels correspond to gates? Or is that something the router cannot work with either?
@@ -35,6 +35,7 @@ class IQMDeviceMetadata(devices.DeviceMetadata): | |||
operations: Supported quantum operations of the device, mapping op types to their possible loci. | |||
gateset: Native gateset of the device. If None, a default IQM device gateset will be used. | |||
resonators: computational resonators of the device | |||
architecture: architecture from which values of the other arguments were obtained | |||
""" | |||
|
|||
QUBIT_NAME_PREFIX: str = 'QB' |
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.
Is this still needed with DQA?
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.
It's still needed because it's used in IQMDevice.get_qubit_index
and IQMDeviceMetadata.from_qubit_indices
.
-
get_qubit_index
is not used anywhere in code. But could be useful for some purpose, not sure if there was some requirement to have it? -
from_qubit_indices
makes creating the hardcoded devices like Apollo a bit nicer
Both are probably something we could get rid of if we really want, but I would still keep this and not change these things in this PR.
IQMDeviceMetadata can now be created from a DQA, and creating it from QuantumArchitectureSpecification (static architecture) is no longer supported.
IQMDevice/IQMDeviceMetadata can still be created independently of the architecture/calset, so the hardcoded Adonis, Apollo etc. classes are not removed. They are currently used mainly for tests, and could be used for simulation.
IQMSampler uses the specified calset (or server default calset if
calibration_set_id
not specified) to create the IQMDeviceMetadata/IQMDevice.IQMSampler adds the calset id to the circuits it decomposes/routes. The calset id is used to warn the user of mismatches between the calset used for execution and the decomposed/routed circuits.
Requires Use dynamic quantum architecture for circuit validation and transpilation iqm-client#140 to be merged first, tests will fail until then. I have tested locally that all tests pass when used together with those changes.