OpenQASM 2 וה-Qiskit SDK
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
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit
ה-Qiskit SDK מספק כלים להמרה בין ייצוגי OpenQASM של תוכניות קוונטיות לבין המחלקה QuantumCircuit.
ייבוא תוכנית OpenQASM 2 אל Qiskit
שתי פונקציות מייבאות תוכניות OpenQASM 2 אל Qiskit.
אלו הן qasm2.load(), שמקבלת שם קובץ, ו-qasm2.loads(), שמקבלת את תוכנית OpenQASM 2 כמחרוזת.
import qiskit.qasm2
qiskit.qasm2.load(filename, include_path=('.',), include_input_directory='append', custom_instructions=(), custom_classical=(), strict=False)
qiskit.qasm2.loads(program, include_path=('.',), custom_instructions=(), custom_classical=(), strict=False)
ראה את ה-API של OpenQASM 2 ב-Qiskit לפרטים נוספים.
ייבוא תוכניות פשוטות
עבור רוב תוכניות OpenQASM 2, אתה יכול פשוט להשתמש ב-qasm2.load וב-qasm2.loads עם ארגומנט יחיד.
דוגמה: ייבוא תוכנית OpenQASM 2 כמחרוזת
השתמש ב-qasm2.loads() כדי לייבא תוכנית OpenQASM 2 כמחרוזת אל תוך QuantumCircuit:
import qiskit.qasm2
program = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0], q[1];
measure q -> c;
"""
circuit = qiskit.qasm2.loads(program)
circuit.draw()
┌───┐ ┌─┐
q_0: ┤ H ├──■──┤M├───
└───┘┌─┴─┐└╥┘┌─┐
q_1: ─────┤ X ├─╫─┤M├
└───┘ ║ └╥┘
c: 2/═══════════╩══╩═
0 1
דוגמה: ייבוא תוכנית OpenQASM 2 מקובץ
השתמש ב-load() כדי לייבא תוכנית OpenQASM 2 מקובץ אל תוך QuantumCircuit:
import qiskit.qasm2
circuit = qiskit.qasm2.load("myfile.qasm")
קישור שערי OpenQASM 2 עם שערי Qiskit
כברירת מחדל, מייבא OpenQASM 2 של Qiskit מתייחס לקובץ ה-include "qelib1.inc" כספריית סטנדרט de facto.
המייבא מתייחס לקובץ זה כמכיל בדיוק את השערים המתוארים בו במאמר המקורי שהגדיר את OpenQASM 2.
Qiskit ישתמש בשערים המובנים בספריית ה-Circuit כדי לייצג את השערים ב-"qelib1.inc".
שערים שמוגדרים בתוכנית באמצעות הצהרות gate ידניות של OpenQASM 2 ייבנו כברירת מחדל כתת-מחלקות מותאמות אישית של Qiskit Gate.
אתה יכול להורות למייבא להשתמש במחלקות Gate ספציפיות עבור הצהרות gate נתונות שהוא נתקל בהן.
אתה יכול גם להשתמש במנגנון זה כדי להתייחס לשמות שערים נוספים כ"מובנים", כלומר, שאינם דורשים הגדרה מפורשת.
אם תציין אילו מחלקות שערים להשתמש בהן עבור הצהרות gate שמחוץ ל-"qelib1.inc", ה-Circuit שיתקבל יהיה בדרך כלל יעיל יותר לעבודה.
החל מ-Qiskit SDK גרסה 1.0, המייצא של Qiskit ל-OpenQASM 2 (ראה ייצוא Circuit של Qiskit אל OpenQASM 2) עדיין מתנהג כאילו ל-"qelib1.inc" יש יותר שערים ממה שיש לו בפועל.
פירוש הדבר הוא שהגדרות ברירת המחדל של המייבא עשויות שלא להיות מסוגלות לייבא תוכנית שיוצאה על-ידי המייצא שלנו.
ראה את הדוגמה הספציפית לעבודה עם המייצא הישן כדי לפתור בעיה זו.
אי-התאמה זו היא התנהגות ישנה של Qiskit, והיא תיפתר בגרסה עתידית של Qiskit.
כדי להעביר מידע על הוראה מותאמת אישית למייבא OpenQASM 2, השתמש במחלקה qasm2.CustomInstruction.
יש לה ארבעה פרטי מידע נדרשים, לפי הסדר:
- השם של השער, כפי שמשמש בתוכנית OpenQASM 2
- מספר פרמטרי הזווית שהשער מקבל
- מספר ה-Qubit שעליהם השער פועל
- מחלקת הבנאי בפייתון או הפונקציה עבור השער, שמקבלת את פרמטרי השער (אך לא את ה-Qubit) כארגומנטים נפרדים
אם המייבא נתקל בהגדרת gate שתואמת להוראה מותאמת אישית נתונה, הוא ישתמש במידע המותאם אישית הזה כדי לשחזר את אובייקט השער.
אם נתקלים בהצהרת gate שתואמת לname של הוראה מותאמת אישית, אך אינה תואמת גם את מספר הפרמטרים וגם את מספר ה-Qubit, המייבא יזרוק QASM2ParseError כדי לציין את אי-ההתאמה בין המידע שסופק לבין התוכנית.
בנוסף, ניתן לאפשר אופציונלית ארגומנט חמישי builtin על-ידי הגדרתו ל-True כדי להפוך את השער לזמין אוטומטית בתוכנית OpenQASM 2, גם אם הוא לא מוגדר במפורש.
אם המייבא נתקל בהגדרת gate מפורשת עבור הוראה מותאמת אישית מובנית, הוא יקבל אותה בשקט.
כבעבר, אם הגדרה מפורשת של אותו שם אינה תואמת להוראה המותאמת אישית שסופקה, יוזרק QASM2ParseError.
זה שימושי לתאימות עם מייצאי OpenQASM 2 ישנים יותר, ועם פלטפורמות קוונטיות מסוימות אחרות שמתייחסות ל"שערי הבסיס" של חומרתן כהוראות מובנות.
Qiskit מספקת תכונת נתונים לעבודה עם תוכניות OpenQASM 2 שנוצרו על-ידי גרסאות ישנות של יכולות ייצוא OpenQASM 2 של Qiskit.
זהו qasm2.LEGACY_CUSTOM_INSTRUCTIONS, שניתן לספק אותו כארגומנט custom_instructions ל-qasm2.load() ול-qasm2.loads().
דוגמה: ייבוא תוכנית שנוצרה על-ידי המייצא הישן של Qiskit
תוכנית OpenQASM 2 זו משתמשת בשערים שאינם בגרסה המקורית של "qelib1.inc" מבלי להצהיר עליהם, אך הם שערים סטנדרטיים בספריית Qiskit.
אתה יכול להשתמש ב-qasm2.LEGACY_CUSTOM_INSTRUCTIONS כדי בקלות להורות למייבא להשתמש באותה קבוצת שערים שמייצא OpenQASM 2 של Qiskit השתמש בה בעבר.
from qiskit import qasm2
program = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[4];
creg c[4];
h q[0];
cx q[0], q[1];
// 'rxx' is not actually in `qelib1.inc`,
// but Qiskit used to behave as if it were.
rxx(0.75) q[2], q[3];
measure q -> c;
"""
circuit = qasm2.loads(
program,
custom_instructions=qasm2.LEGACY_CUSTOM_INSTRUCTIONS,
)
דוגמה: שימוש במחלקת Gate ספציפית בעת ייבוא תוכנית OpenQASM 2
Qiskit אינה יכולה, בדרך כלל, לאמת אם ההגדרה בהצהרת gate של OpenQASM 2 תואמת בדיוק לשער ספריית סטנדרט של Qiskit.
במקום זאת, Qiskit בוחרת שער מותאם אישית באמצעות ההגדרה המדויקת שסופקה.
זה יכול להיות פחות יעיל מאשר שימוש באחד מהשערים הסטנדרטיים המובנים, או בשער מותאם אישית שהמשתמש הגדיר.
אתה יכול להגדיר ידנית הצהרות gate עם מחלקות ספציפיות.
from qiskit import qasm2
from qiskit.circuit import Gate
from qiskit.circuit.library import RZXGate
# Define a custom gate that takes one qubit and two angles.
class MyGate(Gate):
def __init__(self, theta, phi):
super().__init__("my", 1, [theta, phi])
custom_instructions = [
# Link the OpenQASM 2 name 'my' with our custom gate.
qasm2.CustomInstruction("my", 2, 1, MyGate),
# Link the OpenQASM 2 name 'rzx' with Qiskit's
# built-in RZXGate.
qasm2.CustomInstruction("rzx", 1, 2, RZXGate),
]
program = """
OPENQASM 2.0;
gate my(theta, phi) q {
U(theta / 2, phi, -theta / 2) q;
}
gate rzx(theta) a, b {
// It doesn't matter what definition is
// supplied, if the parameters match;
// Qiskit will still use `RZXGate`.
}
qreg q[2];
my(0.25, 0.125) q[0];
rzx(pi) q[0], q[1];
"""
circuit = qasm2.loads(
program,
custom_instructions=custom_instructions,
)
דוגמה: הגדרת Gate מובנה חדש בתוכנית OpenQASM 2
אם מוגדר הארגומנט builtin=True, שער מותאם אישית אינו צריך להיות בעל הגדרה משויכת.
from qiskit import qasm2
from qiskit.circuit import Gate
# Define a custom gate that takes one qubit and two angles.
class MyGate(Gate):
def __init__(self, theta, phi):
super().__init__("my", 1, [theta, phi])
custom_instructions = [
qasm2.CustomInstruction("my", 2, 1, MyGate, builtin=True),
]
program = """
OPENQASM 2.0;
qreg q[1];
my(0.25, 0.125) q[0];
"""
circuit = qasm2.loads(
program,
custom_instructions=custom_instructions,
)
הגדרת פונקציות קלאסיות מותאמות אישית
OpenQASM 2 כולל מספר פונקציות קלאסיות מובנות לשימוש בארגומנטים של שערים.
אתה יכול להרחיב את השפה עם פונקציות נוספות על-ידי שימוש בארגומנט custom_classical ל-qasm2.load() ול-qasm2.loads(), עם המחלקה qasm2.CustomClassical.
כדי להגדיר פונקציה קלאסית מותאמת אישית, עליך לספק:
- השם של הפונקציה כפי שהוא מופיע בתוכנית OpenQASM 2
- מספר ארגומנטי הנקודה הצפה שהיא מקבלת
- אובייקט Python ניתן-לקריאה שמחשב את הפונקציה
כל הפונקציות הקלאסיות המותאמות אישית שהוגדרו מטופלות כמובנות לשפת OpenQASM 2 על-ידי המיי בא. אין דרך רשמית בתוך שפת OpenQASM 2 להגדיר פונקציות חדשות; זוהי הרחבה של Qiskit.
דוגמה: שימוש בהוראות קלאסיות מותאמות אישית
כאן אנו מספקים שתי פונקציות קלאסיות מותאמות אישית.
הראשונה פשוטה, ופשוט מוסיפה אחד לקלט שלה.
השנייה היא הפונקציה math.atan2, שמייצגת את הפעולה המתמטית בצורה מודעת-רביע.
import math
from qiskit import qasm2
program = """
include "qelib1.inc";
qreg q[2];
rx(arctan(pi, 3 + add_one(0.2))) q[0];
cx q[0], q[1];
"""
def add_one(x):
return x + 1
customs = [
# Our `add_one` takes only one parameter.
qasm2.CustomClassical("add_one", 1, add_one),
# `arctan` takes two parameters, and `math.atan2` implements it.
qasm2.CustomClassical("arctan", 2, math.atan2),
]
circuit = qasm2.loads(program, custom_classical=customs)
מצב מחמיר
כברירת מחדל, מנתח זה מקל יותר מהמפרט הרשמי.
הוא מאפשר פסיקים עוקבים ברשימות פרמטרים; נקודה-פסיק מיותרת (הצהרה ריקה); השמטת הצהרת גרסה OPENQASM 2.0;; ושיפורים נוספים לנוחות המשתמש ללא הפקת שגיאות.
עם זאת, אתה יכול להשתמש במצב "לפי האות של המפרט" עם strict=True.
ייצוא Circuit של Qiskit אל OpenQASM 2
Qiskit יכולה גם לייצא QuantumCircuit אל OpenQASM 2.
אתה משתמש בפונקציה qasm2.dump() לכתיבה לקובץ, ו-qasm2.dumps() לכתיבה למחרוזת.
לפונקציות אלה כרגע יש ממשק פשוט מאוד: הן מקבלות circuit ו, רק במקרה של qasm2.dump(), מיקום לכתיבת הפלט אליו.
מייצא OpenQASM 2 של Qiskit עדיין מניח גרסה ישנה ולא-סטנדרטית של קובץ ה-include "qelib1.inc".
הדבר ייפתר בגרסה עתידית של Qiskit, אך בינתיים, אם אתה צריך לייבא מחדש תוכנית OpenQASM 2 שנוצרה עם Qiskit, השתמש בדוגמה לעיל כדי להורות למייבא על שערי הישן.
דוגמה: ייצוא Circuit אל OpenQASM 2
from qiskit import QuantumCircuit, qasm2
# Define any circuit.
circuit = QuantumCircuit(2, 2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure([0, 1], [0, 1])
# Export to a string.
program = qasm2.dumps(circuit)
# Export to a file.
qasm2.dump(circuit, "my_file.qasm")
הצעדים הבאים
- למד כיצד לייצר קוד OpenQASM במדריך IBM Quantum Composer.
- ראה את הAPI של OpenQASM 2 ב-Qiskit.
- עיין בנושא אימות התוכנית שלך.
- בקר במפרט החי של OpenQASM.