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

أدوات 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):

H=(j,k)E(JxXjXk+JyYjYk+JzZjZk)+jV(hxXj+hyYj+hzZj)H = \sum_{(j,k)\in E} \left(J_x X_jX_k + J_yY_jY_k + J_zZ_jZ_k\right) + \sum_{j\in V} \left(h_x X_j + h_y Y_j + h_z Z_j\right)

  • دالة 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)

Output of the previous code cell

في الحالات التي لا توجد فيها طريقة واضحة لاستغلال بنية الدائرة في الانتشار العكسي للمؤثرات، يمكنك تقسيم الدائرة إلى شرائح بعمق محدد.

# 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)

Output of the previous code cell

في حالات مثل تنفيذ دوائر 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)

Output of the previous code cell

إذا كان سير عملك مصمَّمًا لاستغلال اتصالية الكيوبتات الفيزيائية في وحدة 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)

Output of the previous code cell

إذا كان لديك استراتيجية تقسيم مخصصة، يمكنك بدلاً من ذلك وضع حواجز (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)

Output of the previous code cell

بمجرد وضع الحواجز في مكانها، يمكنك فحص كل شريحة على حدة.

from qiskit_addon_utils.slicing import slice_by_barriers

slices = slice_by_barriers(qc)
slices[0].draw("mpl", scale=0.6)

Output of the previous code cell

slices[1].draw("mpl", scale=0.6)

Output of the previous code cell

slices[2].draw("mpl", scale=0.6)

Output of the previous code cell

الخطوات التالية

Recommendations