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

إنشاء مدير تمرير لـ Dynamical Decoupling

إصدارات الحزم

الكود في هذه الصفحة تم تطويره باستخدام المتطلبات التالية. نوصي باستخدام هذه الإصدارات أو أحدث منها.

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1

تُوضّح هذه الصفحة كيفية استخدام تمريرة PadDynamicalDecoupling لإضافة تقنية لقمع الأخطاء تُعرف بـ Dynamical Decoupling إلى الدائرة.

يعمل Dynamical Decoupling عبر إضافة تسلسلات نبضات (تُعرف بـ تسلسلات Dynamical Decoupling) إلى الـ Qubits الخاملة لتدويرها حول كرة بلوخ، مما يُلغي تأثير قنوات الضوضاء ويُقلّل من تأثير التفكك. هذه التسلسلات النبضية مشابهة لنبضات إعادة التركيز المستخدمة في الرنين المغناطيسي النووي. للاطلاع على وصف كامل، راجع A Quantum Engineer's Guide to Superconducting Qubits.

نظرًا لأن تمريرة PadDynamicalDecoupling تعمل فقط على الدوائر المجدولة زمنيًا وتتضمّن Gates ليست بالضرورة Gates أساسية لهدفنا، ستحتاج أيضًا إلى تمريرتَي ALAPScheduleAnalysis وBasisTranslator.

يستخدم هذا المثال ibm_fez الذي تمت تهيئته مسبقًا. احصل على معلومات target من الـ backend واحفظ أسماء العمليات في basis_gates، إذ سيحتاج target إلى التعديل لإضافة معلومات التوقيت للـ Gates المستخدمة في Dynamical Decoupling.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.backend("ibm_fez")

target = backend.target
basis_gates = list(target.operation_names)

أنشئ دائرة efficient_su2 كمثال. أولًا، قم بعملية Transpile للدائرة إلى الـ Backend لأن نبضات Dynamical Decoupling تحتاج إلى إضافتها بعد أن يتم Transpile الدائرة وجدولتها زمنيًا. غالبًا ما يعمل Dynamical Decoupling بشكل أفضل عندما يكون هناك قدر كبير من وقت الخمول في الدوائر الكمومية — أي عندما لا تكون بعض الـ Qubits قيد الاستخدام بينما تكون الأخرى نشطة. هذا هو الحال في هذه الدائرة لأن الـ Gates ثنائية الـ Qubit من نوع ecr تُطبَّق بشكل تسلسلي في هذه الدالة التقريبية.

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)

Output of the previous code cell

تسلسل Dynamical Decoupling هو سلسلة من الـ Gates تتكوّن مجتمعةً من عملية الهوية وتكون متباعدة بانتظام في الزمن. على سبيل المثال، ابدأ بإنشاء تسلسل بسيط يُسمى XY4 يتكوّن من أربع Gates.

from qiskit.circuit.library import XGate, YGate

X = XGate()
Y = YGate()

dd_sequence = [X, Y, X, Y]

بسبب التوقيت المنتظم لتسلسلات Dynamical Decoupling، يجب إضافة معلومات حول YGate إلى target لأنها ليست Gate أساسية، بعكس XGate. غير أننا نعلم مسبقًا أن YGate لها نفس مدة وخطأ XGate، لذا يمكننا فقط استرداد تلك الخصائص من target وإضافتها لكائنات YGate. هذا أيضًا هو السبب في حفظ basis_gates بشكل منفصل، إذ نُضيف تعليمة YGate إلى target رغم أنها ليست Gate أساسية فعلية لـ 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)

دوائر الدوال التقريبية مثل 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 أولًا لإضافة معلومات التوقيت حول الدائرة الكمومية قبل إمكانية إضافة تسلسلات Dynamical Decoupling المتباعدة بانتظام. تُشغَّل هذه التمريرات على الدائرة باستخدام .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)

Output of the previous code cell

أخيرًا، بما أن YGate ليست Gate أساسية فعلية لـ Backend الخاص بنا، قم بتطبيق تمريرة BasisTranslator يدويًا (هذه تمريرة افتراضية، لكنها تُنفَّذ قبل الجدولة الزمنية، لذا تحتاج إلى تطبيقها مرة أخرى). مكتبة التكافؤ للجلسة هي مكتبة من تكافؤات الدوائر تتيح للـ Transpiler تحليل الدوائر إلى Gates أساسية، كما هو محدد أيضًا كمعامل.

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)

Output of the previous code cell

الآن، كائنات YGate غائبة عن دائرتنا، وتوجد معلومات توقيت صريحة في شكل Gates من نوع Delay. هذه الدائرة المُحوَّلة مع Dynamical Decoupling أصبحت الآن جاهزة للإرسال إلى الـ Backend.

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

توصيات