新功能和重要的更新
1.变分量子线路支持结构复用和表达式作为参数化门的门参数
def get_vqc1():
vqc = VQCircuit()
vqc.set_Param([2])
p0 = vqc.Param([0],'p0')
p1 = vqc.Param([1],'p1')
e = 3.14*p0*p1+p1+4
vqc << X(0)
vqc << RX(0,3.14)
vqc << RY(0,e)
return vqc
def get_vqc2():
vqc2 = VQCircuit()
vqc2.set_Param([3])
P0 = vqc2.Param([0],'P0')
P1 = vqc2.Param([1],'P1')
P2 = vqc2.Param([2],'P2')
cir = QCircuit()
cir << Y(0)
vqc2 << cir
vqc1= get_vqc1()
vqc2.append(vqc1,[(vqc1.Param([0]),vqc2.Param([0])),(vqc1.Param([1]),vqc2.Param([1]))])
return vqc2
vqc1 = get_vqc1()
print('vqc1:')
vqc1.display_ansatz()
print()
vqc2 = get_vqc2()
print('vqc2:')
vqc2.display_ansatz()
示例代码输出结果
vqc1:
X q[0]
RX q[0],(3.14000000)
RY q[0],(((3.14*p0*p1+p1)+4))
vqc2:
Y q[0]
X q[0]
RX q[0],(3.14000000)
RY q[0],(((3.14*P0*P1+P1)+4))
2.变分量子线路支持梯度计算,提供同时获得期望值和梯度值的接口
def get_vqc():
vqc = VQCircuit()
vqc.set_Param([2])
vqc << RX(0,vqc.Param([0]))
vqc << RY(1,vqc.Param([1]))
return vqc
def get_param_val():
param_val = [2.14,3.14]
return param_val
def get_hamiltonian():
paulis = [
('YY', [0, 1], (12.36525580995888 + 14.85172018664403j)),
('YX', [0, 1], (12.920260765526914 + 26.29613065236354j))
]
return Hamiltonian(paulis)
def get_gradient(vqc,param_val,ham):
return vqc.get_gradients(params=param_val,observable=ham,diff_method=DiffMethod.ADJOINT_DIFF)
def get_gradient2(vqc:VQCircuit,param_val,ham):
return vqc.get_gradients_and_expectation(params=param_val,observable=ham,diff_method=DiffMethod.ADJOINT_DIFF)
vqc = get_vqc()
param_val = get_param_val()
ham = get_hamiltonian()
res1 = get_gradient(vqc,param_val,ham)
res2 = get_gradient2(vqc,param_val,ham)
print('res1:',res1)
print('res1 gradient:',res1.gradients())
print('res2:',res2)
print('res2 gradient:',res2.gradients())
示例代码输出结果
res1: {gradient(double):{Parameter.at([0]):0.0110905,Parameter.at([1]):23.3932}}
res1 gradient: [0.011090474368968659, 23.39317090007428]
res2: (gradient and expectation){"expectation":-0.017333,"gradients":{Parameter.at([0]):0.0110905,Parameter.at([1]):23.3932}}
res2 gradient: [0.011090474368968659, 23.39317090007428]
3.增加对SQISWAP、ECHO、IDLE、CRX、CRY、CRZ的支持
ir_str="""
QINIT 2
CREG 1
CRX q[0],q[1],(3.14000000)
CRY q[0],q[1],(4.14000000)
CRZ q[0],q[1],(5.14000000)
ECHO q[0]
SQISWAP q[0],q[1]
IDLE q[0],(3.66666006000)
"""
prog = QProg(ir_str)
ir_2 = prog.originir(8)
print('ir_2:\n',ir_2)
prog3 = QProg()
prog3 << CRX(0,1,30.14)
prog3 << CRY(0,1,40.14)
prog3 << CRZ(0,1,50.14)
prog3 << ECHO(0)
prog3 << SQISWAP(0,1)
prog3 << IDLE(0,30.66666)
ir_3 = prog3.originir(8)
print('ir_3:\n',ir_3)
vqc = VQCircuit()
vqc.set_Param([0])
vqc << CRX(0,1,30.14)
vqc << CRY(0,1,40.14)
vqc << CRZ(0,1,50.14)
vqc << ECHO(0)
vqc << SQISWAP(0,1)
vqc << IDLE(0,30.66666)
cir = vqc([]).at([0])
print('cir ir:\n',cir.originir(8))
示例代码输出结果
ir_2:
QINIT 2
CREG 1
CONTROL q[0]
RX q[1],(3.14000000)
ENDCONTROL
CONTROL q[0]
RY q[1],(4.14000000)
ENDCONTROL
CONTROL q[0]
RZ q[1],(5.14000000)
ENDCONTROL
ECHO q[0]
SQISWAP q[0],q[1]
IDLE q[0],(3.00000000)
ir_3:
QINIT 2
CREG 1
CONTROL q[0]
RX q[1],(30.14000000)
ENDCONTROL
CONTROL q[0]
RY q[1],(40.14000000)
ENDCONTROL
CONTROL q[0]
RZ q[1],(50.14000000)
ENDCONTROL
ECHO q[0]
SQISWAP q[0],q[1]
IDLE q[0],(30.00000000)
cir ir:
QINIT 2
CREG 1
CONTROL q[0]
RX q[1],(30.14000000)
ENDCONTROL
CONTROL q[0]
RY q[1],(40.14000000)
ENDCONTROL
CONTROL q[0]
RZ q[1],(50.14000000)
ENDCONTROL
ECHO q[0]
SQISWAP q[0],q[1]
IDLE q[0],(30.00000000)
4.新增ChipBackend类,这个类保存芯片后端用来编译的信息,新增transpile接口,通过传入ChipBackend参数将量子程序编译到指定芯片后端。同时QCloud增加获取云平台芯片后端的功能。 使用示例如下:
import time
apikey = ''
def test_backend():
print("test_get_topo")
service = QCloudService(apikey)
backends = service.backends()
for backend in backends:
print(backend)
backend_wukong = service.backend("WK_C102_400")
backend = backend_wukong.chip_info().get_chip_backend()
all_qbits = list(range(10))
circuit = random_qcircuit(all_qbits, 100, ["RX", "RY", "RZ", "H", "U1", "U2", "U3", "CP", "CNOT", "SWAP"])
prog_1 = QProg()
prog_1 << circuit
for i in all_qbits:
prog_1 << measure(i, i)
transpiler = Transpiler()
print("Enter transpile")
prog_2 = transpiler.transpile(prog_1, backend, {}, 2)
if __name__ == "__main__":
test_backend()
5.新增QProg导出量子芯片指令的接口,量子芯片指令是可以直接发往芯片运行的文件。目前该接口的指令格式仅支持本源量子计算机。 使用该接口需要保证量子程序中已经全部是芯片的基础指令(RPhi、CZ、Measure和ECHO)。 to_instruction有三个参数,第一个参数是指定的芯片后端,第二个参数是转指令过程中qubit的偏移量,第三个参数是是否使用pattern对指令进行分层。
这个接口可以配合to_instruction和run_instruction使用,将一个量子程序编译到云平台的指定芯片上,转成指令文件,运行到芯片上。 以下是一个完整流程的示例代码:
api_key = ""
def run_instruction_test(prog_1: QProg):
service = QCloudService(api_key)
backend_wukong = service.backend("WK_C102_400")
chip_info = backend_wukong.chip_info()
backend: ChipBackend = chip_info.get_chip_backend()
transpiler = Transpiler()
prog_2 = transpiler.transpile(prog_1, backend, {}, 2)
use_pattern = False
ins = prog_2.to_instruction(backend, 1, use_pattern)
options = QCloudOptions()
options.set_mapping(False)
options.set_amend(False)
job = backend_wukong.run_instruction([ins], 1000, options)
result = job.result()
print(result.get_probs_list())
if __name__ == "__main__":
ir = """
QINIT 8
CREG 8
H q[0]
H q[1]
H q[2]
H q[3]
H q[4]
H q[5]
CNOT q[0],q[4]
RZ q[4],(0.93926449)
CNOT q[0],q[4]
CNOT q[0],q[5]
RZ q[5],(0.42459902)
CNOT q[0],q[5]
CNOT q[1],q[4]
RZ q[4],(0.88779795)
CNOT q[1],q[4]
CNOT q[1],q[5]
RZ q[5],(0.46319893)
CNOT q[1],q[5]
CNOT q[2],q[5]
RZ q[5],(1.132264)
CNOT q[2],q[5]
CNOT q[3],q[5]
RZ q[5],(0.86206467)
CNOT q[3],q[5]
RX q[0],(2.3543679)
RX q[1],(2.3543679)
RX q[2],(2.3543679)
RX q[3],(2.3543679)
RX q[4],(2.3543679)
RX q[5],(2.3543679)
MEASURE q[0],c[0]
MEASURE q[1],c[1]
MEASURE q[2],c[2]
MEASURE q[3],c[3]
MEASURE q[4],c[4]
MEASURE q[5],c[5]
"""
prog_1 = convert_originir_string_to_qprog(ir)
run_instruction_test(prog_1)
运行结果如下:
[{'0x0': 0.077, '0x1': 0.007, '0x10': 0.032, '0x11': 0.005, '0x12': 0.043, '0x13': 0.006,
'0x14': 0.009, '0x15': 0.002, '0x16': 0.018, '0x17': 0.005, '0x18': 0.022, '0x19': 0.002,
'0x1a': 0.018, '0x1b': 0.005, '0x1c': 0.018, '0x1d': 0.002, '0x1e': 0.025, '0x1f': 0.003,
'0x2': 0.084, '0x20': 0.036, '0x21': 0.004, '0x22': 0.039, '0x23': 0.003, '0x24': 0.013,
'0x26': 0.011, '0x27': 0.006, '0x28': 0.03, '0x29': 0.004, '0x2a': 0.024, '0x2b': 0.002,
'0x2c': 0.016, '0x2d': 0.006, '0x2e': 0.029, '0x2f': 0.006, '0x3': 0.018, '0x30': 0.014,
'0x31': 0.003, '0x32': 0.019, '0x33': 0.005, '0x34': 0.006, '0x35': 0.002, '0x36': 0.009,
'0x37': 0.002, '0x38': 0.009, '0x39': 0.002, '0x3a': 0.012, '0x3b': 0.001, '0x3c': 0.008,
'0x3d': 0.001, '0x3e': 0.016, '0x3f': 0.001, '0x4': 0.023, '0x5': 0.002, '0x6': 0.03,
'0x7': 0.012, '0x8': 0.042, '0x9': 0.008, '0xa': 0.042, '0xb': 0.004, '0xc': 0.038,
'0xd': 0.005, '0xe': 0.046, '0xf': 0.008}]
6.量子云服务添加指令集任务,可以将量子程序编译到指定后端支持的指令集上,然后直接运行指令集任务
prog = QProg()
prog << CZ(9, 10)
prog << CZ(10, 11)
prog.append(measure(9,9))
online_key = "api_key"
service = QCloudService(online_key)
service.setup_logging()
backend = service.backend("WK_C102_400")
options = QCloudOptions()
options.set_amend(False)
ins = prog.to_instruction(backend.chip_backend())
job = backend.run_instruction([ins,ins], 1000, options)
chip_info = backend.chip_info()
result = job.result()
print(result.get_probs_list())
输出如下:
[{'0x0': 0.7249999761581421, '0x1': 0.2749999940395355}, {'0x0': 0.75, '0x1': 0.25}]
问题修复
1.修复在多线程程序中进行OrginIR转换时出现的偶发崩溃问题
2.修复多控门在超过14比特触发simd优化计算时的报错问题
3.优化多控门分解算法,提高分解效率
4.提升transpile接口性能