Skip to content

pyqpanda3 v0.5.1: simpler cloud access, configurable correction, and topology-aware random circuits

0.5.0 handed users the performance dials. v0.5.1 does not chase a new benchmark number; it closes several gaps in cloud access and configurability: connecting to a service no longer requires hand-writing an address, correction modes become semantic options instead of a boolean switch, failed jobs are reported as result state, random circuits can follow the chip topology directly, and the GPU simulator accepts an initial state.

One API key, connected to the right service ​

QCloudService(api_key) now accepts a single argument. A new-format API key carries its service domain, which the SDK resolves to connect to the corresponding service; legacy keys do not carry a domain and fall back to the historical default cloud endpoint, so existing code keeps working.

For test environments or private deployments, the two-argument constructor still overrides the address explicitly:

python
from pyqpanda3.qcloud import QCloudService

# New-format key: the service domain is resolved from the key
service = QCloudService(api_key="YOUR_API_KEY")

# Explicit URL: overrides the domain encoded in the key
service = QCloudService(
    api_key="YOUR_API_KEY",
    url="https://custom-cloud.example.com",
)

NOTE

The examples above require cloud credentials and a real task; they cannot run locally.

In the 0.5.1 bindings the two-argument constructor's url no longer has a default: pass a custom address explicitly when you need one.

Correction modes become configurable ​

QCloudOptions now supports keyword construction and turns correction and crosstalk suppression from implicit behavior into readable, writable options:

python
from pyqpanda3.qcloud import QCloudOptions

options = QCloudOptions(
    amend_flag=3,          # 0: off; 1: global sampling correction; 3: local real-time correction
    use_cz_pattern=True,   # enable crosstalk noise suppression
    mapping=True,
    optimization=True,
    point_label=1,
    is_prob_counts=True,
    specified_block=[],
)
options.print()

The options object can be built locally; submitting a job still requires cloud credentials.

Failed jobs no longer use exceptions ​

QCloudJob.result() used to raise RuntimeError when a task failed. 0.5.1 reports failure through the result itself: result() keeps polling only while the status is WAITING / COMPUTING / QUEUING, and returns immediately on FINISHED / FAILED; on failure, job_status() == JobStatus.FAILED and error_message() gives the reason.

python
from pyqpanda3.core import H, QProg, measure
from pyqpanda3.qcloud import JobStatus, QCloudService

service = QCloudService(api_key="YOUR_API_KEY")
backend = service.backend("full_amplitude")
prog = QProg() << H(0) << measure(0, 0)
job = backend.run(prog, shots=1000)

result = job.result()
if result.job_status() == JobStatus.FAILED:
    print("failed:", result.error_message())
else:
    print(result.get_probs())

error_message() prefers obj.errInfo, then message, then errCode. Transport-level errors such as network, protocol, or HTTP failures may still be raised by the underlying request, so try/except should not be removed wholesale.

NOTE

The example above requires cloud credentials and a real task; it cannot run locally.

Random circuits follow the chip topology ​

random_qcircuit and random_qprog gain a topology overload. It accepts an edge list in the same format as ChipInfo.get_chip_topology(), and every two-qubit gate is generated on one of the given edges:

python
from pyqpanda3.core import random_qcircuit, random_qprog

topology = [[0, 1], [1, 2]]
circ = random_qcircuit([0, 1, 2], 5, ["H", "CNOT"], topology)
prog = random_qprog([0, 1, 2], 5, ["H", "CNOT"], topology)
print(circ.gate_operations())
print(prog.gate_operations())

Single-qubit gates are not restricted by the topology. If an edge references a qubit outside qubits, the function raises ValueError instead of silently generating a circuit that cannot be mapped.

NOTE

No 0.5.1 wheel is available locally, so the example above was not executed; its semantics follow the bindings and test_random_circuit_topology.py.

An initial state for the GPU simulator ​

GPUQVM.init_state(state) lets the GPU simulator start from a chosen initial state instead of only |0...0>:

python
from pyqpanda3.core import GPUQVM, QProg, measure

qvm = GPUQVM()
qvm.init_state([0, 1])          # |1>
prog = QProg(1)
prog << measure(0, 0)
qvm.run(prog, 16)
print(qvm.result().get_counts())  # {'1': 16}
  • init_state([]) restores the default |0...0>; GPUQVM has no no-argument overload.
  • The length must be a power of two; sizes below 2 (other than the empty list), NaN/Inf amplitudes, and non-normalized states raise RuntimeError (the same validation as CPUQVM).
  • GPUQVM is bound only in CUDA builds; in a build without CUDA, pyqpanda3.core.GPUQVM is None. Use simulator_capabilities("GPUQVM").available to check.

NOTE

The example above requires a CUDA-enabled pyqpanda3 build and was not executed locally.

Upgrade notes ​

  • Code that used try/except RuntimeError to catch server-reported task failures should instead check job_status() == JobStatus.FAILED and read error_message().
  • Transport-layer exceptions remain: network, protocol, or HTTP errors may still be raised, so keep the corresponding try/except.
  • QCloudService(api_key, url=...) still works; the single-argument form now connects using the domain encoded in the key.
  • Only control flow that relied on result() raising needs to change.

The complete API change list is in the v0.5.1 release notes; cloud-service details are in QCloudService and QCloudJob, random circuits in Random Circuit, and the GPU initial state in Simulator.

Released under the MIT License.