# What are physically allowed CNOTs for Rigetti's 19 qubit chip and Google's 72 qubit BristleCone chip?

For each IBM quantum chip, one can write a dictionary mapping each control qubit j to a list of its physically allowed targets, assuming j is the control of a CNOT. For example,

ibmqx4_c_to_tars = {
0: [],
1: [0],
2: [0, 1, 4],
3: [2, 4],
4: []}  # 6 edges


for their ibmqx4 chip.

What would be that dict for Google's 72 qubit Bristlecone chip. You can write the dict as a comprehension. Same question for Rigetti's 19 qubit chip.

• Maybe you could add a link to the description of the chips in the question? I failed to find Regitti's chip specifications. – Nelimee Jul 19 '18 at 15:10
• Jim Wootton should know – rrtucci Jul 19 '18 at 15:15

Bristlecone's native operation is the CZ, not CNOTs. However, you can transform between the two with Hadamard gates so this is sort of a trivial difference.

Bristlecone can perform a CZ between any adjacent pair of qubits on a grid. You can see the grid by installing cirq and printing out the Bristlecone device:

$pip install cirq$ python
>>> import cirq
(0, 5)────(0, 6)
│         │
│         │
(1, 4)───(1, 5)────(1, 6)────(1, 7)
│        │         │         │
│        │         │         │
(2, 3)───(2, 4)───(2, 5)────(2, 6)────(2, 7)───(2, 8)
│        │        │         │         │        │
│        │        │         │         │        │
(3, 2)───(3, 3)───(3, 4)───(3, 5)────(3, 6)────(3, 7)───(3, 8)───(3, 9)
│        │        │        │         │         │        │        │
│        │        │        │         │         │        │        │
(4, 1)───(4, 2)───(4, 3)───(4, 4)───(4, 5)────(4, 6)────(4, 7)───(4, 8)───(4, 9)───(4, 10)
│        │        │        │        │         │         │        │        │        │
│        │        │        │        │         │         │        │        │        │
(5, 0)───(5, 1)───(5, 2)───(5, 3)───(5, 4)───(5, 5)────(5, 6)────(5, 7)───(5, 8)───(5, 9)───(5, 10)───(5, 11)
│        │        │        │        │         │         │        │        │        │
│        │        │        │        │         │         │        │        │        │
(6, 1)───(6, 2)───(6, 3)───(6, 4)───(6, 5)────(6, 6)────(6, 7)───(6, 8)───(6, 9)───(6, 10)
│        │        │        │         │         │        │        │
│        │        │        │         │         │        │        │
(7, 2)───(7, 3)───(7, 4)───(7, 5)────(7, 6)────(7, 7)───(7, 8)───(7, 9)
│        │        │         │         │        │
│        │        │         │         │        │
(8, 3)───(8, 4)───(8, 5)────(8, 6)────(8, 7)───(8, 8)
│        │         │         │
│        │         │         │
(9, 4)───(9, 5)────(9, 6)────(9, 7)
│         │
│         │
(10, 5)───(10, 6)


Here is how you can get a set containing the allowed CZ operations:

qubits = cirq.google.Bristlecone.qubits
allowed = {cirq.CZ(a, b)
for a in qubits
for b in qubits


The set has 121 elements in it, and it's somewhat random whether you get CZ(x, y) or CZ(y, x) in the set, so I won't include a printout of the set here.

An additional constraint to keep in mind is that you cannot perform two CZs next to each other at the same time. Cirq takes this into account when creating circuits targeted at Bristlecone. For example:

import cirq
a, b, c, d, e = device.col(6)[:5]
circuit = cirq.Circuit.from_ops(
cirq.CZ(a, b),
cirq.CZ(c, d),
cirq.CZ(a, b),
cirq.CZ(d, e),
device=device)
print(circuit)
# (0, 6): ───@───────@───
#            │       │
# (1, 6): ───@───────@───
#
# (2, 6): ───────@───────
#                │
# (3, 6): ───────@───@───
#                    │
# (4, 6): ───────────@───


The first two operations were staggered because they are adjacent CZs, but the second two weren't because they aren't.

• Nice use of the API! Your solution is better than mine! :) – Nelimee Jul 19 '18 at 18:29
• Nelimee, your solution is correct too, and terser. Circ has chosen to rotate rectangular array by 45 degrees which is somewhat perverse – rrtucci Jul 19 '18 at 18:42
• Oh, I see. They did it because of ascii drawing limitations – rrtucci Jul 19 '18 at 18:46
• Google has a quantum computer? – user1271772 Jul 19 '18 at 18:48
• @rrtucci ASCII includes diagonal lines (/, \). The coordinate choice was more along the lines of minimizing the difficulty of various tasks, such as guessing if qubit (a,b) is present or not. For those tasks the diamond shape is only tricky near the border, whereas the checkerboard pattern is tricky throughout. – Craig Gidney Jul 19 '18 at 19:04

From the original blog post presenting the Bristlecone quantum chip, here is the connectivity map of the chip:

Each cross represent a qubit, with nearest-neighbour connectivity. If you number the qubits from left to right, top to bottom (just like how you read english), starting by $0$ then the connectivity map would be given by:

connectivity_map = {
i : [i + offset
for offset in (-6, -5, 5, 6) # values deduced by taking a qubit in the middle of
# chip and computing the offsets between the choosen
# qubit and it's 4 neighbours
if ((0 <= i+offset < 72)             # the neighbour should be a valid qubit
and ((i+offset) // 6 != i // 6)) # the neighbour should not be on the same line
]
for i in range(72)
}


Warning: the expression above is completely unverified. It seems to work for the first qubits, it seems logical to me, but it's up to you to check that the map is 100% correct.

Warning 2: Google's blog post does not talk about the orientation of the connections between qubits. The connectivity map given above assumes that the connections are bilateral.

The current version of PyQuil provides an "ISA" object that houses the information that you want about Rigetti's quantun processors, but it isn't formatted as you request. I'm a poor Python programmer, so you'll have to excuse my non-Pythonic-ness—but here's a snippet that will take a device_name and reformat the pyQuil ISA into one of your dictionaries:

import pyquil.api as p

device_name = '19Q-Acorn'

isa = p.get_devices(as_dict=True)[device_name].isa
d = {}
for qubit in isa.qubits:
l = []
for edge in isa.edges:
if qubit.id is edge.targets[0]:
l += [edge.targets[1]]
if qubit.id is edge.targets[1]:
l += [edge.targets[0]]
d[qubit.id] = l

print(d)


As in Google's case, the native two-qubit gate typically available on a Rigetti quantum processor is a CZ, which (1) is bidirectional(†) in the sense that CZ q0 q1 is the same as CZ q1 q0 and (2) is easily converted into either of your preferred CNOTs by sandwiching the target with Hadamard gates.

† - The physical implementation of a CZ gate in a superconducting architecture is handed, which is why you often see architectural descriptions include CZ q0 q1 but not CZ q1 q0. It's a shorthand for which qubit is participating in which half of the physical interaction, even if the result (ignoring noise effects) is the same with either ordering.