From 915c24dc7b6502fe5d9206dbc286a51238c1f7cd Mon Sep 17 00:00:00 2001 From: jaunatisblue Date: Fri, 15 May 2026 09:32:26 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B5=9B=E5=89=8D=E7=A8=B3=E5=AE=9A=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- benchmark_cpu_expectation.py | 216 +++- docs/contest_runners.md | 254 ++++ hostfile | 4 +- src/qibotn/backends/__init__.py | 2 +- src/qibotn/backends/cpu.py | 397 ++++++- src/qibotn/backends/quimb.py | 39 +- src/qibotn/backends/vidal.py | 273 ++++- src/qibotn/backends/vidal_mpi_segment.py | 228 +++- src/qibotn/backends/vidal_tebd.py | 120 +- src/qibotn/circuit_convertor.py | 27 +- src/qibotn/circuit_to_mps.py | 22 +- src/qibotn/csrc/torch_contractor.cpp | 1024 +++++++++++++++++ src/qibotn/eval.py | 55 +- src/qibotn/expectation_runner.py | 17 +- src/qibotn/mps_contraction_helper.py | 15 +- src/qibotn/mps_utils.py | 22 +- src/qibotn/parallel.py | 299 ++++- src/qibotn/torch_contractor.py | 252 ++++ tests/test_cpu_backend.py | 58 +- tests/test_vidal_backend.py | 237 +++- tools/baseline_mps_expectation.py | 28 +- tools/example_tn_case.py | 33 + tools/inspect_contraction_tree.py | 208 ++++ tools/manage_tn_dask_cluster.sh | 223 ++++ tools/mps_contest_runner.py | 313 +++++ tools/run_tn_custom.py | 243 ++++ tools/run_vidal_mpi_contest_cases.sh | 340 ++++++ tools/slice_existing_tree.py | 59 + tools/tn_contest_runner.py | 435 +++++++ tools/torch_profile_tn_complex64.py | 114 ++ tools/vidal_mpi_contest_runner.py | 209 ++++ .../main1_long_z_string_34q20l_auto.pkl | Bin 0 -> 448972 bytes trees/contest_tn/main1_ring_xz_8q2l_s1.pkl | Bin 0 -> 3304 bytes .../smoke_rxx_rzz_34q20l_xz_auto.pkl | Bin 0 -> 451176 bytes .../smoke_rxx_rzz_34q20l_xz_repeat192.pkl | Bin 0 -> 452967 bytes .../smoke_rxx_rzz_34q20l_xz_timeout_stop.pkl | Bin 0 -> 452824 bytes trees/rxx_rzz_30q20l.pkl | Bin 0 -> 399477 bytes .../rxx_rzz_30q20l_from_existing_s2_check.pkl | Bin 0 -> 393004 bytes trees/rxx_rzz_30q20l_from_existing_s4.pkl | Bin 0 -> 393004 bytes trees/rxx_rzz_34q20l_s4.pkl | Bin 0 -> 455270 bytes 40 files changed, 5542 insertions(+), 224 deletions(-) create mode 100644 docs/contest_runners.md create mode 100644 src/qibotn/csrc/torch_contractor.cpp create mode 100644 src/qibotn/torch_contractor.py create mode 100644 tools/example_tn_case.py create mode 100644 tools/inspect_contraction_tree.py create mode 100755 tools/manage_tn_dask_cluster.sh create mode 100644 tools/mps_contest_runner.py create mode 100644 tools/run_tn_custom.py create mode 100755 tools/run_vidal_mpi_contest_cases.sh create mode 100644 tools/slice_existing_tree.py create mode 100644 tools/tn_contest_runner.py create mode 100644 tools/torch_profile_tn_complex64.py create mode 100644 tools/vidal_mpi_contest_runner.py create mode 100644 trees/contest_tn/main1_long_z_string_34q20l_auto.pkl create mode 100644 trees/contest_tn/main1_ring_xz_8q2l_s1.pkl create mode 100644 trees/contest_tn/smoke_rxx_rzz_34q20l_xz_auto.pkl create mode 100644 trees/contest_tn/smoke_rxx_rzz_34q20l_xz_repeat192.pkl create mode 100644 trees/contest_tn/smoke_rxx_rzz_34q20l_xz_timeout_stop.pkl create mode 100644 trees/rxx_rzz_30q20l.pkl create mode 100644 trees/rxx_rzz_30q20l_from_existing_s2_check.pkl create mode 100644 trees/rxx_rzz_30q20l_from_existing_s4.pkl create mode 100644 trees/rxx_rzz_34q20l_s4.pkl diff --git a/benchmark_cpu_expectation.py b/benchmark_cpu_expectation.py index 9141849..3d5897d 100644 --- a/benchmark_cpu_expectation.py +++ b/benchmark_cpu_expectation.py @@ -3,6 +3,10 @@ from __future__ import annotations import argparse +import os +import subprocess +from pathlib import Path +from urllib.parse import urlparse from qibotn.benchmark_cases import ( CIRCUITS, @@ -19,6 +23,51 @@ from qibotn.expectation_runner import ( ) +def optional_int(text): + if isinstance(text, str) and text.lower() in {"none", "null", "inf", "unlimited"}: + return None + return int(text) + + +def optional_float(text): + if isinstance(text, str) and text.lower() in {"none", "null", "inf", "unlimited"}: + return None + return float(text) + + +def format_optional(value, fmt="g"): + return "None" if value is None else format(value, fmt) + + +def should_stop_dask(args): + return ( + not args.keep_dask + and args.tn_search_backend == "dask" + and args.dask_address is not None + and args.tn_load_tree is None + ) + + +def stop_dask_cluster(args, rank): + if rank != 0 or not should_stop_dask(args): + return + script = Path(__file__).resolve().parent / "tools" / "manage_tn_dask_cluster.sh" + if not script.exists(): + print(f"dask_stop_skipped reason=missing_script path={script}", flush=True) + return + + env = os.environ.copy() + parsed = urlparse(args.dask_address) + if parsed.hostname: + env.setdefault("SCHEDULER_HOST", parsed.hostname) + if parsed.port: + env.setdefault("SCHEDULER_PORT", str(parsed.port)) + + print("dask_stop_after_search start", flush=True) + subprocess.run([str(script), "stop"], cwd=str(script.parent.parent), env=env, check=False) + print("dask_stop_after_search done", flush=True) + + def build_parallel_opts(args): slicing_opts = {} if args.tn_target_slices is not None: @@ -31,11 +80,24 @@ def build_parallel_opts(args): "search_workers": args.tn_search_workers or args.torch_threads, "max_repeats": args.tn_search_repeats, "max_time": args.tn_search_time, + "print_stats": not args.no_tn_stats, } if args.tn_search_backend is not None: opts["search_backend"] = args.tn_search_backend if args.dask_address is not None: opts["dask_address"] = args.dask_address + if args.tn_save_tree is not None: + opts["save_tree_path"] = args.tn_save_tree + if args.tn_load_tree is not None: + opts["load_tree_path"] = args.tn_load_tree + if args.tn_search_only: + opts["search_only"] = True + if args.tn_debug_trials: + opts["debug_trials"] = True + if args.tn_contract_implementation is not None: + opts["contract_implementation"] = args.tn_contract_implementation + if args.dask_close_workers: + opts["dask_close_workers"] = True return opts @@ -43,10 +105,16 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument("--nqubits", type=int, default=40) parser.add_argument("--nlayers", type=int, default=30) - parser.add_argument("--bond", "--bonds", dest="bond", type=int, default=1024) - parser.add_argument("--cut-ratio", type=float, default=1e-12) + parser.add_argument("--bond", "--bonds", dest="bond", type=optional_int, default=1024) + parser.add_argument("--cut-ratio", type=optional_float, default=1e-12) parser.add_argument("--seed", type=int, default=42) parser.add_argument("--torch-threads", type=int, default=8) + parser.add_argument("--quimb-backend", choices=("numpy", "torch"), default="torch") + parser.add_argument( + "--dtype", + choices=("complex128", "complex64"), + default="complex128", + ) parser.add_argument("--ansatz", choices=("tn", "mps"), default=None) parser.add_argument("--mps", action="store_true") parser.add_argument("--mpi", action="store_true") @@ -56,19 +124,62 @@ def main(): parser.add_argument("--observables", nargs="+", default=["ring_xz"]) parser.add_argument("--pauli-pattern") parser.add_argument("--tn-target-slices", type=int) - parser.add_argument("--tn-target-size", type=int) + parser.add_argument("--tn-target-size", type=int,default=2**32) parser.add_argument("--tn-search-workers", type=int) parser.add_argument("--tn-search-repeats", type=int, default=128) parser.add_argument("--tn-search-time", type=float, default=60.0) + parser.add_argument( + "--no-tn-stats", + action="store_true", + help="Do not print per-term TN search/contraction diagnostics.", + ) parser.add_argument( "--tn-search-backend", choices=("processpool", "dask"), + default="dask", help="Path-search backend. In MPI mode, dask search runs only on rank 0 and broadcasts the tree.", ) parser.add_argument( "--dask-address", help="Dask scheduler address, for example tcp://host:8786. If omitted with dask search, a local cluster is created.", ) + parser.add_argument( + "--dask-close-workers", + action="store_true", + help="After dask path search, ask the scheduler to close all currently connected workers.", + ) + parser.add_argument( + "--keep-dask", + action="store_true", + help=( + "Keep an external dask cluster running after search. By default, " + "tools/manage_tn_dask_cluster.sh stop is called after search when " + "--dask-address is used." + ), + ) + parser.add_argument( + "--tn-save-tree", + help="Save searched cotengra contraction tree(s) to this pickle file.", + ) + parser.add_argument( + "--tn-load-tree", + help="Load cotengra contraction tree(s) from this pickle file and skip path search.", + ) + parser.add_argument( + "--tn-search-only", + action="store_true", + help="Only run path search and optional --tn-save-tree; skip contraction.", + ) + parser.add_argument( + "--tn-debug-trials", + action="store_true", + help="Print dask worker summary and per-trial worker start/done logs.", + ) + parser.add_argument( + "--tn-contract-implementation", + choices=("auto", "cotengra", "autoray", "cpp"), + help="cotengra contraction implementation for TN contraction.", + ) args = parser.parse_args() ansatz = "mps" if args.mps else (args.ansatz or "tn") @@ -89,6 +200,8 @@ def main(): bond=args.bond, cut_ratio=args.cut_ratio, tensor_module="torch", + quimb_backend=args.quimb_backend, + dtype=args.dtype, torch_threads=args.torch_threads, parallel_opts=build_parallel_opts(args), ) @@ -98,47 +211,74 @@ def main(): print( f"backend=cpu ansatz={ansatz.upper()} mode={mode} " f"nqubits={args.nqubits} nlayers={args.nlayers} " - f"bond={args.bond} cut_ratio={args.cut_ratio:g} seed={args.seed} " + f"bond={format_optional(args.bond)} " + f"cut_ratio={format_optional(args.cut_ratio)} seed={args.seed} " + f"quimb_backend={args.quimb_backend} dtype={args.dtype} " f"torch_threads={args.torch_threads} " - f"tn_search_backend={args.tn_search_backend or 'processpool'}" + f"tn_search_backend={args.tn_search_backend}" ) print("circuit observable exact value abs_error rel_error seconds") - for circuit_kind in circuits: - circuit = build_circuit(circuit_kind, args.nqubits, args.nlayers, args.seed) - named_observables = ( - [(f"pattern:{args.pauli_pattern}", {"pauli_string_pattern": args.pauli_pattern})] - if args.pauli_pattern - else [ - (obs_kind, terms_to_dict(observable_terms(obs_kind, args.nqubits))) - for obs_kind in observables - ] - ) + try: + for circuit_kind in circuits: + circuit = build_circuit(circuit_kind, args.nqubits, args.nlayers, args.seed) + named_observables = ( + [(f"pattern:{args.pauli_pattern}", {"pauli_string_pattern": args.pauli_pattern})] + if args.pauli_pattern + else [ + (obs_kind, terms_to_dict(observable_terms(obs_kind, args.nqubits))) + for obs_kind in observables + ] + ) - for obs_name, observable in named_observables: - exact = None - if args.exact and rank == 0: - if args.nqubits > args.exact_max_qubits: - raise ValueError( - f"--exact is limited to {args.exact_max_qubits} qubits by default." + for obs_name, observable in named_observables: + exact = None + if args.exact and rank == 0: + if args.nqubits > args.exact_max_qubits: + raise ValueError( + f"--exact is limited to {args.exact_max_qubits} qubits by default." + ) + exact = exact_for_observable(circuit, observable, args.nqubits) + + result = run_cpu_expectation(circuit, observable, config) + if args.mpi and result.rank != 0: + continue + + abs_error = float("nan") if exact is None else abs(result.value - exact) + rel_error = ( + float("nan") + if exact is None + else abs_error / max(abs(exact), 1e-15) + ) + exact_text = "nan" if exact is None else f"{exact:.16e}" + print( + f"{circuit_kind} {obs_name} {exact_text} {result.value:.16e} " + f"{abs_error:.6e} {rel_error:.6e} {result.seconds:.3f}" + ) + for stat in result.parallel_stats or (): + cost = stat["path_cost"] + search_stats = stat.get("search_stats", {}) + print( + "tn_term_summary " + f"term={stat.get('term_index', 0)} " + f"search_seconds={stat.get('search_seconds', float('nan')):.3f} " + f"contract_seconds={stat.get('contract_seconds', float('nan')):.3f} " + f"completed_trials={search_stats.get('completed_trials', 'na')} " + f"finite_trials={search_stats.get('finite_trials', 'na')} " + f"failed_trials={search_stats.get('failed_trials', 'na')} " + f"requested_trials={search_stats.get('requested_trials', 'na')} " + f"best_score={search_stats.get('best_score', float('nan')):.6g} " + f"slices={cost['nslices']} " + f"log10_flops={cost['log10_flops']:.3f} " + f"log10_write={cost['log10_write']:.3f} " + f"log2_size={cost['log2_size']:.3f} " + f"log10_combo={cost['log10_combo']:.3f} " + f"peak_memory_gib={cost['peak_memory_gib']:.6g} " + f"slicing_overhead={cost['slicing_overhead']:.6g} " + f"rank_slices={stat.get('rank_slices', 'na')}" ) - exact = exact_for_observable(circuit, observable, args.nqubits) - - result = run_cpu_expectation(circuit, observable, config) - if args.mpi and result.rank != 0: - continue - - abs_error = float("nan") if exact is None else abs(result.value - exact) - rel_error = ( - float("nan") - if exact is None - else abs_error / max(abs(exact), 1e-15) - ) - exact_text = "nan" if exact is None else f"{exact:.16e}" - print( - f"{circuit_kind} {obs_name} {exact_text} {result.value:.16e} " - f"{abs_error:.6e} {rel_error:.6e} {result.seconds:.3f}" - ) + finally: + stop_dask_cluster(args, rank) if __name__ == "__main__": diff --git a/docs/contest_runners.md b/docs/contest_runners.md new file mode 100644 index 0000000..28c0d33 --- /dev/null +++ b/docs/contest_runners.md @@ -0,0 +1,254 @@ +# Contest Runners + +This directory contains two self-contained contest entrypoints: + +- `tools/tn_contest_runner.py`: general tensor-network path search and contraction. +- `tools/mps_contest_runner.py`: Vidal/MPS multi-node expectation runner. + +Both scripts keep circuit and observable definitions inside the script so a +contest case can be edited in one place. + +## Environment + +Run commands from the repository root: + +```bash +cd /home/yx/qibotn +``` + +For Intel MPI on two nodes, use the known working style: + +```bash +mpirun -np 4 -hostfile /home/yx/qibotn/hostfile -perhost 2 ... +``` + +Set `TCM_ENABLE=1` for CPU runs: + +```bash +export TCM_ENABLE=1 +``` + +## TN Workflow + +List built-in TN contest cases: + +```bash +python -u tools/tn_contest_runner.py list +``` + +TN path search uses dask by default. Without `--dask-address`, the script starts +a local dask cluster. For multiple servers, start one scheduler and workers +with the helper script, then pass the scheduler address to the search command. + +Start the default two-node dask cluster: + +```bash +cd /home/yx/qibotn +tools/manage_tn_dask_cluster.sh start +``` + +Check status: + +```bash +cd /home/yx/qibotn +tools/manage_tn_dask_cluster.sh status +``` + +Stop the cluster: + +```bash +cd /home/yx/qibotn +tools/manage_tn_dask_cluster.sh stop +``` + +The helper defaults are: + +```bash +SCHEDULER_HOST=10.20.1.103 +WORKER_HOSTS="10.20.1.103 10.20.1.102" +NWORKERS=48 +NTHREADS=1 +ROOT_DIR=/home/yx/qibotn +PYTHON_BIN=.venv/bin/python +DASK_WORKER_TTL="24 hours" +DASK_TICK_LIMIT="30 minutes" +DASK_LOST_WORKER_TIMEOUT="30 minutes" +``` + +Override them inline if needed: + +```bash +WORKER_HOSTS="10.20.1.103 10.20.1.102" NWORKERS=48 \ + tools/manage_tn_dask_cluster.sh restart +``` + +Check that both nodes are connected by adding `--tn-debug-trials` to a small +search. The output should include `qibotn_dask_workers` with both hosts. + +`tools/tn_contest_runner.py search` stops the external dask cluster after the +search phase by default. Pass `--keep-dask` if you want to reuse the same dask +cluster for several searches. + +Use enough trials to fill the cluster. With the default two-node setup there are +96 worker slots, so `--tn-search-repeats` should be at least 96. The contest +runner default is 2048. + +Cotengra trials are CPU-bound and can hold the Python GIL long enough for dask +to report `Event loop was unresponsive`. Dask defaults are much more aggressive: +`scheduler.worker-ttl=5 minutes`, `admin.tick.limit=3s`, and +`deploy.lost-worker-timeout=15s`. The helper script raises these limits so +workers are not killed by dask during search. The intended timeout is +`--tn-search-time`; after that, the runner stops the external dask cluster. + +Small correctness check against statevector: + +```bash +python -u tools/tn_contest_runner.py validate \ + --case main1 \ + --nqubits 8 \ + --nlayers 2 \ + --torch-threads 4 \ + --tn-search-repeats 8 \ + --tn-search-time 5 +``` + +Search and save contraction trees: + +```bash +TCM_ENABLE=1 python -u tools/tn_contest_runner.py search \ + --case main1 \ + --torch-threads 48 \ + --dtype complex64 \ + --dask-address tcp://10.20.1.103:8786 \ + --tn-search-repeats 2048 \ + --tn-search-time 300 +``` + +Contract using the saved tree on one node: + +```bash +TCM_ENABLE=1 mpirun -np 2 python -u tools/tn_contest_runner.py contract \ + --mpi \ + --case main1 \ + --torch-threads 48 \ + --dtype complex64 +``` + +Contract using the saved tree on two nodes: + +```bash +TCM_ENABLE=1 mpirun -np 4 -hostfile /home/yx/qibotn/hostfile -perhost 2 \ + python -u tools/tn_contest_runner.py contract \ + --mpi \ + --case main1 \ + --torch-threads 48 \ + --dtype complex64 +``` + +Run search and contract in one command: + +```bash +TCM_ENABLE=1 python -u tools/tn_contest_runner.py all \ + --case main1 \ + --torch-threads 48 \ + --dtype complex64 \ + --dask-address tcp://10.20.1.103:8786 \ + --tn-search-repeats 2048 \ + --tn-search-time 300 +``` + +Run only selected observables: + +```bash +python -u tools/tn_contest_runner.py search \ + --case main2 \ + --observables open_zz +``` + +Tree files are written to `trees/contest_tn/` by default. The tree filename +contains case, observable, qubit count, layer count, and target slice count. +If any of these change, search again. + +Edit TN contest cases in `tools/tn_contest_runner.py`: + +- `CASES`: case name, circuit kind, observable list, default scale. +- `build_circuit`: circuit definitions. +- `pauli_sum_observable`: observable definitions. + +## MPS Workflow + +List built-in Vidal/MPS contest cases: + +```bash +python -u tools/mps_contest_runner.py list +``` + +Small correctness check against statevector: + +```bash +mpirun -np 2 python -u tools/mps_contest_runner.py validate \ + --case main1 \ + --nqubits 8 \ + --nlayers 2 \ + --bond 64 \ + --torch-threads 4 +``` + +Run one MPS case on one node: + +```bash +TCM_ENABLE=1 mpirun -np 2 python -u tools/mps_contest_runner.py run \ + --case main1 \ + --torch-threads 48 +``` + +Run one MPS case on two nodes: + +```bash +TCM_ENABLE=1 mpirun -np 4 -hostfile /home/yx/qibotn/hostfile -perhost 2 \ + python -u tools/mps_contest_runner.py run \ + --case main1 \ + --torch-threads 48 +``` + +Run only one observable: + +```bash +TCM_ENABLE=1 mpirun -np 4 -hostfile /home/yx/qibotn/hostfile -perhost 2 \ + python -u tools/mps_contest_runner.py run \ + --case main1 \ + --observables ring_xz \ + --torch-threads 48 +``` + +Override scale: + +```bash +TCM_ENABLE=1 mpirun -np 4 -hostfile /home/yx/qibotn/hostfile -perhost 2 \ + python -u tools/mps_contest_runner.py run \ + --case main1 \ + --nqubits 128 \ + --nlayers 24 \ + --bond 1024 \ + --torch-threads 48 +``` + +Edit MPS contest cases in `tools/mps_contest_runner.py`: + +- `CASES`: case name, circuit kind, observable list, default scale and bond. +- `build_circuit`: circuit definitions. +- `observable`: observable definitions, including dense local terms. + +## Notes + +- TN uses path search plus contraction. Reuse tree files only for the exact same + circuit, observable, qubit count, layer count, seed, and slicing setup. +- TN path search defaults to dask. Use `--tn-search-backend processpool` only + for fallback/debugging. +- Prefer the default `--tn-target-size 4294967296` memory target. Do not force + `--tn-target-slices` unless you have already verified that cotengra can find + valid trees for that exact setting. +- MPS/Vidal does not use contraction-tree search. It runs the circuit directly + and reports `trunc_sum` and `trunc_max`. +- Default TN contraction is the stable torch/quimb path. Do not pass + `--tn-contract-implementation cpp` for contest runs. diff --git a/hostfile b/hostfile index 338d16a..e596b93 100644 --- a/hostfile +++ b/hostfile @@ -1,2 +1,2 @@ -10.20.6.74 -#10.20.6.102 \ No newline at end of file +10.20.1.103:2 +10.20.1.102:2 diff --git a/src/qibotn/backends/__init__.py b/src/qibotn/backends/__init__.py index f2c1189..954f793 100644 --- a/src/qibotn/backends/__init__.py +++ b/src/qibotn/backends/__init__.py @@ -30,7 +30,7 @@ class MetaBackend: elif platform == "quimb": # pragma: no cover import qibotn.backends.quimb as qmb - quimb_backend = kwargs.get("quimb_backend", "numpy") + quimb_backend = kwargs.get("quimb_backend", "torch") contraction_optimizer = kwargs.get("contraction_optimizer", "auto-hq") return qmb.BACKENDS[quimb_backend]( quimb_backend=quimb_backend, contraction_optimizer=contraction_optimizer diff --git a/src/qibotn/backends/cpu.py b/src/qibotn/backends/cpu.py index 0abe8f7..5259fe0 100644 --- a/src/qibotn/backends/cpu.py +++ b/src/qibotn/backends/cpu.py @@ -3,6 +3,9 @@ from __future__ import annotations import os +import pickle +import time +from pathlib import Path import numpy as np from qibo import hamiltonians @@ -10,7 +13,12 @@ from qibo.backends import NumpyBackend from qibo.config import raise_error from qibotn.backends.abstract import QibotnBackend -from qibotn.backends.vidal import _symbolic_hamiltonian_to_pauli_terms, _unsupported_reason +from qibotn.backends.vidal import ( + _observable_mpo_tensors, + _operator_terms_to_mpo, + _symbolic_hamiltonian_to_operator_terms, + _unsupported_reason, +) from qibotn.backends.vidal_mpi_segment import SegmentVidalMPIExecutor from qibotn.backends.vidal_tebd import VidalTEBDExecutor from qibotn.observables import check_observable @@ -23,6 +31,51 @@ def _as_bool_or_dict(value, name): raise TypeError(f"{name} has an unexpected type") +def _bind_numa_node(rank): + """Bind the calling process (or thread) to the NUMA node for *rank*. + + The MPI rank is converted to a local (per-node) rank through the + environment variables commonly set by Open MPI, MVAPICH, and Slurm. + The process CPU affinity and NUMA memory policy are set accordingly. + + Returns the NUMA domain that was selected, or ``None`` if the binding + could not be determined. + """ + local_rank = rank + for name in ( + "OMPI_COMM_WORLD_LOCAL_RANK", + "MV2_COMM_WORLD_LOCAL_RANK", + "MPI_LOCALRANKID", + "SLURM_LOCALID", + ): + try: + local_rank = int(os.environ[name]) + break + except (KeyError, ValueError): + pass + + domain = local_rank % 2 + cpulist = f"/sys/devices/system/node/node{domain}/cpulist" + try: + cpus = _parse_cpu_list(open(cpulist, encoding="utf-8").read().strip()) + if cpus: + os.sched_setaffinity(0, cpus) + except (FileNotFoundError, OSError): + pass + + try: + import ctypes + + libnuma = ctypes.CDLL("libnuma.so.1") + if libnuma.numa_available() >= 0: + libnuma.numa_run_on_node(ctypes.c_int(domain)) + libnuma.numa_set_preferred(ctypes.c_int(domain)) + except Exception: + pass + + return domain + + def _parse_cpu_list(text): cpus = set() for item in text.split(","): @@ -90,8 +143,15 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): ), ) self.tensor_module = runcard.get("tensor_module", "torch") + self.dtype = runcard.get("dtype", "complex128") + self.compile_circuit = bool(runcard.get("compile_circuit", False)) + self.preprocess = bool(runcard.get("preprocess", False)) + self.mpi_term_batch_size = runcard.get( + "mpi_term_batch_size", + runcard.get("term_batch_size", None), + ) self.torch_threads = runcard.get("torch_threads", None) - self.quimb_backend = runcard.get("quimb_backend", "numpy") + self.quimb_backend = runcard.get("quimb_backend", "torch") self.contraction_optimizer = runcard.get("contraction_optimizer", "auto-hq") self.parallel_opts = runcard.get("parallel_opts", {}) self.parallel_stats = [] @@ -117,7 +177,8 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): value = self.expectation(circuit, self.observable) if self.MPI_enabled and self.rank > 0: return np.asarray([0], dtype=np.int64) - return np.asarray([value], dtype=np.float64) + dtype = np.complex128 if np.iscomplexobj(value) else np.float64 + return np.asarray([value], dtype=dtype) backend = self._quimb_backend() backend.configure_tn_simulation( @@ -131,13 +192,26 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): return_array=return_array, ) - def expectation(self, circuit, observable=None, preprocess=True, compile_circuit=None): - observable = check_observable(observable, circuit.nqubits) + def expectation(self, circuit, observable=None, preprocess=None, compile_circuit=None): + mpo_tensors = _observable_mpo_tensors(observable, circuit.nqubits) + if mpo_tensors is None: + observable = check_observable(observable, circuit.nqubits) + use_preprocess = self.preprocess if preprocess is None else preprocess + if mpo_tensors is not None and not self.MPS_enabled: + raise_error( + NotImplementedError, + "MPO expectation is currently supported only by the Vidal MPS path.", + ) if self.MPS_enabled: reason = _unsupported_reason(circuit) - if reason is None: - return self._vidal_expectation(circuit, observable) + if reason is None or self.compile_circuit or use_preprocess: + return self._vidal_expectation( + circuit, + observable, + preprocess=use_preprocess, + compile_circuit=compile_circuit, + ) backend = self._quimb_backend() backend.configure_tn_simulation( @@ -149,8 +223,45 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): return self._quimb_expectation_mpi(backend, circuit, observable) return self._quimb_expectation_processpool(backend, circuit, observable) - def _vidal_expectation(self, circuit, observable): - terms = _symbolic_hamiltonian_to_pauli_terms(observable) + def _vidal_expectation( + self, circuit, observable, preprocess=False, compile_circuit=None + ): + if compile_circuit is None: + compile_circuit = self.compile_circuit + if preprocess: + if self.MPI_enabled: + from mpi4py import MPI + + self.rank = MPI.COMM_WORLD.Get_rank() + + from qibotn.backends.vidal import VidalBackend + + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=self.max_bond_dimension, + cut_ratio=self.cut_ratio, + tensor_module=self.tensor_module, + compile_circuit=compile_circuit, + mpi_approach="CT" if self.MPI_enabled else "SR", + mpi_term_batch_size=self.mpi_term_batch_size, + fallback=False, + ) + value = backend.expectation( + circuit, + observable, + preprocess=True, + compile_circuit=compile_circuit, + ) + self.rank = getattr(backend, "rank", self.rank) + self.last_truncation_error = getattr( + backend, "last_truncation_error", np.nan + ) + self.last_max_truncation_error = getattr( + backend, "last_max_truncation_error", np.nan + ) + return value + + mpo_tensors = _observable_mpo_tensors(observable, circuit.nqubits) if self.MPI_enabled: from mpi4py import MPI @@ -164,8 +275,18 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): comm=comm, ) executor.run_circuit(circuit) - value = executor.expectation_pauli_sum_root(terms) - return np.nan if self.rank != 0 else float(np.real(value)) + self.last_truncation_error = float(executor.global_truncation_error()) + self.last_max_truncation_error = float( + executor.global_max_truncation_error() + ) + if mpo_tensors is not None: + value = executor.expectation_mpo_root(mpo_tensors) + else: + terms = _symbolic_hamiltonian_to_operator_terms(observable) + value = executor.expectation_mpo_root( + _operator_terms_to_mpo(terms, circuit.nqubits) + ) + return np.nan if self.rank != 0 else value executor = VidalTEBDExecutor( nqubits=circuit.nqubits, @@ -174,7 +295,12 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): tensor_module=self.tensor_module, ) executor.run_circuit(circuit) - return float(np.real(executor.expectation_pauli_sum(terms))) + self.last_truncation_error = float(executor.truncation_error) + self.last_max_truncation_error = float(executor.max_truncation_error) + if mpo_tensors is not None: + return executor.expectation_mpo(mpo_tensors) + terms = _symbolic_hamiltonian_to_operator_terms(observable) + return executor.expectation_mpo(_operator_terms_to_mpo(terms, circuit.nqubits)) def _quimb_backend(self): import qibotn.backends.quimb as qmb @@ -185,26 +311,7 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): ) def _bind_rank_to_numa_domain(self, rank): - domain = rank % 2 - cpulist = f"/sys/devices/system/node/node{domain}/cpulist" - try: - cpus = _parse_cpu_list(open(cpulist, encoding="utf-8").read().strip()) - if cpus: - os.sched_setaffinity(0, cpus) - except (FileNotFoundError, OSError): - pass - - try: - import ctypes - - libnuma = ctypes.CDLL("libnuma.so.1") - if libnuma.numa_available() >= 0: - libnuma.numa_run_on_node(ctypes.c_int(domain)) - libnuma.numa_set_preferred(ctypes.c_int(domain)) - except Exception: - pass - - self.numa_domain = domain + self.numa_domain = _bind_numa_node(rank) def _default_search_workers(self, nranks=1): if self.torch_threads: @@ -259,6 +366,22 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): search_time = opts.get("max_time", 60) search_backend = opts.get("search_backend") dask_address = opts.get("dask_address") + dask_close_workers = bool(opts.get("dask_close_workers", False)) + print_stats = bool(opts.get("print_stats", False)) + debug_trials = bool(opts.get("debug_trials", False)) + search_only = bool(opts.get("search_only", False)) + save_tree_path = opts.get("save_tree_path") + load_tree_path = opts.get("load_tree_path") + loaded_trees = None + saved_trees = [] + saved_costs = [] + + if load_tree_path: + with Path(load_tree_path).open("rb") as f: + payload = pickle.load(f) + loaded_trees = payload["trees"] if isinstance(payload, dict) else payload + if not isinstance(loaded_trees, (list, tuple)): + loaded_trees = [loaded_trees] qc = backend._qibo_circuit_to_quimb( circuit, @@ -271,7 +394,7 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): total_value = 0.0 + 0.0j terms = extract_gates_and_qubits(observable) - for coeff, factors in terms: + for term_index, (coeff, factors) in enumerate(terms): if not factors: if self.rank == 0: total_value += coeff @@ -297,31 +420,112 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): user_slicing_opts, ) - tree = parallel_path_search( - tn, - tn.outer_inds(), - method="dask" if method != "mpi" and search_backend == "dask" else method, - total_repeats=search_repeats, - max_time=search_time, - n_workers=search_workers, - slicing_opts=slicing_opts, - trial_timeout=opts.get("trial_timeout"), - search_backend=search_backend, - dask_address=dask_address, - ) + if loaded_trees is not None: + if term_index >= len(loaded_trees): + raise ValueError( + f"Loaded tree file has {len(loaded_trees)} tree(s), " + f"but term {term_index} was requested." + ) + tree = loaded_trees[term_index] + search_seconds = 0.0 + if self.rank == 0 and print_stats: + print( + f"tn_tree_loaded term={term_index} path={load_tree_path}", + flush=True, + ) + else: + search_start = time.perf_counter() + tree = parallel_path_search( + tn, + tn.outer_inds(), + method="dask" if method != "mpi" and search_backend == "dask" else method, + total_repeats=search_repeats, + max_time=search_time, + n_workers=search_workers, + slicing_opts=slicing_opts, + trial_timeout=opts.get("trial_timeout"), + search_backend=search_backend, + dask_address=dask_address, + debug_trials=debug_trials, + dask_close_workers=dask_close_workers, + ) + search_seconds = time.perf_counter() - search_start if tree is None: raise RuntimeError("Failed to find a contraction tree for CPU TN MPI.") + if self.parallel_opts.get("contract_implementation") == "cpp": + from qibotn.torch_contractor import prepare_torch_cpp_contractor - if int(getattr(tree, "multiplicity", 1)) <= 1: + prepare_torch_cpp_contractor(tree) + + path_cost = contraction_tree_costs(tree) + search_stats = getattr(tree, "qibotn_search_stats", {}) + if save_tree_path and loaded_trees is None: + saved_trees.append(tree) + saved_costs.append(path_cost) + if self.rank == 0 and print_stats: + print( + "tn_search_done " + f"term={term_index} " + f"search_seconds={search_seconds:.3f} " + f"completed_trials={search_stats.get('completed_trials', 'na')} " + f"finite_trials={search_stats.get('finite_trials', 'na')} " + f"failed_trials={search_stats.get('failed_trials', 'na')} " + f"requested_trials={search_stats.get('requested_trials', search_repeats)} " + f"best_score={search_stats.get('best_score', float('nan')):.6g} " + f"slices={path_cost['nslices']} " + f"log10_flops={path_cost['log10_flops']:.3f} " + f"log10_write={path_cost['log10_write']:.3f} " + f"log2_size={path_cost['log2_size']:.3f} " + f"log10_combo={path_cost['log10_combo']:.3f} " + f"peak_memory_gib={path_cost['peak_memory_gib']:.6g}", + flush=True, + ) + + if search_only: + self.parallel_stats.append( + { + "term_index": term_index, + "term_factors": tuple(factors), + "path_cost": path_cost, + "search_stats": search_stats, + "tree_slices": int(getattr(tree, "multiplicity", 1)), + "slice_assignment": "search_only", + "rank_slices": [], + "search_seconds": search_seconds, + "contract_seconds": 0.0, + "search_workers": search_workers, + "search_repeats": search_repeats, + "search_time": search_time, + "search_backend": search_backend or method, + "dask_address": dask_address, + "numa_domain": getattr(self, "numa_domain", None), + } + ) + continue + + if comm is None and int(getattr(tree, "multiplicity", 1)) <= 1: if self.rank == 0: + contract_start = time.perf_counter() value = self._contract_term_unsliced(tn, tree, backend) + contract_seconds = time.perf_counter() - contract_start + if print_stats: + print( + "tn_contract_done " + f"term={term_index} " + f"contract_seconds={contract_seconds:.3f}", + flush=True, + ) self.parallel_stats.append( { + "term_index": term_index, "term_factors": tuple(factors), - "path_cost": contraction_tree_costs(tree), + "path_cost": path_cost, + "search_stats": search_stats, "tree_slices": 1, "slice_assignment": "root", "rank_slices": [1] + [0] * (size - 1), + "search_seconds": search_seconds, + "contract_seconds": contract_seconds, "search_workers": search_workers, "search_repeats": search_repeats, "search_time": search_time, @@ -334,14 +538,27 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): continue if comm is None: + contract_start = time.perf_counter() value = self._contract_term_unsliced(tn, tree, backend) + contract_seconds = time.perf_counter() - contract_start + if print_stats: + print( + "tn_contract_done " + f"term={term_index} " + f"contract_seconds={contract_seconds:.3f}", + flush=True, + ) self.parallel_stats.append( { + "term_index": term_index, "term_factors": tuple(factors), - "path_cost": contraction_tree_costs(tree), + "path_cost": path_cost, + "search_stats": search_stats, "tree_slices": int(getattr(tree, "multiplicity", 1)), "slice_assignment": "local", "rank_slices": [int(getattr(tree, "multiplicity", 1))], + "search_seconds": search_seconds, + "contract_seconds": contract_seconds, "search_workers": search_workers, "search_repeats": search_repeats, "search_time": search_time, @@ -353,6 +570,7 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): total_value += coeff * complex(np.asarray(value).reshape(-1)[0]) continue + contract_start = time.perf_counter() arrays = self._term_arrays(tn, backend) value, stats = parallel_contract( tree, @@ -360,18 +578,31 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): method="mpi", comm=comm, return_stats=True, + implementation=self.parallel_opts.get("contract_implementation"), ) + contract_seconds = time.perf_counter() - contract_start gathered_stats = comm.gather(stats, root=0) if rank == 0: + if print_stats: + print( + "tn_contract_done " + f"term={term_index} " + f"contract_seconds={contract_seconds:.3f}", + flush=True, + ) self.parallel_stats.append( { + "term_index": term_index, "term_factors": tuple(factors), - "path_cost": contraction_tree_costs(tree), + "path_cost": path_cost, + "search_stats": search_stats, "tree_slices": stats.nslices, "slice_assignment": stats.assignment, "rank_slices": [ item.local_slices for item in gathered_stats ], + "search_seconds": search_seconds, + "contract_seconds": contract_seconds, "search_workers": search_workers, "search_repeats": search_repeats, "search_time": search_time, @@ -382,22 +613,73 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): ) total_value += coeff * complex(np.asarray(value).reshape(-1)[0]) + if self.rank == 0 and save_tree_path and loaded_trees is None: + path = Path(save_tree_path) + path.parent.mkdir(parents=True, exist_ok=True) + with path.open("wb") as f: + pickle.dump( + { + "trees": saved_trees, + "costs": saved_costs, + "nterms": len(saved_trees), + }, + f, + protocol=pickle.HIGHEST_PROTOCOL, + ) + if print_stats: + print( + f"tn_tree_saved path={save_tree_path} nterms={len(saved_trees)}", + flush=True, + ) + + if search_only: + return np.nan + return np.nan if rank != 0 else float(np.real(total_value)) def _contract_term_unsliced(self, tn, tree, backend): + contract_implementation = self.parallel_opts.get("contract_implementation") + if contract_implementation == "cpp": + if backend.backend != "torch": + raise ValueError("contract_implementation='cpp' requires torch backend.") + from qibotn.backends.quimb import _torch_cpu_array, _torch_dtype + from qibotn.torch_contractor import contract_tree_cpp + + arrays = [ + _torch_cpu_array(array, dtype=_torch_dtype(self.dtype)) + for array in tn.arrays + ] + nslices = int(getattr(tree, "multiplicity", 1)) + if nslices > 1: + total = None + for slice_id in range(nslices): + value = contract_tree_cpp(tree, tree.slice_arrays(arrays, slice_id)) + total = value if total is None else total + value + return total + return contract_tree_cpp(tree, arrays) + if backend.backend == "torch": - import torch - from qibotn.backends.quimb import _torch_cpu_array + from qibotn.backends.quimb import _torch_cpu_array, _torch_dtype for tensor in tn.tensors: - tensor._data = _torch_cpu_array(tensor._data, dtype=torch.complex128) - return tn.contract(all, output_inds=(), optimize=tree, backend="torch") + tensor._data = _torch_cpu_array( + tensor._data, + dtype=_torch_dtype(self.dtype), + ) + return tn.contract( + all, + output_inds=(), + optimize=tree, + backend="torch", + implementation=contract_implementation, + ) return tn.contract( all, output_inds=(), optimize=tree, backend=backend.backend, + implementation=contract_implementation, ) def _mpi_slicing_opts(self, user_slicing_opts): @@ -405,11 +687,12 @@ class CpuTensorNet(QibotnBackend, NumpyBackend): def _term_arrays(self, tn, backend): if backend.backend == "torch": - import torch - from qibotn.backends.quimb import _torch_cpu_array + from qibotn.backends.quimb import _torch_cpu_array, _torch_dtype return [ - _torch_cpu_array(array, dtype=torch.complex128) + _torch_cpu_array(array, dtype=_torch_dtype(self.dtype)) for array in tn.arrays ] - return [backend.engine.asarray(array) for array in tn.arrays] + from qibotn.backends.quimb import _numpy_dtype + + return [backend.engine.asarray(array, dtype=_numpy_dtype(self.dtype)) for array in tn.arrays] diff --git a/src/qibotn/backends/quimb.py b/src/qibotn/backends/quimb.py index ea894d9..3d49b00 100644 --- a/src/qibotn/backends/quimb.py +++ b/src/qibotn/backends/quimb.py @@ -62,12 +62,26 @@ def _torch_cpu_array(data, dtype=None): return x -def _arrays_to_backend(arrays, backend, engine): - if backend == "torch": - import torch +def _torch_dtype(dtype): + import torch - return [_torch_cpu_array(array, dtype=torch.complex128) for array in arrays] - return [engine.asarray(array) for array in arrays] + if dtype in ("complex64", "single"): + return torch.complex64 + return torch.complex128 + + +def _numpy_dtype(dtype): + import numpy as np + + if dtype in ("complex64", "single"): + return np.complex64 + return np.complex128 + + +def _arrays_to_backend(arrays, backend, engine, dtype="complex128"): + if backend == "torch": + return [_torch_cpu_array(array, dtype=_torch_dtype(dtype)) for array in arrays] + return [engine.asarray(array, dtype=_numpy_dtype(dtype)) for array in arrays] def _pauli_term_to_dense_operator(factors): @@ -145,7 +159,7 @@ def pauli_product_expectation( return tn.contract(all, output_inds=(), optimize=optimize, backend=backend) -def __init__(self, quimb_backend="numpy", contraction_optimizer="auto-hq"): +def __init__(self, quimb_backend="torch", contraction_optimizer="auto-hq"): super(self.__class__, self).__init__() self.name = "qibotn" @@ -198,7 +212,7 @@ def circuit_ansatz(self): def setup_backend_specifics( - self, quimb_backend="numpy", contractions_optimizer="auto-hq" + self, quimb_backend="torch", contractions_optimizer="auto-hq" ): """Setup backend specifics. Args: @@ -645,7 +659,7 @@ METHODS = { } -def _generate_backend(quimb_backend: str = "numpy"): +def _generate_backend(quimb_backend: str = "torch"): bases = (QibotnBackend,) if quimb_backend == "numpy": @@ -653,9 +667,14 @@ def _generate_backend(quimb_backend: str = "numpy"): bases += (NumpyBackend,) elif quimb_backend == "torch": - from qiboml.backends import PyTorchBackend + try: + from qiboml.backends import PyTorchBackend + except ImportError: + from qibo.backends import NumpyBackend - bases += (PyTorchBackend,) + bases += (NumpyBackend,) + else: + bases += (PyTorchBackend,) elif quimb_backend == "jax": from qiboml.backends import JaxBackend diff --git a/src/qibotn/backends/vidal.py b/src/qibotn/backends/vidal.py index 02c8a93..8fbd4d5 100644 --- a/src/qibotn/backends/vidal.py +++ b/src/qibotn/backends/vidal.py @@ -39,6 +39,162 @@ def _symbolic_hamiltonian_to_pauli_terms(hamiltonian): return terms +def _symbolic_hamiltonian_to_operator_terms(hamiltonian): + terms = [] + factor_pattern = re.compile(r"([^\d]+)(\d+)") + paulis = { + "I": np.eye(2, dtype=np.complex128), + "X": np.array([[0, 1], [1, 0]], dtype=np.complex128), + "Y": np.array([[0, -1j], [1j, 0]], dtype=np.complex128), + "Z": np.array([[1, 0], [0, -1]], dtype=np.complex128), + } + for term in hamiltonian.terms: + ops_by_site = {} + for factor in term.factors: + site = getattr(factor, "target_qubit", None) + matrix = getattr(factor, "matrix", None) + if site is None or matrix is None: + match = factor_pattern.match(str(factor)) + if match is None: + raise ValueError(f"Unsupported observable factor {factor!r}.") + name = match.group(1).upper() + if name not in paulis: + raise ValueError(f"Unsupported observable operator {name!r}.") + site = int(match.group(2)) + matrix = paulis[name] + matrix = np.asarray(matrix, dtype=np.complex128) + site = int(site) + if site in ops_by_site: + ops_by_site[site] = ops_by_site[site] @ matrix + else: + ops_by_site[site] = matrix + terms.append((complex(term.coefficient), tuple(ops_by_site.items()))) + return terms + + +def _dense_operator_to_product_terms(coeff, qubits, matrix): + """Expand a dense k-local operator into product-matrix terms. + + The dense matrix basis is ordered by the provided ``qubits`` sequence. For + example, ``qubits=[2, 5]`` means matrix rows/columns are ordered as + ``|q2 q5>``. + """ + qubits = tuple(int(qubit) for qubit in qubits) + if len(set(qubits)) != len(qubits): + raise ValueError("Dense observable qubits must be unique.") + matrix = np.asarray(matrix, dtype=np.complex128) + dim = 2 ** len(qubits) + if matrix.shape != (dim, dim): + raise ValueError( + "Dense observable matrix shape must be " + f"({dim}, {dim}) for {len(qubits)} qubits." + ) + + units = [ + np.array([[1, 0], [0, 0]], dtype=np.complex128), + np.array([[0, 1], [0, 0]], dtype=np.complex128), + np.array([[0, 0], [1, 0]], dtype=np.complex128), + np.array([[0, 0], [0, 1]], dtype=np.complex128), + ] + terms = [] + for row in range(dim): + for col in range(dim): + value = complex(coeff) * complex(matrix[row, col]) + if value == 0: + continue + ops = [] + for offset, site in enumerate(qubits): + shift = len(qubits) - offset - 1 + out_bit = (row >> shift) & 1 + in_bit = (col >> shift) & 1 + ops.append((site, units[2 * out_bit + in_bit])) + terms.append((value, tuple(ops))) + return terms + + +def _dense_observable_to_operator_terms(observable): + if not isinstance(observable, dict): + return None + + if "matrix" in observable: + terms = [observable] + else: + terms = observable.get("dense_terms") + if terms is None: + raw_terms = observable.get("terms") + if not raw_terms or not any("matrix" in term for term in raw_terms): + return None + terms = raw_terms + + operator_terms = [] + for term in terms: + if "matrix" not in term: + raise ValueError("Dense observable terms must include a matrix.") + qubits = term.get("qubits", term.get("sites")) + if qubits is None: + raise ValueError("Dense observable terms must include qubits or sites.") + operator_terms.extend( + _dense_operator_to_product_terms( + term.get("coefficient", 1.0), + qubits, + term["matrix"], + ) + ) + return operator_terms + + +def _operator_terms_to_mpo(terms, nqubits): + """Build an exact direct-sum MPO for product-operator terms. + + This intentionally favors correctness and generality over compression: an + ``m``-term sum becomes an MPO with bond dimension ``m``. Local Hamiltonians + can be compressed later without changing the public expectation path. + """ + identity = np.eye(2, dtype=np.complex128) + expanded_terms = [] + for coeff, ops in terms: + local_ops = [identity for _ in range(nqubits)] + for site, matrix in ops: + site = int(site) + if site < 0 or site >= nqubits: + raise ValueError(f"Observable site {site} is outside the circuit.") + matrix = np.asarray(matrix, dtype=np.complex128) + if matrix.shape != (2, 2): + raise ValueError("Only qubit local operators with shape (2, 2) are supported.") + local_ops[site] = matrix + expanded_terms.append((complex(coeff), local_ops)) + + if not expanded_terms: + raise ValueError("Cannot build an MPO from an empty observable.") + + bond_dim = len(expanded_terms) + mpo = [] + for site in range(nqubits): + left_dim = 1 if site == 0 else bond_dim + right_dim = 1 if site == nqubits - 1 else bond_dim + tensor = np.zeros((left_dim, 2, 2, right_dim), dtype=np.complex128) + for term_index, (coeff, local_ops) in enumerate(expanded_terms): + left = 0 if site == 0 else term_index + right = 0 if site == nqubits - 1 else term_index + op = coeff * local_ops[site] if site == 0 else local_ops[site] + tensor[left, :, :, right] += op + mpo.append(tensor) + return mpo + + +def _observable_mpo_tensors(observable, nqubits=None): + if isinstance(observable, dict): + if "mpo_tensors" in observable: + return observable["mpo_tensors"] + if "mpo" in observable: + return observable["mpo"] + if nqubits is not None: + terms = _dense_observable_to_operator_terms(observable) + if terms is not None: + return _operator_terms_to_mpo(terms, nqubits) + return None + + def _unsupported_reason(circuit): for gate in circuit.queue: name = getattr(gate, "name", gate.__class__.__name__) @@ -71,6 +227,44 @@ def _can_route_non_adjacent(circuit): return True +@dataclass +class _PreparedCircuit: + nqubits: int + queue: list + + +def _decompose_gate_for_mps(gate, nqubits, stack=()): + sites = _gate_sites(gate) + if len(sites) <= 2: + return [gate] + if gate in stack or not hasattr(gate, "decompose"): + name = getattr(gate, "name", gate.__class__.__name__) + raise ValueError(f"gate {name} acts on {len(sites)} qubits") + + free = [qubit for qubit in range(nqubits) if qubit not in sites] + try: + decomposed = gate.decompose(*free, use_toffolis=False, method="standard") + except TypeError: + decomposed = gate.decompose(*free) + if not decomposed or decomposed == [gate]: + name = getattr(gate, "name", gate.__class__.__name__) + raise ValueError(f"gate {name} could not be decomposed for Vidal MPS") + + result = [] + for item in decomposed: + result.extend(_decompose_gate_for_mps(item, nqubits, stack + (gate,))) + return result + + +def _prepare_circuit_for_mps(circuit, decompose=True): + if not decompose: + return circuit + queue = [] + for gate in circuit.queue: + queue.extend(_decompose_gate_for_mps(gate, circuit.nqubits)) + return _PreparedCircuit(nqubits=circuit.nqubits, queue=queue) + + @dataclass class VidalBackend(QibotnBackend, NumpyBackend): """QiboTN backend using Vidal/TEBD when possible. @@ -89,14 +283,16 @@ class VidalBackend(QibotnBackend, NumpyBackend): self.name = "qibotn" self.platform = "vidal" self.precision = "double" + self.rank = 0 self.last_truncation_error = 0.0 + self.last_max_truncation_error = 0.0 self.configure_tn_simulation() def configure_tn_simulation( self, ansatz: str = "MPS", - max_bond_dimension: int = 10, - cut_ratio: float = 1e-9, + max_bond_dimension: int | None = 10, + cut_ratio: float | None = 1e-9, trunc_tracking_mode: str = "C", svd_control: str = "E!", ini_bond_dimension: int = 1, @@ -108,6 +304,7 @@ class VidalBackend(QibotnBackend, NumpyBackend): mpi_num_procs: int = 1, mpi_where_barriers: int = -1, mpi_isometrization: int = -1, + mpi_term_batch_size: int | None = None, fallback: bool = True, ): self.ansatz = ansatz @@ -124,6 +321,7 @@ class VidalBackend(QibotnBackend, NumpyBackend): self.mpi_num_procs = mpi_num_procs self.mpi_where_barriers = mpi_where_barriers self.mpi_isometrization = mpi_isometrization + self.mpi_term_batch_size = mpi_term_batch_size self.fallback = fallback self._fallback_backend = None @@ -157,10 +355,15 @@ class VidalBackend(QibotnBackend, NumpyBackend): raise NotImplementedError(reason) return self._qmatchatea_fallback() + def _preprocess_circuit(self, circuit, compile_circuit): + """Decompose unsupported multi-qubit gates for the local Vidal path.""" + return _prepare_circuit_for_mps(circuit, decompose=True) + def _run_fast_executor(self, circuit, compile_circuit=True): if self.mpi_approach == "CT": from mpi4py import MPI + self.rank = MPI.COMM_WORLD.Get_rank() executor = SegmentVidalMPIExecutor( nqubits=circuit.nqubits, max_bond=self.max_bond_dimension, @@ -169,6 +372,7 @@ class VidalBackend(QibotnBackend, NumpyBackend): comm=MPI.COMM_WORLD, ) else: + self.rank = 0 executor = VidalTEBDExecutor( nqubits=circuit.nqubits, max_bond=self.max_bond_dimension, @@ -183,9 +387,21 @@ class VidalBackend(QibotnBackend, NumpyBackend): backend = self._fallback_or_raise("VidalBackend supports only MPS.") return backend.expectation(circuit, observable, preprocess, compile_circuit) + original_circuit = circuit if compile_circuit is None: compile_circuit = self.compile_circuit + if preprocess: + try: + circuit = self._preprocess_circuit(circuit, compile_circuit) + except Exception as exc: + backend = self._fallback_or_raise( + f"VidalBackend preprocessing failed: {exc}" + ) + return backend.expectation( + original_circuit, observable, preprocess, compile_circuit + ) + reason = _unsupported_reason(circuit) if reason is not None: # Non-adjacent gates can be routed at compile time @@ -193,40 +409,51 @@ class VidalBackend(QibotnBackend, NumpyBackend): pass # proceed with Vidal + SWAP routing else: backend = self._fallback_or_raise(reason) - return backend.expectation(circuit, observable, preprocess, compile_circuit) + return backend.expectation( + original_circuit, observable, preprocess, compile_circuit + ) - # preprocess=True requests qmatchatea-style transpilation to MPS topology. - # The fast path validates MPS-compatibility via _unsupported_reason above; - # if the circuit is already MPS-compatible, preprocessing is a no-op. - # If it isn't, _unsupported_reason already routed to fallback. - # So the fast path skips preprocessing — just warn once. - if preprocess: - import warnings + executor = self._run_fast_executor(circuit, compile_circuit=compile_circuit) + self.last_truncation_error = float( + executor.global_truncation_error() + if hasattr(executor, "global_truncation_error") + else executor.truncation_error + ) + self.last_max_truncation_error = float( + executor.global_max_truncation_error() + if hasattr(executor, "global_max_truncation_error") + else executor.max_truncation_error + ) - warnings.warn( - "VidalBackend fast path does not preprocess circuits. " - "If the circuit passes _unsupported_reason (all gates are " - "MPS-compatible), fast-path execution proceeds directly.", - stacklevel=2, - ) + mpo_tensors = _observable_mpo_tensors(observable, circuit.nqubits) + if mpo_tensors is not None: + if self.mpi_approach == "CT": + value = executor.expectation_mpo_root(mpo_tensors) + from qtealeaves.tooling.mpisupport import MPI + + if MPI is not None and MPI.COMM_WORLD.Get_rank() != 0: + return np.nan + return value + return executor.expectation_mpo(mpo_tensors) hamiltonian = check_observable(observable, circuit.nqubits) try: - terms = _symbolic_hamiltonian_to_pauli_terms(hamiltonian) + terms = _symbolic_hamiltonian_to_operator_terms(hamiltonian) except ValueError as exc: backend = self._fallback_or_raise(str(exc)) - return backend.expectation(circuit, observable, preprocess, compile_circuit) + return backend.expectation( + original_circuit, observable, preprocess, compile_circuit + ) - executor = self._run_fast_executor(circuit, compile_circuit=compile_circuit) - self.last_truncation_error = float(executor.truncation_error) + mpo_tensors = _operator_terms_to_mpo(terms, circuit.nqubits) if self.mpi_approach == "CT": - value = executor.expectation_pauli_sum_root(terms) + value = executor.expectation_mpo_root(mpo_tensors) from qtealeaves.tooling.mpisupport import MPI if MPI is not None and MPI.COMM_WORLD.Get_rank() != 0: return np.nan - return np.real(value) - return np.real(executor.expectation_pauli_sum(terms)) + return value + return executor.expectation_mpo(mpo_tensors) def execute_circuit( self, diff --git a/src/qibotn/backends/vidal_mpi_segment.py b/src/qibotn/backends/vidal_mpi_segment.py index c0742c6..1014588 100644 --- a/src/qibotn/backends/vidal_mpi_segment.py +++ b/src/qibotn/backends/vidal_mpi_segment.py @@ -23,6 +23,7 @@ from qibotn.backends.vidal_tebd import ( _is_two_qubit_batch, _make_two_site_update, _ones, + _real_if_close, _route_non_adjacent_gates, _svd, _tensor_update_from_numpy, @@ -35,6 +36,8 @@ from qibotn.backends.vidal_tebd import ( _EDGE_TAG = 1701 _UPDATE_TAG = 1702 +_EXPECT_ENV_TAG = 1703 +_EXPECT_RESULT_TAG = 1704 def _partition_sites(nsites, nranks): @@ -49,9 +52,9 @@ def _partition_sites(nsites, nranks): @dataclass class SegmentVidalMPIExecutor: nqubits: int - max_bond: int + max_bond: int | None comm: object - cut_ratio: float = 1e-12 + cut_ratio: float | None = 1e-12 tensor_module: str = "torch" def __post_init__(self): @@ -63,6 +66,10 @@ class SegmentVidalMPIExecutor: if self.start == self.end: raise ValueError("SegmentVidalMPIExecutor requires at least one site per rank.") + from qibotn.backends.cpu import _bind_numa_node + + self.numa_domain = _bind_numa_node(self.rank) + self.xp = _backend_module(self.tensor_module) if self.xp is np: self.dtype = np.complex128 @@ -82,11 +89,22 @@ class SegmentVidalMPIExecutor: for bond in range(self.start, self.end + 1) } self._accumulated_truncation_error = 0.0 + self._max_truncation_error = 0.0 @property def truncation_error(self): return self._accumulated_truncation_error + def global_truncation_error(self): + return self.comm.allreduce(self._accumulated_truncation_error, op=MPI.SUM) + + @property + def max_truncation_error(self): + return self._max_truncation_error + + def global_max_truncation_error(self): + return self.comm.allreduce(self._max_truncation_error, op=MPI.MAX) + def owns_site(self, site): return self.start <= site < self.end @@ -270,7 +288,12 @@ class SegmentVidalMPIExecutor: def _install_update(self, update): if isinstance(update["left"], np.ndarray): update = _tensor_update_from_numpy(self.xp, update, self.dtype) - self._accumulated_truncation_error += update.get("truncation_error", 0.0) + truncation_error = update.get("truncation_error", 0.0) + self._accumulated_truncation_error += truncation_error + self._max_truncation_error = max( + self._max_truncation_error, + truncation_error, + ) site = update["site"] if self.owns_site(site): self.gammas[site] = update["left"] @@ -288,26 +311,189 @@ class SegmentVidalMPIExecutor: } return self.comm.gather(payload, root=0) - def expectation_pauli_sum_root(self, terms): - payloads = self.gather_full_state() - if self.rank != 0: - return None - full = VidalTEBDExecutor( - self.nqubits, - self.max_bond, - cut_ratio=self.cut_ratio, - tensor_module=self.tensor_module, + def expectation_pauli_sum_root(self, terms, term_batch_size=None): + paulis = { + "I": self._eye(2), + "X": _asarray(self.xp, [[0, 1], [1, 0]], self.dtype), + "Y": _asarray(self.xp, [[0, -1j], [1j, 0]], self.dtype), + "Z": _asarray(self.xp, [[1, 0], [0, -1]], self.dtype), + } + operator_terms = [ + ( + coeff, + tuple((site, paulis[name.upper()]) for name, site in ops), + ) + for coeff, ops in terms + ] + return self.expectation_operator_sum_root( + operator_terms, + term_batch_size=term_batch_size, ) - for payload in payloads: - for site, tensor in payload["gammas"].items(): - full.gammas[int(site)] = _asarray(self.xp, tensor, self.dtype) - for bond, tensor in payload["lambdas"].items(): - full.lambdas[int(bond)] = _asarray( - self.xp, - tensor, - self.xp.float64 if self.xp is not np else np.float64, + + def expectation_operator_sum_root(self, terms, term_batch_size=None): + if term_batch_size is None: + term_batch_size = max(1, len(terms)) + norm = self._distributed_product_expectation({}) + total = 0.0 + 0.0j + for start in range(0, len(terms), int(term_batch_size)): + batch = terms[start : start + int(term_batch_size)] + values = self._distributed_operator_batch_expectation(batch, norm) + if self.rank == 0: + for (coeff, _), term_value in zip(batch, values): + total += complex(coeff) * complex(term_value) + return None if self.rank != 0 else _real_if_close(total / norm) + + def _eye(self, size): + if self.xp is np: + return np.eye(size, dtype=self.dtype) + return self.xp.eye(size, dtype=self.dtype, device=self.device) + + def _distributed_product_expectation(self, operators): + if self.rank == 0: + env = self._segment_product_environment(operators) + if self.size == 1: + return env.reshape(-1)[0] + self.comm.send(_to_numpy(env), dest=1, tag=_EXPECT_ENV_TAG) + return self.comm.recv(source=self.size - 1, tag=_EXPECT_RESULT_TAG) + + incoming = self.comm.recv(source=self.rank - 1, tag=_EXPECT_ENV_TAG) + env = self._segment_product_environment(operators, incoming) + if self.rank == self.size - 1: + self.comm.send(_to_numpy(env).reshape(-1)[0], dest=0, tag=_EXPECT_RESULT_TAG) + else: + self.comm.send(_to_numpy(env), dest=self.rank + 1, tag=_EXPECT_ENV_TAG) + return None + + def _segment_product_environment(self, operators, incoming=None): + if incoming is None: + env = _asarray( + self.xp, + np.eye(len(self.lambdas[self.start]), dtype=np.complex128), + self.dtype, + ) + else: + env = _asarray(self.xp, incoming, self.dtype) + + identity = self._eye(2) + for site in range(self.start, self.end): + tensor = self.gammas[site] * self.lambdas[site + 1].reshape(1, 1, -1) + op = operators.get(site, identity) + env = self.xp.einsum( + "xy,xsb,st,ytd->bd", env, self._conj(tensor), op, tensor + ) + return env + + def _distributed_operator_batch_expectation(self, terms, norm): + if not terms: + return [] + if all(not ops for _, ops in terms): + return [norm] * len(terms) if self.rank == 0 else None + + batch_ops = [ + {int(site): _asarray(self.xp, matrix, self.dtype) for site, matrix in ops} + for _, ops in terms + ] + if self.rank == 0: + env = self._segment_operator_batch_environment(batch_ops) + if self.size == 1: + return list(env.reshape(len(terms), -1)[:, 0]) + self.comm.send(_to_numpy(env), dest=1, tag=_EXPECT_ENV_TAG) + return self.comm.recv(source=self.size - 1, tag=_EXPECT_RESULT_TAG) + + incoming = self.comm.recv(source=self.rank - 1, tag=_EXPECT_ENV_TAG) + env = self._segment_operator_batch_environment(batch_ops, incoming) + if self.rank == self.size - 1: + values = list(_to_numpy(env).reshape(len(terms), -1)[:, 0]) + self.comm.send(values, dest=0, tag=_EXPECT_RESULT_TAG) + else: + self.comm.send(_to_numpy(env), dest=self.rank + 1, tag=_EXPECT_ENV_TAG) + return None + + def _segment_operator_batch_environment(self, batch_ops, incoming=None): + batch_size = len(batch_ops) + if incoming is None: + dim = len(self.lambdas[self.start]) + env = _asarray( + self.xp, + np.tile(np.eye(dim, dtype=np.complex128), (batch_size, 1, 1)), + self.dtype, + ) + else: + env = _asarray(self.xp, incoming, self.dtype) + + identity = self._eye(2) + for site in range(self.start, self.end): + tensor = self.gammas[site] * self.lambdas[site + 1].reshape(1, 1, -1) + ops = self.xp.stack( + [operators.get(site, identity) for operators in batch_ops], + axis=0, + ) + env = self.xp.einsum( + "nxy,xsb,nst,ytd->nbd", + env, + self._conj(tensor), + ops, + tensor, + ) + return env + + def _conj(self, tensor): + return np.conjugate(tensor) if self.xp is np else tensor.conj() + + def expectation_mpo_root(self, mpo_tensors): + if len(mpo_tensors) != self.nqubits: + raise ValueError( + f"Expected {self.nqubits} MPO tensors, got {len(mpo_tensors)}." + ) + norm = self._distributed_product_expectation({}) + if self.rank == 0: + env = self._segment_mpo_environment(mpo_tensors) + if self.size == 1: + return _real_if_close(env.reshape(-1)[0] / norm) + self.comm.send(_to_numpy(env), dest=1, tag=_EXPECT_ENV_TAG) + value = self.comm.recv(source=self.size - 1, tag=_EXPECT_RESULT_TAG) + return _real_if_close(value / norm) + + incoming = self.comm.recv(source=self.rank - 1, tag=_EXPECT_ENV_TAG) + env = self._segment_mpo_environment(mpo_tensors, incoming) + if self.rank == self.size - 1: + self.comm.send( + _to_numpy(env).reshape(-1)[0], + dest=0, + tag=_EXPECT_RESULT_TAG, + ) + else: + self.comm.send(_to_numpy(env), dest=self.rank + 1, tag=_EXPECT_ENV_TAG) + return None + + def _segment_mpo_environment(self, mpo_tensors, incoming=None): + if incoming is None: + left_dim = len(self.lambdas[self.start]) + env = _asarray( + self.xp, + np.zeros((left_dim, 1, left_dim), dtype=np.complex128), + self.dtype, + ) + env[:, 0, :] = self._eye(left_dim) + else: + env = _asarray(self.xp, incoming, self.dtype) + + for site in range(self.start, self.end): + mpo = _asarray(self.xp, mpo_tensors[site], self.dtype) + if mpo.ndim != 4 or mpo.shape[1:3] != (2, 2): + raise ValueError( + "Each MPO tensor must have shape " + "(left_bond, 2, 2, right_bond)." ) - return full.expectation_pauli_sum(terms) + tensor = self.gammas[site] * self.lambdas[site + 1].reshape(1, 1, -1) + env = self.xp.einsum( + "xlc,xub,lutr,ctd->brd", + env, + self._conj(tensor), + mpo, + tensor, + ) + return env def expectation_ring_xz_root(self): terms = [ diff --git a/src/qibotn/backends/vidal_tebd.py b/src/qibotn/backends/vidal_tebd.py index e2b2640..25f001e 100644 --- a/src/qibotn/backends/vidal_tebd.py +++ b/src/qibotn/backends/vidal_tebd.py @@ -50,10 +50,10 @@ def _transpose(xp, tensor, axes): return np.transpose(tensor, axes) if xp is np else tensor.permute(*axes) -def _vdot_real(xp, left, right): +def _vdot(xp, left, right): if xp is np: - return np.vdot(left.reshape(-1), right.reshape(-1)).real - return xp.vdot(left.reshape(-1), right.reshape(-1)).real + return np.vdot(left.reshape(-1), right.reshape(-1)) + return xp.vdot(left.reshape(-1), right.reshape(-1)) def _to_float(x): @@ -62,6 +62,19 @@ def _to_float(x): return float(x) +def _to_scalar(x): + if hasattr(x, "detach"): + return x.detach().cpu().item() + if isinstance(x, np.ndarray): + return x.item() + return x + + +def _real_if_close(x, tol=1000): + value = np.real_if_close(x, tol=tol) + return value.item() if isinstance(value, np.ndarray) else value + + def _to_numpy(tensor): if hasattr(tensor, "detach"): return tensor.detach().cpu().numpy() @@ -154,8 +167,8 @@ def _safe_inverse(xp, values): @dataclass class VidalTEBDExecutor: nqubits: int - max_bond: int - cut_ratio: float = 1e-12 + max_bond: int | None + cut_ratio: float | None = 1e-12 tensor_module: str = "torch" def __post_init__(self): @@ -175,6 +188,7 @@ class VidalTEBDExecutor: _ones(self.xp, 1, self.dtype, self.device) for _ in range(self.nqubits + 1) ] self._accumulated_truncation_error = 0.0 + self._max_truncation_error = 0.0 def run_circuit(self, circuit, compile_circuit=True): gates = circuit.queue @@ -189,6 +203,10 @@ class VidalTEBDExecutor: def truncation_error(self): return self._accumulated_truncation_error + @property + def max_truncation_error(self): + return self._max_truncation_error + def _apply_gate(self, gate): sites = _gate_sites(gate) matrix = _asarray(self.xp, gate.matrix(), self.dtype) @@ -232,6 +250,10 @@ class VidalTEBDExecutor: update = _make_two_site_update(item, umat, singvals, vh, self.max_bond, self.cut_ratio, self.xp) self._accumulated_truncation_error += update["truncation_error"] + self._max_truncation_error = max( + self._max_truncation_error, + update["truncation_error"], + ) i = update["site"] self.gammas[i] = update["left"] self.gammas[i + 1] = update["right"] @@ -252,25 +274,37 @@ class VidalTEBDExecutor: "Y": _asarray(self.xp, [[0, -1j], [1j, 0]], self.dtype), "Z": _asarray(self.xp, [[1, 0], [0, -1]], self.dtype), } - value = 0.0 + operator_terms = [ + ( + coeff, + tuple((site, paulis[name.upper()]) for name, site in ops), + ) + for coeff, ops in terms + ] + return self.expectation_operator_sum(operator_terms) + + def expectation_operator_sum(self, terms): + value = 0.0 + 0.0j norm = self.norm() for coeff, ops in terms: - ops = tuple((name.upper(), site) for name, site in ops) + operators = { + int(site): _asarray(self.xp, matrix, self.dtype) + for site, matrix in ops + } if len(ops) == 0: term_value = norm - elif len(ops) == 1: - name, site = ops[0] - term_value = _to_float(self._expect_one_site(site, paulis[name])) - elif len(ops) == 2 and abs(ops[0][1] - ops[1][1]) == 1: - (name0, site0), (name1, site1) = sorted(ops, key=lambda item: item[1]) - term_value = _to_float( - self._expect_adjacent(site0, paulis[name0], paulis[name1]) + elif len(operators) == 1: + site, matrix = next(iter(operators.items())) + term_value = _to_scalar(self._expect_one_site(site, matrix)) + elif len(operators) == 2 and abs(max(operators) - min(operators)) == 1: + site0, site1 = sorted(operators) + term_value = _to_scalar( + self._expect_adjacent(site0, operators[site0], operators[site1]) ) else: - operators = {site: paulis[name] for name, site in ops} - term_value = _to_float(self.expect_product_operators(operators)) - value += float(np.real(coeff)) * term_value - return value / norm + term_value = _to_scalar(self.expect_product_operators(operators)) + value += complex(coeff) * complex(term_value) + return _real_if_close(value / norm) def _expect_one_site(self, site, op): theta = self.xp.einsum( @@ -280,7 +314,7 @@ class VidalTEBDExecutor: self.lambdas[site + 1], ) op_theta = self.xp.einsum("us,asb->aub", op, theta) - return _vdot_real(self.xp, theta, op_theta) + return _vdot(self.xp, theta, op_theta) def _expect_adjacent(self, site, op_left, op_right): theta = self.xp.einsum( @@ -292,7 +326,7 @@ class VidalTEBDExecutor: self.lambdas[site + 2], ) op_theta = self.xp.einsum("us,vt,astc->auvc", op_left, op_right, theta) - return _vdot_real(self.xp, theta, op_theta) + return _vdot(self.xp, theta, op_theta) def expect_product_operators(self, operators): env = _asarray(self.xp, [[1.0 + 0.0j]], self.dtype) @@ -303,10 +337,38 @@ class VidalTEBDExecutor: env = self.xp.einsum( "xy,xsb,st,ytd->bd", env, _conj(self.xp, tensor), op, tensor ) - return env.reshape(-1)[0].real + return env.reshape(-1)[0] def norm(self): - return _to_float(self.expect_product_operators({})) + return float(np.real(_to_scalar(self.expect_product_operators({})))) + + def expectation_mpo(self, mpo_tensors): + """Compute `` / ``. + + MPO tensors are expected in ``(left_bond, phys_out, phys_in, right_bond)`` + order, with physical dimension 2 on every site. + """ + if len(mpo_tensors) != self.nqubits: + raise ValueError( + f"Expected {self.nqubits} MPO tensors, got {len(mpo_tensors)}." + ) + env = _asarray(self.xp, [[[1.0 + 0.0j]]], self.dtype) + for site, raw_mpo in enumerate(mpo_tensors): + mpo = _asarray(self.xp, raw_mpo, self.dtype) + if mpo.ndim != 4 or mpo.shape[1:3] != (2, 2): + raise ValueError( + "Each MPO tensor must have shape " + "(left_bond, 2, 2, right_bond)." + ) + tensor = self.gammas[site] * self.lambdas[site + 1].reshape(1, 1, -1) + env = self.xp.einsum( + "xlc,xub,lutr,ctd->brd", + env, + _conj(self.xp, tensor), + mpo, + tensor, + ) + return _real_if_close(_to_scalar(env.reshape(-1)[0]) / self.norm()) def _build_theta_svd_matrix(op, xp, lam_left, lam_mid, lam_right, gamma_left, gamma_right): @@ -328,8 +390,8 @@ def _build_theta_svd_matrix(op, xp, lam_left, lam_mid, lam_right, gamma_left, ga def _choose_bond(singvals, max_bond, cut_ratio, xp): max_possible = int(singvals.shape[0]) - keep = min(max_possible, max_bond) - if cut_ratio > 0 and max_possible > 0: + keep = max_possible if max_bond is None else min(max_possible, int(max_bond)) + if cut_ratio is not None and cut_ratio > 0 and max_possible > 0: threshold = singvals[0] * cut_ratio if xp is np: ratio_keep = int(np.count_nonzero(singvals > threshold)) @@ -415,8 +477,8 @@ class _RoutedTwoQubitGate: name = "routed_two_qubit" control_qubits = () - def __init__(self, original_gate, left_phys, right_phys): - self.target_qubits = (left_phys, right_phys) + def __init__(self, original_gate, physical_sites): + self.target_qubits = tuple(physical_sites) self._matrix = original_gate.matrix() def matrix(self): @@ -447,8 +509,10 @@ def _route_non_adjacent_gates(gates, nqubits): for pos in range(right - 1, left, -1): routed.append(_SWAPGate(pos, pos + 1)) - # Apply the original gate at the adjacent physical positions - routed.append(_RoutedTwoQubitGate(gate, left, left + 1)) + # Apply the original gate in its original qubit order. For gates like + # CNOT(5, 0), sorting the routed sites would swap control and target. + physical_map = {left: left, right: left + 1} + routed.append(_RoutedTwoQubitGate(gate, [physical_map[site] for site in sites])) # Reverse SWAPs to restore original ordering for pos in range(left + 1, right): diff --git a/src/qibotn/circuit_convertor.py b/src/qibotn/circuit_convertor.py index 1c8b3ee..900cdf7 100644 --- a/src/qibotn/circuit_convertor.py +++ b/src/qibotn/circuit_convertor.py @@ -1,6 +1,19 @@ -import cupy as cp import numpy as np +try: + import cupy as cp +except ImportError: # pragma: no cover - exercised on CPU-only installations + cp = None + + +def _require_cupy(): + if cp is None: + raise ImportError( + "The cuQuantum circuit converter requires cupy. " + "Install the GPU dependencies or use the CPU backend." + ) + return cp + # Reference: https://github.com/NVIDIA/cuQuantum/tree/main/python/samples/cutensornet/circuit_converter @@ -19,7 +32,7 @@ class QiboCircuitToEinsum: """ def __init__(self, circuit, dtype="complex128"): - self.backend = cp + self.backend = _require_cupy() self.dtype = getattr(self.backend, dtype) self.init_basis_map(self.backend, dtype) self.init_intermediate_circuit(circuit) @@ -116,7 +129,9 @@ class QiboCircuitToEinsum: required_shape = self.op_shape_from_qubits(len(gate_qubits)) self.gate_tensors.append( ( - cp.asarray(gate.matrix(), dtype=self.dtype).reshape(required_shape), + self.backend.asarray(gate.matrix(), dtype=self.dtype).reshape( + required_shape + ), gate_qubits, ) ) @@ -161,7 +176,7 @@ class QiboCircuitToEinsum: required_shape = self.op_shape_from_qubits(len(gate_qubits)) self.gate_tensors_inverse.append( ( - cp.asarray(gate.matrix()).reshape(required_shape), + self.backend.asarray(gate.matrix()).reshape(required_shape), gate_qubits, ) ) @@ -169,7 +184,7 @@ class QiboCircuitToEinsum: # self.active_qubits is to identify qubits with at least 1 gate acting on it in the whole circuit. self.active_qubits_inverse = np.unique(gates_qubits_inverse) - def get_pauli_gates(self, pauli_map, dtype="complex128", backend=cp): + def get_pauli_gates(self, pauli_map, dtype="complex128", backend=None): """Populate the gates for all pauli operators. Parameters: @@ -180,6 +195,8 @@ class QiboCircuitToEinsum: Returns: A sequence of pauli gates. """ + if backend is None: + backend = _require_cupy() asarray = backend.asarray pauli_i = asarray([[1, 0], [0, 1]], dtype=dtype) pauli_x = asarray([[0, 1], [1, 0]], dtype=dtype) diff --git a/src/qibotn/circuit_to_mps.py b/src/qibotn/circuit_to_mps.py index 680ef9b..48cf55d 100644 --- a/src/qibotn/circuit_to_mps.py +++ b/src/qibotn/circuit_to_mps.py @@ -1,10 +1,23 @@ -import cupy as cp -import cuquantum.bindings.cutensornet as cutn import numpy as np from qibotn.circuit_convertor import QiboCircuitToEinsum from qibotn.mps_utils import apply_gate, initial +try: + import cupy as cp + import cuquantum.bindings.cutensornet as cutn +except ImportError: # pragma: no cover - exercised on CPU-only installations + cp = None + cutn = None + + +def _require_cuquantum(): + if cp is None or cutn is None: + raise ImportError( + "The cuQuantum MPS converter requires cupy and cuquantum. " + "Install the GPU dependencies or use the CPU backend." + ) + class QiboCircuitToMPS: """A helper class to convert Qibo circuit to MPS. @@ -23,6 +36,7 @@ class QiboCircuitToMPS: dtype="complex128", rand_seed=0, ): + _require_cuquantum() np.random.seed(rand_seed) cp.random.seed(rand_seed) @@ -44,4 +58,6 @@ class QiboCircuitToMPS: ) def __del__(self): - cutn.destroy(self.handle) + handle = getattr(self, "handle", None) + if cutn is not None and handle is not None: + cutn.destroy(handle) diff --git a/src/qibotn/csrc/torch_contractor.cpp b/src/qibotn/csrc/torch_contractor.cpp new file mode 100644 index 0000000..9551460 --- /dev/null +++ b/src/qibotn/csrc/torch_contractor.cpp @@ -0,0 +1,1024 @@ +#include + +#include +#include +#include + +#ifdef QIBOTN_USE_MKL +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +using Tensor = torch::Tensor; + +struct ContractOp { + int64_t out_id; + int64_t left_id; + int64_t right_id; + int64_t kind; + std::vector left_perm; + std::vector left_shape; + std::vector right_perm; + std::vector right_shape; + std::vector out_shape; + std::vector out_perm; +}; + +bool env_enabled(const char* name) { + const char* raw = std::getenv(name); + if (raw == nullptr) { + return false; + } + std::string value(raw); + return value == "1" || value == "true" || value == "TRUE" || + value == "yes" || value == "on"; +} + +int env_int(const char* name, int default_value) { + const char* raw = std::getenv(name); + if (raw == nullptr || raw[0] == '\0') { + return default_value; + } + char* end = nullptr; + long value = std::strtol(raw, &end, 10); + if (end == raw || value <= 0) { + return default_value; + } + return static_cast(value); +} + +int64_t env_i64(const char* name, int64_t default_value) { + const char* raw = std::getenv(name); + if (raw == nullptr || raw[0] == '\0') { + return default_value; + } + char* end = nullptr; + long long value = std::strtoll(raw, &end, 10); + if (end == raw || value <= 0) { + return default_value; + } + return static_cast(value); +} + +struct WorkspaceKey { + c10::ScalarType dtype; + c10::DeviceType device_type; + c10::DeviceIndex device_index; + int64_t numel; + + bool operator==(const WorkspaceKey& other) const { + return dtype == other.dtype && device_type == other.device_type && + device_index == other.device_index && numel == other.numel; + } +}; + +struct WorkspaceKeyHash { + size_t operator()(const WorkspaceKey& key) const { + size_t h = static_cast(key.numel); + h ^= static_cast(key.dtype) + 0x9e3779b97f4a7c15ULL + (h << 6) + (h >> 2); + h ^= static_cast(key.device_type) + 0x9e3779b97f4a7c15ULL + (h << 6) + (h >> 2); + h ^= static_cast(key.device_index) + 0x9e3779b97f4a7c15ULL + (h << 6) + (h >> 2); + return h; + } +}; + +class Workspace { + public: + Workspace() + : max_cached_bytes_(read_size_env( + "QIBOTN_CPP_WORKSPACE_MAX_BYTES", + 1LL * 1024 * 1024 * 1024)), + max_buffer_bytes_(read_size_env( + "QIBOTN_CPP_WORKSPACE_MAX_BUFFER_BYTES", + 256LL * 1024 * 1024)) {} + + Tensor acquire( + const std::vector& shape, + c10::ScalarType dtype, + c10::Device device) { + const auto numel = product(shape); + WorkspaceKey key{dtype, device.type(), device.index(), numel}; + auto& bucket = pool_[key]; + Tensor out; + if (!bucket.empty()) { + out = bucket.back(); + bucket.pop_back(); + cached_bytes_ -= tensor_bytes(out); + out.resize_(shape); + } else { + out = torch::empty(shape, torch::TensorOptions().dtype(dtype).device(device)); + } + return out; + } + + void release(const Tensor& x) { + if (!x.defined() || !x.is_contiguous() || x.storage_offset() != 0) { + return; + } + const auto bytes = tensor_bytes(x); + if (bytes > max_buffer_bytes_) { + return; + } + if (cached_bytes_ + bytes > max_cached_bytes_) { + return; + } + WorkspaceKey key{ + x.scalar_type(), + x.device().type(), + x.device().index(), + x.numel(), + }; + pool_[key].push_back(x); + cached_bytes_ += bytes; + } + + private: + static int64_t read_size_env(const char* name, int64_t default_value) { + const char* raw = std::getenv(name); + if (raw == nullptr || raw[0] == '\0') { + return default_value; + } + char* end = nullptr; + const auto value = std::strtod(raw, &end); + if (end == raw || value < 0) { + return default_value; + } + std::string suffix(end); + int64_t multiplier = 1; + if (suffix == "g" || suffix == "G" || suffix == "gb" || suffix == "GB") { + multiplier = 1024LL * 1024 * 1024; + } else if ( + suffix == "m" || suffix == "M" || suffix == "mb" || suffix == "MB") { + multiplier = 1024LL * 1024; + } else if ( + suffix == "k" || suffix == "K" || suffix == "kb" || suffix == "KB") { + multiplier = 1024LL; + } + return static_cast(value * multiplier); + } + + static int64_t product(const std::vector& shape) { + int64_t out = 1; + for (const auto value : shape) { + out *= value; + } + return out; + } + + static int64_t tensor_bytes(const Tensor& x) { + return x.numel() * x.element_size(); + } + + std::unordered_map, WorkspaceKeyHash> pool_; + int64_t cached_bytes_ = 0; + int64_t max_cached_bytes_; + int64_t max_buffer_bytes_; +}; + +struct PreparedTensor { + Tensor tensor; + bool workspace_owned; +}; + +std::vector tensor_sizes(const Tensor& x) { + return std::vector(x.sizes().begin(), x.sizes().end()); +} + +PreparedTensor apply_preparation( + Workspace& workspace, + Tensor x, + const std::vector& perm, + const std::vector& shape) { + bool workspace_owned = false; + if (!perm.empty()) { + x = x.permute(perm); + } + if (!shape.empty()) { + try { + x = x.view(shape); + } catch (const c10::Error&) { + Tensor out = workspace.acquire(shape, x.scalar_type(), x.device()); + out.view(tensor_sizes(x)).copy_(x); + x = out; + workspace_owned = true; + } + } + return PreparedTensor{x, workspace_owned}; +} + +std::vector broadcast_shape( + c10::IntArrayRef left, + c10::IntArrayRef right) { + const auto ndim = std::max(left.size(), right.size()); + std::vector out(ndim, 1); + for (size_t i = 0; i < ndim; ++i) { + const auto li = left.size() < ndim - i ? 1 : left[i - (ndim - left.size())]; + const auto ri = right.size() < ndim - i ? 1 : right[i - (ndim - right.size())]; + if (li != ri && li != 1 && ri != 1) { + throw std::runtime_error("Shapes are not broadcastable."); + } + out[i] = std::max(li, ri); + } + return out; +} + +std::vector matmul_output_shape(const Tensor& left, const Tensor& right) { + if (left.dim() == 2 && right.dim() == 2) { + return {left.size(-2), right.size(-1)}; + } + auto batch = broadcast_shape( + left.sizes().slice(0, left.dim() - 2), + right.sizes().slice(0, right.dim() - 2)); + batch.push_back(left.size(-2)); + batch.push_back(right.size(-1)); + return batch; +} + +std::vector multiply_output_shape(const Tensor& left, const Tensor& right) { + return broadcast_shape(left.sizes(), right.sizes()); +} + +bool direct_cblas_mm(const Tensor& left, const Tensor& right, Tensor& out) { +#ifndef QIBOTN_USE_MKL + return false; +#else + static const bool direct_mkl_enabled = env_enabled("QIBOTN_CPP_DIRECT_MKL"); + if (!direct_mkl_enabled) { + return false; + } + if (left.device().type() != c10::DeviceType::CPU || + right.device().type() != c10::DeviceType::CPU || + out.device().type() != c10::DeviceType::CPU) { + return false; + } + if (left.dim() != 2 || right.dim() != 2 || out.dim() != 2) { + return false; + } + if (!left.is_contiguous() || !right.is_contiguous() || !out.is_contiguous()) { + return false; + } + if (left.scalar_type() != right.scalar_type() || + left.scalar_type() != out.scalar_type()) { + return false; + } + if (left.size(1) != right.size(0) || + out.size(0) != left.size(0) || + out.size(1) != right.size(1)) { + return false; + } + + const int m = static_cast(left.size(0)); + const int k = static_cast(left.size(1)); + const int n = static_cast(right.size(1)); + const int lda = static_cast(left.stride(0)); + const int ldb = static_cast(right.stride(0)); + const int ldc = static_cast(out.stride(0)); + const int mkl_threads = env_int("QIBOTN_CPP_MKL_THREADS", 0); + const int previous_threads = + mkl_threads > 0 ? mkl_set_num_threads_local(mkl_threads) : 0; + + if (left.scalar_type() == c10::ScalarType::ComplexFloat) { + const std::complex alpha(1.0f, 0.0f); + const std::complex beta(0.0f, 0.0f); + cblas_cgemm( + CblasRowMajor, + CblasNoTrans, + CblasNoTrans, + m, + n, + k, + &alpha, + left.data_ptr(), + lda, + right.data_ptr(), + ldb, + &beta, + out.data_ptr(), + ldc); + if (mkl_threads > 0) { + mkl_set_num_threads_local(previous_threads); + } + return true; + } + if (left.scalar_type() == c10::ScalarType::ComplexDouble) { + const std::complex alpha(1.0, 0.0); + const std::complex beta(0.0, 0.0); + cblas_zgemm( + CblasRowMajor, + CblasNoTrans, + CblasNoTrans, + m, + n, + k, + &alpha, + left.data_ptr(), + lda, + right.data_ptr(), + ldb, + &beta, + out.data_ptr(), + ldc); + if (mkl_threads > 0) { + mkl_set_num_threads_local(previous_threads); + } + return true; + } + if (mkl_threads > 0) { + mkl_set_num_threads_local(previous_threads); + } + return false; +#endif +} + +Tensor apply_output_preparation( + Tensor x, + const std::vector& shape, + const std::vector& perm) { + if (!shape.empty()) { + x = x.reshape(shape); + } + if (!perm.empty()) { + x = x.permute(perm); + } + return x; +} + +struct ExecutedOp { + Tensor left; + Tensor right; + bool left_workspace_owned = false; + bool right_workspace_owned = false; +}; + +void release_inputs( + const ContractOp& op, + const ExecutedOp& executed, + size_t ninputs, + std::vector& temps, + Workspace& workspace) { + if (executed.left_workspace_owned) { + workspace.release(executed.left); + } + if (executed.right_workspace_owned) { + workspace.release(executed.right); + } + if (op.left_id >= static_cast(ninputs)) { + workspace.release(temps.at(static_cast(op.left_id))); + temps.at(static_cast(op.left_id)) = Tensor(); + } + if (op.right_id >= static_cast(ninputs)) { + workspace.release(temps.at(static_cast(op.right_id))); + temps.at(static_cast(op.right_id)) = Tensor(); + } +} + +ExecutedOp execute_single_op( + const ContractOp& op, + std::vector& temps, + Workspace& workspace) { + Tensor left = temps.at(static_cast(op.left_id)); + Tensor right = temps.at(static_cast(op.right_id)); + if (!left.defined() || !right.defined()) { + throw std::runtime_error("Contraction plan referenced a released tensor."); + } + + auto prepared_left = apply_preparation(workspace, left, op.left_perm, op.left_shape); + auto prepared_right = apply_preparation(workspace, right, op.right_perm, op.right_shape); + left = prepared_left.tensor; + right = prepared_right.tensor; + + Tensor out; + if (op.kind == 0) { + auto out_shape = matmul_output_shape(left, right); + out = workspace.acquire(out_shape, left.scalar_type(), left.device()); + if (left.dim() == 2 && right.dim() == 2) { + if (!direct_cblas_mm(left, right, out)) { + at::_ops::mm_out::call(left, right, out); + } + } else if (left.dim() == 3 && right.dim() == 3) { + at::_ops::bmm_out::call(left, right, out); + } else { + out = torch::matmul(left, right); + } + } else if (op.kind == 1) { + auto out_shape = multiply_output_shape(left, right); + out = workspace.acquire(out_shape, left.scalar_type(), left.device()); + at::_ops::mul_out::call(left, right, out); + } else { + throw std::runtime_error("Unknown contraction op kind."); + } + + out = apply_output_preparation(out, op.out_shape, op.out_perm); + temps.at(static_cast(op.out_id)) = out; + return ExecutedOp{left, right, prepared_left.workspace_owned, prepared_right.workspace_owned}; +} + +struct GemmBatchKey { + c10::ScalarType dtype; + int64_t m; + int64_t k; + int64_t n; + + bool operator==(const GemmBatchKey& other) const { + return dtype == other.dtype && m == other.m && k == other.k && n == other.n; + } +}; + +struct GemmBatchKeyHash { + size_t operator()(const GemmBatchKey& key) const { + size_t h = static_cast(key.m); + h ^= static_cast(key.k) + 0x9e3779b97f4a7c15ULL + (h << 6) + (h >> 2); + h ^= static_cast(key.n) + 0x9e3779b97f4a7c15ULL + (h << 6) + (h >> 2); + h ^= static_cast(key.dtype) + 0x9e3779b97f4a7c15ULL + (h << 6) + (h >> 2); + return h; + } +}; + +bool static_small_2d_gemm_key( + const ContractOp& op, + int64_t max_flops, + GemmBatchKey& key) { + if (op.kind != 0 || op.left_shape.size() != 2 || op.right_shape.size() != 2) { + return false; + } + const int64_t m = op.left_shape[0]; + const int64_t k = op.left_shape[1]; + const int64_t n = op.right_shape[1]; + if (op.right_shape[0] != k || m * k * n > max_flops) { + return false; + } + key = GemmBatchKey{c10::ScalarType::Undefined, m, k, n}; + return true; +} + +#ifdef QIBOTN_USE_MKL +bool execute_mkl_batch( + const std::vector& op_indices, + const std::vector& ops, + std::vector& temps, + Workspace& workspace, + std::vector& executed) { + if (op_indices.empty()) { + return false; + } + + const auto& first_op = ops[op_indices[0]]; + std::vector lefts; + std::vector rights; + std::vector outs; + lefts.reserve(op_indices.size()); + rights.reserve(op_indices.size()); + outs.reserve(op_indices.size()); + executed.clear(); + executed.reserve(op_indices.size()); + + c10::ScalarType dtype = c10::ScalarType::Undefined; + int m = 0; + int k = 0; + int n = 0; + for (const int op_index : op_indices) { + const auto& op = ops[op_index]; + Tensor left = temps.at(static_cast(op.left_id)); + Tensor right = temps.at(static_cast(op.right_id)); + if (!left.defined() || !right.defined()) { + throw std::runtime_error("Batch contraction referenced a released tensor."); + } + auto prepared_left = apply_preparation(workspace, left, op.left_perm, op.left_shape); + auto prepared_right = apply_preparation(workspace, right, op.right_perm, op.right_shape); + left = prepared_left.tensor; + right = prepared_right.tensor; + if (left.dim() != 2 || right.dim() != 2 || !left.is_contiguous() || + !right.is_contiguous() || left.device().type() != c10::DeviceType::CPU || + right.device().type() != c10::DeviceType::CPU || + left.scalar_type() != right.scalar_type()) { + return false; + } + if (dtype == c10::ScalarType::Undefined) { + dtype = left.scalar_type(); + m = static_cast(left.size(0)); + k = static_cast(left.size(1)); + n = static_cast(right.size(1)); + } + if (left.scalar_type() != dtype || left.size(0) != m || left.size(1) != k || + right.size(0) != k || right.size(1) != n) { + return false; + } + Tensor out = workspace.acquire({m, n}, dtype, left.device()); + if (!out.is_contiguous()) { + return false; + } + lefts.push_back(left); + rights.push_back(right); + outs.push_back(out); + executed.push_back( + ExecutedOp{left, right, prepared_left.workspace_owned, prepared_right.workspace_owned}); + } + + if (dtype != c10::ScalarType::ComplexFloat && dtype != c10::ScalarType::ComplexDouble) { + return false; + } + + const int group_count = 1; + const int group_size[] = {static_cast(op_indices.size())}; + const CBLAS_TRANSPOSE transa[] = {CblasNoTrans}; + const CBLAS_TRANSPOSE transb[] = {CblasNoTrans}; + const int m_array[] = {m}; + const int n_array[] = {n}; + const int k_array[] = {k}; + const int lda[] = {k}; + const int ldb[] = {n}; + const int ldc[] = {n}; + std::vector a_array(op_indices.size()); + std::vector b_array(op_indices.size()); + std::vector c_array(op_indices.size()); + for (size_t i = 0; i < op_indices.size(); ++i) { + a_array[i] = lefts[i].data_ptr(); + b_array[i] = rights[i].data_ptr(); + c_array[i] = outs[i].data_ptr(); + } + + const int mkl_threads = env_int("QIBOTN_CPP_BATCH_MKL_THREADS", 0); + const int previous_threads = + mkl_threads > 0 ? mkl_set_num_threads_local(mkl_threads) : 0; + if (dtype == c10::ScalarType::ComplexFloat) { + const std::complex alpha(1.0f, 0.0f); + const std::complex beta(0.0f, 0.0f); + const void* alpha_array[] = {&alpha}; + const void* beta_array[] = {&beta}; + cblas_cgemm_batch( + CblasRowMajor, + transa, + transb, + m_array, + n_array, + k_array, + alpha_array, + a_array.data(), + lda, + b_array.data(), + ldb, + beta_array, + c_array.data(), + ldc, + group_count, + group_size); + } else { + const std::complex alpha(1.0, 0.0); + const std::complex beta(0.0, 0.0); + const void* alpha_array[] = {&alpha}; + const void* beta_array[] = {&beta}; + cblas_zgemm_batch( + CblasRowMajor, + transa, + transb, + m_array, + n_array, + k_array, + alpha_array, + a_array.data(), + lda, + b_array.data(), + ldb, + beta_array, + c_array.data(), + ldc, + group_count, + group_size); + } + if (mkl_threads > 0) { + mkl_set_num_threads_local(previous_threads); + } + + for (size_t i = 0; i < op_indices.size(); ++i) { + const auto& op = ops[op_indices[i]]; + Tensor out = apply_output_preparation(outs[i], op.out_shape, op.out_perm); + temps.at(static_cast(op.out_id)) = out; + } + return true; +} +#endif + +std::vector list_to_i64_vector(const pybind11::handle& object) { + std::vector values; + for (const auto item : object) { + values.push_back(pybind11::cast(item)); + } + return values; +} + +ContractOp parse_op(const pybind11::handle& object) { + auto tuple = pybind11::cast(object); + if (tuple.size() != 10) { + throw std::runtime_error("Compiled contraction op must have 10 fields."); + } + + ContractOp op; + op.out_id = pybind11::cast(tuple[0]); + op.left_id = pybind11::cast(tuple[1]); + op.right_id = pybind11::cast(tuple[2]); + op.kind = pybind11::cast(tuple[3]); + op.left_perm = list_to_i64_vector(tuple[4]); + op.left_shape = list_to_i64_vector(tuple[5]); + op.right_perm = list_to_i64_vector(tuple[6]); + op.right_shape = list_to_i64_vector(tuple[7]); + op.out_shape = list_to_i64_vector(tuple[8]); + op.out_perm = list_to_i64_vector(tuple[9]); + return op; +} + +std::vector parse_plan(const pybind11::list& plan) { + std::vector ops; + ops.reserve(plan.size()); + for (const auto object : plan) { + ops.push_back(parse_op(object)); + } + return ops; +} + +Tensor run_contract( + const std::vector& arrays, + const std::vector& ops, + int64_t ntemps, + int64_t root_id, + Workspace& workspace) { + c10::InferenceMode inference_guard(true); + std::vector temps(static_cast(ntemps)); + + if (arrays.size() > temps.size()) { + throw std::runtime_error("Temporary tensor table is smaller than input arrays."); + } + for (size_t i = 0; i < arrays.size(); ++i) { + temps[i] = arrays[i]; + } + + for (const auto& op : ops) { + Tensor left = temps.at(static_cast(op.left_id)); + Tensor right = temps.at(static_cast(op.right_id)); + if (!left.defined() || !right.defined()) { + throw std::runtime_error("Contraction plan referenced a released tensor."); + } + + auto prepared_left = apply_preparation(workspace, left, op.left_perm, op.left_shape); + auto prepared_right = apply_preparation(workspace, right, op.right_perm, op.right_shape); + left = prepared_left.tensor; + right = prepared_right.tensor; + + Tensor out; + if (op.kind == 0) { + auto out_shape = matmul_output_shape(left, right); + out = workspace.acquire(out_shape, left.scalar_type(), left.device()); + if (left.dim() == 2 && right.dim() == 2) { + if (!direct_cblas_mm(left, right, out)) { + at::_ops::mm_out::call(left, right, out); + } + } else if (left.dim() == 3 && right.dim() == 3) { + at::_ops::bmm_out::call(left, right, out); + } else { + out = torch::matmul(left, right); + } + } else if (op.kind == 1) { + auto out_shape = multiply_output_shape(left, right); + out = workspace.acquire(out_shape, left.scalar_type(), left.device()); + at::_ops::mul_out::call(left, right, out); + } else { + throw std::runtime_error("Unknown contraction op kind."); + } + + out = apply_output_preparation(out, op.out_shape, op.out_perm); + temps.at(static_cast(op.out_id)) = out; + + if (prepared_left.workspace_owned) { + workspace.release(left); + } + if (prepared_right.workspace_owned) { + workspace.release(right); + } + if (op.left_id >= static_cast(arrays.size())) { + workspace.release(temps.at(static_cast(op.left_id))); + temps.at(static_cast(op.left_id)) = Tensor(); + } + if (op.right_id >= static_cast(arrays.size())) { + workspace.release(temps.at(static_cast(op.right_id))); + temps.at(static_cast(op.right_id)) = Tensor(); + } + } + + Tensor result = temps.at(static_cast(root_id)); + if (!result.defined()) { + throw std::runtime_error("Contraction plan did not produce a result tensor."); + } + return result; +} + +Tensor run_contract_dag( + const std::vector& arrays, + const std::vector& ops, + int64_t ntemps, + int64_t root_id, + Workspace& workspace) { + c10::InferenceMode inference_guard(true); + std::vector temps(static_cast(ntemps)); + if (arrays.size() > temps.size()) { + throw std::runtime_error("Temporary tensor table is smaller than input arrays."); + } + for (size_t i = 0; i < arrays.size(); ++i) { + temps[i] = arrays[i]; + } + + std::unordered_map producer; + producer.reserve(ops.size()); + for (size_t i = 0; i < ops.size(); ++i) { + producer[ops[i].out_id] = static_cast(i); + } + + std::vector> dependents(ops.size()); + std::vector pending_inputs(ops.size(), 0); + std::vector remaining_consumers(static_cast(ntemps), 0); + for (size_t i = 0; i < ops.size(); ++i) { + for (const auto tensor_id : {ops[i].left_id, ops[i].right_id}) { + if (tensor_id >= 0 && tensor_id < ntemps) { + remaining_consumers[static_cast(tensor_id)] += 1; + } + auto it = producer.find(tensor_id); + if (it != producer.end()) { + pending_inputs[i] += 1; + dependents[it->second].push_back(static_cast(i)); + } + } + } + + std::vector ready; + ready.reserve(ops.size()); + for (size_t i = 0; i < ops.size(); ++i) { + if (pending_inputs[i] == 0) { + ready.push_back(static_cast(i)); + } + } + + const bool batch_enabled = env_enabled("QIBOTN_CPP_BATCH_SMALL_GEMM"); + const int min_batch = env_int("QIBOTN_CPP_BATCH_MIN_SIZE", 4); + const int64_t max_flops = env_i64("QIBOTN_CPP_BATCH_MAX_FLOPS", 1000000); + std::vector done(ops.size(), 0); + size_t completed = 0; + + auto mark_consumed_and_release = [&](const ContractOp& op, const ExecutedOp& executed) { + if (executed.left_workspace_owned) { + workspace.release(executed.left); + } + if (executed.right_workspace_owned) { + workspace.release(executed.right); + } + for (const auto tensor_id : {op.left_id, op.right_id}) { + if (tensor_id < static_cast(arrays.size()) || tensor_id < 0) { + continue; + } + auto& count = remaining_consumers[static_cast(tensor_id)]; + count -= 1; + if (count == 0) { + workspace.release(temps.at(static_cast(tensor_id))); + temps.at(static_cast(tensor_id)) = Tensor(); + } + } + }; + + while (completed < ops.size()) { + if (ready.empty()) { + throw std::runtime_error("DAG contractor has no ready ops before completion."); + } + + std::vector to_execute; +#ifdef QIBOTN_USE_MKL + if (batch_enabled) { + std::unordered_map, GemmBatchKeyHash> groups; + for (const int op_index : ready) { + if (done[op_index]) { + continue; + } + GemmBatchKey key; + if (!static_small_2d_gemm_key(ops[op_index], max_flops, key)) { + continue; + } + Tensor left = temps.at(static_cast(ops[op_index].left_id)); + if (!left.defined()) { + continue; + } + key.dtype = left.scalar_type(); + groups[key].push_back(op_index); + } + for (const auto& item : groups) { + if (static_cast(item.second.size()) >= min_batch) { + to_execute = item.second; + break; + } + } + } +#endif + + if (to_execute.empty()) { + to_execute.push_back(ready.back()); + } + + std::vector executed_batch; + bool batch_ok = false; +#ifdef QIBOTN_USE_MKL + if (to_execute.size() > 1) { + batch_ok = execute_mkl_batch(to_execute, ops, temps, workspace, executed_batch); + } +#endif + if (!batch_ok) { + if (to_execute.size() > 1) { + to_execute.resize(1); + } + executed_batch.clear(); + executed_batch.push_back(execute_single_op(ops[to_execute[0]], temps, workspace)); + } + + for (size_t j = 0; j < to_execute.size(); ++j) { + const int op_index = to_execute[j]; + if (done[op_index]) { + continue; + } + done[op_index] = 1; + completed += 1; + mark_consumed_and_release(ops[op_index], executed_batch[j]); + for (const int dep : dependents[op_index]) { + pending_inputs[dep] -= 1; + if (pending_inputs[dep] == 0) { + ready.push_back(dep); + } + } + } + + ready.erase( + std::remove_if( + ready.begin(), + ready.end(), + [&](int op_index) { return done[op_index] != 0; }), + ready.end()); + } + + Tensor result = temps.at(static_cast(root_id)); + if (!result.defined()) { + throw std::runtime_error("DAG contractor did not produce a result tensor."); + } + return result; +} + +Tensor contract_impl( + const std::vector& arrays, + const pybind11::list& plan, + int64_t ntemps, + int64_t root_id) { + auto ops = parse_plan(plan); + Workspace workspace; + return run_contract(arrays, ops, ntemps, root_id, workspace); +} + +class Contractor { + public: + Contractor(const pybind11::list& plan, int64_t ntemps, int64_t root_id) + : ops_(parse_plan(plan)), ntemps_(ntemps), root_id_(root_id) { + compute_batch_summary(); + } + + Tensor contract(const std::vector& arrays) { + if (env_enabled("QIBOTN_CPP_DAG_SCHEDULER")) { + return run_contract_dag(arrays, ops_, ntemps_, root_id_, workspace_); + } + return run_contract(arrays, ops_, ntemps_, root_id_, workspace_); + } + + int64_t nsteps() const { + return static_cast(ops_.size()); + } + + pybind11::dict batch_summary() const { + pybind11::dict out; + out["groups"] = batch_groups_; + out["covered_ops"] = batch_covered_ops_; + out["calls_saved"] = batch_calls_saved_; + return out; + } + + private: + void compute_batch_summary() { + const int min_batch = env_int("QIBOTN_CPP_BATCH_MIN_SIZE", 4); + const int64_t max_flops = env_i64("QIBOTN_CPP_BATCH_MAX_FLOPS", 1000000); + std::unordered_map producer; + for (size_t i = 0; i < ops_.size(); ++i) { + producer[ops_[i].out_id] = static_cast(i); + } + std::vector pending_inputs(ops_.size(), 0); + std::vector> dependents(ops_.size()); + for (size_t i = 0; i < ops_.size(); ++i) { + for (const auto tensor_id : {ops_[i].left_id, ops_[i].right_id}) { + auto it = producer.find(tensor_id); + if (it != producer.end()) { + pending_inputs[i] += 1; + dependents[it->second].push_back(static_cast(i)); + } + } + } + std::vector ready; + for (size_t i = 0; i < ops_.size(); ++i) { + if (pending_inputs[i] == 0) { + ready.push_back(static_cast(i)); + } + } + std::vector done(ops_.size(), 0); + size_t completed = 0; + while (completed < ops_.size() && !ready.empty()) { + std::unordered_map counts; + int best_count = 0; + for (const int op_index : ready) { + GemmBatchKey key; + if (!static_small_2d_gemm_key(ops_[op_index], max_flops, key)) { + continue; + } + key.dtype = c10::ScalarType::ComplexFloat; + int count = ++counts[key]; + best_count = std::max(best_count, count); + } + if (best_count >= min_batch) { + batch_groups_ += 1; + batch_covered_ops_ += best_count; + batch_calls_saved_ += best_count - 1; + } + // Simulate one scheduler step: batch best group if present, otherwise one op. + std::vector executed; + if (best_count >= min_batch) { + GemmBatchKey best_key; + for (const auto& item : counts) { + if (item.second == best_count) { + best_key = item.first; + break; + } + } + for (const int op_index : ready) { + GemmBatchKey key; + if (static_small_2d_gemm_key(ops_[op_index], max_flops, key)) { + key.dtype = c10::ScalarType::ComplexFloat; + if (key == best_key) { + executed.push_back(op_index); + } + } + } + } else { + executed.push_back(ready.back()); + } + for (const int op_index : executed) { + if (done[op_index]) { + continue; + } + done[op_index] = 1; + completed += 1; + for (const int dep : dependents[op_index]) { + pending_inputs[dep] -= 1; + if (pending_inputs[dep] == 0) { + ready.push_back(dep); + } + } + } + ready.erase( + std::remove_if( + ready.begin(), + ready.end(), + [&](int op_index) { return done[op_index] != 0; }), + ready.end()); + } + } + + std::vector ops_; + int64_t ntemps_; + int64_t root_id_; + Workspace workspace_; + int64_t batch_groups_ = 0; + int64_t batch_covered_ops_ = 0; + int64_t batch_calls_saved_ = 0; +}; + +} // namespace + +PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { + m.def( + "contract", + &contract_impl, + "Run a compiled cotengra contraction plan with torch CPU tensors."); + pybind11::class_(m, "Contractor") + .def(pybind11::init()) + .def("contract", &Contractor::contract) + .def("batch_summary", &Contractor::batch_summary) + .def_property_readonly("nsteps", &Contractor::nsteps); +} diff --git a/src/qibotn/eval.py b/src/qibotn/eval.py index ae36893..f2fbf71 100644 --- a/src/qibotn/eval.py +++ b/src/qibotn/eval.py @@ -1,8 +1,3 @@ -import cupy as cp -import cuquantum.bindings.cutensornet as cutn -from cupy.cuda import nccl -from cupy.cuda.runtime import getDeviceCount -from cuquantum.tensornet import Network, contract from mpi4py import MPI from qibotn.circuit_convertor import QiboCircuitToEinsum @@ -15,8 +10,37 @@ from qibotn.observables import ( extract_gates_and_qubits, ) +try: + import cupy as cp + import cuquantum.bindings.cutensornet as cutn + from cupy.cuda import nccl + from cupy.cuda.runtime import getDeviceCount + from cuquantum.tensornet import Network, contract +except ImportError: # pragma: no cover - exercised on CPU-only installations + cp = None + cutn = None + nccl = None + getDeviceCount = None + Network = None + contract = None -def get_ham_gates(pauli_map, dtype="complex128", backend=cp): + +def _require_cuquantum(): + if ( + cp is None + or cutn is None + or nccl is None + or getDeviceCount is None + or Network is None + or contract is None + ): + raise ImportError( + "The legacy GPU evaluation helpers require cupy and cuquantum. " + "Install the GPU dependencies or use the CPU backend." + ) + + +def get_ham_gates(pauli_map, dtype="complex128", backend=None): """Populate the gates for all pauli operators. Parameters: @@ -27,6 +51,13 @@ def get_ham_gates(pauli_map, dtype="complex128", backend=cp): Returns: A sequence of pauli gates. """ + if backend is None: + backend = cp + if backend is None: + raise ImportError( + "get_ham_gates requires an array backend; cupy is unavailable " + "in this CPU-only environment." + ) asarray = backend.asarray pauli_i = asarray([[1, 0], [0, 1]], dtype=dtype) pauli_x = asarray([[0, 1], [1, 0]], dtype=dtype) @@ -46,6 +77,7 @@ def get_ham_gates(pauli_map, dtype="complex128", backend=cp): def initialize_mpi(): """Initialize MPI communication and device selection.""" + _require_cuquantum() comm = MPI.COMM_WORLD rank = comm.Get_rank() size = comm.Get_size() @@ -56,6 +88,7 @@ def initialize_mpi(): def initialize_nccl(comm_mpi, rank, size): """Initialize NCCL communication.""" + _require_cuquantum() nccl_id = nccl.get_unique_id() if rank == 0 else None nccl_id = comm_mpi.bcast(nccl_id, root=0) return nccl.NcclCommunicator(size, nccl_id, rank) @@ -73,6 +106,7 @@ def get_operands(qibo_circ, datatype, rank, comm): def compute_optimal_path(network, n_samples, size, comm): """Compute contraction path and broadcast optimal selection.""" + _require_cuquantum() path, info = network.contract_path( optimize={ "samples": n_samples, @@ -101,6 +135,8 @@ def compute_slices(info, rank, size): def reduce_result(result, comm, method="MPI", root=0): """Reduce results across processes.""" + if method == "NCCL": + _require_cuquantum() if method == "MPI": return comm.reduce(sendobj=result, op=MPI.SUM, root=root) @@ -148,6 +184,7 @@ def dense_vector_tn_MPI(qibo_circ, datatype, n_samples=8): Returns: Dense vector of quantum circuit. """ + _require_cuquantum() comm, rank, size, device_id = initialize_mpi() operands = get_operands(qibo_circ, datatype, rank, comm) network = Network(*operands, options={"device_id": device_id}) @@ -179,6 +216,7 @@ def dense_vector_tn_nccl(qibo_circ, datatype, n_samples=8): Returns: Dense vector of quantum circuit. """ + _require_cuquantum() comm_mpi, rank, size, device_id = initialize_mpi() comm_nccl = initialize_nccl(comm_mpi, rank, size) operands = get_operands(qibo_circ, datatype, rank, comm_mpi) @@ -203,6 +241,7 @@ def dense_vector_tn(qibo_circ, datatype): Returns: Dense vector of quantum circuit. """ + _require_cuquantum() myconvertor = QiboCircuitToEinsum(qibo_circ, dtype=datatype) return contract(*myconvertor.state_vector_operands()) @@ -231,6 +270,7 @@ def expectation_tn_nccl(qibo_circ, datatype, observable, n_samples=8): Expectation of quantum circuit due to pauli string. """ + _require_cuquantum() comm_mpi, rank, size, device_id = initialize_mpi() comm_nccl = initialize_nccl(comm_mpi, rank, size) @@ -299,6 +339,7 @@ def expectation_tn_MPI(qibo_circ, datatype, observable, n_samples=8): Returns: Expectation of quantum circuit due to pauli string. """ + _require_cuquantum() # Initialize MPI and device comm, rank, size, device_id = initialize_mpi() @@ -358,6 +399,7 @@ def expectation_tn(qibo_circ, datatype, observable): Returns: Expectation of quantum circuit due to pauli string. """ + _require_cuquantum() myconvertor = QiboCircuitToEinsum(qibo_circ, dtype=datatype) observable = check_observable(observable, qibo_circ.nqubits) @@ -383,6 +425,7 @@ def dense_vector_mps(qibo_circ, gate_algo, datatype): Returns: Dense vector of quantum circuit. """ + _require_cuquantum() myconvertor = QiboCircuitToMPS(qibo_circ, gate_algo, dtype=datatype) mps_helper = MPSContractionHelper(myconvertor.num_qubits) diff --git a/src/qibotn/expectation_runner.py b/src/qibotn/expectation_runner.py index 22c2f55..6af6de8 100644 --- a/src/qibotn/expectation_runner.py +++ b/src/qibotn/expectation_runner.py @@ -16,9 +16,11 @@ from qibotn.observables import check_observable class ExpectationConfig: ansatz: str = "tn" mpi: bool = False - bond: int = 1024 - cut_ratio: float = 1e-12 + bond: int | None = 1024 + cut_ratio: float | None = 1e-12 tensor_module: str = "torch" + quimb_backend: str = "torch" + dtype: str = "complex128" torch_threads: int = 8 parallel_opts: dict | None = None @@ -28,6 +30,7 @@ class ExpectationResult: value: float seconds: float rank: int = 0 + parallel_stats: list | None = None def exact_for_observable(circuit, observable, nqubits): @@ -54,6 +57,8 @@ def run_cpu_expectation(circuit, observable, config): "max_bond_dimension": config.bond, "cut_ratio": config.cut_ratio, "tensor_module": config.tensor_module, + "quimb_backend": config.quimb_backend, + "dtype": config.dtype, "torch_threads": config.torch_threads, "parallel_opts": config.parallel_opts or {}, } @@ -68,4 +73,10 @@ def run_cpu_expectation(circuit, observable, config): elapsed = time.perf_counter() - start rank = getattr(backend, "rank", 0) - return ExpectationResult(float(np.real(value)), elapsed, rank=rank) + stats = getattr(backend, "parallel_stats", None) + return ExpectationResult( + float(np.real(value)), + elapsed, + rank=rank, + parallel_stats=list(stats) if stats is not None else None, + ) diff --git a/src/qibotn/mps_contraction_helper.py b/src/qibotn/mps_contraction_helper.py index fcb4441..b44cfb2 100644 --- a/src/qibotn/mps_contraction_helper.py +++ b/src/qibotn/mps_contraction_helper.py @@ -1,4 +1,16 @@ -from cuquantum.tensornet import contract, contract_path +try: + from cuquantum.tensornet import contract, contract_path +except ImportError: # pragma: no cover - exercised on CPU-only installations + contract = None + contract_path = None + + +def _require_cuquantum(): + if contract is None or contract_path is None: + raise ImportError( + "The cuQuantum MPS contraction helper requires cuquantum. " + "Install the GPU dependencies or use the CPU backend." + ) # Reference: https://github.com/NVIDIA/cuQuantum/blob/main/python/samples/cutensornet/tn_algorithms/mps_algorithms.ipynb @@ -113,6 +125,7 @@ class MPSContractionHelper: return self._contract(interleaved_inputs, options=options) / norm def _contract(self, interleaved_inputs, options=None): + _require_cuquantum() path = contract_path(*interleaved_inputs, options=options)[0] return contract(*interleaved_inputs, options=options, optimize={"path": path}) diff --git a/src/qibotn/mps_utils.py b/src/qibotn/mps_utils.py index 1450837..ff3d010 100644 --- a/src/qibotn/mps_utils.py +++ b/src/qibotn/mps_utils.py @@ -1,6 +1,19 @@ -import cupy as cp -from cuquantum.tensornet import contract -from cuquantum.tensornet.experimental import contract_decompose +try: + import cupy as cp + from cuquantum.tensornet import contract + from cuquantum.tensornet.experimental import contract_decompose +except ImportError: # pragma: no cover - exercised on CPU-only installations + cp = None + contract = None + contract_decompose = None + + +def _require_cuquantum(): + if cp is None or contract is None or contract_decompose is None: + raise ImportError( + "The cuQuantum MPS helpers require cupy and cuquantum. " + "Install the GPU dependencies or use the CPU backend." + ) def initial(num_qubits, dtype): @@ -13,6 +26,7 @@ def initial(num_qubits, dtype): Returns: The initial MPS tensors. """ + _require_cuquantum() state_tensor = cp.asarray([1, 0], dtype=dtype).reshape(1, 2, 1) mps_tensors = [state_tensor] * num_qubits return mps_tensors @@ -28,6 +42,7 @@ def mps_site_right_swap(mps_tensors, i, **kwargs): Returns: The updated MPS tensors. """ + _require_cuquantum() # contraction followed by QR decomposition a, _, b = contract_decompose( "ipj,jqk->iqj,jpk", @@ -60,6 +75,7 @@ def apply_gate(mps_tensors, gate, qubits, **kwargs): The updated MPS tensors. """ + _require_cuquantum() n_qubits = len(qubits) if n_qubits == 1: # single-qubit gate diff --git a/src/qibotn/parallel.py b/src/qibotn/parallel.py index 9445c97..2603b4f 100644 --- a/src/qibotn/parallel.py +++ b/src/qibotn/parallel.py @@ -17,6 +17,196 @@ except ImportError: SEARCH_METHODS = ("greedy", "kahypar", "kahypar-agglom", "spinglass") +_COTENGRA_DASK_PATCHED = False +_COTENGRA_DASK_SUBMIT_PATCHED = False +_DASK_TRIAL_DEBUG = False + + +def _optimizer_search_stats(opt): + scores = list(getattr(opt, "scores", ())) + finite_scores = [score for score in scores if np.isfinite(score)] + times = list(getattr(opt, "times", ())) + best = getattr(opt, "best", {}) or {} + return { + "completed_trials": len(scores), + "finite_trials": len(finite_scores), + "failed_trials": len(scores) - len(finite_scores), + "requested_trials": int(getattr(opt, "max_repeats", 0) or 0), + "trial_seconds_sum": float(sum(times)), + "best_score": float(best.get("score", float("inf"))), + "best_flops": float(best.get("flops", float("inf"))), + "best_write": float(best.get("write", float("inf"))), + "best_size": float(best.get("size", float("inf"))), + } + + +def _attach_search_stats(tree, opt): + try: + tree.qibotn_search_stats = _optimizer_search_stats(opt) + except Exception: + pass + return tree + + +def _dask_worker_slots(client): + info = client.scheduler_info(n_workers=-1) + workers = info.get("workers", {}) + return workers, sum(int(w.get("nthreads", 1) or 1) for w in workers.values()) + + +def _print_dask_worker_summary(client): + workers, slots = _dask_worker_slots(client) + by_host = {} + for worker in workers.values(): + host = worker.get("host", "unknown") + by_host.setdefault(host, {"workers": 0, "threads": 0}) + by_host[host]["workers"] += 1 + by_host[host]["threads"] += int(worker.get("nthreads", 1) or 1) + print( + "qibotn_dask_workers " + f"workers={len(workers)} threads={slots} by_host={by_host}", + flush=True, + ) + + +def _run_trial_with_debug(fn, *args, **kwargs): + import os + import socket + + try: + from distributed import get_worker + + worker = get_worker() + worker_address = worker.address + except Exception: + worker_address = "unknown" + + method = kwargs.get("method", "unknown") + pid = os.getpid() + host = socket.gethostname() + print( + "qibotn_trial_start " + f"worker={worker_address} host={host} pid={pid} method={method}", + flush=True, + ) + start = time.perf_counter() + try: + trial = fn(*args, **kwargs) + except Exception as exc: + elapsed = time.perf_counter() - start + print( + "qibotn_trial_error " + f"worker={worker_address} host={host} pid={pid} " + f"method={method} seconds={elapsed:.3f} error={exc!r}", + flush=True, + ) + raise + elapsed = time.perf_counter() - start + print( + "qibotn_trial_done " + f"worker={worker_address} host={host} pid={pid} method={method} " + f"seconds={elapsed:.3f} score={trial.get('score', float('nan')):.6g} " + f"flops={trial.get('flops', float('nan')):.6g} " + f"size={trial.get('size', float('nan')):.6g}", + flush=True, + ) + return trial + + +def _patch_cotengra_dask_submit(debug_trials=False): + global _COTENGRA_DASK_SUBMIT_PATCHED, _DASK_TRIAL_DEBUG + _DASK_TRIAL_DEBUG = bool(debug_trials) + if _COTENGRA_DASK_SUBMIT_PATCHED: + return + + import cotengra.parallel as ctg_parallel + import cotengra.hyperoptimizers.hyper as hyper + + original_submit = ctg_parallel.submit + + def submit(pool, fn, *args, **kwargs): + backend = pool.__class__.__module__.split(".", 1)[0] + if _DASK_TRIAL_DEBUG and backend == "distributed": + return original_submit( + pool, + _run_trial_with_debug, + fn, + *args, + **kwargs, + ) + return original_submit(pool, fn, *args, **kwargs) + + ctg_parallel.submit = submit + hyper.submit = submit + _COTENGRA_DASK_SUBMIT_PATCHED = True + + +def _patch_cotengra_dask_as_completed(): + """Make cotengra 0.7.5 handle distributed.Future objects. + + This cotengra release routes all parallel futures through + ``concurrent.futures.as_completed()``, which does not accept dask + ``distributed.Future`` instances. Keep cotengra's optimizer/reporting logic + intact and only swap the wait primitive when the futures are from dask. + """ + global _COTENGRA_DASK_PATCHED + if _COTENGRA_DASK_PATCHED: + return + + from cotengra.hyperoptimizers.hyper import HyperOptimizer + + def _get_and_report_next_future(self): + futures_map = {future: setting for setting, future in self._futures} + if not futures_map: + return { + "score": float("inf"), + "flops": float("inf"), + "write": float("inf"), + "size": float("inf"), + "time": 0.0, + } + + future0 = next(iter(futures_map)) + if future0.__class__.__module__.split(".", 1)[0] == "distributed": + from distributed import as_completed + + deadline = getattr(self, "_qibotn_deadline", None) + timeout = None if deadline is None else max(0.0, deadline - time.time()) + try: + future = next(iter(as_completed(futures_map, timeout=timeout))) + except TimeoutError: + for future in futures_map: + future.cancel() + self._futures = [] + return { + "score": float("inf"), + "flops": float("inf"), + "write": float("inf"), + "size": float("inf"), + "time": 0.0, + } + else: + import concurrent.futures as _cf + + future = next(_cf.as_completed(futures_map)) + + setting = futures_map[future] + self._futures = [(s, f) for s, f in self._futures if f is not future] + try: + trial = future.result() + except Exception: + trial = { + "score": float("inf"), + "flops": float("inf"), + "write": float("inf"), + "size": float("inf"), + "time": 0.0, + } + self._maybe_report_result(setting, trial) + return trial + + HyperOptimizer._get_and_report_next_future = _get_and_report_next_future + _COTENGRA_DASK_PATCHED = True def _search_chunk( @@ -46,7 +236,7 @@ def _search_chunk( **kwargs, ) tree = tn.contraction_tree(optimize=opt, output_inds=output_inds) - return tree.combo_cost(factor=256), tree + return tree.combo_cost(factor=256), _attach_search_stats(tree, opt) def _run_single_trial(tn_bytes, output_inds, seed, slicing_opts): @@ -164,6 +354,8 @@ def _dask_search( dask_address=None, n_workers=None, optlib=None, + debug_trials=False, + close_workers=False, ): """Run one centralized cotengra hyper-optimizer over a dask pool. @@ -180,6 +372,9 @@ def _dask_search( import cotengra as ctg + _patch_cotengra_dask_as_completed() + _patch_cotengra_dask_submit(debug_trials=debug_trials) + close_client = False close_cluster = False cluster = None @@ -205,7 +400,20 @@ def _dask_search( if optlib is not None: kwargs["optlib"] = optlib + retire_workers = [] try: + workers, worker_slots = _dask_worker_slots(client) + if close_workers: + retire_workers = list(workers) + if debug_trials: + _print_dask_worker_summary(client) + if total_repeats < worker_slots: + print( + "qibotn_dask_underutilized " + f"requested_trials={total_repeats} worker_slots={worker_slots} " + "hint='increase --tn-search-repeats to at least worker_slots'", + flush=True, + ) opt = ctg.HyperOptimizer( methods=SEARCH_METHODS, max_repeats=total_repeats, @@ -216,8 +424,31 @@ def _dask_search( progbar=False, **kwargs, ) - return tn.contraction_tree(optimize=opt, output_inds=output_inds) + opt._num_workers = max(1, worker_slots) + opt.pre_dispatch = max(1, min(int(total_repeats), worker_slots)) + if max_time is not None: + opt._qibotn_deadline = time.time() + max_time + tree = tn.contraction_tree(optimize=opt, output_inds=output_inds) + return _attach_search_stats(tree, opt) finally: + if close_workers and retire_workers: + try: + retired = client.retire_workers( + workers=retire_workers, + close_workers=True, + remove=True, + ) + print( + "qibotn_dask_workers_closed " + f"requested={len(retire_workers)} retired={len(retired)}", + flush=True, + ) + except Exception as exc: + print( + "qibotn_dask_workers_close_failed " + f"requested={len(retire_workers)} error={exc!r}", + flush=True, + ) if close_client: client.close() if close_cluster: @@ -234,6 +465,8 @@ def _mpi_search( trial_timeout=None, search_backend="processpool", dask_address=None, + debug_trials=False, + dask_close_workers=False, ): comm = MPI.COMM_WORLD rank, size = comm.Get_rank(), comm.Get_size() @@ -258,6 +491,8 @@ def _mpi_search( slicing_opts=slicing_opts, dask_address=dask_address, n_workers=n_workers, + debug_trials=debug_trials, + close_workers=dask_close_workers, ) payload = ("ok", tree) except Exception as exc: @@ -296,7 +531,8 @@ def _mpi_search( def parallel_path_search(tn, output_inds, method='processpool', total_repeats=1024, max_time=300, n_workers=48, slicing_opts=None, trial_timeout=None, search_backend=None, - dask_address=None): + dask_address=None, debug_trials=False, + dask_close_workers=False): """Parallel contraction path search. Args: @@ -324,6 +560,8 @@ def parallel_path_search(tn, output_inds, method='processpool', total_repeats=10 trial_timeout, search_backend=search_backend, dask_address=dask_address, + debug_trials=debug_trials, + dask_close_workers=dask_close_workers, ) elif method == 'processpool': return _processpool_search(tn, output_inds, total_repeats, n_workers, max_time, slicing_opts, trial_timeout) @@ -336,6 +574,8 @@ def parallel_path_search(tn, output_inds, method='processpool', total_repeats=10 slicing_opts=slicing_opts, dask_address=dask_address, n_workers=n_workers, + debug_trials=debug_trials, + close_workers=dask_close_workers, ) else: raise ValueError(f"Unknown method: {method}") @@ -431,17 +671,37 @@ def _to_numpy_vector(value, is_torch): def _zero_vector_like(arrays): - return np.zeros(1, dtype=np.complex128) + array = arrays[0] + if type(array).__module__.startswith("torch"): + return np.zeros(1, dtype=np.complex64 if "64" in str(array.dtype) else np.complex128) + return np.zeros(1, dtype=np.asarray(array).dtype) -def contract_tree_slices(tree, arrays, slice_indices, backend=None): +def contract_tree_slices(tree, arrays, slice_indices, backend=None, implementation=None): """Contract a subset of cotengra slices and return their local sum.""" backend = backend or _array_backend(arrays) is_torch = backend == "torch" local = None + cpp_contract = None + if implementation == "cpp": + if backend != "torch": + raise ValueError("implementation='cpp' requires torch arrays.") + from qibotn.torch_contractor import contract_tree_cpp + + cpp_contract = contract_tree_cpp for slice_id in slice_indices: - value = tree.contract_slice(arrays, slice_id, backend=backend) + if cpp_contract is not None: + value = cpp_contract(tree, tree.slice_arrays(arrays, slice_id)) + elif implementation is None: + value = tree.contract_slice(arrays, slice_id, backend=backend) + else: + value = tree.contract_slice( + arrays, + slice_id, + backend=backend, + implementation=implementation, + ) value = _to_numpy_vector(value, is_torch) local = value if local is None else local + value @@ -455,6 +715,7 @@ def parallel_contract( comm=None, assignment="block", return_stats=False, + implementation=None, ): if method == 'mpi': if not _HAVE_MPI or comm is None: @@ -465,11 +726,20 @@ def parallel_contract( comm, assignment=assignment, return_stats=return_stats, + implementation=implementation, ) raise ValueError(f"Unknown method: {method}") -def _contract_mpi(tree, arrays, comm, root=0, assignment="block", return_stats=False): +def _contract_mpi( + tree, + arrays, + comm, + root=0, + assignment="block", + return_stats=False, + implementation=None, +): rank, size = comm.Get_rank(), comm.Get_size() backend = _array_backend(arrays) is_torch = backend == "torch" @@ -482,15 +752,14 @@ def _contract_mpi(tree, arrays, comm, root=0, assignment="block", return_stats=F "appear in the output." ) - if nslices <= 1: - if rank != root: - return (None, stats) if return_stats else None - result = tree.contract(arrays, backend=backend) - result = _to_numpy_vector(result, is_torch) - return (result, stats) if return_stats else result - plan = mpi_slice_plan(nslices, rank, size, assignment=assignment) - local = contract_tree_slices(tree, arrays, plan.indices, backend=backend) + local = contract_tree_slices( + tree, + arrays, + plan.indices, + backend=backend, + implementation=implementation, + ) stats = SlicedContractStats(rank, size, nslices, len(plan.indices), assignment) result = np.zeros_like(local) if rank == root else None diff --git a/src/qibotn/torch_contractor.py b/src/qibotn/torch_contractor.py new file mode 100644 index 0000000..f2e7a67 --- /dev/null +++ b/src/qibotn/torch_contractor.py @@ -0,0 +1,252 @@ +"""Torch C++ contraction backend for cotengra trees. + +This module compiles a restricted cotengra contraction tree into a compact +execution plan, then executes that plan in a C++ torch extension. It is an +experimental CPU path for reducing Python-level overhead between many +pairwise contractions. +""" + +from __future__ import annotations + +import importlib +import os +from functools import lru_cache +from pathlib import Path +from collections import defaultdict + + +_EXTENSION = None +_CONTRACTORS = {} +SMALL_GEMM_BATCH_FLOPS = 1_000_000 + + +def _load_extension(): + global _EXTENSION + if _EXTENSION is not None: + return _EXTENSION + + from torch.utils.cpp_extension import load + + source = Path(__file__).resolve().parent / "csrc" / "torch_contractor.cpp" + mklroot = os.environ.get("MKLROOT") + extra_cflags = ["-O3"] + extra_ldflags = [] + extra_include_paths = [] + if mklroot: + mklroot_path = Path(mklroot) + mkl_include = mklroot_path / "include" + mkl_lib = mklroot_path / "lib" + if (mkl_include / "mkl_cblas.h").exists() and ( + (mkl_lib / "libmkl_rt.so").exists() + or (mkl_lib / "libmkl_rt.so.2").exists() + ): + extra_cflags.append("-DQIBOTN_USE_MKL") + extra_include_paths.append(str(mkl_include)) + extra_ldflags.extend([f"-L{mkl_lib}", "-lmkl_rt"]) + + _EXTENSION = load( + name="qibotn_torch_contractor", + sources=[str(source)], + extra_cflags=extra_cflags, + extra_ldflags=extra_ldflags, + extra_include_paths=extra_include_paths, + verbose=False, + ) + return _EXTENSION + + +def _is_plain_permutation(expr): + if expr is None: + return None + if isinstance(expr, tuple): + return tuple(int(i) for i in expr) + if not isinstance(expr, str): + return None + if "," in expr or "->" not in expr: + return None + source, target = expr.split("->", 1) + if len(source) != len(target): + return None + if len(set(source)) != len(source) or set(source) != set(target): + return None + return tuple(source.index(ix) for ix in target) + + +def _maybe_tuple(values): + return () if values is None else tuple(int(x) for x in values) + + +def _shape_from_inds(tree, node): + return tuple(int(tree.size_dict[ix]) for ix in tree.get_inds(node)) + + +def _matmul_signature(op): + kind = op[3] + if kind != 0: + return None + left_shape = op[5] + right_shape = op[7] + if len(left_shape) == 2 and len(right_shape) == 2: + m, k, n = left_shape[-2], left_shape[-1], right_shape[-1] + return ("mm", int(m), int(k), int(n), int(m * k * n)) + return None + + +def _normalize_node_ids(tree, contractions): + leaf_to_id = { + frozenset((i,)): i + for i in range(tree.N) + } + next_id = len(leaf_to_id) + node_to_id = dict(leaf_to_id) + for parent, _left, _right, _tdot, _arg, _perm in contractions: + if parent not in node_to_id: + node_to_id[parent] = next_id + next_id += 1 + + return node_to_id, next_id + + +@lru_cache(maxsize=32) +def compile_torch_plan(tree): + """Compile ``tree`` into C++ contractor plan fields. + + The supported subset is the same pairwise matmul lowering used by + cotengra for torch CPU. Single-tensor diagonal/sum preprocessing is not + supported yet because it appears only in less common trees; callers should + fall back to cotengra for those cases. + """ + + contract_mod = importlib.import_module("cotengra.contract") + contractions = contract_mod.extract_contractions(tree) + node_to_id, ntemps = _normalize_node_ids(tree, contractions) + plan = [] + + for parent, left, right, tdot, arg, perm in contractions: + if left is None or right is None: + raise NotImplementedError( + "C++ torch contractor does not support cotengra preprocessing." + ) + + left_shape = _shape_from_inds(tree, left) + right_shape = _shape_from_inds(tree, right) + if tdot: + parsed = contract_mod._parse_tensordot_axes_to_matmul( + arg, + left_shape, + right_shape, + ) + else: + parsed = contract_mod._parse_eq_to_batch_matmul( + arg, + left_shape, + right_shape, + ) + + ( + eq_a, + eq_b, + new_shape_a, + new_shape_b, + new_shape_ab, + perm_ab, + pure_multiplication, + ) = parsed + + left_perm = _is_plain_permutation(eq_a) + right_perm = _is_plain_permutation(eq_b) + if left_perm is None and eq_a is not None: + raise NotImplementedError(f"Unsupported left preparation: {eq_a!r}") + if right_perm is None and eq_b is not None: + raise NotImplementedError(f"Unsupported right preparation: {eq_b!r}") + + plan.append( + ( + node_to_id[parent], + node_to_id[left], + node_to_id[right], + 1 if pure_multiplication else 0, + left_perm or (), + _maybe_tuple(new_shape_a), + right_perm or (), + _maybe_tuple(new_shape_b), + _maybe_tuple(new_shape_ab), + _maybe_tuple(perm_ab), + ) + ) + + if perm is not None: + raise NotImplementedError( + "C++ torch contractor does not support cotengra tensordot perm." + ) + + root_id = node_to_id[tree.root] + return tuple(plan), int(ntemps), int(root_id) + + +@lru_cache(maxsize=32) +def compile_batch_groups(tree, max_flops=SMALL_GEMM_BATCH_FLOPS): + plan, _ntemps, _root_id = compile_torch_plan(tree) + contractions = importlib.import_module("cotengra.contract").extract_contractions(tree) + node_to_id, _ntemps = _normalize_node_ids(tree, contractions) + depth = {frozenset((i,)): 0 for i in range(tree.N)} + tensor_depth = {i: 0 for i in range(tree.N)} + groups = defaultdict(list) + + for op_index, (contract_op, contraction) in enumerate(zip(plan, contractions)): + parent, left, right, _tdot, _arg, _perm = contraction + d = max(depth[left], depth[right]) + 1 + depth[parent] = d + tensor_depth[contract_op[0]] = d + sig = _matmul_signature(contract_op) + if sig is None: + continue + kind, m, k, n, flops = sig + if flops > max_flops: + continue + groups[(d, kind, m, k, n)].append(op_index) + + batch_groups = tuple( + tuple(items) + for _key, items in sorted(groups.items(), key=lambda item: (item[0], item[1][0])) + if len(items) >= 2 + ) + return batch_groups + + +def batch_group_summary(tree, max_flops=SMALL_GEMM_BATCH_FLOPS): + plan, _ntemps, _root_id = compile_torch_plan(tree) + groups = compile_batch_groups(tree, max_flops=max_flops) + covered = sum(len(group) for group in groups) + calls_saved = sum(len(group) - 1 for group in groups) + by_shape = [] + for group in groups: + op = plan[group[0]] + sig = _matmul_signature(op) + by_shape.append((sig[1:4], len(group), group[:8])) + return { + "groups": len(groups), + "covered_ops": covered, + "calls_saved": calls_saved, + "by_shape": by_shape, + } + + +def contract_tree_cpp(tree, arrays): + """Contract a cotengra tree using the experimental C++ torch contractor.""" + + contractor = prepare_torch_cpp_contractor(tree) + return contractor.contract(list(arrays)) + + +def prepare_torch_cpp_contractor(tree): + """Load the extension and compile ``tree`` without running contraction.""" + + ext = _load_extension() + key = id(tree) + contractor = _CONTRACTORS.get(key) + if contractor is None: + plan, ntemps, root_id = compile_torch_plan(tree) + contractor = ext.Contractor(list(plan), ntemps, root_id) + _CONTRACTORS[key] = contractor + return contractor diff --git a/tests/test_cpu_backend.py b/tests/test_cpu_backend.py index 300c6fe..877ddd8 100644 --- a/tests/test_cpu_backend.py +++ b/tests/test_cpu_backend.py @@ -5,7 +5,10 @@ from qibo import Circuit, gates, hamiltonians from qibo.symbols import X, Z from qibotn.backends.cpu import CpuTensorNet -from qibotn.benchmark_cases import build_circuit as build_benchmark_circuit +from qibotn.benchmark_cases import ( + build_circuit as build_benchmark_circuit, + exact_pauli_sum, +) def build_circuit(nqubits=6): @@ -109,6 +112,59 @@ def test_cpu_mps_sampling_uses_nshots(): assert set(result.frequencies()) <= {"0000", "1111"} +def test_cpu_mps_mpo_expectation_matches_statevector(): + circuit = build_circuit(nqubits=4) + x = np.array([[0, 1], [1, 0]], dtype=complex) + z = np.array([[1, 0], [0, -1]], dtype=complex) + i2 = np.eye(2, dtype=complex) + mpo = [ + x.reshape(1, 2, 2, 1), + z.reshape(1, 2, 2, 1), + i2.reshape(1, 2, 2, 1), + i2.reshape(1, 2, 2, 1), + ] + exact = exact_pauli_sum(circuit, [(1.0, (("X", 0), ("Z", 1)))], 4) + + backend = CpuTensorNet( + { + "MPI_enabled": False, + "MPS_enabled": True, + "NCCL_enabled": False, + "expectation_enabled": {"mpo_tensors": mpo}, + "max_bond_dimension": 64, + "tensor_module": "torch", + "torch_threads": 1, + } + ) + value = backend.execute_circuit(circuit)[0] + + assert math.isclose(value, exact, abs_tol=1e-12) + + +def test_cpu_mps_dense_observable_dict_matches_known_value(): + circuit = Circuit(2) + circuit.add(gates.H(0)) + circuit.add(gates.CNOT(0, 1)) + + bell = np.zeros((4, 4), dtype=complex) + bell[0, 0] = bell[0, 3] = bell[3, 0] = bell[3, 3] = 0.5 + + backend = CpuTensorNet( + { + "MPI_enabled": False, + "MPS_enabled": True, + "NCCL_enabled": False, + "expectation_enabled": {"matrix": bell, "qubits": [0, 1]}, + "max_bond_dimension": 16, + "tensor_module": "torch", + "torch_threads": 1, + } + ) + value = backend.execute_circuit(circuit)[0] + + assert math.isclose(value, 1.0, abs_tol=1e-12) + + def test_cpu_generic_tn_long_pauli_string_matches_statevector(): circuit = build_benchmark_circuit("rxx_rzz", 10, 2, 42) observable = {"pauli_string_pattern": "XZ"} diff --git a/tests/test_vidal_backend.py b/tests/test_vidal_backend.py index 149cd0c..0af5736 100644 --- a/tests/test_vidal_backend.py +++ b/tests/test_vidal_backend.py @@ -2,10 +2,18 @@ import math import numpy as np from qibo import Circuit, gates, hamiltonians -from qibo.symbols import X, Y, Z +from qibo.symbols import Symbol, X, Y, Z -from qibotn.backends.vidal import VidalBackend, _can_route_non_adjacent, _unsupported_reason +from qibotn.benchmark_cases import exact_pauli_sum +from qibotn.backends.vidal import ( + VidalBackend, + _can_route_non_adjacent, + _unsupported_reason, + _operator_terms_to_mpo, + _symbolic_hamiltonian_to_operator_terms, +) from qibotn.backends.vidal_tebd import ( + VidalTEBDExecutor, _route_non_adjacent_gates, _gate_sites, ) @@ -37,6 +45,25 @@ def test_vidal_backend_expectation_matches_statevector(): np.testing.assert_allclose(value, exact, atol=1e-12) +def test_vidal_backend_accepts_unlimited_bond_and_no_cutoff(): + circuit = build_local_circuit(nqubits=6, nlayers=2) + observable = hamiltonians.SymbolicHamiltonian( + form=0.5 * X(0) * Z(1) - 0.7 * Z(5) + ) + exact = observable.expectation_from_state(circuit().state(numpy=True)) + + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=None, + cut_ratio=None, + tensor_module="torch", + fallback=False, + ) + value = backend.expectation(circuit, observable, preprocess=False) + + np.testing.assert_allclose(value, exact, atol=1e-12) + + def test_vidal_backend_fallback_for_non_adjacent_gate(): """compile_circuit=False (default) → falls back to qmatchatea for non-adjacent.""" circuit = Circuit(4) @@ -128,6 +155,208 @@ def test_routing_non_adjacent_cnot(): np.testing.assert_allclose(value, exact, atol=1e-12) +def test_routing_preserves_reversed_non_adjacent_gate_order(): + circuit = Circuit(6) + circuit.add(gates.X(5)) + circuit.add(gates.H(0)) + circuit.add(gates.CNOT(5, 0)) + + observable = hamiltonians.SymbolicHamiltonian(form=X(0) + Z(5) + Z(0) * Z(5)) + exact = observable.expectation_from_state(circuit().state(numpy=True)) + + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=64, + tensor_module="torch", + compile_circuit=True, + fallback=False, + ) + value = backend.expectation(circuit, observable, preprocess=False) + + np.testing.assert_allclose(value, exact, atol=1e-12) + + +def test_vidal_backend_preprocesses_non_adjacent_circuit(): + circuit = Circuit(4) + circuit.add(gates.H(0)) + circuit.add(gates.CNOT(0, 3)) + observable = hamiltonians.SymbolicHamiltonian(form=Z(0) * Z(3)) + exact = observable.expectation_from_state(circuit().state(numpy=True)) + + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=64, + tensor_module="torch", + compile_circuit=True, + fallback=False, + ) + value = backend.expectation(circuit, observable, preprocess=True) + + np.testing.assert_allclose(value, exact, atol=1e-12) + + +def test_vidal_backend_preprocesses_toffoli_locally(): + circuit = Circuit(4) + circuit.add(gates.H(0)) + circuit.add(gates.H(1)) + circuit.add(gates.TOFFOLI(0, 1, 3)) + observable = hamiltonians.SymbolicHamiltonian(form=Z(0) * Z(3)) + exact = observable.expectation_from_state(circuit().state(numpy=True)) + + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=128, + tensor_module="torch", + compile_circuit=True, + fallback=False, + ) + value = backend.expectation(circuit, observable, preprocess=True) + + np.testing.assert_allclose(value, exact, atol=1e-12) + + +def test_vidal_expectation_preserves_complex_coefficients(): + circuit = Circuit(1) + observable = hamiltonians.SymbolicHamiltonian(form=(1.0 + 2.0j) * Z(0)) + + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=8, + tensor_module="torch", + fallback=False, + ) + value = backend.expectation(circuit, observable, preprocess=False) + + np.testing.assert_allclose(value, 1.0 + 2.0j, atol=1e-12) + + +def test_vidal_expectation_supports_custom_local_symbols(): + circuit = build_local_circuit(nqubits=4, nlayers=2) + a0 = Symbol(0, np.array([[0.2, 1.0], [1.0, -0.3]], dtype=complex), name="A") + b2 = Symbol(2, np.array([[0.7, -0.4j], [0.4j, 0.1]], dtype=complex), name="B") + a3 = Symbol(3, np.array([[0.5, 0.2], [0.2, -0.8]], dtype=complex), name="A") + observable = hamiltonians.SymbolicHamiltonian(form=0.7 * a0 * b2 - 0.4 * a3) + exact = observable.expectation_from_state(circuit().state(numpy=True)) + + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=64, + tensor_module="torch", + fallback=False, + ) + value = backend.expectation(circuit, observable, preprocess=False) + + np.testing.assert_allclose(value, exact, atol=1e-12) + + +def test_vidal_executor_mpo_expectation_matches_pauli_sum(): + circuit = build_local_circuit(nqubits=4, nlayers=2) + executor = VidalTEBDExecutor( + nqubits=circuit.nqubits, + max_bond=64, + tensor_module="torch", + ) + executor.run_circuit(circuit) + + x = np.array([[0, 1], [1, 0]], dtype=complex) + z = np.array([[1, 0], [0, -1]], dtype=complex) + i2 = np.eye(2, dtype=complex) + mpo = [ + x.reshape(1, 2, 2, 1), + z.reshape(1, 2, 2, 1), + i2.reshape(1, 2, 2, 1), + i2.reshape(1, 2, 2, 1), + ] + mpo_value = executor.expectation_mpo(mpo) + pauli_value = executor.expectation_pauli_sum([(1.0, (("X", 0), ("Z", 1)))]) + + np.testing.assert_allclose(mpo_value, pauli_value, atol=1e-12) + + +def test_vidal_backend_accepts_mpo_observable_dict(): + circuit = build_local_circuit(nqubits=4, nlayers=2) + x = np.array([[0, 1], [1, 0]], dtype=complex) + z = np.array([[1, 0], [0, -1]], dtype=complex) + i2 = np.eye(2, dtype=complex) + mpo = [ + x.reshape(1, 2, 2, 1), + z.reshape(1, 2, 2, 1), + i2.reshape(1, 2, 2, 1), + i2.reshape(1, 2, 2, 1), + ] + exact = exact_pauli_sum(circuit, [(1.0, (("X", 0), ("Z", 1)))], 4) + + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=64, + tensor_module="torch", + fallback=False, + ) + value = backend.expectation(circuit, {"mpo_tensors": mpo}, preprocess=False) + + np.testing.assert_allclose(value, exact, atol=1e-12) + + +def test_vidal_symbolic_hamiltonian_auto_mpo_matches_operator_sum(): + circuit = build_local_circuit(nqubits=5, nlayers=2) + observable = hamiltonians.SymbolicHamiltonian( + form=0.3 * X(0) * Z(1) - 0.2j * Y(2) + 0.7 * Z(3) * X(4) + ) + + executor = VidalTEBDExecutor( + nqubits=circuit.nqubits, + max_bond=64, + tensor_module="torch", + ) + executor.run_circuit(circuit) + terms = _symbolic_hamiltonian_to_operator_terms(observable) + + term_value = executor.expectation_operator_sum(terms) + mpo_value = executor.expectation_mpo(_operator_terms_to_mpo(terms, circuit.nqubits)) + + np.testing.assert_allclose(mpo_value, term_value, atol=1e-12) + + +def test_vidal_backend_accepts_dense_two_qubit_observable(): + circuit = Circuit(2) + circuit.add(gates.H(0)) + circuit.add(gates.CNOT(0, 1)) + + bell = np.zeros((4, 4), dtype=complex) + bell[0, 0] = bell[0, 3] = bell[3, 0] = bell[3, 3] = 0.5 + observable = {"matrix": bell, "qubits": [0, 1]} + + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=16, + tensor_module="torch", + fallback=False, + ) + value = backend.expectation(circuit, observable, preprocess=False) + + np.testing.assert_allclose(value, 1.0, atol=1e-12) + + +def test_vidal_backend_dense_observable_preserves_complex_value(): + circuit = Circuit(2) + circuit.add(gates.H(0)) + circuit.add(gates.H(1)) + + op = np.zeros((4, 4), dtype=complex) + op[0, 3] = 1.0 + observable = {"coefficient": 1.0j, "matrix": op, "qubits": [0, 1]} + + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=16, + tensor_module="torch", + fallback=False, + ) + value = backend.expectation(circuit, observable, preprocess=False) + + np.testing.assert_allclose(value, 0.25j, atol=1e-12) + + def test_truncation_error_no_truncation(): """With large bond, truncation error should be essentially zero.""" circuit = build_local_circuit(nqubits=6, nlayers=2) @@ -141,6 +370,10 @@ def test_truncation_error_no_truncation(): assert backend.last_truncation_error < 1e-14, ( f"Expected near-zero truncation error, got {backend.last_truncation_error}" ) + assert backend.last_max_truncation_error < 1e-14, ( + "Expected near-zero max truncation error, got " + f"{backend.last_max_truncation_error}" + ) def test_vidal_backend_matches_statevector_multiterm(): diff --git a/tools/baseline_mps_expectation.py b/tools/baseline_mps_expectation.py index 311cef7..ef12ae3 100644 --- a/tools/baseline_mps_expectation.py +++ b/tools/baseline_mps_expectation.py @@ -19,6 +19,22 @@ from qibotn.backends.qmatchatea import QMatchaTeaBackend from qibotn.backends.vidal_tebd import run_vidal_ring_xz +def optional_int(text): + if isinstance(text, str) and text.lower() in {"none", "null", "inf", "unlimited"}: + return None + return int(text) + + +def optional_float(text): + if isinstance(text, str) and text.lower() in {"none", "null", "inf", "unlimited"}: + return None + return float(text) + + +def format_optional(value, fmt="g"): + return "None" if value is None else format(value, fmt) + + def build_circuit(nqubits, nlayers, seed): return build_benchmark_circuit("brickwall_cnot", nqubits, nlayers, seed) @@ -35,7 +51,8 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument("--nqubits", type=int, default=40) parser.add_argument("--nlayers", type=int, default=30) - parser.add_argument("--bond", "--bonds", dest="bond", type=int, default=512) + parser.add_argument("--bond", "--bonds", dest="bond", type=optional_int, default=512) + parser.add_argument("--cut-ratio", type=optional_float, default=1e-12) parser.add_argument("--seed", type=int, default=42) parser.add_argument("--tensor-module", choices=("numpy", "torch"), default="torch") parser.add_argument("--torch-threads", type=int, default=32) @@ -109,7 +126,8 @@ def main(): mpi_label = f"MPIMPS/{size}" if args.mpi_ct else "SR" print( f"nqubits={args.nqubits} nlayers={args.nlayers} " - f"bond={args.bond} seed={args.seed} " + f"bond={format_optional(args.bond)} " + f"cut_ratio={format_optional(args.cut_ratio)} seed={args.seed} " f"tensor_module={args.tensor_module} svd_control=E! " f"compile_circuit=True mpi={mpi_label} executor={args.executor}" ) @@ -128,7 +146,7 @@ def main(): value, timings = run_segment_vidal_mpi_ring_xz( circuit, max_bond=args.bond, - cut_ratio=1e-12, + cut_ratio=args.cut_ratio, tensor_module=args.tensor_module, comm=MPI.COMM_WORLD, ) @@ -136,7 +154,7 @@ def main(): value = run_vidal_ring_xz( circuit, max_bond=args.bond, - cut_ratio=1e-12, + cut_ratio=args.cut_ratio, tensor_module=args.tensor_module, ) else: @@ -144,7 +162,7 @@ def main(): backend.configure_tn_simulation( ansatz="MPS", max_bond_dimension=args.bond, - cut_ratio=1e-12, + cut_ratio=args.cut_ratio, svd_control="E!", tensor_module=args.tensor_module, compile_circuit=True, diff --git a/tools/example_tn_case.py b/tools/example_tn_case.py new file mode 100644 index 0000000..c35f057 --- /dev/null +++ b/tools/example_tn_case.py @@ -0,0 +1,33 @@ +"""Example custom case for tools/run_tn_custom.py.""" + +from __future__ import annotations + +import math + +import numpy as np +from qibo import Circuit, gates + + +def build_circuit(nqubits, nlayers, seed): + rng = np.random.default_rng(seed) + circuit = Circuit(nqubits) + for layer in range(nlayers): + for qubit in range(nqubits): + circuit.add(gates.RY(qubit, theta=rng.uniform(-math.pi, math.pi))) + circuit.add(gates.RZ(qubit, theta=rng.uniform(-math.pi, math.pi))) + for qubit in range(layer % 2, nqubits - 1, 2): + circuit.add(gates.RXX(qubit, qubit + 1, theta=rng.uniform(-0.7, 0.7))) + circuit.add(gates.RZZ(qubit, qubit + 1, theta=rng.uniform(-0.7, 0.7))) + return circuit + + +def build_observable(nqubits, seed): + return { + "terms": [ + { + "coefficient": 1.0 / max(1, nqubits - 1), + "operators": [("Z", site), ("Z", site + 1)], + } + for site in range(nqubits - 1) + ] + } diff --git a/tools/inspect_contraction_tree.py b/tools/inspect_contraction_tree.py new file mode 100644 index 0000000..a6422ba --- /dev/null +++ b/tools/inspect_contraction_tree.py @@ -0,0 +1,208 @@ +"""Inspect cotengra contraction trees for dominant torch matmul shapes.""" + +from __future__ import annotations + +import argparse +import importlib +import math +import pickle +from collections import Counter, defaultdict +from pathlib import Path + + +def _prod(values): + out = 1 + for value in values: + out *= int(value) + return out + + +def _broadcast_batch(a_batch, b_batch): + if a_batch == b_batch: + return _prod(a_batch) + if not a_batch: + return _prod(b_batch) + if not b_batch: + return _prod(a_batch) + + ndim = max(len(a_batch), len(b_batch)) + a_batch = (1,) * (ndim - len(a_batch)) + tuple(a_batch) + b_batch = (1,) * (ndim - len(b_batch)) + tuple(b_batch) + return _prod(max(a, b) for a, b in zip(a_batch, b_batch)) + + +def _load_tree(path, index): + with Path(path).open("rb") as f: + payload = pickle.load(f) + trees = payload["trees"] if isinstance(payload, dict) else payload + if not isinstance(trees, (list, tuple)): + trees = [trees] + return trees[index] + + +def _analyze_tree(tree): + contract_mod = importlib.import_module("cotengra.contract") + contractions = contract_mod.extract_contractions(tree) + size_dict = tree.size_dict + ops = [] + counts = Counter() + + for op_index, (parent, left, right, tdot, arg, perm) in enumerate(contractions): + if left is None and right is None: + counts["preprocess"] += 1 + continue + + left_inds = tree.get_inds(left) + right_inds = tree.get_inds(right) + parent_inds = tree.get_inds(parent) + left_shape = tuple(size_dict[ix] for ix in left_inds) + right_shape = tuple(size_dict[ix] for ix in right_inds) + + if tdot: + parsed = contract_mod._parse_tensordot_axes_to_matmul( + arg, + left_shape, + right_shape, + ) + else: + parsed = contract_mod._parse_eq_to_batch_matmul( + arg, + left_shape, + right_shape, + ) + + ( + _eq_a, + _eq_b, + new_shape_a, + new_shape_b, + _new_shape_ab, + _perm_ab, + pure_multiplication, + ) = parsed + + matmul_shape = None + matmul_flops = 0 + if pure_multiplication: + kind = "mul" + else: + a_shape = tuple(new_shape_a or left_shape) + b_shape = tuple(new_shape_b or right_shape) + batch = _broadcast_batch(a_shape[:-2], b_shape[:-2]) + m, k, n = int(a_shape[-2]), int(a_shape[-1]), int(b_shape[-1]) + kind = "mm" if batch == 1 else "bmm" + matmul_shape = (batch, m, k, n) + matmul_flops = batch * m * k * n + + tree_flops = int(tree.get_flops(parent)) + out_size = int(tree.get_size(parent)) + ops.append( + { + "index": op_index, + "kind": kind, + "matmul_shape": matmul_shape, + "matmul_flops": matmul_flops, + "tree_flops": tree_flops, + "out_size": out_size, + "left_shape": left_shape, + "right_shape": right_shape, + "left_rank": len(left_inds), + "right_rank": len(right_inds), + "out_rank": len(parent_inds), + "perm": perm, + } + ) + counts[kind] += 1 + + return contractions, ops, counts + + +def _format_log(value, base): + return "-inf" if value <= 0 else f"{math.log(value, base):.3f}" + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("tree", help="Pickle file containing one tree or {'trees': [...]}.") + parser.add_argument("--index", type=int, default=0, help="Tree index in the file.") + parser.add_argument("--top", type=int, default=20, help="Number of top ops to print.") + parser.add_argument( + "--dtype-bytes", + type=int, + default=8, + help="Bytes per element for memory estimates, for example 8 for complex64.", + ) + args = parser.parse_args() + + tree = _load_tree(args.tree, args.index) + contractions, ops, counts = _analyze_tree(tree) + nslices = int(getattr(tree, "multiplicity", 1)) + per_slice_flops = sum(op["tree_flops"] for op in ops) + per_slice_write = sum(op["out_size"] for op in ops) + max_out = max((op["out_size"] for op in ops), default=0) + all_flops = per_slice_flops * nslices + all_write = per_slice_write * nslices + + print(f"tree={args.tree} index={args.index}") + print( + "summary " + f"slices={nslices} contractions={len(contractions)} " + f"counts={dict(counts)}" + ) + print( + "per_slice " + f"log10_flops={_format_log(per_slice_flops, 10)} " + f"log10_write={_format_log(per_slice_write, 10)} " + f"log2_max_output={_format_log(max_out, 2)} " + f"max_output_gib={max_out * args.dtype_bytes / 1024**3:.6g}" + ) + print( + "all_slices " + f"log10_flops={_format_log(all_flops, 10)} " + f"log10_write={_format_log(all_write, 10)}" + ) + + print(f"\ntop_{args.top}_ops_by_flops") + for op in sorted(ops, key=lambda item: item["tree_flops"], reverse=True)[: args.top]: + print( + f"op={op['index']} kind={op['kind']} " + f"flops={op['tree_flops']:.6e} out={op['out_size']:.6e} " + f"matmul={op['matmul_shape']} " + f"ranks=({op['left_rank']},{op['right_rank']}->{op['out_rank']}) " + f"lhs={op['left_shape']} rhs={op['right_shape']}" + ) + + by_shape = defaultdict(lambda: [0, 0, 0]) + for op in ops: + shape = op["matmul_shape"] + if shape is None: + continue + by_shape[shape][0] += 1 + by_shape[shape][1] += op["tree_flops"] + by_shape[shape][2] += op["out_size"] + + print(f"\ntop_{args.top}_matmul_shapes_by_flops") + for shape, (count, flops, out_size) in sorted( + by_shape.items(), + key=lambda item: item[1][1], + reverse=True, + )[: args.top]: + print( + f"shape={shape} count={count} " + f"flops={flops:.6e} output={out_size:.6e}" + ) + + print(f"\ntop_{args.top}_matmul_shapes_by_count") + for shape, (count, flops, out_size) in sorted( + by_shape.items(), + key=lambda item: item[1][0], + reverse=True, + )[: args.top]: + print( + f"shape={shape} count={count} " + f"flops={flops:.6e} output={out_size:.6e}" + ) + + +if __name__ == "__main__": + main() diff --git a/tools/manage_tn_dask_cluster.sh b/tools/manage_tn_dask_cluster.sh new file mode 100755 index 0000000..2fb7446 --- /dev/null +++ b/tools/manage_tn_dask_cluster.sh @@ -0,0 +1,223 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Manage the dask cluster used by TN path search. +# +# Defaults target two servers: +# scheduler: 10.20.1.103:8786 +# workers: 10.20.1.103, 10.20.1.102 +# +# Usage: +# tools/manage_tn_dask_cluster.sh start +# tools/manage_tn_dask_cluster.sh status +# tools/manage_tn_dask_cluster.sh stop +# +# Common overrides: +# SCHEDULER_HOST=10.20.1.103 +# WORKER_HOSTS="10.20.1.103 10.20.1.102" +# NWORKERS=48 +# NTHREADS=1 +# ROOT_DIR=/home/yx/qibotn +# PYTHON_BIN=.venv/bin/python + +ROOT_DIR="${ROOT_DIR:-/home/yx/qibotn}" +PYTHON_BIN="${PYTHON_BIN:-.venv/bin/python}" +SCHEDULER_HOST="${SCHEDULER_HOST:-10.20.1.103}" +SCHEDULER_PORT="${SCHEDULER_PORT:-8786}" +DASHBOARD_ADDRESS="${DASHBOARD_ADDRESS:-:8787}" +WORKER_HOSTS="${WORKER_HOSTS:-10.20.1.103 10.20.1.102}" +NWORKERS="${NWORKERS:-48}" +NTHREADS="${NTHREADS:-1}" +MEMORY_LIMIT="${MEMORY_LIMIT:-0}" +LOCAL_DIRECTORY="${LOCAL_DIRECTORY:-/tmp/qibotn-dask}" +LOG_DIR="${LOG_DIR:-$ROOT_DIR/logs/dask}" +SSH_BIN="${SSH_BIN:-ssh}" +DASK_WORKER_TTL="${DASK_WORKER_TTL:-24 hours}" +DASK_TICK_LIMIT="${DASK_TICK_LIMIT:-30 minutes}" +DASK_LOST_WORKER_TIMEOUT="${DASK_LOST_WORKER_TIMEOUT:-30 minutes}" + +SCHEDULER_ADDR="tcp://${SCHEDULER_HOST}:${SCHEDULER_PORT}" + +is_local_host() { + local host="$1" + [[ "$host" == "localhost" || "$host" == "127.0.0.1" ]] && return 0 + [[ "$host" == "$(hostname)" ]] && return 0 + [[ "$host" == "$(hostname -f 2>/dev/null || true)" ]] && return 0 + hostname -I 2>/dev/null | tr ' ' '\n' | grep -qx "$host" +} + +run_on_host() { + local host="$1" + shift + local cmd="$*" + if is_local_host "$host"; then + bash -lc "$cmd" + else + "$SSH_BIN" "$host" "bash -lc $(printf '%q' "$cmd")" + fi +} + +start_scheduler() { + local host="$SCHEDULER_HOST" + local log="$LOG_DIR/scheduler_${SCHEDULER_HOST}_${SCHEDULER_PORT}.log" + local pid_file="$LOG_DIR/scheduler_${SCHEDULER_HOST}_${SCHEDULER_PORT}.pid" + run_on_host "$host" " + set -euo pipefail + cd '$ROOT_DIR' + mkdir -p '$LOG_DIR' + if [[ -s '$pid_file' ]]; then + pid=\$(cat '$pid_file') + if kill -0 \"\$pid\" 2>/dev/null; then + echo \"scheduler already running on $host pid=\$pid\" + exit 0 + fi + fi + DASK_DISTRIBUTED__SCHEDULER__WORKER_TTL='$DASK_WORKER_TTL' \ + DASK_DISTRIBUTED__ADMIN__TICK__LIMIT='$DASK_TICK_LIMIT' \ + DASK_DISTRIBUTED__DEPLOY__LOST_WORKER_TIMEOUT='$DASK_LOST_WORKER_TIMEOUT' \ + setsid '$PYTHON_BIN' -m distributed.cli.dask_scheduler \ + --host '$SCHEDULER_HOST' \ + --port '$SCHEDULER_PORT' \ + --dashboard-address '$DASHBOARD_ADDRESS' \ + > '$log' 2>&1 < /dev/null & + pid=\$! + echo \"\$pid\" > '$pid_file' + echo \"scheduler host=$host pid=\$pid addr=$SCHEDULER_ADDR log=$log\" + " +} + +start_worker() { + local host="$1" + local log="$LOG_DIR/worker_${host}.log" + local pid_file="$LOG_DIR/worker_${host}.pid" + run_on_host "$host" " + set -euo pipefail + cd '$ROOT_DIR' + mkdir -p '$LOG_DIR' '$LOCAL_DIRECTORY' + if [[ -s '$pid_file' ]]; then + pid=\$(cat '$pid_file') + if kill -0 \"\$pid\" 2>/dev/null; then + echo \"worker already running on $host pid=\$pid\" + exit 0 + fi + fi + TCM_ENABLE=1 \ + DASK_DISTRIBUTED__SCHEDULER__WORKER_TTL='$DASK_WORKER_TTL' \ + DASK_DISTRIBUTED__ADMIN__TICK__LIMIT='$DASK_TICK_LIMIT' \ + DASK_DISTRIBUTED__DEPLOY__LOST_WORKER_TIMEOUT='$DASK_LOST_WORKER_TIMEOUT' \ + setsid '$PYTHON_BIN' -m distributed.cli.dask_worker \ + '$SCHEDULER_ADDR' \ + --host '$host' \ + --nworkers '$NWORKERS' \ + --nthreads '$NTHREADS' \ + --memory-limit '$MEMORY_LIMIT' \ + --local-directory '$LOCAL_DIRECTORY' \ + > '$log' 2>&1 < /dev/null & + pid=\$! + echo \"\$pid\" > '$pid_file' + echo \"worker host=$host pid=\$pid scheduler=$SCHEDULER_ADDR log=$log\" + " +} + +stop_host() { + local host="$1" + local scheduler_pid_file="$LOG_DIR/scheduler_${SCHEDULER_HOST}_${SCHEDULER_PORT}.pid" + local worker_pid_file="$LOG_DIR/worker_${host}.pid" + run_on_host "$host" " + set +e + for pid_file in '$worker_pid_file' '$scheduler_pid_file'; do + [[ -f \"\$pid_file\" ]] || continue + if [[ \"\$pid_file\" == '$scheduler_pid_file' && '$host' != '$SCHEDULER_HOST' ]]; then + continue + fi + pid=\$(cat \"\$pid_file\") + kill \"\$pid\" 2>/dev/null || true + rm -f \"\$pid_file\" + done + pkill -f '[d]istributed.cli.dask_worker.*$SCHEDULER_ADDR' + pkill -f '[d]istributed.cli.dask_scheduler.*--port $SCHEDULER_PORT' + true + " +} + +status_host() { + local host="$1" + local scheduler_pid_file="$LOG_DIR/scheduler_${SCHEDULER_HOST}_${SCHEDULER_PORT}.pid" + local worker_pid_file="$LOG_DIR/worker_${host}.pid" + echo "--------------------------------------------------------------------------------" + echo "host=$host" + run_on_host "$host" " + set +e + for pid_file in '$worker_pid_file' '$scheduler_pid_file'; do + [[ -f \"\$pid_file\" ]] || continue + if [[ \"\$pid_file\" == '$scheduler_pid_file' && '$host' != '$SCHEDULER_HOST' ]]; then + continue + fi + pid=\$(cat \"\$pid_file\") + if kill -0 \"\$pid\" 2>/dev/null; then + ps -p \"\$pid\" -o pid,ppid,stat,etime,cmd --no-headers + else + echo \"stale pid_file=\$pid_file pid=\$pid\" + fi + done + pgrep -af '[d]istributed.cli.dask' || true + " +} + +case "${1:-help}" in + start) + start_scheduler + sleep 2 + for host in $WORKER_HOSTS; do + start_worker "$host" + done + echo + echo "Dask scheduler: $SCHEDULER_ADDR" + echo "Dashboard: http://$SCHEDULER_HOST$DASHBOARD_ADDRESS" + ;; + stop) + for host in $WORKER_HOSTS; do + stop_host "$host" + done + stop_host "$SCHEDULER_HOST" + ;; + status) + status_host "$SCHEDULER_HOST" + for host in $WORKER_HOSTS; do + [[ "$host" == "$SCHEDULER_HOST" ]] && continue + status_host "$host" + done + ;; + restart) + "$0" stop + sleep 2 + "$0" start + ;; + help|*) + cat < args.exact_max_qubits: + raise ValueError( + f"--exact is limited to {args.exact_max_qubits} qubits by default." + ) + exact = exact_for_observable(circuit, obs, args.nqubits) + + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=args.bond, + cut_ratio=args.cut_ratio, + tensor_module="torch", + mpi_approach="CT", + mpi_num_procs=size, + fallback=False, + ) + + comm.Barrier() + start = time.perf_counter() + try: + value = backend.expectation( + circuit, + obs, + preprocess=True, + compile_circuit=False, + ) + status = "ok" + except Exception as exc: + value = np.nan + status = type(exc).__name__ + ":" + str(exc).split("\n", 1)[0] + seconds = time.perf_counter() - start + + if rank == 0: + abs_error = float("nan") if exact is None else abs(value - exact) + rel_error = float("nan") if exact is None else abs_error / max(abs(exact), 1e-15) + exact_text = "nan" if exact is None else f"{exact:.16e}" + print( + f"{obs_name} {exact_text} {value!r} " + f"{abs_error:.6e} {rel_error:.6e} {seconds:.3f} " + f"{backend.last_truncation_error:.6e} " + f"{backend.last_max_truncation_error:.6e} {status}", + flush=True, + ) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("mode", choices=("run", "validate", "list")) + parser.add_argument("--case", choices=sorted(CASES), default="main1") + parser.add_argument("--observables", nargs="+") + parser.add_argument("--obs-filter", default="") + parser.add_argument("--nqubits", type=int) + parser.add_argument("--nlayers", type=int) + parser.add_argument("--bond", "--bonds", dest="bond", default="case-default") + parser.add_argument("--cut-ratio", type=optional_float, default=1e-12) + parser.add_argument("--seed", type=int) + parser.add_argument("--torch-threads", type=int, default=8) + parser.add_argument("--exact", action="store_true") + parser.add_argument("--exact-max-qubits", type=int, default=24) + args = parser.parse_args() + + if args.mode == "list": + for name, case in CASES.items(): + print( + f"{name}: circuit={case.circuit_kind} " + f"observables={','.join(case.observables)} " + f"nqubits={case.nqubits} nlayers={case.nlayers} " + f"bond={case.bond} seed={case.seed}" + ) + return + + apply_case_defaults(args) + if isinstance(args.bond, str): + args.bond = optional_int(args.bond) + + if args.mode == "validate": + args.exact = True + args.nqubits = min(args.nqubits, args.exact_max_qubits) + + run_case(args) + + +if __name__ == "__main__": + main() diff --git a/tools/run_tn_custom.py b/tools/run_tn_custom.py new file mode 100644 index 0000000..049ebed --- /dev/null +++ b/tools/run_tn_custom.py @@ -0,0 +1,243 @@ +#!/usr/bin/env python +"""Run TN expectation for a user-provided circuit and observable. + +The case module should define: + + def build_circuit(nqubits, nlayers, seed): ... + def build_observable(nqubits, seed): ... + +``build_observable`` may return a Qibo SymbolicHamiltonian/form or the qibotn +dict form: + + {"terms": [ + {"coefficient": 1.0, "operators": [("X", 0), ("Z", 1)]}, + ]} + +For a single repeated Pauli string, pass ``--pauli-pattern`` instead of +defining ``build_observable``. +""" + +from __future__ import annotations + +import argparse +import importlib.util +import inspect +import json +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +SRC = ROOT / "src" +if str(SRC) not in sys.path: + sys.path.insert(0, str(SRC)) + +from qibotn.expectation_runner import ( # noqa: E402 + ExpectationConfig, + exact_for_observable, + run_cpu_expectation, +) + + +def optional_int(text): + if isinstance(text, str) and text.lower() in {"none", "null", "inf", "unlimited"}: + return None + return int(text) + + +def optional_float(text): + if isinstance(text, str) and text.lower() in {"none", "null", "inf", "unlimited"}: + return None + return float(text) + + +def load_module(path): + path = Path(path).resolve() + spec = importlib.util.spec_from_file_location(path.stem, path) + if spec is None or spec.loader is None: + raise RuntimeError(f"Cannot import case module from {path}.") + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +def call_builder(fn, **kwargs): + sig = inspect.signature(fn) + if any(p.kind == p.VAR_KEYWORD for p in sig.parameters.values()): + return fn(**kwargs) + accepted = { + name: value + for name, value in kwargs.items() + if name in sig.parameters + } + return fn(**accepted) + + +def load_observable(args, module): + if args.pauli_pattern: + return {"pauli_string_pattern": args.pauli_pattern} + if args.observable_json: + with Path(args.observable_json).open() as f: + return json.load(f) + if hasattr(module, "build_observable"): + return call_builder( + module.build_observable, + nqubits=args.nqubits, + nlayers=args.nlayers, + seed=args.seed, + ) + if hasattr(module, "OBSERVABLE"): + return module.OBSERVABLE + raise ValueError( + "No observable supplied. Define build_observable/OBSERVABLE in the case " + "module, or pass --pauli-pattern / --observable-json." + ) + + +def build_parallel_opts(args): + slicing_opts = {} + if args.tn_target_slices is not None: + slicing_opts["target_slices"] = args.tn_target_slices + if args.tn_target_size is not None: + slicing_opts["target_size"] = args.tn_target_size + + opts = { + "slicing_opts": slicing_opts or None, + "search_workers": args.tn_search_workers or args.torch_threads, + "max_repeats": args.tn_search_repeats, + "max_time": args.tn_search_time, + "print_stats": not args.no_tn_stats, + } + if args.tn_search_backend is not None: + opts["search_backend"] = args.tn_search_backend + if args.dask_address is not None: + opts["dask_address"] = args.dask_address + if args.dask_close_workers: + opts["dask_close_workers"] = True + if args.tn_save_tree is not None: + opts["save_tree_path"] = args.tn_save_tree + if args.tn_load_tree is not None: + opts["load_tree_path"] = args.tn_load_tree + if args.tn_search_only: + opts["search_only"] = True + return opts + + +def main(): + parser = argparse.ArgumentParser( + description="Run CPU TN expectation for a custom qibo circuit module." + ) + parser.add_argument("case_module", help="Python file defining build_circuit.") + parser.add_argument("--nqubits", type=int, required=True) + parser.add_argument("--nlayers", type=int, default=0) + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--mpi", action="store_true") + parser.add_argument("--exact", action="store_true") + parser.add_argument("--exact-max-qubits", type=int, default=24) + parser.add_argument("--bond", "--bonds", dest="bond", type=optional_int, default=1024) + parser.add_argument("--cut-ratio", type=optional_float, default=1e-12) + parser.add_argument("--torch-threads", type=int, default=8) + parser.add_argument("--quimb-backend", choices=("numpy", "torch"), default="torch") + parser.add_argument("--dtype", choices=("complex128", "complex64"), default="complex128") + parser.add_argument("--pauli-pattern") + parser.add_argument("--observable-json") + parser.add_argument("--tn-target-slices", type=int) + parser.add_argument("--tn-target-size", type=int, default=2**32) + parser.add_argument("--tn-search-workers", type=int) + parser.add_argument("--tn-search-repeats", type=int, default=128) + parser.add_argument("--tn-search-time", type=float, default=60.0) + parser.add_argument("--tn-search-backend", choices=("processpool", "dask")) + parser.add_argument("--dask-address") + parser.add_argument("--dask-close-workers", action="store_true") + parser.add_argument("--tn-save-tree") + parser.add_argument("--tn-load-tree") + parser.add_argument("--tn-search-only", action="store_true") + parser.add_argument("--no-tn-stats", action="store_true") + args = parser.parse_args() + + rank = 0 + if args.mpi: + from mpi4py import MPI + + rank = MPI.COMM_WORLD.Get_rank() + + module = load_module(args.case_module) + if not hasattr(module, "build_circuit"): + raise ValueError("case_module must define build_circuit.") + + circuit = call_builder( + module.build_circuit, + nqubits=args.nqubits, + nlayers=args.nlayers, + seed=args.seed, + ) + observable = load_observable(args, module) + + config = ExpectationConfig( + ansatz="tn", + mpi=args.mpi, + bond=args.bond, + cut_ratio=args.cut_ratio, + tensor_module="torch", + quimb_backend=args.quimb_backend, + dtype=args.dtype, + torch_threads=args.torch_threads, + parallel_opts=build_parallel_opts(args), + ) + + if rank == 0: + mode = "MPI" if args.mpi else "serial" + print( + f"backend=cpu ansatz=TN mode={mode} case={Path(args.case_module).name} " + f"nqubits={args.nqubits} nlayers={args.nlayers} seed={args.seed} " + f"quimb_backend={args.quimb_backend} dtype={args.dtype} " + f"torch_threads={args.torch_threads}", + flush=True, + ) + print("observable exact value abs_error rel_error seconds", flush=True) + + exact = None + if args.exact and rank == 0: + if args.nqubits > args.exact_max_qubits: + raise ValueError( + f"--exact is limited to {args.exact_max_qubits} qubits by default." + ) + exact = exact_for_observable(circuit, observable, args.nqubits) + + result = run_cpu_expectation(circuit, observable, config) + if args.mpi and result.rank != 0: + return + + abs_error = float("nan") if exact is None else abs(result.value - exact) + rel_error = float("nan") if exact is None else abs_error / max(abs(exact), 1e-15) + exact_text = "nan" if exact is None else f"{exact:.16e}" + print( + f"custom {exact_text} {result.value:.16e} " + f"{abs_error:.6e} {rel_error:.6e} {result.seconds:.3f}", + flush=True, + ) + + for stat in result.parallel_stats or (): + cost = stat["path_cost"] + search_stats = stat.get("search_stats", {}) + print( + "tn_term_summary " + f"term={stat.get('term_index', 0)} " + f"search_seconds={stat.get('search_seconds', float('nan')):.3f} " + f"contract_seconds={stat.get('contract_seconds', float('nan')):.3f} " + f"completed_trials={search_stats.get('completed_trials', 'na')} " + f"finite_trials={search_stats.get('finite_trials', 'na')} " + f"failed_trials={search_stats.get('failed_trials', 'na')} " + f"requested_trials={search_stats.get('requested_trials', 'na')} " + f"best_score={search_stats.get('best_score', float('nan')):.6g} " + f"slices={cost.get('slices')} " + f"log10_flops={cost.get('log10_flops', float('nan')):.3f} " + f"log10_write={cost.get('log10_write', float('nan')):.3f} " + f"log2_size={cost.get('log2_size', float('nan')):.3f} " + f"peak_memory_gib={cost.get('peak_memory_gib', float('nan')):.3g} " + f"rank_slices={stat.get('rank_slices')}", + flush=True, + ) + + +if __name__ == "__main__": + main() diff --git a/tools/run_vidal_mpi_contest_cases.sh b/tools/run_vidal_mpi_contest_cases.sh new file mode 100755 index 0000000..f2524e7 --- /dev/null +++ b/tools/run_vidal_mpi_contest_cases.sh @@ -0,0 +1,340 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Contest-style Vidal/MPI MPS cases. +# +# Usage: +# tools/run_vidal_mpi_contest_cases.sh main1 +# tools/run_vidal_mpi_contest_cases.sh main2 +# tools/run_vidal_mpi_contest_cases.sh strong +# tools/run_vidal_mpi_contest_cases.sh all +# +# Common overrides: +# PYTHON_BIN=.venv/bin/python +# MPIEXEC=mpiexec +# MPIEXEC_FULL="mpirun -np 4 -hostfile /home/yx/qibotn/hostfile -perhost 2" +# HOSTFILE=hostfile # optional; used only if the file exists +# RANKS=8 +# TORCH_THREADS=8 +# CUT_RATIO=1e-12 +# OBS_FILTER="boundary_ZZ_q2 ring_xz dense3_spread complex_iZ0" +# +# Per-case overrides: +# MAIN1_NQ=128 MAIN1_LAYERS=50 MAIN1_BOND=1024 MAIN1_SEED=31001 +# MAIN2_NQ=128 MAIN2_LAYERS=64 MAIN2_BOND=2048 MAIN2_SEED=31002 +# STRONG_NQ=256 STRONG_LAYERS=64 STRONG_BOND=2048 STRONG_SEED=41001 + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$ROOT_DIR" + +PYTHON_BIN="${PYTHON_BIN:-.venv/bin/python}" +MPIEXEC="${MPIEXEC:-mpiexec}" +HOSTFILE="${HOSTFILE:-}" +RANKS="${RANKS:-4}" +TORCH_THREADS="${TORCH_THREADS:-1}" +CUT_RATIO="${CUT_RATIO:-1e-12}" +OBS_FILTER="${OBS_FILTER:-}" + +RUNNER_DIR="$ROOT_DIR/.tmp" +mkdir -p "$RUNNER_DIR" +RUNNER="$(mktemp "$RUNNER_DIR/qibotn_vidal_contest.XXXXXX.py")" +cleanup() { + rm -f "$RUNNER" +} +trap cleanup EXIT + +cat > "$RUNNER" <<'PY' +from __future__ import annotations + +import argparse +import math +import time + +import numpy as np +from mpi4py import MPI +from qibo import Circuit, gates, hamiltonians +from qibo.symbols import X, Y, Z + +from qibotn.backends.vidal import VidalBackend + + +def set_torch_threads(nthreads): + try: + import torch + + torch.set_num_threads(nthreads) + except Exception: + pass + + +def build_circuit(kind, nqubits, nlayers, seed): + rng = np.random.default_rng(seed) + circuit = Circuit(nqubits) + + for layer in range(nlayers): + for q in range(nqubits): + circuit.add(gates.RY(q, theta=rng.uniform(-math.pi, math.pi))) + circuit.add(gates.RZ(q, theta=rng.uniform(-math.pi, math.pi))) + if kind in ("rxx_rzz", "scramble"): + circuit.add(gates.RX(q, theta=rng.uniform(-math.pi, math.pi))) + + if kind == "reversed_cnot": + for q in range(0, nqubits - 1, 2): + circuit.add(gates.CNOT(q + 1, q) if layer % 2 else gates.CNOT(q, q + 1)) + for q in range(1, nqubits - 1, 2): + circuit.add(gates.CNOT(q + 1, q) if layer % 2 == 0 else gates.CNOT(q, q + 1)) + elif kind == "rxx_rzz": + for q in range(layer % 2, nqubits - 1, 2): + circuit.add(gates.RXX(q, q + 1, theta=rng.uniform(-0.9, 0.9))) + circuit.add(gates.RZZ(q, q + 1, theta=rng.uniform(-0.9, 0.9))) + elif kind == "scramble": + for q in range(layer % 2, nqubits - 1, 2): + circuit.add(gates.RXX(q, q + 1, theta=rng.uniform(-0.8, 0.8))) + circuit.add(gates.RZZ(q, q + 1, theta=rng.uniform(-0.8, 0.8))) + if layer % 5 == 4: + circuit.add(gates.SWAP(q, q + 1)) + else: + raise ValueError(f"Unknown circuit kind {kind!r}.") + + return circuit + + +def ring_xz(nqubits): + form = 0 + for q in range(nqubits): + form += 0.5 * X(q) * Z((q + 1) % nqubits) + return hamiltonians.SymbolicHamiltonian(form=form) + + +def open_zz(nqubits): + form = 0 + for q in range(nqubits - 1): + form += (1.0 / (nqubits - 1)) * Z(q) * Z(q + 1) + return hamiltonians.SymbolicHamiltonian(form=form) + + +def range2_xx(nqubits): + form = 0 + for q in range(nqubits - 2): + form += (1.0 / (nqubits - 2)) * X(q) * X(q + 2) + return hamiltonians.SymbolicHamiltonian(form=form) + + +def dense_observable(nqubits, qubits, seed, dim): + rng = np.random.default_rng(seed) + raw = rng.normal(size=(dim, dim)) + 1j * rng.normal(size=(dim, dim)) + matrix = (raw + raw.conj().T) / 2.0 + matrix = matrix / np.linalg.norm(matrix) + return {"matrix": matrix, "qubits": list(qubits)} + + +def observables_for_case(nqubits, seed): + q1 = nqubits // 4 + q2 = nqubits // 2 + q3 = (3 * nqubits) // 4 + last = nqubits - 1 + + return [ + ("boundary_ZZ_q1", hamiltonians.SymbolicHamiltonian(form=Z(q1 - 1) * Z(q1))), + ("boundary_ZZ_q2", hamiltonians.SymbolicHamiltonian(form=Z(q2 - 1) * Z(q2))), + ("boundary_ZZ_q3", hamiltonians.SymbolicHamiltonian(form=Z(q3 - 1) * Z(q3))), + ( + "long_Z_5_sites", + hamiltonians.SymbolicHamiltonian(form=Z(0) * Z(q1) * Z(q2) * Z(q3) * Z(last)), + ), + ( + "mixed_XZYZX", + hamiltonians.SymbolicHamiltonian(form=X(0) * Z(q1) * Y(q2) * Z(q3) * X(last)), + ), + ("ring_xz", ring_xz(nqubits)), + ("open_zz", open_zz(nqubits)), + ("range2_xx", range2_xx(nqubits)), + ("complex_iZ0", hamiltonians.SymbolicHamiltonian(form=1.0j * Z(0))), + ("dense2_mid", dense_observable(nqubits, (q2 - 1, q2), seed + 101, 4)), + ("dense3_spread", dense_observable(nqubits, (q1, q2, q3), seed + 202, 8)), + ] + + +def run_case(args): + set_torch_threads(args.torch_threads) + comm = MPI.COMM_WORLD + rank = comm.Get_rank() + size = comm.Get_size() + + circuit = build_circuit(args.kind, args.nqubits, args.nlayers, args.seed) + observables = observables_for_case(args.nqubits, args.seed) + if args.obs_filter: + wanted = set(args.obs_filter.split(",")) + observables = [(name, obs) for name, obs in observables if name in wanted] + if not observables: + raise ValueError(f"OBS_FILTER matched no observables: {args.obs_filter!r}") + + if rank == 0: + print("=" * 88, flush=True) + print( + "case " + f"label={args.label} kind={args.kind} ranks={size} " + f"nqubits={args.nqubits} nlayers={args.nlayers} gates={len(circuit.queue)} " + f"bond={args.bond} cut_ratio={args.cut_ratio:g} " + f"torch_threads={args.torch_threads} seed={args.seed} " + f"obs_filter={args.obs_filter or 'all'}", + flush=True, + ) + print( + "observable value seconds trunc_sum trunc_max status", + flush=True, + ) + + for obs_name, observable in observables: + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=args.bond, + cut_ratio=args.cut_ratio, + tensor_module="torch", + mpi_approach="CT", + mpi_num_procs=size, + fallback=False, + ) + + comm.Barrier() + start = time.perf_counter() + try: + value = backend.expectation( + circuit, + observable, + preprocess=True, + compile_circuit=False, + ) + status = "ok" + except Exception as exc: # pragma: no cover - printed for manual runs + value = np.nan + status = type(exc).__name__ + ":" + str(exc).split("\n", 1)[0] + seconds = time.perf_counter() - start + + if rank == 0: + print( + f"{obs_name} {value!r} {seconds:.3f} " + f"{backend.last_truncation_error:.6e} " + f"{backend.last_max_truncation_error:.6e} {status}", + flush=True, + ) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--label", required=True) + parser.add_argument("--kind", choices=("reversed_cnot", "rxx_rzz", "scramble"), required=True) + parser.add_argument("--nqubits", type=int, required=True) + parser.add_argument("--nlayers", type=int, required=True) + parser.add_argument("--bond", type=int, required=True) + parser.add_argument("--cut-ratio", type=float, required=True) + parser.add_argument("--seed", type=int, required=True) + parser.add_argument("--torch-threads", type=int, required=True) + parser.add_argument("--obs-filter", default="") + run_case(parser.parse_args()) + + +if __name__ == "__main__": + main() +PY + +if [[ -n "${MPIEXEC_FULL:-}" ]]; then + read -r -a mpi_prefix <<< "$MPIEXEC_FULL" +else + mpi_prefix=("$MPIEXEC") + if [[ -n "$HOSTFILE" && -f "$HOSTFILE" ]]; then + mpi_prefix+=("-hostfile" "$HOSTFILE") + fi + mpi_prefix+=("-n" "$RANKS") +fi + +run_case() { + local label="$1" + local kind="$2" + local nq="$3" + local layers="$4" + local bond="$5" + local seed="$6" + + echo + echo "Running $label: kind=$kind nqubits=$nq layers=$layers bond=$bond seed=$seed" + echo "MPI: ${mpi_prefix[*]}" + "${mpi_prefix[@]}" "$PYTHON_BIN" -u "$ROOT_DIR/tools/vidal_mpi_contest_runner.py" \ + --label "$label" \ + --kind "$kind" \ + --nqubits "$nq" \ + --nlayers "$layers" \ + --bond "$bond" \ + --cut-ratio "$CUT_RATIO" \ + --seed "$seed" \ + --torch-threads "$TORCH_THREADS" \ + --obs-filter "$(tr ' ' ',' <<< "$OBS_FILTER")" +} + +case "${1:-help}" in + main1) + run_case \ + "main1-reversed-cnot" \ + "reversed_cnot" \ + "${MAIN1_NQ:-128}" \ + "${MAIN1_LAYERS:-50}" \ + "${MAIN1_BOND:-1024}" \ + "${MAIN1_SEED:-31001}" + ;; + main2) + run_case \ + "main2-rxx-rzz" \ + "rxx_rzz" \ + "${MAIN2_NQ:-128}" \ + "${MAIN2_LAYERS:-64}" \ + "${MAIN2_BOND:-2048}" \ + "${MAIN2_SEED:-31002}" + ;; + strong) + run_case \ + "strong-scramble" \ + "scramble" \ + "${STRONG_NQ:-256}" \ + "${STRONG_LAYERS:-64}" \ + "${STRONG_BOND:-2048}" \ + "${STRONG_SEED:-41001}" + ;; + all) + "$0" main1 + "$0" main2 + "$0" strong + ;; + smoke) + MAIN1_NQ="${MAIN1_NQ:-32}" \ + MAIN1_LAYERS="${MAIN1_LAYERS:-6}" \ + MAIN1_BOND="${MAIN1_BOND:-128}" \ + "$0" main1 + ;; + help|*) + cat >&2 <<'EOF' +Usage: tools/run_vidal_mpi_contest_cases.sh [main1|main2|strong|all|smoke] + +Cases: + main1 128 qubits, 50 layers, reversed-CNOT brickwall, chi=1024 + main2 128 qubits, 64 layers, RXX/RZZ brickwall, chi=2048 + strong 256 qubits, 64 layers, RXX/RZZ + periodic SWAP scramble, chi=2048 + smoke Small syntax/runtime check of main1 + +Common overrides: + PYTHON_BIN=.venv/bin/python + MPIEXEC=mpiexec + MPIEXEC_FULL="mpirun -np 4 -hostfile /home/yx/qibotn/hostfile -perhost 2" + HOSTFILE=hostfile + RANKS=8 + TORCH_THREADS=8 + CUT_RATIO=1e-12 + OBS_FILTER="boundary_ZZ_q2 ring_xz dense3_spread complex_iZ0" + +Per-case overrides: + MAIN1_NQ=128 MAIN1_LAYERS=50 MAIN1_BOND=1024 MAIN1_SEED=31001 + MAIN2_NQ=128 MAIN2_LAYERS=64 MAIN2_BOND=2048 MAIN2_SEED=31002 + STRONG_NQ=256 STRONG_LAYERS=64 STRONG_BOND=2048 STRONG_SEED=41001 +EOF + exit 2 + ;; +esac diff --git a/tools/slice_existing_tree.py b/tools/slice_existing_tree.py new file mode 100644 index 0000000..4e94e9c --- /dev/null +++ b/tools/slice_existing_tree.py @@ -0,0 +1,59 @@ +"""Slice an existing saved cotengra tree without re-running path search.""" + +from __future__ import annotations + +import argparse +import pickle +from pathlib import Path + +from qibotn.parallel import contraction_tree_costs + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("input", help="Input pickle saved by --tn-save-tree.") + parser.add_argument("output", help="Output pickle path.") + parser.add_argument("--term", type=int, default=0) + parser.add_argument("--target-slices", type=int, default=2) + parser.add_argument("--max-repeats", type=int, default=64) + parser.add_argument("--seed", type=int, default=42) + args = parser.parse_args() + + input_path = Path(args.input) + output_path = Path(args.output) + with input_path.open("rb") as f: + payload = pickle.load(f) + + trees = payload["trees"] if isinstance(payload, dict) else payload + if not isinstance(trees, (list, tuple)): + trees = [trees] + tree = trees[args.term] + + print("original", contraction_tree_costs(tree), flush=True) + sliced = tree.slice( + target_slices=args.target_slices, + max_repeats=args.max_repeats, + seed=args.seed, + ) + print("sliced", contraction_tree_costs(sliced), flush=True) + print(f"sliced_inds={sliced.sliced_inds}", flush=True) + + new_trees = list(trees) + new_trees[args.term] = sliced + + if isinstance(payload, dict): + out_payload = dict(payload) + out_payload["trees"] = new_trees + out_payload["costs"] = [contraction_tree_costs(t) for t in new_trees] + out_payload["nterms"] = len(new_trees) + else: + out_payload = new_trees + + output_path.parent.mkdir(parents=True, exist_ok=True) + with output_path.open("wb") as f: + pickle.dump(out_payload, f) + print(f"saved {output_path}", flush=True) + + +if __name__ == "__main__": + main() diff --git a/tools/tn_contest_runner.py b/tools/tn_contest_runner.py new file mode 100644 index 0000000..680cecd --- /dev/null +++ b/tools/tn_contest_runner.py @@ -0,0 +1,435 @@ +#!/usr/bin/env python +"""Contest-style CPU TN path search and contraction runner. + +This file is intentionally self-contained: define contest circuits and +observables here, run path search once, then load the saved trees for repeated +MPI contractions. +""" + +from __future__ import annotations + +import argparse +import math +import os +import subprocess +import sys +from dataclasses import dataclass +from pathlib import Path +from urllib.parse import urlparse + +import numpy as np +from qibo import Circuit, gates, hamiltonians +from qibo.symbols import X, Y, Z + +ROOT = Path(__file__).resolve().parents[1] +SRC = ROOT / "src" +if str(SRC) not in sys.path: + sys.path.insert(0, str(SRC)) + +from qibotn.expectation_runner import ( # noqa: E402 + ExpectationConfig, + exact_for_observable, + run_cpu_expectation, +) + + +@dataclass(frozen=True) +class CaseSpec: + circuit_kind: str + observables: tuple[str, ...] + nqubits: int + nlayers: int + seed: int + target_slices: int | None = None + + +CASES = { + "main1": CaseSpec( + circuit_kind="rxx_rzz_chain", + observables=("ring_xz",), + nqubits=34, + nlayers=20, + seed=31001, + target_slices=None, + ), + "main2": CaseSpec( + circuit_kind="scramble_chain", + observables=("open_zz", "range2_xx"), + nqubits=36, + nlayers=18, + seed=31002, + target_slices=None, + ), + "strong": CaseSpec( + circuit_kind="reversed_cnot", + observables=("ring_xz", "long_z_string"), + nqubits=40, + nlayers=24, + seed=41001, + target_slices=None, + ), +} + + +def optional_int(text): + if isinstance(text, str) and text.lower() in {"none", "null", "inf", "unlimited"}: + return None + return int(text) + + +def optional_float(text): + if isinstance(text, str) and text.lower() in {"none", "null", "inf", "unlimited"}: + return None + return float(text) + + +def set_torch_threads(nthreads): + try: + import torch + + torch.set_num_threads(nthreads) + except Exception: + pass + + +def add_single_qubit_layer(circuit, nqubits, rng, include_rx=False): + for qubit in range(nqubits): + circuit.add(gates.RY(qubit, theta=rng.uniform(-math.pi, math.pi))) + circuit.add(gates.RZ(qubit, theta=rng.uniform(-math.pi, math.pi))) + if include_rx: + circuit.add(gates.RX(qubit, theta=rng.uniform(-math.pi, math.pi))) + + +def build_circuit(kind, nqubits, nlayers, seed): + """Define contest circuits here.""" + rng = np.random.default_rng(seed) + circuit = Circuit(nqubits) + + for layer in range(nlayers): + if kind == "rxx_rzz_chain": + add_single_qubit_layer(circuit, nqubits, rng, include_rx=True) + for qubit in range(layer % 2, nqubits - 1, 2): + circuit.add(gates.RXX(qubit, qubit + 1, theta=rng.uniform(-0.9, 0.9))) + circuit.add(gates.RZZ(qubit, qubit + 1, theta=rng.uniform(-0.9, 0.9))) + + elif kind == "scramble_chain": + add_single_qubit_layer(circuit, nqubits, rng, include_rx=True) + for qubit in range(layer % 2, nqubits - 1, 2): + circuit.add(gates.RXX(qubit, qubit + 1, theta=rng.uniform(-0.8, 0.8))) + circuit.add(gates.RZZ(qubit, qubit + 1, theta=rng.uniform(-0.8, 0.8))) + if layer % 5 == 4: + circuit.add(gates.SWAP(qubit, qubit + 1)) + + elif kind == "reversed_cnot": + add_single_qubit_layer(circuit, nqubits, rng) + for qubit in range(0, nqubits - 1, 2): + gate = gates.CNOT(qubit + 1, qubit) if layer % 2 else gates.CNOT(qubit, qubit + 1) + circuit.add(gate) + for qubit in range(1, nqubits - 1, 2): + gate = gates.CNOT(qubit + 1, qubit) if layer % 2 == 0 else gates.CNOT(qubit, qubit + 1) + circuit.add(gate) + + else: + raise ValueError(f"Unknown circuit kind {kind!r}.") + + return circuit + + +def pauli_sum_observable(kind, nqubits, seed): + """Define contest observables here. + + TN path currently expects Pauli products / SymbolicHamiltonian terms. + Keep production contest observables Hermitian unless complex output is + explicitly required by the scoring rule. + """ + del seed + if kind == "ring_xz": + form = 0 + for qubit in range(nqubits): + form += 0.5 * X(qubit) * Z((qubit + 1) % nqubits) + return hamiltonians.SymbolicHamiltonian(form=form) + + if kind == "open_zz": + form = 0 + for qubit in range(nqubits - 1): + form += (1.0 / max(1, nqubits - 1)) * Z(qubit) * Z(qubit + 1) + return hamiltonians.SymbolicHamiltonian(form=form) + + if kind == "range2_xx": + form = 0 + for qubit in range(nqubits - 2): + form += (1.0 / max(1, nqubits - 2)) * X(qubit) * X(qubit + 2) + return hamiltonians.SymbolicHamiltonian(form=form) + + if kind == "long_z_string": + stride = max(1, nqubits // 16) + form = None + for qubit in range(0, nqubits, stride): + form = Z(qubit) if form is None else form * Z(qubit) + return hamiltonians.SymbolicHamiltonian(form=form) + + if kind == "mixed_local": + q1 = nqubits // 4 + q2 = nqubits // 2 + q3 = (3 * nqubits) // 4 + form = 0.25 * X(0) - 0.5 * Z(nqubits - 1) + form += 0.125 * X(q1) * Z(q2) * Y(q3) + return hamiltonians.SymbolicHamiltonian(form=form) + + raise ValueError(f"Unknown observable kind {kind!r}.") + + +def tree_path(tree_dir, case_name, obs_name, nqubits, nlayers, target_slices): + slice_label = "auto" if target_slices is None else f"s{target_slices}" + return ( + Path(tree_dir) + / f"{case_name}_{obs_name}_{nqubits}q{nlayers}l_{slice_label}.pkl" + ) + + +def build_parallel_opts(args, tree_file=None, search_only=False): + slicing_opts = {} + if args.tn_target_slices is not None: + slicing_opts["target_slices"] = args.tn_target_slices + if args.tn_target_size is not None: + slicing_opts["target_size"] = args.tn_target_size + + opts = { + "slicing_opts": slicing_opts or None, + "search_workers": args.tn_search_workers or args.torch_threads, + "max_repeats": args.tn_search_repeats, + "max_time": args.tn_search_time, + "print_stats": not args.no_tn_stats, + } + if args.tn_search_backend is not None: + opts["search_backend"] = args.tn_search_backend + if args.dask_address is not None: + opts["dask_address"] = args.dask_address + if args.dask_close_workers: + opts["dask_close_workers"] = True + if args.tn_debug_trials: + opts["debug_trials"] = True + if search_only: + opts["search_only"] = True + opts["save_tree_path"] = str(tree_file) + elif tree_file is not None: + opts["load_tree_path"] = str(tree_file) + return opts + + +def run_one(args, case_name, obs_name, mode): + case = CASES[case_name] + circuit = build_circuit(case.circuit_kind, args.nqubits, args.nlayers, args.seed) + observable = pauli_sum_observable(obs_name, args.nqubits, args.seed) + path = tree_path( + args.tree_dir, + case_name, + obs_name, + args.nqubits, + args.nlayers, + args.tn_target_slices, + ) + path.parent.mkdir(parents=True, exist_ok=True) + + rank = 0 + if args.mpi: + from mpi4py import MPI + + rank = MPI.COMM_WORLD.Get_rank() + + if rank == 0: + print("=" * 88, flush=True) + print( + f"mode={mode} case={case_name} circuit={case.circuit_kind} " + f"observable={obs_name} nqubits={args.nqubits} nlayers={args.nlayers} " + f"seed={args.seed} gates={len(circuit.queue)} tree={path}", + flush=True, + ) + + if mode == "contract" and not path.exists(): + raise FileNotFoundError(f"Missing tree file: {path}. Run search first.") + + exact = None + if args.exact and rank == 0 and mode != "search": + if args.nqubits > args.exact_max_qubits: + raise ValueError( + f"--exact is limited to {args.exact_max_qubits} qubits by default." + ) + exact = exact_for_observable(circuit, observable, args.nqubits) + + config = ExpectationConfig( + ansatz="tn", + mpi=args.mpi, + bond=args.bond, + cut_ratio=args.cut_ratio, + tensor_module="torch", + quimb_backend=args.quimb_backend, + dtype=args.dtype, + torch_threads=args.torch_threads, + parallel_opts=build_parallel_opts( + args, + tree_file=path, + search_only=(mode == "search"), + ), + ) + result = run_cpu_expectation(circuit, observable, config) + if args.mpi and result.rank != 0: + return + + if mode == "search": + print(f"searched observable={obs_name} tree={path}", flush=True) + else: + abs_error = float("nan") if exact is None else abs(result.value - exact) + rel_error = float("nan") if exact is None else abs_error / max(abs(exact), 1e-15) + exact_text = "nan" if exact is None else f"{exact:.16e}" + print( + f"result observable={obs_name} exact={exact_text} " + f"value={result.value:.16e} abs_error={abs_error:.6e} " + f"rel_error={rel_error:.6e} seconds={result.seconds:.3f}", + flush=True, + ) + + for stat in result.parallel_stats or (): + cost = stat["path_cost"] + search_stats = stat.get("search_stats", {}) + print( + "tn_term_summary " + f"observable={obs_name} " + f"term={stat.get('term_index', 0)} " + f"search_seconds={stat.get('search_seconds', float('nan')):.3f} " + f"contract_seconds={stat.get('contract_seconds', float('nan')):.3f} " + f"completed_trials={search_stats.get('completed_trials', 'na')} " + f"finite_trials={search_stats.get('finite_trials', 'na')} " + f"failed_trials={search_stats.get('failed_trials', 'na')} " + f"requested_trials={search_stats.get('requested_trials', 'na')} " + f"best_score={search_stats.get('best_score', float('nan')):.6g} " + f"slices={cost.get('slices')} " + f"log10_flops={cost.get('log10_flops', float('nan')):.3f} " + f"log10_write={cost.get('log10_write', float('nan')):.3f} " + f"log2_size={cost.get('log2_size', float('nan')):.3f} " + f"peak_memory_gib={cost.get('peak_memory_gib', float('nan')):.3g} " + f"rank_slices={stat.get('rank_slices')}", + flush=True, + ) + + +def selected_observables(args, case): + if args.observables: + return tuple(args.observables) + if args.obs_filter: + return tuple(x.strip() for x in args.obs_filter.split(",") if x.strip()) + return case.observables + + +def apply_case_defaults(args): + case = CASES[args.case] + if args.nqubits is None: + args.nqubits = case.nqubits + if args.nlayers is None: + args.nlayers = case.nlayers + if args.seed is None: + args.seed = case.seed + if args.tn_target_slices is None: + args.tn_target_slices = case.target_slices + args.observables = selected_observables(args, case) + + +def stop_dask_cluster(args): + if args.keep_dask or args.tn_search_backend != "dask" or not args.dask_address: + return + script = ROOT / "tools" / "manage_tn_dask_cluster.sh" + if not script.exists(): + print(f"dask_stop_skipped reason=missing_script path={script}", flush=True) + return + + env = os.environ.copy() + parsed = urlparse(args.dask_address) + if parsed.hostname: + env.setdefault("SCHEDULER_HOST", parsed.hostname) + if parsed.port: + env.setdefault("SCHEDULER_PORT", str(parsed.port)) + + print("dask_stop_after_search start", flush=True) + subprocess.run([str(script), "stop"], cwd=str(ROOT), env=env, check=False) + print("dask_stop_after_search done", flush=True) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("mode", choices=("search", "contract", "all", "validate", "list")) + parser.add_argument("--case", choices=sorted(CASES), default="main1") + parser.add_argument("--observables", nargs="+") + parser.add_argument("--obs-filter", default="") + parser.add_argument("--tree-dir", default="trees/contest_tn") + parser.add_argument("--nqubits", type=int) + parser.add_argument("--nlayers", type=int) + parser.add_argument("--seed", type=int) + parser.add_argument("--mpi", action="store_true") + parser.add_argument("--exact", action="store_true") + parser.add_argument("--exact-max-qubits", type=int, default=24) + parser.add_argument("--bond", "--bonds", dest="bond", type=optional_int, default=1024) + parser.add_argument("--cut-ratio", type=optional_float, default=1e-12) + parser.add_argument("--torch-threads", type=int, default=8) + parser.add_argument("--quimb-backend", choices=("numpy", "torch"), default="torch") + parser.add_argument("--dtype", choices=("complex128", "complex64"), default="complex64") + parser.add_argument("--tn-target-slices", type=int) + parser.add_argument("--tn-target-size", type=int, default=2**32) + parser.add_argument("--tn-search-workers", type=int) + parser.add_argument("--tn-search-repeats", type=int, default=2048) + parser.add_argument("--tn-search-time", type=float, default=300.0) + parser.add_argument( + "--tn-search-backend", + choices=("processpool", "dask"), + default="dask", + help=( + "Path-search backend. Defaults to dask. Without --dask-address, " + "non-MPI search starts a local dask cluster." + ), + ) + parser.add_argument("--dask-address") + parser.add_argument("--dask-close-workers", action="store_true") + parser.add_argument( + "--keep-dask", + action="store_true", + help=( + "Keep an external dask cluster running after search. By default, " + "tools/manage_tn_dask_cluster.sh stop is called after search when " + "--dask-address is used." + ), + ) + parser.add_argument( + "--tn-debug-trials", + action="store_true", + help="Print dask worker summary and per-trial start/done logs.", + ) + parser.add_argument("--no-tn-stats", action="store_true") + args = parser.parse_args() + + if args.mode == "list": + for name, case in CASES.items(): + print( + f"{name}: circuit={case.circuit_kind} " + f"observables={','.join(case.observables)} " + f"nqubits={case.nqubits} nlayers={case.nlayers} " + f"seed={case.seed} target_slices={case.target_slices}" + ) + return + + apply_case_defaults(args) + set_torch_threads(args.torch_threads) + + modes = ("search", "contract") if args.mode == "all" else (args.mode,) + if args.mode == "validate": + args.exact = True + args.nqubits = min(args.nqubits, args.exact_max_qubits) + modes = ("search", "contract") + + for mode in modes: + for obs_name in args.observables: + run_one(args, args.case, obs_name, mode) + if mode == "search": + stop_dask_cluster(args) + + +if __name__ == "__main__": + main() diff --git a/tools/torch_profile_tn_complex64.py b/tools/torch_profile_tn_complex64.py new file mode 100644 index 0000000..b7392f9 --- /dev/null +++ b/tools/torch_profile_tn_complex64.py @@ -0,0 +1,114 @@ +"""Run the 34q/20L TN complex64 benchmark under torch.profiler briefly.""" + +from __future__ import annotations + +import argparse +import os +import signal +import sys +from pathlib import Path + +from mpi4py import MPI + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--seconds", type=float, default=30.0) + parser.add_argument("--out-dir", default="torch_profiles/tn_complex64") + parser.add_argument("--torch-threads", type=int, default=48) + args = parser.parse_args() + + repo_root = Path(__file__).resolve().parents[1] + os.chdir(repo_root) + sys.path.insert(0, str(repo_root)) + + import torch + from torch.profiler import ProfilerActivity, profile + + comm = MPI.COMM_WORLD + rank = comm.Get_rank() + size = comm.Get_size() + out_dir = Path(args.out_dir) + if rank == 0: + out_dir.mkdir(parents=True, exist_ok=True) + comm.Barrier() + + torch.set_num_threads(args.torch_threads) + + def run_benchmark(): + import benchmark_cpu_expectation + + sys.argv = [ + "benchmark_cpu_expectation.py", + "--mpi", + "--ansatz", + "tn", + "--nqubits", + "34", + "--nlayers", + "20", + "--circuits", + "rxx_rzz", + "--pauli-pattern", + "XZ", + "--tn-load-tree", + "trees/rxx_rzz_34q20l_s4.pkl", + "--quimb-backend", + "torch", + "--torch-threads", + str(args.torch_threads), + "--dtype", + "complex64", + ] + benchmark_cpu_expectation.main() + + trace_path = out_dir / f"rank{rank}_trace.json" + stacks_path = out_dir / f"rank{rank}_stacks.txt" + summary_path = out_dir / f"rank{rank}_summary.txt" + + prof = profile( + activities=[ProfilerActivity.CPU], + record_shapes=True, + profile_memory=True, + with_stack=True, + ) + + class ProfileTimeout(Exception): + pass + + def alarm_handler(signum, frame): + raise ProfileTimeout() + + old_handler = signal.signal(signal.SIGALRM, alarm_handler) + signal.setitimer(signal.ITIMER_REAL, args.seconds) + try: + with prof: + try: + run_benchmark() + except ProfileTimeout: + pass + finally: + signal.setitimer(signal.ITIMER_REAL, 0) + signal.signal(signal.SIGALRM, old_handler) + + prof.export_chrome_trace(str(trace_path)) + try: + prof.export_stacks(str(stacks_path), "self_cpu_time_total") + except Exception as exc: # pragma: no cover - diagnostic only + stacks_path.write_text(f"export_stacks failed: {exc}\n", encoding="utf-8") + + summary = prof.key_averages(group_by_stack_n=5).table( + sort_by="self_cpu_time_total", + row_limit=40, + ) + summary_path.write_text(summary, encoding="utf-8") + + print( + f"torch_profile_done rank={rank}/{size} " + f"trace={trace_path} summary={summary_path}", + flush=True, + ) + + +if __name__ == "__main__": + main() diff --git a/tools/vidal_mpi_contest_runner.py b/tools/vidal_mpi_contest_runner.py new file mode 100644 index 0000000..405f47c --- /dev/null +++ b/tools/vidal_mpi_contest_runner.py @@ -0,0 +1,209 @@ +from __future__ import annotations + +import argparse +import math +import time + +import numpy as np +from mpi4py import MPI +from qibo import Circuit, gates, hamiltonians +from qibo.symbols import X, Y, Z + +from qibotn.backends.vidal import VidalBackend + + +def optional_int(text): + if isinstance(text, str) and text.lower() in {"none", "null", "inf", "unlimited"}: + return None + return int(text) + + +def optional_float(text): + if isinstance(text, str) and text.lower() in {"none", "null", "inf", "unlimited"}: + return None + return float(text) + + +def format_optional(value, fmt="g"): + return "None" if value is None else format(value, fmt) + + +def set_torch_threads(nthreads): + try: + import torch + + torch.set_num_threads(nthreads) + except Exception: + pass + + +def build_circuit(kind, nqubits, nlayers, seed): + rng = np.random.default_rng(seed) + circuit = Circuit(nqubits) + + for layer in range(nlayers): + for q in range(nqubits): + circuit.add(gates.RY(q, theta=rng.uniform(-math.pi, math.pi))) + circuit.add(gates.RZ(q, theta=rng.uniform(-math.pi, math.pi))) + if kind in ("rxx_rzz", "scramble"): + circuit.add(gates.RX(q, theta=rng.uniform(-math.pi, math.pi))) + + if kind == "reversed_cnot": + for q in range(0, nqubits - 1, 2): + circuit.add(gates.CNOT(q + 1, q) if layer % 2 else gates.CNOT(q, q + 1)) + for q in range(1, nqubits - 1, 2): + circuit.add(gates.CNOT(q + 1, q) if layer % 2 == 0 else gates.CNOT(q, q + 1)) + elif kind == "rxx_rzz": + for q in range(layer % 2, nqubits - 1, 2): + circuit.add(gates.RXX(q, q + 1, theta=rng.uniform(-0.9, 0.9))) + circuit.add(gates.RZZ(q, q + 1, theta=rng.uniform(-0.9, 0.9))) + elif kind == "scramble": + for q in range(layer % 2, nqubits - 1, 2): + circuit.add(gates.RXX(q, q + 1, theta=rng.uniform(-0.8, 0.8))) + circuit.add(gates.RZZ(q, q + 1, theta=rng.uniform(-0.8, 0.8))) + if layer % 5 == 4: + circuit.add(gates.SWAP(q, q + 1)) + else: + raise ValueError(f"Unknown circuit kind {kind!r}.") + + return circuit + + +def ring_xz(nqubits): + form = 0 + for q in range(nqubits): + form += 0.5 * X(q) * Z((q + 1) % nqubits) + return hamiltonians.SymbolicHamiltonian(form=form) + + +def open_zz(nqubits): + form = 0 + for q in range(nqubits - 1): + form += (1.0 / (nqubits - 1)) * Z(q) * Z(q + 1) + return hamiltonians.SymbolicHamiltonian(form=form) + + +def range2_xx(nqubits): + form = 0 + for q in range(nqubits - 2): + form += (1.0 / (nqubits - 2)) * X(q) * X(q + 2) + return hamiltonians.SymbolicHamiltonian(form=form) + + +def dense_observable(nqubits, qubits, seed, dim): + rng = np.random.default_rng(seed) + raw = rng.normal(size=(dim, dim)) + 1j * rng.normal(size=(dim, dim)) + matrix = (raw + raw.conj().T) / 2.0 + matrix = matrix / np.linalg.norm(matrix) + return {"matrix": matrix, "qubits": list(qubits)} + + +def observables_for_case(nqubits, seed): + q1 = nqubits // 4 + q2 = nqubits // 2 + q3 = (3 * nqubits) // 4 + last = nqubits - 1 + + return [ + ("boundary_ZZ_q1", hamiltonians.SymbolicHamiltonian(form=Z(q1 - 1) * Z(q1))), + ("boundary_ZZ_q2", hamiltonians.SymbolicHamiltonian(form=Z(q2 - 1) * Z(q2))), + ("boundary_ZZ_q3", hamiltonians.SymbolicHamiltonian(form=Z(q3 - 1) * Z(q3))), + ( + "long_Z_5_sites", + hamiltonians.SymbolicHamiltonian(form=Z(0) * Z(q1) * Z(q2) * Z(q3) * Z(last)), + ), + ( + "mixed_XZYZX", + hamiltonians.SymbolicHamiltonian(form=X(0) * Z(q1) * Y(q2) * Z(q3) * X(last)), + ), + ("ring_xz", ring_xz(nqubits)), + ("open_zz", open_zz(nqubits)), + ("range2_xx", range2_xx(nqubits)), + ("complex_iZ0", hamiltonians.SymbolicHamiltonian(form=1.0j * Z(0))), + ("dense2_mid", dense_observable(nqubits, (q2 - 1, q2), seed + 101, 4)), + ("dense3_spread", dense_observable(nqubits, (q1, q2, q3), seed + 202, 8)), + ] + + +def run_case(args): + set_torch_threads(args.torch_threads) + comm = MPI.COMM_WORLD + rank = comm.Get_rank() + size = comm.Get_size() + + circuit = build_circuit(args.kind, args.nqubits, args.nlayers, args.seed) + observables = observables_for_case(args.nqubits, args.seed) + if args.obs_filter: + wanted = set(args.obs_filter.split(",")) + observables = [(name, obs) for name, obs in observables if name in wanted] + if not observables: + raise ValueError(f"OBS_FILTER matched no observables: {args.obs_filter!r}") + + if rank == 0: + print("=" * 88, flush=True) + print( + "case " + f"label={args.label} kind={args.kind} ranks={size} " + f"nqubits={args.nqubits} nlayers={args.nlayers} gates={len(circuit.queue)} " + f"bond={format_optional(args.bond)} " + f"cut_ratio={format_optional(args.cut_ratio)} " + f"torch_threads={args.torch_threads} seed={args.seed} " + f"obs_filter={args.obs_filter or 'all'}", + flush=True, + ) + print( + "observable value seconds trunc_sum trunc_max status", + flush=True, + ) + + for obs_name, observable in observables: + backend = VidalBackend() + backend.configure_tn_simulation( + max_bond_dimension=args.bond, + cut_ratio=args.cut_ratio, + tensor_module="torch", + mpi_approach="CT", + mpi_num_procs=size, + fallback=False, + ) + + comm.Barrier() + start = time.perf_counter() + try: + value = backend.expectation( + circuit, + observable, + preprocess=True, + compile_circuit=False, + ) + status = "ok" + except Exception as exc: # pragma: no cover - printed for manual runs + value = np.nan + status = type(exc).__name__ + ":" + str(exc).split("\n", 1)[0] + seconds = time.perf_counter() - start + + if rank == 0: + print( + f"{obs_name} {value!r} {seconds:.3f} " + f"{backend.last_truncation_error:.6e} " + f"{backend.last_max_truncation_error:.6e} {status}", + flush=True, + ) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--label", required=True) + parser.add_argument("--kind", choices=("reversed_cnot", "rxx_rzz", "scramble"), required=True) + parser.add_argument("--nqubits", type=int, required=True) + parser.add_argument("--nlayers", type=int, required=True) + parser.add_argument("--bond", type=optional_int, required=True) + parser.add_argument("--cut-ratio", type=optional_float, required=True) + parser.add_argument("--seed", type=int, required=True) + parser.add_argument("--torch-threads", type=int, required=True) + parser.add_argument("--obs-filter", default="") + run_case(parser.parse_args()) + + +if __name__ == "__main__": + main() diff --git a/trees/contest_tn/main1_long_z_string_34q20l_auto.pkl b/trees/contest_tn/main1_long_z_string_34q20l_auto.pkl new file mode 100644 index 0000000000000000000000000000000000000000..76eeedd5e5d3e1cc0a742ee36cb9cc6ea4e7a5c9 GIT binary patch literal 448972 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 {PsDZWQhYN$Nyj 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

C6{`KjyrG`QzY=op)uv6#NP2!u%=lr=6d{d>Qz& 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%0DT{*oGsU?cV!ju$N+df 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 F`!~$!o}&N& literal 0 HcmV?d00001 diff --git a/trees/contest_tn/main1_ring_xz_8q2l_s1.pkl b/trees/contest_tn/main1_ring_xz_8q2l_s1.pkl new file mode 100644 index 0000000000000000000000000000000000000000..f2180f4264c1b15f6d7571bdd15a5249835bae5e GIT binary patch literal 3304 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 l#hi~1t<7eh7M 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 literal 0 HcmV?d00001 diff --git a/trees/contest_tn/smoke_rxx_rzz_34q20l_xz_timeout_stop.pkl b/trees/contest_tn/smoke_rxx_rzz_34q20l_xz_timeout_stop.pkl new file mode 100644 index 0000000000000000000000000000000000000000..dd1b7a6c00ab68bcd8228d8fffc276fd5ba0c9c0 GIT binary patch literal 452824 zcmeFab(mG<8~rV8#X?am>{jgV4lEqI8xc9&Dj;DOiXw{1F;G$L!tO$m=}}>N20O63 zu>Gy|e0co%eXsZL_x(q%YtLuzd#{;c)>(7ro;mw|_674?*JZ9QbNS!7<=*4w88K|Y zfZ^q%%i|X6KV-y!!2^f&TfhI1VFSwJdh9Y}@Q7jk`i~eiWbi=}mB*LY8ddiDbQ?5y z=*SVnwb!Lzd0dy{%a`bFe{CnEJ-u(26Vu*6?UmBrAnirkJ4t&dr@d3OH#qGL(caLs zcdGV=rM=B_a9>aVedb}{-fT1jQz*G{{;I_djBc*pZ5MU>_6-M=h%PV`!BHnqW527e~R~C zPWzSizY_l|?SCcySK9wd{I9hCmH1z2|10so(*9TCf2IAe#Q#eBUy1*f_P-MUEA4+J z{#V-nO8l?1|CRV(Y5yznzta9!;(w+6uf+dK`(KIwmG-|9|10f(CH`01|4RI?wEva( zUupj<@xRjkSK@!A{jbFTO8Z}l|CRQ?68|ghe9e>MJB+y83( zueSfy_+M@RtMR|u{#WCFwf(Qg|7!bRjsG?FzXtzn?0*gZ*Vz9W{I9Y9HTYj+|7-BS z#{Spfe~taG!T%cjUxWWO_P+-IYwUjw{@2+58vL)Z|26nuWB+ULzsCO8;D3$%ufhKs z`(K0qHTJ&-|7+}j4gS~I{~G+SvHvyrUt|Ak@W00X*WiDR{jb6Q8v9>^|26i%2LEg9 ze+~ZE*#8>*ud)9%_+MlHYw*9u{@37tjs35|{~G&Wga5VmzZU;%?SC!)*V_MD{I9kD zwfJ9a|7-ET*8bPxf35wm#s6CSUyJ{>_P-YYYwdq6{@2?7TKuoI|F!sEYyWHUzt;ZO z;(x9Euf_jb`(KOywf4Uj|7-1kE&kWq|62U7wg0vFUu*ws@xRvo*W!Pz{jbIUTKiv% z|F!nN7XNGQe=Yvk+W%VoueJZR_+M-PYw^F<{@3Dvt^KdX|62QBi~n`@zYhQF?0+5p z*V+F%{I9eBb@*Rr|LgF-&i>cof1UlW!~Z(_Ux)v7_P-AQ>+F9W{@2<6I{dG*|8@9Z zXaDQ)zs~;G;eVa|ufzX3`(KCub@smw|Lg339sbwZ|2q7yv;TGYUuXa8@W0Of*WrJi z{jbCSI{ROT|8@4i4*%=ye;xkU+5bBHue1Mk_+MxL>+rwM{@3Auo&B%F|2q3$hyV5V zzaIbV?SDP~*W3Sk{I9qF_4r?J|LgI;-u~C)f4%*$$Nzf!UyuLw_P-wg>+OF%{@2_8 zdi<}q|MmD^Z~yD@zux}W+!$d{@3Gwz5TDp z|9bmhkN*w!zXAUn?0*CPH`xCM{BN-T4fx++{~PeX!TvYke}nyR!2bsO-+=!O_P+uD z8|;4r{x{hF2K;ZZ{|)%xVE-HNzrp@D;D3YtZ@~Ws``>U|xitS6?@TJk=whz9N(-f< z+g-Y&TFB9)-0O3zq$59`4bPNIE2pDp%Q4yKR!>LI`P}p6(rW4Gg>pRRbG_4%ALE9X z%B3~a(UfvL?Q`p-qnCB=wF}CnwSDy3sB*mEbL*!gKklzxR4%QTjz*W`6`$KE9bN2m zmy}BzrlT?CsPef@(~-0A+SqbwlXP@hIqH3Gi*$6k&y6dWHcv-alw-QjZ9PVhnoe9< zE^U`iTvaYDRN7Y6?$Kt!j;VTexwJ@W2UUASr>nc9>NVxkVx^r`?HO;mx?8GVTP`hG z>Z9rs@vf_Trt0`|Y3b4)s`iQxT-`fW%jME?rM{{z8?#*9H&w4ImsTw8qv{IrsjCO1 z>h zYsZhS9+Rp!l}qcFj#hQOnC)u6RK2-e+NgA#svE{{uAY#px0Fkpminu@N&M;Rz*L=B zE^SddQPs_3uDMl>RK2xa+PXAI4^WGh3zSYtRehIiS2|hRZKIpDLsNB9xwK}8?rBSNxAIrLWajM>1E*)GNt?EIsf~%LN zs=hA|D~(b0&{)~k%Tx9Ka_Pv@WvU(#tGRk*syk

3UU9j167ADOL479;FGY4vI}&ov7WdqVVo5 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

{dT=9{0B#1ifLpftSH6;8idURDo(x3+g}v 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