-
Notifications
You must be signed in to change notification settings - Fork 354
Pre-Trajectory Sampling with Batch Execution #3995
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 81 commits
Commits
Show all changes
88 commits
Select commit
Hold shift + click to select a range
6cc3f1c
Adding PTSBE data structures (#3808)
sacpis 46c2644
Ptsbe simulator interface (#3823)
taalexander f00b5d3
Add ptsbe generic implementation and early testing with (#3832)
taalexander 44f22f6
[PTSBE] Add support for async/broadcasting (#3851)
taalexander e11d51a
Fix rebasing issues surrounding context handling updates for PTSBE.
taalexander 2c961c2
[PTSBE] Adding sampling strategies (#3848)
sacpis b8449ef
[PTSBE] Adding NoiseExtractor to extract noise from a circuit trace (…
sacpis e054205
Refactor PTSBE to avoid leaking nvqir headers in public include chain…
taalexander d0ef8f1
[PTSBE] Trajectory Deduplication (#3878)
sacpis 5ac3373
Fix mcm_rejection: catch (...) for dynamic circuit rejection
sacpis 63d7fb4
* Accept any exception type in throw to fix CI jobs
sacpis ad170bb
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 3be6898
[PTSBE] Allocate shots to trajectories (#3899)
sacpis e38ca8a
Adding probability validation to noise channels (#3890)
sacpis a07423c
[python] Remove GlobalAstRegistry (#3896)
lmondada 846fec6
[python] Replace bindings for QIS types with stubs (#3882)
lmondada 4e244b6
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 8f93639
[PTSBE] CPP/Python interface stubs with initial trace definition (#3887)
taalexander ea711bc
Restrain SROA to prevent memory corruption (#3868)
atgeller 443c7d4
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 79e693e
[PTSBE] Decouple PTSBE support for sample from cudaq::sample to cudaq…
taalexander fe0ef45
Resolving the dependency of `cudaq-python-interop` lib (#3908)
1tnguyen d932ccd
Add flaky retry on macos for test_run_async (#3911)
taalexander eee843b
[python] Disable flaky struct deep copy test (#3921)
huaweil-nv fcdf802
[PTSBE] Define and return execution data for PTSBE execution to user …
taalexander 7ee202f
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis d586ab7
[PTSBE] Use `dynamic_cast` for `sampleWithPTSBE` opt-in (#3922)
1tnguyen 066236b
Bump actions/checkout@v4 -> actions/checkout@v6 (#3924)
mitchdz 33d8ef9
Bump nbconvert from 7.16.6 to 7.17.0 (#3903)
dependabot[bot] b08a726
Update mgpu SHA to incorporate PTSBE support (#3937)
1tnguyen aebde0d
[PTSBE] Notebooks for demo (#3934)
sacpis 1401f72
Change device key lookup behavior in python bridge (#3917)
atgeller 0adb970
C++ API doc (#3898)
Renaud-K fde98e4
Type erased jit engine (#3933)
Renaud-K c5f3ea8
[python] Remove unused CapturedDataStorage (#3932)
lmondada fb0cf66
Add operation names to noise model (#3928)
taalexander a2f8c68
fix header
sacpis 63df827
[PTSBE] Fix PTSBESampler (#3939)
sacpis 768393d
[PTSBE] Integration tests (#3942)
sacpis 5121b10
[PTSBE] Fix documentation (#3945)
sacpis e29a25b
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 835e416
[PTSBE] Integration tests with edge cases (#3944)
sacpis a2fb30b
Fix macos devdeps cache invalidation on Github actions runner update …
taalexander e04af64
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 7d1b739
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 0150984
[PTSBE] Increase attempts for low trajectories (#3961)
sacpis 144e5cb
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis b5de579
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis f06d3dc
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis e478fe9
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 7df1b7c
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 360f1cc
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 678e775
[PTSBE] Apply noise style api (#3990)
sacpis 15ca5c6
Remove unused support_conditional_feedback (#3959)
Renaud-K 4cc7a0b
Fix wheel packaging macos (#3955)
taalexander ebb11c2
Passing the execution context as an argument to the compiler. (#3986)
Renaud-K 72d7135
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis f66e654
Fix: recover_kernel_decorator fails for nested if blocks, added check…
derek-yux 22d2e30
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 065c0c3
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis d481009
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 746a266
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 4040956
Add measurement noise support and unify PTSBE trace representation (#…
taalexander 6416fe8
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 506e399
[PTSBE] Handle default-constructed `sample_result` (#4003)
1tnguyen 8644f68
Fix an oversight in test case
1tnguyen dbb453b
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 0ba0d89
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 0d30cb8
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 0d413a9
Fix publishing failure for notebooks (#4007)
sacpis d2a3c89
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 934e964
[PTSBE] Fixing proportional shot allocation (#4012)
sacpis df86c9f
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis fe0a297
[PTSBE] Sampling fixes and improvements from verification testing (#4…
taalexander 7173b3e
[PTSBE] Fix "sample" context bug (#4027)
taalexander 0105d0d
Update mgpu SHA to top of main (#4029)
1tnguyen 3d928c3
[PTSBE] follow up verification fixes (#4028)
taalexander b010293
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis f0538d1
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis ff279ab
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis 183a81d
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis bac2cde
[PTSBE] Core code fixes to merge (#4043)
taalexander b078932
[python] Defer MLIR compilation until kernel invocation (#3948)
lmondada 3f1bd7c
[docs] Add a migration guide for porting kernels from `sample` to `ru…
khalatepradnya 932fcc9
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis a3767f1
Add ptsbe tests for nvq++ (#4049)
taalexander c15f311
Merge branch 'main' into features/ptsbe
lmondada 849a199
Merge remote-tracking branch 'upstream/main' into features/ptsbe
sacpis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| clang | ||
| gcc | ||
| nullary | ||
| pre | ||
| typedef |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,2 @@ | ||
| nvidia-mgpu-repo: cuda-quantum/cuquantum-mgpu.git | ||
| nvidia-mgpu-commit: e41bb18a5e5ff5be44090dfc4cb6c59fb511e9c7 | ||
| nvidia-mgpu-commit: 69fa05df00a069c3bc5c040294678014a396fa68 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
217 changes: 217 additions & 0 deletions
217
docs/sphinx/examples/python/ptsbe_end_to_end_workflow.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,217 @@ | ||
| { | ||
| "cells": [ | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "## PTSBE end-to-end workflow\n", | ||
| "\n", | ||
| "**PTSBE** (Pre-Trajectory Sampling with Batch Execution) is a method for sampling from **noisy** quantum circuits efficiently. Instead of simulating the full density matrix and sampling once per shot, PTSBE:\n", | ||
| "\n", | ||
| "1. **Traces** the kernel to get the gate sequence and qubit layout.\n", | ||
| "2. **Extracts noise sites** by matching the noise model to the trace (each noisy gate becomes a *noise site* with a set of Kraus outcomes, e.g. I, X, Y, Z for depolarization).\n", | ||
| "3. **Generates trajectories** — each trajectory is one possible *realization* of noise (one Kraus outcome per site). A **sampling strategy** decides which trajectories to use (e.g. **Exhaustive**: all combinations, or **Probabilistic**: sample by probability).\n", | ||
| "4. **Allocates shots** across trajectories (e.g. **proportional** to trajectory probability, or **uniform**).\n", | ||
| "5. **Runs batches** — for each trajectory, the circuit is run as a **noiseless** circuit with that trajectory's outcomes applied; results are collected.\n", | ||
| "6. **Aggregates** all per-trajectory counts into a single `SampleResult`.\n", | ||
| "\n", | ||
| "You get the same statistics as density-matrix sampling (in the limit of many shots), but with the ability to batch many shots per trajectory and to control cost via the number of trajectories. This notebook runs the full workflow with a single API call: `cudaq.ptsbe.sample()`." | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "### 1. Set up the environment\n", | ||
| "\n", | ||
| "Use the density-matrix simulator target (required for PTSBE). Set a random seed for reproducibility." | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "import cudaq\n", | ||
| "\n", | ||
| "cudaq.set_target(\"density-matrix-cpu\")\n", | ||
| "cudaq.set_random_seed(42)" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "### 2. Define the circuit and noise model\n", | ||
| "\n", | ||
| "Define a kernel and attach a noise model. Each gate you add to the noise model becomes a **noise site** when that gate appears in the circuit. For **single-qubit** gates (e.g. H) use **DepolarizationChannel** with one qubit; for **CNOTs** pass the **qubit pair** `[control, target]` and use **Depolarization2** (two-qubit depolarization). Here we use a small Bell-style circuit with depol on the Hadamard and on the controlled-X (qubit pair [0, 1])." | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "@cudaq.kernel\n", | ||
| "def bell_with_noise():\n", | ||
| " q = cudaq.qvector(2)\n", | ||
| " h(q[0])\n", | ||
| " x.ctrl(q[0], q[1])\n", | ||
| " mz(q)\n", | ||
| "\n", | ||
| "noise = cudaq.NoiseModel()\n", | ||
| "noise.add_channel(\"h\", [0], cudaq.DepolarizationChannel(0.05))\n", | ||
| "noise.add_channel(\"x\", [0, 1], cudaq.Depolarization2(0.03))" | ||
taalexander marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "### 3. Run PTSBE sampling\n", | ||
| "\n", | ||
| "Call `cudaq.ptsbe.sample()` with the kernel, noise model, and shot count. Optional arguments:\n", | ||
| "\n", | ||
| "- **sampling_strategy** — how trajectories are chosen:\n", | ||
| " - **ExhaustiveSamplingStrategy()**: use all possible trajectories (every combination of Kraus outcomes per noise site).\n", | ||
| " - **ProbabilisticSamplingStrategy(seed=...)**: sample trajectories randomly according to their probabilities; use a seed for reproducibility.\n", | ||
| " - **OrderedSamplingStrategy()**: use the top-$k$ trajectories by probability (highest first), up to `max_trajectories`.\n", | ||
| "- **shot_allocation** — how shots are split across the chosen trajectories:\n", | ||
| " - **PROPORTIONAL** (default): allocate shots in proportion to each trajectory’s probability.\n", | ||
| " - **UNIFORM**: give each trajectory the same number of shots.\n", | ||
| " - **LOW_WEIGHT_BIAS**: bias more shots toward low-weight (fewer errors) trajectories; optional `bias_strength` (default 2.0).\n", | ||
| " - **HIGH_WEIGHT_BIAS**: bias more shots toward high-weight trajectories; optional `bias_strength` (default 2.0).\n", | ||
| " Example: `ShotAllocationStrategy(type=cudaq.ptsbe.ShotAllocationType.UNIFORM)` or `ShotAllocationStrategy(type=cudaq.ptsbe.ShotAllocationType.LOW_WEIGHT_BIAS, bias_strength=5.0)`.\n", | ||
| "- **max_trajectories**: cap the number of trajectories (useful for large shot counts).\n", | ||
| "- **return_execution_data** (bool): If ``True``, the result includes trace instructions and per-trajectory data (``result.ptsbe_execution_data``); see section 6 at the end." | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "shots = 1000000\n", | ||
| "\n", | ||
| "strategy = cudaq.ptsbe.ProbabilisticSamplingStrategy(seed=42)\n", | ||
| "result = cudaq.ptsbe.sample(\n", | ||
| " bell_with_noise,\n", | ||
| " noise_model=noise,\n", | ||
| " shots_count=shots,\n", | ||
| " sampling_strategy=strategy,\n", | ||
| ")\n", | ||
| "\n", | ||
| "print(\"PTSBE sample result:\")\n", | ||
| "print(result)\n", | ||
| "print(f\"Total shots: {result.get_total_shots()}\")" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "### 4. Compare with standard (density-matrix) sampling\n", | ||
| "\n", | ||
| "To verify that PTSBE matches the usual noisy simulation, run standard `cudaq.sample()` with the same kernel and noise model. With enough shots, the two outcome distributions should be close (see the **PTSBE accuracy validation** example for a Hellinger fidelity comparison)." | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "result_standard = cudaq.sample(bell_with_noise, noise_model=noise, shots_count=shots)\n", | ||
| "print(\"Standard (density-matrix) sample result:\")\n", | ||
| "print(result_standard)\n", | ||
| "print(f\"Total shots: {result_standard.get_total_shots()}\")" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "### 5. Return execution data\n", | ||
| "\n", | ||
| "Pass `return_execution_data=True` to get the PTSBE execution data: the trace (gate, noise, measurement instructions) and the list of trajectories with their probabilities and shot allocations. Use `result.ptsbe_execution_data` and `result.has_execution_data()`." | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "result_with_data = cudaq.ptsbe.sample(\n", | ||
| " bell_with_noise,\n", | ||
| " noise_model=noise,\n", | ||
| " shots_count=shots,\n", | ||
| " sampling_strategy=strategy,\n", | ||
| " return_execution_data=True,\n", | ||
| ")\n", | ||
| "assert result_with_data.has_execution_data()\n", | ||
| "data = result_with_data.ptsbe_execution_data\n", | ||
| "\n", | ||
| "Gate = cudaq.ptsbe.TraceInstructionType.Gate\n", | ||
| "Noise = cudaq.ptsbe.TraceInstructionType.Noise\n", | ||
| "Measurement = cudaq.ptsbe.TraceInstructionType.Measurement\n", | ||
| "print(\"Execution data:\")\n", | ||
| "print(f\" Instructions: {len(data.instructions)} total\")\n", | ||
| "n_gate = sum(1 for i in data.instructions if i.type == Gate)\n", | ||
| "n_noise = sum(1 for i in data.instructions if i.type == Noise)\n", | ||
| "n_meas = sum(1 for i in data.instructions if i.type == Measurement)\n", | ||
| "print(f\" Gates: {n_gate}, Noise: {n_noise}, Measurements: {n_meas}\")\n", | ||
| "print(f\" Trajectories: {len(data.trajectories)}\")\n", | ||
| "total_traj_shots = sum(t.num_shots for t in data.trajectories)\n", | ||
| "print(f\" Sum of trajectory shots: {total_traj_shots} (expected {shots})\")\n", | ||
| "print(\" Trace instructions (first 5):\")\n", | ||
| "for i, inst in enumerate(data.instructions[:5]):\n", | ||
| " print(f\" [{i}] type={inst.type}, name={inst.name}, targets={list(inst.targets)}\")\n", | ||
| "if data.trajectories:\n", | ||
| " t0 = data.trajectories[0]\n", | ||
| " print(f\" Example trajectory: id={t0.trajectory_id}, probability={t0.probability:.6f}, num_shots={t0.num_shots}\")\n", | ||
| " print(\" Selected trajectory (kraus_selections):\")\n", | ||
| " for sel in t0.kraus_selections:\n", | ||
| " print(f\" circuit_location={sel.circuit_location}, kraus_operator_index={sel.kraus_operator_index}, is_error={sel.is_error}\")" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "### 6. Two API options:\n", | ||
| "\n", | ||
| "We have two ways to sample from a noisy circuit:\n", | ||
| "\n", | ||
| "1. **`cudaq.sample(kernel, noise_model=noise, use_ptsbe=..., ...)`** — The main sample API with a **`use_ptsbe`** option. When `use_ptsbe=False` (or omitted), sampling uses the standard density-matrix path; when `use_ptsbe=True`, sampling uses the PTSBE (trajectory) path.\n", | ||
taalexander marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "2. **`cudaq.ptsbe.sample(kernel, noise_model=noise, ...)`** — The dedicated PTSBE API. There is no `use_ptsbe` option; sampling always uses the PTSBE path (trajectories, strategies, execution data, etc.).\n", | ||
| "\n", | ||
| "**When to choose which:** Use **`cudaq.sample`** with `use_ptsbe=True` when you want PTSBE from the main sample API (one call, one place for all sampling). Use **`cudaq.ptsbe.sample`** when you want the dedicated PTSBE API (explicit PTSBE entry point, no flag). Both provide the same PTSBE path (large shot counts, batching, trajectory strategies, execution data)." | ||
| ] | ||
| } | ||
| ], | ||
| "metadata": { | ||
| "kernelspec": { | ||
| "display_name": "Python 3", | ||
| "language": "python", | ||
| "name": "python3" | ||
| }, | ||
| "language_info": { | ||
| "codemirror_mode": { | ||
| "name": "ipython", | ||
| "version": 3 | ||
| }, | ||
| "file_extension": ".py", | ||
| "mimetype": "text/x-python", | ||
| "name": "python", | ||
| "nbconvert_exporter": "python", | ||
| "pygments_lexer": "ipython3", | ||
| "version": "3.12.3" | ||
| } | ||
| }, | ||
| "nbformat": 4, | ||
| "nbformat_minor": 4 | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.