Skip to content

Add PNA tutorial#5209

Open
henryzou50 wants to merge 2 commits into
mainfrom
pna-tutorial
Open

Add PNA tutorial#5209
henryzou50 wants to merge 2 commits into
mainfrom
pna-tutorial

Conversation

@henryzou50
Copy link
Copy Markdown
Collaborator

Summary

Adds a new tutorial, "Improving expectation values with propagated noise absorption (PNA)." It is an updated, documentation-ready version of the PNA tutorial from the QDC Challenges 2025 repo: https://github.com/qiskit-community/qdc-challenges-2025/blob/main/day3_tutorials/Track_A/pna/propagated_noise_absorption.ipynb

PNA mitigates two-qubit gate noise by propagating the inverse of learned noise channels into the measured observable (using samplomatic, NoiseLearnerV3, and qiskit-addon-pna), then sampling the randomized circuits with the new QuantumProgram/Executor classes in Qiskit Runtime. The tutorial walks through the full four-step Qiskit pattern on a 30-site mirrored kicked-Ising circuit and compares PNA against PNA+TREX, PNA+PS, and PNA+PS+TREX.

Major changes from the original

  • Updated to released Qiskit Runtime (0.47.0). Migrated off the executor_preview branch. Executor, QuantumProgram, and NoiseLearnerV3 are now imported from the top-level qiskit_ibm_runtime; noise-learner options are passed as a plain dict (no NoiseLearnerV3Options import).
  • Removed hardcoded credentials. Replaced the shared_service (token + instance CRN) and the named QiskitRuntimeService(name="qdc-2025") with a plain QiskitRuntimeService() that reads saved credentials.
  • Runs live, no saved jobs. Removed all saved-job loading (the shared_service.job(...) IDs and load_saved_* branches); the noise learner and Executor now execute live, with the job tagged TUT_PNA.
  • Backend-agnostic qubit selection. Replaced the hardcoded 30-qubit ibm_kingston chain with a find_qubit_chain helper that builds a connected, low-error line from the backend's coupling map, and selects the backend with least_busy. Transpilation stays at optimization_level=0 with the chain pinned as initial_layout, preserving the mirrored two-qubit-gate layer structure that boxing and noise learning rely on.
  • API fix. The measurement basis-change input was hardcoded as basis2, which no longer matches the samplex interface; it now looks up the name from samplex.inputs().get_specs(...).
  • Reformatted to the tutorial template. Added title/description frontmatter, learning outcomes, prerequisites, background, requirements, setup, and next steps. The small-scale simulator section is kept but explains why simulation is skipped (PNA mitigates learned hardware noise).
  • Content corrections and copyediting. Fixed the learned-noise-rates discussion (the original claimed two-qubit rates exceed one-qubit rates, the opposite of what the data shows; now backend-agnostic), and general cleanup.

Files

  • New: docs/tutorials/propagated-noise-absorption.ipynb + images under public/docs/images/tutorials/propagated-noise-absorption/ (3 schematics and the extracted cell outputs).
  • Registered in docs/tutorials/_toc.json and docs/tutorials/index.mdx (Error mitigation section), added to the notebook-CI exclude list in scripts/config/notebook-testing.toml, and given an owner in qiskit_bot.yaml.

Testing

Ran on IBM Quantum hardware, tox -e lint, the notebook normalizer, spelling, and internal-link checks all pass.

Adapt the PNA tutorial from the QDC Challenges 2025 repo [1] into a
documentation tutorial, updated for the stable Qiskit Runtime release and
restructured to follow the standard tutorial template.

New files:
- docs/tutorials/propagated-noise-absorption.ipynb
- public/docs/images/tutorials/propagated-noise-absorption/ (3 schematics
  + extracted cell outputs)

Registered in docs/tutorials/_toc.json and docs/tutorials/index.mdx under
"Error mitigation", excluded from notebook CI in
scripts/config/notebook-testing.toml (consistent with other tutorials), and
given an owner in qiskit_bot.yaml.

Major changes from the original [1]:

- API: migrated off the `executor_preview` branch to the released
  qiskit-ibm-runtime 0.47.0. `Executor`, `QuantumProgram`, and
  `NoiseLearnerV3` are now imported from the top-level package; noise-learner
  options are passed as a plain dict instead of importing
  `NoiseLearnerV3Options`.

- Credentials: replaced the hardcoded `shared_service` (token + `instance`
  CRN) and the named `QiskitRuntimeService(name="qdc-2025")` with a plain
  `service = QiskitRuntimeService()` that reads saved credentials.

- Live execution: removed all saved-job loading (the `shared_service.job(...)`
  IDs and the `load_saved_nl_result` / `load_exec_results_from_disk`
  branches). The noise learner and Executor now run live, and the job is
  tagged `TUT_PNA`.

- Bug fix: the measurement basis-change input was hardcoded as `basis2`,
  which no longer matches the samplex interface (it expects `basis0` here).
  Replaced with a lookup over `samplex.inputs().get_specs(...)` so the name
  is discovered from the circuit's box structure rather than hardcoded. Also
  fixed the execution `shape` to be a real 1-tuple.

- Structure: reformatted to the tutorial template (title/description
  frontmatter, learning outcomes, prerequisites, background, requirements,
  setup, next steps). The small-scale simulator section is kept but
  explains why simulation is skipped (PNA mitigates learned hardware noise),
  and the workflow is presented as the four-step large-scale hardware
  example.

- Content: corrected the learned-noise-rates discussion, which had claimed two-qubit rates exceed one-qubit rates (the opposite of what the plot shows); rewrote it to be device-dependent.
Make the tutorial runnable on any backend instead of being tied to a
hardcoded ibm_kingston chain.

- Add a `find_qubit_chain` helper (defined in the Setup section) that walks
  the backend's coupling map and greedily builds a connected, low-error line
  of `num_qubits`. This replaces the hardcoded 30-qubit layout. Transpilation
  stays at optimization_level=0 with the chain pinned as `initial_layout`, so
  the mirrored two-qubit-gate layer structure that the boxing and
  noise-learning steps depend on is preserved exactly.

- Select the backend dynamically with `service.least_busy(...)` rather than
  pinning ibm_kingston.

- Make the learned-noise-rates commentary backend-agnostic; it no longer
  names a specific device.

- Regenerate the extracted output figures from a fresh hardware run.
@henryzou50 henryzou50 requested a review from a team June 3, 2026 19:26
@qiskit-bot
Copy link
Copy Markdown
Contributor

One or more of the following people are relevant to this code:

  • @nathanearnestnoble

@review-notebook-app
Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants