qml.transforms.rowcol

rowcol(tape, connectivity=None)[source]

CNOT routing algorithm RowCol.

This transform maps a CNOT circuit to a new CNOT circuit under constrained connectivity. The algorithm was introduced by Wu et al. and is detailed on its compilation page, where additional examples can be found as well.

Parameters:
  • tape (QNode or QuantumScript or Callable) – Input circuit containing only CNOT gates. Will internally be translated to the parity_matrix() IR.

  • connectivity (nx.Graph) – Connectivity graph to route into. If None (the default), full connectivity is assumed.

Returns:

the transformed circuit as described in qml.transform.

Return type:

qnode (QNode) or quantum function (Callable) or tuple[List[QuantumScript], function]

Raises:
  • ImportError – if the required galois package is not installed (pip install galois).

  • TypeError – if the input quantum circuit is not a CNOT circuit.

Note

This function requires the package galois to be installed. It can be installed via pip install galois, for details see its documentation.

Example

Let us start by defining a connectivity graph

(0) - (3) - (4)
       |
      (2)
       |
      (1)

and define it in code as a networkx.Graph (networkx documentation).

>>> import networkx as nx
>>> G = nx.Graph([(0, 3), (1, 2), (2, 3), (3, 4)])

Further we define the following circuit:

>>> print(qml.draw(qfunc, wire_order=range(5))())
0: ─╭●──────────╭●─╭X─╭●───────┤
1: ─╰X─╭●───────│──│──│──╭X────┤
2: ────╰X─╭●────│──│──╰X─│──╭●─┤
3: ───────╰X─╭●─│──╰●────╰●─│──┤
4: ──────────╰X─╰X──────────╰X─┤

We now run the algorithm:

>>> new_qfunc = qml.transforms.rowcol(qfunc)
>>> print(qml.draw(new_qfunc, wire_order=range(5))())
0: ───────────────────╭●───────╭X─┤
1: ─╭X────╭X─╭●────╭X─│────────│──┤
2: ─╰●─╭X─╰●─╰X─╭●─╰●─│─────╭X─│──┤
3: ─╭●─╰●───────╰X────╰X─╭●─╰●─╰●─┤
4: ─╰X───────────────────╰X───────┤

We can confirm that this circuit indeed implements the original circuit:

>>> import numpy as np
>>> U1 = qml.matrix(new_qfunc, wire_order=range(5))()
>>> U2 = qml.matrix(qfunc, wire_order=range(5))()
>>> np.allclose(U1, U2)
True

The same is true for the parity_matrix() of both circuits.

Please see the compilation page on RowCol for more details and step-by-step explanations of the algorithm.