# Qubit Mapping

When designing quantum circuits, users often design them based on their algorithmic requirements. However, current quantum chips often struggle to achieve coupling between all qubits. Therefore, when executing quantum circuits on quantum computing hardware, we need to rearrange the qubits used in the quantum algorithm or add some SWAP gates to coupe qubits that were originally uncoupled. This is known as qubit mapping algorithm.

In this tutorial, we will first introduce the qubit node object QubitNode and qubit topology object QubitsTopology. Then, we will explain how to compile quantum circuits using the qubit mapping algorithm.

## Qubit Node

QubitNode represent the qubit in quantum chip. Currently, it has four properties:

• qubit_id：The unique id of quantum qubit.

• color：The face color when drawing qubit, default value is #000000.

• poi_x：The x position when drawing qubit, default value is 0.0

• poi_y：The y position when drawing qubit, default value is 0.0

Here, we are going to initialize a qubit node:

:

from mindquantum.device import QubitNode

q0 = QubitNode(0, '#121212', 0, 0)

print(f"qubit id: {q0.qubit_id}, with color: {q0.color}, and position ({q0.poi_x}, {q0.poi_y})")

qubit id: 0, with color: #121212, and position (0, 0)


QubitNode can be connected by operator >> or <<. Also you can disconnect them by > or <. The different operator for connecting or disconnecting will return different QubitNode.

lhs

op

rhs

Effect

Return

q0

>>

q1

Connect tow qubits

q1

q0

<<

q1

Connect tow qubits

q0

q0

>

q1

Disconnect tow qubits

q1

q0

<

q1

Disconnect tow qubits

q0

Based on the operation we defined above, we can quickly connect qubits like this:

:

q0, q1, q2 = QubitNode(0), QubitNode(1), QubitNode(2)

q0 >> q1 >> q2

:

<mindquantum.device.topology.QubitNode at 0x1322cf810>


In the above code, q0 >> q1 will connect the bits q0 and q1, and return the bit q1, and then through >> q2 you can connect q1 and q2.

### QubitsTopology

The QubitsTopology class is a container for qubits, which can effectively organize and manipulate them. For example, when we want to build a one-dimensional chain of qubits, we can do the following:

:

from mindquantum.device import QubitsTopology, QubitNode

n = 5

topology = QubitsTopology([QubitNode(i, poi_x=i) for i in range(n)])
print(topology)

<mindquantum.device.topology.QubitsTopology object at 0x132888a10>


MindQuantum also provide a method to show the topology:

:

from mindquantum.io.display import draw_topology

draw_topology(topology)

: From above, we successfully generate 5 qubits, but not connected them yet. Now we are going to connect them:

:

left_node = topology
for i in range(1, n):
left_node = left_node << topology[i]

draw_topology(topology)

: In above code, we get the qubit with its qubit_id with operation [], and connect then with operation <<.

In MindQuantum, we already designed some qubit topology, such as LinearQubits and GradQubits:

:

from mindquantum.device import LinearQubits, GridQubits
from IPython.display import display_svg

t1 = LinearQubits(3)
t2 = GridQubits(4, 5)

display_svg(draw_topology(t1))
display_svg(draw_topology(t2))  We can also to more operations on qubit topology, such as delete som qubit node:

:

t2.remove_qubit_node(6)

draw_topology(t2)

: isolate some qubit node:

:

t2.isolate_with_near(13)

draw_topology(t2)

: change the color of some qubit note:

:

t2.set_color(7, '#ff0000')

draw_topology(t2)

: change the position of some qubit node:

:

t2.set_position(4, 5.0, 0.5)

draw_topology(t2)

: or re-coupling with other qubit node:

:

t2 << t2

draw_topology(t2)

: We can also get all coupled edges of the qubit topology:

:

t2.edges_with_id()

:

{(0, 1),
(0, 5),
(1, 2),
(2, 3),
(2, 7),
(3, 4),
(3, 8),
(4, 9),
(4, 14),
(5, 10),
(7, 8),
(7, 12),
(8, 9),
(9, 14),
(10, 11),
(10, 15),
(11, 12),
(11, 16),
(12, 17),
(14, 19),
(15, 16),
(16, 17),
(17, 18),
(18, 19)}


### Qubit Mapping

When we run quantum circuits on real quantum hardware, we often cannot run them directly, because the qubit topology in the real hardware and the quantum circuit structure given by the user may not match. Then qubit mapping technology comes in. We can remap the quantum bits or insert some SWAP gates to make the circuit run successfully.

We give a quantum circuit:

:

from mindquantum.core.circuit import Circuit

circ = Circuit().h(0).h(1).h(2).x(1, 0).x(2, 1).x(0, 2)
circ.svg()

: following a 2x2 grid qubit topology:

:

t = GridQubits(2, 2)

draw_topology(t)

: Because the qubits in the above quantum circuit have interactions with each other, it cannot be directly run on the above quantum hardware. We introduce the SABER algorithm to solve this problem. For more algorithm details, please refer to the paper: Tackling the Qubit Mapping Problem for NISQ-Era Quantum Devices

:

from mindquantum.algorithm.mapping import SABRE

solver = SABRE(circ, t)
new_circ, init_mapping, final_mapping = solver.solve(5, 0.5, 0.3, 0.2)


The new quantum circuit after compiling is:

:

new_circ.svg()

: By comparing the old quantum circuit, we know that the algorithm reassigns the qubit id and inserts SWAP gates at appropriate positions, making the circuit run normally.

:

circ.svg()

: Here init_mapping and final_mapping tells us how to run the circuit at very begin and what is the relationship with the origin qubit id and final qubit id after running the circuit.

:

print(f"initial mapping: {init_mapping}")
print(f"  final mapping: {final_mapping}")

initial mapping: [1, 0, 2, 3]
final mapping: [3, 0, 2, 1]


We can also use draw_topology to show which edges will be used when running the compiled circuit.

:

draw_topology(t, new_circ)

: From the above result, all four edges in qubit topology are all used.

:

from mindquantum.utils.show_info import InfoTable
InfoTable('mindquantum', 'scipy', 'numpy')

:

Software Version
mindquantum0.9.0
scipy1.7.3
numpy1.21.6
System Info
Python3.7.10
OSDarwin x86_64
Memory8.59 GB