Kvantumkód hibakeresése és tesztelése a QDK-ban

A tesztelés és a hibakeresés ugyanolyan fontos a kvantumprogramozásban, mint a klasszikus programozásban. Ez a cikk a kvantumprogramok hibakeresését és tesztelését ismerteti a Visual Studio Code (VS Code) és a Microsoft Quantum Development Kit Jupyter Notebook QDK használatával.

Kvantumkód hibakeresése

A QDK számos eszközt biztosít a kód hibakereséséhez. Ha a VS Code-ban ír Q# vagy OpenQASM-programokat, a VS Code hibakeresőjével töréspontokat állíthat be a programokban, és elemezheti a kódot. A QDK olyan kiíró függvényeket is biztosít, amelyekkel információkat szerezhet a program különböző pontjain.

A VS Code hibakereső használata

A VS Code QDK-bővítményével a hibakeresővel végiglépkedhet a kódon és az egyes függvényeken vagy műveleteken, nyomon követheti a helyi változók értékeit, és követheti a qubitek kvantumállapotait.

Az alábbi példa bemutatja, hogyan használhatja a hibakeresőt egy Q# programmal. A VS Code hibakeresőiről további információt a VS Code webhelyén található hibakeresésben talál.

  1. A VS Code-ban hozzon létre és mentsen egy új .qs fájlt a következő kóddal:

    import Std.Arrays.*;
    import Std.Convert.*;
    
    operation Main() : Result {
        use qubit = Qubit();
        H(qubit);
        let result = M(qubit);
        Reset(qubit);
        return result;
    }
    
  2. A 6 H(qubit). sorban kattintson a sorszámtól balra a töréspont beállításához. Megjelenik egy piros kör.

  3. Az Elsődleges oldalsávon válassza a hibakereső ikont a hibakereső panel megnyitásához, majd válassza a Futtatás és hibakeresés lehetőséget. Megnyílik a hibakereső vezérlősávja.

  4. Nyomja le az F5 a hibakereső elindításához, és folytassa a töréspontig. A hibakereső panel Változók menüjében bontsa ki a Quantum State legördülő menüt, és ellenőrizze, hogy a qubit inicializálva lett-e $\ket{0}$ állapotban.

  5. A művelethez nyomja le az H billentyűt. Megjelenik a H művelet forráskódja. Figyelje meg, hogy a Kvantumállapot szuperpozícióra változik a H művelet végrehajtása során.

  6. Az F10 billentyűt lenyomva lépjen túl a M műveleten. Figyelje meg, hogy a Quantum State a mérés után $\ket{0}$ vagy $\ket{1}$ lesz. A result változó a Helyiek területen található.

  7. A művelet végrehajtásához nyomja le ismét az Reset billentyűt. Vegye észre, hogy a Quantum State újra beállítva $\ket{0}$ állapotba kerül.

Ha befejezte a hibakereső felderítését, a Shift + F5 billentyűkombinációt lenyomva lépjen ki a hibakeresőből.

Feljegyzés

A VS Code hibakeresője csak Q# (.qs) és OpenQASM (.qasm) fájlokkal működik. A VS Code hibakeresője nem használható a Jupyter Notebook Q# celláin.

QDK dump függvényekkel történő hibakeresés

A QDK számos Q# Python-függvényt biztosít, amelyek információt adnak a program aktuális állapotáról, amikor meghívja ezeket a függvényeket. A dump függvényekből származó információk segítségével ellenőrizheti, hogy a program a várt módon viselkedik-e.

A Q#DumpMachine függvény

DumpMachine egy Q# olyan függvény, amely lehetővé teszi, hogy a program futtatásakor a qubitrendszer aktuális állapotával kapcsolatos információkat a konzolra írja. DumpMachine futásidőben nem állítja le vagy szakítja meg a programot.

Az alábbi példa a program két pontján meghívja a DumpMachine-t, és megvizsgálja a kimenetet.

  1. A VS Code-ban hozzon létre és mentsen egy új .qs fájlt a következő kóddal:

    import Std.Diagnostics.*;
    
    operation Main() : 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);
    }
    
  2. A hibakeresési konzol megnyitásához nyomja le a Ctrl + Shift +Y billentyűkombinációt.

  3. A program futtatásához nyomja le a Ctrl + F5 billentyűkombinációt. A DumpMachine a következő kimenet jelenik meg:

    Basis | Amplitude      | Probability | Phase
    -----------------------------------------------
     |00⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
     |01⟩ | −0.7071+0.0000𝑖 |    50.0000% |  -3.1416
    
    Basis | Amplitude      | Probability | Phase
    -----------------------------------------------
     |00⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
     |01⟩ | −0.6533−0.2706𝑖 |    50.0000% |  -2.7489
    

