pyquil icon indicating copy to clipboard operation
pyquil copied to clipboard

qubit and qubit_topology don't take current device connectivity into account

Open genos opened this issue 3 years ago • 5 comments

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?

genos avatar Nov 24 '21 19:11 genos

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?

dbanty avatar Nov 24 '21 21:11 dbanty

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.

genos avatar Nov 24 '21 22:11 genos

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)

genos avatar Dec 03 '21 02:12 genos

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.

erichulburd avatar Dec 07 '21 00:12 erichulburd

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)

genos avatar Apr 04 '22 16:04 genos

This should be solved implicitly by https://github.com/rigetti/pyquil/issues/1496

kalzoo avatar Dec 02 '22 22:12 kalzoo