4. 高阶应用技巧¶
4.1 实验合集管理¶
为提供合理的实验归类管理,量子计算云平台提供实验归类管理,提供了实验合集的概念。
可以在提交实验线路时,将实验线路放在指定的合集下,以便后期管理查看。
注意:
需要先创建实验合集或将已有合集信息传递到后继实验。
实验合集之间不能重名,同一合集下实验名称不能重名。
云平台网站WEB端展示效果待优化,请包涵。
具体实验合集的创建方式如下:
from ezQgd import *
account = Account(login_key='2p1adksE+s6ib6uJa5/P/G3sc2O9kejgGBjgIukfGmY=', machine_name='gd_qc1')
create_res = account.create_experiment('机器学习B')
if create_res == 0:
print('新建实验合集失败')
else :
print('新建实验合辑成功,ID=', create_res)
lab_id = create_res
#实验合集id建议长期保留,以便后继使用。
当前创建实验使用的机器名: Xiaohong 新建实验合辑成功,ID= 3abe799a8e5941f884d27dec96f3e00b
或者直接使用已有实验ID
lab_id=create_res #Your experimentId
#实验合集id的web查询方式为:在我的实验合集页面,点击需要查看的实验合集,观察浏览器地址栏中信息,eg.
#https://quantumctek-cloud.com/expList.html?experimentId=1639487661985239040
#其中experimentId后的参数即为实验合集id
将量子线路提交到指定的实验集合下的操作方式如下:
qcis_circuit = '''
H Q6
X Q0
H Q0
CZ Q6 Q0
H Q0
M Q6
M Q0
'''
query_id = account.submit_job(circuit=qcis_circuit, lab_id=lab_id, version="GPT4-a123")
#对于单次提交实验,可以手动输入上述参数,如果想设计自动化程序,version的参数值可以通过计数等格式提前生成。
#其他流程同标准方式。
print(query_id)
['47179994301838099ustc00000726726']
4.2 切换量子计算机¶
大多数情况,我们都会使用"变量名"代表所需要的量子计算型号,然后在调用account时,直接设置量子计算机。
对于已经开发完成的程序,利用某台机器(如应答机)验证过的程序,也只需要修改变量名称即可快速修改后继的计算机使用情况。
from ezQgd import Account
login_key='2p1adksE+s6ib6uJa5/P/G3sc2O9kejgGBjgIukfGmY='
machine_name = 'gd_test'
account = Account(login_key=login_key, machine_name=machine_name)
#设置用户SDK密钥,选择量子计算机,并创建实例。
print(account.machine_name)
Transponder
但有些特殊情况,例如希望在一个程序内,快速提交同一段实验到两个机器上做对比,则可以使用量子计算机的设置功能。
machine_name = 'gd_test'
account = Account(login_key=login_key)#未设置量子计算机
print(account.machine_name)
#查看当前选择的量子计算机
account.set_machine(machine_name)
#切换量子计算机时,注意最终提交的程序需要遵守量子计算机的拓扑结构限制,否则提交实验时会报错。
print(account.machine_name)
#查看量子计算机设置选择是否生效
None Transponder
4.3 实验提交动作分解¶
submit_job()函数实际上是将多个动作封装在一起的函数,如果有特殊需求,可以分布执行提交动作,或者重新设计自己的提交函数。
当前提交函数内的动作包含:
- assign_parameters(circuit, parameters, values)
将量子线路的变量参数快速带入,生产最终量子线路。
- save_experiment(lab_id, exp_data, name='detailtest', language='qcis')
将量子线路保存到云平台上已被后期调用,返回实验线路id。其中name相当于submit_job中的version变量。
- run_experiment(exp_id, num_shots=12000)
运行指定实验id的线路。
所以一个submit_job()提交可以被等效为如下动作。
qcis_circuit = '''
H Q6
X Q0
H Q0
CZ Q6 Q0
H Q0
M Q6
M Q0
'''
from ezQgd import Account
login_key='2p1adksE+s6ib6uJa5/P/G3sc2O9kejgGBjgIukfGmY='
machine_name = 'gd_qc1'
account = Account(login_key=login_key, machine_name=machine_name)
#设置用户SDK密钥,选择量子计算机,并创建实例。
lab_id='d4a7f5f2b6bd4bdc87f2c1e7dc7a3183'
#query_id = account.submit_job(circuit=qcis_circuit, lab_id=lab_id, version="人工智能a1234")
#以上一个submit_job等于以下几个操作
qcis_circuit=account.assign_parameters(circuit=qcis_circuit,parameters=None, values=None)#参数列表和参数值,在上述ubmit_job中采用了默认值NULL。
print(qcis_circuit)
exp_id=account.save_experiment(lab_id=lab_id, exp_data=qcis_circuit, version="人工智能a123456")#language参数在submit_job函数中不可外部输入。当前该值只支持qcis。
print(exp_id)
query_id=account.run_experiment(exp_id=exp_id, num_shots=12000)#num_shots在上述submit_job中采用了默认值12000。
print(query_id)
['\nRX Q0 0.1\nRX Q6 0.2\nH Q0\nX Q6\nH Q6\nCZ Q0 Q6\nH Q6\nM Q0\nM Q6\n'] ustc8547868912313641000000726728 运行实验失败:失败 0
4.4 多次运行同一线路¶
虽然使用完备的标准门可以实现任意门操作,但对于经典数据的输入,还是希望直接传入到量子程序中,而不是根据参数重新设计线路。
所以,我们专门在submit_job中直接添加了传参函数assign_parameters。用户也可以在线路准备阶段直接使用该函数进行线路的参数传入。
利用线路传参和批量提交可以大幅加速固定线路,但参数不同的批量实验。详见批量提交实验线路。
#续上例程序
saved_exp_id=exp_id
#saved_exp_id='ustc3142744691105312700000005360'
result_list=[]
for i in range(2) :
query_id=account.run_experiment(exp_id=saved_exp_id, num_shots=1000)#num_shots在上述submit_job中采用了默认值12000。
result=account.query_experiment(query_id, max_wait_time=360000)
result_list.append(result)
print(result_list)
--------------------------------------------------------------------------- NameError Traceback (most recent call last) /tmp/ipykernel_180/1944726473.py in <module> 1 #续上例程序 ----> 2 saved_exp_id=exp_id 3 #saved_exp_id='ustc3142744691105312700000005360' 4 result_list=[] 5 for i in range(2) : NameError: name 'exp_id' is not defined
4.5 线路传参¶
虽然使用完备的标准门可以实现任意门操作,但对于经典数据的输入,还是希望直接传入到量子程序中,而不是根据参数重新设计线路。
所以,我们专门在submit_job中直接添加了传参函数assign_parameters。用户也可以在线路准备阶段直接使用该函数进行线路的参数传入。
利用线路传参和批量提交可以大幅加速固定线路,但参数不同的批量实验。详见批量提交实验线路。
#在线路中预置{x}表述待传入参数
qcis_circuit = '''
RX Q0 {N1}
RX Q6 {N2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
#需要注意,assign_parameters主要用于submit_job中调用,所以参数形式以列表为主,即便传递一个线路和其中的参数与数值,都要使用列表形式。
values=[[0.1,0.2]]
#注意assign_parameters的首个参数为circuits,结尾多个s,为复数形式。一定要传递列表进来。
qcis_circuit=account.assign_parameters(circuits=[qcis_circuit], parameters=[['N1','N2']], values=values)
print(qcis_circuit)
#注意此时qcis_circuit已经被带入参数,成为具体的无动态参数线路。
#或者直接使用submit_job函数直接带入参数
qcis_circuit = '''
RX Q0 {N1}
RX Q6 {N2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
values=[[0.1,0.2]]
query_id = account.submit_job(circuit=[qcis_circuit],parameters=[['N1','N2']], values=values)
print(query_id)
上面这种带出参数的意义不大,仅是作为展示。
在异构程序设计时,会活用这个参数传递,将values根据动态数据实时计算带入,得到更强的参数更新特点。
因目前支持批量提交线路功能,所以传入线路都为list类型,而对应的参数都为list[list],所以注意参数格式。
4.6 概率统计¶
为节省带宽,让量子计算机相关服务更专心的做量子计算的服务,当测量比特超过15个时,量子计算机端将不再为用户做结果的概率统计和读取矫正,需要用户自行处理。
我们提供了基础的概率统计函数,调用方式如下:
qcis_circuit = '''
H Q6
X Q0
H Q0
CZ Q6 Q0
H Q0
M Q6
M Q0
'''
from ezQgd import *
account = Account(login_key='2p1adksE+s6ib6uJa5/P/G3sc2O9kejgGBjgIukfGmY=', machine_name='gd_qc1')
query_id = account.submit_job(qcis_circuit)
print(query_id)
if query_id:
result=account.query_experiment(query_id, max_wait_time=360000)
probability_whole=account.readout_data_to_state_probabilities_whole(result)
print(probability_whole)
#以上函数将结果的全部空间进行统计
probability_part=account.readout_data_to_state_probabilities_part(result)
print(probability_part)
#以上函数只对已有结果进行统计,概率为0的结果将不出现。有利于节省存储空间。且第一类完整统计对内存消耗极大。
4.7 读取矫正¶
当今的量子计算机在多环节都有保证度问题,在使用结果的统计结果时,需要进行读取矫正。
当读取比特小于等于15比特时,返回的概率结果已经进行了读取矫正。
#读取矫正需要将实验获得结果和量子计算机参数文件作为输入进行计算。
#如果未提供计算机参数文件,则采用当前量子计算机参数。
#保存实验结果时,可以通过download_config()函数获得。
probability_cali=account.probability_calibration(result[0])
print(probability_cali)
#该读取矫正是对统计概率的修正,不是通过概率重采样。
#如需需要重采样来矫正数据,还请用户自行设计并分享。
probability_cor=account.probability_correction(probability_cali)
print(probability_cor)
4.8 批量提交实验¶
为减小实验批量提交所带来的较大延时,我们做了多种批量运行实验的方式,最先提供的是在原流程基本不变的条件下,批量提交实验。
该批量提交实验,主要针对用户线路基本相同,尤其是测量比特相同,只有具备带入参数不同的情况下可以进行。(非常重要)
该模式下,用户可以通过一次提交动作,在量子计算机上连续运行多条线路。
批量提交实验重点在于效率,所以我们也只提供原始实验数据和最基础的SDK函数给用户使用,如何高效里的利用这些结果,需要用户自己操作,我们暂不封装高级函数,降低数据处理的效率。
用户在使用该功能时,如果遇到什么异常,或者感觉有任何异常,请尽快与我们联系,以便确认原因。
目前该功能的一些限制还请参见函数说明,主要是同时提交的线路数量,shots次数,测量比特等等的一些制约条件,同时查询函数最多一次查询50个线路的结果,一次提交超过50个线路时,请自行分组查询。
from ezQgd import *
account = Account(login_key='2p1adksE+s6ib6uJa5/P/G3sc2O9kejgGBjgIukfGmY=', machine_name='gd_qc1')
qcis_circuit_A = '''
Rx Q0 0
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
qcis_circuit_B = '''
Rx Q0 0.1
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
qcis_circuit = [qcis_circuit_A, qcis_circuit_B]*10
#将所有需要的线路合为一个列表。
#注意:该模式只对测量比特相同,测量顺序相同的情况下有效,其他情况可以提交,但不保证运行结果的正确性。
#注意:该模式下,所消耗的积分为线路的总数量*单线路扣分,所以请理智提交。
print(qcis_circuit)
#其他动作啥都没变
#但注意积分消耗是根据列表中的线路数量来计算的。
query_id = account.submit_job(circuit=qcis_circuit,num_shots=1000)
print(query_id)
#注意批量提交时,query_id也为列表,可以按顺序对照指定的实验查询id
if query_id:
results=account.query_experiment(query_id, max_wait_time=360000)
#结果查询功能,最大只支持同时查询50个线路的结果,所以之前如果一次性提交多了,查询结果,用户要将查询是的id列表切一下,50个为一段来查询。
#实验结果是原来单结果的列表形式。
#用户可以留意一下,该模式下,读取结果时等待的时间,是否显著比单次提交*总次数的耗时提升了很多。
#批量提交模式为了高效,没有在物理机端计算统计结果,probability部分都为空,用户需要在自己本机来处理。
#所以及时保存当前的计算机参数,以便后期修正结果
res=account.download_config()
p1 = []
for query_res in results:
# 实验结果转换,概率转换,读取矫正
# results = account.readout_data_to_state_probabilities_whole(query_res)
prob = account.probability_calibration(query_res, res)
prob = account.probability_correction(prob)
p1.append(prob)
print(p1)
#对结果的处理与新一轮线路。
else :
#实验未运行成功,需要后继重新提交等处理
print("实验运行异常,需要重新提交或运行")
利用线路传参和批量提交可以大幅加速固定线路,但参数不同的批量实验。
#以下为线路传参与批量提交的结合示例。
#在线路中预置{x}表述待传入参数
qcis_circuit = '''
RX Q0 {N1}
RX Q6 {N2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
values=[[0.1,0.2],[0.2,0.1]]
qcis_circuit=account.assign_parameters(circuits=[qcis_circuit]*2, parameters=[['N1','N2']]*2, values=values)
print(qcis_circuit)
#注意此时qcis_circuit已经被带入参数,成为具体的无动态参数线路。
#或者直接使用submit_job函数直接带入参数
qcis_circuit = '''
RX Q0 {N1}
RX Q6 {N2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
values=[[0.1,0.2],[0.2,0.1]]
query_id = account.submit_job(circuit=[qcis_circuit]*2,parameters=[['N1','N2']]*2, values=values, num_shots=1000)
print(query_id)
p1 = []
if query_id:
#query_id超过50项时,要拆分,成50个一组来读取,所以按照50个一组来批量提交效率较好。
result=account.query_experiment(query_id, max_wait_time=360000)
for query_res in result:
# 实验结果转换,概率转换,读取矫正
# results = account.readout_data_to_state_probabilities_whole(query_res)
prob = account.probability_calibration(query_res)
prob = account.probability_correction(prob)
p1.append(prob)
print(p1)