Skip to content

Commit 9e72ff3

Browse files
committed
Implement pyqrack interpreter method for glob.u gate
1 parent 5878705 commit 9e72ff3

File tree

2 files changed

+75
-1
lines changed

2 files changed

+75
-1
lines changed

src/bloqade/pyqrack/qasm2/core.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
from typing import Any
2+
13
from kirin import interp
4+
from kirin.dialects import ilist
25

36
from bloqade.pyqrack.reg import (
47
CBitRef,
@@ -9,7 +12,7 @@
912
PyQrackQubit,
1013
)
1114
from bloqade.pyqrack.base import PyQrackInterpreter
12-
from bloqade.qasm2.dialects import core
15+
from bloqade.qasm2.dialects import core, glob
1316

1417

1518
@core.dialect.register(key="pyqrack")
@@ -77,3 +80,18 @@ def creg_eq(
7780
return (False,)
7881

7982
return (all(left is right for left, right in zip(lhs, rhs)),)
83+
84+
@interp.impl(glob.UGate)
85+
def ugate(self, interp: PyQrackInterpreter, frame: interp.Frame, stmt: glob.UGate):
86+
registers: ilist.IList[PyQrackReg, Any] = frame.get(stmt.registers)
87+
theta, phi, lam = (
88+
frame.get(stmt.theta),
89+
frame.get(stmt.phi),
90+
frame.get(stmt.lam),
91+
)
92+
93+
for qreg in registers:
94+
for qarg in qreg:
95+
if qarg.is_active():
96+
interp.memory.sim_reg.u(qarg.addr, theta, phi, lam)
97+
return ()

test/pyqrack/test_target.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,59 @@ def ghz():
3838
assert math.isclose(out[0].real, val, abs_tol=abs_tol)
3939
assert math.isclose(out[-1].real, val, abs_tol=abs_tol)
4040
assert all(math.isclose(ele.real, 0.0, abs_tol=abs_tol) for ele in out[1:-1])
41+
42+
43+
def test_target_glob():
44+
@qasm2.extended
45+
def global_h():
46+
q = qasm2.qreg(3)
47+
48+
# rotate around Y by pi/2, i.e. perform a hadamard
49+
qasm2.glob.u(math.pi / 2.0, 0, 0, [q])
50+
51+
return q
52+
53+
target = PyQrack(3)
54+
q = target.run(global_h)
55+
56+
assert isinstance(q, reg.PyQrackReg)
57+
58+
out = q.sim_reg.out_ket()
59+
60+
# remove global phase introduced by pyqrack
61+
phase = out[0] / abs(out[0])
62+
out = [ele / phase for ele in out]
63+
64+
for element in out:
65+
assert math.isclose(element.real, 1 / math.sqrt(8), abs_tol=2.2e-7)
66+
assert math.isclose(element.imag, 0, abs_tol=2.2e-7)
67+
68+
@qasm2.extended
69+
def multiple_registers():
70+
q1 = qasm2.qreg(2)
71+
q2 = qasm2.qreg(2)
72+
q3 = qasm2.qreg(2)
73+
74+
# hadamard on first register
75+
qasm2.glob.u(math.pi / 2.0, 0, 0, [q1])
76+
77+
# apply hadamard to the other two
78+
qasm2.glob.u(math.pi / 2.0, 0, 0, [q2, q3])
79+
80+
# rotate all of them back down
81+
qasm2.glob.u(-math.pi / 2.0, 0, 0, [q1, q2, q3])
82+
83+
return q1
84+
85+
target = PyQrack(6)
86+
q1 = target.run(multiple_registers)
87+
88+
assert isinstance(q1, reg.PyQrackReg)
89+
90+
out = q1.sim_reg.out_ket()
91+
92+
assert out[0] == 1
93+
for i in range(1, len(out)):
94+
assert out[i] == 0
95+
96+
assert True

0 commit comments

Comments
 (0)