Skip to content

Commit 41c9c27

Browse files
authored
Merge b355817 into e48ef3b
2 parents e48ef3b + b355817 commit 41c9c27

File tree

8 files changed

+149
-146
lines changed

8 files changed

+149
-146
lines changed

compiler/qsc_qasm/src/semantic/lowerer.rs

Lines changed: 18 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ use crate::convert::safe_i64_to_f64;
3232
use crate::parser::ast::list_from_iter;
3333
use crate::parser::ast::List;
3434
use crate::parser::QasmSource;
35-
use crate::semantic::ast::Expr;
3635
use crate::semantic::types::base_types_equal;
3736
use crate::semantic::types::can_cast_literal;
3837
use crate::semantic::types::can_cast_literal_with_value_knowledge;
@@ -298,21 +297,29 @@ impl Lowerer {
298297
gate_symbol("y", 0, 1),
299298
gate_symbol("z", 0, 1),
300299
gate_symbol("h", 0, 1),
300+
gate_symbol("ch", 0, 2),
301301
gate_symbol("s", 0, 1),
302+
gate_symbol("sdg", 0, 1),
302303
gate_symbol("t", 0, 1),
304+
gate_symbol("tdg", 0, 1),
303305
gate_symbol("sx", 0, 1),
304306
gate_symbol("rx", 1, 1),
305307
gate_symbol("ry", 1, 1),
306308
gate_symbol("rz", 1, 1),
309+
gate_symbol("crx", 1, 2),
310+
gate_symbol("cry", 1, 2),
311+
gate_symbol("crz", 1, 2),
307312
gate_symbol("cx", 0, 2),
308313
gate_symbol("cy", 0, 2),
309314
gate_symbol("cz", 0, 2),
310315
gate_symbol("cp", 1, 2),
311316
gate_symbol("swap", 0, 2),
317+
gate_symbol("cswap", 0, 3),
312318
gate_symbol("ccx", 0, 3),
313319
gate_symbol("cu", 4, 2),
314320
gate_symbol("CX", 0, 2),
315321
gate_symbol("phase", 1, 1),
322+
gate_symbol("cphase", 1, 2),
316323
gate_symbol("id", 0, 1),
317324
gate_symbol("u1", 1, 1),
318325
gate_symbol("u2", 2, 1),
@@ -346,30 +353,29 @@ impl Lowerer {
346353
gate_symbol("u3", 3, 1),
347354
gate_symbol("u2", 2, 1),
348355
gate_symbol("u1", 1, 1),
349-
//gate_symbol("cx", 0, 2), // handled as a modified x
356+
gate_symbol("cx", 0, 2),
350357
gate_symbol("id", 0, 1),
351358
// --- QE Standard Gates ---
352359
gate_symbol("x", 0, 1),
353360
gate_symbol("y", 0, 1),
354361
gate_symbol("z", 0, 1),
355362
gate_symbol("h", 0, 1),
356363
gate_symbol("s", 0, 1),
357-
// sdg handled as a modified s
364+
gate_symbol("sdg", 0, 1),
358365
gate_symbol("t", 0, 1),
359-
// tdg handled as a modified t
360-
366+
gate_symbol("tdg", 0, 1),
361367
// --- Standard rotations ---
362368
gate_symbol("rx", 1, 1),
363369
gate_symbol("ry", 1, 1),
364370
gate_symbol("rz", 1, 1),
365371
// --- QE Standard User-Defined Gates ---
366-
//gate_symbol("cz", 0, 2), // handled as a modified z
367-
//gate_symbol("cy", 0, 2), // handled as a modified y
368-
// ch handled as a modified h
372+
gate_symbol("cz", 0, 2),
373+
gate_symbol("cy", 0, 2),
374+
gate_symbol("ch", 0, 2),
369375
gate_symbol("ccx", 0, 3),
370-
// crz handled as a modified rz
371-
// cu1 handled as a modified u1
372-
// cu3 handled as a modified u3
376+
gate_symbol("crz", 1, 2),
377+
gate_symbol("cu1", 1, 2),
378+
gate_symbol("cu3", 3, 2),
373379
];
374380
for gate in gates {
375381
let name = gate.name.clone();
@@ -1892,18 +1898,7 @@ impl Lowerer {
18921898
self.push_unsupported_error_message("gate call duration", duration.span);
18931899
}
18941900

1895-
let mut name = stmt.name.name.to_string();
1896-
if let Some((gate_name, implicit_modifier)) =
1897-
self.try_get_qsharp_name_and_implicit_modifiers(&name, stmt.name.span)
1898-
{
1899-
// Override the gate name if we mapped with modifiers.
1900-
name = gate_name;
1901-
1902-
// 2. Get implicit modifiers and make them explicit.
1903-
// Q: Do we need this during lowering?
1904-
// A: Yes, we need it to check the gate_call arity.
1905-
modifiers.push(implicit_modifier);
1906-
}
1901+
let name = stmt.name.name.to_string();
19071902

19081903
// need a workaround for qiskit generating gate calls without having declared the gate
19091904
self.define_qiskit_standard_gate_if_needed(&name, stmt.name.span);
@@ -4129,52 +4124,6 @@ impl Lowerer {
41294124
let error = crate::Error(kind);
41304125
WithSource::from_map(&self.source_map, error)
41314126
}
4132-
4133-
fn try_get_qsharp_name_and_implicit_modifiers<S: AsRef<str>>(
4134-
&self,
4135-
gate_name: S,
4136-
name_span: Span,
4137-
) -> Option<(String, semantic::QuantumGateModifier)> {
4138-
use semantic::GateModifierKind::*;
4139-
4140-
let make_modifier = |kind| semantic::QuantumGateModifier {
4141-
span: name_span,
4142-
modifier_keyword_span: name_span,
4143-
kind,
4144-
};
4145-
let ctrl_expr = Expr::uint(1, Span::default());
4146-
4147-
if self.version == Some(QASM2_VERSION) {
4148-
match gate_name.as_ref() {
4149-
"cx" => Some(("x".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4150-
"sdg" => Some(("s".to_string(), make_modifier(Inv))),
4151-
"tdg" => Some(("t".to_string(), make_modifier(Inv))),
4152-
"cz" => Some(("z".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4153-
"cy" => Some(("y".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4154-
"ch" => Some(("h".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4155-
"crz" => Some(("rz".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4156-
"cu1" => Some(("u1".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4157-
"cu3" => Some(("u3".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4158-
_ => None,
4159-
}
4160-
} else {
4161-
match gate_name.as_ref() {
4162-
"cy" => Some(("y".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4163-
"cz" => Some(("z".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4164-
"ch" => Some(("h".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4165-
"crx" => Some(("rx".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4166-
"cry" => Some(("ry".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4167-
"crz" => Some(("rz".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4168-
"cswap" => Some(("swap".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4169-
"sdg" => Some(("s".to_string(), make_modifier(Inv))),
4170-
"tdg" => Some(("t".to_string(), make_modifier(Inv))),
4171-
// Gates for OpenQASM 2 backwards compatibility
4172-
"CX" => Some(("x".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4173-
"cphase" => Some(("phase".to_string(), make_modifier(Ctrl(ctrl_expr)))),
4174-
_ => None,
4175-
}
4176-
}
4177-
}
41784127
}
41794128

41804129
fn wrap_expr_in_cast_expr(ty: Type, rhs: semantic::Expr) -> semantic::Expr {

compiler/qsc_qasm/src/semantic/tests.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,50 +191,50 @@ fn semantic_errors_map_to_their_corresponding_file_specific_spans() {
191191
Stmt [196-206]:
192192
annotations: <empty>
193193
kind: ClassicalDeclarationStmt [196-206]:
194-
symbol_id: 32
194+
symbol_id: 40
195195
ty_span: [196-199]
196196
init_expr: Expr [204-205]:
197197
ty: const bit
198198
kind: Lit: Bit(1)
199199
Stmt [211-227]:
200200
annotations: <empty>
201201
kind: ClassicalDeclarationStmt [211-227]:
202-
symbol_id: 32
202+
symbol_id: 40
203203
ty_span: [211-215]
204204
init_expr: Expr [220-226]:
205205
ty: bool
206206
kind: BinaryOpExpr:
207207
op: AndL
208208
lhs: Expr [220-221]:
209209
ty: unknown
210-
kind: SymbolId(33)
210+
kind: SymbolId(41)
211211
rhs: Expr [225-226]:
212212
ty: bool
213213
kind: Cast [0-0]:
214214
ty: bool
215215
expr: Expr [225-226]:
216216
ty: bit
217-
kind: SymbolId(32)
217+
kind: SymbolId(40)
218218
Stmt [140-154]:
219219
annotations: <empty>
220220
kind: ClassicalDeclarationStmt [140-154]:
221-
symbol_id: 34
221+
symbol_id: 42
222222
ty_span: [140-145]
223223
init_expr: Expr [150-153]:
224224
ty: const angle
225225
kind: Lit: Angle(0.7168146928204138)
226226
Stmt [159-179]:
227227
annotations: <empty>
228228
kind: ClassicalDeclarationStmt [159-179]:
229-
symbol_id: 35
229+
symbol_id: 43
230230
ty_span: [159-164]
231231
init_expr: Expr [169-178]:
232232
ty: float
233233
kind: BinaryOpExpr:
234234
op: Add
235235
lhs: Expr [169-170]:
236236
ty: angle
237-
kind: SymbolId(34)
237+
kind: SymbolId(42)
238238
rhs: Expr [173-178]:
239239
ty: float
240240
kind: Cast [0-0]:
@@ -245,11 +245,11 @@ fn semantic_errors_map_to_their_corresponding_file_specific_spans() {
245245
Stmt [74-84]:
246246
annotations: <empty>
247247
kind: ClassicalDeclarationStmt [74-84]:
248-
symbol_id: 37
248+
symbol_id: 45
249249
ty_span: [74-77]
250250
init_expr: Expr [82-83]:
251251
ty: unknown
252-
kind: SymbolId(36)
252+
kind: SymbolId(44)
253253
254254
[Qasm.Lowerer.UndefinedSymbol
255255

compiler/qsc_qasm/src/semantic/tests/lowerer_errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ fn check_lowerer_error_spans_are_correct() {
8484
8585
x inconsistent types in alias expression: Expr [842-859]:
8686
| ty: array[int, 2]
87-
| kind: SymbolId(37), Expr [863-880]:
87+
| kind: SymbolId(45), Expr [863-880]:
8888
| ty: array[angle, 2]
89-
| kind: SymbolId(38)
89+
| kind: SymbolId(46)
9090
,-[Test.qasm:37:1]
9191
36 | array[angle, 2] alias_component_2 = {1.0, 2.0};
9292
37 | let alias = alias_component_1 ++ alias_component_2;

compiler/qsc_qasm/src/tests/statement/gate_call.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,8 +1493,8 @@ fn qasm2_all_qiskit_stdgates_can_be_called_included() -> miette::Result<(), Vec<
14931493
csdg(q[0], q[1]);
14941494
sxdg(q[0]);
14951495
csx(q[0], q[1]);
1496-
Controlled u1([q[1]], (Std.OpenQASM.Angle.DoubleAsAngle(Std.Math.PI() / 2., 53), q[0]));
1497-
Controlled u3([q[1]], (Std.OpenQASM.Angle.DoubleAsAngle(Std.Math.PI() / 2., 53), Std.OpenQASM.Angle.DoubleAsAngle(Std.Math.PI() / 4., 53), Std.OpenQASM.Angle.DoubleAsAngle(Std.Math.PI() / 8., 53), q[0]));
1496+
cu1(Std.OpenQASM.Angle.DoubleAsAngle(Std.Math.PI() / 2., 53), q[1], q[0]);
1497+
cu3(Std.OpenQASM.Angle.DoubleAsAngle(Std.Math.PI() / 2., 53), Std.OpenQASM.Angle.DoubleAsAngle(Std.Math.PI() / 4., 53), Std.OpenQASM.Angle.DoubleAsAngle(Std.Math.PI() / 8., 53), q[1], q[0]);
14981498
rccx(q[0], q[1], q[2]);
14991499
c3sqrtx(q[0], q[1], q[2], q[3]);
15001500
c3x(q[0], q[1], q[2], q[3]);
@@ -1542,9 +1542,9 @@ fn qasm2_broadcast_two_qubit_gate() -> miette::Result<(), Vec<Report>> {
15421542
import Std.OpenQASM.Intrinsic.*;
15431543
let ctrls = QIR.Runtime.AllocateQubitArray(3);
15441544
let targets = QIR.Runtime.AllocateQubitArray(3);
1545-
Controlled x([ctrls[0]], targets[0]);
1546-
Controlled x([ctrls[1]], targets[1]);
1547-
Controlled x([ctrls[2]], targets[2]);
1545+
cx(ctrls[0], targets[0]);
1546+
cx(ctrls[1], targets[1]);
1547+
cx(ctrls[2], targets[2]);
15481548
"#]]
15491549
.assert_eq(&qsharp);
15501550
Ok(())

compiler/qsc_qasm/src/tests/statement/implicit_modified_gate_call.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fn cy_gate_can_be_called() -> miette::Result<(), Vec<Report>> {
1919
import Std.OpenQASM.Intrinsic.*;
2020
let ctl = QIR.Runtime.__quantum__rt__qubit_allocate();
2121
let target = QIR.Runtime.__quantum__rt__qubit_allocate();
22-
Controlled y([ctl], target);
22+
cy(ctl, target);
2323
"#]]
2424
.assert_eq(&qsharp);
2525
Ok(())
@@ -39,7 +39,7 @@ fn cz_gate_can_be_called() -> miette::Result<(), Vec<Report>> {
3939
import Std.OpenQASM.Intrinsic.*;
4040
let ctl = QIR.Runtime.__quantum__rt__qubit_allocate();
4141
let target = QIR.Runtime.__quantum__rt__qubit_allocate();
42-
Controlled z([ctl], target);
42+
cz(ctl, target);
4343
"#]]
4444
.assert_eq(&qsharp);
4545
Ok(())
@@ -59,7 +59,7 @@ fn ch_gate_can_be_called() -> miette::Result<(), Vec<Report>> {
5959
import Std.OpenQASM.Intrinsic.*;
6060
let ctl = QIR.Runtime.__quantum__rt__qubit_allocate();
6161
let target = QIR.Runtime.__quantum__rt__qubit_allocate();
62-
Controlled h([ctl], target);
62+
ch(ctl, target);
6363
"#]]
6464
.assert_eq(&qsharp);
6565
Ok(())
@@ -77,7 +77,7 @@ fn sdg_gate_can_be_called() -> miette::Result<(), Vec<Report>> {
7777
expect![[r#"
7878
import Std.OpenQASM.Intrinsic.*;
7979
let q = QIR.Runtime.__quantum__rt__qubit_allocate();
80-
Adjoint s(q);
80+
sdg(q);
8181
"#]]
8282
.assert_eq(&qsharp);
8383
Ok(())
@@ -95,7 +95,7 @@ fn tdg_gate_can_be_called() -> miette::Result<(), Vec<Report>> {
9595
expect![[r#"
9696
import Std.OpenQASM.Intrinsic.*;
9797
let q = QIR.Runtime.__quantum__rt__qubit_allocate();
98-
Adjoint t(q);
98+
tdg(q);
9999
"#]]
100100
.assert_eq(&qsharp);
101101
Ok(())
@@ -115,10 +115,10 @@ fn crx_gate_can_be_called() -> miette::Result<(), Vec<Report>> {
115115
import Std.OpenQASM.Intrinsic.*;
116116
let ctl = QIR.Runtime.__quantum__rt__qubit_allocate();
117117
let target = QIR.Runtime.__quantum__rt__qubit_allocate();
118-
Controlled rx([ctl], (new Std.OpenQASM.Angle.Angle {
118+
crx(new Std.OpenQASM.Angle.Angle {
119119
Value = 716770142402832,
120120
Size = 53
121-
}, target));
121+
}, ctl, target);
122122
"#]]
123123
.assert_eq(&qsharp);
124124
Ok(())
@@ -138,10 +138,10 @@ fn cry_gate_can_be_called() -> miette::Result<(), Vec<Report>> {
138138
import Std.OpenQASM.Intrinsic.*;
139139
let ctl = QIR.Runtime.__quantum__rt__qubit_allocate();
140140
let target = QIR.Runtime.__quantum__rt__qubit_allocate();
141-
Controlled ry([ctl], (new Std.OpenQASM.Angle.Angle {
141+
cry(new Std.OpenQASM.Angle.Angle {
142142
Value = 716770142402832,
143143
Size = 53
144-
}, target));
144+
}, ctl, target);
145145
"#]]
146146
.assert_eq(&qsharp);
147147
Ok(())
@@ -161,10 +161,10 @@ fn crz_gate_can_be_called() -> miette::Result<(), Vec<Report>> {
161161
import Std.OpenQASM.Intrinsic.*;
162162
let ctl = QIR.Runtime.__quantum__rt__qubit_allocate();
163163
let target = QIR.Runtime.__quantum__rt__qubit_allocate();
164-
Controlled rz([ctl], (new Std.OpenQASM.Angle.Angle {
164+
crz(new Std.OpenQASM.Angle.Angle {
165165
Value = 716770142402832,
166166
Size = 53
167-
}, target));
167+
}, ctl, target);
168168
"#]]
169169
.assert_eq(&qsharp);
170170
Ok(())
@@ -184,7 +184,7 @@ fn cswap_gate_can_be_called() -> miette::Result<(), Vec<Report>> {
184184
import Std.OpenQASM.Intrinsic.*;
185185
let ctl = QIR.Runtime.__quantum__rt__qubit_allocate();
186186
let q = QIR.Runtime.AllocateQubitArray(2);
187-
Controlled swap([ctl], (q[0], q[1]));
187+
cswap(ctl, q[0], q[1]);
188188
"#]]
189189
.assert_eq(&qsharp);
190190
Ok(())
@@ -204,7 +204,7 @@ fn legacy_cx_gate_can_be_called() -> miette::Result<(), Vec<Report>> {
204204
import Std.OpenQASM.Intrinsic.*;
205205
let ctl = QIR.Runtime.__quantum__rt__qubit_allocate();
206206
let target = QIR.Runtime.__quantum__rt__qubit_allocate();
207-
Controlled x([ctl], target);
207+
CX(ctl, target);
208208
"#]]
209209
.assert_eq(&qsharp);
210210
Ok(())
@@ -224,10 +224,10 @@ fn legacy_cphase_gate_can_be_called() -> miette::Result<(), Vec<Report>> {
224224
import Std.OpenQASM.Intrinsic.*;
225225
let ctl = QIR.Runtime.__quantum__rt__qubit_allocate();
226226
let target = QIR.Runtime.__quantum__rt__qubit_allocate();
227-
Controlled phase([ctl], (new Std.OpenQASM.Angle.Angle {
227+
cphase(new Std.OpenQASM.Angle.Angle {
228228
Value = 1433540284805665,
229229
Size = 53
230-
}, target));
230+
}, ctl, target);
231231
"#]]
232232
.assert_eq(&qsharp);
233233
Ok(())

0 commit comments

Comments
 (0)