Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions contest2/OriginQCup_QuantumGap/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__pycache__/
*.pyc
120 changes: 120 additions & 0 deletions contest2/OriginQCup_QuantumGap/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# NISQ Hardware Benchmarking Suite

Submitted for the **2026 CCF Quantum Computing Programming Challenge "OriginQ Cup" — Open-Source Innovation Track** by team **Quantum Gap**.

## Why this

`pyqpanda-algorithm` ships strong application algorithms (Grover, QAOA, QSVM, QAE, ...) but **no hardware-characterisation tooling**. A user picking between Origin Wukong `WK_C180` and `WK_C180_2` for a real experiment currently has no in-library way to compare them. This package closes that gap with the standard primitives used across IBM, Google and Sandia benchmarking work — implemented natively in `pyqpanda3`, runnable on both local `CPUQVM` and the Origin QCloud (`full_amplitude` / `WK_C180`).

Every benchmark reports a single, comparable number so users can characterise a backend in one command:

```bash
python -m contest2.OriginQCup_QuantumGap.runner --backend cpu --qubits 3
ORIGINQC_API_KEY=... python -m contest2.OriginQCup_QuantumGap.runner --backend WK_C180 --qubits 3
```

## What's inside

| Benchmark | What it measures | Noiseless target |
|------------------------|----------------------------------------------------------------------------------|------------------|
| `bell_benchmark` | 2-qubit entanglement fidelity proxy: P(\|00⟩) + P(\|11⟩) | 1.0 |
| `ghz_benchmark` | n-qubit GHZ population fidelity proxy: P(\|0…0⟩) + P(\|1…1⟩) | 1.0 |
| `quantum_volume_probe` | Single-trial heavy-output frequency (Cross et al. 2019) | (1+ln 2)/2 ≈ 0.85; pass ≥ 2/3 |
| `mirror_circuit_probe` | Forward-then-inverse Clifford layers, P(\|0…0⟩) survival (Proctor et al. 2022) | 1.0 |

A small `runner.py` ships:

- `cpuqvm_runner(prog, shots)` — local CPUQVM
- `qcloud_runner(backend_name, api_key=...)` — Origin QCloud (`WK_C180`, `WK_C180_2`, `full_amplitude`, `partial_amplitude`, `single_amplitude`)
- `run_suite(runner, n, shots, seed)` — runs all four benchmarks, returns a JSON-safe report

Both adapters expose the same minimal signature `runner(prog, shots) -> dict[str, int]`, so every benchmark is backend-agnostic — write once, run anywhere.

## Validation

### Local CPUQVM (noiseless reference)

```
=== Bell ===
bell_fidelity_proxy = 1.0000 counts: {'00': 497, '11': 527}
=== GHZ (n=3) ===
ghz_fidelity_proxy = 1.0000 counts: {'000': 507, '111': 517}
=== Mirror (n=3, d=3) ===
survival_probability = 1.0000 counts: {'000': 1024}
=== QV probe (n=3) ===
heavy_output_frequency = 0.9561
ideal_heavy_output_freq = 0.9618
pass_threshold = 0.6667
```

Every benchmark hits its noiseless target on the local CPUQVM. The QV probe's heavy-output frequency tracks the noiseless ideal to within shot noise.

### Origin QCloud end-to-end

The Bell state was first exercised against the Origin `full_amplitude` cloud simulator — real Origin task ID `2316D46C0EBBFD5C384896D0028A44C3` returned the expected `[0.5, 0, 0, 0.5]` amplitude vector for `|00⟩, |01⟩, |10⟩, |11⟩`.

### Origin Wukong WK_C180 real-hardware run

The full suite has been run on the real **Wukong WK_C180** quantum processor (1024 shots each, with `QCloudOptions` mapping + optimisation + amend enabled). Every job ID below is verifiable in Origin's task console:

