# Get PennyLane wire ordering and state-vector conventions right
Use this when a prepared state, `qml.state()` output, or `qml.probs()` result
does not match the bitstring you expected, or when PennyLane numbers disagree
with Qiskit (or another framework) on the same circuit. Nearly all of these are
convention mismatches, not bugs — check the convention before rewriting the
circuit.
## 1. The convention: wire 0 is the most significant bit
PennyLane uses |q0, q1, ..., qN-1> with q0 as the most significant bit
(documented in the device API). Consequences:
- `qml.BasisState([1, 0], wires=[0, 1])` puts the amplitude-1 entry at index 2
of the state vector (binary `10`, wire 0 read first) — not index 1.
- `qml.probs(wires=[0, 1, 2, 3])` returns a 16-element vector where index `i`
holds the probability of the bitstring equal to the binary representation of
`i` (wire 0 = MSB).
- `qml.probs(wires=0)` returns the *marginal* distribution of wire 0 alone
(other wires traced out).
Verify with a known state before trusting a large circuit:
```python
import pennylane as qml
dev = qml.device("default.qubit", wires=2)
def prep():
qml.BasisState([1, 0], wires=[0, 1])
return qml.state()
prep_qnode = qml.QNode(prep, dev)
print(prep_qnode()) # expect [0, 0, 1, 0]: amplitude at index 2 = binary 10
```
If this prints what you expect, the convention is understood; the bug is
elsewhere in your circuit.
## 2. Classify the mismatch
- **Comparing against Qiskit**: Qiskit numbers qubits little-endian (qubit 0 =
least significant bit) — the opposite convention. Convert a Qiskit
statevector to PennyLane ordering with:
```python
pl_state = qiskit_state.reshape([2] * n_qubits).T.flatten()
```
(PennyLane team answer on the forum.) If you convert the wrong direction,
everything looks bit-reversed.
- **Controlled gates**: in `qml.CNOT(wires=[0, 1])` the FIRST wire is the
control (wire 0) and the second is the target (wire 1). Swapping the list
order changes which qubit controls the gate — check every multi-qubit gate's
wire list.
- **Marginal vs joint probabilities**: `qml.probs(wires=[0])` is the marginal
for wire 0; `qml.probs(wires=[0, 1])` is the joint distribution. A Bell pair
measures `[0.5, 0.5]` marginally but `[0.5, 0, 0, 0.5]` jointly — mixing these
up is a classic "wrong answer".
- **Drawing order**: `qml.draw` lists wires in device wire order; pass
`wire_order=[...]` to pin it. A "Wires in circuit are inconsistent with
those in wire_order" error means your `wire_order` list does not match the
circuit's wires — fix the list, not the circuit.
## 3. Wire labels are not necessarily integers
Wires can be any unique labels: `qml.device("default.qubit", wires=["a", "b"])`
is valid, and ops take `wires="a"`. The device wire count must cover every wire
the circuit uses. Composite ops that build internal wire lists (e.g.
`qml.QSVT`) can produce wire orders that surprise device checks — print
`op.wires` and compare against the circuit's wires when a wire-consistency
error appears.
## 4. Checklist
1. Write down the expected index/bitstring for a 2-qubit basis state first;
run the verify snippet in step 1.
2. If comparing frameworks, confirm each framework's endianness and convert
once, explicitly, in the right direction.
3. Check control/target order in every multi-qubit gate's wire list.
4. Check marginal vs joint in every `qml.probs` call.
5. Pin `wire_order` in `qml.draw` when sharing or comparing circuit diagrams.