A kimenet DumpMachine azt mutatja be, hogyan változik a qubitrendszerek állapota az egyes kapuk után.

Feljegyzés

A kimenet DumpMachine big-endian sorrendet használ.

A Python dump_machine függvény

A dump_machine függvény a Python-csomag egyik függvénye qsharp . Ez a függvény az aktuálisan lefoglalt qubitszámot adja vissza, valamint egy szótárt, amely a qubitrendszer ritka állapot amplitúdóit tartalmazza.

Az alábbi példa ugyanazt a programot futtatja, mint az előző DumpMachine példában, de nem .qs fájlban, hanem egy Jupyter-jegyzetfüzetben.

  1. A VS Code-ban nyomja le a Ctrl + Shift + P billentyűkombinációt a parancskatalógus megnyitásához.

  2. Írja be a Létrehozás: Új Jupyter-jegyzetfüzet parancsot, és nyomja meg az Enter billentyűt. Megnyílik egy új Jupyter Notebook lap.

  3. Az első cellában másolja és futtassa a következő kódot:

    from qdk import qsharp 
    
  4. Hozzon létre egy új kódcellát, majd másolja és futtassa a következő Q# kódot:

    %%qsharp
    
    use qubits = Qubit[2];
    X(qubits[0]);
    H(qubits[1]);
    
  5. Hozzon létre egy új kódcellát. Másolja és futtassa a következő Python-kódot a qubit állapotának megtekintéséhez a program ezen pontján:

    dump = qsharp.dump_machine()
    dump
    

    A dump_machine függvény a következő kimenetet jeleníti meg:

    Basis State
    (|𝜓₁…𝜓ₙ⟩)  Amplitude       Measurement Probability  Phase
    |10⟩       0.7071+0.0000𝑖   50.0000%                 ↑  0.0000
    |11⟩       0.7071+0.0000𝑖   50.0000%                 ↑  0.0000
    
  6. Hozzon létre egy új kódcellát, majd másolja és futtassa a következő Q# kódot:

    %%qsharp
    
    R1Frac(1, 2, qubits[0]);
    R1Frac(1, 3, qubits[1]);
    
  7. Hozzon létre egy új kódcellát. Másolja és futtassa a következő Python-kódot a qubit állapotának megtekintéséhez a program ezen pontján:

    dump = qsharp.dump_machine()
    dump
    

    A dump_machine függvény a következő kimenetet jeleníti meg:

    Basis State
    (|𝜓₁…𝜓ₙ⟩)  Amplitude      Measurement Probability  Phase
    |10⟩       0.5000+0.5000𝑖  50.0000%                 ↗  0.7854
    |11⟩       0.2706+0.6533𝑖  50.0000%                 ↗  1.1781
    
  8. A kimenet rövidített verziójának dump_machine nyomtatásához hozzon létre egy új cellát, és futtassa a következő Python-kódot:

    print(dump)
    
  9. A qubitek teljes számának lekéréséhez hozzon létre egy új kódcellát, és futtassa a következő Python-kódot:

    dump.qubit_count
    
  10. A nemzero amplitúdóval rendelkező egyes qubitállapotok amplitúdóit elérheti. Hozzon létre például egy új kódcellát, és futtassa a következő Python-kódot a $\ket{10}$ és $\ket{11}$ állapotok egyéni amplitúdóinak lekéréséhez:

    print(dump[2])
    print(dump[3])
    

A dump_operation függvény

A dump_operation függvény a qdk.qsharp Python modulban érhető el. Ez a függvény két bemenetet fogad: egy műveleti sztringet, vagy a művelet definícióját sztringként, valamint a műveletben felhasznált qubitek számát. A kimenet dump_operation egy beágyazott lista, amely az adott kvantumműveletnek megfelelő komplex számok négyzetmátrixát jelöli. A mátrixértékek számítási alapértékek, és minden allista a mátrix egy sorát jelöli.

