Отладка и тестирование квантового кода

Возможность проверить, что квантовая программа работает должным образом, и диагностировать ее в случае некорректного поведения очень важна, как и в классическом программировании. В этой статье рассматриваются средства, предлагаемые Azure Quantum Development Kit для тестирования и отладки квантовых программ.

Отладка Q# программы

Расширение Azure Quantum Development Kit (Современный QDK) Visual Studio Code включает отладчик для Q# программ. Вы можете задавать точки останова, пошагово выполнять код и переходить к каждой функции или каждой операции, а также отслеживать не только локальные переменные, но и квантовое состояние кубитов.

Примечание

Отладчик VS Code работает только с файлами Q# (QS) и не работает с Q# ячейками в Jupyter Notebook. Сведения о тестировании Jupyter Notebook ячеек см. в разделе Тестирование кода.

В следующем примере показаны основные функции отладчика. Полные сведения об использовании отладчиков VS Code см. в разделе Отладка.

В VS Code создайте и сохраните новый QS-файл со следующим кодом:

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. Установите точку останова в строке H(qubit) , щелкнув слева от номера строки.
  2. Щелкните значок отладчика, чтобы открыть панель отладчика, и выберите Запуск и отладка. Элементы управления отладчика отображаются в верхней части экрана.
  3. Нажмите клавишу F5, чтобы начать отладку и перейти к точке останова. В области Переменные отладчика разверните категорию Квантовое состояние . Вы видите, что кубит инициализирован в состоянии |0> .
  4. Шаг в (F11) отображается H операция и исходный H код для операции. При пошаговом выполнении операции обратите внимание, что квантовое значение изменяется, H так как операция помещает кубит в суперпозицию.
  5. При пошаговом выполнении операции (F10) M квантовое значение разрешается в |0> или |1> в результате измерения, и отображается значение классической переменной result .
  6. При пошаговом выполнении Reset операции кубит сбрасывается до |0>.

Тестирование кода

Хотя отладчик VS Code Q# недоступен для Q# ячеек в Jupyter Notebook, современный QDK предоставляет некоторые выражения и функции, которые могут помочь в устранении неполадок в коде.

Выражение fail

Выражение fail полностью завершает вычисление, что соответствует неустранимой ошибке, которая останавливает программу.

Рассмотрим этот простой пример, который проверяет значение параметра:

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

fail Здесь выражение не позволяет продолжить выполнение программы с недопустимыми данными.

Функция Fact()

Вы можете реализовать то же поведение, что и в предыдущем примере, используя функцию Fact() из Microsoft.Quantum.Diagnostics пространства имен. Функция Fact() вычисляет заданное классическое условие и создает исключение, если оно имеет значение 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 │         }
    ╰────

Функция DumpMachine()

DumpMachine()Q#— это функция, которая позволяет отправлять сведения о текущем состоянии target компьютера в консоль и продолжать запускать программу.

Примечание

С выпуском Azure Quantum Development KitDumpMachine() функция теперь использует упорядочение по большому эндиану для выходных данных.

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()

dump_machine — это функция Python, которая возвращает текущее выделенное число кубитов и словарь Python разреженных амплитуд состояния, которые можно проанализировать. Использование любой из этих функций в Jupyter Notebook позволяет выполнять операции так же, как отладчик. С помощью предыдущего примера программы:

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)