0.3.5
新功能和重要的更新
1.新增量子态、量子线路和概率分布可视化模块。
新增 pyqpanda3.visualization 模块,提供 Bloch 球绘制、量子态可视化(city 图、密度矩阵)、概率分布图表、量子线路绘制(text/pic/latex)以及线路统计功能。
from pyqpanda3 import visualization
# 线路绘制
from pyqpanda3.core import H, X, CNOT, measure, QProg
prog = QProg()
prog << H(0) << X(1) << CNOT(0, 1) << measure(0, 0) << measure(1, 1)
print(prog.draw())
# 量子态可视化
from pyqpanda3.core import H, CNOT, measure, QProg, CPUQVM
import numpy as np
qvm = CPUQVM()
prog = QProg()
prog << H(0) << CNOT(0, 1)
qvm.run(prog)
state = qvm.get_qstate()
from pyqpanda3 import visualization
visualization.plot_state(state, kind='city', title='State City Plot')2.改进 QCloudResult 错误处理——错误现在存储在结果中,而非抛出异常。
此前,云任务失败时会抛出未处理的异常。现在,错误存储在 QCloudResult 中,可通过 error_message() 和 job_id() 方法获取。
result = job.result()
if result.error_message():
print(f"Job {result.job_id()} failed: {result.error_message()}")3.ECHO 门现在支持可选的持续时间参数。
ECHO 门接受一个可选的 param 参数(默认为 0.0),用于指定持续时间。
from pyqpanda3.core import ECHO
gate = ECHO(0, param=1.5)4.新增 QCloudResult 的 timing_info() 方法。
新方法返回一个包含量子任务执行时间信息的字典:
qpuRunTime(float):量子芯片运行时间,指任务在量子芯片上实际执行并完成测量所占用的时间,单位毫秒(ms)
result = job.result()
timing = result.timing_info()
print(f"QPU runtime: {timing['qpuRunTime']} ms")5.Linux 平台编译要求 GCC 8.5 及以上版本。
6.Python 版本支持调整为 3.10–3.14,不再支持 Python 3.9。
Bug 修复
5.修复 QProg.remap() 在重映射前未展平嵌套程序的问题。
此前,对包含子线路或条件块的程序调用 remap() 可能产生错误的量子比特/经典比特映射。现在程序会先进行展平处理。
6.修复 VF2 子图匹配在稀疏图拓扑下的错误。
转换器的初始量子比特布局在处理非连续量子比特索引或断开节点的线路时可能失败,现已修复。
7.修复路由阶段对未映射量子比特和 BARRIER 门的处理问题。
包含 BARRIER 门或不属于 VF2 映射的辅助量子比特的线路现在可以正确编译。
8.转换器在芯片拓扑没有连接边时自动跳过路由。
对无约束目标(空边列表)的编译现在可以成功完成,不会报错。
9.修复超过 8 个量子比特时测量结果的十六进制/二进制转换问题。
来自云后端的较大量子比特数量的测量结果现在可以生成正确的概率分布。
10.增强 QCloud 错误报告,包含任务 ID 信息。
当 QCloud 任务结果请求失败时,错误消息现在包含任务 ID,便于调试和问题追踪。改进了错误处理机制,提供更详细的错误信息。
11.修复大比特系统(32+ 量子比特)的 QCloud 结果计数不匹配问题。
修复了 QCloud 在大比特系统(32 个量子比特或更多)中返回的结果数量与进制转换后的结果数量不匹配的问题。以前,例如当量子云返回 4000 条结果时,结果对象中只有 2600 条可用。此问题已解决。
from pyqpanda3.core import H, measure, QProg
from pyqpanda3.qcloud import QCloudService, QCloudOptions, QCloudJob
prog = QProg()
prog << H(0) << measure(0, 0) << measure(1, 1)
# 从 https://account.originqc.com.cn/ 获取您的真实 API token
api_key = "your_api_key"
service = QCloudService(api_key=api_key)
job = QCloudJob("task_id")
result = job.result()
for result_list in result.get_probs_list():
print(result_list)12.修复 measure() 接口传递错误 cbits 参数的问题。
measure() 函数此前错误地将 qubits 同时作为量子比特和经典比特参数传递。现已修正为正确使用指定的 cbits。
13.修复 IDLE 门参数编码/解码问题。
- 修复了 IDLE 门参数使用角度公式进行错误解码的问题。
- 将 IDLE 门参数范围从 16 位扩展到 32 位(0–4294967295),使用双 uint64 编码。
- IDLE 门参数 ≤ 65535 使用单个 uint64;参数 > 65535 使用双 uint64 并带有恢复机制。
14.修复在无 GPU 机器上使用噪声模型时 expval_hamiltonian 和 expval_pauli_operator 的错误。
修复了在同时指定噪声模型和后端类型时,期望值计算在没有 GPU 的机器上会失败的问题。
15.修复 decompose 对 1–2 量子比特矩阵的错误。
decompose 函数此前会对 1–2 量子比特的矩阵错误地排序量子比特索引。现在对这些情况跳过排序。
16.修复 profiling 模块在空线路上的除零错误。
profiling 模块(QCircuitFeatures)在计算空线路的连通性、活性、并行度、纠缠度或深度指标时可能因除零而崩溃。这些边界情况现已正确处理。
17.修复转译器中 BARRIER 门的映射错误。
修复了转译器中多个与 BARRIER 相关的 bug:VF2 子图匹配对稀疏图拓扑的失败、路由传递对未映射量子比特和 BARRIER 门的处理、以及 DAG 构建中 BARRIER 门的错误。包含 BARRIER 门或不在 VF2 映射中的辅助量子比特的线路现在可以正确编译。
18.修复可视化模块的测量支持和 LaTeX 输出。
改进了可视化模块,使其正确处理线路图中的测量门。修复了 LaTeX 输出以生成正确的线路表示并支持保存到文件。线路分层算法现在使用顺序分层来保持测量的正确时序。
19.修复 GPU 代码在 CUDA 13.2 下的编译问题。
解决了在 CUDA Toolkit 13.2 下编译 GPU 量子虚拟机模块时的编译错误。
20.修复 transpile Python 接口传递 ChipBackend 的类型不匹配问题。
transpile 函数的 Python 绑定此前错误地传递 ChipBackend 值,导致类型错误。现已修正。
21.修复 Pybinder 所有 .def() 绑定的返回值策略。
为所有 Pybinder .def() 调用添加了显式的 py::return_value_policy::automatic,防止 Python 代码通过绑定访问 C++ 对象时可能出现的内存管理问题。
破坏性变更
QCloudResult 构造函数现在需要两个参数。
QCloudResult 构造函数从 QCloudResult(result_string) 变更为 QCloudResult(result_string, job_id_str)。在大多数情况下,QCloudResult 对象是通过 QCloudJob.result() 或 QCloudJob.query() 获取的,而非直接构造,因此不会影响大多数用户。
API 变更
expval_hamiltonian 和 expval_pauli_operator 参数重命名:node → prog。
expval_hamiltonian 和 expval_pauli_operator 的第一个参数已从 node 重命名为 prog,以提高可读性。这仅影响关键字参数用法;位置参数用法不受影响。
# 之前的位置参数用法(仍然有效):
expval_hamiltonian(prog, ham, shots=1000)
# 更新后的关键字参数用法:
expval_hamiltonian(prog=prog, hamiltonian=ham, shots=1000)QGate.dagger() 和 QCircuit.dagger() 现在返回新副本,而非原地修改。
此前,dagger() 会就地修改门/线路并返回引用。现在改为返回新副本,原始对象不会被修改。依赖原地修改的代码需要重新赋值结果:
# 之前(原地修改):
gate.dagger() # gate 已变为 dagger
# 现在(返回新副本):
gate = gate.dagger() # 必须重新赋值QGate.control() 和 QCircuit.control() 现在返回新实例,而非原地修改。
此前,control() 会就地修改门/线路并返回引用。现在改为返回新实例,原始对象不会被修改。依赖原地修改的代码需要重新赋值结果:
# 之前(原地修改):
gate.control(0) # gate 已变为受控门
# 现在(返回新实例):
gate = gate.control(0) # 必须重新赋值ChipBackend 从 qcloud 模块迁移至 transpilation 模块。
ChipBackend 现在从 pyqpanda3.transpilation 导出,而非 pyqpanda3.qcloud。请更新导入语句:
# 之前:
from pyqpanda3.qcloud import ChipBackend
# 现在:
from pyqpanda3.transpilation import ChipBackend