pyqpanda3 v0.4.0 is best understood as a workflow release. The individual APIs are useful on their own, but the real improvement is how they fit together: QCloud chip metadata can become a ChipBackend, that backend can drive fidelity-aware transpilation and instruction timing, the scheduled instruction stream can be drawn before submission, and QCloud result fields can be pulled back into local recovery tools.
From Cloud Calibration to a Submitted Instruction Stream
The new QCloud flow should start from chip metadata, not a hand-written instruction JSON snippet. That single choice keeps topology, fidelity, compensation, and timing consistent across layout, transpilation, visualization, and submission.
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_backend = 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,
)
figure = 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()
print(chip_backend.single_gate_timing, chip_backend.double_gate_timing)
print(type(figure).__name__)
raw = result.origin_data()
print(type(raw).__name__)Example output shape:
40 80
Figure
strThe visible difference for users is that the instruction timing is no longer a magic constant in an example. It comes from the same QCloud ChipBackend that was used to make the layout decision.
Instructions Round-Trip and Draw
The same workflow works locally without cloud access. instruction_to_qprog() rebuilds a program from instruction JSON, while the visualization layer turns the same stream into a timing diagram.
import json
from pyqpanda3.core import instruction_to_qprog
from pyqpanda3.visualization import draw_time_scheduling, parse_instruction_schedule
instruction = [
{"RPhi": [1, 90.0, 0.0, 0]},
{"CZ": [1, 2, 40]},
{"Measure": [[2, 1], 120]},
]
prog = instruction_to_qprog(json.dumps(instruction), qubit_offset=1)
items = parse_instruction_schedule(instruction, durations={"RPhi": 40, "CZ": 40})
fig = draw_time_scheduling(instruction, durations={"RPhi": 40, "CZ": 40})
fig.savefig("schedule-v040.png", dpi=160)
print(type(prog).__name__)
print(items[0].name, items[0].end_time)
print("schedule-v040.png")Output:
QProg
RPhi 40.0
schedule-v040.pngLayout Can Use Fidelity, Then Export Instructions
ChipBackend now carries single-qubit, readout, and two-qubit fidelity maps. fidelity_layout() exposes the mapping decision, and Transpiler().transpile(..., "fidelity") applies it inside the transpilation pipeline.
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)Output:
{0: 2, 1: 1}
TrueState Preparation Learns the Topology
Encode.topology_aware_mps_encode() adds a hardware-aware path for approximate amplitude encoding.
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))Output:
QCircuit
1.0Read the full 0.4.0 release notes, the QCloud API, and the Time Scheduling API for the complete surface area.