附录E:isq-Core 文档¶
isQ-core python 包安装使用说明¶
环境¶
python == 3.8
安装¶
pip直接安装
pip install isqopen
通过源码进行离线安装
git clone https://gitee.com/arclight_quantum/isq-core/
python setup.py build
python setup.py install
硬件支持¶
isQ-core 支持创新院云平台的 12 比特量子硬件,使用量子硬件需先去该云台注册相应的账号密码。
isQ-core 支持aws braket对接的硬件,可通过设置硬件编号和 s3 存储桶使用对应量子硬件,当离线使用时,请先安装aws-braket-sdk,注册 aws 账号,并开通 braket 相关权限,申请 s3 存储桶。在isQ 云平台时,平台提供 aws 使用权限,运行需消耗平台积分。
使用¶
使用时通过import isq 引入 isqopen
Device 使用¶
用户需先定义好使用的Device,然后编写好 isQ-core 程序,调用 Device 的run接口即可运行,Device 初始化参数可详见 API 说明。LocalDevice返回结果为测量的统计结果,以dict的形式返回。QcisDevice及AwsDevice返回ISQTask,可通过result接口获取结果(等待时间超过 max_wait_time 则返回空字典,可根据state属性查询任务执行状态)。使用示例如下
from isq import LocalDevice, QcisDevice, AwsDevice
isq_str = '''
qbit a, b;
X(a);
CNOT(a, b);
M(a);
M(b);
'''
# local device
ld = LocalDevice(shots = 200)
# 返回dict
ld_res = ld.run(isq_str)
print(ld_res)
#qcis device
qd = QcisDevice(user = "xxx", passwd = "xxx", max_wait_time = 60)
#返回ISQTask
task = qd.run(file = './test.isq')
#输出状态和结果
print(task.state)
print(task.result())
import logging
logger = logging.getLogger() # initialize logging class
logger.setLevel(logging.CRITICAL)
#aws device
from isq import TaskState
ad = AwsDevice(shots=100, device_arn = "arn:aws:braket:::device/qpu/ionq/ionQdevice", s3 = ("amazon-braket-arclight", "simulate"), max_wait_time=10, logger = logger)
task = ad.run(isq_str)
print(task.state)
#等待结果直到执行完成
while task.state == TaskState.WAIT:
task.result()
print(task.result())
Device 提供compile_to_ir接口,可将 isq 编译到 openqasm/qcis,示例如下:
'''
isQ-core -> openqasm2.0
qreg大小与isQ-core定义的量子比特数目一致
creg大小与测量的比特数目一致
测量结果按测量顺序从creg[0]开始依次存储
'''
ld = LocalDevice()
ir = ld.compile_to_ir(file = './test.isq', target="openqasm")
print(ir)
isq_str = '''
qbit a,b;
H(a);
CNOT(a,b);
M(a);
M(b);
'''
ld = LocalDevice()
ir = ld.compile_to_ir(isq_str, target="qcis")
print(ir)
量子核函数¶
isQ-core 提供了函数修饰符isq.qpu,通过该修饰符可定义一个量子核函数,该修饰符有如下参数
| 参数名 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| device | Device | 量子后端,可为LocalDeivce,QcisDeivce,AwsDeivce |
无 |
用该修饰符修饰的函数内部需采用注释的形式用 isQ-core 的相关语法进行编程。量子核函数的调用方式和 python 的函数调用方式一致,其返回结果与使用 Device 的run函数一致
#使用模拟器运行,制备bell态
import isq
from isq import LocalDevice, QcisDevice, AwsDevice
ld = LocalDevice()
@isq.qpu(ld)
def bell_sim():
'''
qbit a, b;
X(a);
CNOT(a, b);
M(a);
M(b);
'''
res = bell_sim()
print(res)
ir = ld.get_ir()
print(ir)
#使用12bit量子硬件运行,制备bell态
qd = QcisDevice(user = "xxx", passwd = "xxx")
@isq.qpu(qd)
def bell_qcis():
'''
qbit a, b;
X(a);
CNOT(a, b);
M(a);
M(b);
'''
task = bell_qcis()
res = task.result()
print(res)
带参电路¶
isQ-core 支持编写带参的电路,并在编译运行时传入具体的参数值。用户可直接在编写电路时使用参数,并在 Device 调用编译运行的接口中传入**同名**参数的具体值,如
isq_str = '''
qbit a, b;
RX(theta[0], a);
RY(theta[1], b);
M(a);
M(b);
'''
from isq import LocalDevice
# local device
ld = LocalDevice(shots = 200)
# 返回dict
ld_res = ld.run(isq_str, theta = [0.2, 0.4])
print(ld_res)
或者通过量子核函数的方式,在定义核函数时确定参数名,并在调用函数时传入具体值,如
#带参数的量子核函数
import isq
from isq import LocalDevice
ld = LocalDevice()
@isq.qpu(ld)
def test(theta, a):
'''
qbit t[5];
if (a < 5){
X(t[0]);
}else{
RX(theta[1],t[1]);
}
M(t[1]);
'''
res = test([0.1, 0.2], 3)
自定义酉门¶
可使用quantumCor.addGate函数在 kernel 外部声明自定义酉门,这些酉门可在所有 kernel 中直接使用(酉操作)。kernel 中声明同名酉门则会在内部覆盖。自定义酉门需传入两个参数,门名称(str)和门的矩阵表示(list/np.array),示例如下
from isq import quantumCor
import isq
a = [[0.5+0.8660254j,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
quantumCor.addGate("Rs", a)
ld = LocalDevice()
@isq.qpu(ld)
def test():
'''
qbit a, b;
...
Rs(a, b);
...
'''
电路图生成¶
isQ-core 可通过 Device 的draw_circuit函数,打印指令集的电路展示图。由于为从编译结果生成,电路图只包含基础门集,用户自定义门会被分解后展示。RX,RY,RZ 的旋转角度默认不显示,如需显示,可通过showparam参数设置
from isq import LocalDevice
#定义量子线路
isq_str = '''
qbit a,b;
H(a);
CNOT(a,b);
RX(2.333, a);
M(a);
M(b);
'''
ld = LocalDevice()
ld.run(isq_str)
ld.draw_circuit()
ld.draw_circuit(True)

自动微分¶
isQ-core 可对参数化电路进行自动微分,并利用优化器进行参数优化。LocalDevice内置了 probs 接口,其在编译阶段进行带参编译,生成参数化电路(目前只支持 RX, RY, RZ 门带参),这些参数是需要优化的参数,在调用接口传入时需用optv进行封装,在模拟阶段,返回测量比特的概率值(不进行测量,直接返回概率)。
isQ-core 提供了基于梯度下降法的优化器optimizer,其opt接口接收用户自定义的损失函数,及需要优化的参数,并返回优化后参数及当次损失函数值
示例如下:
import isq
from isq import LocalDevice, optv
#定义量子线路
isq_str = '''
qbit q[2];
RX(theta[0], q[0]);
RY(theta[1], q[1]);
M(q[0]);
'''
#定义device
ld = LocalDevice()
#定义损失函数
def loss(params):
#使用probs函数进行带参编译和模拟,其中需要优化的参数通过optv封装后传入
c = ld.probs(isq_str, theta = optv(params))
return c[0] - c[1]
#定义optimizer
opt = isq.optimizer(0.01)
#获取优化后参数及当次损失函数计算值
newp, cost = opt.opt(loss, [0.2, 0.4])
print(newp, cost)
自定义 optimizer¶
isQ-core 提供自动微分接口grad以使用户可根据微分结果自定义优化器。grad接收损失函数及损失函数中需要微分的参数位置作为输入,返回一个可调用类型,再传入计算函数所需参数,即可返回参数的微分结果,示例如下
import isq
from isq import LocalDevice, optv
#定义量子线路
isq_str = '''
qbit q[2];
RX(theta[0], q[0]);
RY(theta[1], q[1]);
M(q[0]);
'''
#定义device
ld = LocalDevice()
#定义计算函数
def calc(params):
#使用probs函数进行带参编译和模拟,其中需要微分的参数通过optv封装后传入
c = ld.probs(isq_str, theta = optv(params))
return c[0] - c[1]
#定义grad,并调用,对第0个参数求微分
g = isq.grad(calc, [0])
d = g([0.2, 0.4])
print(d)
批量处理¶
isQ-core 通过 jax 的 vmap 提供自动微分的批处理功能,该功能在单次微分的运行效率上不如上述grad接口,但是在批处理上有着明显的优势。
使用时需先安装jax环境,并在损失函数中使用LocalDevice的probs接口时添加mod参数,并设置为 1(默认为 0)。微分采用 jax 自带的grad 函数,批处理采用 jax 的vmap 函数,示例如下
from isq import LocalDevice
from jax import grad, vmap
from jax import numpy as jnp
#定义量子线路
isq_str = '''
qbit q[2];
RX(theta[0], q[0]);
RY(theta[1], q[1]);
M(q[0]);
'''
#定义device
ld = LocalDevice()
#定义计算函数
def calc(params):
#使用probs函数进行带参编译和模拟,其中需要优化的参数通过optv封装后传入,mod值为1,使用jax.numpy计算
c = ld.probs(isq_str, mod = 1, theta = optv(params))
return c[0] - c[1]
theta = jnp.array([[0.2, 0.4] for _ in range(10)])
#微分
g = grad(calc)
#vmap批处理,以第0轴索引,输出每个划分的微分结果。该例子中即为以行为划分,输出10个结果
c = jax.vmap(g)
d = c(theta)
print(d)
isQ-core 语法说明¶
isQ-core 编程语言包含如下操作
1.1 自定义 qubit 变量¶
isQ-core 支持用户定义 qubit 变量(仅支持定义全局变量),可为单个变量,或者 qubit 数组(注意在 isQ 中, qubit 对应的关键字是 qbit),定义格式如下
其中ID为变量名,由字母和数字构成,如 a, b2,变量名不能重复;数组变量形式为ID[NUMBER],NUMBER为数字,如 a[3], b1[10];每一行可定义单个或多个变量/数组。所有的 qubit 变量均默认初始化为|0>
示例
qbit a;
qbit b[3];
qbit q, p[5];
注:当编译为 QCIS 指令集时,qubit 按顺序对应到物理比特上,如上述示例中 a->Q1,b[0]->Q2
1.2 自定义 qcouple 变量¶
isQ-core 支持用户定义 qcouple 变量(仅支持定义全局变量),qcouple 指代耦合的两个量子比特,定义格式如下
qcouple 的定义与 qubit 类似,在使用时,qcouple 只能用于两比特门,如 CNOT,CZ
示例
qcouple c;
qcouple qc[3];
qcouple q, p[5];
...
CZ(c);
...
注:当编译为 QCIS 指令集时,qcouple 按顺序对应到耦合的物理比特对上,如上述示例中 c->Q67(Q1, Q7),qc[0]->Q68(Q1, Q8)
1.3 经典变量定义¶
isQ-core 支持用户通过var定义经典变量(仅支持定义全局变量)定义格式如下
经典变量定义时需要给初始值,这些经典变量一般可用于旋转门的参数
示例
qbit q[66];
var x = 1.3;
var theta = {1.2, 1.4};
...
RX(x, q[0]);
RXY(theta[0], theta[1], q[5]);
...
1.4 自定义酉门¶
isQ-core 允许用户自定义符合下述三个条件的酉门
- 门的大小为 2 的幂次
- 定义在程序一开始
- 不和基础门重名
示例:
defgate Rs = [
0.5+0.8660254j,0,0,0;
0,1,0,0;
0,0,1,0;
0,0,0,1
]
1.5 酉操作¶
在说明酉操作之前,我们先介绍一个概念:qbundle。qbundle 表示 qubit 数组内的一组 qubit,其表达形式如下:
qbundle有两种表达形式,其中ID为 qubit 变量名,必须为之前定义的数组变量,idx为下标,可以为常数,或以四则运算构建的表达式。在第一种表达形式中,用一系列下标来表示这一组 qubit,如我们之前定义了t[10],则可以用t[1,3,5,7]来表示t[1],t[3],t[5],t[7]这四个 qubit。第二种表达形式类似 python 的 range,用start/stop表示起始/终止下标(不包含 stop),step表示步长,默认为 1。如t[1:4]表示t[1],t[2],t[3]
酉操作为对 qubit 作用酉门,定义格式如下:
GateID为酉门名称,现有基础门包括:H,X,Y,Z,S,T,SD,TD,X2P,X2M,Y2P,Y2M,CX, CY, CZ,CNOT,RX,RY,RZ,RXY。n 为门作用的 qubit 数目(CZ,CNOT 为 2,其余门均为 1)。酉门可作用在 qubit 变量上(形式一)或者 qbundle(形式二)上。当作用在 qbundle 上时,qbound_i的长度必须一致,此时其语义为对每个 j,执行GateID<qbundle_{1,j},…,qbundle_{n,j}>
示例
H(q);
H(p[1+2]);
CNOT(q, p[1]);
CNOT(p[1:3], p[2:4]); // = CNOT<p[1], p[2]>, CNOT<p[2], p[3]>
RX(0.5, q);
1.6 测量操作¶
对 qubit 进行测量,定义格式类似上面的酉操作:
其中对 qbundle 测量的语义为对 qbundle 里每一个 qubit 进行测量
示例:
M(q);
M(p[1]);
M(p[1:4]); // = M(p[1]), M(p[2]), M(p[3]);
1.7 for 循环¶
为方便用户做一些循环酉操作,简化代码,isQ-core 提供了 for 循环的支持,定义格式如下:
其中cid为循环自增变量名,start,stop,step和qbundle中定义一致,start/stop表示起始/终止值(不包含 stop),step表示步长。forloopBody里面可包含酉操作,测量操作,for 循环及 if 条件语句。在forloopBody中可用带 cid 的表达式做下标来访问 qubit 变量
示例:
for i in 1:3{
H(t[i]);
CZ(w[i],w[i+1]);
}
1.8 if 条件语句¶
isQ-core 提供了 if 条件分支语句,定义格式如下:
或者
其中express为可计算的算是表达式,如常量,int 变量或者其四则运算,asso为比较运算符,目前支持>,>=,<,<=,==,!=。ifbody和elseBody与forloopBody一致。
1.9 注释¶
isQ-core 提供单行注释功能,在需要注释内容前加 // 即可
isQ-core api 说明¶
quantumCor¶
addGate¶
静态函数,注册用户自定义酉门
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| name | str | 酉门名称 | - |
| val | [np.array, list] | 酉门矩阵表示 | - |
getGate¶
静态函数,获取当前注册的酉门集合
getMapping¶
静态函数,实现量子比特映射(QcisDevice 中已调用该接口实现创新院 12 比特量子硬件的映射)
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| qbit_num | int | 物理比特数 | - |
| topo | list | 硬件拓扑结构 | - |
| isq_ir | str | 编译得到的 isq_ir | - |
Device¶
run¶
编译+运行,根据后台选择对应编译结果
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| isq_str | str | isq 源码 | '' |
| file | str | isq 外部文件,当有 isq_str 和 file 同时存在时,优先编译文件内容 | None |
| **kwargs | - | isq 参数 | - |
compile_to_ir¶
编译
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| isq_str | isq 源码 | '' | |
| file | str | isq 外部文件,当有 isq_str 和 file 同时存在时,优先编译文件内容 | None |
| target | str | 编译目标,目前支持isq, qcis, openqasm |
isq |
| **kwargs | - | isq 参数 | - |
get_ir¶
获取当次run的编译结果
draw_circuit¶
打印当前编译得到的 ir 的电路图
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| showparam | bool | 是否显示 RX,RY,RZ 的角度 | False |
LocalDevice¶
__init__
初始化
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| shots | int | 运行次数 | 100 |
| max_wait_time | int | 任务查询最大等待时间 | 60 |
| name | str | 后台名称 | 'local_device' |
| mode | str | 模拟模式,fast/normal |
fast |
| logger | Logger | 日志对象 | logging.getLogger(name) |
probs
获取幅值(不进行测量,直接返回概率)
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| isq_str | str | isq 源码 | '' |
| file | str | isq 外部文件,当有 isq_str 和 file 同时存在时,优先编译文件内容 | None |
| mod | int | 采用的数据模式,0—autograd.numpy, 1—jax.numpy |
0 |
| **kwargs | - | isq 参数,当需要配合优化器使用时,需要优化的参数用 optv 封装 | - |
QcisDevice¶
__init__
初始化
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| user | str | 创新院平台用户名 | - |
| passwd | str | 创新院平台密码 | - |
| shots | int | 运行次数 | 100 |
| max_wait_time | int | 任务查询最大等待时间 | 60 |
| name | str | 后台名称 | 'qcis_device' |
| logger | Logger | 日志对象 | logging.getLogger(name) |
AwsDevice¶
__init__
初始化
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| device_arn | str | aws QPU, 可选值详见 braket 说明文档 | - |
| s3 | tuple | aws s3 存储桶,云平台使用时,无需填写,使用平台提供的存储桶 | - |
| shots | int | 运行次数 | 100 |
| max_wait_time | int | 任务查询最大等待时间 | 60 |
| name | str | 后台名称 | 'aws_device' |
| logger | Logger | 日志对象 | logging.getLogger(name) |
ISQTask¶
__init__¶
初始化
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| task_id | Union[int, str] | 任务编号 | - |
| task_type | TaskType | 任务类型 | - |
| state | TaskState | 任务状态 | - |
| device | Device | 关联设备 | - |
| **kwargs | - | 其他参数 | - |
result¶
获取结果,当任务状态为TaskState.COMPLETE时,直接返回结果,当状态为TaskState.WAIT时,开始查询结果,当查询时间超过关联设备设置的任务查询最大等待时间,则任务仍在排队或运行中,返回空字典,否则,返回查询结果
cancel¶
当使用 AwsDevice 生成任务时,可通过该接口取消任务(目前 QcisDevice 的任务无法取消)
TaskState¶
- WAIT
- COMPLETE
- FAIL
- CANCEL
TaskType¶
- QCSI
- AWS
optimizer¶
__init__¶
初始化
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| lr | float | 学习率 | - |
| argnum | list | 需要优化的参数位置 | [0] |
opt¶
梯度下降法优化参数
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| fun | function | 损失函数 | - |
| params | list | 需要优化的参数 | - |
grad¶
__init__¶
初始化
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| fun | function | 损失函数 | - |
| argnum | list | 需要优化的参数位置 | [0] |