Depuración y prueba del código cuántico

Al igual que con la programación clásica, es esencial poder comprobar que los programas cuánticos actúan según lo previsto y poder diagnosticar comportamientos incorrectos. En este artículo se describen las herramientas que ofrece Azure Quantum Development Kit para probar y depurar programas cuánticos.

Depuración del Q# programa

La extensión de Visual Studio Code azure Quantum Development Kit (QDK moderno) incluye un depurador para Q# programas. Puede establecer puntos de interrupción, recorrer el código y en cada función o operación, y realizar un seguimiento no solo de las variables locales, sino también del estado cuántico de los cúbits.

Nota

El depurador de VS Code solo funciona con Q# archivos (.qs) y no funciona con Q# celdas de un Jupyter Notebook. Para probar Jupyter Notebook celdas, consulte Prueba del código.

En el ejemplo siguiente se muestran las características básicas del depurador. Para obtener información completa sobre el uso de depuradores de VS Code, consulte Depuración.

En VS Code, cree y guarde un nuevo archivo .qs con el código siguiente:

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. Establezca un punto de interrupción en la línea H(qubit) haciendo clic a la izquierda del número de línea.
  2. Seleccione el icono del depurador para abrir el panel del depurador y seleccione Ejecutar y depurar. Los controles del depurador se muestran en la parte superior de la pantalla.
  3. Seleccione F5 para iniciar la depuración y continuar con el punto de interrupción. En el panel Variables del depurador, expanda la categoría Estado cuántico . Puede ver que el cúbit se ha inicializado en el estado |0> .
  4. Depurar paso a paso por instrucciones (F11) la H operación y el código fuente de la H operación se muestra. A medida que recorre la operación, tenga en cuenta que el valor cuántico cambia a medida que la H operación coloca el cúbit en superposición.
  5. A medida que supere (F10) la M operación, el valor cuántico se resuelve en |0> o |1> como resultado de la medida y se muestra el valor de la variable result clásica.
  6. A medida que avanza por la Reset operación, el cúbit se restablece a |0>.

Probar el código

Aunque el depurador de VS Code Q# no está disponible para Q# las celdas de un Jupyter Notebook, el QDK moderno proporciona algunas expresiones y funciones que pueden ayudar a solucionar problemas del código.

Expresión fail

La fail expresión finaliza el cálculo por completo, correspondiente a un error irrecuperable que detiene el programa.

Considere este ejemplo sencillo que valida un valor de parámetro:

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

Aquí, la fail expresión impide que el programa continúe ejecutó con datos no válidos.

Función Fact()

Puede implementar el mismo comportamiento que el ejemplo anterior mediante la Fact() función del Microsoft.Quantum.Diagnostics espacio de nombres . La Fact() función evalúa una condición clásica determinada y produce una excepción si es false.

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

Función DumpMachine()

DumpMachine() es una Q# función que permite volcar información sobre el estado actual de la target máquina en la consola y seguir ejecutando el programa.

Nota

Con el lanzamiento de Azure Quantum Development Kit, la DumpMachine() función ahora usa el orden big-endian para su salida.

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

dump_machine() (función)

dump_machine es una función de Python que devuelve el recuento de cúbits asignados actual y un diccionario de Python de amplitudes de estado dispersas que se pueden analizar. El uso de cualquiera de estas funciones en un Jupyter Notebook le permite recorrer paso a paso las operaciones de forma muy similar a un depurador. Con el programa de ejemplo anterior:

import qsharp
%%qsharp

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)