开源之夏,是由中国科学院软件研究所发起,专为高校学生精心打造的活动。旨在鼓励广大学子积极参与开源软件的开发与维护,推动优秀开源软件社区的蓬勃发展。
目前,开源之夏2024已圆满结项!在本届开源之夏中,不少开发者跟随昇思MindSpore一起,在开源的世界里畅游,成功完成项目任务。在此,昇思 MindSpore 开源社区邀请了开源之夏的开发者们,分享他们在本次活动中的宝贵经验与心得。我们希望通过这些精彩的项目经历和实战技巧,能够激发更多创意火花,帮助大家提升技术能力。本文为昇思MindSpore 开源之夏项目经验分享系列第5篇。
项目基本介绍
1、项目名称:提升MindSpore Quantum中Stabilizer模拟器性能
2、项目导师:杨金元
3、项目链接:https://summer-ospp.ac.cn/org/prodetail/24c6d0467?list=org&navpage=org
4、项目描述:Minspore Quantum运行的基本原理是使用矩阵计算让经典计算机去模拟量子计算机,目前框架已使用Python实现几个常用的量子模拟器,但存在效率不高的问题,无法满足量子模拟的实际需求。项目内容是使用C++实现一个Stabilizer模拟器,并探索实现改进Stabilizer模拟器性能的方法,以用来满足大比特场景下复杂量子计算。同时,对改进Stabilizer模拟器性能与Mindspore Quantum 现有的模拟器性能进行基准测试,验证其高效性能。
项目代码:https://gitee.com/mindspore/mindquantum/tree/research/summer_ospp/2024/24c6d0467
项目选择初衷
在本科的时候,经过同学介绍,参与过一次开源之夏,当时负责的是ElasticSearch数据库增删改查接口的实现,项目难度为基础,编程语言为Java。在经过实验室科研训练和参加算法编程竞赛后,我发现自己相较于Java面向业务端的开发内容,更喜欢底层模块开发以及更具有挑战性的算法优化与实现。正又值开源之夏申请季,我在浏览了众多项目后,与杨金元导师简单沟通,了解到量子计算与量子模拟的相关内容,发现项目内容十分富有挑战性。MindSpore作为国内顶尖AI开源框架,我认为这是近距离接触前沿技术的良好契机,抱着试一试的态度,投递了项目申请书。在杨金元导师的悉心指导下,我成功中选并着手进行项目开发。
项目方案介绍
目前MindSpore Quantum中已有python实现的基于stabilizer tableau模拟器,但由于python自身的运行效率较低,无法满足1000大比特的实现,无法满足功能模拟。同时,根据参考文献,目前有一种改进的Stabilizer Tableau模拟器。至此,项目的开发内容就比较明确:
1、完成Stabilizer Tableau的C++重构
2、实现改进Stabilizer Tableau模拟器的创新点,分别为 1). Inverse Tableau. 2). Vectorized Code
项目实现思路
我将从原理解析和程序设计两个方面来介绍项目的实现思路。
01
原理解析
- Inverse Tableau 优化 Stabilizer Tableau
Mindspore Quantum现有基于Python实现的Stabilizer模拟器,参考的是CHP算法,时间复杂度为O(n^2)。根据参考文献,取消Clifford门与Tableau的计算,通过追踪Clifford门的逆,在最后进行量子测量的时候,判断量子态是否为确定态,确定态即可直接得到测量结果(复杂度降到线性O(1)),非确定态再进行测量。
02
Vectorized Code 向量化计算
以H门为例,H^-1与tableau的计算,是Xq与Zq整行进行交换。其他大部分的量子逻辑门逆都是整行计算,现有的矩阵向量计算方案多为逐个元素计算,单线程操作,效率低下,面对量子比特大,量子电路复杂的情况,表现十分差。因此,采用SIMD指令优化加速计算过程,并行操作。
03
程序设计
核心的数据结构是Tableau的设计,所有的操作实际上是针对Tableau 模拟。一个Tableau从数据结构的角度来理解,由X、Z、Phase三部分组成,是一个值全为0/1的二维矩阵,大小为(2n+1)*2n,n系统的量子比特数。其中X、Z大小为n*2n,Phase大小为n*1。如果用常用的数据类型(例如int类型)构建一个二维数组对Tableau进行存储,会造成存储空间的巨大浪费(值只有0/1,一个int类型消耗1byte的内存),并且计算效率低下(单线程)。针对存储空间优化,每个元素实际上只需要1bit的内存。针对计算效率优化,在原理解析已经介绍了SIMD指令多线程加速计算。在C++中,SIMD指令有相关的头文件(Linux系统下是<immintrin.h>)封装了相关数据类型及基本操作。
最终方案
SIMD指令加速方面,<immintrin.h>头文件中,支持不同类型的SIMD指令,我使用了256位AVX指令,也就意味着一次对256位的数据进行计算,使用m256i类型创建变量,每一位存储Tableau的一个值(0/1)。这里,我将m256i变量和基础位运算操作简单封装为SIMDWord类,Tableau存储到多个SIMDWord中。又因为调用一次SIMD指令最小操作单位为256位,因此需要对不足256的数据进行补全。
Tableau与量子逻辑门计算通过操作SIMDWord位运算实现。观察不同量子门的计算发现,一共有两种,对X或者Z行/列计算、逐位计算。因此,Tableau需要支持按行查询一整行该数据,同时支持按行按列查询该位存储数据,类似一个二维数据。针对以上需求,我封装了SIMDTable类、SIMDArray类,通过重载[]运算符,支持按行查询,返回结果为SIMDArray类。SIMDArray类中重载[]运算符,返回结果为SIMDWord中一个bit。
在梳理完需求后,剩下的工作内容就是代码复现和完善程序设计,值得一提的就是内存管理部分的优化设计,这也是由C++语言特性决定的。在初版代码中,由于理解不到位,我把内存的申请与内存的释放写在了SimdTable、SimdArray的析构函数中,但SIMDTable是一个中间变量,会多次调用,是根据SimdWord生成,这样会存在Tableau还需要运算,SIMDWord申请的内存已经释放的情况,导致内存泄漏。所以,内存申请释放应该写在Tableau的构造函数中,然后在Tableau中实现对XTable、ZTable、Phase的查询。
项目总结
回顾整个项目开发过程,60%的时间在了解量子计算与Stabilizer模拟器相关的基础知识,因为我是初次接触量子力学,这也是最具有挑战的部分,在这个过程中,杨金元导师给我的鼓励和支持,并且耐心地为我解答相关知识。这次项目开发极大地锻炼了我独立解决问题、思考的能力,将理论问题抽象成程序设计并实现。经过这次开发,我意识到一个项目的开发是需要经历多次版本迭代,并不可能一次就完成,项目的完成更需要的是面对一次次报错的耐心和坚持。最后,再次感谢昇思提供的这次机会,让我了解开源,爱上开源。