microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/bounds

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_codegen/src/qir/tests.rs

236lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use super::ToQir;
5use expect_test::expect;
6use qsc_rir::builder;
7use qsc_rir::rir;
8
9#[test]
10fn single_qubit_gate_decl_works() {
11 let decl = builder::x_decl();
12 expect!["declare void @__quantum__qis__x__body(%Qubit*)"]
13 .assert_eq(&decl.to_qir(&rir::Program::default()));
14}
15
16#[test]
17fn two_qubit_gate_decl_works() {
18 let decl = builder::cx_decl();
19 expect!["declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)"]
20 .assert_eq(&decl.to_qir(&rir::Program::default()));
21}
22
23#[test]
24fn single_qubit_rotation_decl_works() {
25 let decl = builder::rx_decl();
26 expect!["declare void @__quantum__qis__rx__body(double, %Qubit*)"]
27 .assert_eq(&decl.to_qir(&rir::Program::default()));
28}
29
30#[test]
31fn measurement_decl_works() {
32 let decl = builder::m_decl();
33 expect!["declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1"]
34 .assert_eq(&decl.to_qir(&rir::Program::default()));
35}
36
37#[test]
38fn read_result_decl_works() {
39 let decl = builder::read_result_decl();
40 expect!["declare i1 @__quantum__qis__read_result__body(%Result*)"]
41 .assert_eq(&decl.to_qir(&rir::Program::default()));
42}
43
44#[test]
45fn result_record_decl_works() {
46 let decl = builder::result_record_decl();
47 expect!["declare void @__quantum__rt__result_record_output(%Result*, i8*)"]
48 .assert_eq(&decl.to_qir(&rir::Program::default()));
49}
50
51#[test]
52fn single_qubit_call() {
53 let mut program = rir::Program::default();
54 program
55 .callables
56 .insert(rir::CallableId(0), builder::x_decl());
57 let call = rir::Instruction::Call(
58 rir::CallableId(0),
59 vec![rir::Operand::Literal(rir::Literal::Qubit(0))],
60 None,
61 );
62 expect![" call void @__quantum__qis__x__body(%Qubit* inttoptr (i64 0 to %Qubit*))"]
63 .assert_eq(&call.to_qir(&program));
64}
65
66#[test]
67fn qubit_rotation_call() {
68 let mut program = rir::Program::default();
69 program
70 .callables
71 .insert(rir::CallableId(0), builder::rx_decl());
72 let call = rir::Instruction::Call(
73 rir::CallableId(0),
74 vec![
75 rir::Operand::Literal(rir::Literal::Double(std::f64::consts::PI)),
76 rir::Operand::Literal(rir::Literal::Qubit(0)),
77 ],
78 None,
79 );
80 expect![" call void @__quantum__qis__rx__body(double 3.141592653589793, %Qubit* inttoptr (i64 0 to %Qubit*))"]
81 .assert_eq(&call.to_qir(&program));
82}
83
84#[test]
85fn qubit_rotation_round_number_call() {
86 let mut program = rir::Program::default();
87 program
88 .callables
89 .insert(rir::CallableId(0), builder::rx_decl());
90 let call = rir::Instruction::Call(
91 rir::CallableId(0),
92 vec![
93 rir::Operand::Literal(rir::Literal::Double(3.0)),
94 rir::Operand::Literal(rir::Literal::Qubit(0)),
95 ],
96 None,
97 );
98 expect![
99 " call void @__quantum__qis__rx__body(double 3.0, %Qubit* inttoptr (i64 0 to %Qubit*))"
100 ]
101 .assert_eq(&call.to_qir(&program));
102}
103
104#[test]
105fn qubit_rotation_variable_angle_call() {
106 let mut program = rir::Program::default();
107 program
108 .callables
109 .insert(rir::CallableId(0), builder::rx_decl());
110 let call = rir::Instruction::Call(
111 rir::CallableId(0),
112 vec![
113 rir::Operand::Variable(rir::Variable {
114 variable_id: rir::VariableId(0),
115 ty: rir::Ty::Double,
116 }),
117 rir::Operand::Literal(rir::Literal::Qubit(0)),
118 ],
119 None,
120 );
121 expect![
122 " call void @__quantum__qis__rx__body(double %var_0, %Qubit* inttoptr (i64 0 to %Qubit*))"
123 ]
124 .assert_eq(&call.to_qir(&program));
125}
126
127#[test]
128fn bell_program() {
129 let program = builder::bell_program();
130 expect![[r#"
131 %Result = type opaque
132 %Qubit = type opaque
133
134 declare void @__quantum__qis__h__body(%Qubit*)
135
136 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
137
138 declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
139
140 declare void @__quantum__rt__array_record_output(i64, i8*)
141
142 declare void @__quantum__rt__result_record_output(%Result*, i8*)
143
144 define void @ENTRYPOINT__main() #0 {
145 block_0:
146 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 0 to %Qubit*))
147 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
148 call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
149 call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
150 call void @__quantum__rt__array_record_output(i64 2, i8* null)
151 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
152 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
153 ret void
154 }
155
156 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="2" }
157 attributes #1 = { "irreversible" }
158
159 ; module flags
160
161 !llvm.module.flags = !{!0, !1, !2, !3}
162
163 !0 = !{i32 1, !"qir_major_version", i32 1}
164 !1 = !{i32 7, !"qir_minor_version", i32 0}
165 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
166 !3 = !{i32 1, !"dynamic_result_management", i1 false}
167 "#]].assert_eq(&program.to_qir(&program));
168}
169
170#[test]
171fn teleport_program() {
172 let program = builder::teleport_program();
173 expect![[r#"
174 %Result = type opaque
175 %Qubit = type opaque
176
177 declare void @__quantum__qis__h__body(%Qubit*)
178
179 declare void @__quantum__qis__z__body(%Qubit*)
180
181 declare void @__quantum__qis__x__body(%Qubit*)
182
183 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
184
185 declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*) #1
186
187 declare i1 @__quantum__qis__read_result__body(%Result*)
188
189 declare void @__quantum__rt__result_record_output(%Result*, i8*)
190
191 define void @ENTRYPOINT__main() #0 {
192 block_0:
193 call void @__quantum__qis__x__body(%Qubit* inttoptr (i64 0 to %Qubit*))
194 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
195 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
196 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
197 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 0 to %Qubit*))
198 call void @__quantum__qis__mresetz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
199 %var_0 = call i1 @__quantum__qis__read_result__body(%Result* inttoptr (i64 0 to %Result*))
200 br i1 %var_0, label %block_1, label %block_2
201 block_1:
202 call void @__quantum__qis__z__body(%Qubit* inttoptr (i64 1 to %Qubit*))
203 br label %block_2
204 block_2:
205 call void @__quantum__qis__mresetz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
206 %var_1 = call i1 @__quantum__qis__read_result__body(%Result* inttoptr (i64 1 to %Result*))
207 br i1 %var_1, label %block_3, label %block_4
208 block_3:
209 call void @__quantum__qis__x__body(%Qubit* inttoptr (i64 1 to %Qubit*))
210 br label %block_4
211 block_4:
212 call void @__quantum__qis__mresetz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 2 to %Result*))
213 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 2 to %Result*), i8* null)
214 ret void
215 }
216
217 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="3" "required_num_results"="3" }
218 attributes #1 = { "irreversible" }
219
220 ; module flags
221
222 !llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10}
223
224 !0 = !{i32 1, !"qir_major_version", i32 1}
225 !1 = !{i32 7, !"qir_minor_version", i32 0}
226 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
227 !3 = !{i32 1, !"dynamic_result_management", i1 false}
228 !4 = !{i32 1, !"classical_ints", i1 false}
229 !5 = !{i32 1, !"classical_floats", i1 false}
230 !6 = !{i32 1, !"backwards_branching", i1 false}
231 !7 = !{i32 1, !"qubit_resetting", i1 false}
232 !8 = !{i32 1, !"classical_fixed_points", i1 false}
233 !9 = !{i32 1, !"user_functions", i1 false}
234 !10 = !{i32 1, !"multiple_target_branching", i1 false}
235 "#]].assert_eq(&program.to_qir(&program));
236}
237