Skip to content

Commit 2d75238

Browse files
committed
Fix sign error in cirq.ZPowGate lowering (#373)
I just spent about 2 hours looking for that... Btw, this fix is already in #369, so if we merge it first, we can close this PR.
1 parent 63ac29d commit 2d75238

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

src/bloqade/squin/cirq/lowering.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ def visit_ZPowGate(self, state: lowering.State[CirqNode], node: cirq.ZPowGate):
281281
return state.current_frame.push(op.stmts.Z())
282282

283283
# NOTE: just for the Z gate, an arbitrary exponent is equivalent to the ShiftOp
284-
t = node.exponent
284+
# up to a minus sign!
285+
t = -node.exponent
285286
theta = state.current_frame.push(py.Constant(math.pi * t))
286287
return state.current_frame.push(op.stmts.ShiftOp(theta=theta.result))
287288

test/squin/cirq/test_cirq_to_squin.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,3 +291,60 @@ def test_multiple_classical_controls(run_sim: bool = False):
291291

292292
kernel = squin.cirq.load_circuit(circuit)
293293
kernel.print()
294+
295+
296+
def test_ghz_simulation():
297+
q = cirq.LineQubit.range(2)
298+
299+
# NOTE: uses native gateset
300+
circuit = cirq.Circuit(
301+
cirq.PhasedXZGate(x_exponent=0.5, z_exponent=0.0, axis_phase_exponent=0.5).on(
302+
q[0]
303+
),
304+
cirq.PhasedXZGate(x_exponent=0.5, z_exponent=0.0, axis_phase_exponent=0.5).on(
305+
q[1]
306+
),
307+
cirq.CZ(*q),
308+
cirq.PhasedXZGate(x_exponent=1.0, z_exponent=0.0, axis_phase_exponent=0.5).on(
309+
q[0]
310+
),
311+
cirq.PhasedXZGate(x_exponent=0.5, z_exponent=1.0, axis_phase_exponent=0.5).on(
312+
q[1]
313+
),
314+
)
315+
316+
print(circuit)
317+
318+
# manually written kernel
319+
@squin.kernel
320+
def manual():
321+
q = squin.qubit.new(2)
322+
s = squin.op.s()
323+
s_adj = squin.op.adjoint(s)
324+
squin.qubit.broadcast(s_adj, q)
325+
x = squin.op.x()
326+
xrot = squin.op.rot(x, math.pi / 2)
327+
squin.qubit.broadcast(xrot, q)
328+
squin.qubit.broadcast(s, q)
329+
cz = squin.op.cz()
330+
squin.qubit.apply(cz, q)
331+
squin.qubit.broadcast(s_adj, q)
332+
squin.qubit.apply(x, q[0])
333+
squin.qubit.apply(xrot, q[1])
334+
squin.qubit.broadcast(s, q)
335+
z = squin.op.z()
336+
squin.qubit.apply(z, q[1])
337+
338+
# lower from circuit
339+
kernel = squin.cirq.load_circuit(circuit)
340+
cirq_sim = cirq.Simulator().simulate(circuit)
341+
342+
sim = DynamicMemorySimulator()
343+
ket_manual = sim.state_vector(manual)
344+
345+
ket_kernel = sim.state_vector(kernel)
346+
347+
for ket in (ket_manual, ket_kernel, cirq_sim.final_state_vector):
348+
assert ket[1] == ket[2] == 0
349+
assert math.isclose(abs(ket[0]) ** 2, 0.5, abs_tol=1e-5)
350+
assert math.isclose(abs(ket[3]) ** 2, 0.5, abs_tol=1e-5)

0 commit comments

Comments
 (0)