Skip to content

0.4.0 ​

pyqpanda3 0.4.0 是一次面向硬件工作流的更新。相关提交之间的主线是:在云端芯片元数据、保真度感知转译、原生指令 JSON、指令还原和时序可视化之间建立连续链路。

1. QCloud 芯片元数据 -> 调度指令 -> 结果回收 ​

0.4.0 中 QCloud 更新的重点不只是"能返回更多字段",而是把真实硬件执行前后的链路打通:芯片元数据生成 ChipBackend,ChipBackend 驱动保真度布局和指令时序,带调度的指令流可以先在本地可视化,再提交到 QCloud,结果字段还能回到本地程序和图形工具中。

需要云端凭据的示例:

python
import os

from pyqpanda3.core import CZ, H, QProg, instruction_to_qprog, measure
from pyqpanda3.qcloud import QCloudOptions, QCloudService
from pyqpanda3.transpilation import Transpiler, decompose
from pyqpanda3.visualization import draw_time_scheduling

service = QCloudService(os.environ["QPANDA_QCLOUD_API_KEY"])
backend = service.backend(os.environ.get("QPANDA_QCLOUD_BACKEND", "WK_C180"))

chip_info = backend.chip_info()
chip_backend = chip_info.get_chip_backend()

prog = QProg()
prog << H(0) << CZ(0, 1) << measure(0, 0) << measure(1, 1)

decomposed = decompose(prog, ["U3", "CZ"])
transpiled = Transpiler().transpile(decomposed, chip_backend, {}, 2, "fidelity")
instruction = transpiled.to_instruction(
    chip_backend,
    offset=1,
    is_scheduling=True,
    compensate_pulse=False,
)
figures = draw_time_scheduling(instruction, backend=chip_backend, output="plotly")

options = QCloudOptions()
options.set_mapping(False)
options.set_optimization(False)
options.set_amend(False)

job = backend.run_instruction([instruction], 1000, options)
result = job.result(keys=["convertQProg", "mappingQprog", "mappingQubit"])

print(chip_backend.single_gate_timing, chip_backend.double_gate_timing)
print(type(figures).__name__)
print("convertQProg" in result)
print("mappingQprog" in result)
print("mappingQubit" in result)

if "convertQProg" in result:
    recovered = instruction_to_qprog(result.instructions(), qubit_offset=1)
    print(type(recovered).__name__)

示例输出形态:

text
40 80
Figure
True
True
True
QProg

本地指令往返示例:

python
import json

from pyqpanda3.core import instruction_to_qprog
from pyqpanda3.visualization import draw_time_scheduling, parse_instruction_schedule

single_stream = [
    {"RPhi": [1, 90.0, 0.0, 0]},
    {"CZ": [1, 2, 40]},
    {"Measure": [[2, 1], 120]},
]

prog = instruction_to_qprog(json.dumps(single_stream), qubit_offset=1)
programs = instruction_to_qprog(
    json.dumps([single_stream, single_stream]),
    qubit_offset=1,
    insert_barrier=False,
)
items = parse_instruction_schedule(single_stream, durations={"RPhi": 40, "CZ": 40})
fig = draw_time_scheduling(single_stream, durations={"RPhi": 40, "CZ": 40})
fig.savefig("schedule-v040.png", dpi=160)

print(type(prog).__name__)
print(type(programs).__name__, len(programs))
print(items[0].name, items[0].end_time)
print("schedule-v040.png")

输出:

text
QProg
list 2
RPhi 40.0
schedule-v040.png

2. 保真度布局 -> 转译 -> 原生指令导出 ​

fidelity_layout() 与 transpile(backend, ..., layout_method="fidelity") 的修复和新增能力应一起使用。fidelity_layout() 根据拓扑和保真度映射计算初始布局;Transpiler().transpile(..., "fidelity") 可以在内部使用同样的布局逻辑;随后 QProg.to_instruction() 将程序导出为后端原生指令,并可选择是否做 CZ 补偿。

python
from pyqpanda3.core import CZ, H, QProg, measure
from pyqpanda3.transpilation import ChipBackend, Transpiler, fidelity_layout

prog = QProg()
prog << H(0) << CZ(0, 1) << measure(0, 0) << measure(1, 1)

backend = ChipBackend()
backend.chip_topology_edges = [[0, 1], [1, 2]]
backend.basic_gates = ["RPhi", "CZ"]
backend.single_gate_fidelity = {0: 0.99, 1: 0.99, 2: 0.99}
backend.readout_fidelity = {0: 0.90, 1: 0.90, 2: 0.99}
backend.double_gate_fidelity = {(0, 1): 0.90, (1, 2): 0.99}

mapping = fidelity_layout(
    prog,
    backend.chip_topology_edges,
    backend.single_gate_fidelity,
    backend.readout_fidelity,
    backend.double_gate_fidelity,
)
transpiled = Transpiler().transpile(prog, backend, {}, 1, "fidelity")

print(mapping)
print(len(transpiled.operations()) > 0)

以上后端配置的输出:

text
{0: 2, 1: 1}
True

导出指令前,先将程序分解到 virtual_z() 支持的门族:

python
import json

from pyqpanda3.core import CZ, H, QProg, measure
from pyqpanda3.transpilation import ChipBackend, decompose, virtual_z

prog = QProg()
prog << H(0) << CZ(0, 1) << measure(0, 0) << measure(1, 1)

backend = ChipBackend()
backend.chip_topology_edges = [[0, 1], [1, 2]]
backend.basic_gates = ["RPhi", "CZ"]
backend.single_gate_timing = 40
backend.double_gate_timing = 80

ready = virtual_z(decompose(prog, ["X1", "RZ", "CZ"]))
instruction_json = ready.to_instruction(
    backend,
    offset=1,
    is_scheduling=True,
    compensate_pulse=False,
)
instructions = json.loads(instruction_json)

print(type(instruction_json).__name__, len(instructions))
print(instructions[0])

输出:

text
str 3
{'RPhi': [1, 270.0, 90.0, 0]}

3. OriginIR -> 协议编码 ​

OriginIR 通信协议更新允许已经生成 OriginIR 的流程直接进入二进制协议层。

python
from pyqpanda3.intermediate_compiler import convert_originir_string_to_qprog
from pyqpanda3.utils import CommProtocolConfig, comm_protocol_encode

config = CommProtocolConfig()
config.shots = 2048

originir = "QINIT 1\nCREG 1\nH q[0]\nMEASURE q[0],c[0]\n"
prog = convert_originir_string_to_qprog(originir)
payload = comm_protocol_encode([prog], config)

print(type(payload).__name__)
print(len(payload) > 0)

示例输出:

text
bytes
True

4. 拓扑感知状态制备 ​

Encode.topology_aware_mps_encode() 可以在连通拓扑约束下生成近似振幅编码线路。

python
from pyqpanda3.core import Encode

data = [0.25] * 16
topology = [[0, 1], [1, 2], [2, 3]]

encoder = Encode()
encoder.topology_aware_mps_encode([0, 1, 2, 3], data, topology, depth=3)

print(type(encoder.get_circuit()).__name__)
print(round(encoder.get_fidelity(data), 6))

输出:

text
QCircuit
1.0

API 变化 ​

Released under the MIT License.