実装を進めています

先週(2019/09/11)はブログの更新をお休みしました. すみません.

しばらくは, gcc の改造やこれまでに検討して参りましたシミュレータの改造を進めております.
コンポーネントごとに改造が進んだタイミングで, ソースコードを含めた改造箇所を解説する予定です.

LLVM Frontend 量子拡張 (Qlang を考える)

@k_yamaz 蛙 は, 量子コンピュータのための量子プログラミング言語や, 量子コンパイラを開発するための
OSSコミュニティ「OpenQL Project」を運営しております.
量子プログラミング言語, 量子コンパイラを開発するための調査, 検討を書いています.
OpenQL は, OpenMP や OpenCL の仕様を参考にして, 仕様を検討しています.

“A Software Methodology for Compiling Quantum Programs arXiv:1604.01401 “ による提案や
QuTechQuEST * , EPiQCによるLLVM ベースで量子拡張を目指した実装 ScaffCC など,
世界の研究機関でも同様の研究がされております.

LLVM Frontend の拡張

LLVM Frontend 量子拡張 (1. Qlang を考える) のエントリで検討しましたが,
状況が少しずつ変化してきました.

以前は, #pragma を定義してプログラムを書くことを想定してC言語の拡張を考えておりました.
このフロントエンドの開発では, 次の2つのアプローチを検討しました.

1) gcc に手を加えて, #pragma を使った実装を行う.
2) LLVM に手を入れて, primitive な型を拡張する.

gcc は構造化が見づらい一方で, LLVM は DSL が作りやすい構造があります.
LLVM を試していく予定です.

量子計算ライブラリ QuEST

RISC-V量子拡張は, 「RiscV.RV32IU」として @k_yamaz 蛙 が提案しています.
(詳しくは, 技術ブログ Qiita に投稿した RISC-Vの量子計算拡張 をご参照ください. )
思いつきなどをメモしていきます.

量子計算拡張を行ううえで, 量子計算ライブラリを自作するか, あるものを使うことになります.
ここでは, MIT Licence である QuEST を採用してRISC-Vシミュレータ(Spike)に組み込むこととします.

QuESTを利用できるようにするための, 導入は簡単です.

1
2
3
4
5
6
7
git clone https://github.com/quest-kit/QuEST.git
cd QuEST

mkdir build
cd build
cmake ..
make

このときにビルドされる libQuEST を RISC-V のシミュレータから利用することにします.
作成されるデモを試してみることもできます.

1
./demo

RISC-V 量子拡張の仕様検討

RISC-V量子拡張は, 「RiscV.RV32IU」として @k_yamaz 蛙 が提案しています.
(詳しくは, 技術ブログ Qiita に投稿した RISC-Vの量子計算拡張 をご参照ください. )
思いつきなどをメモしていきます.

RISC-V 量子拡張 で検討した内容から, 次の点を改善しました.
1量子ビット演算で全量子ビットに Hゲートをかける場合は, ユースケースとしては多く発生するのですが, 1量子ビット演算は
1命令セットで1量子ビットずつの指定しかできないため, 呼び出し数が多くなることが容易に想定されます.
そこでマスク指定した量子ビットに対して同じユニタリ操作ができるように変更しました.

量子レジスタ

量子計算の拡張セットでは, レジスタについては q0 から q32 (q0 は qzero を表す)とします.

拡張版:量子命令セット

1
2
3
4
5
6
7
8
9
10
qmeas.k   rd rs1 rs2 qimm6 31=1 14..12=0 6..2=0x02 1..0=3  # quantum measurement
qtelep.k rd rs1 rs2 qimm6 31=0 14..12=0 6..2=0x02 1..0=3 # quantum teleportation
qtocx.k rd rs1 rs2 qimm6 31=1 14..12=4 6..2=0x02 1..0=3 # quantum two-qubit operator CX-gate
qootdg.k rd rs1 rs2 qimm6 31=0 14..12=1 6..2=0x02 1..0=3 # quantum one-qubit operator T^{\dag}-gate
qoosdg.k rd rs1 rs2 qimm6 31=0 14..12=2 6..2=0x02 1..0=3 # quantum one-qubit operator S^{\dag}-gate
qooz.k rd rs1 rs2 qimm6 31=0 14..12=3 6..2=0x02 1..0=3 # quantum one-qubit operator Z-gate
qoox.k rd rs1 rs2 qimm6 31=0 14..12=4 6..2=0x02 1..0=3 # quantum one-qubit operator X-gate
qoos.k rd rs1 rs2 qimm6 31=0 14..12=5 6..2=0x02 1..0=3 # quantum one-qubit operator S-gate
qoot.k rd rs1 rs2 qimm6 31=0 14..12=6 6..2=0x02 1..0=3 # quantum one-qubit operator T-gate
qooh.k rd rs1 rs2 qimm6 31=0 14..12=7 6..2=0x02 1..0=3 # quantum one-qubit operator H-gate
  • 量子ビット間の移動(qtelep.k)

