Debug e test del codice quantistico

Come per la programmazione classica, è essenziale essere in grado di verificare che i programmi quantistici agiscano come previsto e di diagnosticare un comportamento non corretto. Questo articolo illustra gli strumenti offerti da Azure Quantum Development Kit per il test e il debug dei programmi quantistici.

Debug del Q# programma

L'estensione Azure Quantum Development Kit (QDK moderno) di Visual Studio Code include un debugger per Q# i programmi. È possibile impostare punti di interruzione, eseguire il codice e in ogni funzione o operazione e tenere traccia non solo delle variabili locali, ma anche dello stato quantistico dei qubit.

Nota

Il debugger di VS Code funziona solo con Q# i file (.qs) e non funziona con Q# le celle in un Jupyter Notebook. Per testare le celle Jupyter Notebook, vedere Test del codice.

Nell'esempio seguente vengono illustrate le funzionalità di base del debugger. Per informazioni complete sull'uso dei debugger di VS Code, vedere Debug.

In VS Code creare e salvare un nuovo file con estensione qs con il codice seguente:

namespace Sample {

    open Microsoft.Quantum.Arrays;
    open Microsoft.Quantum.Convert;

    @EntryPoint()
    operation Superposition() : Result {

        use qubit = Qubit();
        H(qubit);
        let result = M(qubit);
        Reset(qubit);
        return result;
    }
}
  1. Impostare un punto di interruzione sulla riga facendo clic a sinistra del numero di riga H(qubit) .
  2. Selezionare l'icona del debugger per aprire il riquadro del debugger e selezionare Esegui e Debug. I controlli del debugger vengono visualizzati nella parte superiore della schermata.
  3. Selezionare F5 per avviare il debug e continuare con il punto di interruzione. Nel riquadro Variabili del debugger espandere la categoria Quantum State . È possibile notare che il qubit è stato inizializzato nello stato |0> .
  4. Eseguire l'operazione H (F11) e il codice sorgente per la visualizzazione dell'operazione H . Durante il passaggio dell'operazione, notare che il valore quantistico cambia quando l'operazione H inserisce il qubit in sovrapposizione.
  5. Durante il passaggio (F10) l'operazione M , il valore quantistico viene risolto in |0> o |1> come risultato della misurazione e viene visualizzato il valore della variabile result classica.
  6. Durante il passaggio dell'operazione Reset , il qubit viene reimpostato su |0>.

Test del codice

Anche se il debugger di VS Code Q# non è disponibile per Q# le celle in un Jupyter Notebook, il QDK moderno fornisce alcune espressioni e funzioni che consentono di risolvere i problemi del codice.

Espressione fail

L'espressione fail termina interamente il calcolo, corrispondente a un errore irreversibile che arresta il programma.

Si consideri questo semplice esempio che convalida un valore di parametro:

import qsharp 
# import qsharp package to acccess the %%qsharp magic command
%%qsharp 
// use the %%qsharp magic command to change the cell type from Python to Q#

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 │     }   
   ╰────

In questo caso, l'espressione fail impedisce al programma di continuare l'esecuzione con dati non validi.

Funzione Fact()

È possibile implementare lo stesso comportamento dell'esempio precedente usando la Fact() funzione dallo Microsoft.Quantum.Diagnostics spazio dei nomi. La Fact() funzione valuta una determinata condizione classica e genera un'eccezione se è false.

import qsharp 
# import qsharp package to acccess the %%qsharp magic command
%%qsharp
// use the %%qsharp magic command to change the cell type from Python to Q#

    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 │         }
    ╰────

Funzione DumpMachine()

DumpMachine() è una Q# funzione che consente di eseguire il dump delle informazioni sullo stato corrente del target computer nella console e continuare a eseguire il programma.

Nota

Con la versione di Azure Quantum Development Kit, la DumpMachine() funzione ora usa l'ordinamento big-endian per l'output.

import qsharp
%%qsharp

open 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
|10⟩	−0.7071+0.0000𝑖	 50.0000%	↑	-3.1416

Basis State
(|𝜓ₙ…𝜓₁⟩)	Amplitude	Measurement Probability	Phase
|00⟩	0.5879−0.3928𝑖	 50.0000%	↑	-0.5890
|10⟩	−0.6935+0.1379𝑖	 50.0000%	↑	2.9452

funzione dump_machine()

dump_machine è una funzione Python che restituisce il conteggio qubit allocato corrente e un dizionario python di ampiezza dello stato sparse che è possibile analizzare. L'uso di una di queste funzioni in un Jupyter Notebook consente di eseguire operazioni molto simili a un debugger. Uso del programma di esempio precedente:

import qsharp 
# import qsharp package to acccess the %%qsharp magic command
%%qsharp
// use the %%qsharp magic command to change the cell type from Python to Q#

use qubits = Qubit[2];
X(qubits[0]);
H(qubits[1]);
dump = qsharp.dump_machine()
dump

Basis State
(|𝜓ₙ…𝜓₁⟩)	Amplitude	Measurement Probability	Phase
|11⟩	0.7071+0.0000𝑖	 50.0000%	↑	0.0000
|01⟩	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
|11⟩	0.5879+0.3928𝑖	 50.0000%	↑	0.5890
|01⟩	0.6935+0.1379𝑖	 50.0000%	↑	0.1963
# you can print an abbreviated version of the values
print(dump)
STATE:
|11⟩: 0.5879+0.3928𝑖
|01⟩: 0.6935+0.1379𝑖
# you can access the current qubit count
dump.qubit_count
2
# you can access individal states by their index
dump[1]
(0.6935199226610738, 0.1379496896414715)
dump[3]
(0.5879378012096794, 0.3928474791935511)