銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

Qiskit を使ってQ#で記述した量子回路を描画する

Q# で書いた量子回路を回路図として表示したいというUserVoiceを見つけました。

General questions and feedback on Microsoft's Quantum Developer Kit
  • 2 votes
  • 1 comment

How to draw the quantum circuits using the Q#Language?

Hi, I find that one can draw the quantum circuits using the LIQUii>.How to draw the quantum circuits using the Q#Language?
I would appreciate it if you give me some advice.

quantum.uservoice.com

実際、量子回路を書くのに使えるツールはいくつかあって、図を描くという観点だとLaTeXで直接記述するのが一番直接的かつ出力もきれいだと思います。しかし、書いたコードから回路図を出したいという気持ちもあります。IBMが提供しているQiskitには実際にそのような機能があります。

qiskit.org

Qiskitでは量子回路をOpenQASMというフォーマットで扱うことができ、Q#もOpenQASMを出力するサンプルコードがある...ということで、これらを組み合わせて、Q#のコードで記述されている量子回路をQiskit経由で出力するというのが今回のテーマです。

こんな感じで実行されます。

f:id:tanaka733:20190127175947p:plain

ASCIIアート本体はこれです。

        ┌───┐     ┌─┐   
q_0: |0>┤ H ├──■──┤M├───
        └───┘┌─┴─┐└╥┘┌─┐
q_1: |0>─────┤ X ├─╫─┤M├
             └───┘ ║ └╥┘
 c_0: 0 ═══════════╩══╬═
                      ║ 
 c_1: 0 ══════════════╩═
                        

環境依存の強いコードですが、ここに一式置いておきます。

github.com

仕組みとしては、Microsoft/Qunatumが提供しているOpenQASMのDriverコードのサンプルを使って、Q#のコードをOpenQASM形式のファイルとして出力します。

Quantum/Samples at release/v0.3.1810 · Microsoft/Quantum · GitHub

Q#のコードは、Microsoft Quantumのサンプルにあったものを利用しています。

QuantumCircuitPractice/Operations.qs at 8760ca4171231c991057368441ea063732345522 · tanaka-takayoshi/QuantumCircuitPractice · GitHub

これに対応するOpenQASM形式のファイルはinput.txtという名前で出力されています。

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];

次にQiskitはOpenQASM形式のファイルから量子回路をロードするAPIがあるので、これを使って量子回路を構築しASCIIアートとしてファイル出力するPythonコードを実行します。QisikitはPythonライブラリなので、今回はこちらのコードはPythonで書いています。OpenQASMで書かれたinput.txtが存在すれば単体で動くコードです。

import sys, qiskit
from qiskit import load_qasm_string
from qiskit.tools.visualization import circuit_drawer
from qiskit import QuantumCircuit

print(sys.version)
print("qiskit version:", qiskit.__version__)

circ = QuantumCircuit.from_qasm_file("input.txt")

utf8stdout = open(1, 'w', encoding='utf-8', closefd=False)
circ.draw(filename="output.txt")

あとは、このPythonコードを(Q#を実行している).NET CoreからProcess.Startで実行して、出力されたファイルを読み込んで表示しています。

注意点としては、Q#からOpenQASMを出力するコードはサンプルレベルであり、またそもそもQ#が用意しているすべてのAPIをOpenQASM形式に出力できるわけではありません。また、通常、Q#は "{Q#のoperation名}.Run"というメソッドにQ#のDriverを指定して実行します。OpenQASMを出力するDriverもこの形式に則っていますが、既存の実装だと測定ゲートのたびに量子回路を評価する処理が呼び出されておりそこにファイル出力のコードを書くとそのたびにコードが出力されます。そこで、Runメソッドでは内部的に量子回路を読み込むもののそれ以外の処理はせず、OpenQASMを出力してPythonプロセスを実行する別のDrawメソッドを用意しています。 また、OpenQASMDriverの既存のコードでは、量子ビットの数をあらかじめ指定する必要があるため、量子ビット数が固定値2となっています。Q#のコードで3つ以上の量子ビットを割り当てたい場合は、この数値を変更する必要があります。この辺は、OpenQASMDriverをまじめに書き直せば改善できる気はしています。

OpenQASMを介するとこういうこともできるという一例でした。