Delen via


Debuggen en testen van kwantumcode

Testen en foutopsporing zijn net zo belangrijk in kwantumprogrammering als in klassieke programmering. In dit artikel wordt beschreven hoe u fouten in uw kwantumprogramma's opspoort en test met azure Quantum Development Kit (QDK) in Visual Studio Code (VS Code) en Jupyter Notebook.

Debuggen van uw kwantumcode

De QDK biedt verschillende hulpprogramma's voor het opsporen van fouten in uw code. Als u programma's schrijft Q# of OpenQASM in VS Code, kunt u het foutopsporingsprogramma van VS Code gebruiken om onderbrekingspunten in uw programma's in te stellen en uw code te analyseren. De QDK biedt ook een set dumpfuncties die u kunt gebruiken om informatie op verschillende punten in uw programma op te halen.

Het foutopsporingsprogramma van VS Code gebruiken

Met de QDK-extensie in VS Code kunt u het foutopsporingsprogramma gebruiken om uw code en in elke functie of bewerking te doorlopen, de waarden van lokale variabelen bij te houden en de kwantumstatussen van de qubits te volgen.

In het volgende voorbeeld ziet u hoe u de debugger gebruikt met een programma zoals Q#. Zie Foutopsporing op de WEBSITE van VS Code voor volledige informatie over foutopsporingsprogramma's van VS Code.

  1. Maak en sla in VS Code een nieuw .qs bestand op met de volgende code:

    import Std.Arrays.*;
    import Std.Convert.*;
    
    operation Main() : Result {
        use qubit = Qubit();
        H(qubit);
        let result = M(qubit);
        Reset(qubit);
        return result;
    }
    
  2. Klik op regel 6 H(qubit)links van het regelnummer om een onderbrekingspunt in te stellen. Er wordt een rode cirkel weergegeven.

  3. Kies in de primaire zijbalk het pictogram voor foutopsporingsprogramma om het deelvenster foutopsporing te openen en kies vervolgens Uitvoeren en fouten opsporen. De bedieningsbalk van de debugger wordt weergegeven.

  4. Druk op F5 om het foutopsporingsprogramma te starten en door te gaan naar het onderbrekingspunt. Vouw in het menu Variabelen van het foutopsporingsprogramma de vervolgkeuzelijst Kwantumstatus uit om te zien dat de qubit is geïnitialiseerd in de status $\ket{0}$.

  5. Druk op F11 om de H bewerking te openen. De broncode voor de H bewerking wordt weergegeven. U ziet dat de kwantumstatus verandert in een superpositie wanneer u de H bewerking doorloopt.

  6. Druk op F10 om de M bewerking te doorlopen. Merk op dat kwantumtoestand resulteert in $\ket{0}$ of $\ket{1}$ na de meting. De result variabele wordt ook weergegeven onder Locals.

  7. Druk nogmaals op F10 om de Reset bewerking te doorlopen. U ziet dat de kwantumstatus opnieuw wordt ingesteld op $\ket{0}$.

Wanneer u klaar bent met het verkennen van het foutopsporingsprogramma, drukt u op *Ctrl + F5 om het foutopsporingsprogramma af te sluiten.

Notitie

Het VS Code-foutopsporingsprogramma werkt alleen met Q# (.qs) en OpenQASM-bestanden (.qasm). U kunt het foutopsporingsprogramma van VS Code niet gebruiken in Q# cellen in Jupyter Notebook.

Hoe te debuggen met QDK-dumpfuncties

De QDK biedt verschillende Q# en Python-functies waarmee informatie over de huidige status van uw programma wordt gedumpt wanneer u deze functies aanroept. Gebruik informatie van deze dumpfuncties om te controleren of uw programma zich gedraagt zoals verwacht.

De Q#DumpMachine functie

DumpMachine is een Q# functie waarmee u informatie over de huidige status van het qubitsysteem naar de console kunt dumpen terwijl uw programma wordt uitgevoerd. DumpMachine stopt of onderbreekt uw programma niet tijdens runtime.

In het volgende voorbeeld wordt `DumpMachine` op twee punten in een `Q#` programma aangeroepen en wordt de uitvoer verkend.

  1. Maak en sla in VS Code een nieuw .qs bestand op met de volgende code:

    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. Druk op Ctrl+Shift+Y om de console voor foutopsporing te openen.

  3. Druk op Ctrl+F5 om het programma uit te voeren. De volgende uitvoer van DumpMachine verschijnt in de foutopsporingsconsole:

    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
    

In de uitvoer van DumpMachine ziet u hoe de toestand van de qubitsystemen na elke set poorten verandert.

Notitie

De uitvoer van DumpMachine is in big-endian volgorde.

De Python-functie dump_machine

De dump_machine functie is een functie uit het qsharp Python-pakket. Deze functie retourneert het huidige aantal toegewezen qubits en een woordenlijst die de sparse-statusamplitudes van het qubitsysteem bevat.