量子レジスタ rs1 の rd で指定された位置の量子ビットの状態を, 量子レジスタ rs2 の qimm6 で指定された位置の量子ビットに量子テレポーテーションします.
qimm6(30) = 1 のときは, rd や qimm6(25-29) に関わらず, rs1 の全量子ビットの状態を rs2 に量子テレポーテーションします.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 qimm6 rs2 rs1 000 rd 0001011
  • 量子レジスタの1量子ビットの初期化

量子レジスタ rs2 の qimm6 で指定された位置の量子ビットの状態を初期化します.
qimm6(30) = 1 のときは, qimm6(25-29) に関わらず, rs2 の全量子ビットの状態を初期化します.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 qimm6 rs2 rs1(=q0) 000 rd 0001011
  • 1量子ビット演算

量子レジスタ rs1 に対して, qimm6 で指定したビット位置に, Unitray で示されたユニタリ行列を作用する命令です.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 qimm6 rs2(=q0) rs1 Unitary rd 0001011
14 .. 12 Unitary opcode
001 $T^{\dagger}$ qootdg.k
010 $S^{\dagger}$ qoosdg.k
011 $Z$ qooz.k
100 $X$ qoox.k
101 $S$ qoos.k
110 $T$ qoot.k
111 $H$ qooh.k
  • 複数量子ビットに対する同一1量子ビット演算(古典レジスタrs2にマスク情報が保持されている前提)

古典レジスタ rs2 の値で指定された量子ビット(マスクで指定)に対して, 量子レジスタ rs1 に, Unitary で示されたユニタリ行列を作用する命令です.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 qimm6(=000000) rs2( $\ne$ q0) rs1 Unitary rd 0001011

※ Unitary は「1量子ビット演算」と同じです.

  • 2量子ビット演算

量子レジスタ rs2 の qimm6[control] で指定したビット位置を制御ビット, 量子レジスタ rs1 の rd[target] で指定したビット位置を操作ビットとして 2量子ビットの Control Unitary を作用する命令です.
qimm6(30) = 1 のときは, qimm6(25-29) に関わらず, rs2 の全量子ビットを制御ビットとして, rs1 の rs2 と同じ位置の量子ビットを操作ビットとして 2量子ビットの Control Unitary を作用します.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 qimm6 rs2 rs1 Unitary rd 0001011
14 .. 12 Unitary opcode
100 CNOT qtocx.k
  • 1量子ビットの測定(qmeas.k)

量子レジスタ rs1 の qimm6 で指定された位置の量子ビットの状態を測定して, 古典レジスタ rd の qimm6 ビット位置に値を保持します.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
1 qimm6 rs2(=q0) rs1 000 rd 0001011
  • 複数量子ビットの測定(古典レジスタrs2にマスク情報が保持されている前提)

古典レジスタ rs2 の値で指定された量子ビット(マスクで指定)に対して, 量子レジスタ rs1 の状態を測定して, 古典レジスタ rd のビット位置に値を保持します.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
1 qimm6(=000000) rs2( $\ne$ q0) rs1 000 rd 0001011

Github の private repository への bare & mirror

本開発は, 暫くはステルスで開発しております. 公開されている repository を元にしていますが, fork した repository ではなく,
次の手順で非公開( Private )の repoository に bare & mirror して開発を進めます.

1
2
3
4
5
6
7
# あらかじめ, 同名の空のリポジトリを非公開( Private )として作成しておきます. 
export SYNC_MODULE=risv-tools