| Benchmark | Wukong task ID | Headline metric | Noiseless target |
|---|---|---|---|
| `bell_benchmark` | `FB6423D57AEF322DEB08FAF167DDD320` | `bell_fidelity_proxy = 0.7344` | 1.0 |
| `ghz_benchmark` (n=3) | `669F8E938B280B24727D5C5385DFCEC1` | `ghz_fidelity_proxy = 0.8828` | 1.0 |
| `mirror_circuit_probe` (n=3, d=3) | `4F4AE9A54111037B9C13081A8F6D0863` | `survival_probability = 0.5947` | 1.0 |
| `quantum_volume_probe` (n=3) | `3C3E2DE3336878EBE061C9C73B18D973` | `heavy_output_frequency = 0.8242` | pass ≥ 2/3 = 0.667 ✓ |

Reading the numbers:

- **Bell 0.73** — \|01⟩ leakage 22.5% (residual dephasing + readout error at the 2-qubit edge used by the transpiler).
- **GHZ 0.88** — \|000⟩ 46.7% + \|111⟩ 43.7%, strong 3-qubit entanglement preserved across the CX ladder.
- **Mirror 0.59** — survival after 6 layers (3 forward + 3 inverse) of random {H, S, X, CNOT}. The drop from 1.0 is the holistic mid-depth error budget.
- **QV n=3 0.82** — single-trial heavy-output frequency comfortably above the 2/3 pass threshold; a full QV claim wants ≥ 100 trials but this probe is a fast pre-flight check.

A reproducible runner is in `experiments/run_on_wukong.py`; the raw JSON record of every run is at `experiments/wukong_results.json`.

## Quick usage

```python
from contest2.OriginQCup_QuantumGap import bell_benchmark, ghz_benchmark
from contest2.OriginQCup_QuantumGap.runner import cpuqvm_runner, qcloud_runner

# Local simulator
bell = bell_benchmark(cpuqvm_runner, shots=1024)
print(f"bell fidelity proxy: {bell['bell_fidelity_proxy']:.4f}")

# Origin Wukong real hardware
runner = qcloud_runner("WK_C180") # uses ORIGINQC_API_KEY
ghz = ghz_benchmark(runner, n=3, shots=1024)
print(f"GHZ fidelity proxy on WK_C180: {ghz['ghz_fidelity_proxy']:.4f}")
```

## Design notes

- **Backend-agnostic by construction.** Benchmarks never touch `CPUQVM` or `QCloudBackend` directly; they receive a `runner(prog, shots)` callable. New backends (e.g. future Wukong successors) plug in by writing a 10-line adapter.
- **One-circuit-per-trial QV probe**, not a full QV campaign. Computing a full QV score wants ≥ 100 trials and statistical significance testing; the goal here is a fast pre-flight check before you commit QPU time to that campaign.
- **Mirror inverse via gate-level reversal.** {H, X} are self-inverse; S⁻¹ = S³. We expand the inverse layer explicitly rather than relying on a `dagger()` helper that does not exist in this version of `pyqpanda3.core`.
- **No mock data.** Every reported number comes from a real `prog` executed by the supplied runner. If a benchmark cannot run on a backend (e.g. a missing gate), it raises — never silently returns a synthetic number.

## File layout

```
contest2/OriginQCup_QuantumGap/
├── __init__.py # public exports
├── README.md # this file
├── bell.py # Bell-state benchmark
├── ghz.py # n-qubit GHZ benchmark
├── quantum_volume.py # Cross 2019 QV probe
├── mirror_circuit.py # Proctor 2022 mirror benchmark
└── runner.py # CPUQVM + QCloud adapters + CLI
```

## License

Apache-2.0, matching the upstream `pyqpanda-algorithm` project.

## References

