gpuqviz 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gpuqviz-0.5.0/.gitattributes +5 -0
- gpuqviz-0.5.0/.github/workflows/ci.yml +95 -0
- gpuqviz-0.5.0/.github/workflows/release.yml +45 -0
- gpuqviz-0.5.0/.gitignore +22 -0
- gpuqviz-0.5.0/.zcodeignore +49 -0
- gpuqviz-0.5.0/CHANGELOG.md +168 -0
- gpuqviz-0.5.0/DESIGN.md +240 -0
- gpuqviz-0.5.0/LICENSE +201 -0
- gpuqviz-0.5.0/PKG-INFO +359 -0
- gpuqviz-0.5.0/PROMPTS.md +428 -0
- gpuqviz-0.5.0/README.md +323 -0
- gpuqviz-0.5.0/benchmarks/encode_path.py +92 -0
- gpuqviz-0.5.0/benchmarks/suite.py +119 -0
- gpuqviz-0.5.0/docs/INTERACTIVE_VIEWER.md +133 -0
- gpuqviz-0.5.0/docs/api.md +161 -0
- gpuqviz-0.5.0/docs/benchmarks.md +26 -0
- gpuqviz-0.5.0/docs/conventions.md +118 -0
- gpuqviz-0.5.0/docs/development-plan.md +298 -0
- gpuqviz-0.5.0/docs/images/ghz_split_view.png +0 -0
- gpuqviz-0.5.0/docs/images/scene_title.png +0 -0
- gpuqviz-0.5.0/docs/images/showcase_bloch_heatmap.png +0 -0
- gpuqviz-0.5.0/docs/optimization-plan.md +514 -0
- gpuqviz-0.5.0/examples/algorithms_demo.py +79 -0
- gpuqviz-0.5.0/examples/bell_state_bloch.py +29 -0
- gpuqviz-0.5.0/examples/bell_states.npz +0 -0
- gpuqviz-0.5.0/examples/bench_states.npz +0 -0
- gpuqviz-0.5.0/examples/circuit_viewer_demo.py +120 -0
- gpuqviz-0.5.0/examples/density_demo.py +69 -0
- gpuqviz-0.5.0/examples/entanglement_demo.py +86 -0
- gpuqviz-0.5.0/examples/ghz_heatmap.py +78 -0
- gpuqviz-0.5.0/examples/grover_mcx.py +73 -0
- gpuqviz-0.5.0/examples/histogram_demo.py +77 -0
- gpuqviz-0.5.0/examples/minimum_pipeline.py +17 -0
- gpuqviz-0.5.0/examples/mps_demo.py +97 -0
- gpuqviz-0.5.0/examples/noise_demo.py +100 -0
- gpuqviz-0.5.0/examples/overlay_demo.py +140 -0
- gpuqviz-0.5.0/examples/publication_fig.py +63 -0
- gpuqviz-0.5.0/examples/pyq_bell.py +54 -0
- gpuqviz-0.5.0/examples/scene.json +39 -0
- gpuqviz-0.5.0/examples/scene_demo.py +52 -0
- gpuqviz-0.5.0/examples/showcase.py +65 -0
- gpuqviz-0.5.0/examples/sweep_demo.py +68 -0
- gpuqviz-0.5.0/examples/teleport_demo.py +88 -0
- gpuqviz-0.5.0/pyproject.toml +50 -0
- gpuqviz-0.5.0/scripts/build_site.py +290 -0
- gpuqviz-0.5.0/scripts/gen_font_atlas.py +111 -0
- gpuqviz-0.5.0/site/assets/circuit-composer.js +565 -0
- gpuqviz-0.5.0/site/assets/gallery-data.js +99 -0
- gpuqviz-0.5.0/site/assets/quantum-sim.js +595 -0
- gpuqviz-0.5.0/site/assets/site.css +821 -0
- gpuqviz-0.5.0/site/assets/site.js +214 -0
- gpuqviz-0.5.0/site/assets/three.min.js +7 -0
- gpuqviz-0.5.0/site/assets/viewer.js +486 -0
- gpuqviz-0.5.0/site/demos/bell.html +609 -0
- gpuqviz-0.5.0/site/demos/bernstein_vazirani.html +609 -0
- gpuqviz-0.5.0/site/demos/deutsch_jozsa.html +609 -0
- gpuqviz-0.5.0/site/demos/ghz.html +609 -0
- gpuqviz-0.5.0/site/demos/grover.html +609 -0
- gpuqviz-0.5.0/site/demos/phase_estimation.html +609 -0
- gpuqviz-0.5.0/site/demos/qft.html +609 -0
- gpuqviz-0.5.0/site/demos/quantum_walk.html +609 -0
- gpuqviz-0.5.0/site/demos/simon.html +609 -0
- gpuqviz-0.5.0/site/demos/superdense.html +609 -0
- gpuqviz-0.5.0/site/demos/superposition.html +609 -0
- gpuqviz-0.5.0/site/demos/teleportation.html +609 -0
- gpuqviz-0.5.0/site/docs.html +364 -0
- gpuqviz-0.5.0/site/gallery.html +68 -0
- gpuqviz-0.5.0/site/images/thumbs/bell.png +0 -0
- gpuqviz-0.5.0/site/images/thumbs/bernstein_vazirani.png +0 -0
- gpuqviz-0.5.0/site/images/thumbs/deutsch_jozsa.png +0 -0
- gpuqviz-0.5.0/site/images/thumbs/ghz.png +0 -0
- gpuqviz-0.5.0/site/images/thumbs/grover.png +0 -0
- gpuqviz-0.5.0/site/images/thumbs/phase_estimation.png +0 -0
- gpuqviz-0.5.0/site/images/thumbs/qft.png +0 -0
- gpuqviz-0.5.0/site/images/thumbs/quantum_walk.png +0 -0
- gpuqviz-0.5.0/site/images/thumbs/simon.png +0 -0
- gpuqviz-0.5.0/site/images/thumbs/superdense.png +0 -0
- gpuqviz-0.5.0/site/images/thumbs/superposition.png +0 -0
- gpuqviz-0.5.0/site/images/thumbs/teleportation.png +0 -0
- gpuqviz-0.5.0/site/index.html +214 -0
- gpuqviz-0.5.0/site/playground.html +142 -0
- gpuqviz-0.5.0/site/screenshots/docs.png +0 -0
- gpuqviz-0.5.0/site/screenshots/gallery.png +0 -0
- gpuqviz-0.5.0/site/screenshots/index.png +0 -0
- gpuqviz-0.5.0/site/screenshots/playground.png +0 -0
- gpuqviz-0.5.0/src/gpuqviz/__init__.py +45 -0
- gpuqviz-0.5.0/src/gpuqviz/adapters/__init__.py +176 -0
- gpuqviz-0.5.0/src/gpuqviz/algorithms/__init__.py +118 -0
- gpuqviz-0.5.0/src/gpuqviz/algorithms/_bernstein_vazirani.py +71 -0
- gpuqviz-0.5.0/src/gpuqviz/algorithms/_deutsch_jozsa.py +90 -0
- gpuqviz-0.5.0/src/gpuqviz/algorithms/_engine.py +95 -0
- gpuqviz-0.5.0/src/gpuqviz/algorithms/_grover.py +187 -0
- gpuqviz-0.5.0/src/gpuqviz/algorithms/_primitive.py +106 -0
- gpuqviz-0.5.0/src/gpuqviz/algorithms/_qft.py +110 -0
- gpuqviz-0.5.0/src/gpuqviz/algorithms/_qpe.py +79 -0
- gpuqviz-0.5.0/src/gpuqviz/algorithms/_quantum_walk.py +123 -0
- gpuqviz-0.5.0/src/gpuqviz/algorithms/_simon.py +84 -0
- gpuqviz-0.5.0/src/gpuqviz/algorithms/_superdense.py +90 -0
- gpuqviz-0.5.0/src/gpuqviz/algorithms/_teleportation.py +100 -0
- gpuqviz-0.5.0/src/gpuqviz/analysis/__init__.py +27 -0
- gpuqviz-0.5.0/src/gpuqviz/analysis/entanglement.py +164 -0
- gpuqviz-0.5.0/src/gpuqviz/analysis/measurement.py +223 -0
- gpuqviz-0.5.0/src/gpuqviz/analysis/metrics.py +210 -0
- gpuqviz-0.5.0/src/gpuqviz/api.py +968 -0
- gpuqviz-0.5.0/src/gpuqviz/assets/font_msyh_64.bin +0 -0
- gpuqviz-0.5.0/src/gpuqviz/assets/font_msyh_64.json +1 -0
- gpuqviz-0.5.0/src/gpuqviz/assets/vendor/three.min.js +7 -0
- gpuqviz-0.5.0/src/gpuqviz/assets/vendor/three.module.min.js +6 -0
- gpuqviz-0.5.0/src/gpuqviz/assets/viewer.js +486 -0
- gpuqviz-0.5.0/src/gpuqviz/assets/viewer_template.html +116 -0
- gpuqviz-0.5.0/src/gpuqviz/backends/__init__.py +66 -0
- gpuqviz-0.5.0/src/gpuqviz/backends/cpu.py +715 -0
- gpuqviz-0.5.0/src/gpuqviz/circuits.py +383 -0
- gpuqviz-0.5.0/src/gpuqviz/cli.py +354 -0
- gpuqviz-0.5.0/src/gpuqviz/encode.py +276 -0
- gpuqviz-0.5.0/src/gpuqviz/env.py +123 -0
- gpuqviz-0.5.0/src/gpuqviz/evolve.py +194 -0
- gpuqviz-0.5.0/src/gpuqviz/export_html.py +243 -0
- gpuqviz-0.5.0/src/gpuqviz/interpolate.py +106 -0
- gpuqviz-0.5.0/src/gpuqviz/jupyter.py +408 -0
- gpuqviz-0.5.0/src/gpuqviz/mps.py +311 -0
- gpuqviz-0.5.0/src/gpuqviz/noise.py +245 -0
- gpuqviz-0.5.0/src/gpuqviz/parameters.py +181 -0
- gpuqviz-0.5.0/src/gpuqviz/pipeline.py +85 -0
- gpuqviz-0.5.0/src/gpuqviz/presets.py +52 -0
- gpuqviz-0.5.0/src/gpuqviz/preview.py +118 -0
- gpuqviz-0.5.0/src/gpuqviz/pro.py +202 -0
- gpuqviz-0.5.0/src/gpuqviz/render/__init__.py +5 -0
- gpuqviz-0.5.0/src/gpuqviz/render/bloch.py +254 -0
- gpuqviz-0.5.0/src/gpuqviz/render/colorconvert.py +68 -0
- gpuqviz-0.5.0/src/gpuqviz/render/compositor.py +26 -0
- gpuqviz-0.5.0/src/gpuqviz/render/context.py +171 -0
- gpuqviz-0.5.0/src/gpuqviz/render/density.py +177 -0
- gpuqviz-0.5.0/src/gpuqviz/render/entanglement.py +173 -0
- gpuqviz-0.5.0/src/gpuqviz/render/heatmap.py +180 -0
- gpuqviz-0.5.0/src/gpuqviz/render/histogram.py +182 -0
- gpuqviz-0.5.0/src/gpuqviz/render/phasesphere.py +86 -0
- gpuqviz-0.5.0/src/gpuqviz/render/text.py +140 -0
- gpuqviz-0.5.0/src/gpuqviz/scene.py +239 -0
- gpuqviz-0.5.0/src/gpuqviz/state.py +332 -0
- gpuqviz-0.5.0/tests/cross_validation/__init__.py +0 -0
- gpuqviz-0.5.0/tests/cross_validation/test_against_qiskit.py +234 -0
- gpuqviz-0.5.0/tests/cross_validation/test_conditional.py +189 -0
- gpuqviz-0.5.0/tests/cross_validation/test_conventions.py +126 -0
- gpuqviz-0.5.0/tests/cross_validation/test_entanglement.py +212 -0
- gpuqviz-0.5.0/tests/cross_validation/test_measurement.py +192 -0
- gpuqviz-0.5.0/tests/cross_validation/test_mps.py +155 -0
- gpuqviz-0.5.0/tests/cross_validation/test_noise.py +352 -0
- gpuqviz-0.5.0/tests/cross_validation/test_properties.py +189 -0
- gpuqviz-0.5.0/tests/cross_validation/test_sweep.py +116 -0
- gpuqviz-0.5.0/tests/test_adapters.py +109 -0
- gpuqviz-0.5.0/tests/test_algorithms.py +389 -0
- gpuqviz-0.5.0/tests/test_backends.py +43 -0
- gpuqviz-0.5.0/tests/test_bloch_vectors_track.py +91 -0
- gpuqviz-0.5.0/tests/test_circuit_viewer.py +260 -0
- gpuqviz-0.5.0/tests/test_cpu_portability.py +138 -0
- gpuqviz-0.5.0/tests/test_density_track.py +117 -0
- gpuqviz-0.5.0/tests/test_entanglement_track.py +108 -0
- gpuqviz-0.5.0/tests/test_evolve.py +59 -0
- gpuqviz-0.5.0/tests/test_export_html.py +64 -0
- gpuqviz-0.5.0/tests/test_frame_export.py +93 -0
- gpuqviz-0.5.0/tests/test_gates_matrix.py +221 -0
- gpuqviz-0.5.0/tests/test_gpu_sampling.py +128 -0
- gpuqviz-0.5.0/tests/test_histogram_track.py +122 -0
- gpuqviz-0.5.0/tests/test_jupyter.py +190 -0
- gpuqviz-0.5.0/tests/test_layout.py +78 -0
- gpuqviz-0.5.0/tests/test_pipeline.py +25 -0
- gpuqviz-0.5.0/tests/test_pro.py +129 -0
- gpuqviz-0.5.0/tests/test_render_lod.py +101 -0
- gpuqviz-0.5.0/tests/test_render_s3.py +78 -0
- gpuqviz-0.5.0/tests/test_resolution_overlays.py +344 -0
- gpuqviz-0.5.0/tests/test_scene.py +82 -0
- gpuqviz-0.5.0/tests/test_smoke.py +14 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
strategy:
|
|
11
|
+
fail-fast: false # 一个 OS 失败不取消另一个,便于对照
|
|
12
|
+
matrix:
|
|
13
|
+
os: [ubuntu-latest, windows-latest]
|
|
14
|
+
runs-on: ${{ matrix.os }}
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.11"
|
|
20
|
+
# ubuntu 无显示环境:装 headless GL 系统库,
|
|
21
|
+
# moderngl standalone context 经 EGL/Mesa 可用
|
|
22
|
+
- name: Install headless GL (ubuntu)
|
|
23
|
+
if: runner.os == 'Linux'
|
|
24
|
+
run: |
|
|
25
|
+
sudo apt-get update
|
|
26
|
+
sudo apt-get install -y libegl1 libgl1 libosmesa6
|
|
27
|
+
- name: Install (CPU-only extras; GPU extras need CUDA runners)
|
|
28
|
+
run: |
|
|
29
|
+
python -m pip install --upgrade pip
|
|
30
|
+
pip install -e .[qiskit,cpu-fallback,dev]
|
|
31
|
+
- name: Lint
|
|
32
|
+
run: |
|
|
33
|
+
ruff check src tests examples benchmarks scripts
|
|
34
|
+
- name: Test
|
|
35
|
+
env:
|
|
36
|
+
QT_QPA_PLATFORM: offscreen
|
|
37
|
+
run: |
|
|
38
|
+
python -m pytest tests -q -k "not gpu_only" --tb=short 2>&1 | tee pytest_output.txt
|
|
39
|
+
exit ${PIPESTATUS[0]}
|
|
40
|
+
- name: Failure diagnostics → step summary
|
|
41
|
+
if: failure()
|
|
42
|
+
run: |
|
|
43
|
+
echo "### pytest 失败摘要(${{ matrix.os }})" >> "$GITHUB_STEP_SUMMARY"
|
|
44
|
+
tail -n 60 pytest_output.txt >> "$GITHUB_STEP_SUMMARY" || true
|
|
45
|
+
- name: Upload test log (failure diagnostics)
|
|
46
|
+
if: ${{ failure() }}
|
|
47
|
+
uses: actions/upload-artifact@v4
|
|
48
|
+
with:
|
|
49
|
+
name: pytest-${{ matrix.os }}
|
|
50
|
+
path: pytest_output.txt
|
|
51
|
+
# 无 NVIDIA GPU:NVENC/NV12 用例自带 skipif;cupy 用例模块级
|
|
52
|
+
# importorskip 跳过;GPU 采样基准标记 gpu_only 不在 CI 跑。
|
|
53
|
+
|
|
54
|
+
# S8: 无 GPU 环境可移植性回归门禁——强制 CPU 后端完整出片
|
|
55
|
+
# (ubuntu runner 不装 CUDA/cupy,模拟零硬件用户的实际环境)
|
|
56
|
+
cpu-portability:
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
env:
|
|
59
|
+
GPUQVIZ_BACKEND: cpu
|
|
60
|
+
QT_QPA_PLATFORM: offscreen
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v4
|
|
63
|
+
- uses: actions/setup-python@v5
|
|
64
|
+
with:
|
|
65
|
+
python-version: "3.11"
|
|
66
|
+
- name: Install (CPU-only, no GPU extras)
|
|
67
|
+
run: |
|
|
68
|
+
python -m pip install --upgrade pip
|
|
69
|
+
pip install -e .[qiskit,cpu-fallback,dev]
|
|
70
|
+
- name: CPU backend bell + heatmap video
|
|
71
|
+
run: |
|
|
72
|
+
python - <<'PY'
|
|
73
|
+
import av, os
|
|
74
|
+
from qiskit import QuantumCircuit
|
|
75
|
+
from gpuqviz import render_bloch_video, render_heatmap_video
|
|
76
|
+
from gpuqviz.backends import detect_backend
|
|
77
|
+
assert detect_backend() == "cpu", f"expected cpu, got {detect_backend()}"
|
|
78
|
+
qc = QuantumCircuit(2); qc.h(0); qc.cx(0, 1)
|
|
79
|
+
# bell 2s@30fps
|
|
80
|
+
out1 = render_bloch_video(circuit=qc, steps=20, fps=30, seconds=2,
|
|
81
|
+
out="out/cpu_bell.mp4", backend="cpu")
|
|
82
|
+
with av.open(str(out1)) as c:
|
|
83
|
+
n1 = sum(1 for _ in c.decode(video=0))
|
|
84
|
+
assert n1 == 60, f"bell: expected 60 frames, got {n1}"
|
|
85
|
+
assert os.path.getsize(out1) > 1000
|
|
86
|
+
# ghz heatmap 2s@30fps
|
|
87
|
+
qc3 = QuantumCircuit(3); qc3.h(0); qc3.cx(0,1); qc3.cx(1,2)
|
|
88
|
+
out2 = render_heatmap_video(circuit=qc3, steps=20, fps=30, seconds=2,
|
|
89
|
+
out="out/cpu_heatmap.mp4", backend="cpu")
|
|
90
|
+
with av.open(str(out2)) as c:
|
|
91
|
+
n2 = sum(1 for _ in c.decode(video=0))
|
|
92
|
+
assert n2 == 60, f"heatmap: expected 60 frames, got {n2}"
|
|
93
|
+
assert os.path.getsize(out2) > 1000
|
|
94
|
+
print(f"CPU portability: bell={n1}f, heatmap={n2}f — PASS")
|
|
95
|
+
PY
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
# tag 触发(v*);也可在 GitHub Releases 页面手动发布
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
tags: ["v*"]
|
|
7
|
+
workflow_dispatch: # 支持手动触发(选 tag)
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.11"
|
|
20
|
+
- name: Build sdist + wheel
|
|
21
|
+
run: |
|
|
22
|
+
python -m pip install --upgrade pip build
|
|
23
|
+
python -m build
|
|
24
|
+
- name: Check artifacts
|
|
25
|
+
run: |
|
|
26
|
+
python -m pip install twine
|
|
27
|
+
python -m twine check dist/*
|
|
28
|
+
- uses: actions/upload-artifact@v4
|
|
29
|
+
with:
|
|
30
|
+
name: dist
|
|
31
|
+
path: dist/
|
|
32
|
+
|
|
33
|
+
publish:
|
|
34
|
+
needs: build
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
environment: pypi # PyPI Trusted Publisher 里配置的 environment 名
|
|
37
|
+
permissions:
|
|
38
|
+
id-token: write # OIDC:Trusted Publishing 必须
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/download-artifact@v4
|
|
41
|
+
with:
|
|
42
|
+
name: dist
|
|
43
|
+
path: dist/
|
|
44
|
+
- name: Publish to PyPI
|
|
45
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
gpuqviz-0.5.0/.gitignore
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
.venv/
|
|
8
|
+
.mypy_cache/
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
.pytest_cache/
|
|
11
|
+
.coverage
|
|
12
|
+
|
|
13
|
+
# 渲染输出
|
|
14
|
+
out/
|
|
15
|
+
*.mp4
|
|
16
|
+
|
|
17
|
+
# IDE
|
|
18
|
+
.idea/
|
|
19
|
+
.vscode/
|
|
20
|
+
|
|
21
|
+
# ===== ↑ 以上同步自 .gitignore(「从 .gitignore 同步」只重写以上部分)=====
|
|
22
|
+
.git/
|
|
23
|
+
.hg/
|
|
24
|
+
.svn/
|
|
25
|
+
node_modules/
|
|
26
|
+
bower_components/
|
|
27
|
+
jspm_packages/
|
|
28
|
+
site-packages/
|
|
29
|
+
venv/
|
|
30
|
+
coverage/
|
|
31
|
+
htmlcov/
|
|
32
|
+
lcov-report/
|
|
33
|
+
cmakefiles/
|
|
34
|
+
cmake-build-*/
|
|
35
|
+
bazel-*/
|
|
36
|
+
pods/
|
|
37
|
+
deriveddata/
|
|
38
|
+
storybook-static/
|
|
39
|
+
playwright-report/
|
|
40
|
+
test-results/
|
|
41
|
+
allure-results/
|
|
42
|
+
allure-report/
|
|
43
|
+
cdk.out/
|
|
44
|
+
*.dist-info/
|
|
45
|
+
eggs/
|
|
46
|
+
pip-wheel-metadata/
|
|
47
|
+
wheels/
|
|
48
|
+
# ----- ↑ 以上为 ZCode 默认排除规则(自定义规则请写在本行下方,不会被同步/恢复改动)-----
|
|
49
|
+
# 自定义规则写在下方(本行提示可删除)
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 未发布(内置算法库 + CLI demo + 引擎切换)
|
|
4
|
+
|
|
5
|
+
- **CLI `demo` 命令**:`gpuqviz demo --algo grover` 一行命令演示内置算法
|
|
6
|
+
- `--list`:列出全部 12 个算法及简介
|
|
7
|
+
- `--format html|mp4|png`:交互式播放器 / 视频 / 静态帧
|
|
8
|
+
- `--engine qiskit|pyqpanda`:模拟引擎切换(默认 qiskit)
|
|
9
|
+
- `--n-qubits`/`--steps`/`--fps`/`--seconds`/`--style`/`--trail`/`--time`:可视化参数
|
|
10
|
+
- qiskit/pyqpanda 未安装时优雅提示安装命令
|
|
11
|
+
- pyqpanda 引擎自动管理 QVM 生命周期(init_qvm/qAlloc/finalize)
|
|
12
|
+
- **`gpuqviz.algorithms` 模块**:12 个经典量子算法电路构建器
|
|
13
|
+
- 基础态:`bell()`、`ghz(n)`、`superposition(n)`
|
|
14
|
+
- 搜索:`grover(n, marked, iterations)`(统一原有两个不一致实现)
|
|
15
|
+
- 变换:`qft(n, inverse=False)`
|
|
16
|
+
- 估计:`phase_estimation(n_count, theta)`
|
|
17
|
+
- 查询复杂度:`deutsch_jozsa(oracle_type, n)`、`bernstein_vazirani(secret)`、`simon(s, n)`
|
|
18
|
+
- 通信:`teleportation()`、`superdense(message)`
|
|
19
|
+
- 游走:`quantum_walk(n, steps)`
|
|
20
|
+
- 每个算法接受 `engine="qiskit"|"pyqpanda"|"numpy"` 参数
|
|
21
|
+
- 注册表 `ALGORITHM_REGISTRY` + `get_algorithm(name)` + `list_algorithms()`
|
|
22
|
+
- 包级导出:`from gpuqviz import algorithms` / `from gpuqviz.algorithms import grover`
|
|
23
|
+
- **引擎切换架构**:`engine` 参数贯穿 CLI → 算法库 → 可视化 API
|
|
24
|
+
- qiskit(默认):QuantumCircuit → sample_circuit / evolve_gates
|
|
25
|
+
- pyqpanda:QProg → ORIGINIR → numpy(CLI 自动创建 CPUQVM)
|
|
26
|
+
- numpy(保留扩展):list[Gate] → evolve_gates(无外部依赖)
|
|
27
|
+
- **测试**:`tests/test_algorithms.py`(45 例:注册表完整性、每个算法 qiskit/numpy
|
|
28
|
+
路径一致性、数值正确性验证——Bell 末态、GHZ 纠缠、Grover 振幅放大、QFT†∘QFT=I、
|
|
29
|
+
QPE 相位编码、DJ 常数/平衡判定、BV 秘密恢复、隐形传态态转移、超密编码消息解码、
|
|
30
|
+
Simon 电路一致性、量子游走一致性、引擎参数验证)
|
|
31
|
+
- **示例**:`examples/algorithms_demo.py`(遍历 12 个算法批量生成 HTML 演示)
|
|
32
|
+
- **文档**:README 新增"内置算法库"小节 + CLI demo 用法 + roadmap 勾选;
|
|
33
|
+
`docs/api.md` 新增 `gpuqviz.algorithms` 命名空间与 CLI demo 参数说明
|
|
34
|
+
|
|
35
|
+
## 未发布(交互式电路图 + Bloch 球联动)
|
|
36
|
+
|
|
37
|
+
- `export_html(circuit=qc)` / `show(qc)` 自动在播放器顶部绘制 **SVG 量子电路图**,
|
|
38
|
+
与 3D Bloch 球双向联动
|
|
39
|
+
- 浏览器端纯 JavaScript 生成 SVG(无外部电路绘制库依赖),支持单量子门方框、
|
|
40
|
+
受控门(控制点 + ⊕ 目标符)、SWAP(× 符号)、ISWAP(跨行方框)、参数门标签
|
|
41
|
+
(`RX(π/2)` 等角度格式化)、UNITARY(U 方框)
|
|
42
|
+
- 播放时自动高亮当前正在执行的门(橙色 `--accent2`);点击电路图中的门
|
|
43
|
+
跳转到该门对应时刻,Bloch 球与状态面板同步更新
|
|
44
|
+
- 门-关键帧精确对齐:`circuit` 输入时改用 `evolve_gates` + `sample_snapshots`
|
|
45
|
+
路径采样(与 `sample_circuit` 数值一致),每个关键帧天然对应一个门
|
|
46
|
+
- payload 新增 `circuit` 字段:`{n_qubits, n_ops, gates[], active_gates[],
|
|
47
|
+
gate_times[]}`(`export_html._build_circuit_info`)
|
|
48
|
+
- 优雅降级:states-only 输入 / pyqpanda 翻译失败时隐藏电路面板,其余功能不受
|
|
49
|
+
影响;降级模式(>8MB)保留 `circuit` 字段(体积小)
|
|
50
|
+
- `viewer_template.html`:新增 `#circuitPanel` DOM 节点 + 电路图 SVG 样式
|
|
51
|
+
(wire / gate-box / control-dot / target-circle / swap-cross / active 高亮)
|
|
52
|
+
- `viewer.js`:新增 `buildCircuitDiagram()` / `updateCircuitHighlight()` /
|
|
53
|
+
`seekToGate()`,`Init` 构建电路图,`renderFrame` 每帧更新高亮
|
|
54
|
+
- `jupyter.py`:`show(circuit=qc)` 路径同步使用 `evolve_gates` 采样 +
|
|
55
|
+
`circuit_info` 附加 payload
|
|
56
|
+
- 测试:`tests/test_circuit_viewer.py`(18 例:门标签格式化、Bell/GHZ 门元数据、
|
|
57
|
+
active_gates/gate_times 映射、HTML 包含电路图元素、降级保留 circuit、
|
|
58
|
+
viewer.js 函数存在、show() 集成)
|
|
59
|
+
- 文档:README 交互式播放器段落增述电路图联动,Roadmap 勾选
|
|
60
|
+
|
|
61
|
+
## 未发布(S9 Jupyter 交互集成)
|
|
62
|
+
|
|
63
|
+
- `gpuqviz.show(circuit=None, states=None, scene=None, steps=60, out=None,
|
|
64
|
+
as_video=False, height=520, **kwargs)`:一行代码在 Jupyter notebook 中内嵌
|
|
65
|
+
交互式 3D 播放器(`src/gpuqviz/jupyter.py`)
|
|
66
|
+
- 环境检测:`_is_notebook()` 检查 `IPython.get_ipython()` 是否为 ZMQ 内核
|
|
67
|
+
(notebook / JupyterLab / qtconsole),终端回退写 HTML 文件
|
|
68
|
+
- notebook 内:复用 `export_html` payload 构建,生成自包含 HTML(three.js
|
|
69
|
+
内联,断网可用),通过 `IPython.display.HTML` 以 iframe `srcdoc` 内嵌,
|
|
70
|
+
`height` 可调
|
|
71
|
+
- payload 降级:超 8MB 时自动剥离 `states_re`/`states_im`(只保留 Bloch
|
|
72
|
+
向量),文件从 ~8.7MB 降至 ~0.7MB 并发 `RuntimeWarning`
|
|
73
|
+
- `as_video=True`:先渲染 MP4 再用 `IPython.display.Video` 内嵌
|
|
74
|
+
- `viewer.js` 降级兼容:`states_re` 为 null 时 `updatePanel` 跳过概率条更新、
|
|
75
|
+
`renderFrame` 跳过态矢量插值,只显示 Bloch 向量
|
|
76
|
+
- 包级入口:`__init__.py` 导出 `show`(惰性 import,未装 IPython 不影响
|
|
77
|
+
`import gpuqviz`)
|
|
78
|
+
- 测试:`tests/test_jupyter.py`(11 例:非 notebook 写文件、payload 数值正确、
|
|
79
|
+
降级触发/不触发、`_strip_state_panel`、viewer.js null guard、环境检测、
|
|
80
|
+
nbconvert 执行最小 notebook smoke)
|
|
81
|
+
- 文档:README 新增"Jupyter 交互集成"小节(show 示例 + 参数说明),
|
|
82
|
+
`docs/api.md` 增补 `show` 签名与后端/ Jupyter 小节
|
|
83
|
+
|
|
84
|
+
## 未发布(S8 CPU/无 GL 环境可移植性 + NVENC 修复)
|
|
85
|
+
|
|
86
|
+
- NVENC 修复:`NvencEncoder` 重写适配 PyNvVideoCodec 2.x API(`FFmpegMuxer`
|
|
87
|
+
完整参数构造 + `MuxVideoPacket` + `Finalize` + `SetUniformPtsIncrement`),
|
|
88
|
+
CAIMemoryView 显存直喂失败(error 8)改用 `usecpuinputbuffer=True` + cupy
|
|
89
|
+
GPU NV12 kernel + `asnumpy` 路径;`nvenc_available()` 探测改隔离子进程避免
|
|
90
|
+
原生崩溃杀宿主。性能:cupy GPU NV12(787 fps)+ NVENC 硬件编码(236 fps)
|
|
91
|
+
端到端 141 fps @1080p,比 libx264 快 3.8×(此前 numpy CPU NV12 路径为瓶颈)
|
|
92
|
+
- CPU 软光栅重写(`backends/cpu.py`):包围盒光栅(不再每帧全屏距离场)+
|
|
93
|
+
numba `@njit(parallel=True, cache=True)` 加速圆盘/圆环/椭圆环/线段/热图LUT/
|
|
94
|
+
相位色盘热路径,numba 缺失时静默回退 numpy。CPU bell 3s@30fps 720p 从
|
|
95
|
+
116.3s 降至 ~6s(19× 加速),远超 ≤20s 目标
|
|
96
|
+
- CPU 后端补齐:新增 `SoftRasterHeatmap`(LUT 伪彩,与 GL 路径数值一致)、
|
|
97
|
+
`draw_text`(PIL ImageDraw + ImageFont,支持系统字体回退)、`draw_phase_disc`
|
|
98
|
+
(HSV→RGB 相位色盘 CPU 版);`render_heatmap_video` 支持 `backend="cpu"`,
|
|
99
|
+
`render_frame` CPU 路径支持 scene(bloch+heatmap+title)
|
|
100
|
+
- GL 降级链(`render/context.py`):`create_gl_context` 先试 GL 3.3 再降 3.2,
|
|
101
|
+
每次降级打印决策日志,全部失败抛 `GLUnavailableError`;新增
|
|
102
|
+
`GLUnavailableError` 异常类型
|
|
103
|
+
- 环境变量 `GPUQVIZ_BACKEND`(auto/gl/cpu)强制指定后端,优先级高于
|
|
104
|
+
`detect_backend()` 自动探测和调用方 `backend` 参数默认值;`detect_backend`
|
|
105
|
+
和 `resolve_backend` 尊重环境变量
|
|
106
|
+
- `report_env()` 新增"实际渲染路径"列(显示 `GPUQVIZ_BACKEND` 或探测结果);
|
|
107
|
+
NVENC 探测改用隔离子进程 `nvenc_available()`
|
|
108
|
+
- CI:新增 `cpu-portability` job(ubuntu-latest,不装 CUDA,`GPUQVIZ_BACKEND=cpu`
|
|
109
|
+
下 `render_bloch_video` + `render_heatmap_video` 各出 2s 小视频并用 PyAV
|
|
110
|
+
校验帧数,作为可移植性回归门禁);test job 安装 `cpu-fallback` extras
|
|
111
|
+
- 测试:`tests/test_cpu_portability.py`(10 例:环境变量后端选择、CPU 软光栅
|
|
112
|
+
基元、热图 LUT 查表、CPU 热图出片、CPU render_frame PNG、CPU GHZ 多球)
|
|
113
|
+
- 基准:`benchmarks/suite.py` 重写,新增 CPU 优化前后对照行;
|
|
114
|
+
`docs/benchmarks.md` 更新
|
|
115
|
+
|
|
116
|
+
## 未发布(S7 布局/样式系统 + 出版级静态图)
|
|
117
|
+
|
|
118
|
+
- 样式系统扩展:`STYLES` 新增 `bw`(论文黑白:纯白背景、黑轴、灰球壳、深灰矢量)
|
|
119
|
+
与 `poster`(高对比度深底 + 暖色矢量)预设;`style` 参数支持 str 预设名或 dict,
|
|
120
|
+
新增 `style_overrides` 参数按 merge 语义覆盖任意键(如 `{"vector_color": (1,0,0)}`)
|
|
121
|
+
- 布局系统:`render_bloch_video` 新增 `cols`(一行最多几个球,语义对齐 recorder
|
|
122
|
+
的 `num_cols`)与 `figsize`(英寸元组,dpi=100 换算像素,与默认 1920×1080 互斥);
|
|
123
|
+
多行布局行距自适应,相机距离取行列包络;CPU 后端同步支持 `cols` 网格
|
|
124
|
+
- 出版级静态图:`render_frame(circuit|states|scene, t, out, scale, style, cols, figsize)`
|
|
125
|
+
渲染归一化时刻 t∈[0,1] 的单帧 → PNG,`scale` 超采样(2/4×)抗锯齿,
|
|
126
|
+
内部以 scale×分辨率 GL 渲染后 PIL LANCZOS 缩回目标尺寸;等效 300dpi 输出
|
|
127
|
+
方式:`figsize=(英寸,)` 指定像素数 = 英寸 × 100(再乘 scale 做超采样)
|
|
128
|
+
- CLI:`gpuqviz frame --scene xxx.json | --states xxx.npz --time 0.5 --scale 2 -o fig.png`
|
|
129
|
+
- 依赖:新增 `Pillow>=10.0`(PNG 编码)
|
|
130
|
+
- 测试:`tests/test_layout.py`(8 例:预设完整性、覆盖语义、figsize 换算、
|
|
131
|
+
单行/多行/单列布局包围盒不重叠)+ `tests/test_frame_export.py`(7 例:
|
|
132
|
+
PNG 尺寸正确、非纯色、bw 白底、scale 抗锯齿、t 越界报错、style_overrides)
|
|
133
|
+
- 示例:`examples/publication_fig.py`(Bell bw 3200×2000 scale=4、8-qubit GHZ
|
|
134
|
+
cols=2 多行、Bell dark 中间时刻)
|
|
135
|
+
|
|
136
|
+
## 未发布(S6 高层门/复杂电路兼容性)
|
|
137
|
+
|
|
138
|
+
- 门级模拟器扩展:通用矩阵作用原语 `_apply_matrix`、多控制门构造 `_controlled`、
|
|
139
|
+
U/U1/U2/U3/P/PHASE、受控参数门 CRX/CRY/CRZ/CH/CU、任意控制位 MCX/MCP/Toffoli、
|
|
140
|
+
ISWAP、SDG/TDG
|
|
141
|
+
- `adapters.qiskit_to_gates`:qiskit QuantumCircuit → 框架无关 Gate 列表的翻译器,
|
|
142
|
+
优先命名直译 → `to_matrix`/`Operator` 矩阵路径 → `definition` 递归展开 →
|
|
143
|
+
`transpile` 到基础门集兜底(未知指令也能出片)
|
|
144
|
+
- 态矢量路径对中途 `measure`/`reset`/`delay` 的处理:自动跳过并提示,
|
|
145
|
+
`measure_all` 自动剔除(不再触发 `Cannot apply instruction with classical bits`)
|
|
146
|
+
- ORIGINIR 解析扩展:TOFFOLI/CCX、ISWAP、U1/U2/U3/P、CRZ/CH/CU3
|
|
147
|
+
- `encode.nvenc_available` 探测改为隔离子进程执行:Pascal EOL 驱动上
|
|
148
|
+
`nvEncOpenEncodeSessionEx` 触发的原生 access violation 不再杀死宿主进程,
|
|
149
|
+
结果进程内缓存
|
|
150
|
+
- 测试:新增 `tests/test_gates_matrix.py`,14 个电路(Bell/GHZ3/QFT/mcx oracle/
|
|
151
|
+
受控参数门全家/StatePreparation/measure/UnitaryGate/global phase/barrier/
|
|
152
|
+
自定义门/嵌套定义/cu+mcp/4-qubit mcx 链)对 qiskit Statevector 末态保真度
|
|
153
|
+
全部 ≥ 1-1e-9;1:1 翻译电路逐层快照逐帧一致
|
|
154
|
+
- 示例:`examples/grover_mcx.py`(3-qubit 含 mcx 的两轮 Grover,目标态 |101⟩
|
|
155
|
+
振幅放大至 0.945,出片 `out/grover.mp4`)
|
|
156
|
+
|
|
157
|
+
## 0.1.0 (2026-09-13)
|
|
158
|
+
|
|
159
|
+
首个可用版本。
|
|
160
|
+
|
|
161
|
+
- 零落盘渲染管线:moderngl 离屏 FBO → 进程内 PyAV 编码(h264_nvenc 探测回退 libx264)
|
|
162
|
+
- `render_bloch_video` / `render_heatmap_video` / Scene 声明式 API(JSON 持久化 + CLI)
|
|
163
|
+
- 布洛赫球(Phong 球壳/轨迹/多 qubit)、概率热图(viridis/inferno)、相位色盘、SDF 中文字幕
|
|
164
|
+
- qiskit 电路采样(按深度分层)+ 批量 einsum Bloch 向量 + slerp 关键帧插值(含对跖点)
|
|
165
|
+
- NVENC 显存直喂路径(PyNvVideoCodec + cupy RGBA→NV12 kernel),会话探测失败自动回退
|
|
166
|
+
- CPU 软光栅后端(numpy,limited 样式),无 OpenGL 环境自动降级
|
|
167
|
+
- 规避的兼容性问题:fbo.read() 全零(改读颜色附件)、色表 REPEAT 边缘混色(clamp)、
|
|
168
|
+
矩阵行/列主序、qiskit 小端序 Bloch 索引、freetype SDF 过渡宽度量纲
|
gpuqviz-0.5.0/DESIGN.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# gpuqviz — GPU 加速量子态演化可视化视频渲染库 · 方案设计
|
|
2
|
+
|
|
3
|
+
> 目标:替代 `qiskit-state-evolution-record` 的 CPU 逐帧渲染流水线,把 15s 视频的渲染时间从 30+ 分钟压缩到 **1~3 分钟以内**(数量级提升来自:GPU 光栅化 + GPU 上传/合成 + NVENC 硬编码 + 消除逐帧写盘)。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 现状瓶颈分析
|
|
8
|
+
|
|
9
|
+
典型 CPU 流水线(qiskit-state-evolution-record 类库)的每帧路径:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Statevector (CPU) → matplotlib 画布渲染 (~2-10s/帧) → PNG 编码落盘 → ffmpeg 软编码读盘
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
三大瓶颈:
|
|
16
|
+
|
|
17
|
+
| 瓶颈 | 原因 | 占比(估计) |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| matplotlib 逐帧绘制 | CPU 光栅化、每帧重建 Figure、抗锯齿全在 CPU | ~70% |
|
|
20
|
+
| 逐帧写盘 PNG | 磁盘 IO + PNG 压缩编码 | ~15% |
|
|
21
|
+
| CPU 软编码 + 读盘 | x264/libx264 编码、再次 IO | ~15% |
|
|
22
|
+
|
|
23
|
+
## 2. 新流水线设计
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
qiskit Circuit/Statevector
|
|
27
|
+
│ (一次性,CPU 上仿真或 GPU 上演化)
|
|
28
|
+
▼
|
|
29
|
+
关键帧态矢量序列 [ψ(t₀), ψ(t₁), ...] ── GPU 间插值/演化(CuPy)
|
|
30
|
+
│ 常驻显存,不落盘
|
|
31
|
+
▼
|
|
32
|
+
GPU 渲染层(ModernGL / VisPy,离屏 FBO):
|
|
33
|
+
├─ 布洛赫球(球体网格 + 相机 + 深度测试)
|
|
34
|
+
├─ 量子态波函数/概率幅热图(纹理 + 片元着色器)
|
|
35
|
+
├─ 相位色环、坐标轴、标注(线框 + SDF 文字)
|
|
36
|
+
│ 关键帧之间由顶点/片段着色器插值,实现任意帧率平滑动画
|
|
37
|
+
▼
|
|
38
|
+
FBO 像素 → NVJPEG/CUDA 直接取回或零拷贝进编码器
|
|
39
|
+
▼
|
|
40
|
+
NVENC 硬编码(PyNvVideoCodec 或 PyAV + h264_nvenc)→ MP4
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
核心原则:
|
|
44
|
+
1. **帧不落盘**:渲染帧直接进编码器(pinned memory / CUDA IPC)。
|
|
45
|
+
2. **插值在 GPU**:只算 N 个关键帧态矢量,中间帧由着色器插值生成,CPU 仿真次数与输出帧率解耦。
|
|
46
|
+
3. **复用 GL 上下文与网格资源**:初始化一次,逐帧只更新 uniform/纹理。
|
|
47
|
+
|
|
48
|
+
## 3. 技术栈与引用的开源库
|
|
49
|
+
|
|
50
|
+
| 层 | 选型 | 理由 |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| 量子仿真 | `qiskit` + `qiskit-aer`(可选用 `qiskit-aer-gpu`) | 与现有工作流兼容;Aer-GPU 可让态矢量演化也在 GPU |
|
|
53
|
+
| GPU 数组/演化 | `cupy`(CUDA 12.x) | 态矢量操作、插值、概率计算全部在 GPU;API 近似 NumPy |
|
|
54
|
+
| GPU 渲染 | `moderngl`(离屏渲染,首选) + `moderngl-window`(可选交互预览) | 轻量、无需窗口即可渲染到 FBO;比 VisPy 更底层可控,比 PyOpenGL 省事 |
|
|
55
|
+
| 文字/标注 | `freetype-py` + 自制 SDF 字形图集 | GL 里高质量渲染中文/数学标注 |
|
|
56
|
+
| 数学网格 | `trimesh`(生成布洛赫球、坐标轴网格,预处理一次) | 生成球体/圆环 obj,运行时上传 VBO |
|
|
57
|
+
| 视频编码 | `pynvvideocodec`(NVIDIA 官方 Python 绑定 NVENC,首选);回退 `PyAV` + `h264_nvenc`/`hevc_nvenc` | 帧数据可留在 GPU 显存直接喂编码器,实现零落盘 |
|
|
58
|
+
| CPU 回退路径 | `numpy` + `pygame/SDL` 软渲染 + PyAV x264 | 无 NVIDIA GPU 时仍可用(比旧库快,因无 matplotlib 开销) |
|
|
59
|
+
| 配置/CLI | `pydantic` + `typer` | 场景描述用 pydantic 模型,CLI 用 typer |
|
|
60
|
+
| 测试 | `pytest` + `pytest-mock`;渲染用像素哈希对比 | 回归测试 |
|
|
61
|
+
| 打包 | `pyproject.toml` (hatchling) + 可选 `nvidia-*` wheel 依赖 | pip 一键装 |
|
|
62
|
+
|
|
63
|
+
明确**不用**的东西:
|
|
64
|
+
- ❌ matplotlib(慢的根源;如需静态图保留一个导出接口即可)
|
|
65
|
+
- ❌ 逐帧 PNG 中间文件
|
|
66
|
+
- ❌ ffmpeg 子进程管道(PyAV/PYNVVIDEOCODEC 进程内编码,省 IO 与序列化)
|
|
67
|
+
|
|
68
|
+
## 4. 包结构
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
gpuqviz/
|
|
72
|
+
├── pyproject.toml
|
|
73
|
+
├── README.md
|
|
74
|
+
├── src/gpuqviz/
|
|
75
|
+
│ ├── __init__.py # 导出公开 API
|
|
76
|
+
│ ├── scene.py # Scene / Track / 关键帧模型 (pydantic)
|
|
77
|
+
│ ├── evolve.py # 量子演化:qiskit circuit → 关键帧态矢量(CuPy 数组)
|
|
78
|
+
│ ├── render/
|
|
79
|
+
│ │ ├── context.py # 隐藏 GL 上下文/设备管理、离屏 FBO 封装
|
|
80
|
+
│ │ ├── bloch.py # 布洛赫球 renderer(多 qubit 网格布局)
|
|
81
|
+
│ │ ├── heatmap.py # 波函数/概率热图 renderer(GPU 纹理)
|
|
82
|
+
│ │ ├── phasesphere.py # 相位色环/幅值柱 renderer
|
|
83
|
+
│ │ ├── text.py # SDF 文字渲染
|
|
84
|
+
│ │ └── compositor.py # 多 renderer 合成到同一帧(framebuffer 混合)
|
|
85
|
+
│ ├── interpolate.py # GPU 关键帧插值(slerp 四元数 / 态矢量线性插值+归一化)
|
|
86
|
+
│ ├── encode.py # NVENC / PyAV 编码器抽象(帧 GPU 内存直入)
|
|
87
|
+
│ ├── pipeline.py # 顶层编排:evolve → render loop → encode
|
|
88
|
+
│ ├── preview.py # moderngl-window 实时预览(可选)
|
|
89
|
+
│ └── backends/
|
|
90
|
+
│ ├── cuda.py # CuPy/CUDA 路径
|
|
91
|
+
│ └── cpu.py # numpy 回退路径
|
|
92
|
+
├── examples/
|
|
93
|
+
│ ├── bell_state_bloch.py
|
|
94
|
+
│ └── ghz_heatmap.py
|
|
95
|
+
└── tests/
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 5. 公开 API 设计
|
|
99
|
+
|
|
100
|
+
### 5.1 快捷函数(覆盖 90% 用例)
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
import gpuqviz
|
|
104
|
+
|
|
105
|
+
# 一行出片:qiskit 电路 → 布洛赫球动画 MP4
|
|
106
|
+
gpuqviz.render_bloch_video(
|
|
107
|
+
circuit=qc, # qiskit.QuantumCircuit;无参演化(按电路层推进)
|
|
108
|
+
steps=120, # 电路均匀采样 120 个关键帧
|
|
109
|
+
fps=60, # 输出帧率(关键帧间 GPU 插值到 60fps)
|
|
110
|
+
out="bell.mp4",
|
|
111
|
+
style="dark", # 预设主题
|
|
112
|
+
codec="h264", # h264 / hevc,NVENC 硬编码
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
# 从 Statevector 序列出片(用户自己演化也行)
|
|
116
|
+
gpuqviz.render_heatmap_video(
|
|
117
|
+
states=[psi0, psi1, ...], # qiskit.quantum_info.Statevector 序列
|
|
118
|
+
fps=30, out="evol.mp4",
|
|
119
|
+
)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 5.2 声明式 Scene API(可组合、可持久化为 JSON)
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from gpuqviz import Scene, BlochTrack, HeatmapTrack, Camera, render
|
|
126
|
+
|
|
127
|
+
scene = Scene(
|
|
128
|
+
width=1920, height=1080, fps=60, duration=8.0, # 秒
|
|
129
|
+
background="#0b0e14",
|
|
130
|
+
)
|
|
131
|
+
scene.add(BlochTrack(
|
|
132
|
+
states=statevectors, # 关键帧(qiskit Statevector 或 cupy 数组)
|
|
133
|
+
qubit_indices=[0, 1], # 多 qubit 各一个球
|
|
134
|
+
trail=True, # 显示轨迹尾巴
|
|
135
|
+
))
|
|
136
|
+
scene.add(HeatmapTrack(
|
|
137
|
+
states=statevectors,
|
|
138
|
+
basis="probability", # probability / amplitude / phase / real / imag
|
|
139
|
+
))
|
|
140
|
+
scene.camera = Camera(orbit=(azimuth=(0, 90), elevation=(20, 35))) # 相机动画
|
|
141
|
+
render(scene, "out.mp4", codec="hevc", quality=0.9)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 5.3 底层 API(逐帧回调,完全可控)
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from gpuqviz import Renderer, Encoder, GLContext
|
|
148
|
+
|
|
149
|
+
with GLContext(width=1920, height=1080, device=0) as gl:
|
|
150
|
+
enc = Encoder("out.mp4", fps=60, codec="hevc_nvenc") # 常驻编码器
|
|
151
|
+
for t, frame_gpu in gl.frame_iterator(total_frames=480):
|
|
152
|
+
# frame_gpu: cupy ndarray (H,W,4) uint8,显存中
|
|
153
|
+
... # 自定义绘制,或调用内置 renderer
|
|
154
|
+
enc.write(frame_gpu) # 显存直入 NVENC,零落盘
|
|
155
|
+
enc.close()
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### 5.4 与 qiskit 的衔接点
|
|
159
|
+
|
|
160
|
+
- `evolve.py` 内部用 `qiskit.quantum_info.Statevector(circuit)` + 逐步分解(对电路按层截断得到关键帧),或接受 `qiskit-aer` 的 `save_state` 结果。
|
|
161
|
+
- 可选:检测到 `qiskit-aer-gpu` 时把 `AerSimulator(method="statevector", device="GPU")` 用于演化本身。
|
|
162
|
+
- 输入协议:任何能转 `numpy/cupy 复数向量 (2^n,)` 的对象都可以(qiskit `Statevector`、`DensityMatrix`、自定义数组),对 qiskit 仅软依赖(extras:`pip install gpuqviz[qiskit]`)。
|
|
163
|
+
|
|
164
|
+
## 6. 关键技术点
|
|
165
|
+
|
|
166
|
+
1. **态矢量 → 布洛赫球**:对多 qubit 态求 `ρᵢ = Tr(ψψ† ⊗ 其余)` 得每个 qubit 的 Bloch 向量(CuPy einsum,微秒级);帧间用球面 slerp 插值。
|
|
167
|
+
2. **关键帧 → 任意帧率**:只在上游算 N 个关键帧,输出帧率与仿真解耦;60fps 输出 15s = 900 帧,其中大多数是着色器插值帧,成本可忽略。
|
|
168
|
+
3. **零落盘编码**:FBO 用 `glReadPixels` 进 pinned buffer → CuPy 视图 → NVENC 输入。`pynvvideocodec` 支持 CUDA device buffer 直喂;无 NVENC 时回退 PyAV `h264_nvenc`(仍走 GPU 编码)或 libx264(最后手段)。
|
|
169
|
+
4. **文字**:freetype 生成字形图集纹理一次,运行时片元着色器采样,支持中文标注。
|
|
170
|
+
5. **确定性测试**:GL 渲染对同一驱动/硬件是确定的,用帧哈希做回归;跨硬件则比较结构相似度。
|
|
171
|
+
|
|
172
|
+
## 7. 依赖文件(pyproject.toml)
|
|
173
|
+
|
|
174
|
+
```toml
|
|
175
|
+
[build-system]
|
|
176
|
+
requires = ["hatchling"]
|
|
177
|
+
build-backend = "hatchling.build"
|
|
178
|
+
|
|
179
|
+
[project]
|
|
180
|
+
name = "gpuqviz"
|
|
181
|
+
version = "0.1.0"
|
|
182
|
+
description = "GPU-accelerated quantum state evolution visualization and video rendering"
|
|
183
|
+
readme = "README.md"
|
|
184
|
+
requires-python = ">=3.10"
|
|
185
|
+
license = { text = "Apache-2.0" }
|
|
186
|
+
dependencies = [
|
|
187
|
+
"numpy>=1.24",
|
|
188
|
+
"cupy-cuda12x>=13.0", # GPU 数组计算
|
|
189
|
+
"moderngl>=5.10", # 离屏 GL 渲染
|
|
190
|
+
"pynvvideocodec>=12.2.72.0", # NVENC 硬编码(NVIDIA 官方包)
|
|
191
|
+
"PyAV>=14.0", # 回退/封装编码器
|
|
192
|
+
"freetype-py>=2.4",
|
|
193
|
+
"trimesh>=4.0",
|
|
194
|
+
"pydantic>=2.6",
|
|
195
|
+
"typer>=0.12",
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
[project.optional-dependencies]
|
|
199
|
+
qiskit = ["qiskit>=1.0", "qiskit-aer>=0.14"]
|
|
200
|
+
qiskit-gpu = ["qiskit>=1.0", "qiskit-aer-gpu>=0.14"]
|
|
201
|
+
preview = ["moderngl-window>=2.4"]
|
|
202
|
+
cpu-fallback = ["numba>=0.59"]
|
|
203
|
+
dev = ["pytest>=8.0", "pytest-cov", "ruff", "mypy"]
|
|
204
|
+
|
|
205
|
+
[project.scripts]
|
|
206
|
+
gpuqviz = "gpuqviz.cli:app"
|
|
207
|
+
|
|
208
|
+
[tool.ruff]
|
|
209
|
+
line-length = 100
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
> 安装:`pip install gpuqviz[qiskit]`;硬件要求:NVIDIA GPU(SM ≥ 6.0,驱动 ≥ 550),CUDA 12.x。无 NVIDIA 卡时自动降级 CPU 后端。
|
|
213
|
+
|
|
214
|
+
## 8. 性能预算(15s @ 60fps = 900 帧,1920×1080,单卡 RTX 3060 级别)
|
|
215
|
+
|
|
216
|
+
| 阶段 | 预估 |
|
|
217
|
+
|---|---|
|
|
218
|
+
| 态演化 + Bloch 向量计算(120 关键帧,CuPy) | < 5 s |
|
|
219
|
+
| 布洛赫球光栅化 ~0.5 ms/帧 × 900 | < 1 s |
|
|
220
|
+
| 热图纹理更新 ~1 ms/帧 | ~1 s |
|
|
221
|
+
| FBO 读回 (pinned) ~2 ms/帧 | ~2 s |
|
|
222
|
+
| NVENC hevc 编码 1080p60 | 实时(< 8 s) |
|
|
223
|
+
| **合计** | **≈ 10–20 s** |
|
|
224
|
+
|
|
225
|
+
对比现状 30 分钟,预期 **100× 左右**加速。瓶颈会转移到 FBO 读回,后续可用 CUDA-GL interop(`cudaGraphicsGLRegisterImage`,经 cuda-python)进一步消除拷贝。
|
|
226
|
+
|
|
227
|
+
## 9. 里程碑
|
|
228
|
+
|
|
229
|
+
1. **M0(1 周)**:骨架 + GLContext/FBO + 纯色帧 → PyAV 编码出片(打通零落盘管线)。
|
|
230
|
+
2. **M1(2 周)**:布洛赫球 renderer + 关键帧 slerp + qiskit 输入,`render_bloch_video` 可用。
|
|
231
|
+
3. **M2(1 周)**:接入 PyNvVideoCodec 显存直喂编码;热图/相位 renderer。
|
|
232
|
+
4. **M3(1 周)**:Scene 声明式 API、SDF 文字、主题、CLI。
|
|
233
|
+
5. **M4(持续)**:CPU 回退后端、CUDA-GL interop 优化、文档与示例、发 PyPI。
|
|
234
|
+
|
|
235
|
+
## 10. 风险与对策
|
|
236
|
+
|
|
237
|
+
- **PyNvVideoCodec API 变动/仅部分格式**:Encoder 抽象层隔离,PyAV nvenc 作为等价回退。
|
|
238
|
+
- **无 NVIDIA GPU 的用户**:CPU 后端(numba 并行软光栅 + libx264)保证可用性,性能仍远好于 matplotlib 方案。
|
|
239
|
+
- **多 qubit 热图维度爆炸**(n>10):限制热图到 ≤ 10 qubit,提示用约化密度矩阵/局域观测渲染。
|
|
240
|
+
- **跨平台(Windows/Linux)GL 离屏**:moderngl 用 EGL/headless 在 Linux 无显示环境可用;Windows 默认 WGL,均无需窗口。
|