انتقل إلى المحتوى الرئيسي

Automatically find cuts

لم تُترجم بعد

هذه الصفحة لم تُترجم بعد. يتم عرض المحتوى باللغة الإنجليزية.

Step 1: Map

Create a circuit and observables

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-addon-cutting
import numpy as np
from qiskit.circuit.random import random_circuit
from qiskit.quantum_info import SparsePauliOp

circuit = random_circuit(7, 6, max_operands=2, seed=1242)
observable = SparsePauliOp(["ZIIIIII", "IIIZIII", "IIIIIIZ"])

circuit.draw("mpl", scale=0.8)

Quantum circuit diagram

Step 2: Optimize

Find cut locations, given a maximum of 4 qubits per subcircuit. This circuit can be separated in two by making a single wire cut and cutting one CRZGate

from qiskit_addon_cutting.automated_cut_finding import (
find_cuts,
OptimizationParameters,
DeviceConstraints,
)

# Specify settings for the cut-finding optimizer
optimization_settings = OptimizationParameters(seed=111)

# Specify the size of the QPUs available
device_constraints = DeviceConstraints(qubits_per_subcircuit=4)

cut_circuit, metadata = find_cuts(circuit, optimization_settings, device_constraints)
print(
f'Found solution using {len(metadata["cuts"])} cuts with a sampling '
f'overhead of {metadata["sampling_overhead"]}.\n'
f'Lowest cost solution found: {metadata["minimum_reached"]}.'
)
for cut in metadata["cuts"]:
print(f"{cut[0]} at circuit instruction index {cut[1]}")
cut_circuit.draw("mpl", scale=0.8, fold=-1)
Found solution using 2 cuts with a sampling overhead of 127.06026169907257.
Lowest cost solution found: True.
Wire Cut at circuit instruction index 19
Gate Cut at circuit instruction index 28

Quantum circuit diagram

Add ancillas for wire cuts and expand the observables to account for ancilla qubits

from qiskit_addon_cutting import cut_wires, expand_observables

qc_w_ancilla = cut_wires(cut_circuit)
observables_expanded = expand_observables(observable.paulis, circuit, qc_w_ancilla)
qc_w_ancilla.draw("mpl", scale=0.8, fold=-1)

Quantum circuit diagram

Partition the circuit and observables into subcircuits and subobservables. Calculate the sampling overhead incurred from cutting these gates and wires.

from qiskit_addon_cutting import partition_problem

partitioned_problem = partition_problem(
circuit=qc_w_ancilla, observables=observables_expanded
)
subcircuits = partitioned_problem.subcircuits
subobservables = partitioned_problem.subobservables
print(
f"Sampling overhead: {np.prod([basis.overhead for basis in partitioned_problem.bases])}"
)
Sampling overhead: 127.06026169907257
subobservables
{0: PauliList(['IIII', 'IZII', 'IIIZ']),
1: PauliList(['ZIII', 'IIII', 'IIII'])}
subcircuits[0].draw("mpl", style="iqp", scale=0.8)

Quantum circuit diagram

subcircuits[1].draw("mpl", style="iqp", scale=0.8)

Quantum circuit diagram

Generate the experiments to run on the backend.

from qiskit_addon_cutting import generate_cutting_experiments

subexperiments, coefficients = generate_cutting_experiments(
circuits=subcircuits, observables=subobservables, num_samples=1_000
)
print(
f"{len(subexperiments[0]) + len(subexperiments[1])} total subexperiments to run on backend."
)
96 total subexperiments to run on backend.

Steps 3 and 4 of a Qiskit pattern can then be performed as in the preceding tutorials.