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─┤