Ladění a testování kvantového kódu v QDK

Testování a ladění je stejně důležité pro kvantové programování, jako jsou v klasickém programování. Tento článek popisuje, jak ladit a testovat kvantové programy pomocí Microsoft Quantum Development Kit (QDK) ve Visual Studio Code (VS Code) a Jupyter Notebook.

Ladit kvantový kód

Sada QDK poskytuje několik nástrojů pro ladění kódu. Pokud v editoru VS Code píšete Q# nebo programy OpenQASM, můžete pomocí ladicího programu VS Code nastavit zarážky v programech a analyzovat kód. QDK také poskytuje sadu funkcí výpisu paměti, které můžete použít k získání informací v různých bodech programu.

Jak používat ladicí program VS Code

S rozšířením QDK ve VS Code můžete pomocí ladicího programu procházet kód a do každé funkce nebo operace, sledovat hodnoty místních proměnných a sledovat kvantové stavy qubitů.

Následující příklad ukazuje, jak používat ladicí nástroj s programem Q#. Úplné informace o ladicích programech VS Code najdete v tématu Ladění na webu VS Code.

  1. Ve VS Code vytvořte a uložte nový .qs soubor s následujícím kódem:

    import Std.Arrays.*;
    import Std.Convert.*;
    
    operation Main() : Result {
        use qubit = Qubit();
        H(qubit);
        let result = M(qubit);
        Reset(qubit);
        return result;
    }
    
  2. Na řádku 6 H(qubit) klikněte vlevo od čísla řádku a nastavte bod přerušení. Zobrazí se červený kruh.

  3. Na hlavním bočním panelu zvolte ikonu ladicího programu, otevřete podokno ladicího programu a pak zvolte Spustit a Ladit. Otevře se ovládací lišta ladicího programu.

  4. Stisknutím klávesy F5 spusťte ladicí program a pokračujte k místu přerušení. V nabídce Proměnné podokna ladicího programu rozbalte rozevírací seznam Quantum State , abyste viděli, že qubit byl inicializován ve stavu $\ket{0}$.

  5. Stisknutím klávesy F11 přejděte do H operace. Zobrazí se zdrojový kód operace H . Všimněte si, že při procházení operace H změní na superpozici.

  6. Stisknutím klávesy F10 přejděte k M operaci. Všimněte si, že kvantový stav se po měření přeloží na $\ket{0}$ nebo $\ket{1}$. Proměnná result je uvedená v části Místní hodnoty.

  7. Dalším stisknutím klávesy F10 přeskočte Reset operaci. Všimněte si, že kvantový stav se resetuje na $\ket{0}$.

Až dokončíte prozkoumávání ladicího programu, ukončete jej stisknutím Shift + F5.

Poznámka:

Ladicí program VS Code funguje jenom se soubory Q# (.qs) a OpenQASM .qasm. Nemůžete použít ladicí program VS Code v Q# buňkách v poznámkovém bloku Jupyter.

Ladění pomocí funkcí výpisu paměti QDK

Sada QDK poskytuje několik Q# a funkcí Pythonu, které vypisují informace o aktuálním stavu vašeho programu, když je vyvoláte. Pomocí informací z těchto funkcí výpisu paměti zkontrolujte, jestli se váš program chová podle očekávání.

Funkce Q#DumpMachine

DumpMachine Q# je funkce, která umožňuje výpis informací o aktuálním stavu qubitového systému do konzoly při spuštění programu. DumpMachine program během běhu nezastaví ani nepřeruší.

Následující příklad volá DumpMachine ve dvou bodech programu Q# a zkoumá výstup.

  1. Ve VS Code vytvořte a uložte nový .qs soubor s následujícím kódem:

    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. Stisknutím kombinace kláves Ctrl + Shift + Y otevřete konzolu ladění.

  3. Stisknutím kombinace kláves Ctrl+F5 spusťte program. V DumpMachine se zobrazí následující výstup:

    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
    

Výstup z DumpMachine ukazuje, jak se stav qubitových systémů mění po každé sadě bran.

Poznámka:

Výstup z DumpMachine používá big-endian pořadí.

Funkce Pythonu dump_machine

Funkce dump_machine je funkce z balíčku Pythonu qsharp . Tato funkce vrátí aktuální přidělený počet qubitů a slovník, který obsahuje zhuštěné amplitudy stavu qubitového systému.

