Skip to main content
IBM Quantum Platform

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)

GitHub

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プログラムを表す回路オブジェクト。

戻りの型

QuantumCircuit

loads

qiskit.qasm2.loads(string, *, include_path=('.',), custom_instructions=(), custom_classical=(), strict=False)

GitHub

OpenQASM 2のプログラムを文字列からパースし、次のように変換する。 QuantumCircuit.

内部の古典的式パーサーは再帰的であり、評価に過度な深さが必要となる式がある場合、例外 RecursionError を発生させます。 sys.setrecursionlimit()この最大深度は を使用して調整できます。実際の制限値はこの値の10分の1となります。

パラメーター

戻り値

同じ OpenQASM 2プログラムを表す回路オブジェクト。

戻りの型

QuantumCircuit

これらのローディング関数はどちらも、 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)

GitHub

ベース: object

パース中に定義されるべきカスタム命令に関する情報。

namenum_paramsnum_qubits フィールドは自明である。 constructor フィールドは、 *args -> Instruction のシグネチャを持つ呼び出し可能なオブジェクトであるべきで、 num_params args のそれぞれは浮動小数点値である。 組み込みのQiskitゲートクラスのほとんどはこの形式を持っています。

最後に builtin 。 これはオプションであり、trueに設定すると、たとえ含まれる OpenQASM 2ファイルに定義がなくても、命令が定義され、構文解析で利用できるようになる。

インポーターにQiskitの ECRGateRZXGate オブジェクトを使用し、 OpenQASM 2 エクスポート時に同じオブジェクトから作成されたことがわかっている gate ステートメントを解釈するように指示します:

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, /)

GitHub

回路を OpenQASM 2 プログラムとしてファイルまたはストリームにダンプする。

パラメーター

レイズ

QASM2ExportError - 回路が OpenQASM 2で表現できない場合。

dumps

qiskit.qasm2.dumps(circuit, /)

GitHub

回路を文字列で OpenQASM 2 プログラムにエクスポートします。

パラメーター

circuit (QuantumCircuit) – その QuantumCircuit をエクスポートする。

戻り値

OpenQASM 2 回路を表す文字列。

レイズ

QASM2ExportError - 回路が OpenQASM 2で表現できない場合。

戻りの型

str


エラー

このモジュールは QiskitError から派生する汎用エラー型を定義します。

QASM2Error

exception qiskit.qasm2.QASM2Error(*message)

GitHub

ベース: QiskitError

OpenQASM 2インターオペレーションレイヤーで発生した一般的なエラー。

エラーメッセージを設定する。

無効な OpenQASM 2 ファイルが原因でレキサーやパーサーが失敗した場合、変換関数は、失敗の内容とファイルのどこで発生したかを説明するメッセージとともに、より具体的なエラーを発生させます。

QASM2ParseError

exception qiskit.qasm2.QASM2ParseError(*message)

GitHub

ベース: QASM2Error

OpenQASM 2 ファイルの解析に失敗し、エラーが発生した。

エラーメッセージを設定する。

回路が OpenQASM 2.0 で表現できない構造を持っているためと思われるが、エクスポータが回路のエクスポートに失敗すると、カスタムエラーも発生する。

QASM2ExportError

exception qiskit.qasm2.QASM2ExportError(*message)

GitHub

ベース: 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 バージョンを提供する。これは数学的には arctan(y/x)\arctan(y/x) であるが、角度の四分位と無限大を正しく処理するもので、 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事実上の標準ライブラリには、 u1rz の定義が以下のように含まれている:

gate u1(lambda) q {
    U(0, 0, lambda) q;
}

gate rz(phi) a {
    u1(phi) a;
}

言い換えれば、 rz は、 u1 の直接の別名のようである。 しかし、 u1 の解釈は、その言語を記述した論文の式(3) で次のように規定されている

u1(λ)=diag(1,eiλ)Rz(λ)u_1(\lambda) = \operatorname{diag}\bigl(1, e^{i\lambda}\bigr) \sim R_z(\lambda)

ここで、 \sim の記号は、大域的な位相までのみ等価であることを示す。 OpenQASM 2を解析する際、このようなゲートの区別をどのように扱うかを選択する必要がある。 u1 は、 rz と位相が異なると散文で定義されているが、言語はこれを表現するようには設計されていない。

