你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

调试和测试量子代码

与经典编程一样,能够检查量子程序是否按预期方式运行,并且能够诊断不正确的行为是至关重要的。 本文介绍 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 将完全结束计算,对应于导致程序停止的致命错误。

请考虑验证参数值的简单示例:

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

在这里, fail 表达式阻止程序继续运行无效数据。

事实 () 函数

可以使用 命名空间中的 函数Microsoft.Quantum.Diagnostics实现与上一示例Fact()相同的行为。 函数 Fact() 计算给定的经典条件,如果为 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 │         }
    ╰────

DumpMachine () 函数

DumpMachine() 是一个 Q# 函数,可用于将有关计算机当前状态 target 的信息转储到控制台并继续运行程序。

注意

随着 Azure Quantum Development Kit的发布,函数 DumpMachine() 现在对其输出使用 big-endian 排序。

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