Q# で書いた量子回路を回路図として表示したいというUserVoiceを見つけました。
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.
実際、量子回路を書くのに使えるツールはいくつかあって、図を描くという観点だとLaTeXで直接記述するのが一番直接的かつ出力もきれいだと思います。しかし、書いたコードから回路図を出したいという気持ちもあります。IBMが提供しているQiskitには実際にそのような機能があります。
Qiskitでは量子回路をOpenQASMというフォーマットで扱うことができ、Q#もOpenQASMを出力するサンプルコードがある...ということで、これらを組み合わせて、Q#のコードで記述されている量子回路をQiskit経由で出力するというのが今回のテーマです。
こんな感じで実行されます。
ASCIIアート本体はこれです。
┌───┐ ┌─┐ q_0: |0>┤ H ├──■──┤M├─── └───┘┌─┴─┐└╥┘┌─┐ q_1: |0>─────┤ X ├─╫─┤M├ └───┘ ║ └╥┘ c_0: 0 ═══════════╩══╬═ ║ c_1: 0 ══════════════╩═
環境依存の強いコードですが、ここに一式置いておきます。
仕組みとしては、Microsoft/Qunatumが提供しているOpenQASMのDriverコードのサンプルを使って、Q#のコードをOpenQASM形式のファイルとして出力します。
Quantum/Samples at release/v0.3.1810 · Microsoft/Quantum · GitHub
Q#のコードは、Microsoft Quantumのサンプルにあったものを利用しています。
これに対応する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を介するとこういうこともできるという一例でした。