Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Qamomile v0.10.0

Qamomile v0.10.0は、量子プログラミング層をゼロから再構築したリリースです。これにより従来のスコープである量子最適化アルゴリズム開発のみならず、より一般的に任意の量子プログラム/アルゴリズムの開発をカバーできるようになりました。v0.9.0からの変更点は非常に多岐にわたるため、差分の一覧ではなく、v0.10.0で何ができるようになったかをご紹介します。

より詳しい使い方についてはチュートリアルをご覧ください。

pip install qamomile==0.10.0

フロントエンド: @qkernel

Qamomile v0.10.0で量子プログラムを記述する中心となるAPIは@qkernelデコレータです。型アノテーション付きの通常のPython関数を書くだけで、Qamomileがそれを中間表現(IR)にトレースします。このIRは解析・可視化・トランスパイルに利用されますが、ユーザーが直接操作する必要はありません。また、for/whileループやif文による古典的な制御フローもサポートされており、これらもIRにトレースされます。

@qkernelを書くための必ず守る必要があるルールは以下の通りです:

  • **型ヒントは必須です。**引数と戻り値には主にQamomileで用意された型(QubitBitFloatUIntVector[T]Dict[K, V]Tuple[...])を使用します。

  • 量子ビットはアフィン型です。Qubitハンドルはゲート適用のたびに再代入が必要です(q = qmc.h(q))。

利用可能なゲートにはH、X、Y、Z、S、T、RX、RY、RZ、RZZ、CX、CZ、CCX、CP、SWAPなどがあります。測定にはqmc.measure()を使用します。

import qamomile.circuit as qmc


@qmc.qkernel
def ghz_state(
    n: qmc.UInt,
) -> qmc.Vector[qmc.Bit]:  # 引数と戻り値に型ヒントを指定
    q = qmc.qubit_array(n, name="q")  # 指定したサイズと名前で量子ビット配列を確保

    q[0] = qmc.h(q[0])
    for i in qmc.range(1, n):  # qmc.rangeで量子ビット1からn-1をイテレーション
        q[0], q[i] = qmc.cx(q[0], q[i])

    return qmc.measure(q)
ghz_state.draw(n=4, fold_loops=False)
<Figure size 880.5x336 with 1 Axes>

リソース推定

Qamomile v0.10.0ではシンボリックなリソース推定機能が提供されます。任意のqkernelに対してestimate_resources()を呼び出すと、qkernelを実行することなく量子ビット数やゲートの内訳を取得できます。これらは入力パラメータのシンボリック式として表現されるため、問題サイズに対するリソースのスケーリングの解析が容易です。具体的な値を代入して、特定の入力サイズに対する具体的な推定値を得ることも可能です。さらに、@composite_gateデコレータにてstub=Trueを指定して定義できる実装が不要なブラックボックスオラクルを定義することができ、これを用いたqkernelに対するリソースの推定も可能です。

est = ghz_state.estimate_resources()
print("qubits:", est.qubits)
print("total two-qubit gates:", est.gates.two_qubit)
qubits: n
total two-qubit gates: n - 1
# 特定のサイズで評価
print("two-qubit gates at n=100:", est.substitute(n=100).gates.two_qubit)
two-qubit gates at n=100: 99

マルチ量子SDKトランスパイル

@qkernelで回路を一度定義すれば、対応するサポート済みの量子SDKの形式へとトランスパイルが可能です。トランスパイルされたqkernelは対応する変換先の量子SDK毎のExecutableProgramとなります。Qamomile v0.10.0には各量子SDKにプリセットのExecutorが用意されているため,変換先の量子SDKのコードを書かずとも実行まで行うことができます。このプリセットのExecutorは原則シミュレータ実行を仮定しています。より細かい制御や実機へのアクセスのために、カスタムExecutorを作成することもできます。

バックエンドモジュールトランスパイラデフォルト実行
Qiskitqamomile.qiskitQiskitTranspilerローカルシミュレータ
QURI Partsqamomile.quri_partsQuriPartsTranspilerローカルシミュレータ
CUDA-Qqamomile.cudaqCudaqTranspilerローカルシミュレータ

さらに、Qiskitについては、qBraid実行をサポートとしており、クラウド量子デバイス上で実行することも可能です。

Qiskitはpip install qamomileにデフォルトで含まれていますが、その他の量子SDKやqBraid環境実行のためにはオプションの追加パッケージが必要です:

pip install "qamomile[cudaq-cu12]"   # CUDA-Q with CUDA 12.x (Linux)
pip install "qamomile[cudaq-cu13]"   # CUDA-Q with CUDA 13.x (Linux / macOS ARM64)
pip install "qamomile[quri_parts]"   # QURI Parts
pip install "qamomile[qbraid]"       # qBraid integration for Qiskit
from qamomile.qiskit import QiskitTranspiler

qiskit_transpiler = QiskitTranspiler()
qiskit_executable = qiskit_transpiler.transpile(ghz_state, bindings={"n": 4})
samples = qiskit_executable.sample(
    qiskit_transpiler.executor(),  # 実行するエグゼキュータを指定
    shots=1024,
).result()

for outcome, count in samples.results:
    print(f"  outcome={outcome}, count={count}")
  outcome=(0, 0, 0, 0), count=494
  outcome=(1, 1, 1, 1), count=530

標準ライブラリ

量子アルゴリズムを手軽に書けるよう、Qamomile v0.10.0ではqmc.stdlibqmc.algorithmモジュールに組み込みのアルゴリズムを用意しています。現在は量子フーリエ変換(QFT)や量子位相推定(QPE)、Quantum Approximation Optimization Algorithm(QAOA)などが含まれます。qmc.stdlibは広く使われる基本的なアルゴリズムブロック、qmc.algorithmはより特化したアルゴリズムとして収録していますが、この分類は厳密なものではなく、リリース毎に変更される可能性があります。

これらのモジュールにはアルゴリズムを随時追加していく予定です。ぜひご期待ください!

from qamomile.circuit.stdlib import qft


@qmc.qkernel
def qft_example() -> qmc.Vector[qmc.Bit]:
    q = qmc.qubit_array(4, name="q")
    q[0] = qmc.x(q[0])
    q = qft(q)
    return qmc.measure(q)


qft_example.draw(expand_composite=True)
<Figure size 2494.5x552 with 1 Axes>

最適化コンバータ

v0.9.0で提供されていたコンバータはqamomile.optimization以下で引き続き利用可能で、新しい@qkernelベースの回路層を使って書き直されています。 JijModelingやOMMXの数理モデルから、すぐに実行可能な回路を生成します。