A kvantumkód hibakeresése és tesztelése
A klasszikus programozáshoz hasonlóan elengedhetetlen annak ellenőrzése, hogy a kvantumprogramok a kívánt módon működnek-e, és hogy képesek legyenek-e a helytelen viselkedés diagnosztizálására. Ez a cikk az Azure Quantum Development Kit által a kvantumprogramok teszteléséhez és hibakereséséhez kínált eszközöket ismerteti.
A program hibakeresése Q#
Az Azure Quantum Development Kit (QDK) Visual Studio Code bővítmény tartalmaz egy programok hibakeresőt Q# . Beállíthat töréspontokat, végiglépkedhet a kódon és az egyes függvényeken vagy műveleteken, és nemcsak a helyi változókat, hanem a qubitek kvantumállapotát is nyomon követheti.
Feljegyzés
A VS Code hibakeresője csak (.qs) fájlokkal Q# működik, és nem működik a Jupyter Notebook celláival Q# . A Jupyter Notebook-cellák teszteléséhez lásd a kód tesztelése című témakört.
Az alábbi példa a hibakereső alapvető funkcióit mutatja be. A VS Code hibakeresőinek használatával kapcsolatos teljes információkért lásd a hibakeresést.
A VS Code-ban hozzon létre és mentsen egy új .qs-fájlt a következő kóddal:
import Microsoft.Quantum.Arrays.*;
import Microsoft.Quantum.Convert.*;
operation Main() : Result {
use qubit = Qubit();
H(qubit);
let result = M(qubit);
Reset(qubit);
return result;
}
- Állítson be egy töréspontot a vonalon
H(qubit)
a sor számától balra kattintva. - A hibakereső panel megnyitásához válassza a hibakereső ikont, majd válassza a Futtatás és hibakeresés lehetőséget. A hibakereső vezérlők a képernyő tetején jelennek meg.
- A hibakeresés megkezdéséhez válassza az F5 lehetőséget, és folytassa a törésponttal. A Hibakereső változók paneljén bontsa ki a Quantum State kategóriát. Láthatja, hogy a qubit inicializálása |0> állapotban történt.
- Lépjen be (F11) a
H
műveletbe és a művelet forráskódjábaH
. A művelet során figyelje meg a kvantumérték változásait, mivel aH
művelet a qubitet szuperpozícióba helyezi. - A művelet (F10)
M
elvégzésekor a kvantumérték a mérés eredményeként |0> vagy |1> lesz, és megjelenik a klasszikus változóresult
értéke. - A művelet végrehajtása során a
Reset
qubit alaphelyzetbe áll a következőre: |0>.
A kód tesztelése
Bár a VS Code Q# hibakeresője nem érhető el a Jupyter Notebook celláihoz Q# , az Azure QDK olyan kifejezéseket és függvényeket biztosít, amelyek segíthetnek a kód hibaelhárításában.
Feladatkifejezés
A fail
kifejezés teljes egészében befejezi a számítást, amely a programot leálló végzetes hibának felel meg.
Tekintse meg ezt az egyszerű példát, amely egy paraméter értékét érvényesíti:
# import qsharp package to access the %%qsharp magic command
import qsharp
// use the %%qsharp magic command to change the cell type from Python to Q#
%%qsharp
function PositivityFact(value : Int) : Unit {
if value <= 0 {
fail $"{value} isn't a positive number.";
}
}
PositivityFact(0);
Error: program failed: 0 isn't a positive number.
Call stack:
at PositivityFact in line_2
Qsc.Eval.UserFail
× runtime error
╰─▶ program failed: 0 isn't a positive number.
╭─[line_2:5:1]
5 │
6 │ fail $"{value} isn't a positive number.";
· ────────────────────┬───────────────────
· ╰── explicit fail
7 │ }
╰────
Itt a fail
kifejezés megakadályozza, hogy a program továbbra is érvénytelen adatokkal fusson.
Fact() függvény
Ugyanazt a viselkedést valósíthatja meg, mint az előző példában a Fact()
Microsoft.Quantum.Diagnostics
névtérből származó függvény használatával. A Fact()
függvény kiértékel egy adott klasszikus feltételt, és kivételt ad, ha hamis.
import qsharp
%%qsharp
function PositivityFact(value : Int) : Unit {
Fact(value > 0, "Expected a positive number.");
}
PositivityFact(4);
Error: program failed: Expected a positive number.
Call stack:
at Microsoft.Quantum.Diagnostics.Fact in diagnostics.qs
at PositivityFact in line_4
Qsc.Eval.UserFail
× runtime error
╰─▶ program failed: Expected a positive number.
╭─[diagnostics.qs:29:1]
29 │ if (not actual) {
30 │ fail message;
· ──────┬─────
· ╰── explicit fail
31 │ }
╰────
DumpMachine() függvény
DumpMachine()
egy Q# olyan függvény, amely lehetővé teszi, hogy a gép aktuális állapotával target kapcsolatos információkat a konzolra írja, és folytassa a program futtatását.
Feljegyzés
Az Azure Quantum Development Kitkiadásával a DumpMachine()
függvény most már big-endian rendezést használ a kimenetéhez.
import qsharp
%%qsharp
import Microsoft.Quantum.Diagnostics.*;
operation MultiQubitDumpMachineDemo() : Unit {
use qubits = Qubit[2];
X(qubits[1]);
H(qubits[1]);
DumpMachine();
R1Frac(1, 2, qubits[0]);
R1Frac(1, 3, qubits[1]);
DumpMachine();
ResetAll(qubits);
}
MultiQubitDumpMachineDemo();
Basis State
(|𝜓₁…𝜓ₙ⟩) Amplitude Measurement Probability Phase
|00⟩ 0.7071+0.0000𝑖 50.0000% ↑ 0.0000
|01⟩ −0.7071+0.0000𝑖 50.0000% ↓ -3.1416
Basis State
(|𝜓₁…𝜓ₙ⟩) Amplitude Measurement Probability Phase
|00⟩ 0.7071+0.0000𝑖 50.0000% ↑ 0.0000
|01⟩ −0.6533−0.2706𝑖 50.0000% ↙ -2.7489
dump_machine() függvény
dump_machine
Egy Python-függvény, amely az aktuálisan lefoglalt qubitszámot adja vissza, valamint egy Python-szótárt, amely a ritkán elemezhető állapot amplitúdóit tartalmazza. Ezeknek a függvényeknek a Jupyter Notebookban való használatával a hibakeresőhöz hasonlóan végiglépkedhet a műveleteken. Az előző példaprogram használata:
import qsharp
%%qsharp
use qubits = Qubit[2];
X(qubits[0]);
H(qubits[1]);
dump = qsharp.dump_machine()
dump
Basis State
(|𝜓₁…𝜓ₙ⟩) Amplitude Measurement Probability Phase
|10⟩ 0.7071+0.0000𝑖 50.0000% ↑ 0.0000
|11⟩ 0.7071+0.0000𝑖 50.0000% ↑ 0.0000
%%qsharp
R1Frac(1, 2, qubits[0]);
R1Frac(1, 3, qubits[1]);
dump = qsharp.dump_machine()
dump
Basis State
(|𝜓₁…𝜓ₙ⟩) Amplitude Measurement Probability Phase
|10⟩ 0.5000+0.5000𝑖 50.0000% ↗ 0.7854
|11⟩ 0.2706+0.6533𝑖 50.0000% ↗ 1.1781
# you can print an abbreviated version of the values
print(dump)
STATE:
|10⟩: 0.5000+0.5000𝑖
|11⟩: 0.2706+0.6533𝑖
# you can access the current qubit count
dump.qubit_count
2
# you can access individual states by their index
dump[2]
(0.5+0.5000000000000001j)
dump[3]
(0.27059805007309845+0.6532814824381883j)
CheckZero() és CheckAllZero() műveletek
CheckZero()
és CheckAllZero()
olyan műveletek, amelyek ellenőrzik Q# , hogy egy qubit vagy qubittömb aktuális állapota $\ket{0}$. CheckZero()
akkor adja true
vissza, ha a qubit $\ket{0}$ állapotban van, és false
ha bármilyen más állapotban van. CheckAllZero()
akkor adja true
vissza, ha a tömb összes qubitje $\ket{0}$ állapotban van, és false
ha a qubitek bármely más állapotban vannak.
import Microsoft.Quantum.Diagnostics.*;
operation Main() : Unit {
use qs = Qubit[2];
X(qs[0]);
if CheckZero(qs[0]) {
Message("X operation failed");
}
else {
Message("X operation succeeded");
}
ResetAll(qs);
if CheckAllZero(qs) {
Message("Reset operation succeeded");
}
else {
Message("Reset operation failed");
}
}
dump_operation() függvény
dump_operation
Egy Python-függvény, amely egy műveletet vagy műveletdefiníciót, valamint számos használandó qubitet használ, és a művelet kimenetét jelképező összetett számok négyzetes mátrixát adja vissza.
Importálja dump_operation
a . parancsot qsharp.utils
.
import qsharp
from qsharp.utils import dump_operation
Ez a példa egy egy qubites identitáskapu és a Hadamard-kapu mátrixát nyomtatja ki.
res = dump_operation("qs => ()", 1)
print(res)
res = dump_operation("qs => H(qs[0])", 1)
print(res)
[[(1+0j), 0j], [0j, (1+0j)]]
[[(0.707107+0j), (0.707107+0j)], [(0.707107+0j), (-0.707107-0j)]]
Függvényt vagy műveletet qsharp.eval()
is definiálhat, majd hivatkozhat rá dump_operation
. A korábban képviselt egyetlen qubit a következőként is ábrázolható:
qsharp.eval("operation SingleQ(qs : Qubit[]) : Unit { }")
res = dump_operation("SingleQ", 1)
print(res)
[[(1+0j), 0j], [0j, (1+0j)]]
Ez a példa egy kapuval Controlled Ry
vált a második qubitre
qsharp.eval ("operation ControlRy(qs : Qubit[]) : Unit {qs[0]; Controlled Ry([qs[0]], (0.5, qs[1]));}")
res = dump_operation("ControlRy", 2)
print(res)
[[(1+0j), 0j, 0j, 0j], [0j, (1+0j), 0j, 0j], [0j, 0j, (0.968912+0j), (-0.247404+0j)], [0j, 0j, (0.247404+0j), (0.968912+0j)]]
Az alábbi kód határozza meg a Q# műveletet ApplySWAP
, és a mátrixot a két qubites identitásművelettel együtt nyomtatja ki.
qsharp.eval("operation ApplySWAP(qs : Qubit[]) : Unit is Ctl + Adj { SWAP(qs[0], qs[1]); }")
res = dump_operation("qs => ()", 2)
print(res)
res = dump_operation("ApplySWAP", 2)
print(res)
[[(1+0j), 0j, 0j, 0j], [0j, (1+0j), 0j, 0j], [0j, 0j, (1+0j), 0j], [0j, 0j, 0j, (1+0j)]]
[[(1+0j), 0j, 0j, 0j], [0j, 0j, (1+0j), 0j], [0j, (1+0j), 0j, 0j], [0j, 0j, 0j, (1+0j)]]
További példák a tesztelési műveletekre dump_operation()
a QDK Tesztelési műveletek lapján találhatók.