13. 矩阵乘法加速与量子程序模拟¶
13.1. Systolic Array¶
https://github.com/qurisc-dev/qusim
考虑到量子计算模拟器中存在大量的矩阵运算需求,我们引入了协处理器Systolic Array用来加速矩阵运算。
13.1.1. 实现原理¶
在协处理器的设计上,我们使用Systolic Array(脉动执行)结构,执行快速的矩阵乘法运算。
上图中的方格部分为核心运算单元,由乘法器和累加器构成。 待运算矩阵的源数据以流水线方式按节拍流入核心运算阵列中,以流水方式进行乘加,最终可以$O(n)$的时间效率得到$n*n$矩阵乘法的结果; 而朴素的直接运算其时间复杂度为$O(n^3)$。结合片内资源限制,我们最终实现了$4*4$的矩阵乘法协处理器, 利用Xilinx提供的Floating Point IP核,实现了32位浮点数矩阵的快速乘法。
13.1.2. Memory mapping¶
为了在不增加新指令的基础上利用协处理器,我们将协处理器及其控制单元映射到了给定的内存地址中,通过内存访问方式统一进行处理。 考虑到我们实现的是64位CPU,我们将源矩阵交叉映射到内存中,即两个输入矩阵对应位置各32位拼接为一个整字。 同时,我们通过专用的编译器以利用该协处理器,进行矩阵乘法的加速。
和其它部件一样,协处理器采用了AXI4 Lite协议与处理器进行交互。
13.1.3. 效率分析与测试¶
协处理器的核心逻辑部分允许单周期的流水运算,总共能够在约490ns内完成一次4*4的矩阵乘法。 作为对比,在不引入协处理器的情况下,朴素的64条浮点乘法指令和48条浮点加法指令仅发射即需占用112周期,即1120ns, 其实际完成矩阵乘法操作(包括累加运算及运算)远高于本协处理器的运行时间。 因此,本协处理器的加速是有效的。
我们生成了若干组随机的benchmark进行矩阵浮点运算正确性测试。 经实际上机测试,本协处理器可在100MHz下正常运行,其运算结果正确。
13.1.4. 可能的进一步优化¶
当前,协处理器使用了Block RAM与处理器进行交互; 考虑到490ns较短不值得使用中断(同时当前处理器不支持中断),处理器不得不轮询状态寄存器以获知计算完成。 同时,当连续进行大量矩阵乘法运算(例如进行分块矩阵乘法的运算)时,大量的处理器时间被浪费在从Block RAM和处理器之间来回复制数据上。
一种进一步优化的思路是允许协处理器访问总线,以DMA方式直接从内存载入待处理数据,不再浪费处理器的时间; 同时,从内存载入待处理数据的方式可以针对分块矩阵进行优化,例如,借助硬件自动完成矩阵的分块与分块相乘。
13.2. Quantum Compiler¶
https://github.com/qurisc-dev/qusim-compiler/tree/master/qcomp
13.2.1. 实现功能¶
在源语言的选择上,为方便实现,我们引入了qasm2circ中的简单量子门指令集为参考; 在此基础上,允许X, Y, Z, Toffoli, CNOT等基本门操作的模拟和Rx, Ry, Rz等带参数单比特旋转门。 这些门构成了Universal gate set,即原则上本语言支持任意量子操作的实现。 在此基础上,我们允许程序员自定义任何两比特以下的门以方便运算。
13.2.2. 实现方法¶
考虑到实现的方便性,我们选择先将源语言编译到简单的C语言,再利用riscv-gcc toolchain编译成二进制文件烧入内存。 其中,利用分块矩阵乘法的算法,以分块矩阵为单位进行矩阵运算,有效利用了我们的协处理器进行加速。
在量子态的表示方面,我们暂时选择了较易实现的vector representation代替density operator。 对于较长的向量,仍然可以通过分块的方法压缩成矩阵,利用协处理器进行高效运算。
13.2.3. 实际测试¶
在原本的设计上,我们还实现了测量操作和经典比特的引入,并利用模拟器测试了编译器的正确性。 但是,由于时间所限,我们的处理器暂时不支持普通的浮点运算操作,仅允许通过协处理器进行浮点操作。
为展示最终效果,我们对编译器进行了修改,限制了原编译器的部分功能,抹除了所有额外的浮点运算; 由于universal的量子运算模拟需要在复数域上进行,为避免浮点加法运算,我们被迫将本模拟器的运算限制在实数域。 因此,支持的门减少到X, Z, Toffoli, CNOT和Ry,模拟器的功能也被弱化;但仍可进行相当复杂度的量子运算。
13.3. Testbench¶
https://github.com/qurisc-dev/qusim-compiler/tree/master/testbench
13.3.1. 简单的协处理器Testbench¶
为了测试协处理器本身,我们编写了一组工具,用于随机生成矩阵乘法测试样例,从而测试协处理器的正确性。
13.3.2. 量子程序测试样例¶
我们选取了一个简单的量子电路作为测试样例,该电路源代码如下。
gatedef testgate
ry 0,-1.5707963267949
ry 1,-1.5707963267949
cnot 0,1
endgatedef
gatedef swap
cnot 0,1
cnot 1,0
cnot 0,1
endgatedef
qubit 0
qubit 1
qubit 2
cnot 0,1
testgate 0,2
swap 1,2
电路在IBM Q Experience上的图例和运行结果如下。
我们的运行结果与其一致。