Následující příklad spustí stejný program jako v předchozím DumpMachine příkladu, ale v poznámkovém bloku Jupyter místo .qs souboru.

  1. V editoru VS Code stisknutím kombinace kláves Ctrl + Shift + P otevřete paletu příkazů.

  2. Zadejte Vytvořit: Nový Jupyter Notebook a stiskněte Enter. Otevře se nová karta Jupyter Poznámkový blok.

  3. V první buňce zkopírujte a spusťte následující kód:

    from qdk import qsharp 
    
  4. Vytvořte novou buňku kódu a pak zkopírujte a spusťte následující Q# kód:

    %%qsharp
    
    use qubits = Qubit[2];
    X(qubits[0]);
    H(qubits[1]);
    
  5. Vytvořte novou buňku kódu. Zkopírujte následující kód Pythonu a zobrazte stav qubitu v tomto okamžiku v programu:

    dump = qsharp.dump_machine()
    dump
    

    Funkce dump_machine zobrazí následující výstup:

    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. Vytvořte novou buňku kódu a pak zkopírujte a spusťte následující Q# kód:

    %%qsharp
    
    R1Frac(1, 2, qubits[0]);
    R1Frac(1, 3, qubits[1]);
    
  7. Vytvořte novou buňku kódu. Zkopírujte následující kód Pythonu a zobrazte stav qubitu v tomto okamžiku v programu:

    dump = qsharp.dump_machine()
    dump
    

    Funkce dump_machine zobrazí následující výstup:

    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. Pokud chcete vytisknout zkrácenou verzi výstupu dump_machine , vytvořte novou buňku a spusťte následující kód Pythonu:

    print(dump)
    
  9. Pokud chcete získat celkový počet qubitů v systému, vytvořte novou buňku kódu a spusťte následující kód Pythonu:

    dump.qubit_count
    
  10. Můžete získat přístup k amplitudám stavů jednotlivých qubitů, které mají nenulové amplitudy. Vytvořte například novou buňku kódu a spuštěním následujícího kódu Pythonu získejte jednotlivé amplitudy stavů $\ket{10}$ a $\ket{11}$:

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

Funkce dump_operation

Funkce dump_operation je dostupná v qdk.qsharp modulu Python. Tato funkce přijímá dva vstupy: Q# operaci nebo definici operace jako řetězec a počet qubitů, které se v operaci používají. Výstupem dump_operation je vnořený seznam, který představuje čtvercovou matici komplexních čísel, která odpovídají dané kvantové operaci. Hodnoty matice jsou ve výpočetním základu a každý dílčí seznam představuje řádek matice.

Následující příklad používá dump_operation k zobrazení informací pro 1-qubitový a 2-qubitový systém.

  1. V editoru VS Code stisknutím kombinace kláves Ctrl + Shift + P otevřete paletu příkazů.

  2. Zadejte Vytvořit: Nový Jupyter Notebook a stiskněte Enter. Otevře se nová karta Jupyter Poznámkový blok.

  3. V první buňce zkopírujte a spusťte následující kód:

    from qdk.qsharp import dump_operation
    
  4. Pokud chcete zobrazit maticové prvky brány s jedním qubitem, zavolejte dump_operation a předejte 1 pro počet qubitů. Zkopírujte a spusťte následující kód Pythonu v nové buňce kódu, abyste získali maticové prvky pro bránu identity a hadamardovou bránu:

    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. Můžete také zavolat funkci qsharp.eval a poté odkazovat na operaci Q# v dump_operation, aby se získal stejný výsledek. Vytvořte například novou buňku kódu a pak zkopírujte a spusťte následující kód Pythonu, který vytiskne maticové prvky pro bránu Hadamard s jedním qubitem:

    qsharp.eval("operation SingleH(qs : Qubit[]) : Unit { H(qs[0]) }")
    
    res = dump_operation("SingleH", 1)
    print("Single-qubit Hadamard gate:\n", res)
    
  6. Pokud chcete zobrazit prvky matice dvouqubitové brány, zavolejte dump_operation a předejte číslo 2 jako počet qubitů. Zkopírujte a spusťte například následující kód Pythonu v nové buňce kódu, abyste získali maticové prvky pro řízenou operaci Ry, kde druhý qubit je 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)
    

Pro více příkladů, jak testovat a ladit svůj kód s dump_operation, viz Testování operací z ukázek QDK.

Testování kvantového kódu

Sada QDK poskytuje několik Q# funkcí a operací, které můžete použít k otestování kódu při jeho spuštění. Můžete také psát testy jednotek pro Q# programy.

