pyquil
pyquil copied to clipboard
qubit and qubit_topology don't take current device connectivity into account
Pre-Request Checklist
- [X] I am running the latest versions of pyQuil and the Forest SDK
- [X] I checked to make sure that this feature has not already been requested
Issue Description
QCSQuantumProcessor.qubits()
and QCSQuantumProcessor.qubit_topology()
return information from the ISA without taking "dead" qubits into account—that is, they return information straight from the raw ISA. QCSQuantumProcessor.to_compiler_isa()
, however, filters the nodes and edges and marks dead anything without gates. If one were to try to, say, construct a Program
that addresses all available qubits and/or edges on a lattice via qubits()
or qubit_topology()
, they might run into strange-looking errors or the compiler might bend over backward to accommodate the original program in light of the current limitations of a device.
Proposed Solution
Perhaps an optional argument to qubits()
& qubit_topology
to remove things that aren't currently active on a QPU lattice?
I wonder if there's any good reason not to just make that the default behavior. What might someone want to do with .qubits()
or .qubit_topology()
involving qubits they can't actually use?
Some benchmarks might want to look at readout fidelity or some such for qubits that don’t happen to have any gates available, I suppose.
Here's a workaround/suggestion for what the proposed optional argument might instigate:
import networkx as nx
from pyquil import get_qc
computer = get_qc(<qc_name>)
qubits = computer.qubits()
topology = computer.qubit_topology()
isa = computer.to_compiler_isa()
# modify topology to remove dead qubits and edges
for qubit in isa.qubits.values():
if qubit.dead:
qubits.remove(qubit.id)
t = topology.subgraph(qubits).to_undirected()
for edge in isa.edges.values():
if edge.dead and edge.ids in t.edges:
t.remove_edge(*edge.ids)
topology = nx.freeze(t)
Those pyQuil v3 methods, ie qubits
and qubit_topology
, were designed without intention of being consistent with what Quilc expected. I wouldn't want to change that design now because it would represent a breaking change; we should add an optional boolean kwarg to return what @genos spec'd out above when set to the non-default value.
Code golfed version which may work for some scenarios:
computer = get_qc(<qc_name>)
qubits = [q.id for q in computer.to_compiler_isa().qubits.values() if not q.dead]
topology = computer.qubit_topology().subgraph(live_qubits)
This should be solved implicitly by https://github.com/rigetti/pyquil/issues/1496