### wai-quantum 0.6.12: cheaper contraction trees, and the cut-rank table on the GPU

0.6.11 was not published on its own: this release carries it to the package registry, and `wai-quantum-cli` 0.1.0 requires it, since the command line's `metal` feature turns on `quantum_cutrank_metal`.

One pinned digest changes, by design: the tensor-network plan in `tests/bit_identity.rs`, because the search now finds a cheaper plan. The native and WASI builds compute the same new digest. Every other pin is unchanged.

- **Each bisection runs two V-cycles.** After the split is projected onto the full graph:
  - the graph is coarsened again, matching nodes only within a side, so the split carries to the coarse graph with the same cut;
  - the split is refined there and on the way back down, which never raises the cut.
- **The best few trees are annealed after reconfiguration** (`quantum_tn::anneal`):
  - random rotations at each node are accepted on the change in log total cost, at a falling temperature;
  - the cheapest tree seen is kept and reconfigured again;
  - a rotation changes the cost of two contractions only, so each move costs two set sizes.
- **On the 61-qubit Nighthawk logical circuits** (split and reduced, 1024 trials, 8 restarts, the median of 4 seeds). The figures are log10 complex multiply-adds for one amplitude:

  | depth | 0.6.11 | 0.6.12 |
  |---|---|---|
  | 8 | 5.30 | 5.29 |
  | 12 | 8.10 | 8.09 |
  | 16 | 11.12 | 10.97 |
  | 20 | 14.02 | 13.68 |

  The search takes about 1.7 times as long at depth 20.
- **`quantum_cutrank_metal`** (feature `quantum_cutrank_metal`, macOS) runs the cut-rank table on the platform's GPU:
  - one shared buffer of `2^cut` single-precision entries, at most `2³¹`;
  - one dispatch per pass of the walk, in its order and with its arithmetic, done in `f32`, so an amplitude is one command buffer;
  - a sample's sums reduced per threadgroup on the device and added on the host in `f64`, in order, with the outcome drawn as the host's walk draws it;
  - a batch of shots sampled side by side, each shot's table at its own offset and its weights in a small per-shot array, so a qubit is one command buffer for the whole batch;
  - each shot drawing from a stream of its own, so a seed's samples are the same at any batch size.

  It is reproducible on one device, and is checked against the double-precision walk on states of 10 to 34 qubits: amplitudes within `10⁻⁵` of each amplitude's size, and samples whose probabilities are their own and whose counts follow them.
- **The engine's `cutrank_single` method** runs a `cutrank` job on that table, where the build has the feature and the host has a GPU. `auto` never picks it.
  - Its amplitudes carry the circuit's global phase, which is found on the same table.
  - The job service, the command line's `metal` feature and the desktop app's `metal` feature build it in.
  - The service marks a `cutrank_single` job's energy figure partial, as it does `statevector_single`'s, because the counter does not read the GPU.
  - `examples/cutrank_gpu` times it against the host's tables.
- **Speed.** One amplitude of a random graph state on a shared desktop machine, each device timed at its quietest. Either side ran up to five times slower while other work held it.

  | widest cut | host, double | host, single | GPU |
  |---|---|---|---|
  | 23 bits | 0.027 s | 0.024 s | 0.005 s |
  | 25 bits | 0.057 s | 0.045 s | 0.019 s |
  | 27 bits | 0.18 s | 0.17 s | 0.046 s |
  | 29 bits | 1.03 s | 0.54 s | 0.34 s |

  A pass of the table runs at about 550 GB/s on an idle device.

  Sampling 64 shots of the same states, 16 a batch, with the host at about half its quietest speed:

  | widest cut | host, single | GPU, one at a time | GPU, 16 a batch |
  |---|---|---|---|
  | 16 bits | 0.52 s | 0.62 s | 0.036 s |
  | 20 bits | 1.97 s | 0.73 s | 0.067 s |
  | 23 bits | 3.87 s | 0.91 s | 0.34 s |
  | 25 bits | 7.48 s | 1.82 s | 1.20 s |

  The engine samples up to 32 shots a batch, as many as 2 GiB beside the job's first table holds.

