你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
量子编程语言简介 Q#
Q# 是一种高级 的开源 编程语言,由Microsoft开发,用于编写量子程序。 Q# 包含在 Quantum 开发工具包(QDK)中。 有关详细信息,请参阅 设置 Quantum 开发工具包。
作为量子编程语言,Q# 满足语言、编译器和运行时的以下要求:
- 硬件不可知: 量子算法中的量子比特不绑定到特定的量子硬件或布局。 Q# 编译器和运行时处理从程序量子比特到物理量子比特的映射,从而允许相同的代码在不同的量子处理器上运行。
- 量子和经典计算的集成:Q# 允许量子和经典计算的集成,这对于通用量子计算至关重要。
- 量子比特管理:Q# 提供用于管理量子比特的内置操作和功能,包括创建叠加状态、纠缠量子位和执行量子测量。
- 尊重物理规律:Q# 和量子算法必须遵循量子物理规则。 例如,不能直接复制或访问量子比特状态。Q#
有关 Q#起源的详细信息,请参阅博客文章 为什么我们需要 Q#?。
Q#程序的结构
开始编写 Q# 程序之前,请务必了解其结构和组件。 请考虑以下名为 叠加的 Q# 程序,它生成一个叠加状态:
namespace Superposition {
@EntryPoint()
operation MeasureOneQubit() : Result {
// Allocate a qubit. By default, it's in the 0 state.
use q = Qubit();
// Apply the Hadamard operation, H, to the state.
// It now has a 50% chance of being measured as 0 or 1.
H(q);
// Measure the qubit in the Z-basis.
let result = M(q);
// Reset the qubit before releasing it.
Reset(q);
// Return the result of the measurement.
return result;
}
}
根据注释(//
), Q# 程序首先分配量子比特,应用一个操作来将量子比特置于叠加状态,测量量子比特状态,重置量子比特,最后返回结果。
让我们将此 Q# 程序分解成其组件。
用户命名空间
Q# 程序可以选择从用户定义的 命名空间开始,例如:
namespace Superposition {
// Your code goes here.
}
命名空间可帮助你组织相关功能。 命名空间在 Q# 程序中是可选的,这意味着可以在不定义命名空间的情况下编写程序。
例如,示例的 叠加 程序也可以在没有命名空间的情况下编写为:
@EntryPoint()
operation MeasureOneQubit() : Result {
// Allocate a qubit. By default, it's in the 0 state.
use q = Qubit();
// Apply the Hadamard operation, H, to the state.
// It now has a 50% chance of being measured as 0 or 1.
H(q);
// Measure the qubit in the Z-basis.
let result = M(q);
// Reset the qubit before releasing it.
Reset(q);
// Return the result of the measurement.
return result;
}
注意
每个 Q# 程序只能有一个 namespace
。 如果未指定命名空间,则 Q# 编译器使用文件名作为命名空间。
入口点
每个 Q# 程序都必须有一个入口点,即程序的起点。 默认情况下, Q# 编译器会开始从 Main()
操作执行程序(如果可用),该操作可以位于程序中的任何位置。 (可选)可以使用 @EntryPoint()
特性将程序中的任何操作指定为执行点。
例如,在 叠加 程序中,MeasureOneQubit()
操作是程序的入口点,因为它在操作定义之前具有 @EntryPoint()
属性:
@EntryPoint()
operation MeasureOneQubit() : Result {
...
}
但是,也可以通过将 MeasureOneQubit()
操作重命名为 Main()
来编写程序而不编写 @EntryPoint()
属性,例如:
// The Q# compiler automatically detects the Main() operation as the entry point.
operation Main() : Result {
// Allocate a qubit. By default, it's in the 0 state.
use q = Qubit();
// Apply the Hadamard operation, H, to the state.
// It now has a 50% chance of being measured as 0 or 1.
H(q);
// Measure the qubit in the Z-basis.
let result = M(q);
// Reset the qubit before releasing it.
Reset(q);
// Return the result of the measurement.
return result;
}
类型
类型在任何编程语言中都至关重要,因为它们定义了程序可以使用的数据。 Q# 提供大多数语言共有的内置类型,包括 Int
、Double
、Bool
和 String
,以及定义范围、数组和元组的类型。
Q# 还提供特定于量子计算的类型。 例如,Result
类型表示量子比特度量的结果,可以有两个值:Zero
或 One
。
在 叠加 程序中,MeasureOneQubit()
操作返回 Result
类型,该类型对应于 M
操作的返回类型。 度量结果存储在使用语句定义的新变量中 let
:
// The operation definition returns a Result type.
operation MeasureOneQubit() : Result {
...
// Measure the qubit in the Z-basis, returning a Result type.
let result = M(q);
...
}
特定于量子类型的另一个示例是表示量子位的 Qubit
类型。
Q# 还允许定义自己的自定义类型。 有关详细信息,请参阅 类型声明。
分配量子位
在 Q#中,使用 use
关键字和 Qubit
类型分配量子比特。 量子比特始终以 $\ket{0}$ 状态分配。
例如,叠加 程序定义单个量子位并将其存储在变量 q
:
// Allocate a qubit.
use q = Qubit();
还可以分配多个量子比特并通过其索引访问每个量子比特:
use qubits = Qubit[2]; // Allocate two qubits.
H(qubits[0]); // Apply H to the first qubit.
X(qubits[1]); // Apply X to the second qubit.
有关详细信息,请参阅 Use 语句。
量子操作
在分配量子比特之后,你可以将其传递给操作和函数。 运算是 Q# 程序的基本构建基块。 Q#操作是量子子例程,或包含更改量子比特寄存器状态的量子运算的可调用例程。
若要定义 Q# 操作,请指定操作的名称、操作的输入和输出。 在 叠加 程序中,MeasureOneQubit()
操作不采用任何参数并返回 Result
类型:
operation MeasureOneQubit() : Result {
...
}
下面是一个基本示例,它不采用任何参数,且不期望返回值。 该值 Unit
等效于 NULL
其他语言:
operation SayHelloQ() : Unit {
Message("Hello quantum world!");
}
标准 Q# 库还提供可以在量子程序中使用的操作,如 Hadamard 操作, H
在 Superposition
程序中使用。 给定 Z 基量子位, H
将量子位置于均匀叠加中,其中它有 50% 的机会被测量为 Zero
或 One
。
测量量子比特
虽然有许多类型的量子测量, Q# 但侧重于单个量子比特的投影测量,也称为 Pauli 测量。
在 Q#中, Measure
操作度量指定 Pauli 基数中的一个或多个量子比特,可以是 PauliX
, PauliY
也可以 PauliZ
。 Measure
返回一Result
种Zero
或One
一种类型。
若要在计算基础 $\lbrace、\ket{0}\rbrace\ket{1}$ 中实现度量,也可以使用该M
运算来度量 Pauli Z 基中的量子位。 M
这相当于 Measure([PauliZ], [qubit])
.
例如,叠加 程序使用 M
操作:
// Measure the qubit in the Z-basis.
let result = M(q);
重置量子比特
在 Q#中,量子比特 在释放时必须 处于 $\ket{0}$ 状态,以避免量子硬件中的错误。 可以使用程序末尾的 Reset
操作将量子位重置为 $\ket{0}$ 状态。 无法重置量子位会导致运行时错误。
// Reset a qubit.
Reset(q);
标准库命名空间
标准 Q# 库具有内置命名空间,其中包含可在量子程序中使用的函数和操作。 例如, Microsoft.Quantum.Intrinsic
命名空间包含常用的操作和函数,例如 M
测量结果以及 Message
显示程序中的任意位置的用户消息。
若要调用函数或操作,可以指定完整的命名空间或使用 import
语句,使该命名空间的所有函数和操作都可用,并使代码更具可读性。 以下示例调用相同的操作:
Microsoft.Quantum.Intrinsic.Message("Hello quantum world!");
// imports all functions and operations from the Microsoft.Quantum.Intrinsic namespace.
import Microsoft.Quantum.Intrinsic.*;
Message("Hello quantum world!");
// imports just the `Message` function from the Microsoft.Quantum.Intrinsic namespace.
import Microsoft.Quantum.Intrinsic.Message;
Message("Hello quantum world!");
// namespaces in the standard library may be imported using `Std` instead of `Microsoft.Quantum`.
import Std.Intrinsic.*;
Message("Hello quantum world!");
注意
叠加 程序没有任何具有完整命名空间的 import
语句或调用。 这是因为 Q# 开发环境会自动加载两个命名空间: Microsoft.Quantum.Core
以及 Microsoft.Quantum.Intrinsic
包含常用函数和操作的命名空间。
通过使用 MResetZ
操作来优化叠加程序,您可以利用 Microsoft.Quantum.Measurement
命名空间。 MResetZ
将度量和重置操作合并为一个步骤,如以下示例所示:
// Import the namespace for the MResetZ operation.
import Microsoft.Quantum.Measurement.*;
@EntryPoint()
operation MeasureOneQubit() : Result {
// Allocate a qubit. By default, it's in the 0 state.
use q = Qubit();
// Apply the Hadamard operation, H, to the state.
// It now has a 50% chance of being measured as 0 or 1.
H(q);
// Measure and reset the qubit, and then return the result value.
return MResetZ(q);
}
了解如何使用 Q# 和 Azure Quantum 开发量子程序
Q# 和 Azure Quantum 是开发和运行量子程序的强大组合。 借助 Q# Azure Quantum,可以编写量子程序、模拟其行为、估算资源要求,并在实际量子硬件上运行它们。 通过这种集成,可以探索量子计算的潜力,并为复杂问题开发创新解决方案。 无论你是初学者还是经验丰富的量子开发人员, Q# Azure Quantum 都提供解锁量子计算所需的工具和资源。
下图显示了使用和 Azure Quantum 开发 Q# 量子程序时通过的阶段。 你的程序从开发环境开始,最后将作业提交到真正的量子硬件。
让我们分解关系图中的步骤。
选择开发环境
在首选的开发环境中运行量子程序。 可以使用 Azure Quantum 网站中的联机代码编辑器、Azure 门户中 Azure Quantum 工作区中的托管 Jupyter Notebook 或 Visual Studio Code 的本地开发环境。 有关详细信息,请参阅 运行 Q# 程序的不同方法。
编写量子程序
可以使用量子开发工具包(QDK)编写 Q# 量子程序。 若要开始,请参阅 快速入门:创建第一个 Q# 程序。
Q#此外,QDK 还提供对量子计算(如 Qiskit 和 Cirq)其他语言的支持。
与 Python 集成
可以在各种 IDE 中单独使用 Q# 或与 Python 一起使用。 例如,可以将 Q# 项目与 Python 主机程序配合使用来调用 Q# 操作,或在 Jupyter Notebooks 中将 Q# 与 Python 集成。 如需更多信息,请参阅Q# 和 Python 的集成。
%%qsharp 命令
默认情况下, Q# Jupyter Notebook 中的程序使用 ipykernel
Python 包。 若要将代码添加到 Q# 笔记本单元,请使用 %%qsharp
通过 Python 包启用 qsharp
的命令,后跟 Q# 代码。
使用 %%qsharp
时,请记住以下几点:
- 必须首先运行
import qsharp
才能启用%%qsharp
。 %%qsharp
范围到笔记本单元格的显示范围,并将单元格类型从 Python 更改为 Q#。- 不能在或之后
%%qsharp
放置 Python 语句。 - Q# 以下
%%qsharp
代码必须遵循 Q# 语法。 例如,使用//
而不是#
表示注释和;
结束代码行。
估计资源
在实际量子硬件上运行之前,需要确定程序是否可以在现有硬件上运行,以及它消耗的资源数量。
Azure Quantum 资源估算器允许你评估体系结构决策、比较量子比特技术并确定执行给定量子算法所需的资源。 可以从预定义的容错协议中进行选择,并指定基础物理量子比特模型的假设。
有关详细信息,请参阅 “运行第一个资源估算”。
注意
Azure Quantum 资源估算器是免费的,不需要 Azure 帐户。
在模拟中运行程序
编译并运行量子程序时,QDK 会创建量子模拟器的实例,并将代码传递给 Q# 它。 该模拟器使用 Q# 代码创建量子比特(量子粒子的模拟)并应用转换来修改其状态。 然后将模拟器中的量子操作结果返回到程序。 在模拟器中隔离 Q# 代码可确保算法遵循量子物理学定律,还确保这些算法可在量子计算机上正确运行。
将程序提交到真正的量子硬件
可以将 Q# 程序提交到 Azure Quantum,以在真实量子硬件上运行。 还可以运行和提交使用 Qiskit 和 Cirq 语言编写的量子线路。 在 Azure Quantum 中运行量子程序时,创建并运行 作业。 有关详细信息,请参阅 如何将 Q# 程序提交到 Azure Quantum。
xref:microsoft.quantum.work-with-jobs
Azure Quantum 提供当今行业领导者提供的一些最引人入胜且最多样化的量子硬件。 有关受支持的硬件提供程序的当前列表,请参阅量子计算提供程序。
注意
若要将作业提交到 Azure Quantum 提供程序,需要一个 Azure 帐户和量子工作区。 如果没有量子工作区,请参阅 “创建 Azure Quantum 工作区”。
提交作业后,Azure Quantum 将管理作业生命周期,包括作业计划、执行和监视。 可以在 Azure Quantum 门户中跟踪作业的状态并查看结果。 有关详细信息,请参阅处理 Azure Quantum 作业。