qp.decomposition.inspect_decomps¶
- inspect_decomps(op, *rules, show_not_applicable=True, num_work_wires=None)[source]¶
Inspect the decomposition rules of an operator.
Takes an operator instance and displays how the operator is decomposed using different decomposition rules.
Note
This function is only relevant when the new experimental graph-based decomposition system (introduced in v0.41) is enabled via
enable_graph(). This new way of performing decompositions is generally more resource-efficient and accommodates multiple alternative decomposition rules for an operator.- Parameters:
op (Operator) – the operator instance whose decomposition rules will be inspected.
*rules (str or DecompositionRule) – the decomposition rules to inspect. Accepts instances of the
DecompositionRuleclass or rule names (str) that represent the decomposition rules registered with the type ofop. If none are provided, all available rules will be displayed.show_not_applicable (bool) – if True (the default), all decomposition rules, including those that are not applicable to the specific operator instance (e.g., due to constraints on the number of wires), are displayed.
num_work_wires (int or None) – the maximum number of available work wires for dynamic allocation. Decomposition rules that allocate more wires than are available will be marked as “Not applicable” (and excluded if
show_not_applicable=False). Defaults toNone, which puts no constraint on the maximum number of work wires.
- Returns:
The string that displays how the operator is decomposed.
- Return type:
str
Example
By default, this function displays all available decomposition rules for an operator.
>>> print(qp.inspect_decomps(qp.CRX(0.5, wires=[0, 1]))) Decomposition 0 (name: _crx_to_rx_cz) 0: ───────────╭●────────────╭●─┤ 1: ──RX(0.25)─╰Z──RX(-0.25)─╰Z─┤ Gate Count: {RX: 2, CZ: 2} Decomposition 1 (name: _crx_to_rz_ry) 0: ─────────────────────╭●────────────╭●────────────┤ 1: ──RZ(1.57)──RY(0.25)─╰X──RY(-0.25)─╰X──RZ(-1.57)─┤ Gate Count: {RZ: 2, RY: 2, CNOT: 2} Decomposition 2 (name: _crx_to_h_crz) 0: ────╭●───────────┤ 1: ──H─╰RZ(0.50)──H─┤ Gate Count: {Hadamard: 2, CRZ: 1} Decomposition 3 (name: _crx_to_ppr) 0: ───────────╭RZX(-0.25)─┤ 1: ──RX(0.25)─╰RZX(-0.25)─┤ Gate Count: {PauliRot(pauli_word=ZX): 1, PauliRot(pauli_word=X): 1}
For each decomposition rule, the output includes its name, circuit diagram, gate count, and wire allocation (if any). Alternatively, you can inspect a single decomposition rule by passing its name.
>>> print(qp.inspect_decomps(qp.CRX(0.5, wires=[0, 1]), "_crx_to_h_crz")) Name: _crx_to_h_crz 0: ────╭●───────────┤ 1: ──H─╰RZ(0.50)──H─┤ Gate Count: {Hadamard: 2, CRZ: 1}
Or use this tool to inspect a custom decomposition rule:
@qp.register_resources({qp.CNOT: 1, qp.H: 2}) def my_cz(wires): qp.H(wires[1]) qp.CNOT(wires) qp.H(wires[1])
>>> print(qp.inspect_decomps(qp.CZ([0, 1]), my_cz)) Name: my_cz 0: ────╭●────┤ 1: ──H─╰X──H─┤ Gate Count: {CNOT: 1, Hadamard: 2}