git clone --bare --config remote.origin.fetch='+refs/heads/*:refs/heads/*' --config remote.origin.mirror=true https://github.com/riscv/${SYNC_MODULE}.git
cd ${SYNC_MODULE}.git
git remote add --mirror=push other https://openql-org@github.com/openql-org/${SYNC_MODULE}.git
git push other

制約付き量子ビット(Constraint Qubit)

RISC-V量子拡張は, 「RiscV.RV32IU」として @k_yamaz 蛙 が提案しています.
(詳しくは, 技術ブログ Qiita に投稿した RISC-Vの量子計算拡張 をご参照ください. )
思いつきなどをメモしていきます.

量子レジスタを考えるときに, 量子ビットを並べるわけですが, 現在開発されている多くの量子ビットは任意のユニタリ操作が動作するように作られています.
一方で, 量子誤り訂正の理論ではエンコードした複数の量子ビットに対しては, 任意のユニタリ操作を施すというより, 限定的なユニタリ操作しか行えません.
扱えるユニタリ操作は, 誤り訂正の種類によっても様々ですが, 量子誤り訂正を施した後の量子ビットは, 操作できる操作も制限があります.
ユニバーサリティを保つには H, T, CNOT ができる量子ビットが必要で, 最低限でも H, T, CNOT はできるようにすれば, 任意ユニタリ操作ができる一般的な
量子ビットと近似的に同様の計算が行えます.

さてここで, もう少し制約を付与した量子ビットを考えます. 例えば, ユニバーサリティが保てていない制約のある量子ビットを多く配置して,
ユニバーサリティが保てている量子ビットを少しだけ配置した構造で, 量子計算を目指すような構造を検討してみたいと思います.

T ゲート(非クリフォード操作)ができないクリフォード操作しか行えない量子ビットを考えます. 量子ビットの性能は満たさないため, これを「制約付き量子ビット(Constraint Qubit)」と呼びます.

※制約付き量子ビット(Constraint Qubit)の呼称は, ここで提案する呼び方で一般的な用語ではありません.

この制約付き量子ビットとクリフォード操作を組み合わせて一つの量子レジスタを構成します.
ここで検討している構成は次のような制約付き量子ビットを 7個と, 非クリフォードを含んだ結合のための量子ビット 1個の構成です.

●結合量子ビット(Connection-Qubit)

* 初期化: |0>のみ  
* 1量子ビットゲート操作: アダマール演算(H), π/8ゲート(T)のみ可能
* 2量子ビットゲート操作: 隣接する3つの量子ビットとの CNOT (CNOTの方向は制御側1つ、被制御側が2つ)  
* 測定: Z基底の測定、測定結果を古典レジスタ(測定レジスタ)のビットに反映  

●制約付き量子ビット(Constraint-Qubit)

* 初期化: |0>のみ  
* 1量子ビットゲート操作:    X, Z, H, Sゲートのみ可能  
* 2量子ビットゲート操作: 隣接する2つの量子ビットとの CNOT(CNOTの方向は制御側1つ、被制御側が1つ)  
                        (終端の量子ビットは, 隣接の1つの量子ビットと被制御側として CNOT を行える)
* 測定: Z基底の測定、測定結果を古典レジスタ(測定レジスタ)のビットに反映

(※本稿で記載した構成の量子レジスタは, 実装面とかけ離れすぎているという理由もあり, ボツ案となりました. [2019/08/21追記] )

RISC-V 量子拡張の実装

RISC-V量子拡張は, 「RiscV.RV32IU」として @k_yamaz 蛙 が提案しています.
(詳しくは, 技術ブログ Qiita に投稿した RISC-Vの量子計算拡張 をご参照ください. )
思いつきなどをメモしていきます.

さて, そろそろ RISC-V 量子拡張の実装を進めて参りましょう.
計画時では, RISC-V 量子拡張の実装は, ユニバーサルゲートである H ゲート, T ゲート, CNOT ゲートのみを準備するだけにしようとしていましたが,
QPU シミュレータの中を試行錯誤的に色々と検討したいという事由もあり, 次の通りの構成としました.

