mps-sim-gpu 1.0.1
GPU-accelerated MPS quantum circuit simulator (CUDA / Apple MPS / CPU)
License: MIT
Requires Python: >=3.9
Keywords: quantum computing MPS tensor network GPU CUDA simulation

# mps_sim_gpu

GPU-accelerated Matrix Product State (MPS) quantum circuit simulator.

A drop-in extension of `mps_sim` that transparently accelerates the two
hottest operations — **SVD truncation** and **tensor contraction** (einsum)
— using whichever GPU backend is available on your machine.

---

## Supported backends

| Backend | Hardware | Library |
|---------|----------|---------|
| `cuda`  | NVIDIA GPU | CuPy *(preferred)* or PyTorch |
| `mps`   | Apple Silicon (M1/M2/M3…) | PyTorch |
| `cpu`   | Any CPU | NumPy (original behaviour) |

Backend is **auto-detected** at runtime — no code changes needed when
moving between machines.

---

## Installation

```bash
# Base install (CPU fallback always available)
pip install mps_sim_gpu

# NVIDIA GPU support via CuPy (fastest on CUDA)
pip install "mps_sim_gpu[cuda]"

# Apple MPS or CUDA via PyTorch
pip install "mps_sim_gpu[torch]"
```

---

## Quick start

```python
from mps_gpu import GPUSimulator
from mps_sim.circuits import Circuit

# Build a 20-qubit GHZ circuit
circ = Circuit(20)
circ.h(0)
for i in range(19):
    circ.cx(i, i + 1)

# Run — backend auto-selected (CUDA > MPS > CPU)
sim = GPUSimulator(chi=64)
state = sim.run(circ)

print(state)
# GPUMPS(n=20, chi=64, backend=cuda, ...)

print(state.expectation_pauli_z(0))   # → ~0.0  (GHZ is Z-symmetric)
```

### Force a specific backend

```python
sim = GPUSimulator(chi=128, backend="cuda")   # NVIDIA GPU
sim = GPUSimulator(chi=128, backend="mps")    # Apple Silicon
sim = GPUSimulator(chi=128, backend="cpu")    # CPU / debug mode
```

---

## Benchmarking

```python
from mps_gpu import benchmark

results = benchmark(n_qubits=20, chi=64, depth=40)
# ============================================================
#   MPS GPU Benchmark
#   n=20 qubits | chi=64 | depth≈40 | 3 runs
# ============================================================
#   cpu       4.821s ± 0.031s
#   cuda      0.182s ± 0.008s
#
#   Speedups vs CPU:
#     cuda: 26.5×
# ============================================================
```

Typical speedups (random brickwork circuit, chi=64):

| Hardware | Speedup vs CPU |
|----------|---------------|
| NVIDIA A100 | 30–60× |
| NVIDIA RTX 4090 | 20–40× |
| Apple M2 Pro | 4–10× |
| Apple M1 | 2–6× |

Speedup scales with bond dimension χ — larger χ means more benefit.

---

## Architecture

```
mps_gpu/
├── __init__.py       — public API
├── backend.py        — detects CuPy / PyTorch-MPS / PyTorch-CUDA / NumPy
├── mps.py            — GPUMPS: backend-dispatched tensor ops
├── simulator.py      — GPUSimulator: circuit runner
└── benchmark.py      — CPU vs GPU timing comparison
```

### How it works

All MPS tensor operations flow through a **backend object** that exposes
a NumPy-compatible API (`einsum`, `svd`, `qr`, …).  The three hot-paths
that benefit most from GPU acceleration are:

1. **SVD** (`apply_svd_truncation`) — called once per two-qubit gate.
   Dominates runtime for large χ.  CuPy `cupy.linalg.svd` uses cuSolver
   under the hood and is typically 20–50× faster than NumPy for χ ≥ 64.

2. **Two-site einsum** (`'lir,rjs->lijs'`, `'abij,lijs->labs'`) — GPU
   einsum via CuPy or `torch.einsum`.

3. **QR** (`canonicalize`) — called during expectation-value evaluation.
   GPU QR gives 5–15× speedup for large χ.

Tensors live in host (CPU) memory between gate applications and are
**transferred to device only for the duration of each heavy op**.  This
keeps the memory model simple and avoids issues with Python's GC on device
arrays.  For workloads with very large χ (≥ 512), enabling `pin_tensors=True`
keeps tensors device-resident and reduces transfer overhead further
(requires CuPy).

---

## Compatibility

`GPUMPS` and `GPUSimulator` expose the same public API as the original
`MPS` and `MPSSimulator` from `mps_sim`, so they can be used as drop-in
replacements.  The `mps_sim.extrapolation` module works unchanged with
`GPUSimulator`.

---

## Requirements

- Python ≥ 3.9
- `mps_sim >= 1.0.0`
- `numpy >= 1.22`
- For CUDA: `cupy-cuda11x` or `cupy-cuda12x` (match your CUDA version)
- For Apple MPS / CUDA via PyTorch: `torch >= 2.0`