In het volgende voorbeeld wordt hetzelfde programma uitgevoerd als in het vorige DumpMachine voorbeeld, maar in een Jupyter-notebook in plaats van een .qs bestand.

  1. Druk in VS Code op Ctrl+Shift+P om het opdrachtenpalet te openen.

  2. Enter Create: New Jupyter Notebook en druk op Enter. Er wordt een nieuw Jupyter Notebook-tabblad geopend.

  3. Kopieer en voer in de eerste cel de volgende code uit:

    from qdk import qsharp 
    
  4. Maak een nieuwe codecel en kopieer en voer de volgende Q# code uit:

    %%qsharp
    
    use qubits = Qubit[2];
    X(qubits[0]);
    H(qubits[1]);
    
  5. Maak een nieuwe codecel. Kopieer en voer de volgende Python-code uit om de qubitstatus op dit punt in het programma weer te geven:

    dump = qsharp.dump_machine()
    dump
    

    De dump_machine functie geeft de volgende uitvoer weer:

    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. Maak een nieuwe codecel en kopieer en voer de volgende Q# code uit:

    %%qsharp
    
    R1Frac(1, 2, qubits[0]);
    R1Frac(1, 3, qubits[1]);
    
  7. Maak een nieuwe codecel. Kopieer en voer de volgende Python-code uit om de qubitstatus op dit punt in het programma weer te geven:

    dump = qsharp.dump_machine()
    dump
    

    De dump_machine functie geeft de volgende uitvoer weer:

    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. Als u een verkorte versie van de dump_machine uitvoer wilt afdrukken, maakt u een nieuwe cel en voert u de volgende Python-code uit:

    print(dump)
    
  9. Als u het totale aantal qubits in het systeem wilt ophalen, maakt u een nieuwe codecel en voert u de volgende Python-code uit:

    dump.qubit_count
    
  10. U hebt toegang tot de amplitudes van afzonderlijke qubitsstatussen die niet-nul-amplitude hebben. Maak bijvoorbeeld een nieuwe codecel en voer de volgende Python-code uit om de afzonderlijke amplitudes voor de status $\ket{10}$ en $\ket{11}$ op te halen:

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

De functie dump_operation

De dump_operation functie is een functie uit het qsharp.utils Python-pakket. Deze functie gebruikt twee invoerwaarden: een Q# bewerkings- of bewerkingsdefinitie als een tekenreeks en het aantal qubits dat in de bewerking wordt gebruikt. De uitvoer van dump_operation is een geneste lijst die de vierkante matrix van complexe getallen vertegenwoordigt die overeenkomt met de opgegeven kwantumbewerking. De matrixwaarden bevinden zich in de rekenkundige basis en elke sublijst vertegenwoordigt een rij van de matrix.

In het volgende voorbeeld wordt dump_operation gebruikt om informatie weer te geven voor een 1-qubit- en 2-qubitsysteem.

  1. Druk in VS Code op Ctrl+Shift+P om het opdrachtenpalet te openen.

  2. Enter Create: New Jupyter Notebook en druk op Enter. Er wordt een nieuw Jupyter Notebook-tabblad geopend.

  3. Kopieer en voer in de eerste cel de volgende code uit:

    from qdk import qsharp
    from qsharp.utils import dump_operation
    
  4. Als u de matrixelementen van een poort met één qubit wilt weergeven, roept dump_operation u aan en geeft u 1 door voor het aantal qubits. Kopieer en voer bijvoorbeeld de volgende Python-code uit in een nieuwe codecel om de matrixelementen voor een identiteitspoort en een Hadamard-poort op te halen:

    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. U kunt ook de qsharp.eval functie aanroepen en vervolgens verwijzen naar de Q# bewerking in dump_operation om hetzelfde resultaat te krijgen. Maak bijvoorbeeld een nieuwe codecel en kopieer en voer de volgende Python-code uit om de matrixelementen voor een hadamard-poort met één qubit af te drukken:

    qsharp.eval("operation SingleH(qs : Qubit[]) : Unit { H(qs[0]) }")
    
    res = dump_operation("SingleH", 1)
    print("Single-qubit Hadamard gate:\n", res)
    
  6. Als u de matrixelementen van een poort met twee qubits wilt weergeven, roept dump_operation u aan en geeft u 2 door voor het aantal qubits. Kopieer en voer bijvoorbeeld de volgende Python-code uit in een nieuwe codecel om de matrixelementen op te halen voor een gecontroleerde Ry-bewerking waarbij de tweede qubit de target qubit is:

    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)
    

Zie dump_operation uit de QDK-voorbeelden voor meer voorbeelden van het testen en opsporen van fouten in uw code.

Uw kwantumcode testen

De QDK biedt verschillende Q# functies en bewerkingen die u kunt gebruiken om uw code te testen terwijl deze wordt uitgevoerd. U kunt ook eenheidstests schrijven voor Q# programma's.

De fail expressie