なお, RISC-V 量子拡張 (2. カスタム拡張を考える[続き]) で検討していた内容から, さらに検討が進み, 変更した事項があります.

1
2
3
4
5
6
7
8
9
10
qmeas.k   rd rs1 rs2 qimm6 31=1 14..12=0 6..2=0x02 1..0=3  # quantum measurement
qtelep.k rd rs1 rs2 qimm6 31=0 14..12=0 6..2=0x02 1..0=3 # quantum teleportation
qtocx.k rd rs1 rs2 qimm6 31=1 14..12=4 6..2=0x02 1..0=3 # quantum two-qubit operator CX-gate
qootdg.k rd rs1 rs2 qimm6 31=0 14..12=1 6..2=0x02 1..0=3 # quantum one-qubit operator T^{\dag}-gate
qoosdg.k rd rs1 rs2 qimm6 31=0 14..12=2 6..2=0x02 1..0=3 # quantum one-qubit operator S^{\dag}-gate
qooz.k rd rs1 rs2 qimm6 31=0 14..12=3 6..2=0x02 1..0=3 # quantum one-qubit operator Z-gate
qoox.k rd rs1 rs2 qimm6 31=0 14..12=4 6..2=0x02 1..0=3 # quantum one-qubit operator X-gate
qoos.k rd rs1 rs2 qimm6 31=0 14..12=5 6..2=0x02 1..0=3 # quantum one-qubit operator S-gate
qoot.k rd rs1 rs2 qimm6 31=0 14..12=6 6..2=0x02 1..0=3 # quantum one-qubit operator T-gate
qooh.k rd rs1 rs2 qimm6 31=0 14..12=7 6..2=0x02 1..0=3 # quantum one-qubit operator H-gate
  • 量子ビット間の移動(qtelep.k)

量子レジスタ rs1 の rd で指定された位置の量子ビットの状態を, 量子レジスタ rs2 の qimm6 で指定された位置の量子ビットに量子テレポーテーションします.
qimm6(30) = 1 のときは, rd や qimm6(25-29) に関わらず, rs1 の全量子ビットの状態を rs2 に量子テレポーテーションします.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 qimm6 rs2 rs1 000 rd 0001011
  • 量子レジスタの初期化(qtelep.k の特殊な命令)

量子レジスタ rs2 の qimm6 で指定された位置の量子ビットの状態を初期化します.
qimm6(30) = 1 のときは, qimm6(25-29) に関わらず, rs2 の全量子ビットの状態を初期化します.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 qimm6 rs2 rs1(=q0) 000 rd 0001011
  • 1量子ビット演算

量子レジスタ rs1 に対して, qimm6 で指定したビット位置に, Unitray で示されたユニタリ行列を作用する命令です.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 qimm6 rs2(=q0) rs1 Unitary rd 0001011
14 .. 12 Unitary opcode
001 $T^{\dagger}$ qootdg.k
010 $S^{\dagger}$ qoosdg.k
011 $Z$ qooz.k
100 $X$ qoox.k
101 $S$ qoos.k
110 $T$ qoot.k
111 $H$ qooh.k
  • 2量子ビット演算

量子レジスタ rs2 の qimm6[control] で指定したビット位置を制御ビット, 量子レジスタ rs1 の rd[target] で指定したビット位置を操作ビットとして 2量子ビットの Control Unitary を作用する命令です.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 qimm6 rs2 rs1 Unitary rd 0001011
14 .. 12 Unitary opcode
100 CNOT qtocx.k
  • 1量子ビットの測定(qmeas.k)

量子レジスタ rs1 の qimm6 で指定された位置の量子ビットの状態を測定して, 古典レジスタ rd の qimm6 ビット位置に値を保持します.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
1 qimm6 rs2(=q0) rs1 000 rd 0001011
  • 複数量子ビットの測定(qmeas.kの特殊な命令)

古典レジスタ rs2 の値で指定された量子ビット(マスクで指定)に対して, 量子レジスタ rs1 の状態を測定して, 古典レジスタ rd のビット位置に値を保持します.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
1 qimm6(=000000) rs2( $\ne$ q0) rs1 000 rd 0001011

RISC-V エミュレータ Spike と拡張命令の実装方針

