Skip to content

Qubit ordering

An MPS is a one-dimensional chain. Entanglement between neighbouring sites is cheap; entanglement between distant sites is expensive, because every bond in between has to carry it. A gate on qubits 0 and 40 forces a wide bond across everything separating them, and the cost is paid by every gate that follows.

Qubit numbering is a labelling, not physics. Relabelling so that interacting qubits sit near each other can lower the bond dimension a circuit needs, for the same answer. This is the one control that can make a run cheaper without making it less accurate.

Turning it on

Reordering is off by default. The layout you wrote is the layout that runs.

import tensorweaver as tw

results = tw.execute(circuit, nsamples=1000, reorderqubits=True)

True runs the whole portfolio of searches and keeps whichever result scores best. Naming one ("greedy", "sa" / "simulated_annealing", "multilevel") pins the search instead, which is mostly useful for comparing them: the result is scored the same way either way.

The same arguments work on TwSimulator:

sim = tw.TwSimulator(bonddim=64, reorderqubits=True)

How a layout is chosen

The searches minimise the total weighted distance between interacting qubits. That is a good thing to descend, and a poor thing to decide by: it has no bond dimension in it, so it cannot tell a layout that fits under your cap from one that does not, and on a ring it will happily fold the chain and double every cut.

So the search result is not the answer, it is a candidate. What decides is a different cost. For each bond k of the chain, with u_k two-qubit gate applications crossing it and h_k bits of entanglement those gates can create:

C = Σ_k  u_k · max(0, min(h_k, k, n−k) − log2(bonddim))

Over every bond: how many truncations happen there, times how many bits each one has to throw away. C = 0 means no bond ever exceeds bonddim, so the layout truncates nothing. Your own layout is always one of the candidates, and a search result has to beat it by reorderqubits_margin (default 2.0) before it is used. A layout that truncates nothing is used whatever the margin.

Two consequences worth knowing:

  • bonddim changes the answer. The same circuit can want different layouts at 64 and at 1024, because what matters is which bonds do not fit.
  • Gates are weighted by what they entangle, not by how many there are. A CP(π) is worth one bit, a CP(1e-9) none. A circuit carrying a cloud of negligible controlled phases used to drag the layout towards gates that do nothing.

What it decided, and why

Both outcomes are reported, so you never have to guess whether the pass helped:

sim = tw.TwSimulator(bonddim=256, reorderqubits=True)
sim.compile(circuit)
print(sim.last_layout_report)

The report carries the cost, the widest bond in bits, and the number of bonds over budget, each for the chosen layout and for the one you wrote, plus which search won. It is also logged at INFO on the tensorweaver.reorder logger:

import logging
logging.basicConfig(level=logging.INFO)

You get your own labelling back

The permutation is internal. Samples, amplitudes, and z-variables are all translated back to the qubit numbering you wrote, so nothing downstream has to know a reordering happened. A circuit run with and without reordering answers in the same frame.

When it helps

Reordering pays when the interaction graph has locality that the numbering hides:

  • long-range pairings, such as a circuit coupling qubit i with qubit n-1-i
  • a layout inherited from hardware whose numbering does not match its connectivity
  • a circuit generated from a graph problem, where the graph is local but the labelling is arbitrary

It cannot help when the interaction graph is genuinely all-to-all, because there is no layout in which every pair is close. It does nothing for a circuit that is already nearest-neighbour, because the identity permutation is already the best one. In both cases the searches run, score no better than your layout, and the circuit passes through unchanged.

The search is a compile step, so it costs preparation time: milliseconds on a hundred qubits, under a second on a thousand. Above a size threshold the portfolio runs fewer searches rather than slower ones, so it never costs more than a large multiple of a single search.

Deciding whether it is worth it

Measure it. The peak bond dimension is the number that moves:

import tensorweaver as tw

for reorder in (False, True):
    sim = tw.TwSimulator(bonddim=256, reorderqubits=reorder, seed=1)
    state, fidelity = sim.evolve(sim.zerostate(n), sim.compile(circuit))
    print(f"reorderqubits={reorder!s:>5}  "
          f"chi {state.mps.max_used_bond_dim:>4}  "
          f"fidelity {float(fidelity):.6f}")

Run it once at a bonddim large enough that neither configuration saturates, so you are comparing the width each layout genuinely needs rather than the ceiling. If the reordered run needs a much smaller bond dimension, it will be faster and more accurate at every bonddim below that; if the two are close, the layout was already reasonable and reordering is not where the cost is.

Example 07 in the bundled examples builds the canonical bad case and prints the peak bond dimension with and without reordering.

Bond observables pin the layout

Bond observables are the one thing not permuted. BondDim(), SchmidtRank() and VonNeumannEntropy() take a bond index, naming the bipartition {0..k-1} | {k..n-1}, not a qubit. A layout that moved a qubit across such a cut would change what the observable measures, so those cuts are kept intact and the index is left alone: the observable still reports the bipartition you asked for.

A circuit that profiles every bond is therefore fully pinned, and no reordering is available to it.

Reading the entropy profile

Where the entanglement sits is what tells you whether a different layout could help at all. The von Neumann entropy across each bond is the direct measurement: a profile with one tall peak in the middle usually means a few long-range couplings are responsible and a layout change may pay, while a broad, flat profile means the entanglement is spread across the whole chain and no relabelling will concentrate it.