qml.qcut.place_wire_cuts

place_wire_cuts(graph, cut_edges)[source]

Inserts a WireCut node for each provided cut edge into a circuit graph.

Parameters
  • graph (nx.MultiDiGraph) – The original (tape-converted) graph to be cut.

  • cut_edges (Sequence[Tuple[Operation, Operation, Any]]) – List of MultiDiGraph edges to be replaced with a WireCut node. Each 3-tuple represents the source node, the target node, and the wire key of the (multi)edge.

Returns

Copy of the input graph with WireCut nodes inserted.

Return type

MultiDiGraph

Example

Consider the following 2-wire circuit with one CNOT gate connecting the wires:

ops = [
    qml.RX(0.432, wires=0),
    qml.RY(0.543, wires="a"),
    qml.CNOT(wires=[0, "a"]),
]
measurements = [qml.expval(qml.Z(0))]
tape = qml.tape.QuantumTape(ops, measurements)
>>> print(qml.drawer.tape_text(tape, decimals=3))
0: ──RX(0.432)─╭●─┤  <Z>
a: ──RY(0.543)─╰X─┤

If we know we want to place a WireCut node between the nodes corresponding to the RY(0.543, wires=["a"]) and CNOT(wires=[0, 'a']) operations after the tape is constructed, we can first find the edge in the graph:

>>> graph = qml.qcut.tape_to_graph(tape)
>>> op0, op1 = tape.operations[1], tape.operations[2]
>>> cut_edges = [e for e in graph.edges if e[0].obj is op0 and e[1].obj is op1]
>>> cut_edges
[(Wrapped(RY(0.543, wires=['a'])), Wrapped(CNOT(wires=[0, 'a'])), 0)]

Then feed it to this function for placement:

>>> cut_graph = qml.qcut.place_wire_cuts(graph=graph, cut_edges=cut_edges)
>>> cut_graph
<networkx.classes.multidigraph.MultiDiGraph at 0x7f7251ac1220>

And visualize the cut by converting back to a tape:

>>> print(qml.qcut.graph_to_tape(cut_graph).draw(decimals=3))
0: ──RX(0.432)─────╭●─┤  <Z>
a: ──RY(0.543)──//─╰X─┤