qml.transforms.qcut.place_wire_cuts

place_wire_cuts(graph: networkx.classes.multidigraph.MultiDiGraph, cut_edges: Sequence[Tuple[pennylane.operation.Operation, pennylane.operation.Operation, Any]])networkx.classes.multidigraph.MultiDiGraph[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:

with qml.tape.QuantumTape() as tape:
    qml.RX(0.432, wires=0)
    qml.RY(0.543, wires="a")
    qml.CNOT(wires=[0, "a"])
    qml.expval(qml.PauliZ(wires=[0]))
>>> print(qml.drawer.tape_text(tape))
 0: ──RX(0.432)──╭●──┤ ⟨Z⟩
 a: ──RY(0.543)──╰X──┤

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

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

Then feed it to this function for placement:

>>> cut_graph = qml.transforms.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.transforms.qcut.graph_to_tape(cut_graph).draw())
 0: ──RX(0.432)──────╭●──┤ ⟨Z⟩
 a: ──RY(0.543)──//──╰X──┤