File tree Expand file tree Collapse file tree 3 files changed +91
-2
lines changed
Expand file tree Collapse file tree 3 files changed +91
-2
lines changed Original file line number Diff line number Diff line change @@ -17,8 +17,8 @@ dependencies = [
1717 " rich>=13.9.4" ,
1818 " pydantic>=1.3.0,<2.11.0" ,
1919 " pandas>=2.2.3" ,
20- " pyqrack>=1.38.2 ; sys_platform == 'darwin'" ,
21- " pyqrack-cpu>=1.38.2 ; sys_platform != 'darwin'" ,
20+ " pyqrack>=1.38.2,<1.41 ; sys_platform == 'darwin'" ,
21+ " pyqrack-cpu>=1.38.2,<1.41 ; sys_platform != 'darwin'" ,
2222]
2323
2424[project .optional-dependencies ]
Original file line number Diff line number Diff line change 55from kirin .ir .dialect import Dialect as Dialect
66
77from bloqade .qasm2 .parse import ast
8+ from bloqade .qasm2 .dialects .uop import SingleQubitGate , TwoQubitCtrlGate
9+ from bloqade .qasm2 .dialects .expr import GateFunction
810
911from .base import EmitQASM2Base , EmitQASM2Frame
12+ from ..dialects .core .stmts import Reset , Measure
1013
1114
1215@dataclass
@@ -94,6 +97,24 @@ def emit_if_else(
9497
9598 cond = emit .assert_node (ast .Cmp , frame .get (stmt .cond ))
9699
100+ # NOTE: we need exactly one of those in the then body in order to emit valid QASM2
101+ AllowedThenType = SingleQubitGate | TwoQubitCtrlGate | Measure | Reset
102+
103+ then_stmts = stmt .then_body .blocks [0 ].stmts
104+ uop_stmts = 0
105+ for s in then_stmts :
106+ if isinstance (s , AllowedThenType ):
107+ uop_stmts += 1
108+ continue
109+
110+ if isinstance (s , func .Invoke ):
111+ uop_stmts += isinstance (s .callee .code , GateFunction )
112+
113+ if uop_stmts != 1 :
114+ raise interp .InterpreterError (
115+ "Cannot lower if-statement: QASM2 only allows exactly one quantum operation in the body."
116+ )
117+
97118 with emit .new_frame (stmt ) as then_frame :
98119 then_frame .entries .update (frame .entries )
99120 emit .emit_block (then_frame , stmt .then_body .blocks [0 ])
Original file line number Diff line number Diff line change 1+ import pytest
2+ from kirin .interp import InterpreterError
3+
14from bloqade import qasm2
25
36
@@ -221,3 +224,68 @@ def para_u():
221224U(0.1, 0.2, 0.3) qreg[0];
222225"""
223226 )
227+
228+
229+ def test_if ():
230+ @qasm2 .extended
231+ def non_empty_else ():
232+ q = qasm2 .qreg (1 )
233+ c = qasm2 .creg (1 )
234+ qasm2 .measure (q , c )
235+
236+ if c [0 ] == 1 :
237+ qasm2 .x (q [0 ])
238+ else :
239+ qasm2 .y (q [0 ])
240+
241+ return q
242+
243+ target = qasm2 .emit .QASM2 ()
244+
245+ with pytest .raises (InterpreterError ):
246+ target .emit (non_empty_else )
247+
248+ @qasm2 .extended
249+ def multiline_then ():
250+ q = qasm2 .qreg (1 )
251+ c = qasm2 .creg (1 )
252+ qasm2 .measure (q , c )
253+
254+ if c [0 ] == 1 :
255+ qasm2 .x (q [0 ])
256+ qasm2 .y (q [0 ])
257+
258+ return q
259+
260+ target = qasm2 .emit .QASM2 ()
261+
262+ with pytest .raises (InterpreterError ):
263+ target .emit (multiline_then )
264+
265+ @qasm2 .extended
266+ def valid_if ():
267+ q = qasm2 .qreg (1 )
268+ c = qasm2 .creg (1 )
269+ qasm2 .measure (q , c )
270+
271+ if c [0 ] == 0 :
272+ qasm2 .x (q [0 ])
273+
274+ return q
275+
276+ target = qasm2 .emit .QASM2 ()
277+ target .emit (valid_if )
278+
279+ @qasm2 .extended
280+ def nested_kernel ():
281+ q = qasm2 .qreg (1 )
282+ c = qasm2 .creg (1 )
283+ qasm2 .measure (q , c )
284+
285+ if c [0 ] == 0 :
286+ valid_if ()
287+
288+ return q
289+
290+ target = qasm2 .emit .QASM2 ()
291+ target .emit (nested_kernel )
You can’t perform that action at this time.
0 commit comments