# QRAM data structures: pointers, offsets, and random writes
**English** · 简体中文
{obj}`QMem ` abstracts QRAM resources into C-style array access: base addresses, constant and quantum offsets, multidimensional views, and random reads and writes. All of the addressing is Python generation-stage sugar — what lands in the RIR is only register arithmetic, {obj}`Load `, and {obj}`Store ` (see [the RIR specification](../reference/rir.md), section 3.2). The API is documented in [QRAM pointer-style reads and writes](../api/infrastructure/qmem.rst).
## Pointers and reads
{obj}`QMem ` binds a QRAM resource already declared in the builder. `ptr()` returns a pointer to cell 0; integer addition and subtraction produce constant offsets; passing a register view yields a pointer holding a quantum address. Dereferencing with `load` is the existing XOR-Load: `|addr⟩|d⟩ ↦ |addr⟩|d ⊕ M[addr]⟩`, with superposed addresses supported for free.
```{doctest}
>>> from oracq import Builder, QRAM, QMem, UInt, simulate
>>> b = Builder("demo", {"idx": UInt(2), "out": UInt(4)}, {"rom": QRAM(2, 4)})
>>> mem = QMem(b, "rom")
>>> (mem.ptr() + 1).load(b["out"])
>>> state = simulate(b.finish().program(), {"rom": [10, 11, 12, 13]})
>>> sorted(state.amplitudes.items())
[((0, 11), (1+0j))]
```
Quantum offsets (`p + b["idx"]`) and multidimensional flattening require register addition: `QMem` automatically synthesizes bit-by-bit carry adders and shift-concatenation; the temporary address registers are cleaned by a whole-block Adjoint after dereferencing, keeping the module unitary. The gate cost of address arithmetic is counted faithfully in [resource estimation](resource-estimation.md). When the address expression is exactly a single full-width register with no constant component, no addressing arithmetic is introduced.
## Multidimensional views
`shape` declares row-major flattening; subscripts may be integers, register views, or slices, and the width of a quantum subscript must satisfy 2^width not exceeding that dimension's length. A slice returns a re-addressed subarray view.
```{doctest}
>>> b = Builder("grid", {"row": UInt(2), "out": UInt(4)}, {"rom": QRAM(4, 4)})
>>> grid = QMem(b, "rom", shape=(4, 4))
>>> grid[b["row"], 2].load(b["out"])
>>> state = simulate(b.finish().program(), {"rom": list(range(16))}, initial={"row": 3})
>>> sorted(state.amplitudes.items())
[((3, 14), (1+0j))]
```
## Random writes
`store` is the RIR `Store` instruction: `M[addr] := data`. Memory cells are modeled classically and random writes carry no gate cost (counted separately as `qram_writes` in resource estimation). At execution the address and data registers must be in a definite basis state; a write under a superposed address has no linear semantics and the executor raises immediately. Structurally, `Store` cannot appear inside a {obj}`Control ` or {obj}`Adjoint ` body, and modules containing `Store` have neither the controlled nor the adjoint capability.
```{doctest}
>>> b = Builder("write", {"addr": UInt(2), "val": UInt(4), "out": UInt(4)}, {"ram": QRAM(2, 4)})
>>> mem = QMem(b, "ram")
>>> mem[b["addr"]].store(b["val"])
>>> mem.ptr(3).load(b["out"])
>>> state = simulate(b.finish().program(), {"ram": [0, 0, 0, 0]}, initial={"addr": 1, "val": 9})
>>> sorted(state.amplitudes.items())
[((1, 9, 0), (1+0j))]
```
A subsequent `Load` reads the evolved memory: in the example above cell 1 now holds 9 while cell 3 is still 0. The [OriginIR-ext](backends.md#originir-ext) export lowers `Store` to the `QRAMWRITE` extension line; the text executors (UnifiedQuantum, PySparQ) do not yet accept runtime writes and raise at the execution entry when a program contains `Store`; text export is unaffected.
## Capability overview
| Capability | Form | Lowering result |
|---|---|---|
| Constant offset | `mem.ptr(2) + 3`, `p - 1` | `add_const` (modulo 2^address width) |
| Quantum pointer | `mem.ptr(b["addr"])` | direct addressing or shift-concatenation |
| Quantum offset | `p + b["idx"]` | when overlapping the pointer range, a carry adder is synthesized (Toffoli/CNOT) |
| Multidimensional indexing | `grid[b["row"], 3]` | shift-concatenation; no adder needed when the dimensions occupy disjoint bit segments |
| Subarray view | `grid[2:]` | constant re-addressing, no instructions |
The full semantic tests are in `tests/core/test_qmem.py`.