Phase-Gradient Rotations¶
The phase_gradient gallery entry composes signed single-qubit rotations from
T-resource injection stages. It shows how a small family of reusable modules
can form a longer adaptive computation. Start with modules and
T Block.
Note
The gallery’s k=4 label names a fixed single-qubit rotation construction. It
does not describe a four-qubit phase-gradient register or expose a general
rotation-synthesis API. Its source contains 22 signed \(\pi/4\) rotations,
followed by a Hadamard.
What the source implements¶
Let \(R_P(\theta)=\exp(-i\theta P/2)\). In time order, each row below applies \(R_X(a\pi/4)\) followed by \(R_Z(b\pi/4)\):
Pair |
\(a\) |
\(b\) |
|---|---|---|
0 |
+1 |
+1 |
1 |
+1 |
+1 |
2 |
−1 |
−1 |
3 |
−1 |
−1 |
4 |
−1 |
+1 |
5 |
−1 |
−1 |
6 |
+1 |
−1 |
7 |
−1 |
+1 |
8 |
−1 |
+1 |
9 |
+1 |
−1 |
10 |
+1 |
+1 |
A final \(H\) completes the map. This is the exact gate sequence checked by Bloq’s independent logical-map test, up to global phase. The example does not attach an approximation-error bound to a different target rotation.
Four reusable definitions cover the two axes and rotation signs:
Definition |
Logical role |
Transverse resource arm |
|---|---|---|
|
\(R_X(+\pi/4)\) |
Local |
|
\(R_X(-\pi/4)\) |
Local |
|
\(R_Z(+\pi/4)\) |
Local |
|
\(R_Z(-\pi/4)\) |
Local |
Each definition has temporal q_in / q_out data ports and one T source. Here
is the positive X rotation:
module RxPlusAtYPlus {
in q_in: data = 0
out q_out: data = 2
0: Port [0, 0, 0] role=input <q_in>
1: XZX [0, 0, 1]
2: Port [0, 0, 2] role=output <q_out>
3: T [0, 1, 0]
4: XZZ [0, 1, 1]
5: ZY [0, 1, 2]
0 -> +Z
1 -> +Z
1 -> +Y
3 -H> +Z
4 -> +Z
m = measure 1 -> +Y
resolve 5 if !m
feedback X 1 if m
}
m is a named merge readout. resolve chooses the ordered measurement basis,
and feedback applies the declared correction. The positive and negative
definitions differ in their selective cap and, for X rotations, their feedback
condition. Substituting one for the other changes the signed operation.
Place the instances¶
The root alternates resource arms around the data wire: +Y, +X, −Y, −X.
A Z half-turn moves a definition’s arm to the opposite side while keeping its
time direction. This allows nearby instances without overlapping their arms.
s00: RxPlusAtYPlus @ [0, 0, 0]
s01: RzPlusAtXPlus @ [0, 0, 1]
s02: RxPlusAtYPlus @ [0, 0, 2] rotate Z 180
s03: RzPlusAtXPlus @ [0, 0, 3] rotate Z 180
s04: RxMinusAtYPlus @ [0, 0, 4]
s05: RzMinusAtXPlus @ [0, 0, 5]
s06: RxMinusAtYPlus @ [0, 0, 6] rotate Z 180
s07: RzMinusAtXPlus @ [0, 0, 7] rotate Z 180
flowchart LR q["q_in"] --> rx0["s00: +Rx"] --> rz0["s01: +Rz"] rz0 --> rx1["s02: +Rx, rotate Z 180"] --> rz1["s03: +Rz, rotate Z 180"] rz1 --> rest["s04 … s21"] --> h["Hadamard seam"] --> output["q_out"]
All 22 stages connect explicitly. The last stage uses a Hadamard pipe into a parent-owned cube, followed by the output Port:
s20.q_out -> s21.q_in
s21.q_out -H> 1
1 -> 2
The full hierarchy has five definitions, including main. It contains 21
direct child-to-child seams. The final Hadamard is a connection; there is no
extra FinalHadamard module.
Load and compile¶
Compile at distance three with ordinary T cultivation, then save text Bloq IR:
from pathlib import Path
import bloq
example = bloq.GalleryItem.PHASE_GRADIENT
Path("phase-gradient.blog").write_text(example.source(), encoding="utf-8")
graph = example.load()
flat = graph.flatten()
assert flat.t_count == 22
assert flat.selective_count == 22
program = bloq.compile(graph, distance=3)
program.validate()
program.save("phase-gradient.bloqir")
use bloq::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let source = GalleryItem::PhaseGradientK4.build();
assert_eq!(source.modules().count(), 5);
assert_eq!(source.instances.len(), 22);
std::fs::write("phase-gradient.blog", source.to_blog_text())?;
let program = compile(&source, 3)?;
program.validate()?;
std::fs::write("phase-gradient.bloqir", program.to_text())?;
Ok(())
}
The named readouts remain output-safe after composition; the compiler derives terminal corrections from the same signed relation.
CLI:
bloq compile --gallery phase_gradient -d 3 --backend ir-text -o phase-gradient.bloqir
bloq validate phase-gradient.bloqir
Download the full BLOG source to modify placements or open it
in the editor.
Verification and proxies¶
The result retains T-source retries, selected measurements, and feed-forward. Use the verification VM to simulate those dependencies. The T states here come from the compiled cultivation regions. They are not assumed to arrive through external prepared-state ports.
For a Clifford distance-analysis circuit, the CLI supports a reproducible proxy:
bloq compile --gallery phase_gradient -d 3 --clifford-proxy --proxy-seed 7 -o phase-gradient-proxy.stim
Important
A Clifford proxy replaces T resources with ideal ports and jointly selects a reachable measurement path. It is a distance-analysis stand-in, not an execution of the rotation channel or a measurement of its logical error rate.