Výraz fail

Výraz fail okamžitě ukončí váš program. Pokud chcete do kódu začlenit testy, použijte fail výrazy uvnitř podmíněných příkazů.

Následující příklad používá fail příkaz k otestování, že pole qubitu obsahuje přesně 3 qubity. Program končí chybovou zprávou, když test neprojde.

  1. Ve VS Code vytvořte a uložte nový .qs soubor s následujícím kódem:

    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. Stisknutím kombinace kláves Ctrl + F5 spusťte program. Program selže a v konzole ladění se zobrazí následující výstup:

    Error: program failed: The system should have 3 qubits, not 6.
    
  3. Upravte kód od Qubit[6] do Qubit[3], uložte soubor a stiskněte Ctrl + F5 a spusťte program znovu. Program se spustí bez chyby, protože test projde.

Funkce Fact

K otestování kódu můžete také použít funkci Q#Fact z Std.Diagnostics oboru názvů. Funkce Fact přebírá booleovský výraz a řetězec chybové zprávy. Pokud je logický výraz pravdivý, test projde a váš program se bude dál spouštět. Pokud je logický výraz false, Fact ukončí program a zobrazí se chybová zpráva.

Chcete-li provést stejný test délky pole ve vašem předchozím kódu, ale s funkcí Fact, postupujte takto:

  1. Ve VS Code vytvořte a uložte nový .qs soubor s následujícím kódem:

    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. Stisknutím kombinace kláves Ctrl + F5 spusťte program. Testovací podmínka Fact neprojde a chybová zpráva se zobrazí v konzole ladění.

  3. Upravte kód od Qubit[6] do Qubit[3], uložte soubor a stiskněte Ctrl + F5 a spusťte program znovu. Testovací podmínka v Fact splňuje a váš program se spustí bez chyby.

Napište Q# jednotkové testy s @Test() anotací

V Q# programech můžete použít anotaci @Test() na volání (funkci nebo operaci) a převést je na jednotkový test. Tyto testy jednotek se zobrazí v nabídce Testování v editoru VS Code, abyste mohli tuto funkci VS Code využít. Volatelnou položku můžete změnit na jednotkový test pouze v případě, kdy volatelná nepřebírá vstupní parametry.

Následující příklad zabalí kód testování délky pole do operace a převede tuto operaci na jednotkový test.

  1. Ve VS Code vytvořte a uložte nový .qs soubor s následujícím kódem:

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

    Poznámka @Test() na řádku před definicí TestCase operace změní operaci na jednotkový test VS Code. Na řádku definice operace se zobrazí zelená šipka.

  2. Vyberte zelenou šipku k spuštění TestCase a ohlášení výsledků testu.

  3. Pokud chcete pracovat s jednotkovými testy v Průzkumníku testů VS Code, klikněte na ikonu testování flask v hlavním postranním panelu.

  4. Upravte kód z Qubit[3] do Qubit[6] a znovu spusťte test jednotek, abyste viděli, jak se mění informace o testu.

Jednotkové testy můžete psát a spouštět Q# ve VS Code bez operace vstupního bodu v programu.

Poznámka:

Volání z Std.Diagnostics oboru názvů nejsou kompatibilní s generováním QIR, takže zahrňte do kódu, který spouštíte na simulátorech, pouze jednotkové testy Q#. Pokud chcete vygenerovat QIR z Q# kódu, nezahrnujte do kódu jednotkové testy.

Operace CheckZero a CheckAllZero

Operace CheckZero a CheckAllZeroQ# ověřují, zda je aktuální stav qubitu nebo pole qubitů $\ket{0}$. Operace CheckZero vezme jeden qubit a vrátí true se pouze v případech, kdy je qubit ve stavu $\ket{0}$. Operace CheckAllZero přebírají pole qubitu a vrátí se true pouze tehdy, když jsou všechny qubity v poli ve stavu $\ket{0}$. Pokud chcete použít CheckZero a CheckAllZero, importujte je z oboru názvů Std.Diagnostics.

Následující příklad používá obě operace. Testy CheckZero ověřují, že X operace převrací první qubit ze stavu $\ket{0}$ do stavu $\ket{1}$, a operace CheckAllZero ověřuje, že oba qubity jsou resetovány do stavu $\ket{0}$.

Ve VS Code vytvořte a uložte nový .qs soubor s následujícím kódem, spusťte program a prozkoumejte výstup v konzole ladění.

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