ข้ามไปยังเนื้อหาหลัก

การตัดสายสัญญาณสำหรับการประมาณค่าความคาดหวัง

ประมาณการใช้งาน: หนึ่งนาทีบนโปรเซสเซอร์ Eagle (หมายเหตุ: นี่เป็นเพียงการประมาณการเท่านั้น เวลาจริงอาจแตกต่างออกไป)

พื้นหลัง

Circuit-knitting เป็นคำรวมที่ครอบคลุมวิธีการต่างๆ ในการแบ่ง Circuit ออกเป็น subcircuit ขนาดเล็กหลายๆ ชิ้น ซึ่งประกอบด้วย Gate และ/หรือ Qubit น้อยลง แต่ละ subcircuit สามารถรันได้อิสระ และผลลัพธ์สุดท้ายได้จากการประมวลผลแบบคลาสสิกผ่านผลลัพธ์ของแต่ละ subcircuit เทคนิคนี้เข้าถึงได้ผ่าน Qiskit addon สำหรับการตัด Circuit โดยมีคำอธิบายอย่างละเอียดของเทคนิคนี้อยู่ใน docs พร้อมด้วย เนื้อหาเบื้องต้นอื่นๆ

โน้ตบุ๊กนี้เกี่ยวกับวิธีที่เรียกว่า wire cutting ซึ่ง Circuit ถูกแบ่งตามสายสัญญาณ [1], [2] สังเกตว่าในวงจรคลาสสิก การแบ่งนั้นง่ายเพราะผลลัพธ์ที่จุดแบ่งสามารถกำหนดได้แน่นอน คือ 0 หรือ 1 อย่างไรก็ตาม สถานะของ Qubit ที่จุดตัดนั้น โดยทั่วไปจะเป็น mixed state ดังนั้นแต่ละ subcircuit จึงต้องวัดหลายครั้งในฐาน (basis) ที่แตกต่างกัน (โดยทั่วไปจะเป็นชุด basis ที่ครบถ้วนสำหรับ tomography เช่น Pauli basis [3], [4]) และเตรียมใน eigenstate ที่สอดคล้องกัน ภาพด้านล่าง (ที่มา: PhD Thesis, Ritajit Majumdar) แสดงตัวอย่างของ wire cutting สำหรับ GHZ state ขนาด 4 Qubit ออกเป็นสาม subcircuit ที่นี่ MjM_j แทนชุดของ basis (โดยทั่วไปคือ Pauli X, Y และ Z) และ PiP_i แทนชุดของ eigenstate (โดยทั่วไปคือ 0|0\rangle, 1|1\rangle, +|+\rangle และ +i|+i\rangle)

wc-1.png wc-2.png

เนื่องจากแต่ละ subcircuit มี Qubit และ/หรือ Gate น้อยกว่า จึงคาดว่าจะได้รับผลกระทบจากสัญญาณรบกวนน้อยลง โน้ตบุ๊กนี้แสดงตัวอย่างที่วิธีนี้สามารถใช้เพื่อลดสัญญาณรบกวนในระบบได้อย่างมีประสิทธิภาพ

สิ่งที่ต้องการ

ก่อนเริ่มบทเรียนนี้ ต้องติดตั้งสิ่งต่อไปนี้:

  • Qiskit SDK v2.0 หรือใหม่กว่า พร้อมรองรับ visualization
  • Qiskit Runtime v0.22 หรือใหม่กว่า ( pip install qiskit-ibm-runtime )
  • Circuit cutting Qiskit addon v0.9.0 หรือใหม่กว่า (pip install qiskit-addon-cutting)

เราจะพิจารณาวงจร Many Body Localization (MBL) สำหรับโน้ตบุ๊กนี้ วงจร MBL เป็นวงจรที่มีประสิทธิภาพสำหรับฮาร์ดแวร์และมีพารามิเตอร์สองตัวคือ θ\theta และ ϕ\vec{\phi} เมื่อกำหนด θ\theta เป็น 00 และเตรียมสถานะเริ่มต้นใน 0|0\rangle สำหรับ Qubit ทั้งหมด ค่าความคาดหวังในอุดมคติของ Zi\langle Z_i \rangle จะเท่ากับ +1+1 สำหรับทุก Qubit ตำแหน่ง ii โดยไม่ขึ้นกับค่าของ ϕ\vec{\phi} สามารถดูรายละเอียดเพิ่มเติมเกี่ยวกับวงจร MBL ได้ใน บทความนี้