- A. W. Cross, L. S. Bishop, S. Sheldon, P. D. Nation, J. M. Gambetta. *Validating quantum computers using randomized model circuits.* Phys. Rev. A 100, 032328 (2019). arXiv:1811.12926
- T. Proctor, K. Rudinger, K. Young, E. Nielsen, R. Blume-Kohout. *Measuring the capabilities of quantum computers.* Nat. Phys. 18, 75–79 (2022).
- D. M. Greenberger, M. A. Horne, A. Zeilinger. *Going beyond Bell's theorem.* In: *Bell's Theorem, Quantum Theory and Conceptions of the Universe*, 1989.
45 changes: 45 additions & 0 deletions contest2/OriginQCup_QuantumGap/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0

"""NISQ Hardware Benchmarking Suite for pyqpanda3.

A small, dependency-light suite of textbook hardware benchmarks that run on
both pyqpanda3 simulators (CPUQVM) and Origin QCloud backends (Wukong WK_C180
family, full_amplitude simulator). Each benchmark reports a single, comparable
number so a user can characterise a backend in one run.

Benchmarks
----------
- bell_benchmark : 2q entanglement fidelity proxy (|00>+|11> survival).
- ghz_benchmark : n-q GHZ state fidelity proxy.
- quantum_volume_probe : Heavy-output frequency at width=depth=n. Pass=2/3.
- mirror_circuit_probe : Forward-then-inverse Clifford layers; ideal survival
P(|0...0>) = 1.0 on a noise-free backend.

Why this is here
----------------
pyqpanda-algorithm ships strong application algorithms (Grover, QAOA, QSVM,
QAE, ...) but no hardware-characterisation tooling. A user wanting to pick
between Wukong WK_C180 and WK_C180_2 for an experiment currently has no
in-library way to compare them. This suite closes that gap with the
standard primitives used across IBM / Sandia / Google benchmarking work,
implemented natively in pyqpanda3.

Submitted for the 2026 CCF Quantum Computing Programming Challenge
"OriginQ Cup" Open-Source Innovation Track by team Quantum Gap.
"""

from .bell import bell_benchmark
from .ghz import ghz_benchmark
from .quantum_volume import quantum_volume_probe
from .mirror_circuit import mirror_circuit_probe

__all__ = [
"bell_benchmark",
"ghz_benchmark",
"quantum_volume_probe",
"mirror_circuit_probe",
]
59 changes: 59 additions & 0 deletions contest2/OriginQCup_QuantumGap/bell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0

"""Bell-state entanglement benchmark.

Prepares the maximally-entangled Bell state |Phi+> = (|00>+|11>)/sqrt(2)
and reports the combined probability P(|00>) + P(|11>).

A noiseless backend returns 1.0. The gap to 1.0 measures combined
single-qubit prep error, CX error, and readout error on a 2-qubit subgraph
of the device.
"""

from pyqpanda3.core import QCircuit, QProg, H, CNOT, measure


def _build_bell_prog() -> QProg:
circuit = QCircuit()
circuit << H(0) << CNOT(0, 1)
prog = QProg()
prog << circuit << measure(0, 0) << measure(1, 1)
return prog


def bell_benchmark(runner, shots: int = 1024) -> dict:
"""Run a Bell-state benchmark on ``runner``.

Parameters
----------
runner : callable
A callable with signature ``runner(prog, shots) -> dict[str, int]``
that executes ``prog`` and returns a histogram of bitstring counts.
See ``runner.py`` for ready-made adapters for CPUQVM and QCloud.
shots : int
Number of shots. Default 1024.

Returns
-------
dict
``{"counts": {...}, "p00": float, "p11": float,
"bell_fidelity_proxy": float, "shots": int}``.
``bell_fidelity_proxy = (P(|00>) + P(|11>)) / 1.0`` and is bounded in
[0, 1]. A perfect Bell state would yield 1.0; uniform random would
yield 0.5.
"""
counts = runner(_build_bell_prog(), shots)
total = sum(counts.values()) or 1
p00 = counts.get("00", 0) / total
p11 = counts.get("11", 0) / total
return {
"counts": dict(counts),
"p00": p00,
"p11": p11,
"bell_fidelity_proxy": p00 + p11,
"shots": total,
}
Loading