QuBranch与QuTrunk初试
1.QuBranch与QuTrunk项目简介
量子编程也称为量子计算,是汇编指令序列在电脑中已执行的程序。量子编程,首先由编译器将高级语言编写的量子程序转化为指令集语言,然后在真实的量子计算机或模拟器上运行,最终查询量子程序运行结果。QuBranch与QuTrunk是由启科量子发起的量子编程框架项目。启科量子软件产品框架包括量子基础架构层、量子混合云基础架构层、量子编程框架层、量子应用层,其中量子编程框架层包括QuBranch、QuTrunk、QuFlower等,QuTrunk为量子编程工作提供基础的架构体系,QuBranch主要为用户提供便捷高效的量子编程开发环境,所有支持Python编程的IDE均可安装使用QuTrunk。
启科量子软件产品的技术先进性主要体现于量子软件产品体系架构在量子软件产品布局的完整性、产品的独立性和可扩展性。整个量子软件产品体系主要采用分层架构,既可至上而下解耦为独立产品,又可以随意搭配组合为新的产品体系对外使用,QuBranch+QuTrunk+QuBOX、QuBranch+QuTrunk+QuRoot等。其中,软件产品体系的每一层接口预留充足、全面,可为后续软件产品的升级迭代预留充足的空间。以下将对QuBranch和QuTrunk等内容进行介绍。
1.1QuBranch项目
项目介绍
QuBranch功能如下:
量子程序调试与运行。QuBranch支持错误代码位置跳转,用户可通过观察程序运行步骤,发现程序中出现的逻辑错误,并及时对语法和逻辑错误做出修正。量子模拟执行方面,启科量子研发团队自主研发的QuTrunk目前以量子计算模拟器QuSimulator作为后端,还可扩展支持更多后端支持量子程序的运行与调试。
一站式量子编程开发环境。QuBranch可通过结合量子编程框架QuTrunk、调用QuFlower的量子算法资源,最终实现多种量子算法的运行。现阶段启科已经可以通过QuTrunk的backend接口,采用RPC与QuSimulator在QuBranch上模拟运行多种量子算法。
以柱状图、折线图、雷达图等多种图表形式直观显示程序输出信息和设备信息。QuBranch可以自动统计量子态信息、量子设备信息和运行数据信息,并以柱状图、折线图、雷达图等多图表形式显示数据输出结果,输出json数据格式化。程序运行结束后还支持生成量子线路图,并一键导出生成的图形。
一键拖拽实现可视化量子编程。QuBranch中通过查看-命令面板调用QuComposer实现可视化编程。只需通过简单拖拽量子逻辑门即可生成量子线路和相应代码,测量结果将由QuComposer自带的柱状图显示。
QuBranch项目旨在研发经典适用的量子编程开发工具,联接开发者在经典计算中的开发习惯需求,让更多非物理专业背景的爱好者或经典计算机编程人员能轻松参与到量子编程队伍中来。
1.2QuTrunk项目
项目介绍
启科量子自主研发一款量子编程框架QuTrunk,为量子编程开发提供了一个通用的软件环境。QuTrunk使用Python作为宿主语言,利用Python的语法特性实现针对量子程序的DSL(领域专用语言),所有支持Python编程的IDE均可安装使用QuTrunk。
QuTrunk基于量子逻辑门、量子线路等概念提供量子编程所需的各类API。这些API分别由相应的模块实现,比如QCircuit实现量子线路功能,Qubit实现量子比特,Qureg实现量子寄存器,Command对应每个量子门操作的指令, Backend代表运行量子线路的后端模块,gate模块实现了各类基础量子门操作。同时QuTrunk还可以作为其他上层量子计算应用的基础,比如:量子算法、量子可视化编程、量子机器学习等。
目前QuTrunk以QuSprout作为后端。QuSprout也是启科量子自研的一款基于经典计算资源的量子计算模拟软件,支持支持多线程、多节点、GPU加速,也可预安装在QuBox 中。QuTrunk为量子编程工作提供了量子编程框架,建立起一套统一的量子编程规范,进而实现量子程序开发的“降本增效”。启科量子目前正在筹备QuTrunk项目的开源计划,旨在通过产品开源的方式促进量子计算软件技术的发展与普及。
QuTrunk框架设计要点:
为了能在量子虚拟机中更好的模拟真实量子计算机带来的计算误差,QuTrunk支持在量子线路初始化时设置噪声模型,可为用户带来真实的量子编程体验。QuTrunk的全振幅量子模拟功能可以一次性模拟计算量子态的所有振幅,在初始化时配置适当的计算方式,即可体验差异化的计算效率。在通用量子计算机正式问世之前,混合量子-经典计算将是量子计算领域一种很好的发展思路。
2.量子编程软件技术
2.1 混合量子与经典体系
在量子编程软件开发中,创建和调试量子程序的软件工具对于所有量子计算机来说,如同量子数据必不可少。有 告将量子计算的硬件结构划分为四个层次:一是量子比特所在的“量子数据层”;二是根据需要对量子进行操作和测量的“控制和测量层”;三是确定操作和算法序列的“控制处理器层”;四是用于处理 络访问、大存储阵列和用户界面的“主处理器层”,主处理层通过高速宽带与控制处理器连接。
类比经典计算编程,量子编程软件则应包括能够让程序员描述量子计算算法的编程语言、分析量子程序语言并将其映射到量子硬件的编译器,以及可在特定量子硬件上实现分析、优化、调试和测试程序的其他软件支持,如需要仿真和调试工具来调试软硬件、需要优化工具来帮助高效实现算法、需要验证工具来帮助确保软硬件的正确性等。
2.2量子编程语言
量子编程语言的层级由低到高分别是:量子设备语言(量子比特)、量子设备指令语言(量子比特上的门序列)、量子程序(简易方式编程的量子算法)、量子算法(仅处理参数)、量子通用语言(适用于所有设备的语言)。量子计算机行业预设未来的量子计算机可能是量子计算机和经典计算机的混合结构。从量子硬件设备当下的发展来看,混合量子-经典算法(变分量子算法)是一个较合理的模型。它结合了量子设备的计算能力与经典设备的优化方法,可借助经典计算机尽可能发挥量子设备的计算能力。
在传统的计算机运算中,调试程序是软件开发中最耗时的任务之一。量子计算领域中如果没有调试器等工具的帮助,即使是经验丰富的量子程序员也会因为程序编写中的错误导致程序结果无法给出正确的运算结果,因此量子程序调试工具开发也是一个很大的挑战。
2.2.1QuSL量子汇编
QuTrunk使用python作为宿主语言,利用python的语法特性实现针对量子程序的DSL(领域专用语言),我们把用于量子编程的专用语言称为:QuSL(一套类似Openqasm的量子汇编语言),QuSL主要特点是最左边是一个量子门操作,中间加入( * ) 链接符,最右边是操作的量子比特,其形式如下:
gate * qubits
几个例子:
H * q[0]; # 对q[0]做hadamard门操作CNOT * (q[0], q[1]); # q[0]为控制位,q[1]为目标位All(Measure) * q # 对q代表的所有量子比特做测量操作
使用该标准是充分利用了python语法对( * )运算符的重载特性。该表形式更接近量子物理计算公式,同时 ( * )在计算机编程语言上表示乘法的意思,借此表示左边的量子门操作实际上是对量子比特做矩阵乘法运算。该标准编写的量子汇编可以直接被QuTrunk析运行,不需要做词法/语法方面的解析处理工作。基于该特性,QuTrunk可以无缝衔接QuBranch通过可视化量子编程生成的量子线路,即QuTrunk可以直接运行QuBranch生成的量子线路(只需做一些简单的初始化工作),而无需做语法上的编译/转译处理,下面是QuSL部分量子门操作介绍(具体可参见http://developer.queco):
星 (*)左边为相应的门操作,右边出现的a, b, c…均代表操作的量子比特位
//H(hadamard): 哈达马门,对a做H门操作,常用于使量子比特处于叠加态H * a//X(NOT): 非门(Pauli-X)对a进行取反操作, 量子比特绕布洛赫球的x轴旋转pi角度X * a//Y: Pauli-Y, 量子比特绕布洛赫球的y轴旋转pi角度Y * a//Z: Pauli-Z, 量子比特绕布洛赫球的z轴旋转pi角度Z * a//CNOT(CX): 受控非门,a作为控制位,b为目标位,如果a为1则对b进行取反,如果a为0则不做任何操作CNOT * (a, b)//Toffoli: 托佛利门,a, b作为控制位,c为目标位, 如果a,b均为1则对b进行取反,否则不做任何操作Toffoli * (a, b, c)//Measure: 测量门,对a进行测量,结果要么是0,要么是1,测量结果受概率振幅影响Measure * a
现阶段,量子编程软件工具的研究工作已取得一些良好进展,如华为的量子计算云平台HiQ、本源量子基于C++的QPanda、启科量子的QuBranch和QuTrunk等。即便如此,量子编程软件的开发工作还面临系列挑战。例如,在量子算法层面,量子计算系统的状态空间庞大,在经典计算机中即使是模拟60位左右或更多量子位的量子计算算法,也很难在合理的时间或空间内完成。此外,量子程序的调试和验证也是一项很大的挑战。在经典计算机中,程序员可以在程序的任意点停止执行并能检查机器状态值和其他项值,以便检查程序中的错误。而量子计算程序需要很大的状态空间,在进行物理量子位测量时面临崩溃,且测量后不能重启量子计算执行。因此,量子程序的调试与验证技术也待突破。
3.[QuBranch-QuTrunk-QuSim]产品使用示例
此次QuTrunk运行算法将QuBox作为后端提供量子模拟资源(QuBox为预装了QuSimulator的PKS体系硬件设备)。
# apply gate H | qr[0] CNOT | (qr[0], qr[1]) NOT | qr[0] Toffoli | (qr[0], qr[1], qr[2]) P(pi/2) | qr[2] R(pi/2) | qr[0] Rx(pi/2) | qr[1] S | qr[0] Sdg | qr[0] T | qr[0] Tdg | qr[0] X | qr[2] Swap | (qr[0], qr[1]) SqrtSwap | (qr[0], qr[1]) SqrtX | qr[0] C(P(pi/2)) | (qr[0], qr[1]) C(Rx(pi/2)) | (qr[0], qr[1]) Rzz(pi/2) | (qr[0], qr[1])
# print circuit Printer.print_circuit(qc) qc.run() # print measure result# print([int(q) for q in qr])
import yamlimport osBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))def get_qubox_setting(): """获取Qubox后端配置信息""" with open(BASE_DIR + "/config/qubox.yaml") as f: yaml_content = yaml.load(f, Loader=yaml.FullLoader) return yaml_contentdef get_qulocalbox_setting(): 获取Qulocalbox后端配置信息 with open(BASE_DIR + "/config/qulocal.yaml") as f: yaml_content = yaml.load(f, Loader=yaml.FullLoader) return yaml_content
3.1示例一:Grover算法
步骤1 首先在QuBranch中导入随机数模块和QuTrunk中的部分模块
import math import random from numpy import pi from QuTrunk.core.circuit import QCircuit, InitState from QuTrunk.core.gates import H, X, C, Z from QuTrunk.core.calculator import Calculator from QuTrunk.core.counter import Counter
步骤2 调用Oracle门和Diffuser函数,将量子态进行相位翻转和放大
def apply_oracle(qr, num_qubits, sol_elem)... def apply_diffuser(qr, num_qubits)...
步骤3 运行Grover算法,不断进行G迭代直至搜索出目标值
def run_grover(): num_qubits = 15 num_elems = 2 ** num_qubits num_reps = math.ceil(pi / 4 * math.sqrt(num_elems)) print("num_qubits:", num_qubits, "num_elems:", num_elems, "num_reps:", num_reps)
步骤4 输出运行结果
从结果中可观察到搜索的量子比特数为15Qubit、量子门数为11726个、总的运行时间为10.8659s(其中QuBox运行时间为10.6309s,QuTrunk运行时间仅为0.2350s)。
Counter(quit=15) qubits = 15 quantum_gates = 11726 total_time = 10.865945100784302 qubox_time = 10.630940914154053 qutrunk_time = 0.23500418663024902
以上Grover算法中生成随机数目标为17560,最终搜索结果概率峰值为0.999986接近于1。在搜索过程中,当此概率出现峰值且第一次下降时即停止搜索,认为已经找到目标值即为17560。
3.2示例二:贝尔电路
from qutrunk.core.circuit import QCircuit from qutrunk.core.printer import Printer from qutrunk.core.gates import H, CNOT, Measure qc = QCircuit() qr = qc.allocate(2) # allocate H | qr[0] # apply gate CNOT | (qr[0], qr[1]) Measure | qr[0] Measure | qr[1] Printer.print_circuit(qc) # print circuit res = qc.run(shots=1024) # run circuit print(res.get_counts()) # print result
3.3示例三:量子随机数
步骤1 环境准备
from qutrunk.core.circuit import QCircuitfrom qutrunk.core.printer import Printerfrom qutrunk.core.gates import H, Measure, Allfrom qutrunk.core.counter import Counterfrom qutrunk.core.backends import BackendQuSim
步骤2 运行随机数比特,并归集信息
def run_random_byte(backend=None): # allocate qc = QCircuit(backend) qureg = qc.allocate(8) # 将统计信息归集到Counter类 ct = Counter(qc)
步骤3 打印电路和输出信息结果
All(H) | qureg All(Measure) | qureg # print circuit Printer.print_circuit(qc) # run circuit res = qc.run() # print([int(q) for q in qureg]) print(res.get_measure()) ct.show_verbose()if __name__ == '__main__': # run_random_byte(backend=BackendQuSim()) run_random_byte()
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!