えらいこっちゃ、えらいこっちゃ
blueqat開発者のgyu-donです。blueqatでは、Qiskitに合わせて、u1, u2, u3ゲート、cu1, cu2, cu3ゲートを用意していたのですが、いつの間にかQiskitでそれらが非推奨になっていました。
それはいいとして(?)、厄介なことに、いつの間にかcu3ゲートの定義が変わっていたので、これはえらいこっちゃ、えらいこっちゃ。
blueqat側も対応しないといけないので、とりあえず現状をまとめてみました。
qelib1.incの変更を見る
Qiskitのいろんなゲートが書かれているqelib1.incのgit blameをとりあえず見てみます。
このファイルが単なる参考なのか、これを読み込んでバックエンドが実装されているのかは定かではない(なんとなく、読んでいない気がする)のですが、ゲート定義のドキュメントのひとつとしては有力です。
すると、いくつか、知っておく必要のある変更があることが分かります。
とにかく、変更履歴を片っ端から追ってみました。
syncing qiskit/qasm/libs/qelib1.inc and qiskit/extensions/standard/cu3.py #3479
Date: 2019/11/20
gate cu3(theta,phi,lambda) c, t
{
// implements controlled-U(theta,phi,lambda) with target t and control c
u1((lambda-phi)/2) t;
cx c,t;
u3(-theta/2,0,-(phi+lambda)/2) t;
cx c,t;
u3(theta/2,phi,0) t;
}
を
gate cu3(theta,phi,lambda) c, t
{
// implements controlled-U(theta,phi,lambda) with target t and control c
u1((lambda+phi)/2) c;
u1((lambda-phi)/2) t;
cx c,t;
u3(-theta/2,0,-(phi+lambda)/2) t;
cx c,t;
u3(theta/2,phi,0) t;
}
に変更。
CU3の定義が変わっています。互換性がなく、過去のを前提に書いたコードは書き直す必要があります。実は#2755(2019/7/20)でCU3の定義を変えていて(というか、CU3が元々バグっていたのを修正したという認識?)、qelib1.incと整合性が取れていなかったのを、ここで直したらしいです。
そういう仕様だと思っていた人もいただろうに、変更したら互換性とかどうなるの、という感じです。
Fixed issue 3673 #3675
Date: 2020/1/9
// two-qubit XX rotation
gate rxx(theta) a,b
{
u3(pi/2, theta, 0) a;
h b;
cx a,b;
u1(-theta) b;
cx a,b;
h b;
u2(-pi, pi-theta) a;
}
を追加。
rxxゲートをqelib1.incに付け加えるのを忘れていたのでイオントラップ用のqasmファイルを読み込めなかった、というバグ#3673の対策として、qelib1.incにrxxゲートを付け加えた、という内容です。
Implement the relative phase Toffoli gates #3761
Date: 2020/2/14
// relative-phase CCX
gate rccx a,b,c
{
u2(0,pi) c;
u1(pi/4) c;
cx b, c;
u1(-pi/4) c;
cx a, c;
u1(pi/4) c;
cx b, c;
u1(-pi/4) c;
u2(0,pi) c;
}
// relative-phase CCCX
gate rcccx a,b,c,d
{
u2(0,pi) d;
u1(pi/4) d;
cx c,d;
u1(-pi/4) d;
u2(0,pi) d;
cx a,d;
u1(pi/4) d;
cx b,d;
u1(-pi/4) d;
cx a,d;
u1(pi/4) d;
cx b,d;
u1(-pi/4) d;
u2(0,pi) d;
u1(pi/4) d;
cx c,d;
u1(-pi/4) d;
u2(0,pi) d;
}
を追加。
Summary
Implement the relative phase Toffoli gates (CCX and CCCX), which only existed as functions and not Gates. These gates are used in the definition of other multi-controlled gates and are blocking their implementation.
ということで、Multi-controlledゲートを作るためにこれらのゲートが使えるそうです。詳しくは
https://arxiv.org/pdf/1508.03273.pdf
を見よ、とのことです。勉強になります。
Convert the MCX functions to gates #4082
Date: 2020/4/9
rcccx
をrc3x
に名称変更。また、
// 3-controlled X gate
gate c3x a,b,c,d
{
h d; cu1(-pi/4) a,d; h d;
cx a,b;
h d; cu1(pi/4) b,d; h d;
cx a,b;
h d; cu1(-pi/4) b,d; h d;
cx b,c;
h d; cu1(pi/4) c,d; h d;
cx a,c;
h d; cu1(-pi/4) c,d; h d;
cx b,c;
h d; cu1(pi/4) c,d; h d;
cx a,c;
h d; cu1(-pi/4) c,d; h d;
}
// 3-controlled sqrt(X) gate, this equals the C3X gate where the CU1 rotations are -pi/8 not -pi/4
gate c3sqrtx a,b,c,d
{
h d; cu1(-pi/8) a,d; h d;
cx a,b;
h d; cu1(pi/8) b,d; h d;
cx a,b;
h d; cu1(-pi/8) b,d; h d;
cx b,c;
h d; cu1(pi/8) c,d; h d;
cx a,c;
h d; cu1(-pi/8) c,d; h d;
cx b,c;
h d; cu1(pi/8) c,d; h d;
cx a,c;
h d; cu1(-pi/8) c,d; h d;
}
// 4-controlled X gate
gate c4x a,b,c,d,e
{
h e; cu1(-pi/2) d,e; h e;
c3x a,b,c,d;
h d; cu1(pi/4) d,e; h d;
c3x a,b,c,d;
c3sqrtx a,b,c,e;
}
を追加。
これもmulti-controlledゲート関係の話です。作り方がいろいろあるから、トランスパイラ任せにして、基本的なゲートだけ作ろう、という発想のようです。筋のいい考え方だと思います。
Sqrt(X) and C-Sqrt(X) gates #4638
Date: 2020/8/5
// sqrt(X)
gate sx a { sdg a; h a; sdg a; }
// inverse sqrt(X)
gate sxdg a { s a; h a; s a; }
// controlled-sqrt(X)
gate csx a,b { h b; cu1(pi/2) a,b; h b; }
を追加。
Add the Sqrt(X) (as SX) and C-Sqrt(X) (as CSX) gates and closes #4637.
Sqrt(X), C-Sqrt(X), Sqrt(X)† (sxdg)を定義しています。ちなみにC-Sqrt(X)†はありません。
Sqrt(X)は
\sqrt{X} = \frac{1}{2} \begin{pmatrix}
1 + i & 1 - i \\
1 - i & 1 + i
\end{pmatrix}
で定義されており、グローバル位相を除いてRX(π/2)と同じ、とのことです。
RX(\pi/2) = \frac{1}{\sqrt{2}} \begin{pmatrix}
1 & -i \\
-i & 1
\end{pmatrix}
= e^{-i \pi/4} \sqrt{X}
また$\sqrt{X}^2$は、グローバル位相も込みで、ちょうどXゲートに一致します。
SXゲートを実装した理由は#4637に書かれており、
We should add these two gates. The first one is the current native hardware gate that is tuned up (a.k.a X90p or RX(pi/2) although I think there's a global phase difference). The second one gives more efficient oracles via better Toffolis.
Let's call them SX and CSX for now (although V and CV also appear in the literature).
Then we should try to replace all usages of U2 with the SX gate (conjugated by RZ), which would put us on a path towards #4106.
とのことです。
ハードウェア実装上、SXゲートは1パルスでいけて、U2ゲートはこちらで置き換えるべき、という指摘は重要です。CSXについては、ついでだから付け足したのかなって印象です。
Add U and Phase gate #4765
Date: 2020/8/5
// generic single qubit gate
gate u(theta,phi,lambda) q { U(theta,phi,lambda) q; }
// phase gate
gate p(lambda) q { U(0,0,lambda) q; }
gate cp(lambda) a,b
{
p(lambda/2) a;
cx a,b;
p(-lambda/2) b;
cx a,b;
p(lambda/2) b;
}
gate cu(theta,phi,lambda,gamma) c, t
{ p(gamma) c;
p((lambda+phi)/2) c;
p((lambda-phi)/2) t;
cx c,t;
u(-theta/2,0,-(phi+lambda)/2) t;
cx c,t;
u(theta/2,phi,0) t;
}
を追加。
Summary
Adds U/CU and Phase/CPhase gates.
Details and comments
The phase gate is equivalent to U1, the U gate equivalent to U3. Unlike CU3 which contains 3 parameters, CU has a total of 4 parameters, where the new one is used to account for a possible phase of the controlled-U gate.
The U gate is called 'u', the phase gate called 'P' (which is also how they are displayed in plots).
U1/U2/U3 are not yet deprecated. Since this will probably touch a lot of code where references to 'u1' etc. are hardcoded, this will be addressed in a separate issue.
Partially addresses #4106, but doesn't close it since U1/U2/U3 are not removed.
- Phaseゲート(p)とUゲートを付け加える
- Phaseゲート(p)は、U1ゲートと同値、UゲートはU3ゲートと同値
- CUゲートはCU3の3つのパラメータに加えて、4つ目のパラメータγをもたせる(Uではグローバル位相にあたるものがCUでは効いてくるため)
- この段階ではU1/U2/U3の廃止はしないけれど、別途#4106で議論を行う
といった内容です。
U1, U2, U3廃止の議論がされている#4106を見てみます。
Gates clean up (Remove U1, U2, and U3) #4106
Date: 2020/8/8 opened (クローズしていない)
What is the expected enhancement?
Now that we have the transpiler working there is no need to have a confusing set of gate.
- U1 should be removed (as we have rz(theta)) or renamed p(theta) or phase(theta).
The motivation for the keeping is p.control() is different to rz.control()
U2 should be removed. There is no need we have this gate now the transpiler working. This really needs to happen in the transpiler and depending on the backend basis set choose how to do it.
U3 should be renamed just U as it is an arbitrary single-qubit gate.
CU1 should be renamed Cphase or CP depending on above
CU3 should be removed as it implies a control unitary but it is not (as it is missing global phase)
Add CU which should take into 4 parameters (three from U and one more - global phase in su(2))
- U1は廃止。RZまたはPを使う(両者はグローバル位相が異なる)
- U2は廃止。どうやら、元々はハードウェアの都合に合っていたけど今はそうでもなくなったような雰囲気ですね
- U3はUに改名
- CU1はCPに改名
- CU3は廃止、代わりにCUを新たに作り、グローバル位相項を付け加える
p.control()
という記法を検討(実現?)していることも伺わされます。
なお、これら廃止予定のゲートは、#5083において、「v0.16.0以降、廃止予定であり、3ヶ月の猶予期間のあと削除される」との旨の警告が出るよう変更され、取り入れられています。
Fix C4XGate QASM definition. #5265
// 4-controlled X gate
gate c4x a,b,c,d,e
{
h e; cu1(-pi/2) d,e; h e;
c3x a,b,c,d;
h d; cu1(pi/4) d,e; h d;
c3x a,b,c,d;
c3sqrtx a,b,c,e;
}
を
// 4-controlled X gate
gate c4x a,b,c,d,e
{
h e; cu1(-pi/2) d,e; h e;
c3x a,b,c,d;
h e; cu1(pi/2) d,e; h e;
c3x a,b,c,d;
c3sqrtx a,b,c,e;
}
に変更。
qelib1.incと実装に齟齬があったらしいです。
More efficient C3X implementation #5668
c3xの実装を以下のように変更。
// 3-controlled X gate
gate c3x a,b,c,d
{
h d;
p(pi/8) a;
p(pi/8) b;
p(pi/8) c;
p(pi/8) d;
cx a, b;
p(-pi/8) b;
cx a, b;
cx b, c;
p(-pi/8) c;
cx a, c;
p(pi/8) c;
cx b, c;
p(-pi/8) c;
cx a, c;
cx c, d;
p(-pi/8) d;
cx b, d;
p(pi/8) d;
cx c, d;
p(-pi/8) d;
cx a, d;
p(pi/8) d;
cx c, d;
p(-pi/8) d;
cx b, d;
p(pi/8) d;
cx c, d;
p(-pi/8) d;
cx a, d;s
h d;
}
効率よくなったらしいです。
グローバル位相関連
グローバル位相を回路に付け加える
add global_phase to QuantumCircuit class #4565
theta = 0
circ = QuantumCircuit(2, global_phase=theta)
circ.cx(0, 1)
個人的には微妙だな〜と思いました。
各ゲートにphase
プロパティを持たせて、ゲートのグローバル位相を調整できるようにする(却下)
Add phase
property to Gate
class #3930
面白いと思ったんですが、jaygambetta (Qiskitのボス)が微妙な反応を見せて、却下となりました。
blueqatはどうするか?
現在、blueqatでは、やや古めのU1/U2/U3, CU1/CU2/CU3の実装を取り入れています。CU3が途中で変更された影響でQiskitとblueqatで挙動が違う件については、最近issueが建てられました。(#109)
CU1/CU2/CU3のグローバル位相がなんか変なのは薄々気づいていたのですが、せっかくQiskit互換のために挙動を合わせたにも関わらず、Qiskit側がしれっと挙動を変えているのは、怒りを感じなくもないです。いずれにせよU1/U2/U3系自体が廃止の流れなので、CU3の挙動はそのままで利用を非推奨に、CUを新たに実装し、そちらは現状のQiskitと合わせることにしようかと思いました。
追記: Blueqatは0.4.2から突然、U1/U2/U3/CU1/CU2/CU3を廃止にします。互換性を壊して申し訳ないですが、将来廃止になるものをメンテするのが大変なので、この機会に廃止とさせてください。
CUゲートにはUゲートのグローバル位相に当たるγがあり、Uゲートにはそれがないことは、気持ち悪いな、と感じました。
blueqatには、省略可能なパラメータとしてγをつけようかと思います。Qiskitもいずれそうなると思います。知らんけど。
SXのような、ハードウェア実行を視野に入れたゲートについては、積極的に追加していきたいです。
Pゲートは、既にblueqatではRゲートとして実装しています。別名として、Pという名前も提供すればいいと思っています。
multi-controlledゲートなどは、シミュレータとハードウェアでコードを共通化できるような実装を探っていきます。
30年前にはユニバーサルなゲートセットは何か分かっていたにも関わらず、歴史的経緯、人間にとっての分かりやすさ、論理的な綺麗さ、ハードウェアの都合、トランスパイラの都合などが複雑に絡み合って、ごちゃごちゃと変化し、混沌が深まってきています。
とはいえ、これらの変化は実際に動くハードウェアが複数種類でき、また、ハードウェアで動かすために実際に量子回路を書くことが必要となった結果として生じたものでもあります。
特に、グローバル位相の重要性は、実際に回路を書いてはじめて気づくものでもあります。互換性を壊す破壊的な変更には怒りを感じつつも、基本的にはいい方向に発展してきていると感じますし、よい部分はblueqatにも取り入れていきたいです。