RISC-V量子拡張は, 「RiscV.RV32IU」として @k_yamaz 蛙 が提案しています.
(詳しくは, 技術ブログ Qiita に投稿した RISC-Vの量子計算拡張 をご参照ください. )
思いつきなどをメモしていきます.

前回 RISC-V エミュレータ Spikeの最後に, Spike を Proxy Kernel を介してベアメタルプログラムで動作させるかを試しましたが, うまく行きませんでした. もう少し詳しく調査して最終的には riscv32 のコンパイラで作成したベアメタルプログラムを動作させてみたいですが, ここでは, RISCV 量子拡張版の エミュレータを動かすことを先に進めたいです.

まずは, riscv-gnu-toolchain は既に riscv64 版を準備しましたので, riscv-tools の下にある riscv-isa-sim, riscv-pk の riscv64 版をビルドします.
ビルドは, export RISCV=/opt/riscv 等で環境変数 RISCV を指定して, cmake / make / make install をします.
次に, riscv64 版のベアメタルプログラムを動作させましょう.

1
2
3
4
#include <stdio.h>
int main() {
printf("Hello RISCV!\n");
}

を準備して, 次のようにビルド / 実行します.

1
2
3
4
5
$ riscv64-unknown-elf-gcc hello.c -o hello
$ spike pk hello

bbl loader
Hello RISCV!

riscv64 版であれば, さほど苦もなく動作するようです.

さて, それでは Spike エミュレータに 拡張命令を組み込んでみましょう.
拡張命令セットの追加は, riscv-tools の submodule である riscv-opcodes を修正して, riscv-isa-sim に反映させます.

1
2
3
4
$ cd riscv-tools
$ cd risc-opcodes
(opcodes ファイルを適当に修正)
$ make install

命令セットの追加は, riscv-isa-sim の riscv/insns に実際の命令セットの動作を記述して追加し, spike をビルド/インストールします.

1
2
3
4
$ cd ../riscv-isa-sim
$ cd build
$ make
$ make install

RISC-V エミュレータ Spike

RISC-V toolchain(開発環境を整える)で RISC-Vの32ビット対応のための riscv-gnu-toolchain の開発環境を整えましたが, 本エントリで扱う riscv-tools を開発に使います. この riscv-tools は toolchain に risv64 のコンパイル環境を前提としているため, 一度構築した 32bit 環境を変更します.
変更した riscv-gnu-toolchain のインスール手順を掲載します.

1
2
3
4
5
6
$ git clone https://github.com/riscv/riscv-gnu-toolchain.git
$ cd riscv-gnu-toolchain
$ mkdir build
$ ../configure --prefix=/opt/riscv --enable-multilib
$ make
$ sudo make install

さて, RISC-V のエミュレーション環境は, すでに QEMU の環境を整えましたが, riscv-tool の中にある Spike もエミュレータとして動作します.
Spike は, QEMU よりも RISC-V の開発専用になっている分, 拡張実装の手順も簡便です. そこで, Spike を使って量子拡張実装を試して, QEMU に適応できるかを取り組んでいく手順で作業していきます.

Spike のビルド手順と, Proxy Kernel と呼ばれるベアメタルプログラムを動かす機構のビルド手順を掲載します.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ git clone https://github.com/riscv/riscv-tools.git
$ export RISCV=/opt/riscv
$ cd riscv-tools
$ cd riscv-spike
$ mkdir build
$ cd build
$ ../configure --prefix=${RISCV}
$ make
$ sudo make install

$ cd ../../riscv-pk
$ mkdir build
$ cd build
$ ../configure --prefix=${RISCV} --host=riscv32-unknown-elf
$ make
$ sudo make install

Spike を Proxy Kernel を介してベアメタルプログラムで動作させるには, 次のようにします.

1
2
$ riscv32-unknown-elf-gcc hello.c -o hello -mabi=ilp32 -fPIC -nostdlib -nostartfiles
$ spike --isa=rv32i /opt/riscv/riscv32-unknown-elf/bin/pk hello

(↑手元の環境でうまく動作していないため, 調査しています. )

RISC-V 量子拡張 (2. カスタム拡張を考える[続き])

RISC-V量子拡張は, 「RiscV.RV32IU」として @k_yamaz 蛙 が提案しています.
(詳しくは, 技術ブログ Qiita に投稿した RISC-Vの量子計算拡張 をご参照ください. )
思いつきなどをメモしていきます.