Az alábbi példa dump_operation egy 1 qubites és 2 qubites rendszer adatait jeleníti meg.

  1. A VS Code-ban nyomja le a Ctrl + Shift + P billentyűkombinációt a parancskatalógus megnyitásához.

  2. Írja be a Létrehozás: Új Jupyter-jegyzetfüzet parancsot, és nyomja meg az Enter billentyűt. Megnyílik egy új Jupyter Notebook lap.

  3. Az első cellában másolja és futtassa a következő kódot:

    from qdk.qsharp import dump_operation
    
  4. Az egy qubites kapu mátrixelemeinek megjelenítéséhez hívja meg dump_operation és adja át az 1-et a qubitek számához. Másolja és futtassa például a következő Python-kódot egy új kódcellában egy identitáskapu és egy Hadamard-kapu mátrixelemeinek lekéréséhez:

    res = dump_operation("qs => ()", 1)
    print("Single-qubit identity gate:\n", res)
    print()
    
    res = dump_operation("qs => H(qs[0])", 1)
    print("Single-qubit Hadamard gate:\n", res)
    
  5. Meghívhatja a függvényt is, qsharp.eval majd hivatkozhat a Q# műveletre dump_operation , hogy ugyanazt az eredményt kapja. Hozzon létre például egy új kódcellát, majd másolja és futtassa a következő Python-kódot egy egy qubites Hadamard-kapu mátrixelemeinek nyomtatásához:

    qsharp.eval("operation SingleH(qs : Qubit[]) : Unit { H(qs[0]) }")
    
    res = dump_operation("SingleH", 1)
    print("Single-qubit Hadamard gate:\n", res)
    
  6. A két qubites kapu mátrixelemeinek megjelenítéséhez hívja meg dump_operation és adja át a 2-t a qubitek számához. Másolja és futtassa például a következő Python-kódot egy új kódcellában egy szabályozott Ry művelet mátrixelemeinek lekéréséhez, ahol a második qubit a target qubit:

    qsharp.eval ("operation ControlRy(qs : Qubit[]) : Unit { Controlled Ry([qs[0]], (0.5, qs[1])); }")
    
    res = dump_operation("ControlRy", 2)
    print("Controlled Ry rotation gate:\n", res)
    

További példák a kód dump_operationtesztelésére és hibakeresésére: Tesztelési műveletek a QDK-mintákból.

A kvantumkód tesztelése

A QDK számos Q# függvényt és műveletet biztosít, amelyekkel futtatás közben tesztelheti a kódot. Egységteszteket is írhat a Q# programokhoz.

A fail kifejezés

A fail kifejezés azonnal befejezi a programot. Ha teszteket szeretne beépíteni a kódba, használja a fail feltételes utasításokon belüli kifejezéseket.

Az alábbi példa egy fail utasítással teszteli, hogy egy qubittömb pontosan 3 qubitet tartalmaz-e. A program hibaüzenettel végződik, ha a teszt nem megy át.

  1. A VS Code-ban hozzon létre és mentsen egy új .qs fájlt a következő kóddal:

    operation Main() : Unit {
        use qs = Qubit[6];
        let n_qubits = Length(qs);
    
        if n_qubits != 3 {
            fail $"The system should have 3 qubits, not {n_qubits}.";
        }  
    }
    
  2. A program futtatásához nyomja le a Ctrl + F5 billentyűkombinációt. A program meghiúsul, és a hibakeresési konzolon a következő kimenet jelenik meg:

    Error: program failed: The system should have 3 qubits, not 6.
    
  3. Szerkessze a kódot Qubit[6] és Qubit[3] között, mentse el a fájlt, majd nyomja meg a Ctrl + F5 billentyűkombinációt a program újbóli futtatásához. A program hiba nélkül fut, mert a teszt sikeres.

A Fact függvény

A Q# névtérben található FactStd.Diagnostics függvény használatával tesztelheti a kódot. A Fact függvény logikai kifejezést és en hibaüzenet-sztringet vesz fel. Ha a logikai kifejezés igaz, akkor a teszt sikeres lesz, és a program továbbra is fut. Ha a logikai kifejezés hamis, akkor Fact befejezi a programot, és megjeleníti a hibaüzenetet.

