新功能和重要更新
- 优化 CPU 测量算法
针对 CPUQVM 和 GPUQVM 进行了优化,尤其是对于大规模量子比特测量(当测量节点位于末尾时),执行时间显著减少。
一个非常明显的示例表明,操作速度得到了显著提升。
prog = QProg()
prog << H(0)
for i in range(21):
prog << CNOT(i, i + 1)
for i in range(22):
prog << measure(i, i)
machine = CPUQVM()
machine.run(prog, 10000)
measure_result = machine.result().get_counts()
print(measure_result)
输出如下:
{'0000000000000000000000': 4957, '1111111111111111111111': 5043}
- 量子云计算服务
对于针对真实量子芯片的任务,用户在提交任务时可以选择以二进制流格式传输量子程序,相较于原有方式,通信效率更高。
现有 run 接口增加了额外参数,其他用法与之前版本保持一致。
import time
prog = QProg()
prog << H(0)
prog << CNOT(0, 1)
prog.append(measure(0,0))
api_key = "302e020030100602a8648ce3020160528100050204615ad5e"
service = QCloudService(api_key)
backend = service.backend("WK_C102_400")
options = QCloudOptions()
job = backend.run(prog, 1000, options, True)
while True:
status = job.status()
if status == JobStatus.FINISHED:
break
print(job.job_id()," wait for finished.")
time.sleep(2)
result = job.result()
print(result.get_probs())
输出如下:
- 量子云集群任务的标准化调整
针对部分振幅和单个振幅接口进行了标准化调整。
集群任务提交接口在参数上略有不同:
- 部分振幅接口除
QProg 外,还对应一个振幅数组。
- 单个振幅接口除
QProg 外,还对应一个单振幅值。
查询接口完全相同,都使用 QCloudResult.get_amplitudes(),返回一个数组。
prog = QProg(6)
prog << H(0)
prog << CNOT(1, 2)
prog << RY(0, 0.34)
prog << RX(1, 0.98)
api_key = "302e020100301006094453a3c8a/6327"
service = QCloudService(api_key)
service.setup_logging()
single_amplitude_backend = service.backend("single_amplitude")
single_amplitude_job = single_amplitude_backend.run(prog, "0")
print(single_amplitude_job.result().get_amplitudes())
partial_amplitude_backend = service.backend("partial_amplitude")
partial_amplitude_job = partial_amplitude_backend.run(prog, ["0","1","2"])
print(partial_amplitude_job.result().get_amplitudes())
输出如下:
{'0': (0.5093563616148238+0j)}
{'0': (0.5093563616148238+0j), '1': (0.7204633002944995+0j), '2': (0.5093563616148238+0j)}
**注意**:集群任务支持异步操作,但不支持批量提交多个线路。
def pauli_x_error(prob: float) -> QuantumError
def pauli_y_error(prob: float) -> QuantumError
def pauli_z_error(prob: float) -> QuantumError
def phase_damping_error(prob: float) -> QuantumError
def amplitude_damping_error(prob: float) -> QuantumError
def decoherence_error(arg0: float, arg1: float, arg2: float) -> QuantumError
def depolarizing_error(prob: float) -> QuantumError
示例程序如下:
from pyqpanda3.core import QCircuit,QProg,H,RX,RY,CNOT,measure,GateType
circuit = QCircuit(3)
circuit << H(0)
circuit << RY(1, 0.3)
circuit << RY(2, 2.7)
circuit << RX(0, 1.5)
circuit << CNOT(0, 1)
circuit << CNOT(1, 2)
prog = QProg()
prog.append(circuit)
prog.append(measure(0, 0))
prog.append(measure(1, 1))
prog.append(measure(2, 2))
model = NoiseModel()
model.add_all_qubit_quantum_error(pauli_x_error(0.5),GateType.RX)
model.add_all_qubit_quantum_error(pauli_x_error(0.9),GateType.H)
machine = GPUQVM()
machine.run(prog, 1000, model)
measure_result = machine.result().get_counts()
print(measure_result)
输出如下:
{'011': 466, '001': 3, '100': 468, '111': 22, '000': 17, '101': 13, '010': 11}
(1)使用CPUQVM计算线路在指定哈密顿量的系统上的期望值(pyqpanda3.core)
原始接口
pyqpanda3.core.CPUQVM.expval_hamiltonian的API文档
expval_hamiltonian(self: core.CPUQVM, prog: core.QProg, hamiltonian: QPanda3::Hamiltonian, shots: int = 1000, noise_model: core.NoiseModel = <core.NoiseModel object at 0x000002548518BB30>)
新接口
pyqpanda3.core.expval_hamiltonian的API文档
expval_hamiltonian(node: core.QProg, hamiltonian: QPanda3::Hamiltonian, shots: int = 1, model: core.NoiseModel = <core.NoiseModel object at 0x0000026A734CB370>, used_threads: int = 4, backend: str = \'CPU\')
示例代码
from pyqpanda3.core import CPUQVM, QProg, S, BARRIER,expval_hamiltonian
def test_expectation2():
qvm = CPUQVM()
prog = QProg()
prog << S(0)
prog << BARRIER([0, 1, 2])
"""The qubits used in qprog should be consistent with the qubits in the Pauli operator. The simulator determines the qubits that should be included in the quantum system based on the qbits in QProg, which are three quantum #bits in this case"""
Ham = Hamiltonian({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", Ham)
try:
res = qvm.expval_hamiltonian(prog, Ham)
print("res:", res)
res2 = expval_hamiltonian(prog,Ham,backend='CPU')
print('res2:',res2)
except Exception as e:
print(e)
if __name__ == "__main__":
test_expectation2()
输出如下
without I:
{ qbit_total = 3, pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, } }
res: 0.0
res2: 0.0
Warrning! This interface will be deprecated in the future. Please use the new interface expval_hamiltonian (a global interface exported by pyqpanda3.core).
(2)使用GPUQVM计算线路在指定哈密顿量的系统上的期望值(pyqpanda3.core)
新接口
pyqpanda3.core.expval_hamiltonian的API文档
expval_hamiltonian(node: core.QProg, hamiltonian: QPanda3::Hamiltonian, shots: int = 1, model: core.NoiseModel = <core.NoiseModel object at 0x0000026A734CB370>, used_threads: int = 4, backend: str = \'CPU\')
示例代码
from pyqpanda3.core import QProg, S, BARRIER,expval_hamiltonian
def test_expectation2():
prog = QProg()
prog << S(0)
prog << BARRIER([0, 1, 2])
"""The qubits used in qprog should be consistent with the qubits in the Pauli operator. The simulator determines the qubits that should be included in the quantum system based on the qbits in QProg, which are three quantum #bits in this case"""
Ham = Hamiltonian({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", Ham)
try:
res2 = expval_hamiltonian(prog,Ham,backend='GPU')
print('res2:',res2)
except Exception as e:
print(e)
if __name__ == "__main__":
test_expectation2()
输出如下
without I:
{ qbit_total = 3, pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, } }
res2: 0.0
(3) 使用CPUQVM计算线路在指定哈密顿量的系统上的期望值(pyqpanda3.vqcircuit)
原始接口
expval_hamiltonian(self:
pyqpanda3.vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, exp_type: pyqpanda3.vqcircuit.ExpectationType = <ExpectationType.THEORETICAL: 0>)
expval_hamiltonian(self:
pyqpanda3.vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], exp_type: pyqpanda3.vqcircuit.ExpectationType = <ExpectationType.THEORETICAL: 0>)
新接口
pyqpanda3.vqcircuit.VQCResult.expval_hamiltonian的API文档
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, used_threads: int = 4, backend: str = 'CPU')
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], used_threads: int = 4, backend: str = 'CPU')
(4) 使用GPUQVM计算线路在指定哈密顿量的系统上的期望值(pyqpanda3.vqcircuit)
新接口
pyqpanda3.vqcircuit.VQCResult.expval_hamiltonian的API文档
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, used_threads: int = 4, backend: str = 'CPU')
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], used_threads: int = 4, backend: str = 'CPU')
(5) 使用CPUQVM计算线路在指定泡利算子的系统上的期望值(pyqpanda3.core)
原始接口
pyqpanda3.CPUQVM.expval_pauli_operator的API文档
新接口
pyqpanda3.core.expval_pauli_operator的API文档
expval_pauli_operator(node: core.QProg, pauli_operator: QPanda3::PauliOperator, shots: int = 1, model: core.NoiseModel = <core.NoiseModel object at 0x0000026A734CB5B0>, used_threads: int = 4, backend: str = \'CPU\')
示例代码
from pyqpanda3.core import CPUQVM, QProg, S, BARRIER,expval_pauli_operator
def test_expectation2():
qvm = CPUQVM()
prog = QProg()
prog << S(0)
prog << BARRIER([0, 1, 2])
"""The qubits used in qprog should be consistent with the qubits in the Pauli operator. The simulator determines the qubits that should be included in the quantum system based on the qbits in QProg, which are three quantum #bits in this case"""
op = PauliOperator({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", op)
try:
res = qvm.expval_pauli_operator(prog, op)
print("res:", res)
res2 = expval_pauli_operator(prog,op,backend='CPU')
print('res2:',res2)
except Exception as e:
print(e)
if __name__ == "__main__":
test_expectation2()
输出如下
without I:
{ qbit_total = 3, pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, } }
res: 0.0
res2: 0.0
Warrning! This interface will be deprecated in the future. Please use the new interface expval_pauli_operator (a global interface exported by pyqpanda3.core).
(6) 使用GPUQVM计算线路在指定泡利算子的系统上的期望值(pyqpanda3.core)
新接口
pyqpanda3.core.expval_pauli_operator的API文档
expval_pauli_operator(node: core.QProg, pauli_operator: QPanda3::PauliOperator, shots: int = 1, model: core.NoiseModel = <core.NoiseModel object at 0x0000026A734CB5B0>, used_threads: int = 4, backend: str = \'CPU\')
示例代码
from pyqpanda3.core import QProg, S, BARRIER,expval_pauli_operator
def test_expectation2():
prog = QProg()
prog << S(0)
prog << BARRIER([0, 1, 2])
"""The qubits used in qprog should be consistent with the qubits in the Pauli operator. The simulator determines the qubits that should be included in the quantum system based on the qbits in QProg, which are three quantum #bits in this case"""
op = PauliOperator({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", op)
try:
res2 = expval_pauli_operator(prog,op,backend='GPU')
print('res2:',res2)
except Exception as e:
print(e)
if __name__ == "__main__":
test_expectation2()
输出如下
without I:
{ qbit_total = 3, pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, } }
res2: 0.0
(7) 使用CPUQVM计算线路在指定泡利算子的系统上的期望值(pyqpanda3.vqcircuit)
原始接口
expval_pauli_operator(self:
pyqpanda3.vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, exp_type: pyqpanda3.vqcircuit.ExpectationType = <ExpectationType.THEORETICAL: 0>)
expval_pauli_operator(self:
pyqpanda3.vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], exp_type: pyqpanda3.vqcircuit.ExpectationType = <ExpectationType.THEORETICAL: 0>)
新接口
pyqpanda3.vqcircuit.VQCResult.expval_pauli_operator的API文档
expval_pauli_operator(self: vqcircuit.VQCResult, pauli_operator: QPanda3::PauliOperator, shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, used_threads: int = 4, backend: str = 'CPU')
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], used_threads: int = 4, backend: str = 'CPU')
(8) 使用GPUQVM计算线路在指定泡利算子的系统上的期望值(pyqpanda3.vqcircuit)
pyqpanda3.vqcircuit.VQCResult.expval_pauli_operator的API文档
新接口
expval_pauli_operator(self: vqcircuit.VQCResult, pauli_operator: QPanda3::PauliOperator, shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, used_threads: int = 4, backend: str = 'CPU')
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], used_threads: int = 4, backend: str = 'CPU')
编译模块增加对Oracle门的处理
在编译模块下的Transpiler和decompose都支持对Oracle门的支持 示例代码如下:
prog = QProg()
matrix = CNOT(0, 1).matrix()
prog << Oracle([0, 1], matrix)
t = Transpiler()
prog2 = t.transpile(prog, [], {}, 2, ['RX', 'RY', 'RZ', 'CNOT'])
prog3 = decompose(prog, ['RX', 'RY', 'RZ', 'CNOT'])
print(prog2)
print(prog3)
对量子线路的编译和分解可以分解到指定的门集
在编译模块下的Transpiler和decompose都支持分解到指定的基础门集。 示例代码如下:
prog = QProg()
prog << random_qcircuit(list(range(3)),10,['RX','RY','RZ','U3','H','SWAP','CNOT'])
t = Transpiler()
basic_gates = ['RX', 'RY', 'RZ', 'CP']
prog2 = t.transpile(prog, [], {}, 2,basic_gates=basic_gates )
prog3 = decompose(prog, basic_gates=basic_gates)
print(prog2)
print(prog3)
增加将矩阵分解到指定的门集
在编译模块下的decompose接口增加将矩阵分解到指定的基础门集的函数重载。 示例代码如下:
import numpy as np
A = np.random.rand(4, 4) + 1j * np.random.rand(4, 4)
Q, R = np.linalg.qr(A)
basic_gates = ['RX', 'RY', 'RZ', 'CP']
prog = decompose(Q, basic_gates=basic_gates)
print(prog)
增加pauli算子分组功能
在PauliOperator类中增加group_commuting接口,该接口将对易的pauli算子分到一组。 示例代码如下:
import random
def generate_random_pauli_operator(num_qubits, num: int = 10, max_coeff=1.0):
"""
生成一组随机的Pauli算符。
参数:
num_operators (int): 要生成的Pauli算符数量。
num_qubits (int): 作用的量子比特数量。
max_coeff (float): 系数的最大值(默认为1.0)。
返回:
list[PauliOperator]: 生成的随机Pauli算符列表。
"""
pauli_symbols = ["I", "X", "Y", "Z"]
pauli_string_list = []
coefficient_list = []
for _ in range(num):
pauli_string = "".join(random.choice(pauli_symbols) for i in range(num_qubits))
real_part = random.uniform(-max_coeff, max_coeff)
imag_part = random.uniform(-max_coeff, max_coeff)
coefficient = complex(real_part, imag_part)
pauli_string_list.append(pauli_string)
coefficient_list.append(coefficient)
operator = PauliOperator(pauli_string_list, coefficient_list, True)
return operator
operator = generate_random_pauli_operator(3, 30)
operators: list[PauliOperator] = operator.group_commuting(True)
- 增加量子态制备功能,可通过Encode类进行调用,其支持的编码方式与QPanda2支持一致。具体使用见量子态编码章节。
- 根据QProg对象生成QASM2.0指令字符串
convert_qprog_to_qasm的API文档
示例代码
prog = QProg()
prog << RX(0,3.1415926)<<CNOT(0,2)
qasm = convert_qprog_to_qasm(prog,10)
print('qasm:\n',qasm)
输出为
qasm:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
creg c[0];
rx(3.1415926000) q[0];
cx q[0],q[2];
变更前,不同的量子比特寄存器数组名称都指向名为“q”的寄存器数组。
变更后,不同的量子比特寄存器数组名称标识不同的寄存器起始索引和元素数量。
convert_qasm_string_to_qprog的API文档
示例代码
qasm='''
OPENQASM 2.0;
include "qelib1.inc";
qreg q1[2];
qreg q2[2];
creg c[0];
x q1[0];
y q1[1];
z q2[0];
s q2[1];
'''
prog:QProg = convert_qasm_string_to_qprog(qasm)
print('prog:\n',prog)
print('used qbits in prog:',prog.qubits())
实现变更前,输出为:
prog:
┌─┐ ┌─┐
q_0: |0>─┤X├ ┤Z├
├─┤ ├─┤
q_1: |0>─┤Y├ ┤S├
└─┘ └─┘
c : / ═
used qbits in prog: [0, 1]
实现变更后,输出为:
prog:
┌─┐
q_0: |0>─┤X├
├─┤
q_1: |0>─┤Y├
├─┤
q_2: |0>─┤Z├
├─┤
q_3: |0>─┤S├
└─┘
c : / ═
used qbits in prog: [0, 1, 2, 3]
已修复的 Bug
- 解决了在 macOS 上运行
pyqpanda3 时偶尔出现的崩溃和异常问题。
- 解决在构造PauliOperator对象时,某些特殊情况下合并一些泡利项时出现的错误问题。
- 解决从QASM生成QProg对象时解析门错误的问题。
优化
- 通过集成
mimalloc 库优化了 CPUQVM 的模拟性能,使得全振幅模拟速度相比之前提升约 **30%**。
- 优化量子线路的内部实现,以便在具有指定泡利算子或哈密顿量的量子系统上进行相应的计算。