Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
"dockerfile": "Dockerfile"
},
"remoteUser": "vscode",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"version": "22"
}
},
"customizations": {
"vscode": {
"settings": {
Expand Down
54 changes: 42 additions & 12 deletions .github/workflows/docpages.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Simple workflow for deploying static content to GitHub Pages
# Build the Fumadocs site under docs/ and deploy it to GitHub Pages
name: Documentation

# specify which events will trigger this workflow
Expand All @@ -19,7 +19,7 @@ on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
Expand All @@ -37,10 +37,20 @@ env:
jobs:
build:
runs-on: ubuntu-latest

defaults:
run:
working-directory: docs

env:
# The site is served from algorithmiq.github.io/src-method.
NEXT_PUBLIC_BASE_PATH: /src-method

steps:
- name: Checkout
uses: actions/checkout@v7
with:
# grab the history, so hatch-vcs can compute the version number
fetch-depth: 0

- name: Install the latest version of uv
Expand All @@ -49,21 +59,42 @@ jobs:
enable-cache: true
python-version: "3.14"

- name: Install package
run: |
uv sync --group docs
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: 22
cache: npm
cache-dependency-path: docs/package-lock.json

- name: Python environment information
- name: Install dependencies
run: |
uv tree
uv sync --no-dev --group docs
npm ci

- name: Get src_method version
run: |
uv run python -c "import src_method; print(src_method.__version__)"
uv run --no-sync python -c "import src_method; print(src_method.__version__)"

- name: Generate the API reference
run: |
uv run --no-sync python scripts/gen_api_dump.py src_method -d .
node scripts/generate-api.mjs

- name: Run the examples in the prose pages
working-directory: .
run: >-
uv run --no-sync python -m pytest --markdown-docs -p no:cacheprovider
docs/content/docs
--ignore=docs/content/docs/api
--ignore=docs/content/docs/tutorials

- name: Execute the tutorial notebooks
run: |
uv run --no-sync python scripts/notebooks_to_mdx.py

- name: Build docs
- name: Build the static site
run: |
uv run mkdocs build
npm run build

- name: Setup Pages
if: ${{ github.ref == 'refs/heads/main' }}
Expand All @@ -73,8 +104,7 @@ jobs:
if: ${{ github.ref == 'refs/heads/main' }}
uses: actions/upload-pages-artifact@v5
with:
# Upload entire repository
path: site
path: docs/out

deploy:
if: ${{ github.ref == 'refs/heads/main' }}
Expand Down
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ dist/
downloads/
eggs/
.eggs/
lib/
# using lib/ would exclude the docs/src/lib directory used by next.js
/lib/
lib64/
parts/
sdist/
Expand Down Expand Up @@ -172,8 +173,6 @@ venv.bak/
# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
Expand Down
17 changes: 12 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ tensor, so there is no wrapper type.
skipped lint is a red PR.
- Changes to the API or to user-facing behavior -- developers included, e.g.
workflows or test layout -- belong in the docs and, when relevant, in
`README.md`. `docs/developer-guide/` covers versioning, dependencies and how
to write tests; read it before changing any of those.
`README.md`. `docs/content/docs/contributing/` covers versioning,
dependencies, tests and the docs site; read it before changing any of those.
Python blocks in the docs pages run in CI: keep them self-contained, or mark
them `python notest`.

## Git and PRs

Expand All @@ -49,8 +51,9 @@ Package `src/src_method/`: `apply.py` and `compress.py` are the public entry
points, `_tensor_train.py` holds the shared train helpers, `utils/_backend.py`
the NumPy/CuPy dispatch and `utils/linalg.py` the decompositions. Tests in
`tests/`, benchmarks in `benches/` with recorded results in
`baseline-benchmarks/`, MkDocs sources in `docs/`, throwaway scripts in
`sandbox/`.
`baseline-benchmarks/`, the Fumadocs site in `docs/` (MDX pages in
`docs/content/docs/`, tutorial notebooks in `docs/notebooks/`), throwaway
scripts in `sandbox/`.

`src/src_method/_version.py` is generated by `hatch-vcs` -- never edit it.

Expand All @@ -65,9 +68,13 @@ uv run pytest -m "not slow" # fast suite
uv run pytest # everything
uv run ruff check src/ tests/
uv run ty check src/
uv run mkdocs serve
```

Docs site (Node.js 22+), from `docs/`: `npm ci`, then
`uv run python scripts/gen_api_dump.py src_method -d .`,
`node scripts/generate-api.mjs`, `uv run python scripts/notebooks_to_mdx.py`
and `npm run dev`.

## Notes

- `filterwarnings = ["error"]` is on: a stray warning fails the suite. Networks
Expand Down
30 changes: 18 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Successive Randomized Compression

[![Documentation](https://github.com/Algorithmiq/src-method/actions/workflows/docpages.yml/badge.svg)](https://docs.algorithmiq.fi/src-method)
[![Documentation](https://github.com/Algorithmiq/src-method/actions/workflows/docpages.yml/badge.svg)](https://algorithmiq.github.io/src-method/)
[![Test src_method](https://github.com/Algorithmiq/src-method/actions/workflows/test.yml/badge.svg)](https://github.com/Algorithmiq/src-method/actions/workflows/test.yml)
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)

Expand All @@ -25,7 +25,7 @@ from src_method import apply, compress, src

The `apply` function covers cases 1 and 2 above, the `compress` function cases 3 and 4, and `src` all five: `apply` and `compress` are its two- and one-train special cases. All three functions are pure, meaning no in-place modification ever happens. The user should
manage the assignment of the returned objects, possibly overwriting the input variables.
See the [reference documentation](algorithmiq.github.io/src_method/) for details, and the [tests](tests/) or [benchmarks](benches/) folders for usage examples.
See the [reference documentation](https://algorithmiq.github.io/src-method/) for details, and the [tests](tests/) or [benchmarks](benches/) folders for usage examples.

Whether a train is an MPS or an MPO is inferred from the rank of its first site tensor, so no wrapper type is needed.

Expand Down Expand Up @@ -193,18 +193,23 @@ you. Run `prek install --prepare-hooks` once after the first `nix develop`.

## Documentation

We use [MkDocs] to generate our documentation pages. You can find the latest version [at this link].
The documentation is a [Fumadocs] site under `docs/`, published [at this link].
It covers concepts, features, tutorials, the API reference generated from the
docstrings, and the developer guide.

We encourage you to build the documentation locally, so you can check that newer
documentation you might have added looks as it should.
To preview it locally you need [Node.js] 22 or later:

To do so, open a terminal in [Visual Studio Code] and run:

```
mkdocs serve
```bash
uv sync --group docs
cd docs
npm ci
uv run python scripts/gen_api_dump.py src_method -d .
node scripts/generate-api.mjs
uv run python scripts/notebooks_to_mdx.py
npm run dev
```

the editor will prompt you to open a new page in your browser, where you can see the rendered documentation.
and open http://localhost:3000. See [`docs/README.md`](docs/README.md) for details.

[DevContainer]: https://containers.dev/
[Docker]: https://docs.docker.com/get-docker/
Expand All @@ -214,5 +219,6 @@ the editor will prompt you to open a new page in your browser, where you can see
[Nix]: https://nixos.org/download/
[direnv]: https://direnv.net/
[uv]: https://docs.astral.sh/uv/
[MkDocs]: https://www.mkdocs.org/
[at this link]: https://docs.algorithmiq.fi/src_method
[Fumadocs]: https://fumadocs.dev
[Node.js]: https://nodejs.org
[at this link]: https://algorithmiq.github.io/src-method/
31 changes: 31 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# deps
/node_modules

# generated content
.source
# griffe dump + generated API reference and tutorial MDX (produced by
# docs/scripts/gen_api_dump.py, generate-api.mjs and notebooks_to_mdx.py)
/src_method.json
/content/docs/api/
/content/docs/tutorials/

# test & build
/coverage
/.next/
/out/
/build
*.tsbuildinfo

# misc
.DS_Store
*.pem
/.pnp
.pnp.js
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# others
.env*.local
.vercel
next-env.d.ts
27 changes: 27 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# src_method documentation site

A [Fumadocs](https://fumadocs.dev) (Next.js) application, exported as static
files and deployed to GitHub Pages by `.github/workflows/docpages.yml`.

- `content/docs/` holds the hand-written MDX pages; `meta.json` files order the
sidebar.
- `notebooks/<name>/<name>.ipynb` are the tutorials, executed at build time.
- `scripts/` generate the API reference from the docstrings and the tutorial
pages from the notebooks.
- `src/` is the Next.js app: layout, components and routes.

Build it from the repository root with Node.js 22 or later:

```bash
uv sync --group docs
cd docs
npm ci
uv run python scripts/gen_api_dump.py src_method -d .
node scripts/generate-api.mjs
uv run python scripts/notebooks_to_mdx.py
npm run dev # live preview on http://localhost:3000
npm run build # static export in out/
```

The Documenting page of the site (`content/docs/contributing/documenting.mdx`)
covers writing pages, cross-references, citations and tutorials.
Binary file removed docs/assets/algo_symbol.png
Binary file not shown.
33 changes: 33 additions & 0 deletions docs/bibliography.bib
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@ARTICLE{camano2026src,
title = "{Successive randomized compression: A randomized algorithm for the compressed MPO-MPS product}",
author = "Camaño, Chris and Epperly, Ethan N. and Tropp, Joel A.",
journal = "Quantum",
volume = 10,
pages = 2022,
year = 2026,
doi = "10.22331/q-2026-03-10-2022",
eprint = "2504.06475",
archivePrefix = "arXiv"
}

@ARTICLE{halko2011finding,
title = "{Finding structure with randomness: Probabilistic algorithms for constructing approximate matrix decompositions}",
author = "Halko, Nathan and Martinsson, Per-Gunnar and Tropp, Joel A.",
journal = "SIAM Review",
volume = 53,
number = 2,
pages = "217--288",
year = 2011,
doi = "10.1137/090771806"
}

@ARTICLE{gray2018quimb,
title = "{quimb: A python package for quantum information and many-body calculations}",
author = "Gray, Johnnie",
journal = "Journal of Open Source Software",
volume = 3,
number = 29,
pages = 819,
year = 2018,
doi = "10.21105/joss.00819"
}
53 changes: 53 additions & 0 deletions docs/content/docs/benchmarks.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: Benchmarks
description: Accuracy and timing of SRC against quimb and against pairwise application.
---

The benchmark scripts live in
[`benches/`](https://github.com/Algorithmiq/src-method/tree/main/benches) and need
the `bench` dependency group. Each folder's README holds the full tables and the
commands to reproduce them.

## Primitives

[`benches/primitives`](https://github.com/Algorithmiq/src-method/tree/main/benches/primitives)
compares the MPO-MPO product against `quimb`'s contract-then-compress on the
Leonardo supercomputer at CINECA. One MPO is random, the other a slightly
perturbed identity, so the product is highly compressible.

| Experiment | CPUs | quimb (s) | src (s) | Speedup |
|---|---|---|---|---|
| 50 sites, $\chi = 50$ | 32 | 164.97 | 11.92 | 13.8x |
| 20 sites, $\chi = 100$ | 32 | 2004.52 | 94.83 | 21x |
| 25 sites, $\chi = 1000$, $\chi_{\text{id}} = 4$ | 112 | 501.82 (rsvd) | 71.01 | 7x |
| 50 sites, $\chi = 1000$, $\chi_{\text{id}} = 4$ | 112 | 1187.82 (rsvd) | 150.11 | 8x |

At $\chi = 1000$, SRC also used about a sixth of the peak memory of `quimb`.

## Stacks

[`benches/stack`](https://github.com/Algorithmiq/src-method/tree/main/benches/stack)
compares one sweep over a [stack](/features/stacks), `src(A_1, ..., A_k, psi)`,
with pairwise application truncating after every product, as a function of the
number of trains.

- One sweep over the whole stack is at best moderately more accurate. For random
stacks ending in an MPS it has about 20 % lower median error at depth 4; for
random MPO products the gain is at most 8 %; for Trotter layers there is no
systematic difference.
- Both methods sit 2-15x above the best possible error at the same bond
dimension, so the randomized sketch, not compounding across layers, dominates
the error.
- The per-site cost grows with $\chi^2$ times the product of the layer bonds.
Thin Trotter layers run at 0.6-1.4x the pairwise time up to depth 5, while
random MPOs of bond 8 and 16 at depth 4 are 30x and 136x slower.

| Stack | Depth | $\chi$ | one sweep (s) | pairwise (s) | ratio |
|---|---|---|---|---|---|
| Trotter, 1 layer + MPS | 2 | 64 | 0.0764 | 0.0642 | 1.19 |
| Trotter, 2 layers + MPS | 3 | 64 | 0.0936 | 0.147 | 0.639 |
| Trotter, 3 layers + MPS | 4 | 64 | 0.201 | 0.207 | 0.975 |
| Trotter, 4 layers + MPS | 5 | 64 | 0.384 | 0.283 | 1.36 |
| random $D=8$, 2 layers + MPS | 3 | 64 | 1.67 | 0.52 | 3.21 |
| random $D=8$, 3 layers + MPS | 4 | 64 | 24.7 | 0.837 | 29.5 |
| random $D=16$, 3 layers + MPS | 4 | 64 | 316 | 2.33 | 136 |
Loading
Loading