# Qubit Connectivity of IBM Quantum Computer

When simulating a quantum circuit using the qiskit qasm_simulator, the qubits that you assign to the quantum circuit may be connected to all other qubits. In other words, if there are $$n$$ qubits in the quantum circuit, a single qubit can interact with all other $$n-1$$ qubits.

This is quite an unpractical hypothesis for real quantum computation. k-locality is a common criterion for a quantum computer and the only quantum computer I know of that has full qubit-connectivity is this one(I omitted the trivial cases of single- or two-qubit quantum computer). In the case of quantum devices that IBM provides via cloud access, e.g., 5-qubit ibmq_santiago, 5-qubit ibmq_5_yorktown, and 15-qubit ibmq_16_melbourne, all provide limited qubit connectivity.

So here arises my question: when designing a quantum circuit we have to take qubit connectivity into consideration, but how does qiskit handle this? Does it assign the job automatically (such that the quantum circuit can still work), or should I pre-assign my logical qubits to the real qubits of the IBM quantum computer by hand? And if so, how do I do that?

You can pass the parameter coupling_map to execute or transpile. This allows simulating a specific connectivity scheme as a list of edges.

The transpiling process (implicit during the execution process) takes care of adapting your circuit to the specific limitations of the backend or to the given limitations such as the coupling_map parameter. You can also control parts of that adaptation with parameters like initial_layout (you can define to which physical qubits you want to allocate your circuit).

Consider the following example:

from qiskit import *

circuit = QuantumCircuit(3)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.cx(2, 0)
circuit.draw('mpl')


This circuit requires a directed circular connectivity map. By default, transpiling this circuit takes a fully connected map, so it has no changes:

transpiled = transpile(circuit)
transpiled.draw('mpl')


If you want to add the restriction of a particular connectivity map, you can do so with the argument coupling_map. In this case, it is a directed linear connectivity $$0 \rightarrow 1 \rightarrow 2$$:

transpiled = transpile(circuit, coupling_map=[[0,1], [1,2]])
transpiled.draw('mpl')


Notice that a SWAP gate was added and the direction of CNOT was corrected. Also, the qubit allocation is showed on the left-hand side (e.g. logical qubit $$q_0$$ was allocated to physical qubit $$2$$.

You can control the qubit allocation with the parameter initial_layout. In the following example, logical $$q_0$$ is forced to be allocated to physical qubit 0 and so on:

transpiled = transpile(circuit, coupling_map=[[0,1], [1,2]], initial_layout=[0, 1, 2])
transpiled.draw('mpl')


Qiskit usually does the layout automatically, and it will do so by considering the device you are using (i.e. the qubits connectivity), of course the circuit, and the optimisation level. You can see a brief explanation on the Initial Layout part related to the optimisation level here. You will find explanation as well about this in the Mapping circuits to hardware technology part about the importance of a good layout for optimising the circuit and having the best results possible in the end.

You can also do it yourself. Here, you will find all of the layout selections already in Qiskit; as you can see there are a lot of ways to do this. You can also directly put the layout you wish when running your circuit in the execute function.
Maybe if you want to play with those to better understand the difference, I would suggest to either simply try them on real hardware or on a simulator by also adding the CouplingMap and see where this leads you !

I hope this helps :)

Just to add to the other two good answers, we don't just have qubit layout constraint but also available gates. For instance, SWAP gate or an arbitrary two qubit controlled gate is not being implemented directly as a native gate on current hardware. This is something we should take into account when transpiled the circuit as well.

Fr example, let's us take a similar circuit to the one given by @Luciano:

setting basis_gates= ['u1', 'u2', 'u3', 'cx'] in your transpile call, you might get something like this: