OpenQASM 2
qiskit.qasm2
Qiskitは、 OpenQASM 2.0 プログラムとの相互運用をサポートしており、 Qiskitフォーマットへのパースと OpenQASM 2へのエクスポートの両方が可能です。
OpenQASM 2は単純な言語であり、Qiskitオブジェクトの一般的なシリアライズには適していません。 あなたがそれを探しているのであれば、 以下の代替案を参照してください。
APIの解析
このモジュールには2つのパブリック関数が含まれている。 QuantumCircuitOpenQASM を作成する。 load() はファイル名を取る。 loads() はプログラムそのものを文字列として受け取る。 両者の内部構造はよく似ており、APIもほとんど同じである。
load
qiskit.qasm2.load(filename, *, include_path=('.',), include_input_directory='append', custom_instructions=(), custom_classical=(), strict=False)
OpenQASM 2 プログラムをファイルからパースして QuantumCircuit. 与えられたパスはASCIIまたは UTF-8 エンコードされ、 OpenQASM 2プログラムを含んでいなければならない。
内部の古典的式パーサーは再帰的であり、評価に過度な深さが必要となる式がある場合、例外 RecursionError を発生させます。 sys.setrecursionlimit()この最大深度は を使用して調整できます。実際の制限値はこの値の10分の1となります。
パラメーター
- filename (str |PathLike) – 「 OpenQASM 2」ファイルへのパス。
- include_path (Iterable[str |PathLike]) – ステートメントを
include評価する際に検索するディレクトリの順序。 - include_input_directory (Literal['append', 'prepend'] | None) – 入力ファイルのディレクトリを
include_pathに追加するかどうか、追加する場合は、それを最後に検索に追加するか、あるいは最初に検索に追加するかどうか。Noneを渡すと、このディレクトリの追加を完全に禁止する。 - custom_instructions (Iterable[CustomInstruction]) – 回路構築時に、特定のゲートや不透明な命令に対して使用するべきカスタムコンストラクタ。 詳しくは、「カスタム指示の指定」 を参照してください。
- custom_classical (Iterable[CustomClassical]) – 古典式を解析する際に使用するべきカスタム古典関数。 詳細については、「カスタム古典関数の指定」 を参照してください。
- strict (bool) – ストリクト・モードで実行するかどうか。
戻り値
同じ OpenQASM 2プログラムを表す回路オブジェクト。
戻りの型
loads
qiskit.qasm2.loads(string, *, include_path=('.',), custom_instructions=(), custom_classical=(), strict=False)
OpenQASM 2のプログラムを文字列からパースし、次のように変換する。 QuantumCircuit.
内部の古典的式パーサーは再帰的であり、評価に過度な深さが必要となる式がある場合、例外 RecursionError を発生させます。 sys.setrecursionlimit()この最大深度は を使用して調整できます。実際の制限値はこの値の10分の1となります。
パラメーター
- string (str) – OpenQASM 2 プログラムの文字列。
- include_path (Iterable[str |PathLike]) – ステートメントを
include評価する際に検索するディレクトリの順序。 - custom_instructions (Iterable[CustomInstruction]) – 回路構築時に、特定のゲートや不透明な命令に対して使用するべきカスタムコンストラクタ。 詳しくは、「カスタム指示の指定」 を参照してください。
- custom_classical (Iterable[CustomClassical]) – 古典式を解析する際に使用するべきカスタム古典関数。 詳細については、「カスタム古典関数の指定」 を参照してください。
- strict (bool) – ストリクト・モードで実行するかどうか。
戻り値
同じ OpenQASM 2プログラムを表す回路オブジェクト。
戻りの型
これらのローディング関数はどちらも、 include ステートメントでファイルを検索する際に使用するディレクトリ名のイテレート可能な引数 include_path も取る。 ディレクトリはインデックス0から順に試行され、最初にマッチしたものが使用される。 インポート qelib1.inc は特別に扱われ、インクルード・パスを探す前に必ず見つかり、 OpenQASM 2 言語を説明した論文の内容を正確に含んでいる。 このインクルードファイルのゲートは、Qiskitによって定義された回路ライブラリゲートオブジェクトにマッピングされます。
カスタム指示の指定
custom_instructions の引数として、カスタム命令に関する情報を反復可能な形で渡すことで、 OpenQASM 2 言語の量子コンポーネントを拡張することができます。 これらの命令に対して互換性のある定義があるファイルでは、与えられた constructor が、他のどのような処理であれ、その代わりに使われる。 qiskit.qasm2 の代わりに使われる。 これらの命令は、オプションで builtin とマークすることができ、 opaque または gate 宣言を必要としないが、互換宣言は黙って無視される。 いずれにせよ、パースされたプログラムにおいて、定義された命令と異なる数のパラメータや量子ビットを持つカスタム命令を提供することはエラーである。 引数iterableの各要素は、特定のデータ・クラスでなければならない:
CustomInstruction
class qiskit.qasm2.CustomInstruction(name, num_params, num_qubits, constructor, builtin=False)
ベース: object
パース中に定義されるべきカスタム命令に関する情報。
name、 num_params 、 num_qubits フィールドは自明である。 constructor フィールドは、 *args -> Instruction のシグネチャを持つ呼び出し可能なオブジェクトであるべきで、 num_params args のそれぞれは浮動小数点値である。 組み込みのQiskitゲートクラスのほとんどはこの形式を持っています。
最後に builtin 。 これはオプションであり、trueに設定すると、たとえ含まれる OpenQASM 2ファイルに定義がなくても、命令が定義され、構文解析で利用できるようになる。
例
インポーターに対し、 OpenQASM 2のエクスポート時に、それらのオブジェクトから生成されたことが判明している ステートメントを解釈 gate するために、Qiskitの ECRGate および RZXGate オブジェクトを使用するよう指示します:
from qiskit import qasm2
from qiskit.circuit import QuantumCircuit, library
qc = QuantumCircuit(2)
qc.ecr(0, 1)
qc.rzx(0.3, 0, 1)
qc.rzx(0.7, 1, 0)
qc.rzx(1.5, 0, 1)
qc.ecr(1, 0)
# This output string includes `gate ecr q0, q1 { ... }` and `gate rzx(p) q0, q1 { ... }`
# statements, since `ecr` and `rzx` are neither built-in gates nor in ``qelib1.inc``.
dumped = qasm2.dumps(qc)
# Tell the importer how to interpret the `gate` statements, which we know are safe
# because we controlled the input OpenQASM 2 source.
custom = [
qasm2.CustomInstruction("ecr", 0, 2, library.ECRGate),
qasm2.CustomInstruction("rzx", 1, 2, library.RZXGate),
]
loaded = qasm2.loads(dumped, custom_instructions=custom)パラメーター
これは、 OpenQASM 2 プログラムのグローバル・フェーズの規約のあいまいさを解決しようとするときに、特に役に立つ。 詳細は、 OpenQASM 2 Phase Conventions を参照のこと。
カスタム古典関数の指定
上記の量子拡張と同様に、どちらのローダーでも引数 custom_classical にイテラブルを渡すことで、古典的な式(ゲートの引数)に対して行われる処理を拡張することもできる。 これには、 name (有効な OpenQASM 2識別子)、取るパラメータの数 num_params 、関数を実装する Python callableが必要です。 Python callableは、 num_params 位置浮動小数点数引数を受け取ることができ、floatまたは整数(これはfloatに変換される)を返さなければならない。 組み込み関数はオーバーライドできない。
CustomClassical
class qiskit.qasm2.CustomClassical(name, num_params, callable, /)
ベース: object
数式で定義されるべきカスタム古典関数に関する情報。
与えられた callable は、num_params 浮動小数点を受け取り、浮動小数点を返す Python 関数でなければならない。 この名前は、 OpenQASM 2 プログラムでそれを参照する識別子である。 これは、定義されたゲートと衝突することはない。
厳密モード
どちらのローダー関数にも、オプションで "strict "モードがある。 デフォルトでは、このパーサーは公式仕様よりも少し緩和されている。パラメータ・リストの末尾のカンマ、不要な(空の)ステートメントのセミコロン、 OPENQASM 2.0; バージョン・ステートメントの省略、その他いくつかのQOLの向上が、エラーを出さずに許容される。 strict=True で仕様書モードを使用できます。
エクスポートAPI
Python の他のシリアライズ・モジュールと同様に、このモジュールも2つのパブリック関数を提供している: dump() と dumps()を受け取り、それぞれ代表的なプログラムをファイルのようなオブジェクトに書き出したり、文字列を返したりします。 QuantumCircuit を受け取り、代表的な OpenQASM 2 プログラムをファイルのようなオブジェクトに書き出すか、文字列を返す。
dump
qiskit.qasm2.dump(circuit, filename_or_stream, /)
回路を OpenQASM 2 プログラムとしてファイルまたはストリームにダンプする。
パラメーター
- circuit (QuantumCircuit) – その
QuantumCircuitをエクスポートする。 - filename_or_stream (PathLike |TextIOBase) – パス様オブジェクト(おそらく または
strpathlib.Path)か、既に開かれているテキストモードストリームのいずれか。
レイズ
QASM2ExportError - 回路が OpenQASM 2で表現できない場合。
dumps
qiskit.qasm2.dumps(circuit, /)
回路を文字列で OpenQASM 2 プログラムにエクスポートします。
パラメーター
circuit (QuantumCircuit) – その QuantumCircuit をエクスポートする。
戻り値
OpenQASM 2 回路を表す文字列。
レイズ
QASM2ExportError - 回路が OpenQASM 2で表現できない場合。
戻りの型
エラー
このモジュールは QiskitError から派生する汎用エラー型を定義します。
QASM2Error
exception qiskit.qasm2.QASM2Error(*message)
ベース: QiskitError
OpenQASM 2インターオペレーションレイヤーで発生した一般的なエラー。
エラーメッセージを設定する。
無効な OpenQASM 2 ファイルが原因でレキサーやパーサーが失敗した場合、変換関数は、失敗の内容とファイルのどこで発生したかを説明するメッセージとともに、より具体的なエラーを発生させます。
QASM2ParseError
exception qiskit.qasm2.QASM2ParseError(*message)
ベース: QASM2Error
OpenQASM 2 ファイルの解析に失敗し、エラーが発生した。
エラーメッセージを設定する。
回路が OpenQASM 2.0 で表現できない構造を持っているためと思われるが、エクスポータが回路のエクスポートに失敗すると、カスタムエラーも発生する。
QASM2ExportError
exception qiskit.qasm2.QASM2ExportError(*message)
ベース: QASM2Error
Qiskitオブジェクトの OpenQASM 2フォームへの変換に失敗したために発生したエラー。
エラーメッセージを設定する。
例
例をエクスポートする
単純な QuantumCircuit を OpenQASM 2 文字列にエクスポートする:
import qiskit.qasm2
from qiskit.circuit import QuantumCircuit
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
print(qiskit.qasm2.dumps(qc))OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0],q[1];
measure q[0] -> c[0];
measure q[1] -> c[1];同じ QuantumCircuit を指定されたファイル名に書き出す:
qiskit.qasm2.dump(qc, "myfile.qasm")同様に、一般的な os.PathLike インスタンスをファイル名として使うことができる:
import pathlib
qiskit.qasm2.dump(qc, pathlib.Path.home() / "myfile.qasm")また、すでに開いているストリームにテキストをダンプすることもできる:
import io
with io.StringIO() as stream:
qiskit.qasm2.dump(qc, stream)構文解析の例
使用方法 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プログラムがファイルに格納されている場合、同じことができる。 load() 代わりにファイル名を引数として渡す:
import qiskit.qasm2
circuit = qiskit.qasm2.load("myfile.qasm")OpenQASM 2 ファイルは、 include ステートメントを介して他の OpenQASM 2 ファイルをインクルードすることができます。 これらのファイルを見つけるために使用される検索パスは、 include_path 引数で指定できます。 load() と loads(). デフォルトでは、現在の作業ディレクトリのみが検索される。
import qiskit.qasm2
program = """
include "other.qasm";
// ... and so on
"""
circuit = qiskit.qasm2.loads(program, include_path=("/path/to/a", "/path/to/b", "."))の場合のみ。 load() の場合のみ、 include_input_directory という追加引数があり、 'append'、 'prepend' 、またはインクルード・パス内のロードされたファイルのディレクトリを無視(None )することができる。 デフォルトでは、このディレクトリは検索パスに追加され、最後に試行されるが、これを変更することもできる。
import qiskit.qasm2
filenames = ["./subdirectory/a.qasm", "/path/to/b.qasm", "~/my.qasm"]
# Search the directory of each file before other parts of the include path.
circuits = [
qiskit.qasm2.load(filename, include_input_directory="prepend") for filename in filenames
]
# Override the include path, and don't search the directory of each file unless it's in the
# absolute path list.
circuits = [
qiskit.qasm2.load(
filename,
include_path=("/usr/include/qasm", "~/qasm/include"),
include_input_directory=None,
)
for filename in filenames
]場合によっては、特定の名前付き命令に対してインポーターが生成するオブジェクトに Gate 何らかの影響を与えたいこともあるでしょう。 この記述 include "qelib1.inc"; で定義されたゲートは、自動的に適切なQiskit回路ライブラリのゲートに関連付けられますが、これを拡張することも可能です:
from qiskit.circuit import Gate
from qiskit.qasm2 import loads, CustomInstruction
class MyGate(Gate):
def __init__(self, theta):
super().__init__("my", 2, [theta])
class Builtin(Gate):
def __init__(self):
super().__init__("builtin", 1, [])
program = """
opaque my(theta) q1, q2;
qreg q[2];
my(0.5) q[0], q[1];
builtin q[0];
"""
customs = [
CustomInstruction(name="my", num_params=1, num_qubits=2, constructor=MyGate),
# Setting 'builtin=True' means the instruction doesn't require a declaration to be usable.
CustomInstruction("builtin", 0, 1, Builtin, builtin=True),
]
circuit = loads(program, custom_instructions=customs)同様に、ゲートへの引数の記述中に使用される新しい古典的関数を、プログラム本体(定数折りたたまれて出てくる)と、定義されたゲート本体(オンデマンドで計算される)の両方に追加することができる。 ここでは、 atan2(y, x) の Python バージョンを提供する。これは数学的には であるが、角度の四分位と無限大を正しく処理するもので、 add_one 関数はカスタムである:
import math
from qiskit.qasm2 import loads, CustomClassical
program = """
include "qelib1.inc";
qreg q[2];
rx(atan2(pi, 3 + add_one(0.2))) q[0];
cx q[0], q[1];
"""
def add_one(x):
return x + 1
customs = [
# `atan2` takes two parameters, and `math.atan2` implements it.
CustomClassical("atan2", 2, math.atan2),
# Our `add_one` takes only one parameter.
CustomClassical("add_one", 1, add_one),
]
circuit = loads(program, custom_classical=customs)OpenQASM 2相規約
言語として、 OpenQASM 2は、完全なプログラムのグローバル・フェーズや特定のゲート定義を指定する方法を持たない。 つまり、この言語のパーサーは、特定のゲートを、あなたが期待するものとは異なるグローバルな位相で解釈する可能性があるということだ。 例えば、 OpenQASM 2 qelib1.inc の事実上の標準ライブラリには、 u1 と rz の定義が以下のように含まれている:
gate u1(lambda) q {
U(0, 0, lambda) q;
}
gate rz(phi) a {
u1(phi) a;
}言い換えれば、 rz は、 u1 の直接の別名のようである。 しかし、 u1 の解釈は、その言語を記述した論文の式(3) で次のように規定されている
ここで、 の記号は、大域的な位相までのみ等価であることを示す。 OpenQASM 2を解析する際、このようなゲートの区別をどのように扱うかを選択する必要がある。 u1 は、 rz と位相が異なると散文で定義されているが、言語はこれを表現するようには設計されていない。
U1GateRZGateQiskit のデフォルトの挙動は、標準ライブラリ rz の の使用を によるものと解釈し、 の使用を u1 位相が異なる によるものと解釈することです。 ヘッダーファイル内の記述 gate を文字通り解釈した際に示唆される位相の規則を使用したい場合は、を使用して CustomInstruction 、Qiskitによる回路の構築方法を上書きすることができます。
標準的な qelib1.inc 、差は1点のみであるため、その位相規則を切り替えるために必要なオーバーライドは次のようになる:
from qiskit import qasm2
from qiskit.circuit.library import PhaseGate
from qiskit.quantum_info import Operator
program = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[1];
rz(pi / 2) q[0];
"""
custom = [
qasm2.CustomInstruction("rz", 1, 1, PhaseGate),
]U1Gateここでは、Qiskitの PhaseGate クラスを使用して 命令を rz 表現します。これは(位相も含めて)以下と等しくなります:
Operator(qasm2.loads(program, custom_instructions=custom))Operator([[1.000000e+00+0.j, 0.000000e+00+0.j],
[0.000000e+00+0.j, 6.123234e-17+1.j]],
input_dims=(2,), output_dims=(2,))レガシー互換性
QuantumCircuit.from_qasm_str() そして from_qasm_file() 生の仕様の上にいくつかの追加を行うために使用される。 Qiskitはもともと、 OpenQASM 2を一種のシリアライゼーション・フォーマットとして使おうとし、Qiskitの拡大とともにその動作を拡張してきた。 新しいパーサーはデフォルトのまま、より厳密に仕様を実装している。
特にレガシー・インポーターの場合だ:
-
include_pathが効果的である:
<qiskit>/qasm/libs<qiskit>はインストールされた パッケージのルートである;qiskit- 現行作業ディレクトリー。
-
**
qelib1.incで定義されている命令もある:**csx a, bCSXGate制御された ゲート。これは…に対応する。cu(theta, phi, lambda, gamma) c, tCUGate制御付き の4パラメータ版は、以下に対応する。rxx(theta) a, bRXXGate軸周りの2量子ビットの回転。これは、に相当する。rzz(theta) a, bRZZGate軸周りの2量子ビットの回転。これは、に相当する。rccx a, b, c二重制御の ゲートだが、標準的なToffoliゲートに比べて相対的な位相差がある。
RCCXGateこれはQiskitのゲートに対応するはずですが、レガシーコンバータでは実際にはこの型が出力されません。rc3x a, b, c, d3点制御の ゲートですが、標準的な定義とは位相差が異なります。
RC3XGate…に相当する。c3x a, b, c, dC3XGate. に対応する、3点制御式の ゲート。c3sqrtx a, b, c, dC3SXGate. に対応する、3点制御式の ゲート。c4x a, b, c, d, e4点制御式の ゲート
C4XGate…に相当する。 -
opaque、またはgateの定義がdelayという名前に対して与えられていた場合、それらは各呼び出しに対して命令を出力しようとする。Delay命令を出力しようとする。opaque delay(t) q;時間tはdtの単位で与えられる。 インポーターは、1つのパラメータと1つの量子ビットが正確に存在しない場合、またはパラメータが整数値でない場合、構築時にエラーを発生させます。 -
科学計算関数
asin、acos、atanが利用可能です。 -
パースされた文法は、実質的に新しいインポーターのストリクト・モードと同じである。
でこの動作をエミュレートできます。 load() と loads() でこの動作をエミュレートすることができる。include_pathを適切に設定し(インストールされた場所を見つけるために変数 qiskit.__file__ を調べてみてほしい)、気になるカスタム・ゲートごとに CustomInstruction インスタンスのリストを渡すことでこの動作をエミュレートできる。 物事を簡単にするために、私たちは3つのタプルを利用できるようにしています。それぞれのタプルには、Qiskitのレガシーコンバーターの動作と同等の設定のコンポーネントが1つずつ含まれています。
qiskit.qasm2.LEGACY_CUSTOM_INSTRUCTIONS
qelib1.inc 、 delay 命令の定義がある場合、Qiskitのレガシー組み込みコンバーターが使用する余分なcustom_instructionsを含むタプル。 論文版 qelib1.inc と delay のゲートはすべて、 OpenQASM 2プログラム内に互換宣言文が存在することを必要とするが、Qiskitのレガシー追加は、このパーサーが見るどのインクルードファイルにも実際には存在しないため、すべてビルトインとしてマークされる。
qiskit.qasm2.LEGACY_CUSTOM_CLASSICAL
Qiskitのレガシー組み込みコンバータが、論文で指定されているもの以外に使用する余分なcustom_classic関数を含むタプル。 これは3つの基本的な逆三角関数である: と 。
qiskit.qasm2.LEGACY_INCLUDE_PATH
レガシーQiskitコンバータが使用する正確なinclude_pathを含むタプル。
Qiskitのレガシーバージョンの qelib1.inc と delay 命令で定義されたすべてのゲートでは、ゲートが実際にどのように定義され使用されているかに関係なく、レガシーインポーターは常にそのカスタムオブジェクトを出力しようとします。 このため、パースに成功した後でも、回路構築中にエラーが発生する可能性がある。 でこのバギーな動作をエミュレートする方法はありません。 qiskit.qasm2include "qelib1.inc"; ステートメントかcustom_instructions引数のみが組み込みQiskit命令を使用させることができ、これらのシグネチャは互いに一致する。
上記のレガシー互換性設定を使用して load() および loads() でインポートされた回路は、非ユーザーゲートがqelib1.inc 定義されていない限り、Qiskitのレガシーインポーターによって作成された回路と等しいはずである。 新しいインポーターでは、ユーザー定義ゲートの扱いが若干異なります。検査上は同等の definition フィールドを持つはずですが、このモジュールでは(ほとんどのQiskitオブジェクトと同様に)、解析中に即座に生成するのではなく、要求があった際に定義を遅延読み込みするためのカスタムクラスを使用しています。 Qiskitのゲートに関する比較ルールでは、これら2つのオブジェクトは等しくないものとみなされますが、特定のバックエンドでこれらを通過 transpile() させれば、同じ出力回路が生成されるはずです。
代替
このモジュールのパーサー・コンポーネントは、最初は別の PyPI パッケージとしてスタートした: qiskit-qasm2. このパッケージのバージョン 0.5.3 は Qiskit Terra 0.24 に提供されました。 その後、2つのパッケージ間で変更があった場合、必ずしも同期が保たれるとは限りません。
OpenQASM、バージョン 3.0。 https://openqasm.com. これには、ハイレベルなクラシック・プログラミングのための設備がはるかに多く含まれている。 Qiskitはすでに OpenQASM 3を初歩的にサポートしている。 qiskit.qasm3 を参照してください。
OpenQASM 2 は Qiskit のシリアライズ言語には適さない。 QuantumCircuit. このモジュールは相互運用性のために提供されるものであり、一般的な直列化フォーマットとして提供されるものではない。 それが必要なら、代わりに qiskit.qpy 代わりに