De fail expressie beëindigt uw programma onmiddellijk. Als u tests in uw code wilt opnemen, gebruikt u de fail expressies in voorwaardelijke instructies.

In het volgende voorbeeld wordt een fail instructie gebruikt om te testen of een qubitmatrix exact 3 qubits bevat. Het programma eindigt met een foutbericht wanneer de test niet doorkomt.

  1. Maak en sla in VS Code een nieuw .qs bestand op met de volgende code:

    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. Druk op Ctrl+F5 om het programma uit te voeren. Uw programma mislukt en de volgende uitvoer wordt weergegeven in de console voor foutopsporing:

    Error: program failed: The system should have 3 qubits, not 6.
    
  3. Bewerk de code van Qubit[6] naar Qubit[3], sla het bestand op en druk op Ctrl + F5 om het programma opnieuw uit te voeren. Het programma wordt uitgevoerd zonder een fout omdat de test is geslaagd.

De functie Fact

U kunt de Q#Fact functie ook uit de Std.Diagnostics naamruimte gebruiken om uw code te testen. De Fact functie gebruikt een Boole-expressie en een foutberichttekenreeks. Als de Boole-expressie waar is, wordt de test geslaagd en blijft het programma actief. Als de Boole-expressie onwaar is, beëindigt Fact het programma en wordt het foutbericht weergegeven.

Voer de volgende stappen uit om dezelfde matrixlengtetest uit te voeren in uw vorige code, met behulp van de Fact functie.

  1. Maak en sla in VS Code een nieuw .qs bestand op met de volgende code:

    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. Druk op Ctrl+F5 om het programma uit te voeren. De testvoorwaarde in Fact wordt niet doorgegeven en het foutbericht wordt weergegeven in de Console voor foutopsporing.

  3. Bewerk de code van Qubit[6] naar Qubit[3], sla het bestand op en druk op Ctrl + F5 om het programma opnieuw uit te voeren. De testvoorwaarde is geslaagd Fact en uw programma wordt uitgevoerd zonder fout.

Schrijf unit tests Q# met de @Test() annotatie

In Q# programma's kunt u de @Test() aantekening toepassen op een aanroepbare (functie of bewerking) om de aanroepbare functie of bewerking om te zetten in een eenheidstest. Deze eenhedentests worden weergegeven in het menu Testen in VS Code, zodat u kunt profiteren van deze VS Code-functie. U kunt een aanroepbare functie alleen omzetten in een eenheidstest wanneer de aanroepbare invoerparameters niet accepteert.

In het volgende voorbeeld wordt de testcode van de matrixlengte in een bewerking verpakt en wordt die bewerking omgezet in een eenheidstest:

  1. Maak en sla in VS Code een nieuw .qs bestand op met de volgende code:

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

    De annotatie @Test() op de regel vóór de TestCase definitie van de bewerking zorgt ervoor dat de bewerking wordt omgezet in een VS Code-eenheidstest. Er wordt een groene pijl weergegeven op de definitieregel van de bewerking.

  2. Kies de groene pijl om de testresultaten uit te voeren TestCase en te rapporteren.

  3. Als u wilt communiceren met uw unittests in de VS Code Test Explorer, kiest u het pictogram Testen in de hoofdzijbalk.

  4. Bewerk uw code van Qubit[3] en Qubit[6] voer de eenheidstest opnieuw uit om te zien hoe de testgegevens veranderen.

U kunt eenheidstests schrijven en uitvoeren Q# in VS Code zonder een invoerpuntbewerking in uw programma.

Notitie

Aanroepbare items uit de Std.Diagnostics naamruimte zijn niet compatibel met het genereren van QIR, dus neem alleen eenheidstests op in Q# code die u uitvoert op simulators. Als u QIR wilt genereren op basis van uw Q# code, neemt u geen eenheidstests op in uw code.

De CheckZero en CheckAllZero bewerkingen

De CheckZero en CheckAllZeroQ# bewerkingen controleren of de huidige status van een qubit- of qubitmatrix $\ket{0}$ is. De CheckZero bewerking neemt één qubit en retourneert true alleen wanneer de qubit de status $\ket{0}$ heeft. De CheckAllZero bewerkingen nemen een qubitmatrix en retourneert true alleen wanneer alle qubits in de matrix de status $\ket{0}$ hebben. Als u ze wilt gebruiken CheckZero en CheckAllZeroimporteert u deze uit de Std.Diagnostics naamruimte.

In het volgende voorbeeld worden beide bewerkingen gebruikt. De CheckZero tests dat de X bewerking de eerste qubit van de status $\ket{0}$ omdraait naar de status $\ket{1}$, en de CheckAllZero bewerking test dat beide qubits worden teruggezet naar de status $\ket{0}$.

Maak en sla in VS Code een nieuw .qs bestand op met de volgende code, voer vervolgens het programma uit en bekijk de uitvoer in de Console voor foutopsporing.

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