RISC-Vの 量子計算拡張を考えています.
量子計算の拡張セットでは, レジスタについては q0 から q32 (q0 は qzero を表す)としました.
量子命令セットは.

custom0(opecode = 0xb) := 今は定義することを考えないで空けておきます. (今後の検討で必要になるかもしれません. )
custom1(opecode = 0x2b) := 1量子ビット・ユニタリ演算
custom2(opecode = 0x5b) := 2量子ビット・ユニタリ演算
custom3(opecode = 0x7b) := 量子ビットの射影測定

とおきます. そして, 1量子ビット・ユニタリ演算は custom1_rs1, 2量子ビット・ユニタリ演算は custom2_rs1_rs2, 量子ビット射影測定は custom3_rs1_rs2 (rs2は古典レジスタ)で表せると仮定します. ほかに「量子ビットの初期化」「レジスタ間の移動」が必要ですが, 古典命令セットを流用できそうです.

というところまでは既に検討したところです.

なお, 量子拡張を表す識別文字を検討した際に,

量子を示すのに都合がよさそうなQuantumの頭文字「Q」は「4倍浮動小数点」として予約されていますので使えません. 
そこで量子計算に欠かせない「ユニタリ」を表す「U」の記号を当てるのが良さそうです. 量子計算拡張は「U」として提案しましょう. 

としていたのですが, qemu のソースコードを確認したところ, 「U」は user-level として特権モードかどうかの識別文字として使われていることが分かりました. ( user-level 「U」に対して, supervisor-level の「S」です. )
それを除くと使われていない識別文字は, G, K, O, R, W, X, Y, Z です. この中で量子っぽい文字を割付けたいのですが, 適当な文字があまりありません. 苦しまぎれに, 「K」はどうかと考えています. ロシア語圏などでは, “quantum” を “kvant” と記すようです.

さて, 具体的な量子命令セットを定義していきましょう.

詳細を検討してみると拡張セットの定義領域は思いのほか広く, custom0 だけで全ての量子命令セットが表現できる可能性がでてきました.
そこで, 以前に検討した方針を全面的に見直します. また, 「量子ビットの初期化」「レジスタ間の移動」は量子命令セットを独自で定義します.

再定義の量子命令セットは, フォーマット custom0_rs1_rs2 の R形式とするのが良いようです.

  • 量子ビット間の移動

量子レジスタ rs1 の shmat で指定された量子ビットの状態を, 量子レジスタ rs2 の shamt で指定された量子ビットに量子テレポーテーションします.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 shamt rs2 rs1 000 rd 0001011
  • 量子レジスタの初期化

量子レジスタ rs2 の shmat で指定された量子ビットの状態を初期化します.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 shamt rs2 rs1(=q0) 000 rd 0001011
  • 1量子ビット演算

量子レジスタ rs1 に対して, shamt で指定したビット位置に, Unitray で示されたユニタリ行列を作用する命令です.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 shamt rs2(=q0) rs1 Unitary rd 0001011
14 .. 12 Unitary
110 T
111 H
  • 2量子ビット演算

量子レジスタ rs1 の shamt[control] で指定したビット位置を制御ビット, 量子レジスタ rs2 の shamt[target] で指定したビット位置を操作ビットとして 2量子ビットの Control Unitary を作用する命令です.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
0 shamt[control] rs2 rs1 Unitary shamt[target] 0001011
14 .. 12 Unitary
011 CNOT
  • 1量子ビットの測定

量子レジスタ rs1 の shamt で指定された量子ビットの状態を測定して, 古典レジスタ rd の shamt ビット位置に値を保持します.

31 30 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
1 shamt rs2(=q0) rs1 000 rd 0001011
  • 複数量子ビットの測定

量子レジスタ rs2 で指定された量子ビット(マスクで指定)に対して, 量子レジスタ rs1 の状態を測定して, 古典レジスタ rd のビット位置に値を保持します.

31 .. 25 24 .. 20 19 .. 15 14 .. 12 11 .. 7 6 .. 0
1000000 rs2( $\ne$ q0) rs1 000 rd 0001011