إنشاء مدير تمرير لـ Dynamical Decoupling
إصدارات الحزم
الكود في هذه الصفحة تم تطويره باستخدام المتطلبات التالية. نوصي باستخدام هذه الإصدارات أو أحدث منها.
qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0
توضح هذه الصفحة كيفية استخدام تمريرة PadDynamicalDecoupling لإضافة تقنية لقمع الأخطاء تسمى فك الاقتران الديناميكي إلى الـ Circuit.
يعمل فك الاقتران الديناميكي عن طريق إضافة تسلسلات نبضية (تُعرف بـ تسلسلات فك الاقتران الديناميكي) إلى الـ Qubits الخاملة لقلبها حول كرة بلوخ، مما يلغي تأثير قنوات الضوضاء، وبالتالي يقمع فقدان الترابط. تشبه هذه التسلسلات النبضية نبضات إعادة التركيز المستخدمة في الرنين المغناطيسي النووي. للحصول على وصف كامل، راجع دليل مهندس الكم للـ Qubits الفائقة التوصيل.
نظرًا لأن تمريرة PadDynamicalDecoupling تعمل فقط على الدارات المجدولة وتتضمن بوابات ليست بالضرورة بوابات أساسية للهدف الخاص بنا، ستحتاج أيضًا إلى تمريرتَي ALAPScheduleAnalysis وBasisTranslator.
احصل على معلومات target من backend واحفظ أسماء العمليات كـ basis_gates لأن target سيحتاج إلى تعديل لإضافة معلومات التوقيت للبوابات المستخدمة في فك الاقتران الديناميكي.
يتم استخدام الـ Backend الوهمي FakeSherbrooke من qiskit_ibm_runtime في هذه الأمثلة، ولكن يمكنك تجربته على أي Backend حقيقي أو وهمي متوافق مع Qiskit. قد تختلف نتائجك.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend = FakeSherbrooke()
target = backend.target
basis_gates = list(target.operation_names)
أنشئ دارة efficient_su2 كمثال. أولًا، حوِّل الدارة لتناسب الـ Backend لأن نبضات فك الاقتران الديناميكي يجب إضافتها بعد ترجمة الدارة وجدولتها. غالبًا ما يعمل فك الاقتران الديناميكي بشكل أفضل عندما يكون هناك وقت خمول كبير في الدارات الكمية - أي، توجد Qubits غير مستخدمة بينما تكون أخرى نشطة. هذا هو الحال في هذه الدارة لأن بوابات ecr ثنائية الـ Qubit تُطبَّق بالتتابع في هذا Ansatz.
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.circuit.library import efficient_su2
qc = efficient_su2(12, entanglement="circular", reps=1)
pm = generate_preset_pass_manager(1, target=target, seed_transpiler=12345)
qc_t = pm.run(qc)
qc_t.draw("mpl", fold=-1, idle_wires=False)
تسلسل فك الاقتران الديناميكي هو سلسلة من البوابات يكون تركيبها مساويًا للمؤثر المحايد (مصفوفة الوحدة) وتكون متباعدة بانتظام في الزمن. على سبيل المثال، ابدأ بإنشاء تسلسل بسيط يسمى XY4 يتألف من أربع بوابات.
from qiskit.circuit.library import XGate, YGate
X = XGate()
Y = YGate()
dd_sequence = [X, Y, X, Y]
بسبب التوقيت المنتظم لتسلسلات فك الاقتران الديناميكي، يجب إضافة معلومات حول YGate إلى target لأنها ليست بوابة أساسية، بينما XGate هي كذلك. نعلم مسبقًا أن YGate لها نفس المدة والخطأ اللذين لـ XGate، لذا يمكننا ببساطة استرجاع تلك الخصائص من target وإضافتها مرة أخرى لكائنات YGate. هذا أيضًا سبب حفظ basis_gates بشكل منفصل، حيث نضيف تعليمة YGate إلى target رغم أنها ليست بوابة أساسية فعلية لـ ibm_fez.
from qiskit.transpiler import InstructionProperties
y_gate_properties = {}
for qubit in range(target.num_qubits):
y_gate_properties.update(
{
(qubit,): InstructionProperties(
duration=target["x"][(qubit,)].duration,
error=target["x"][(qubit,)].error,
)
}
)
target.add_instruction(YGate(), y_gate_properties)
دارات Ansatz مثل efficient_su2 هي دارات ذات معاملات، لذا يجب ربط قيم بها قبل إرسالها إلى الـ Backend. هنا، عيّن معاملات عشوائية.
import numpy as np
rng = np.random.default_rng(1234)
qc_t.assign_parameters(
rng.uniform(-np.pi, np.pi, qc_t.num_parameters), inplace=True
)
بعد ذلك، نفّذ التمريرات المخصصة. أنشئ PassManager بـ ALAPScheduleAnalysis وPadDynamicalDecoupling. شغّل ALAPScheduleAnalysis أولًا لإضافة معلومات التوقيت حول الدارة الكمية قبل إمكانية إضافة تسلسلات فك الاقتران الديناميكي المتباعدة بانتظام. تُشغَّل هذه التمريرات على الدارة باستخدام .run().
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes.scheduling import (
ALAPScheduleAnalysis,
PadDynamicalDecoupling,
)
dd_pm = PassManager(
[
ALAPScheduleAnalysis(target=target),
PadDynamicalDecoupling(target=target, dd_sequence=dd_sequence),
]
)
qc_dd = dd_pm.run(qc_t)
استخدم أداة التصور timeline_drawer لرؤية توقيت الدارة والتأكد من ظهور تسلسل متباعد بانتظام من كائنات XGate وكائنات YGate في الدارة.
from qiskit.visualization import timeline_drawer
timeline_drawer(qc_dd, idle_wires=False, target=target)
أخيرًا، بما أن YGate ليست بوابة أساسية فعلية للـ Backend الخاص بنا، طبّق يدويًا تمريرة BasisTranslator (هذه تمريرة افتراضية، لكنها تُنفَّذ قبل الجدولة، لذا يجب تطبيقها مرة أخرى). مكتبة تكافؤ الجلسة هي مكتبة من تكافؤات الدارات تتيح لـ Transpiler تفكيك الدارات إلى بوابات أساسية، كما هو محدد أيضًا كوسيطة.
from qiskit.circuit.equivalence_library import (
SessionEquivalenceLibrary as sel,
)
from qiskit.transpiler.passes import BasisTranslator
qc_dd = BasisTranslator(sel, basis_gates)(qc_dd)
qc_dd.draw("mpl", fold=-1, idle_wires=False)
الآن، كائنات YGate غائبة عن دارتنا، وهناك معلومات توقيت صريحة على شكل بوابات Delay. هذه الدارة المُرجَّمة مع فك الاقتران الديناميكي جاهزة الآن للإرسال إلى الـ Backend.
الخطوات التالية
- لتتعلم كيفية استخدام الدالة
generate_preset_passmanagerبدلًا من كتابة تمريراتك الخاصة، ابدأ بموضوع الإعدادات الافتراضية للـ Transpilation وخيارات الضبط. - جرّب دليل مقارنة إعدادات الـ Transpiler.
- راجع توثيق Transpile API.