ตั้งค่า

# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-addon-cutting qiskit-ibm-runtime
import numpy as np
import matplotlib.pyplot as plt

from qiskit.circuit import Parameter, ParameterVector, QuantumCircuit
from qiskit.quantum_info import PauliList, SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.result import sampled_expectation_value

from qiskit_addon_cutting.instructions import CutWire
from qiskit_addon_cutting import (
cut_wires,
expand_observables,
partition_problem,
generate_cutting_experiments,
reconstruct_expectation_values,
)

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2, Batch

class MBLChainCircuit(QuantumCircuit):
def __init__(
self, num_qubits: int, depth: int, use_cut: bool = False
) -> None:
super().__init__(
num_qubits, name=f"MBLChainCircuit<{num_qubits}, {depth}>"
)
evolution = MBLChainEvolution(num_qubits, depth, use_cut)
self.compose(evolution, inplace=True)

class MBLChainEvolution(QuantumCircuit):
def __init__(self, num_qubits: int, depth: int, use_cut) -> None:
super().__init__(
num_qubits, name=f"MBLChainEvolution<{num_qubits}, {depth}>"
)

theta = Parameter("θ")
phis = ParameterVector("φ", num_qubits)

for layer in range(depth):
layer_parity = layer % 2
# print("layer parity", layer_parity)
for qubit in range(layer_parity, num_qubits - 1, 2):
# print(qubit)
self.cz(qubit, qubit + 1)
self.u(theta, 0, np.pi, qubit)
self.u(theta, 0, np.pi, qubit + 1)
if (
use_cut
and layer_parity == 0
and (
qubit == num_qubits // 2 - 1
or qubit == num_qubits // 2
)
):
self.append(CutWire(), [num_qubits // 2])
if use_cut and layer < depth - 1 and layer_parity == 1:
if qubit == num_qubits // 2:
self.append(CutWire(), [qubit])
for qubit in range(num_qubits):
self.p(phis[qubit], qubit)

ส่วนที่ I. ตัวอย่างขนาดเล็ก

ขั้นตอนที่ 1: แมปอินพุตแบบคลาสสิกไปยังปัญหาควอนตัม

ก่อนอื่นเราสร้าง Circuit แม่แบบโดยไม่มีค่าพารามิเตอร์ที่เฉพาะเจาะจง เรายังเพิ่ม placeholder ที่เรียกว่า CutWire เพื่อระบุตำแหน่งของการตัด สำหรับตัวอย่างขนาดเล็ก เราพิจารณาวงจร MBL ขนาด 10 Qubit

num_qubits = 10
depth = 2
mbl = MBLChainCircuit(num_qubits, depth)
mbl.draw("mpl", fold=-1)

Output of the previous code cell

ระลึกว่าเราต้องการหาค่าความคาดหวังของ observable 1ni=1nZi\frac{1}{n}\sum_{i=1} ^n Z_i เมื่อ θ=0\theta=0 เราจะกำหนดค่าสุ่มให้กับพารามิเตอร์ ϕ\vec{\phi}

phis = list(np.random.rand(mbl.num_parameters - 1))
theta = [0]
params = theta + phis
params
[0,
0.2376615174332788,
0.28244289857682414,
0.019248960591717768,
0.46140600996102477,
0.31408025180068433,
0.718184005135733,
0.991153920182475,
0.09289485768301442,
0.8857848280067783,
0.6177529765767047]

ตอนนี้เราระบุตำแหน่งการตัดใน Circuit โดยแทรก CutWire ที่เหมาะสมเพื่อสร้างการตัดที่มีขนาดใกล้เคียงกันสองส่วน เรากำหนด use_cut=True ในฟังก์ชัน และให้มันระบุตำแหน่งหลังจาก n2\frac{n}{2} Qubit โดยที่ nn คือจำนวน Qubit ในวงจรดั้งเดิม

mbl_cut = MBLChainCircuit(num_qubits, depth, use_cut=True)
mbl_cut.assign_parameters(params, inplace=True)
mbl_cut.draw("mpl", fold=-1)

Output of the previous code cell

ขั้นตอนที่ 2: ปรับ Circuit ให้เหมาะสมสำหรับการรันบนฮาร์ดแวร์ควอนตัม

ต่อไปเราตัด Circuit ออกเป็น subcircuit ขนาดเล็ก สองชิ้น สำหรับตัวอย่างนี้เราจำกัดที่ 2 subcircuit เท่านั้น สำหรับสิ่งนี้ เราใช้ Qiskit Addon: Circuit Cutting

ตัด Circuit ออกเป็น subcircuit ขนาดเล็ก

การตัดสายสัญญาณที่จุดหนึ่งจะเพิ่มจำนวน Qubit ขึ้นหนึ่งตัว นอกจาก Qubit เดิมแล้ว ยังมี Qubit เพิ่มเติมอีกหนึ่งตัวเป็น placeholder สำหรับ Circuit หลังการตัด ภาพต่อไปนี้แสดงให้เห็นถึงสิ่งนี้:

wc-4.png

Addon นี้ใช้ฟังก์ชัน cut_wires เพื่อรองรับ Qubit เพิ่มเติมที่เกิดจากการตัด

mbl_move = cut_wires(mbl_cut)

สร้างและขยาย observable

ตอนนี้เราสร้าง observable Mz=1ni=1nZiM_z = \frac{1}{n}\sum_{i=1}^n \langle Z_i \rangle เนื่องจากผลลัพธ์ในอุดมคติของ Zi\langle Z_i \rangle สำหรับแต่ละ ii คือ +1+1 ดังนั้นผลลัพธ์ในอุดมคติของ MzM_z ก็คือ +1+1 เช่นกัน

observable = PauliList(
["I" * i + "Z" + "I" * (num_qubits - i - 1) for i in range(num_qubits)]
)
observable
PauliList(['ZIIIIIIIII', 'IZIIIIIIII', 'IIZIIIIIII', 'IIIZIIIIII',
'IIIIZIIIII', 'IIIIIZIIII', 'IIIIIIZIII', 'IIIIIIIZII',
'IIIIIIIIZI', 'IIIIIIIIIZ'])

อย่างไรก็ตาม สังเกตว่าจำนวน Qubit ใน Circuit ได้เพิ่มขึ้นหลังจากแทรกการดำเนินการ Move เสมือน 2 Qubit หลังการตัด ดังนั้นเราจึงต้องขยาย observable ด้วยโดยแทรก identity เพื่อให้ตรงกับ Circuit ปัจจุบัน

new_obs = expand_observables(observable, mbl, mbl_move)
new_obs
PauliList(['ZIIIIIIIIII', 'IZIIIIIIIII', 'IIZIIIIIIII', 'IIIZIIIIIII',
'IIIIZIIIIII', 'IIIIIIZIIII', 'IIIIIIIZIII', 'IIIIIIIIZII',
'IIIIIIIIIZI', 'IIIIIIIIIIZ'])

สังเกตว่าแต่ละ observable ได้ขยายออกเพื่อรองรับเจ็ด Qubit ตามที่ Circuit พร้อมการดำเนินการ Move กำหนด แทนที่จะเป็น 6 Qubit เดิม ต่อไป แบ่ง Circuit ออกเป็นสอง subcircuit

partitioned_problem = partition_problem(circuit=mbl_move, observables=new_obs)

มาดู subcircuit กัน

subcircuits = partitioned_problem.subcircuits
subcircuits[0].draw("mpl", fold=-1)

Output of the previous code cell

subcircuits[1].draw("mpl", fold=-1)

Output of the previous code cell

observable ก็ถูกแบ่งด้วยเพื่อให้เข้ากับ subcircuit

subobservables = partitioned_problem.subobservables
subobservables
{0: PauliList(['IIIIII', 'IIIIII', 'IIIIII', 'IIIIII', 'IIIIII', 'IZIIII',
'IIZIII', 'IIIZII', 'IIIIZI', 'IIIIIZ']),
1: PauliList(['ZIIII', 'IZIII', 'IIZII', 'IIIZI', 'IIIIZ', 'IIIII', 'IIIII',
'IIIII', 'IIIII', 'IIIII'])}

สังเกตว่าแต่ละ subcircuit จะสร้างตัวอย่างจำนวนหนึ่ง การ reconstruct จะนำผลลัพธ์ของแต่ละตัวอย่างเหล่านี้มาคำนึงถึง แต่ละตัวอย่างเหล่านี้เรียกว่า subexperiment การขยาย observable โดยใช้การดำเนินการ Move ต้องใช้โครงสร้างข้อมูล PauliList เราสามารถสร้าง observable MzM_z ในโครงสร้างข้อมูล SparsePauliOp ที่มีความยืดหยุ่นมากกว่า ซึ่งจะมีประโยชน์ในภายหลังระหว่างการ reconstruct subexperiment

M_z = SparsePauliOp(
["I" * i + "Z" + "I" * (num_qubits - i - 1) for i in range(num_qubits)],
coeffs=[1 / num_qubits] * num_qubits,
)
M_z
SparsePauliOp(['ZIIIIIIIII', 'IZIIIIIIII', 'IIZIIIIIII', 'IIIZIIIIII', 'IIIIZIIIII', 'IIIIIZIIII', 'IIIIIIZIII', 'IIIIIIIZII', 'IIIIIIIIZI', 'IIIIIIIIIZ'],
coeffs=[0.1+0.j, 0.1+0.j, 0.1+0.j, 0.1+0.j, 0.1+0.j, 0.1+0.j, 0.1+0.j, 0.1+0.j,
0.1+0.j, 0.1+0.j])
subexperiments, coefficients = generate_cutting_experiments(
circuits=subcircuits,
observables=subobservables,
num_samples=np.inf,
)

มาดูตัวอย่างสองตัวอย่างที่ Qubit ที่ถูกตัดถูกวัดใน basis สองแบบที่แตกต่างกัน ครั้งแรกวัดใน basis Z ปกติ และครั้งต่อไปวัดใน basis X

subexperiments[0][6].draw("mpl", fold=-1)

Output of the previous code cell

subexperiments[0][2].draw("mpl", fold=-1)

Output of the previous code cell

Transpile แต่ละ subexperiment

ตอนนี้เราต้องทำการ Transpile Circuit ก่อนส่งไปรันจริง ดังนั้นเราจะ Transpile แต่ละ Circuit ใน subexperiment ก่อน

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)

ตอนนี้เราต้องทำการ Transpile แต่ละ Circuit ใน subexperiment สำหรับสิ่งนี้ เราสร้าง pass manager ก่อน แล้วจึงใช้มันในการ Transpile แต่ละ Circuit

pm = generate_preset_pass_manager(optimization_level=2, backend=backend)
isa_subexperiments = {
label: pm.run(partition_subexpts)
for label, partition_subexpts in subexperiments.items()
}
isa_subexperiments[0][0].draw("mpl", fold=-1, idle_wires=False)

Output of the previous code cell

ขั้นตอนที่ 3: รันโดยใช้ Qiskit primitives

ตอนนี้เราจะรันแต่ละ Circuit ใน subexperiment Qiskit-addon-cutting ใช้ SamplerV2 เพื่อรัน subexperiment

with Batch(backend=backend) as batch:
sampler = SamplerV2(mode=batch)
jobs = {
label: sampler.run(subsystem_subexpts, shots=2**12)
for label, subsystem_subexpts in isa_subexperiments.items()
}

ขั้นตอนที่ 4: ประมวลผลหลังการรันและส่งคืนผลลัพธ์ในรูปแบบคลาสสิกที่ต้องการ

เมื่อรัน Circuit เสร็จแล้ว ตอนนี้เราต้องดึงผลลัพธ์และ reconstruct ค่าความคาดหวังสำหรับ Circuit ที่ไม่ได้ตัดและ observable ดั้งเดิม

# Retrieve results
results = {label: job.result() for label, job in jobs.items()}
reconstructed_expval_terms = reconstruct_expectation_values(
results,
coefficients,
subobservables,
)
reconstructed_expval = np.dot(reconstructed_expval_terms, M_z.coeffs).real
reconstructed_expval
0.9674376845359803

ตรวจสอบไขว้

ตอนนี้มารัน Circuit โดยไม่มีการตัดและตรวจสอบผลลัพธ์ สังเกตว่าสำหรับการรัน Circuit ที่ไม่ได้ตัด เราสามารถใช้ EstimatorV2 โดยตรงเพื่อคำนวณค่าความคาดหวัง แต่เราจะใช้ Primitive เดียวกันตลอด ดังนั้นเราจะใช้ SamplerV2 เพื่อรับการกระจาย probability และคำนวณค่าความคาดหวังโดยใช้ฟังก์ชัน sampled_expectation_value

ก่อนอื่นเราต้อง Transpile mbl Circuit ที่ไม่ได้ตัด

sampler = SamplerV2(mode=backend)

if mbl.num_clbits == 0:
mbl.measure_all()
isa_mbl = pm.run(mbl)

ต่อไปเราสร้าง pub และรัน Circuit ที่ไม่ได้ตัด

pub = (isa_mbl, params)
uncut_job = sampler.run([pub])
uncut_counts = uncut_job.result()[0].data.meas.get_counts()
uncut_expval = sampled_expectation_value(uncut_counts, M_z)
uncut_expval
0.9498046875000001

เราสังเกตว่าค่าความคาดหวังที่ได้จาก wire cutting นั้นใกล้เคียงกับค่าในอุดมคติที่ +1+1 มากกว่าแบบที่ไม่ตัด ตอนนี้มาขยายขนาดของปัญหากัน

Part II. ขยายขนาดกันเลย!

ก่อนหน้านี้ เราแสดงผลลัพธ์สำหรับ Circuit MBL ขนาด 10 Qubit ต่อไปเราจะแสดงให้เห็นว่าการปรับปรุงค่า expectation value นั้นสามารถทำได้กับ Circuit ที่ใหญ่กว่าด้วย เพื่อพิสูจน์สิ่งนี้ เราจะทำกระบวนการเดิมซ้ำสำหรับ Circuit MBL ขนาด 60 Qubit

ขั้นตอนที่ 1: แปลง input แบบ classical เป็นปัญหา quantum

num_qubits = 60
depth = 2
mbl = MBLChainCircuit(num_qubits, depth)

เราสร้างชุดค่าสุ่มสำหรับ ϕ\vec{\phi}

phis = list(np.random.rand(mbl.num_parameters - 1))
theta = [0]
params = theta + phis

จากนั้นสร้าง Circuit ที่ถูก cut

mbl_cut = MBLChainCircuit(num_qubits, depth, use_cut=True)
mbl_cut.assign_parameters(params, inplace=True)
mbl_cut.draw("mpl", fold=-1)

ขั้นตอนที่ 2: ปรับปรุงปัญหาสำหรับการรันบน quantum hardware

เช่นเดียวกับตัวอย่างขนาดเล็ก เราแบ่งพาร์ติชัน Circuit และ observable สำหรับการทดลอง cutting

mbl_move = cut_wires(mbl_cut)

# Define observable
observable = PauliList(
["I" * i + "Z" + "I" * (num_qubits - i - 1) for i in range(num_qubits)]
)
new_obs = expand_observables(observable, mbl, mbl_move)

# Partition the circuit into subcircuits
partitioned_problem = partition_problem(circuit=mbl_move, observables=new_obs)

# Get subcircuits
subcircuits = partitioned_problem.subcircuits
subobservables = partitioned_problem.subobservables

เราสร้าง object SparsePauliOp สำหรับ observable พร้อมกับ coefficient ที่เหมาะสมด้วย

M_z = SparsePauliOp(
["I" * i + "Z" + "I" * (num_qubits - i - 1) for i in range(num_qubits)],
coeffs=[1 / num_qubits] * num_qubits,
)

จากนั้นสร้าง subexperiment และ transpile แต่ละ Circuit ใน subexperiment

subexperiments, coefficients = generate_cutting_experiments(
circuits=subcircuits,
observables=subobservables,
num_samples=np.inf,
)
isa_subexperiments = {
label: pm.run(partition_subexpts)
for label, partition_subexpts in subexperiments.items()
}

ขั้นตอนที่ 3: รันด้วย Qiskit primitives

เราใช้โหมด Batch เพื่อรัน Circuit ทั้งหมดใน subexperiment

with Batch(backend=backend) as batch:
sampler = SamplerV2(mode=batch)
jobs = {
label: sampler.run(subsystem_subexpts, shots=2**12)
for label, subsystem_subexpts in isa_subexperiments.items()
}

ขั้นตอนที่ 4: ประมวลผลหลังการรันและคืนผลในรูปแบบ classical ที่ต้องการ

มาดึงผลลัพธ์ของแต่ละ Circuit ใน subexperiment และสร้าง expectation value ใหม่ที่สอดคล้องกับ Circuit ที่ไม่ถูก cut และ observable เดิม

# Retrieve results
results = {label: job.result() for label, job in jobs.items()}
reconstructed_expval_terms = reconstruct_expectation_values(
results,
coefficients,
subobservables,
)
reconstructed_expval = np.dot(reconstructed_expval_terms, M_z.coeffs).real
reconstructed_expval
0.9631355921427409

ตรวจสอบข้ามกัน

เช่นเดียวกับตัวอย่างขนาดเล็ก เราจะหาค่า expectation value อีกครั้งโดยการรัน Circuit ที่ไม่ถูก cut และเปรียบเทียบผลลัพธ์กับ circuit cutting เราจะใช้ SamplerV2 เพื่อให้การใช้ Primitives มีความสม่ำเสมอ

sampler = SamplerV2(mode=backend)

if mbl.num_clbits == 0:
mbl.measure_all()
isa_mbl = pm.run(mbl)

pub = (isa_mbl, params)
uncut_job = sampler.run([pub])
uncut_counts = uncut_job.result()[0].data.meas.get_counts()
uncut_expval = sampled_expectation_value(uncut_counts, M_z)
uncut_expval
0.9426757812499998

แสดงผลด้วยกราฟ

มาแสดงผลการปรับปรุงที่ได้จากการใช้ wire cutting ต่อค่า expectation value

ax = plt.gca()
methods = ["cut", "uncut"]
values = [reconstructed_expval, uncut_expval]

plt.bar(methods, values, color="#a56eff", width=0.4, edgecolor="#8a3ffc")
plt.axhline(y=1, color="k", linestyle="--")
ax.set_ylim([0.85, 1.02])
plt.text(0.3, 0.99, "Exact result")
plt.show()

Output of the previous code cell

ข้อสรุป

เราสังเกตว่าทั้งในปัญหาขนาดเล็กและขนาดใหญ่ wire cutting ให้ผลลัพธ์ที่ดีกว่า Circuit ที่ไม่ถูก cut โปรดทราบว่าไม่มีการใช้เทคนิค error mitigation ใดๆ ในการทดลองเหล่านี้ ดังนั้นการปรับปรุงผลลัพธ์ที่ได้มาจาก wire cutting เพียงอย่างเดียว อาจเป็นไปได้ที่จะปรับปรุงผลลัพธ์ให้ดียิ่งขึ้นโดยใช้วิธี mitigation ต่างๆ ร่วมกับ circuit cutting

นอกจากนี้ ใน notebook นี้เรารัน subcircuit ทั้งสองบน hardware เดียวกัน ใน [5], [6] ผู้เขียนแสดงวิธีการกระจาย subcircuit ไปบน hardware ต่างๆ โดยใช้ข้อมูล noise เพื่อเพิ่มการระงับ noise ให้สูงสุด และทำกระบวนการแบบขนาน

ภาคผนวก: การพิจารณาการขยายขนาดทรัพยากร

จำนวน Circuit ที่ต้องรันจะเพิ่มขึ้นตามจำนวนการ cut ดังนั้น แม้ว่าการ cut หลายครั้งจะทำให้ได้ subcircuit ที่เล็กลง ซึ่งช่วยปรับปรุงประสิทธิภาพได้มากขึ้น แต่ก็ทำให้จำนวนการรัน Circuit สูงมากจนอาจไม่เหมาะสมสำหรับกรณีส่วนใหญ่ ด้านล่างนี้ เราแสดงตัวอย่างจำนวน subcircuit ที่สอดคล้องกับจำนวนการ cut สำหรับ Circuit ขนาด 50 Qubit

wc-5.png

โปรดทราบว่าแม้แต่การ cut 5 ครั้ง จำนวน subexperiment ก็อยู่ที่ประมาณ 200,000 ดังนั้นควรใช้ circuit cutting เฉพาะเมื่อจำนวนการ cut มีน้อยเท่านั้น

ตัวอย่างของ Circuit ที่ cut ได้ดีและ Circuit ที่ cut ได้ไม่ดี

Circuit ที่ cut ได้ดี

ดังที่กล่าวไว้ก่อนหน้านี้ Circuit จะ cut ได้ดีเมื่อสามารถแบ่งพาร์ติชันเป็น subcircuit ที่เล็กกว่าและแยกกันได้ด้วยการ cut จำนวนน้อย Circuit ที่มีประสิทธิภาพกับ hardware นั่นคือ Circuit ที่ต้องใช้ SWAP Gate น้อยหรือไม่มีเลยเมื่อ map ไปบน coupling map ของ hardware โดยทั่วไปจะ cut ได้ดี ด้านล่างนี้ เราแสดงตัวอย่างของ excitation preserving ansatz ซึ่งใช้ใน Quantum Chemistry โปรดสังเกตว่า Circuit ดังกล่าวสามารถแบ่งพาร์ติชันเป็น subcircuit สองส่วนด้วยการ cut เพียงครั้งเดียว โดยไม่ขึ้นกับจำนวน Qubit

wc-6.png

Circuit ที่ cut ได้ไม่ดี

Circuit จะ cut ได้ไม่ดีถ้าโดยทั่วไปจำนวนการ cut ที่ต้องการเพื่อสร้างพาร์ติชันที่แยกกันเพิ่มขึ้นอย่างมีนัยสำคัญตาม depth หรือจำนวน Qubit โปรดจำไว้ว่าแต่ละการ cut ต้องใช้ Qubit เพิ่มขึ้นหนึ่งตัว ดังนั้นเมื่อจำนวนการ cut เพิ่มขึ้น จำนวน Qubit ที่มีประสิทธิภาพก็เพิ่มขึ้นด้วย ด้านล่างนี้ เราแสดงตัวอย่างของ Grover Circuit ขนาด 3 Qubit พร้อมกับตัวอย่างการ cutting ที่เป็นไปได้

wc-7.png

เราสังเกตว่าต้องใช้การ cut ถึงสามครั้ง และการ cut นั้นมีลักษณะแนวตั้งมากกว่าแนวนอน ซึ่งหมายความว่าจำนวนการ cut คาดว่าจะเพิ่มขึ้นเป็นเชิงเส้นตามจำนวน Qubit ซึ่งไม่เหมาะสำหรับการ cutting

References

[1] Peng, T., Harrow, A. W., Ozols, M., & Wu, X. (2020). Simulating large quantum circuits on a small quantum computer. Physical review letters, 125(15), 150504.

[2] Tang, W., Tomesh, T., Suchara, M., Larson, J., & Martonosi, M. (2021, April). Cutqc: using small quantum computers for large quantum circuit evaluations. In Proceedings of the 26th ACM International conference on architectural support for programming languages and operating systems (pp. 473-486).

[3] Perlin, M. A., Saleem, Z. H., Suchara, M., & Osborn, J. C. (2021). Quantum circuit cutting with maximum-likelihood tomography. npj Quantum Information, 7(1), 64.

[4] Majumdar, R., & Wood, C. J. (2022). Error mitigated quantum circuit cutting. arXiv preprint arXiv:2211.13431.

[5] Khare, T., Majumdar, R., Sangle, R., Ray, A., Seshadri, P. V., & Simmhan, Y. (2023). Parallelizing Quantum-Classical Workloads: Profiling the Impact of Splitting Techniques. In 2023 IEEE International Conference on Quantum Computing and Engineering (QCE) (Vol. 1, pp. 990-1000). IEEE.

[6] Bhoumik, D., Majumdar, R., Saha, A., & Sur-Kolay, S. (2023). Distributed Scheduling of Quantum Circuits with Noise and Time Optimization. arXiv preprint arXiv:2309.06005.

แบบสำรวจ tutorial

Link to survey

Note: This survey is provided by IBM Quantum and relates to the original English content. To give feedback on doQumentation's website, translations, or code execution, please open a GitHub issue.

กรุณาทำแบบสำรวจสั้นๆ นี้เพื่อให้ feedback เกี่ยวกับ tutorial นี้ ข้อมูลของคุณจะช่วยเราปรับปรุงเนื้อหาและประสบการณ์การใช้งาน

Source: IBM Quantum docs — updated 6 พ.ค. 2569
English version on doQumentation — updated 7 พ.ค. 2569
This translation based on the English version of 9 เม.ย. 2569