Skip to main content
IBM Quantum Platform

OpenQASM 2 と Qiskit SDK

  • このページのコードは、以下の要件に基づいて開発された。 これらのバージョンまたは新しいバージョンの使用をお勧めします。

    qiskit[all]~=2.5.1
    

Qiskit SDKは、量子プログラムの OpenQASM 表現の間で変換するためのいくつかのツールを提供します。 QuantumCircuit クラスを提供します。


OpenQASM 2プログラムをQiskitにインポートする

OpenQASM 2のプログラムをQiskitにインポートする2つの関数。 これらは 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)

詳しくは OpenQASM 2 Qiskit APIをご覧ください。

簡単なプログラムをインポートする

ほとんどの OpenQASM 2プログラムでは、単純に qasm2.loadqasm2.loads を1つの引数で使うことができる。

例: 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()

Output:

     ┌───┐     ┌─┐   
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ゲートで接続

デフォルトでは、Qiskitの OpenQASM 2インポータはインクルードファイル "qelib1.inc"事実上の標準ライブラリとして扱います。 インポーターはこのファイルを、 OpenQASM 2を定義した元の論文に記述されているゲートを正確に含むものとして扱う。 Qiskitは回路ライブラリの組み込みゲートを使用して、 "qelib1.inc" のゲートを表現します。 マニュアル OpenQASM 2 gate ステートメントによってプログラム内で定義されたゲートは、デフォルトでは、カスタム Qiskit Gate サブクラスとして構築されます。

インポーターに特定の Gategate を使うように指示できます。 このメカニズムを使って、追加のゲート名を「ビルトイン」、つまり明示的な定義を必要としないものとして扱うこともできる。 "qelib1.inc" の外部で、 gate ステートメントに使用するゲート・クラスを指定すると、通常、結果の回路はより効率的に動作します。

Warning

Qiskit SDK v1.0 の時点で、Qiskitの OpenQASM* 2エクスポーター* ( OpenQASM 2へのQiskit回路のエクスポートを参照)は、依然として実際のゲート数よりも多いゲート数 "qelib1.inc" があるかのように動作します。 これは、インポーターのデフォルト設定では、当社のインポーターでエクスポートされたプログラムをインポートできない可能性があることを意味します。 この問題を解決するためのレガシーエクスポーターの使用方法については、具体的な例を参照してください。

この矛盾はQiskitのレガシーな動作であり、 Qiskitの後のリリースで解決される予定です

カスタム命令に関する情報を OpenQASM 2 インポータに渡すには、 qasm2.CustomInstruction クラスを使用します。 これには4つの必須情報があり、順に説明する:

  • OpenQASM 2 プログラムで使用されるゲートの名前
  • ゲートが取る角度パラメータの数
  • ゲートが作用する量子ビットの数
  • Python ゲートのコンストラクタクラスまたは関数。個々の引数としてゲートパラメータ(量子ビットは含まない)を取る

インポーターは、指定されたカスタム命令と一致する gate 定義に遭遇した場合、そのカスタム情報を使用してゲート・オブジェクトを再構築する。 カスタム命令の name と一致する gate ステートメントに遭遇したが、パラメータの数と量子ビットの数の両方と一致しない場合、インポーターは、提供された情報とプログラムとの不一致を示すために QASM2ParseErrorを発生させ、提供された情報とプログラムの不一致を示します。

さらに、5番目の引数 builtin をオプションで True に設定すると、ゲートが明示的に定義されていなくても、 OpenQASM 2 プログラム内で自動的に利用できるようになる。 インポーターが組み込みカスタム命令の明示的な gate 定義に遭遇した場合、それを黙って受け入れる。 以前と同様、同じ名前の明示的な定義が、提供されたカスタム命令と互換性がない場合は QASM2ParseError が発生します。 これは、古い OpenQASM 2 エクスポーターや、ハードウェアの「ベーシス・ゲート」を内蔵命令として扱う他の量子プラットフォームとの互換性を保つのに役立つ。

Qiskit は、 Qiskit の OpenQASM 2 エクスポート機能のレガシーバージョンで作成された OpenQASM 2 プログラムを操作するためのデータ属性を提供します。 これは qasm2.LEGACY_CUSTOM_INSTRUCTIONScustom_instructions 引数として与えられる。 qasm2.load() そして qasm2.loads().

例: Qiskitのレガシーエクスポーターで作成されたプログラムをインポートする

この OpenQASM 2プログラムでは、 "qelib1.inc" のオリジナル・バージョンにはないゲートを宣言せずに使用しているが、Qiskitのライブラリには標準的なゲートである。 を使用することができます。 qasm2.LEGACY_CUSTOM_INSTRUCTIONS を使うと、Qiskitの OpenQASM 2 エクスポーターが以前使っていたのと同じゲートのセットを使うように、インポーターに簡単に指示できます。

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

例: OpenQASM 2プログラムをインポートする際に特定のゲートクラスを使用する

Qiskitは一般的に、 OpenQASM 2 gate ステートメント内の定義が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,
)

例: 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の拡張機能です。

例:カスタムの古典的命令を使用する

ここでは、2つのカスタム・クラシック関数を提供する。 最初は単純で、入力に1を加えるだけだ。 2つ目は、四分円を意識した方法で数学演算 arctan(y/x)\arctan(y/x) を表す関数 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 で「letter-of-spec」モードを使うことができる。


Qiskit回路を OpenQASM にエクスポートする 2

Qiskitは QuantumCircuit を OpenQASM 2。 関数 qasm2.dump() を使ってファイルに書き込み qasm2.dumps() 文字列への書き込みには これらの関数は現在、非常にシンプルなインターフェースを持っている。 qasm2.dump()の場合のみ、出力を書き込む場所を指定する。

Warning

Qiskit の OpenQASM 2 エクスポーターは、レガシーな非標準バージョンの "qelib1.inc" インクルードファイルをまだ想定しています。 これはQiskitの後のリリースで解決される予定ですが、それまでの間、Qiskitで作成された OpenQASM 2プログラムを再インポートする必要がある場合は、 インポーターにレガシーゲートについて伝える方法について上記の例を使用してください。

例: 回路を 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")

次のステップ

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