Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Las pruebas y la depuración son tan importantes en la programación cuántica como en la programación clásica. En este artículo se describe cómo depurar y probar los programas cuánticos con Azure Quantum Development Kit (QDK) en Visual Studio Code (VS Code) y Jupyter Notebook.
Depura tu código cuántico
El QDK proporciona varias herramientas para depurar el código. Si usted escribe Q# o programas OpenQASM en VS Code, entonces puede usar el depurador de VS Code para establecer puntos de interrupción en sus programas y analizar su código. El QDK también proporciona un conjunto de funciones de volcado de memoria que puede usar para obtener información en distintos puntos del programa.
Uso del depurador de VS Code
Con la extensión QDK en VS Code, puede usar el depurador para recorrer el código y en cada función o operación, realizar un seguimiento de los valores de las variables locales y seguir los estados cuánticos de los cúbits.
En el ejemplo siguiente se muestra cómo usar el depurador con un programa Q#. Para obtener información completa sobre los depuradores de VS Code, consulte Depuración en el sitio web de VS Code.
En VS Code, cree y guarde un nuevo
.qsarchivo con el código siguiente:import Std.Arrays.*; import Std.Convert.*; operation Main() : Result { use qubit = Qubit(); H(qubit); let result = M(qubit); Reset(qubit); return result; }En la línea 6,
H(qubit), haga clic a la izquierda del número de línea para establecer un punto de interrupción. Aparece un círculo rojo.En la barra del lado principal, elija el icono del depurador para abrir el panel del depurador y, a continuación, elija Ejecutar y depurar. Aparece la barra de control del depurador.
Presione F5 para iniciar el depurador y continuar hasta el punto de interrupción. En el menú Variables del panel del depurador, expanda la lista desplegable Estado cuántico para ver que el cúbit se ha inicializado en el estado $\ket{0}$.
Presione F11 para entrar en la
Hoperación. Aparece el código fuente de laHoperación. Observe que el estado cuántico cambia a una superposición al recorrer laHoperación.Presione F10 para recorrer paso a paso la
Moperación. Observe que el estado cuántico se resuelve en $\ket{0}$ o $\ket{1}$ después de la medición. Laresultvariable también aparece en Variables locales.Presione F10 de nuevo para pasar por encima de la
Resetoperación. Observe que el estado cuántico se restablece a $\ket{0}$.
Cuando haya terminado de explorar el depurador, presione *Ctrl + F5 para salir del depurador.
Nota:
El depurador de VS Code solo funciona con Q# archivos (.qs) y OpenQASM (.qasm). No puede usar el depurador de VS Code en Q# celdas de Jupyter Notebook.
Cómo depurar con el uso de funciones de volcado de QDK
El QDK proporciona varias Q# funciones de Python que vuelcan información sobre el estado actual de tu programa cuando llamas a estas funciones. Use información de estas funciones de volcado de memoria para comprobar si el programa se comporta según lo previsto.
La Q#DumpMachine función
DumpMachine es una Q# función que permite volcar información sobre el estado actual del sistema de cúbits en la consola a medida que se ejecuta el programa.
DumpMachine no detiene ni interrumpe el programa durante el tiempo de ejecución.
En el siguiente ejemplo se llama a DumpMachine en dos puntos de un programa Q# y se explora la salida.
En VS Code, cree y guarde un nuevo
.qsarchivo con el código siguiente: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); }Presione Ctrl + Mayús + Y para abrir la consola de depuración.
Presione Ctrl + F5 para ejecutar el programa. La siguiente salida de
DumpMachineaparece en la Consola de Depuración: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
La salida de DumpMachine muestra cómo cambia el estado de los sistemas de cúbits después de cada conjunto de puertas.
Nota:
La salida de DumpMachine usa la ordenación big-endian.
La función de Python dump_machine
La dump_machine función es una función del paquete de qsharp Python. Esta función devuelve el recuento de cúbits asignado actual y un diccionario que contiene las amplitudes de estado dispersas del sistema de cúbits.
En el ejemplo siguiente se ejecuta el mismo programa que el ejemplo anterior DumpMachine , pero en un cuaderno de Jupyter Notebook en lugar de un .qs archivo.
En VS Code, presione Ctrl + Mayús + P para abrir la paleta de comandos.
Escriba Create: New Jupyter Notebook (Crear: Nuevo cuaderno de Jupyter Notebook ) y presione Entrar. Se abre una nueva pestaña de Jupyter Notebook.
En la primera celda, copie y ejecute el código siguiente:
from qdk import qsharpCree una nueva celda de código y, a continuación, copie y ejecute el código siguiente Q# :
%%qsharp use qubits = Qubit[2]; X(qubits[0]); H(qubits[1]);Cree una celda de código. Copie y ejecute el siguiente código de Python para ver el estado del cúbit en este punto del programa:
dump = qsharp.dump_machine() dumpLa
dump_machinefunción muestra la siguiente salida:Basis State (|𝜓₁…𝜓ₙ⟩) Amplitude Measurement Probability Phase |10⟩ 0.7071+0.0000𝑖 50.0000% ↑ 0.0000 |11⟩ 0.7071+0.0000𝑖 50.0000% ↑ 0.0000Cree una nueva celda de código y, a continuación, copie y ejecute el código siguiente Q# :
%%qsharp R1Frac(1, 2, qubits[0]); R1Frac(1, 3, qubits[1]);Cree una celda de código. Copie y ejecute el siguiente código de Python para ver el estado del cúbit en este punto del programa:
dump = qsharp.dump_machine() dumpLa
dump_machinefunción muestra la siguiente salida:Basis State (|𝜓₁…𝜓ₙ⟩) Amplitude Measurement Probability Phase |10⟩ 0.5000+0.5000𝑖 50.0000% ↗ 0.7854 |11⟩ 0.2706+0.6533𝑖 50.0000% ↗ 1.1781Para imprimir una versión abreviada de la
dump_machinesalida, cree una nueva celda y ejecute el siguiente código de Python:print(dump)Para obtener el número total de cúbits en el sistema, cree una nueva celda de código y ejecute el siguiente código de Python:
dump.qubit_countPuede acceder a las amplitudes de los estados de cúbits individuales que tienen amplitud distinta de cero. Por ejemplo, cree una nueva celda de código y ejecute el siguiente código de Python para obtener las amplitudes individuales de los estados $\ket{10}$ y $\ket{11}$:
print(dump[2]) print(dump[3])
La función dump_operation
La dump_operation función es una función del paquete de qsharp.utils Python. Esta función toma dos entradas: una operación o definición de operación como una cadena y el número de cúbits que se usan en la operación. La salida de dump_operation es una lista anidada que representa la matriz cuadrada de números complejos que corresponde a la operación cuántica dada. Los valores de la matriz se encuentran en la base computacional y cada sublista representa una fila de la matriz.
En el ejemplo siguiente se usa dump_operation para mostrar información de un sistema de 1 cúbit y 2 cúbits.
En VS Code, presione Ctrl + Mayús + P para abrir la paleta de comandos.
Escriba Create: New Jupyter Notebook (Crear: Nuevo cuaderno de Jupyter Notebook ) y presione Entrar. Se abre una nueva pestaña de Jupyter Notebook.
En la primera celda, copie y ejecute el código siguiente:
from qdk import qsharp from qsharp.utils import dump_operationPara mostrar los elementos de matriz de una puerta de un qubit único, llame a
dump_operationy pase 1 para el número de qubits. Por ejemplo, copie y ejecute el siguiente código de Python en una nueva celda de código para obtener los elementos de matriz de una puerta de identidad y una puerta hadamard: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)También puede llamar a la función
qsharp.evaly hacer referencia a la operación Q# endump_operationpara obtener el mismo resultado. Por ejemplo, cree una nueva celda de código y, a continuación, copie y ejecute el siguiente código de Python para imprimir los elementos de matriz de una puerta Hadamard de un solo cúbit:qsharp.eval("operation SingleH(qs : Qubit[]) : Unit { H(qs[0]) }") res = dump_operation("SingleH", 1) print("Single-qubit Hadamard gate:\n", res)Para mostrar los elementos de matriz de una puerta de dos cúbits, llame a
dump_operationy pase 2 como el número de cúbits. Por ejemplo, copie y ejecute el siguiente código de Python en una nueva celda de código para obtener los elementos de matriz de una operación Ry controlada donde el segundo cúbit es el target cúbit: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)
Para obtener más ejemplos de cómo probar y depurar el código con dump_operation, consulte Operaciones de prueba de los ejemplos de QDK.
Prueba del código cuántico
El QDK proporciona varias Q# funciones y operaciones que puede usar para probar el código a medida que se ejecuta. También puede escribir pruebas unitarias para Q# programas.
La expresión fail
La fail expresión finaliza inmediatamente el programa. Para incorporar pruebas en el código, use las fail expresiones dentro de instrucciones condicionales.
En el ejemplo siguiente se usa una fail instrucción para probar que una matriz de cúbits contiene exactamente 3 cúbits. El programa finaliza con un mensaje de error cuando no se supera la prueba.
En VS Code, cree y guarde un nuevo
.qsarchivo con el código siguiente: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}."; } }Presione Ctrl + F5 para ejecutar el programa. Se produce un error en el programa y aparece la siguiente salida en la consola de depuración:
Error: program failed: The system should have 3 qubits, not 6.Edite el código de
Qubit[6]aQubit[3], guarde el archivo y presione Ctrl + F5 para volver a ejecutar el programa. El programa se ejecuta sin error porque la prueba se supera.
La función Fact
También puede usar la función Q#Fact del espacio de nombres Std.Diagnostics para probar el código. La Fact función toma una expresión booleana y una cadena de mensaje de error. Si la expresión booleana es true, la prueba pasa y el programa continúa ejecutándose. Si la expresión booleana es false, Fact finaliza el programa y muestra el mensaje de error.
Para realizar la misma prueba de longitud de matriz en el código anterior, pero con la Fact función, siga estos pasos:
En VS Code, cree y guarde un nuevo
.qsarchivo con el código siguiente: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}.") }Presione Ctrl + F5 para ejecutar el programa. La condición de prueba en
Factno se supera y el mensaje de error aparece en la consola de depuración.Edite el código de
Qubit[6]aQubit[3], guarde el archivo y presione Ctrl + F5 para volver a ejecutar el programa. La condición de prueba enFactsupera y el programa se ejecuta sin un error.
Escribe Q# pruebas unitarias con la anotación @Test()
En Q# los programas, puede aplicar la @Test() anotación a una función o operación invocable para convertir el invocable en una prueba unitaria. Estas pruebas de unidades aparecen en el menú Pruebas de VS Code para que pueda aprovechar esta característica de VS Code. Puede convertir un invocable en una prueba unitaria solo cuando el invocable no toma parámetros de entrada.
En el ejemplo siguiente, se ajusta el código de prueba para la longitud de la matriz en una operación y se convierte esa operación en una prueba unitaria.
En VS Code, cree y guarde un nuevo
.qsarchivo con el código siguiente: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}."); }La
@Test()anotación en la línea antes de la definición de laTestCaseoperación convierte la operación en un test unitario de VS Code. Aparece una flecha verde en la línea de definición de la operación.Elija la flecha verde para ejecutar
TestCasey notificar los resultados de la prueba.Para interactuar con tus pruebas unitarias en el Explorador de Pruebas de VS Code, elige el icono Testing en la barra lateral principal.
Edite el código de
Qubit[3]aQubit[6]y vuelva a ejecutar la prueba unitaria para ver cómo cambian los resultados de la prueba.
Puede escribir y ejecutar Q# pruebas unitarias en VS Code sin necesidad de una operación de punto de entrada en su programa.
Nota:
Los elementos invocables del espacio de nombres Std.Diagnostics no son compatibles con la generación de QIR, por lo que solo deberías incluir pruebas unitarias en el código Q# que ejecutas en simuladores. Si desea generar QIR a partir del Q# código, no incluya pruebas unitarias en el código.
Las CheckZero y CheckAllZero operaciones
Las operaciones CheckZero y CheckAllZeroQ# comprueban si el estado actual de un cúbit o matriz de cúbits es $\ket{0}$. La CheckZero operación toma un solo cúbit y solo devuelve true cuando el cúbit está en estado $\ket{0}$. Las CheckAllZero operaciones toman una matriz de cúbits y solo devuelven true cuando todos los cúbits de la matriz están en estado $\ket{0}$. Para usar CheckZero y CheckAllZero, impórtelos desde el Std.Diagnostics espacio de nombres .
En el ejemplo siguiente se usan ambas operaciones. La operación CheckZero verifica que la operación X invierte el primer cúbit del estado $\ket{0}$ al estado $\ket{1}$, y la operación CheckAllZero verifica que ambos cúbits se restablecen al estado $\ket{0}$.
En VS Code, cree y guarde un nuevo .qs archivo con el código siguiente, ejecute el programa y examine la salida en la consola de depuració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");
}
}