Qiskitのデフォルトの立場は、標準ライブラリ rz の用法を RZGateを使用していると解釈し、 u1 の使用は、相異なる U1Gate. ヘッダーファイルの gate ステートメントを直接解釈することで、より暗示的な位相規約を使用したい場合は、Qiskit が回路を構築する方法を上書きするために 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),
]

これはQiskitの PhaseGate クラスを使って rz 命令を表します。 U1Gate:

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が効果的である:

    1. <qiskit>/qasm/libs <qiskit> はインストールされた パッケージのルートである; qiskit
    2. 現行作業ディレクトリー。
  • ** qelib1.inc で定義されている命令もある:**

    csx a, b

    X\sqrt X ゲートを制御。 CSXGate.

    cu(theta, phi, lambda, gamma) c, t

    UU に対応する。 CUGate.

    rxx(theta) a, b

    XXXX の軸を中心とした2量子ビットの回転。 RXXGate.

    rzz(theta) a, b

    ZZZZ の軸を中心とした2量子ビットの回転。 RZZGate.

    rccx a, b, c

    二重制御 XX ゲートだが、標準的なトッフォリゲートとは相対的な位相差がある。 これは Qiskitのゲート RCCXGateに対応するはずだが、レガシー・コンバーターは実際にはこのタイプを出力しない。

    rc3x a, b, c, d

    トリプル制御の XX ゲートだが、標準的な定義よりも相対的な位相差がある。 に相当する。 RC3XGate.

    c3x a, b, c, d

    トリプル制御の XX ゲートは、次のように対応する。 C3XGate.

    c3sqrtx a, b, c, d

    トリプル制御の X\sqrt X ゲートは、次のように対応する。 C3SXGate.

    c4x a, b, c, d, e

    四重制御 XX ゲート..、 に相当する。 C4XGate.

  • opaque 、または gate定義が delay という名前に対して与えられていた場合、それらは各呼び出しに対して命令を出力しようとする。 Delay 命令を出力しようとする。 opaque delay(t) q;時間 tdt の単位で与えられる。 インポーターは、1つのパラメータと1つの量子ビットが正確に存在しない場合、またはパラメータが整数値でない場合、構築時にエラーを発生させます。

  • 科学計算関数 asinacosatan が利用可能です。

  • パースされた文法は、実質的に新しいインポーターのストリクト・モードと同じである。

でこの動作をエミュレートできます。 load()loads() でこの動作をエミュレートすることができる。include_pathを適切に設定し(インストールされた場所を見つけるために変数 qiskit.__file__ を調べてみてほしい)、気になるカスタム・ゲートごとに CustomInstruction インスタンスのリストを渡すことでこの動作をエミュレートできる。 物事を簡単にするために、私たちは3つのタプルを利用できるようにしています。それぞれのタプルには、Qiskitのレガシーコンバーターの動作と同等の設定のコンポーネントが1つずつ含まれています。

qiskit.qasm2.LEGACY_CUSTOM_INSTRUCTIONS

qelib1.incdelay 命令の定義がある場合、Qiskitのレガシー組み込みコンバーターが使用する余分なcustom_instructionsを含むタプル。 論文版 qelib1.incdelay のゲートはすべて、 OpenQASM 2プログラム内に互換宣言文が存在することを必要とするが、Qiskitのレガシー追加は、このパーサーが見るどのインクルードファイルにも実際には存在しないため、すべてビルトインとしてマークされる。

qiskit.qasm2.LEGACY_CUSTOM_CLASSICAL

Qiskitのレガシー組み込みコンバータが、論文で指定されているもの以外に使用する余分なcustom_classic関数を含むタプル。 これは3つの基本的な逆三角関数である: arcsin\arcsin arccos\arccosarctan\arctan

qiskit.qasm2.LEGACY_INCLUDE_PATH

レガシーQiskitコンバータが使用する正確なinclude_pathを含むタプル。

Qiskitのレガシーバージョンの qelib1.incdelay 命令で定義されたすべてのゲートでは、ゲートが実際にどのように定義され使用されているかに関係なく、レガシーインポーターは常にそのカスタムオブジェクトを出力しようとします。 このため、パースに成功した後でも、回路構築中にエラーが発生する可能性がある。 でこのバギーな動作をエミュレートする方法はありません。 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 代わりに

このページは役に立ちましたか?
バグや誤字の報告、またはコンテンツの要求はGitHubで行ってください。