Ha ugyanazt a tömbhosszúsági tesztet szeretné elvégezni az előző kódban, de most a Fact függvénnyel, kövesse az alábbi lépéseket:

  1. A VS Code-ban hozzon létre és mentsen egy új .qs fájlt a következő kóddal:

    import Std.Diagnostics.Fact;
    
    operation Main() : Unit {
        use qs = Qubit[6];
        let n_qubits = Length(qs);
    
        Fact(n_qubits == 3,  $"The system should have 3 qubits, not {n_qubits}.")
    }
    
  2. A program futtatásához nyomja le a Ctrl + F5 billentyűkombinációt. A tesztfeltétel Fact nem teljesül, és a hibakeresési konzolon megjelenik a hibaüzenet.

  3. Szerkessze a kódot Qubit[6] és Qubit[3] között, mentse el a fájlt, majd nyomja meg a Ctrl + F5 billentyűkombinációt a program újbóli futtatásához. A tesztelési Fact feltétel sikeres, és a program hiba nélkül fut.

Egységtesztek írása Q# annotációval @Test()

A Q# programokban alkalmazhatja a @Test() annotációt egy hívható elemre (függvényre vagy műveletre), hogy azt egységtesztté alakítsa. Ezek az egységtesztek a VS Code Tesztelés menüjében jelennek meg, hogy kihasználhassa ezt a VS Code-funkciót. A hívhatót csak akkor lehet egységtesztté alakítani, ha a hívható nem veszi figyelembe a bemeneti paramétereket.

Az alábbi példa egy műveletbe burkolja a tömbhossz-tesztkódot, és egységtesztté alakítja a műveletet:

  1. A VS Code-ban hozzon létre és mentsen egy új .qs fájlt a következő kóddal:

    import Std.Diagnostics.Fact;
    
    @Test()
    operation TestCase() : Unit {
        use qs = Qubit[3];
        let n_qubits = Length(qs);
    
        Fact(n_qubits == 3, $"The system should have 3 qubits, not {n_qubits}.");
    }
    

    A @Test() műveletdefiníció előtti sora TestCase megjegyzéssel ellátva VS Code-egységtesztté alakítja a műveletet. Zöld nyíl jelenik meg a műveletdefiníciós sorban.

  2. A teszteredmények futtatásához TestCase és jelentéséhez válassza a zöld nyílbillentyűt.

  3. Ha a VS Code Test Explorerben szeretné kezelni az egységteszteket, válassza a Testelés ikont a fő oldalsávban.

  4. Szerkessze a kódot Qubit[3]-ról Qubit[6]-re, és futtassa újra az egységtesztet, hogy lássa, hogyan változnak a tesztinformációk.

VS Code-ban egységteszteket írhat és futtathat, anélkül hogy belépési pont műveletet végezne a programban.

Feljegyzés

A Std.Diagnostics névtérből származó hívható elemek nem kompatibilisek a QIR-generációval, ezért csak az Q# kódba foglaljanak egységteszteket, amelyeket szimulátorokon futtatnak. Ha QIR-t szeretne létrehozni a Q# kódból, akkor ne foglalja bele az egységteszteket a kódba.

Az CheckZero és a CheckAllZero műveletek

Az CheckZero és CheckAllZeroQ# a műveletek ellenőrzik, hogy egy qubit vagy qubittömb aktuális állapota $\ket{0}$-e. A CheckZero művelet egyetlen qubitet vesz fel, és csak akkor ad true vissza, ha a qubit $\ket{0}$ állapotban van. A CheckAllZero műveletek qubittömböt vesznek fel, és csak akkor adnak true vissza, ha a tömb összes qubitje $\ket{0}$ állapotban van. Ahhoz, hogy használja a CheckZero és CheckAllZero, importálja őket a Std.Diagnostics névtérből.

Az alábbi példa mindkét műveletet használja. A CheckZero tesztek azt vizsgálják, hogy a X művelet az első qubitet a $\ket{0}$ állapotból a $\ket{1}$ állapotba állítja, és a CheckAllZero művelet azt vizsgálja, hogy mindkét qubit visszaáll-e a $\ket{0}$ állapotra.

A VS Code-ban hozzon létre és mentsen egy új .qs fájlt a következő kóddal, majd futtassa a programot, és vizsgálja meg a kimenetet a hibakeresési konzolon.

import Std.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");
    }
}