Skip to content

Commit c94f282

Browse files
committed
add tests
1 parent a4aca8a commit c94f282

File tree

8 files changed

+157
-98
lines changed

8 files changed

+157
-98
lines changed

src/bloqade/noise/fidelity.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from kirin import interp
22
from kirin.lattice import EmptyLattice
33

4+
from bloqade.analysis.address import AddressQubit, AddressTuple
45
from bloqade.analysis.fidelity import FidelityAnalysis
56

6-
from .native import dialect
7+
from .native import dialect
78
from .native.stmts import PauliChannel, CZPauliChannel, AtomLossChannel
8-
from bloqade.analysis.address import AddressQubit, AddressTuple
99

1010

1111
@dialect.register(key="circuit.fidelity")

src/bloqade/noise/native/_wrappers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def pauli_channel(
3535
@wraps(native.CZPauliChannel)
3636
def cz_pauli_channel(
3737
ctrls: ilist.IList[Qubit, Any] | list,
38-
qarg2: ilist.IList[Qubit, Any] | list,
38+
qargs: ilist.IList[Qubit, Any] | list,
3939
*,
4040
px_ctrl: float,
4141
py_ctrl: float,

src/bloqade/qasm2/dialects/noise.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@ def emit_pauli(
3434
pz: ast.Number = frame.get(stmt.pz)
3535
qarg: ast.Bit | ast.Name = frame.get(stmt.qarg)
3636

37-
qarg_str = f"{qarg.name.id}[{qarg.addr}]" if isinstance(qarg, ast.Bit) else f"{qarg.id}"
38-
37+
qarg_str = (
38+
f"{qarg.name.id}[{qarg.addr}]"
39+
if isinstance(qarg, ast.Bit)
40+
else f"{qarg.id}"
41+
)
3942

4043
frame.body.append(
4144
ast.Comment(

src/bloqade/qasm2/emit/gate.py

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
from bloqade.types import QubitType
99
from bloqade.qasm2.parse import ast
1010

11-
from bloqade.noise import native
12-
1311
from .base import EmitError, EmitQASM2Base, EmitQASM2Frame
1412

1513

@@ -90,83 +88,3 @@ def emit_err(self, emit: EmitQASM2Gate, frame: EmitQASM2Frame, stmt):
9088
def ignore(self, emit: EmitQASM2Gate, frame: EmitQASM2Frame, stmt):
9189
return ()
9290

93-
94-
@native.dialect.register(key="emit.qasm2.gate")
95-
class NativeNoise(interp.MethodTable):
96-
97-
def _convert(self, node: ast.Bit | ast.Name) -> str:
98-
if isinstance(node, ast.Bit):
99-
return f"{node.name.id}[{node.addr}]"
100-
else:
101-
return f"{node.id}"
102-
103-
@interp.impl(native.CZPauliChannel)
104-
def emit_czp(
105-
self,
106-
emit: EmitQASM2Gate,
107-
frame: EmitQASM2Frame,
108-
stmt: native.CZPauliChannel,
109-
):
110-
paired: bool = stmt.paired
111-
px_ctrl: float = stmt.px_ctrl
112-
py_ctrl: float = stmt.py_ctrl
113-
pz_ctrl: float = stmt.pz_ctrl
114-
px_qarg: float = stmt.pz_qarg
115-
py_qarg: float = stmt.py_qarg
116-
pz_qarg: float = stmt.pz_qarg
117-
ctrls: ilist.IList[ast.Bit, Any] = frame.get(stmt.ctrls)
118-
qargs: ilist.IList[ast.Bit, Any] = frame.get(stmt.qargs)
119-
frame.body.append(
120-
ast.Comment(
121-
text=f"native.CZPauliChannel(paired={paired}, p_ctrl[{px_ctrl}, {py_ctrl}, {pz_ctrl}], p_qarg[{px_qarg}, {py_qarg}, {pz_qarg}])"
122-
)
123-
)
124-
frame.body.append(
125-
ast.Comment(
126-
text=f" -: ctrls: {', '.join([self._convert(q) for q in ctrls])}"
127-
)
128-
)
129-
frame.body.append(
130-
ast.Comment(
131-
text=f" -: qargs: {', '.join([self._convert(q) for q in qargs])}"
132-
)
133-
)
134-
return ()
135-
136-
@interp.impl(native.AtomLossChannel)
137-
def emit_loss(
138-
self,
139-
emit: EmitQASM2Gate,
140-
frame: EmitQASM2Frame,
141-
stmt: native.AtomLossChannel,
142-
):
143-
prob: float = stmt.prob
144-
qargs: ilist.IList[ast.Bit, Any] = frame.get(stmt.qargs)
145-
frame.body.append(ast.Comment(text=f"native.Atomloss(p={prob})"))
146-
frame.body.append(
147-
ast.Comment(
148-
text=f" -: qargs: {', '.join([self._convert(q) for q in qargs])}"
149-
)
150-
)
151-
return ()
152-
153-
@interp.impl(native.PauliChannel)
154-
def emit_pauli(
155-
self,
156-
emit: EmitQASM2Gate,
157-
frame: EmitQASM2Frame,
158-
stmt: native.PauliChannel,
159-
):
160-
px: float = stmt.px
161-
py: float = stmt.py
162-
pz: float = stmt.pz
163-
qargs: ilist.IList[ast.Bit, Any] = frame.get(stmt.qargs)
164-
frame.body.append(
165-
ast.Comment(text=f"native.Atomloss(px={px}, py={py}, pz={pz})")
166-
)
167-
frame.body.append(
168-
ast.Comment(
169-
text=f" -: qargs: {', '.join([self._convert(q) for q in qargs])}"
170-
)
171-
)
172-
return ()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import noise_native as noise_native
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
2+
from typing import Any
3+
from kirin import interp
4+
from kirin.dialects import ilist
5+
from bloqade.noise import native
6+
from bloqade.qasm2.parse import ast
7+
from bloqade.qasm2.emit.gate import EmitQASM2Gate, EmitQASM2Frame
8+
9+
@native.dialect.register(key="emit.qasm2.gate")
10+
class NativeNoise(interp.MethodTable):
11+
12+
def _convert(self, node: ast.Bit | ast.Name) -> str:
13+
if isinstance(node, ast.Bit):
14+
return f"{node.name.id}[{node.addr}]"
15+
else:
16+
return f"{node.id}"
17+
18+
@interp.impl(native.CZPauliChannel)
19+
def emit_czp(
20+
self,
21+
emit: EmitQASM2Gate,
22+
frame: EmitQASM2Frame,
23+
stmt: native.CZPauliChannel,
24+
):
25+
paired: bool = stmt.paired
26+
px_ctrl: float = stmt.px_ctrl
27+
py_ctrl: float = stmt.py_ctrl
28+
pz_ctrl: float = stmt.pz_ctrl
29+
px_qarg: float = stmt.pz_qarg
30+
py_qarg: float = stmt.py_qarg
31+
pz_qarg: float = stmt.pz_qarg
32+
ctrls: ilist.IList[ast.Bit, Any] = frame.get(stmt.ctrls)
33+
qargs: ilist.IList[ast.Bit, Any] = frame.get(stmt.qargs)
34+
frame.body.append(
35+
ast.Comment(
36+
text=f"native.CZPauliChannel(paired={paired}, p_ctrl=[x:{px_ctrl}, y:{py_ctrl}, z:{pz_ctrl}], p_qarg[x:{px_qarg}, y:{py_qarg}, z:{pz_qarg}])"
37+
)
38+
)
39+
frame.body.append(
40+
ast.Comment(
41+
text=f" -: ctrls: {', '.join([self._convert(q) for q in ctrls])}"
42+
)
43+
)
44+
frame.body.append(
45+
ast.Comment(
46+
text=f" -: qargs: {', '.join([self._convert(q) for q in qargs])}"
47+
)
48+
)
49+
return ()
50+
51+
@interp.impl(native.AtomLossChannel)
52+
def emit_loss(
53+
self,
54+
emit: EmitQASM2Gate,
55+
frame: EmitQASM2Frame,
56+
stmt: native.AtomLossChannel,
57+
):
58+
prob: float = stmt.prob
59+
qargs: ilist.IList[ast.Bit, Any] = frame.get(stmt.qargs)
60+
frame.body.append(ast.Comment(text=f"native.Atomloss(p={prob})"))
61+
frame.body.append(
62+
ast.Comment(
63+
text=f" -: qargs: {', '.join([self._convert(q) for q in qargs])}"
64+
)
65+
)
66+
return ()
67+
68+
@interp.impl(native.PauliChannel)
69+
def emit_pauli(
70+
self,
71+
emit: EmitQASM2Gate,
72+
frame: EmitQASM2Frame,
73+
stmt: native.PauliChannel,
74+
):
75+
px: float = stmt.px
76+
py: float = stmt.py
77+
pz: float = stmt.pz
78+
qargs: ilist.IList[ast.Bit, Any] = frame.get(stmt.qargs)
79+
frame.body.append(
80+
ast.Comment(text=f"native.PauliChannel(px={px}, py={py}, pz={pz})")
81+
)
82+
frame.body.append(
83+
ast.Comment(
84+
text=f" -: qargs: {', '.join([self._convert(q) for q in qargs])}"
85+
)
86+
)
87+
return ()

src/bloqade/qasm2/emit/target.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
from .gate import EmitQASM2Gate
1515
from .main import EmitQASM2Main
16+
from . import impls as impls # register the tables
1617

1718

1819
class QASM2:

test/qasm2/emit/test_extended_noise.py

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,69 @@
11
from bloqade import noise, qasm2
22

33

4-
@qasm2.extended
5-
def main():
6-
qreg = qasm2.qreg(4)
4+
def test_pauli_ch():
75

8-
qasm2.cx(qreg[0], qreg[1])
9-
qasm2.u(qreg[2], theta=0.1, phi=0.2, lam=0.3)
6+
@qasm2.extended
7+
def main():
8+
qreg = qasm2.qreg(4)
109

11-
noise.native.pauli_channel(qargs=[qreg[0], qreg[1]], px=0.1, py=0.2, pz=0.3)
10+
qasm2.cx(qreg[0], qreg[1])
11+
qasm2.u(qreg[2], theta=0.1, phi=0.2, lam=0.3)
1212

13-
qasm2.u(qreg[2], theta=0.1, phi=0.2, lam=0.3)
13+
noise.native.pauli_channel(qargs=[qreg[0], qreg[1]], px=0.1, py=0.2, pz=0.3)
1414

15+
qasm2.u(qreg[2], theta=0.1, phi=0.2, lam=0.3)
16+
17+
18+
main.print()
19+
20+
target = qasm2.emit.QASM2(allow_noise=True)
21+
out = target.emit_str(main)
22+
23+
expected = """OPENQASM 2.0;
24+
include "qelib1.inc";
25+
qreg qreg[4];
26+
CX qreg[0], qreg[1];
27+
U(0.1, 0.2, 0.3) qreg[2];
28+
// native.PauliChannel(px=0.1, py=0.2, pz=0.3)
29+
// -: qargs: qreg[0], qreg[1]
30+
U(0.1, 0.2, 0.3) qreg[2];
31+
"""
32+
33+
assert out == expected
34+
35+
36+
def test_pauli_ch_para():
37+
38+
@qasm2.extended
39+
def main():
40+
qreg = qasm2.qreg(4)
41+
42+
qasm2.cx(qreg[0], qreg[1])
43+
qasm2.parallel.u([qreg[2],qreg[3]], theta=0.1, phi=0.2, lam=0.3)
44+
45+
noise.native.pauli_channel(qargs=[qreg[0], qreg[1]], px=0.1, py=0.2, pz=0.3)
46+
47+
qasm2.u(qreg[2], theta=0.1, phi=0.2, lam=0.3)
48+
49+
50+
main.print()
51+
52+
target = qasm2.emit.QASM2(allow_noise=True, allow_parallel=True)
53+
out = target.emit_str(main)
54+
expected = """KIRIN {func,lowering.call,lowering.func,native,py.ilist,qasm2.core,qasm2.expr,qasm2.indexing,qasm2.parallel,qasm2.uop,scf};
55+
include "qelib1.inc";
56+
qreg qreg[4];
57+
CX qreg[0], qreg[1];
58+
parallel.U(0.1, 0.2, 0.3) {
59+
qreg[2];
60+
qreg[3];
61+
}
62+
// native.PauliChannel(px=0.1, py=0.2, pz=0.3)
63+
// -: qargs: qreg[0], qreg[1]
64+
U(0.1, 0.2, 0.3) qreg[2];
65+
"""
66+
67+
assert out == expected
1568

16-
main.print()
1769

18-
target = qasm2.emit.QASM2(allow_noise=True)
19-
ast = target.emit(main)
20-
qasm2.parse.pprint(ast)

0 commit comments

Comments
 (0)