أدوات Qiskit addon المساعدة
Package versions
The code on this page was developed using the following requirements. We recommend using these versions or newer.
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 المساعدة هي مجموعة من الوظائف التي تُكمّل سير العمل التي تتضمن addon واحدة أو أكثر من Qiskit addons. على سبيل المثال، تحتوي هذه الحزمة على دوال لإنشاء الهاملتونيات (Hamiltonians)، وتوليد دوائر التطور الزمني (Trotter time-evolution circuits)، وتقسيم الدوائر الكمومية ودمجها.
التثبيت
يوجد طريقتان لتثبيت حزمة أدوات Qiskit addon المساعدة: عبر PyPI أو البناء من المصدر. يُنصح بتثبيت هذه الحزم داخل بيئة افتراضية لضمان عزل تبعيات الحزم.
التثبيت من PyPI
أسهل طريقة لتثبيت حزمة أدوات Qiskit addon المساعدة هي عبر PyPI.
pip install 'qiskit-addon-utils'
التثبيت من المصدر
Click here to read how to install this package manually.
إذا أردت المساهمة في هذه الحزمة أو تثبيتها يدويًا، ابدأ باستنساخ المستودع:
git clone git@github.com:Qiskit/qiskit-addon-utils.git
ثم ثبّت الحزمة عبر pip. إذا كنت تخطط لتشغيل الدروس التعليمية الموجودة في مستودع الحزمة، ثبّت تبعيات notebook أيضًا. وإذا كنت تخطط للتطوير في المستودع، ثبّت تبعيات dev.
pip install tox jupyterlab -e '.[notebook-dependencies,dev]'
البدء باستخدام الأدوات المساعدة
توجد عدة وحدات (modules) داخل حزمة qiskit-addon-utils، منها وحدة لتوليد المسائل لمحاكاة الأنظمة الكمومية، وأخرى لتلوين الرسم البياني (graph coloring) لوضع البوابات في الدائرة الكمومية بصورة أكثر كفاءة، ووحدة لتقسيم الدوائر (circuit slicing) التي يمكن أن تساعد في الانتشار العكسي للمؤثرات (operator backpropagation). تُلخّص الأقسام التالية كل وحدة. كما تحتوي وثائق API الخاصة بالحزمة على معلومات مفيدة.
توليد المسائل
محتويات وحدة qiskit_addon_utils.problem_generators تشمل:
- دالة
generate_xyz_hamiltonian()، التي تولّد تمثيلSparsePauliOpالواعي بالاتصالية لنموذج XYZ من نوع إيزينغ (Ising-type):
- دالة
generate_time_evolution_circuit()، التي تبني دائرة تُمثّل التطور الزمني لمؤثر معيّن. - ثلاثة كائنات
PauliOrderStrategyمختلفة لتعداد ترتيبات سلاسل باولي (Pauli strings) المتعددة. يكون هذا مفيدًا بصورة خاصة عند استخدامه مع تلوين الرسم البياني، ويمكن استخدامه كوسيطات في دالتيgenerate_xyz_hamiltonian()وgenerate_time_evolution_circuit().
تلوين الرسم البياني
تُستخدم وحدة qiskit_addon_utils.coloring لتلوين حواف خريطة الاقتران (coupling map) واستخدام هذا التلوين لوضع البوابات في الدائرة الكمومية بكفاءة أعلى. الهدف من خريطة الاقتران ذات الحواف الملوّنة هو إيجاد مجموعة من ألوان الحواف بحيث لا يتشارك حافّتان من اللون نفسه في عقدة (node) مشتركة. بالنسبة لوحدة المعالجة الكمومية (QPU)، هذا يعني أن البوابات الموجودة على الحواف ذات اللون نفسه (اتصالات الكيوبتات) يمكن تشغيلها بالتوازي، مما يجعل الدائرة تُنفَّذ بشكل أسرع.
كمثال سريع، يمكنك استخدام دالة auto_color_edges() لتوليد تلوين للحواف لدائرة بسيطة تُنفّذ بوابة CZGate على كل اتصال كيوبت. يستخدم مقطع الكود أدناه خريطة اقتران الـ backend الخاصة بـ FakeSherbrooke، ثم يبني هذه الدائرة البسيطة، ويستخدم دالة auto_color_edges() لإنشاء دائرة مكافئة أكثر كفاءة.
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
التقسيم
أخيرًا، تحتوي وحدة qiskit-addon-utils.slicing على دوال ومسارات transpiler للعمل مع إنشاء "شرائح" الدوائر (circuit slices)، وهي أقسام زمنية لـ QuantumCircuit تمتد عبر جميع الكيوبتات. تُستخدم هذه الشرائح بصورة رئيسية في الانتشار العكسي للمؤثرات (operator backpropagation). الطرق الرئيسية الأربع لتقسيم الدائرة هي: حسب نوع البوابة، أو العمق، أو التلوين، أو تعليمات Barrier. يُعيد ناتج دوال التقسيم قائمة من كائنات QuantumCircuit. يمكن أيضًا إعادة دمج الشرائح باستخدام دالة combine_slices(). اقرأ مرجع API الخاص بالوحدة للمزيد من المعلومات.
فيما يلي بعض الأمثلة على كيفية إنشاء هذه الشرائح باستخدام الدائرة التالية:
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)
في الحالات التي لا توجد فيها طريقة واضحة لاستغلال بنية الدائرة في الانتشار العكسي للمؤثرات، يمكنك تقسيم الدائرة إلى شرائح بعمق محدد.
# 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 لمحاكاة ديناميكيات نظام كمومي، قد يكون من المفيد التقسيم حسب نوع البوابة.
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)
إذا كان سير عملك مصمَّمًا لاستغلال اتصالية الكيوبتات الفيزيائية في وحدة QPU التي سيُشغَّل عليها، يمكنك إنشاء شرائح بناءً على تلوين الحواف. سيُعيّن مقطع الكود أدناه تلوينًا ثلاثيًا لحواف الدائرة ويقسّمها وفق تلوين الحواف. (ملاحظة: يؤثر هذا فقط على البوابات غير المحلية. أما البوابات أحادية الكيوبت، فستُقسَّم حسب نوع البوابة).
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)
إذا كان لديك استراتيجية تقسيم مخصصة، يمكنك بدلاً من ذلك وضع حواجز (barriers) في الدائرة لتحديد نقاط التقسيم، ثم استخدام دالة 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)
بمجرد وضع الحواجز في مكانها، يمكنك فحص كل شريحة على حدة.
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)
الخطوات التالية
- اقرأ نظرة عامة على addon الخاص بـ OBP.
- تعرّف على كيفية عمل addon الخاص بـ SQD.
- تعرّف على addon الخاص بـ AQC-Tensor.