Qiskit addon utilities
เวอร์ชันของแพ็กเกจ
โค้ดในหน้านี้ถูกพัฒนาโดยใช้ requirement ต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
qiskit-addon-utils~=0.3.0
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-addon-utils qiskit-ibm-runtime
แพ็กเกจ Qiskit addon utilities คือชุดรวมฟังก์ชันเพื่อเสริม workflow ที่เกี่ยวข้องกับ Qiskit addon หนึ่งตัวหรือมากกว่า ตัวอย่างเช่น แพ็กเกจนี้มีฟังก์ชันสำหรับสร้าง Hamiltonian สร้าง Trotter time-evolution circuit และการ slice และรวม quantum circuit
การติดตั้ง
ติดตั้ง Qiskit addon utilities ได ้สองวิธี: PyPI และการ build จาก source แนะนำให้ติดตั้งแพ็กเกจเหล่านี้ใน virtual environment เพื่อแยก dependency ของแพ็กเกจออกจากกัน
ติดตั้งจาก PyPI
วิธีที่ตรงไปตรงมาที่สุดในการติดตั้งแพ็กเกจ Qiskit addon utilities คือผ่าน PyPI
pip install 'qiskit-addon-utils'
ติดตั้งจาก source
คลิก ที่นี่เพื่ออ่านวิธีติดตั้งแพ็กเกจนี้ด้วยตัวเอง
หากต้องการมีส่วนร่วมใน package นี้หรือต้องการติดตั้งด้วยตัวเอง ให้ clone repository ก่อน:
git clone git@github.com:Qiskit/qiskit-addon-utils.git
แล้วติดตั้งแพ็กเกจผ่าน pip หากวางแผนจะรัน tutorial ที่อยู่ใน package repository ให้ติดตั้ง notebook dependency ด้วย หากวางแผนจะพัฒนาใน repository ให้ติดตั้ง dependency แบบ dev
pip install tox jupyterlab -e '.[notebook-dependencies,dev]'
เริ่มต้นใช้งาน utilities
มีหลาย module ภายในแพ็กเกจ qiskit-addon-utils รวมถึงหนึ่ง module สำหรับ problem generation เพื่อจำลองระบบ quantum, graph coloring เพื่อ place Gate ใน quantum circuit ได้อย่างมีประสิทธิภาพมากขึ้น และ circuit slicing ซึ่งสามารถช่วยกับ operator backpropagation ได้ ส่วนต่อไปนี้สรุปแต่ละ module เอกสาร API ของแพ็กเกจยังมีข้อมูลที่เป็นประโยชน์อีกด้วย
Problem generation
เนื้อหาของ module qiskit_addon_utils.problem_generators ประกอบด้วย:
- ฟังก์ชัน
generate_xyz_hamiltonian()ซึ่งสร้างSparsePauliOprepresentation ที่คำนึงถึง connectivity ของ Ising-type XYZ model:
- ฟังก์ชัน
generate_time_evolution_circuit()ซึ่งสร้าง Circuit ที่จำลอง time evolution ของ operator ที่กำหนด - Object
PauliOrderStrategyสามตัวสำหรับการแจกแจง Pauli string ordering แบบต่างๆ ซึ่งส่วนใหญ่มีประโยชน์เมื่อใช้ร่วมกับ graph coloring และสามารถใช้เป็น argument ในทั้งฟังก์ชันgenerate_xyz_hamiltonian()และgenerate_time_evolution_circuit()
Graph coloring
Module qiskit_addon_utils.coloring ใช้สำหรับกำหนดสีให้กับ edge ใน coupling map และใช้การกำหนดสีนี้เพื่อ place Gate ใน quantum circuit ได้อย่างมีประสิทธิภาพมากขึ้น จุดประสงค์ของ edge-colored coupling map นี้คือการหาชุดสีของ edge เพื่อให้ edge สองเส้นที่มีสีเดียวกันไม่แชร์ node เดียวกัน สำหรับ QPU หมายความว่า Gate ตาม edge ที่มีสีเดียวกัน (การเชื่อมต่อ Qubit) สามารถรันพร้อมกันได้ และ Circuit จะรันเร็วขึ้น
เป็นตัวอย่างสั้นๆ สามารถใช้ฟังก์ชัน auto_color_edges() เพื่อสร้าง edge coloring สำหรับ Circuit แบบ naive ที่รัน CZGate ตาม qubit connection แต่ละจุด ตัวอย่างโค้ดด้านล่างใช้ coupling map ของ Backend FakeSherbrooke สร้าง Circuit แบบ naive นี้ จากนั้นใช้ฟังก์ชัน auto_color_edges() เพื่อสร้าง Circuit ที่เทียบเท่ากันแต่มีประสิทธิภาพมากขึ้น
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
from qiskit import QuantumCircuit
from qiskit_addon_utils.coloring import auto_color_edges
from qiskit_addon_utils.slicing import combine_slices, slice_by_depth
from collections import defaultdict
backend = FakeSherbrooke()
coupling_map = backend.coupling_map
# Create naive circuit
circuit = QuantumCircuit(backend.num_qubits)
for edge in coupling_map.graph.edge_list():
circuit.cz(edge[0], edge[1])
# Color the edges of the coupling map
coloring = auto_color_edges(coupling_map)
circuit_with_coloring = QuantumCircuit(backend.num_qubits)
# Make a reverse coloring dict in order to make the circuit
color_to_edge = defaultdict(list)
for edge, color in coloring.items():
color_to_edge[color].append(edge)
# Place edges in order of color
for edges in color_to_edge.values():
for edge in edges:
circuit_with_coloring.cz(edge[0], edge[1])
print(f"The circuit without using edge coloring has depth: {circuit.depth()}")
print(
f"The circuit using edge coloring has depth: {circuit_with_coloring.depth()}"
)
The circuit without using edge coloring has depth: 37
The circuit using edge coloring has depth: 3
Slicing
สุดท้าย module qiskit-addon-utils.slicing มีฟังก์ชันและ Transpiler pass สำหรับทำงานกับการสร้าง Circuit "slice" ซึ่งเป็น partition แบบ time-like ของ QuantumCircuit ที่ span ข้ามทุก Qubit slice เหล่านี้ส่วนใหญ่ใช้สำหรับ operator backpropagation สี่วิธีหลักในการ slice Circuit คือตาม gate type, depth, coloring หรือคำสั่ง Barrier ผลลัพธ์ของฟังก์ชัน slicing เหล่านี้คือ list ของ object QuantumCircuit Circuit ที่ slice แล้วยังสามารถรวมกลับได้โดยใช้ฟังก์ชัน combine_slices() อ่าน API reference ของ module สำหรับข้อมูลเพิ่มเติม
ด้านล่างเป็นตัวอย่างสองสามตัวอย่างเกี่ยวกับวิธีสร้าง slice เหล่านี้โดยใช้ Circuit ต่อไปนี้:
import numpy as np
from qiskit import QuantumCircuit
num_qubits = 9
qc = QuantumCircuit(num_qubits)
qc.ry(np.pi / 4, range(num_qubits))
qubits_1 = [i for i in range(num_qubits) if i % 2 == 0]
qubits_2 = [i for i in range(num_qubits) if i % 2 == 1]
qc.cx(qubits_1[:-1], qubits_2)
qc.cx(qubits_2, qubits_1[1:])
qc.cx(qubits_1[-1], qubits_1[0])
qc.rx(np.pi / 4, range(num_qubits))
qc.rz(np.pi / 4, range(num_qubits))
qc.draw("mpl", scale=0.6)
ในกรณีที่ไม่มีวิธีที่ชัดเจนในการใช้ประโยชน์จากโครงสร้างของ Circuit สำหรับ operator backpropagation สามารถ partition Circuit ออกเป็น slice ตาม depth ที่กำหนดได้
# Slice circuit into partitions of depth 1
slices = slice_by_depth(qc, 1)
# Recombine slices in order to visualize the partitions together
combined_slices = combine_slices(slices, include_barriers=True)
combined_slices.draw("mpl", scale=0.6)
ในกรณีเช่นเมื่อรัน Trotter circuit เพื่อจำลอง dynamics ของระบบ quantum การ slice ตาม gate type อาจเป็นประโยชน์
from qiskit_addon_utils.slicing import slice_by_gate_types
slices = slice_by_gate_types(qc)
# Recombine slices in order to visualize the partitions together
combined_slices = combine_slices(slices, include_barriers=True)
combined_slices.draw("mpl", scale=0.6)
หาก workload ของคุณถูกออกแบบให้ใช้ประโยชน์จาก physical qubit connectivity ของ QPU ที่จะรันบน สามารถสร้าง slice โดยอิงจาก edge coloring ได้ ตัวอย่างโค้ดด้านล่างจะกำหนด three-coloring ให้กับ Circuit edge และ slice Circuit ตาม edge coloring (หมายเหตุ: สิ่งนี้มีผลกับ non-local Gate เท่านั้น Single-qubit Gate จะถูก slice ตาม gate type)
from qiskit_addon_utils.slicing import slice_by_coloring
# Assign a color to each set of connected qubits
coloring = {}
for i in range(num_qubits - 1):
coloring[(i, i + 1)] = i % 3
coloring[(num_qubits - 1, 0)] = 2
# Create a circuit with operations added in order of color
qc = QuantumCircuit(num_qubits)
qc.ry(np.pi / 4, range(num_qubits))
edges = [
edge for color in range(3) for edge in coloring if coloring[edge] == color
]
for edge in edges:
qc.cx(edge[0], edge[1])
qc.rx(np.pi / 4, range(num_qubits))
qc.rz(np.pi / 4, range(num_qubits))
# Create slices by edge color
slices = slice_by_coloring(qc, coloring=coloring)
# Recombine slices in order to visualize the partitions together
combined_slices = combine_slices(slices, include_barriers=True)
combined_slices.draw("mpl", scale=0.6)
หากมี slicing strategy แบบกำหนดเอง สามารถ place barrier ใน Circuit เพื่อระบุจุดที่ควร slice และใช้ฟังก์ชัน slice_by_barriers แทนได้
qc = QuantumCircuit(num_qubits)
qc.ry(np.pi / 4, range(num_qubits))
qc.barrier()
qubits_1 = [i for i in range(num_qubits) if i % 2 == 0]
qubits_2 = [i for i in range(num_qubits) if i % 2 == 1]
qc.cx(qubits_1[:-1], qubits_2)
qc.cx(qubits_2, qubits_1[1:])
qc.cx(qubits_1[-1], qubits_1[0])
qc.barrier()
qc.rx(np.pi / 4, range(num_qubits))
qc.rz(np.pi / 4, range(num_qubits))
qc.draw("mpl", scale=0.6)
เมื่อ barrier อยู่ในที่แล้ว สามารถตรวจสอบแต่ละ slice แยกกันได้
from qiskit_addon_utils.slicing import slice_by_barriers
slices = slice_by_barriers(qc)
slices[0].draw("mpl", scale=0.6)
slices[1].draw("mpl", scale=0.6)
slices[2].draw("mpl", scale=0.6)
ขั้นตอนถัดไป
- อ่านภาพรวมของ OBP addon
- ทำความเข้าใจวิธีการทำงานของ SQD addon
- ทำความคุ้นเคยกับ AQC-Tensor addon