Skip to content

Commit d3bc7f2

Browse files
committed
refactor: harden package structure and add tensor inspector
1 parent f08982d commit d3bc7f2

48 files changed

Lines changed: 2476 additions & 1059 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
fail-fast: false
3535
matrix:
3636
os: [ubuntu-latest, windows-latest]
37-
python-version: ["3.12"]
37+
python-version: ["3.12", "3.13"]
3838

3939
runs-on: ${{ matrix.os }}
4040

@@ -50,12 +50,15 @@ jobs:
5050
- name: Install build tool
5151
run: python -m pip install build==1.4.2
5252

53-
- name: Build wheel
54-
run: python scripts/verify.py wheel
53+
- name: Build package artifacts
54+
run: python scripts/verify.py package
5555

5656
- name: Create wheel test venv
5757
run: python -m venv .wheel-venv
5858

59+
- name: Create sdist test venv
60+
run: python -m venv .sdist-venv
61+
5962
- name: Install wheel (Linux)
6063
if: runner.os != 'Windows'
6164
run: .wheel-venv/bin/python -m pip install dist/*.whl
@@ -73,6 +76,23 @@ jobs:
7376
if: runner.os == 'Windows'
7477
run: .wheel-venv\Scripts\python -c "import matplotlib; matplotlib.use('Agg'); import tensor_network_viz; from tensor_network_viz import PlotConfig, pair_tensor, show_tensor_network; trace=[pair_tensor('A', 'x', 'r0', 'ab,b->a')]; fig, _ = show_tensor_network(trace, engine='einsum', view='2d', config=PlotConfig(tensor_label_refinement='never'), show=False); assert fig is not None"
7578

79+
- name: Install sdist (Linux)
80+
if: runner.os != 'Windows'
81+
run: .sdist-venv/bin/python -m pip install dist/*.tar.gz
82+
83+
- name: Install sdist (Windows)
84+
if: runner.os == 'Windows'
85+
run: .sdist-venv\Scripts\python -m pip install (Get-ChildItem dist\*.tar.gz | Select-Object -First 1).FullName
86+
87+
- name: Smoke sdist import and render (Linux)
88+
if: runner.os != 'Windows'
89+
run: |
90+
.sdist-venv/bin/python -c "import matplotlib; matplotlib.use('Agg'); import tensor_network_viz; from tensor_network_viz import PlotConfig, pair_tensor, show_tensor_network; trace=[pair_tensor('A', 'x', 'r0', 'ab,b->a')]; fig, _ = show_tensor_network(trace, engine='einsum', view='2d', config=PlotConfig(tensor_label_refinement='never'), show=False); assert fig is not None"
91+
92+
- name: Smoke sdist import and render (Windows)
93+
if: runner.os == 'Windows'
94+
run: .sdist-venv\Scripts\python -c "import matplotlib; matplotlib.use('Agg'); import tensor_network_viz; from tensor_network_viz import PlotConfig, pair_tensor, show_tensor_network; trace=[pair_tensor('A', 'x', 'r0', 'ab,b->a')]; fig, _ = show_tensor_network(trace, engine='einsum', view='2d', config=PlotConfig(tensor_label_refinement='never'), show=False); assert fig is not None"
95+
7696
lint-and-test:
7797
strategy:
7898
fail-fast: false

CONTRIBUTING.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,26 @@ With the project venv (Windows):
4949

5050
Add tests for new features or bug fixes. All tests must pass before opening a PR.
5151

52+
### Optional: focused smoke and performance runs
53+
54+
Pytest markers are available for the render-specific regression checks:
55+
56+
```bash
57+
pytest -m smoke
58+
pytest -m perf
59+
```
60+
61+
Use `smoke` for lightweight draw sanity checks and `perf` for runtime-sensitive guards.
62+
For larger local comparisons outside CI, run:
63+
64+
```bash
65+
python scripts/bench_render_workflows.py
66+
```
67+
68+
That benchmark compares first render vs repeated render, network object vs list input,
69+
and static render vs interactive controls through the public `show_tensor_network(...)`
70+
entry point.
71+
5272
### Optional: manual example smoke checks
5373

5474
Automated tests do not open interactive Matplotlib windows. After **`pytest`** passes, sanity-check **layout and drawing** by running the examples below from the **repository root** (with **`pip install -r requirements.dev.txt`** or the matching optional extras). Run **one command at a time** (each line is a separate invocation).
@@ -163,7 +183,10 @@ Adding a new engine (e.g. a new tensor-network library) requires:
163183
- `graph.py` — convert backend-native objects to `_GraphData` (see `_core/graph.py`)
164184
- `renderer.py` — implement `plot_<engine>_network_2d` and `plot_<engine>_network_3d` using the shared `_core` drawing layer
165185
- `__init__.py` — export the two plot functions
166-
2. **Registration** in `config.py` (add to `EngineName`) and `_registry.py` (add to `_ENGINE_CONFIG`).
186+
2. **Registration** in `config.py` / `_engine_specs.py`:
187+
- add the new literal to `EngineName`
188+
- add the module/function triple to `ENGINE_MODULE_MAP` in `src/tensor_network_viz/_engine_specs.py`
189+
- `_registry.py` reads that map to resolve the public plotters
167190
3. **Optional dependency** in `pyproject.toml` under `[project.optional-dependencies]`.
168191
4. **Tests** in `tests/test_integration_<engine>.py` and optional `tests/test_<engine>_backend.py`.
169192
5. **Example script** in `examples/<engine>_demo.py` and an entry in `examples/README.md`.

examples/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,14 @@ When `--no-show` or `--save` is used, the launcher calls
8080
```bash
8181
python examples/run_demo.py einsum ellipsis --view 2d --scheme
8282
python examples/run_demo.py einsum mps --view 2d --scheme --playback
83+
python examples/run_demo.py einsum mps --view 2d --tensor-inspector
8384
python examples/run_demo.py tenpy chain --view 2d --scheme
8485
```
8586

87+
For the linked tensor inspector, use an auto-traced `EinsumTrace` example such as `mps`, `mpo`,
88+
`peps`, `ellipsis`, or `nway`. Manual `--from-scratch` / `--from-list` variants do not carry the
89+
live tensor values needed by the inspector.
90+
8691
## Useful Options
8792

8893
| Option | Meaning |
@@ -95,6 +100,7 @@ python examples/run_demo.py tenpy chain --view 2d --scheme
95100
| `--scheme` | Draw contraction-scheme overlays when available. |
96101
| `--playback` | Start with contraction playback enabled. |
97102
| `--hover-cost` | Show contraction-cost details in the playback panel. |
103+
| `--tensor-inspector` | Open the linked tensor inspector for `EinsumTrace` playback. |
98104
| `--from-scratch` | Use the manual builder when that example supports it. |
99105
| `--from-list` | Pass list/iterable input when supported. |
100106
| `--save [PATH]` | Save the figure. If omitted, use the auto-generated path. |

examples/demo_cli.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class ExampleCliArgs:
3232
scheme: bool
3333
playback: bool
3434
hover_cost: bool
35+
tensor_inspector: bool
3536
from_scratch: bool
3637
from_list: bool
3738
save: Path | None
@@ -168,6 +169,12 @@ def build_run_demo_parser() -> argparse.ArgumentParser:
168169
default=False,
169170
help_text="Show contraction-cost details during playback; also enables scheme rendering.",
170171
)
172+
add_bool_flag(
173+
parser,
174+
name="tensor-inspector",
175+
default=False,
176+
help_text="Open the linked tensor inspector for EinsumTrace playback examples.",
177+
)
171178
add_bool_flag(
172179
parser,
173180
name="from-scratch",
@@ -235,6 +242,7 @@ def namespace_to_cli_args(namespace: argparse.Namespace) -> ExampleCliArgs:
235242
scheme=bool(namespace.scheme),
236243
playback=bool(namespace.playback),
237244
hover_cost=bool(namespace.hover_cost),
245+
tensor_inspector=bool(namespace.tensor_inspector),
238246
from_scratch=bool(namespace.from_scratch),
239247
from_list=bool(namespace.from_list),
240248
save=namespace.save,
@@ -309,6 +317,7 @@ def finalize_demo_plot_config(
309317
getattr(args, "scheme", False)
310318
or getattr(args, "playback", False)
311319
or getattr(args, "hover_cost", False)
320+
or getattr(args, "tensor_inspector", False)
312321
)
313322
return PlotConfig(
314323
show_tensor_labels=labels_nodes,
@@ -318,6 +327,7 @@ def finalize_demo_plot_config(
318327
contraction_scheme_by_name=scheme_tensor_names if scheme_enabled else None,
319328
contraction_playback=bool(getattr(args, "playback", False)),
320329
contraction_scheme_cost_hover=bool(getattr(args, "hover_cost", False)),
330+
contraction_tensor_inspector=bool(getattr(args, "tensor_inspector", False)),
321331
)
322332

323333

0 commit comments

Comments
 (0)