你会学到什么
- 量子算法如何执行
- 量子模拟器包含在这个版本中
- 如何为您的量子算法编写C#驱动程序
Quantum开发工具包执行模型
在编写量子程序时 ,我们通过将QuantumSimulator
对象传递给算法类的Run
方法来执行量子算法。 QuantumSimulator
类通过完全模拟量子状态向量来执行量子算法,它非常适合运行和测试Teleport
。 有关量子状态矢量的更多信息,请参阅概念指南 。
其他目标机器可用于运行量子算法。 该机器负责为算法提供量子基元的实现。 这包括诸如H,CNOT和Measure之类的基本操作,以及量子位管理和跟踪。 不同类别的量子机器代表相同量子算法的不同执行模式。
每种类型的量子机可以提供这些基元的不同实现。 例如,开发套件中包含的量子计算机轨迹模拟器根本不做任何模拟。 而是跟踪算法的门限,量子位和其他资源使用情况。
量子机器
未来,我们将定义额外的量子机器类来支持其他类型的模拟并支持拓扑量子计算机上的执行。 在改变底层机器实现的同时允许算法保持不变,可以很容易地在仿真中测试和调试算法,然后在真实硬件上运行它,并确信该算法没有改变。
本发行版中包含的内容
量子开发工具包的这个版本包含两个量子机器类。 两者都在Microsoft.Quantum.Simulation.Simulators
命名空间中定义。
- 一个完整的状态矢量模拟器 ,
QuantumSimulator
类。 - 基于跟踪的资源评估器 ,即
QCTraceSimulator
类。
写一个经典驱动程序
在编写量子程序时 ,我们为我们的传送算法编写了一个简单的C#驱动程序。 AC#驱动程序有四个主要目的:
- 构建目标机器
- 计算量子算法所需的任何参数
- 使用模拟器运行量子算法
- 处理操作的结果
这里我们将更详细地讨论每一步。
注意
在经典驱动程序中执行预处理和后处理通常比在Q#代码中更好。 将来,当Q#代码运行在冷古典硬件上并控制量子设备的详细过程时,纯经典计算的开销和成本将远低于冷计算的开销和成本。
当然,影响量子计算的计算和分析应该在Q#中完成。 例如,基于状态测量的特性动态调整参数演化速率的自适应绝热算法应该在Q#中进行分析和调整。
构建目标机器
Quantum机器是普通.NET类的实例,因此它们是通过调用它们的构造函数创建的,就像任何.NET类一样。 一些模拟器(包括QuantumSimulator
)实现.NET IDisposable
接口,因此应该用C# using
语句包装。
注意
一次只能使用QuantumSimulator
类的一个实例。 该仿真器经过高度优化,可以并行化计算,因此不允许多个计算。
计算算法的参数
在我们的Teleport
例子中,我们计算了一些相对人为的参数传递给量子算法。 然而,更典型的是,量子算法需要大量的数据,并且从经典的驱动程序中提供它是最容易的。
例如,在进行化学模拟时,量子算法需要大量的分子轨道相互作用积分表。 通常,这些是从运行算法时提供的文件读入的。 由于Q#没有访问文件系统的机制,因此这类数据最好由经典驱动程序收集,然后传递给量子算法的Run
方法。
经典驾驶员扮演关键角色的另一个案例是变分方法。 在这类算法中,基于一些经典参数准备量子状态,并且该状态用于计算一些感兴趣的值。 根据某种类型的爬山或机器学习算法调整参数,并再次运行量子算法。 对于这样的算法,爬山算法本身最好实现为经典驱动程序调用的纯经典函数; 然后将爬山的结果传递给量子算法的下一次执行。
运行量子算法
这部分通常非常简单。 每个Q#操作都被编译成一个提供静态Run
方法的类。 这个方法的参数由操作本身的扁平参数元组给出,另外还有一个额外的第一个参数,它是要执行的模拟器。 对于类型为(String, (Double, Double))
的元组,它的扁平对象的类型是(String, Double, Double)
。
将参数传递给Run
方法时有一些细微之处:
- 数组必须包装在
Microsoft.Quantum.Simulation.Core.QArray<T>
对象中。 一个QArray
类具有一个构造函数,它可以接受适当对象的任何有序集合(IEnumerable<T>
)。 - Q#中的空元组
()
在Q#中由QVoid.Instance
表示。 - 非空元组表示为.NET
ValueType
实例。 - Q#用户定义类型作为其基本类型传递。
- 要将操作或函数传递给
Run
方法,必须创建操作或函数类的实例,将模拟器对象传递给构造函数。
处理结果
量子算法的结果从Run
方法返回。 Run
方法异步执行,因此它返回一个Task<T>
。 有多种方式可以获得实际操作的结果。 最简单的方法是使用Task
的Result
属性 :
var res = BellTest.Run(sim, 1000, initial).Result;
但其他技术,如使用Wait
方法或C# await
关键字也可以。
与参数一样,Q#元组表示为ValueTuple
实例,而Q#数组表示为QArray
实例。 用户定义的类型将作为其基本类型返回。 空元组()
作为QVoid
类的一个实例返回。
许多量子算法需要大量的后处理来获得有用的答案。 例如,Shor算法的量子部分仅仅是计算的开始,它可以找到一个数的因子。
在大多数情况下,在经典驱动程序中进行这种后处理是最简单也是最容易的。 只有传统的驱动程序才能将结果报告给用户或将其写入磁盘。 经典的驱动程序可以访问分析库和Q#中未公开的其他数学函数。
故障
在执行操作期间达到Q# fail
语句时,会引发ExecutionFailException
。
由于在Run
方法中使用了System.Task
,因此fail
语句引发的异常将被封装到System.AggregateException
。 要找到失败的实际原因,您需要迭代AggregateException
InnerExceptions
,例如:
try
{
using(var sim = new QuantumSimulator())
{
/// call your operations here...
}
}
catch (AggregateException e)
{
// Unwrap AggregateException to get the message from Q# fail statement.
// Go through all inner exceptions.
foreach (Exception inner in e.InnerExceptions)
{
// If the exception of type ExecutionFailException
if (inner is ExecutionFailException failException)
{
// Print the message it contains
Console.WriteLine($" {failException.Message}");
}
}
}wrap AggregateException to get the message from Q# fail statement. // Go through all inner exceptions. foreach (Exception inner in e.InnerExceptions) { // If the exception of type ExecutionFailException if (inner is ExecutionFailException failException) { // Print the message it contains Console.WriteLine($" {failException.Message}"); } } }
其他经典语言
虽然我们提供的样本是用C#或F#编写的,但编写经典驱动程序所需的全部内容都是对.NET的支持。 如果你想在Visual Basic中编写驱动程序,它应该工作得很好。