microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
iadavis/pipeline-issue-debugging

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/pip/tests-integration/devices/test_atom_decomp.py

1719lines · modecode

1# Copyright (c) Microsoft Corporation.
2# Licensed under the MIT License.
3
4import pytest
5from expecttest import assert_expected_inline
6
7import qsharp
8from qsharp._device._atom._decomp import (
9 DecomposeMultiQubitToCZ,
10 DecomposeSingleRotationToRz,
11 DecomposeSingleQubitToRzSX,
12 DecomposeRzAnglesToCliffordGates,
13 ReplaceResetWithMResetZ,
14)
15
16try:
17 import pyqir
18
19 PYQIR_AVAILABLE = True
20except ImportError:
21 PYQIR_AVAILABLE = False
22
23SKIP_REASON = "PyQIR is not available"
24
25
26@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
27def test_ccx_decomposition() -> None:
28 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
29 qir = qsharp.compile(
30 """
31 {
32 use (q1, q2, q3) = (Qubit(), Qubit(), Qubit());
33 CCNOT(q1, q2, q3);
34 }
35 """
36 )
37
38 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
39 DecomposeMultiQubitToCZ().run(module)
40 transformed_qir = str(module)
41
42 assert_expected_inline(
43 transformed_qir,
44 """\
45
46%Qubit = type opaque
47
48@empty_tag = internal constant [1 x i8] zeroinitializer
49
50define i64 @ENTRYPOINT__main() #0 {
51block_0:
52 call void @__quantum__rt__initialize(i8* null)
53 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
54 call void @__quantum__qis__t__adj(%Qubit* null)
55 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 1 to %Qubit*))
56 call void @__quantum__qis__h__body(%Qubit* null)
57 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Qubit* null)
58 call void @__quantum__qis__h__body(%Qubit* null)
59 call void @__quantum__qis__t__body(%Qubit* null)
60 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
61 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
62 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
63 call void @__quantum__qis__h__body(%Qubit* null)
64 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* null)
65 call void @__quantum__qis__h__body(%Qubit* null)
66 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 2 to %Qubit*))
67 call void @__quantum__qis__t__adj(%Qubit* null)
68 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
69 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
70 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
71 call void @__quantum__qis__h__body(%Qubit* null)
72 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Qubit* null)
73 call void @__quantum__qis__h__body(%Qubit* null)
74 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 2 to %Qubit*))
75 call void @__quantum__qis__t__body(%Qubit* null)
76 call void @__quantum__qis__h__body(%Qubit* null)
77 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* null)
78 call void @__quantum__qis__h__body(%Qubit* null)
79 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
80 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
81 ret i64 0
82}
83
84declare void @__quantum__rt__initialize(i8*)
85
86declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
87
88declare void @__quantum__rt__tuple_record_output(i64, i8*)
89
90declare void @__quantum__qis__h__body(%Qubit*)
91
92declare void @__quantum__qis__s__body(%Qubit*)
93
94declare void @__quantum__qis__s__adj(%Qubit*)
95
96declare void @__quantum__qis__t__body(%Qubit*)
97
98declare void @__quantum__qis__t__adj(%Qubit*)
99
100declare void @__quantum__qis__rz__body(double, %Qubit*)
101
102declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
103
104attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="3" "required_num_results"="0" }
105
106!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
107
108!0 = !{i32 1, !"qir_major_version", i32 1}
109!1 = !{i32 7, !"qir_minor_version", i32 0}
110!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
111!3 = !{i32 1, !"dynamic_result_management", i1 false}
112!4 = !{i32 5, !"int_computations", !5}
113!5 = !{!"i64"}
114!6 = !{i32 5, !"float_computations", !7}
115!7 = !{!"double"}
116""",
117 )
118
119
120@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
121def test_cx_decomposition() -> None:
122 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
123 qir = qsharp.compile(
124 """
125 {
126 use (q1, q2) = (Qubit(), Qubit());
127 CNOT(q1, q2);
128 }
129 """
130 )
131
132 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
133 DecomposeMultiQubitToCZ().run(module)
134 transformed_qir = str(module)
135
136 assert_expected_inline(
137 transformed_qir,
138 """\
139
140%Qubit = type opaque
141
142@empty_tag = internal constant [1 x i8] zeroinitializer
143
144define i64 @ENTRYPOINT__main() #0 {
145block_0:
146 call void @__quantum__rt__initialize(i8* null)
147 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
148 call void @__quantum__qis__cz__body(%Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
149 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
150 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
151 ret i64 0
152}
153
154declare void @__quantum__rt__initialize(i8*)
155
156declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
157
158declare void @__quantum__rt__tuple_record_output(i64, i8*)
159
160declare void @__quantum__qis__h__body(%Qubit*)
161
162declare void @__quantum__qis__s__body(%Qubit*)
163
164declare void @__quantum__qis__s__adj(%Qubit*)
165
166declare void @__quantum__qis__t__body(%Qubit*)
167
168declare void @__quantum__qis__t__adj(%Qubit*)
169
170declare void @__quantum__qis__rz__body(double, %Qubit*)
171
172declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
173
174attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
175
176!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
177
178!0 = !{i32 1, !"qir_major_version", i32 1}
179!1 = !{i32 7, !"qir_minor_version", i32 0}
180!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
181!3 = !{i32 1, !"dynamic_result_management", i1 false}
182!4 = !{i32 5, !"int_computations", !5}
183!5 = !{!"i64"}
184!6 = !{i32 5, !"float_computations", !7}
185!7 = !{!"double"}
186""",
187 )
188
189
190@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
191def test_cy_decomposition() -> None:
192 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
193 qir = qsharp.compile(
194 """
195 {
196 use (q1, q2) = (Qubit(), Qubit());
197 CY(q1, q2);
198 }
199 """
200 )
201
202 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
203 DecomposeMultiQubitToCZ().run(module)
204 transformed_qir = str(module)
205
206 assert_expected_inline(
207 transformed_qir,
208 """\
209
210%Qubit = type opaque
211
212@empty_tag = internal constant [1 x i8] zeroinitializer
213
214define i64 @ENTRYPOINT__main() #0 {
215block_0:
216 call void @__quantum__rt__initialize(i8* null)
217 call void @__quantum__qis__s__adj(%Qubit* inttoptr (i64 1 to %Qubit*))
218 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
219 call void @__quantum__qis__cz__body(%Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
220 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
221 call void @__quantum__qis__s__body(%Qubit* inttoptr (i64 1 to %Qubit*))
222 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
223 ret i64 0
224}
225
226declare void @__quantum__rt__initialize(i8*)
227
228declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
229
230declare void @__quantum__rt__tuple_record_output(i64, i8*)
231
232declare void @__quantum__qis__h__body(%Qubit*)
233
234declare void @__quantum__qis__s__body(%Qubit*)
235
236declare void @__quantum__qis__s__adj(%Qubit*)
237
238declare void @__quantum__qis__t__body(%Qubit*)
239
240declare void @__quantum__qis__t__adj(%Qubit*)
241
242declare void @__quantum__qis__rz__body(double, %Qubit*)
243
244declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
245
246attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
247
248!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
249
250!0 = !{i32 1, !"qir_major_version", i32 1}
251!1 = !{i32 7, !"qir_minor_version", i32 0}
252!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
253!3 = !{i32 1, !"dynamic_result_management", i1 false}
254!4 = !{i32 5, !"int_computations", !5}
255!5 = !{!"i64"}
256!6 = !{i32 5, !"float_computations", !7}
257!7 = !{!"double"}
258""",
259 )
260
261
262@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
263def test_rxx_decomposition() -> None:
264 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
265 qir = qsharp.compile(
266 """
267 {
268 use (q1, q2) = (Qubit(), Qubit());
269 Rxx(1.2345, q1, q2);
270 }
271 """
272 )
273
274 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
275 DecomposeMultiQubitToCZ().run(module)
276 transformed_qir = str(module)
277
278 assert_expected_inline(
279 transformed_qir,
280 """\
281
282%Qubit = type opaque
283
284@empty_tag = internal constant [1 x i8] zeroinitializer
285
286define i64 @ENTRYPOINT__main() #0 {
287block_0:
288 call void @__quantum__rt__initialize(i8* null)
289 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
290 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* null)
291 call void @__quantum__qis__h__body(%Qubit* null)
292 call void @__quantum__qis__rz__body(double 1.234500e+00, %Qubit* null)
293 call void @__quantum__qis__h__body(%Qubit* null)
294 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* null)
295 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
296 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
297 ret i64 0
298}
299
300declare void @__quantum__rt__initialize(i8*)
301
302declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
303
304declare void @__quantum__rt__tuple_record_output(i64, i8*)
305
306declare void @__quantum__qis__h__body(%Qubit*)
307
308declare void @__quantum__qis__s__body(%Qubit*)
309
310declare void @__quantum__qis__s__adj(%Qubit*)
311
312declare void @__quantum__qis__t__body(%Qubit*)
313
314declare void @__quantum__qis__t__adj(%Qubit*)
315
316declare void @__quantum__qis__rz__body(double, %Qubit*)
317
318declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
319
320attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
321
322!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
323
324!0 = !{i32 1, !"qir_major_version", i32 1}
325!1 = !{i32 7, !"qir_minor_version", i32 0}
326!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
327!3 = !{i32 1, !"dynamic_result_management", i1 false}
328!4 = !{i32 5, !"int_computations", !5}
329!5 = !{!"i64"}
330!6 = !{i32 5, !"float_computations", !7}
331!7 = !{!"double"}
332""",
333 )
334
335
336@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
337def test_ryy_decomposition() -> None:
338 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
339 qir = qsharp.compile(
340 """
341 {
342 use (q1, q2) = (Qubit(), Qubit());
343 Ryy(1.2345, q1, q2);
344 }
345 """
346 )
347
348 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
349 DecomposeMultiQubitToCZ().run(module)
350 transformed_qir = str(module)
351
352 assert_expected_inline(
353 transformed_qir,
354 """\
355
356%Qubit = type opaque
357
358@empty_tag = internal constant [1 x i8] zeroinitializer
359
360define i64 @ENTRYPOINT__main() #0 {
361block_0:
362 call void @__quantum__rt__initialize(i8* null)
363 call void @__quantum__qis__s__adj(%Qubit* null)
364 call void @__quantum__qis__s__adj(%Qubit* inttoptr (i64 1 to %Qubit*))
365 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
366 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* null)
367 call void @__quantum__qis__h__body(%Qubit* null)
368 call void @__quantum__qis__rz__body(double 1.234500e+00, %Qubit* null)
369 call void @__quantum__qis__h__body(%Qubit* null)
370 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* null)
371 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
372 call void @__quantum__qis__s__body(%Qubit* inttoptr (i64 1 to %Qubit*))
373 call void @__quantum__qis__s__body(%Qubit* null)
374 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
375 ret i64 0
376}
377
378declare void @__quantum__rt__initialize(i8*)
379
380declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
381
382declare void @__quantum__rt__tuple_record_output(i64, i8*)
383
384declare void @__quantum__qis__h__body(%Qubit*)
385
386declare void @__quantum__qis__s__body(%Qubit*)
387
388declare void @__quantum__qis__s__adj(%Qubit*)
389
390declare void @__quantum__qis__t__body(%Qubit*)
391
392declare void @__quantum__qis__t__adj(%Qubit*)
393
394declare void @__quantum__qis__rz__body(double, %Qubit*)
395
396declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
397
398attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
399
400!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
401
402!0 = !{i32 1, !"qir_major_version", i32 1}
403!1 = !{i32 7, !"qir_minor_version", i32 0}
404!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
405!3 = !{i32 1, !"dynamic_result_management", i1 false}
406!4 = !{i32 5, !"int_computations", !5}
407!5 = !{!"i64"}
408!6 = !{i32 5, !"float_computations", !7}
409!7 = !{!"double"}
410""",
411 )
412
413
414@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
415def test_rzz_decomposition() -> None:
416 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
417 qir = qsharp.compile(
418 """
419 {
420 use (q1, q2) = (Qubit(), Qubit());
421 Rzz(1.2345, q1, q2);
422 }
423 """
424 )
425
426 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
427 DecomposeMultiQubitToCZ().run(module)
428 transformed_qir = str(module)
429
430 assert_expected_inline(
431 transformed_qir,
432 """\
433
434%Qubit = type opaque
435
436@empty_tag = internal constant [1 x i8] zeroinitializer
437
438define i64 @ENTRYPOINT__main() #0 {
439block_0:
440 call void @__quantum__rt__initialize(i8* null)
441 call void @__quantum__qis__h__body(%Qubit* null)
442 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* null)
443 call void @__quantum__qis__h__body(%Qubit* null)
444 call void @__quantum__qis__rz__body(double 1.234500e+00, %Qubit* null)
445 call void @__quantum__qis__h__body(%Qubit* null)
446 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* null)
447 call void @__quantum__qis__h__body(%Qubit* null)
448 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
449 ret i64 0
450}
451
452declare void @__quantum__rt__initialize(i8*)
453
454declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
455
456declare void @__quantum__rt__tuple_record_output(i64, i8*)
457
458declare void @__quantum__qis__h__body(%Qubit*)
459
460declare void @__quantum__qis__s__body(%Qubit*)
461
462declare void @__quantum__qis__s__adj(%Qubit*)
463
464declare void @__quantum__qis__t__body(%Qubit*)
465
466declare void @__quantum__qis__t__adj(%Qubit*)
467
468declare void @__quantum__qis__rz__body(double, %Qubit*)
469
470declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
471
472attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
473
474!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
475
476!0 = !{i32 1, !"qir_major_version", i32 1}
477!1 = !{i32 7, !"qir_minor_version", i32 0}
478!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
479!3 = !{i32 1, !"dynamic_result_management", i1 false}
480!4 = !{i32 5, !"int_computations", !5}
481!5 = !{!"i64"}
482!6 = !{i32 5, !"float_computations", !7}
483!7 = !{!"double"}
484""",
485 )
486
487
488@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
489def test_swap_decomposition() -> None:
490 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
491 qir = qsharp.compile(
492 """
493 {
494 use (q1, q2) = (Qubit(), Qubit());
495 SWAP(q1, q2);
496 }
497 """
498 )
499
500 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
501 DecomposeMultiQubitToCZ().run(module)
502 transformed_qir = str(module)
503
504 assert_expected_inline(
505 transformed_qir,
506 """\
507
508%Qubit = type opaque
509
510@empty_tag = internal constant [1 x i8] zeroinitializer
511
512define i64 @ENTRYPOINT__main() #0 {
513block_0:
514 call void @__quantum__rt__initialize(i8* null)
515 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
516 call void @__quantum__qis__cz__body(%Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
517 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
518 call void @__quantum__qis__h__body(%Qubit* null)
519 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* null)
520 call void @__quantum__qis__h__body(%Qubit* null)
521 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
522 call void @__quantum__qis__cz__body(%Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
523 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
524 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
525 ret i64 0
526}
527
528declare void @__quantum__rt__initialize(i8*)
529
530declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
531
532declare void @__quantum__rt__tuple_record_output(i64, i8*)
533
534declare void @__quantum__qis__h__body(%Qubit*)
535
536declare void @__quantum__qis__s__body(%Qubit*)
537
538declare void @__quantum__qis__s__adj(%Qubit*)
539
540declare void @__quantum__qis__t__body(%Qubit*)
541
542declare void @__quantum__qis__t__adj(%Qubit*)
543
544declare void @__quantum__qis__rz__body(double, %Qubit*)
545
546declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
547
548attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
549
550!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
551
552!0 = !{i32 1, !"qir_major_version", i32 1}
553!1 = !{i32 7, !"qir_minor_version", i32 0}
554!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
555!3 = !{i32 1, !"dynamic_result_management", i1 false}
556!4 = !{i32 5, !"int_computations", !5}
557!5 = !{!"i64"}
558!6 = !{i32 5, !"float_computations", !7}
559!7 = !{!"double"}
560""",
561 )
562
563
564@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
565def test_rx_decomposition() -> None:
566 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
567 qir = qsharp.compile(
568 """
569 {
570 use q = Qubit();
571 Rx(1.2345, q);
572 }
573 """
574 )
575
576 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
577 DecomposeSingleRotationToRz().run(module)
578 transformed_qir = str(module)
579
580 assert_expected_inline(
581 transformed_qir,
582 """\
583
584%Qubit = type opaque
585
586@empty_tag = internal constant [1 x i8] zeroinitializer
587
588define i64 @ENTRYPOINT__main() #0 {
589block_0:
590 call void @__quantum__rt__initialize(i8* null)
591 call void @__quantum__qis__h__body(%Qubit* null)
592 call void @__quantum__qis__rz__body(double 1.234500e+00, %Qubit* null)
593 call void @__quantum__qis__h__body(%Qubit* null)
594 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
595 ret i64 0
596}
597
598declare void @__quantum__rt__initialize(i8*)
599
600declare void @__quantum__qis__rx__body(double, %Qubit*)
601
602declare void @__quantum__rt__tuple_record_output(i64, i8*)
603
604declare void @__quantum__qis__h__body(%Qubit*)
605
606declare void @__quantum__qis__s__body(%Qubit*)
607
608declare void @__quantum__qis__s__adj(%Qubit*)
609
610declare void @__quantum__qis__rz__body(double, %Qubit*)
611
612attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
613
614!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
615
616!0 = !{i32 1, !"qir_major_version", i32 1}
617!1 = !{i32 7, !"qir_minor_version", i32 0}
618!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
619!3 = !{i32 1, !"dynamic_result_management", i1 false}
620!4 = !{i32 5, !"int_computations", !5}
621!5 = !{!"i64"}
622!6 = !{i32 5, !"float_computations", !7}
623!7 = !{!"double"}
624""",
625 )
626
627
628@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
629def test_ry_decomposition() -> None:
630 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
631 qir = qsharp.compile(
632 """
633 {
634 use q = Qubit();
635 Ry(1.2345, q);
636 }
637 """
638 )
639
640 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
641 DecomposeSingleRotationToRz().run(module)
642 transformed_qir = str(module)
643
644 assert_expected_inline(
645 transformed_qir,
646 """\
647
648%Qubit = type opaque
649
650@empty_tag = internal constant [1 x i8] zeroinitializer
651
652define i64 @ENTRYPOINT__main() #0 {
653block_0:
654 call void @__quantum__rt__initialize(i8* null)
655 call void @__quantum__qis__s__adj(%Qubit* null)
656 call void @__quantum__qis__h__body(%Qubit* null)
657 call void @__quantum__qis__rz__body(double 1.234500e+00, %Qubit* null)
658 call void @__quantum__qis__h__body(%Qubit* null)
659 call void @__quantum__qis__s__body(%Qubit* null)
660 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
661 ret i64 0
662}
663
664declare void @__quantum__rt__initialize(i8*)
665
666declare void @__quantum__qis__ry__body(double, %Qubit*)
667
668declare void @__quantum__rt__tuple_record_output(i64, i8*)
669
670declare void @__quantum__qis__h__body(%Qubit*)
671
672declare void @__quantum__qis__s__body(%Qubit*)
673
674declare void @__quantum__qis__s__adj(%Qubit*)
675
676declare void @__quantum__qis__rz__body(double, %Qubit*)
677
678attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
679
680!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
681
682!0 = !{i32 1, !"qir_major_version", i32 1}
683!1 = !{i32 7, !"qir_minor_version", i32 0}
684!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
685!3 = !{i32 1, !"dynamic_result_management", i1 false}
686!4 = !{i32 5, !"int_computations", !5}
687!5 = !{!"i64"}
688!6 = !{i32 5, !"float_computations", !7}
689!7 = !{!"double"}
690""",
691 )
692
693
694@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
695def test_h_decomposition() -> None:
696 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
697 qir = qsharp.compile(
698 """
699 {
700 use q = Qubit();
701 H(q);
702 }
703 """
704 )
705
706 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
707 DecomposeSingleQubitToRzSX().run(module)
708 transformed_qir = str(module)
709
710 assert_expected_inline(
711 transformed_qir,
712 """\
713
714%Qubit = type opaque
715
716@empty_tag = internal constant [1 x i8] zeroinitializer
717
718define i64 @ENTRYPOINT__main() #0 {
719block_0:
720 call void @__quantum__rt__initialize(i8* null)
721 call void @__quantum__qis__rz__body(double 0x3FF921FB54442D18, %Qubit* null)
722 call void @__quantum__qis__sx__body(%Qubit* null)
723 call void @__quantum__qis__rz__body(double 0x3FF921FB54442D18, %Qubit* null)
724 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
725 ret i64 0
726}
727
728declare void @__quantum__rt__initialize(i8*)
729
730declare void @__quantum__qis__h__body(%Qubit*)
731
732declare void @__quantum__rt__tuple_record_output(i64, i8*)
733
734declare void @__quantum__qis__sx__body(%Qubit*)
735
736declare void @__quantum__qis__rz__body(double, %Qubit*)
737
738attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
739
740!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
741
742!0 = !{i32 1, !"qir_major_version", i32 1}
743!1 = !{i32 7, !"qir_minor_version", i32 0}
744!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
745!3 = !{i32 1, !"dynamic_result_management", i1 false}
746!4 = !{i32 5, !"int_computations", !5}
747!5 = !{!"i64"}
748!6 = !{i32 5, !"float_computations", !7}
749!7 = !{!"double"}
750""",
751 )
752
753
754@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
755def test_s_decomposition() -> None:
756 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
757 qir = qsharp.compile(
758 """
759 {
760 use q = Qubit();
761 S(q);
762 }
763 """
764 )
765
766 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
767 DecomposeSingleQubitToRzSX().run(module)
768 transformed_qir = str(module)
769
770 assert_expected_inline(
771 transformed_qir,
772 """\
773
774%Qubit = type opaque
775
776@empty_tag = internal constant [1 x i8] zeroinitializer
777
778define i64 @ENTRYPOINT__main() #0 {
779block_0:
780 call void @__quantum__rt__initialize(i8* null)
781 call void @__quantum__qis__rz__body(double 0x3FF921FB54442D18, %Qubit* null)
782 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
783 ret i64 0
784}
785
786declare void @__quantum__rt__initialize(i8*)
787
788declare void @__quantum__qis__s__body(%Qubit*)
789
790declare void @__quantum__rt__tuple_record_output(i64, i8*)
791
792declare void @__quantum__qis__sx__body(%Qubit*)
793
794declare void @__quantum__qis__rz__body(double, %Qubit*)
795
796attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
797
798!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
799
800!0 = !{i32 1, !"qir_major_version", i32 1}
801!1 = !{i32 7, !"qir_minor_version", i32 0}
802!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
803!3 = !{i32 1, !"dynamic_result_management", i1 false}
804!4 = !{i32 5, !"int_computations", !5}
805!5 = !{!"i64"}
806!6 = !{i32 5, !"float_computations", !7}
807!7 = !{!"double"}
808""",
809 )
810
811
812@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
813def test_sadj_decomposition() -> None:
814 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
815 qir = qsharp.compile(
816 """
817 {
818 use q = Qubit();
819 Adjoint S(q);
820 }
821 """
822 )
823
824 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
825 DecomposeSingleQubitToRzSX().run(module)
826 transformed_qir = str(module)
827
828 assert_expected_inline(
829 transformed_qir,
830 """\
831
832%Qubit = type opaque
833
834@empty_tag = internal constant [1 x i8] zeroinitializer
835
836define i64 @ENTRYPOINT__main() #0 {
837block_0:
838 call void @__quantum__rt__initialize(i8* null)
839 call void @__quantum__qis__rz__body(double 0xBFF921FB54442D18, %Qubit* null)
840 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
841 ret i64 0
842}
843
844declare void @__quantum__rt__initialize(i8*)
845
846declare void @__quantum__qis__s__adj(%Qubit*)
847
848declare void @__quantum__rt__tuple_record_output(i64, i8*)
849
850declare void @__quantum__qis__sx__body(%Qubit*)
851
852declare void @__quantum__qis__rz__body(double, %Qubit*)
853
854attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
855
856!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
857
858!0 = !{i32 1, !"qir_major_version", i32 1}
859!1 = !{i32 7, !"qir_minor_version", i32 0}
860!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
861!3 = !{i32 1, !"dynamic_result_management", i1 false}
862!4 = !{i32 5, !"int_computations", !5}
863!5 = !{!"i64"}
864!6 = !{i32 5, !"float_computations", !7}
865!7 = !{!"double"}
866""",
867 )
868
869
870@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
871def test_t_decomposition() -> None:
872 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
873 qir = qsharp.compile(
874 """
875 {
876 use q = Qubit();
877 T(q);
878 }
879 """
880 )
881
882 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
883 DecomposeSingleQubitToRzSX().run(module)
884 transformed_qir = str(module)
885
886 assert_expected_inline(
887 transformed_qir,
888 """\
889
890%Qubit = type opaque
891
892@empty_tag = internal constant [1 x i8] zeroinitializer
893
894define i64 @ENTRYPOINT__main() #0 {
895block_0:
896 call void @__quantum__rt__initialize(i8* null)
897 call void @__quantum__qis__rz__body(double 0x3FE921FB54442D18, %Qubit* null)
898 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
899 ret i64 0
900}
901
902declare void @__quantum__rt__initialize(i8*)
903
904declare void @__quantum__qis__t__body(%Qubit*)
905
906declare void @__quantum__rt__tuple_record_output(i64, i8*)
907
908declare void @__quantum__qis__sx__body(%Qubit*)
909
910declare void @__quantum__qis__rz__body(double, %Qubit*)
911
912attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
913
914!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
915
916!0 = !{i32 1, !"qir_major_version", i32 1}
917!1 = !{i32 7, !"qir_minor_version", i32 0}
918!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
919!3 = !{i32 1, !"dynamic_result_management", i1 false}
920!4 = !{i32 5, !"int_computations", !5}
921!5 = !{!"i64"}
922!6 = !{i32 5, !"float_computations", !7}
923!7 = !{!"double"}
924""",
925 )
926
927
928@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
929def test_tadj_decomposition() -> None:
930 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
931 qir = qsharp.compile(
932 """
933 {
934 use q = Qubit();
935 Adjoint T(q);
936 }
937 """
938 )
939
940 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
941 DecomposeSingleQubitToRzSX().run(module)
942 transformed_qir = str(module)
943
944 assert_expected_inline(
945 transformed_qir,
946 """\
947
948%Qubit = type opaque
949
950@empty_tag = internal constant [1 x i8] zeroinitializer
951
952define i64 @ENTRYPOINT__main() #0 {
953block_0:
954 call void @__quantum__rt__initialize(i8* null)
955 call void @__quantum__qis__rz__body(double 0xBFE921FB54442D18, %Qubit* null)
956 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
957 ret i64 0
958}
959
960declare void @__quantum__rt__initialize(i8*)
961
962declare void @__quantum__qis__t__adj(%Qubit*)
963
964declare void @__quantum__rt__tuple_record_output(i64, i8*)
965
966declare void @__quantum__qis__sx__body(%Qubit*)
967
968declare void @__quantum__qis__rz__body(double, %Qubit*)
969
970attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
971
972!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
973
974!0 = !{i32 1, !"qir_major_version", i32 1}
975!1 = !{i32 7, !"qir_minor_version", i32 0}
976!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
977!3 = !{i32 1, !"dynamic_result_management", i1 false}
978!4 = !{i32 5, !"int_computations", !5}
979!5 = !{!"i64"}
980!6 = !{i32 5, !"float_computations", !7}
981!7 = !{!"double"}
982""",
983 )
984
985
986@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
987def test_x_decomposition() -> None:
988 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
989 qir = qsharp.compile(
990 """
991 {
992 use q = Qubit();
993 X(q);
994 }
995 """
996 )
997
998 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
999 DecomposeSingleQubitToRzSX().run(module)
1000 transformed_qir = str(module)
1001
1002 assert_expected_inline(
1003 transformed_qir,
1004 """\
1005
1006%Qubit = type opaque
1007
1008@empty_tag = internal constant [1 x i8] zeroinitializer
1009
1010define i64 @ENTRYPOINT__main() #0 {
1011block_0:
1012 call void @__quantum__rt__initialize(i8* null)
1013 call void @__quantum__qis__sx__body(%Qubit* null)
1014 call void @__quantum__qis__sx__body(%Qubit* null)
1015 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1016 ret i64 0
1017}
1018
1019declare void @__quantum__rt__initialize(i8*)
1020
1021declare void @__quantum__qis__x__body(%Qubit*)
1022
1023declare void @__quantum__rt__tuple_record_output(i64, i8*)
1024
1025declare void @__quantum__qis__sx__body(%Qubit*)
1026
1027declare void @__quantum__qis__rz__body(double, %Qubit*)
1028
1029attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1030
1031!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1032
1033!0 = !{i32 1, !"qir_major_version", i32 1}
1034!1 = !{i32 7, !"qir_minor_version", i32 0}
1035!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1036!3 = !{i32 1, !"dynamic_result_management", i1 false}
1037!4 = !{i32 5, !"int_computations", !5}
1038!5 = !{!"i64"}
1039!6 = !{i32 5, !"float_computations", !7}
1040!7 = !{!"double"}
1041""",
1042 )
1043
1044
1045@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1046def test_y_decomposition() -> None:
1047 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1048 qir = qsharp.compile(
1049 """
1050 {
1051 use q = Qubit();
1052 Y(q);
1053 }
1054 """
1055 )
1056
1057 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1058 DecomposeSingleQubitToRzSX().run(module)
1059 transformed_qir = str(module)
1060
1061 assert_expected_inline(
1062 transformed_qir,
1063 """\
1064
1065%Qubit = type opaque
1066
1067@empty_tag = internal constant [1 x i8] zeroinitializer
1068
1069define i64 @ENTRYPOINT__main() #0 {
1070block_0:
1071 call void @__quantum__rt__initialize(i8* null)
1072 call void @__quantum__qis__sx__body(%Qubit* null)
1073 call void @__quantum__qis__sx__body(%Qubit* null)
1074 call void @__quantum__qis__rz__body(double 0x400921FB54442D18, %Qubit* null)
1075 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1076 ret i64 0
1077}
1078
1079declare void @__quantum__rt__initialize(i8*)
1080
1081declare void @__quantum__qis__y__body(%Qubit*)
1082
1083declare void @__quantum__rt__tuple_record_output(i64, i8*)
1084
1085declare void @__quantum__qis__sx__body(%Qubit*)
1086
1087declare void @__quantum__qis__rz__body(double, %Qubit*)
1088
1089attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1090
1091!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1092
1093!0 = !{i32 1, !"qir_major_version", i32 1}
1094!1 = !{i32 7, !"qir_minor_version", i32 0}
1095!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1096!3 = !{i32 1, !"dynamic_result_management", i1 false}
1097!4 = !{i32 5, !"int_computations", !5}
1098!5 = !{!"i64"}
1099!6 = !{i32 5, !"float_computations", !7}
1100!7 = !{!"double"}
1101""",
1102 )
1103
1104
1105@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1106def test_z_decomposition() -> None:
1107 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1108 qir = qsharp.compile(
1109 """
1110 {
1111 use q = Qubit();
1112 Z(q);
1113 }
1114 """
1115 )
1116
1117 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1118 DecomposeSingleQubitToRzSX().run(module)
1119 transformed_qir = str(module)
1120
1121 assert_expected_inline(
1122 transformed_qir,
1123 """\
1124
1125%Qubit = type opaque
1126
1127@empty_tag = internal constant [1 x i8] zeroinitializer
1128
1129define i64 @ENTRYPOINT__main() #0 {
1130block_0:
1131 call void @__quantum__rt__initialize(i8* null)
1132 call void @__quantum__qis__rz__body(double 0x400921FB54442D18, %Qubit* null)
1133 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1134 ret i64 0
1135}
1136
1137declare void @__quantum__rt__initialize(i8*)
1138
1139declare void @__quantum__qis__z__body(%Qubit*)
1140
1141declare void @__quantum__rt__tuple_record_output(i64, i8*)
1142
1143declare void @__quantum__qis__sx__body(%Qubit*)
1144
1145declare void @__quantum__qis__rz__body(double, %Qubit*)
1146
1147attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1148
1149!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1150
1151!0 = !{i32 1, !"qir_major_version", i32 1}
1152!1 = !{i32 7, !"qir_minor_version", i32 0}
1153!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1154!3 = !{i32 1, !"dynamic_result_management", i1 false}
1155!4 = !{i32 5, !"int_computations", !5}
1156!5 = !{!"i64"}
1157!6 = !{i32 5, !"float_computations", !7}
1158!7 = !{!"double"}
1159""",
1160 )
1161
1162
1163@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1164def test_rz_3pi_over_2_clifford_decomposition() -> None:
1165 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1166 qir = qsharp.compile(
1167 """
1168 {
1169 use q = Qubit();
1170 Rz(3.0 * Std.Math.PI() / 2.0, q);
1171 }
1172 """
1173 )
1174
1175 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1176 DecomposeRzAnglesToCliffordGates().run(module)
1177 transformed_qir = str(module)
1178
1179 assert_expected_inline(
1180 transformed_qir,
1181 """\
1182
1183%Qubit = type opaque
1184
1185@empty_tag = internal constant [1 x i8] zeroinitializer
1186
1187define i64 @ENTRYPOINT__main() #0 {
1188block_0:
1189 call void @__quantum__rt__initialize(i8* null)
1190 call void @__quantum__qis__s__adj(%Qubit* null)
1191 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1192 ret i64 0
1193}
1194
1195declare void @__quantum__rt__initialize(i8*)
1196
1197declare void @__quantum__qis__rz__body(double, %Qubit*)
1198
1199declare void @__quantum__rt__tuple_record_output(i64, i8*)
1200
1201declare void @__quantum__qis__s__body(%Qubit*)
1202
1203declare void @__quantum__qis__s__adj(%Qubit*)
1204
1205declare void @__quantum__qis__z__body(%Qubit*)
1206
1207attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1208
1209!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1210
1211!0 = !{i32 1, !"qir_major_version", i32 1}
1212!1 = !{i32 7, !"qir_minor_version", i32 0}
1213!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1214!3 = !{i32 1, !"dynamic_result_management", i1 false}
1215!4 = !{i32 5, !"int_computations", !5}
1216!5 = !{!"i64"}
1217!6 = !{i32 5, !"float_computations", !7}
1218!7 = !{!"double"}
1219""",
1220 )
1221
1222
1223@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1224def test_rz_neg_pi_over_2_clifford_decomposition() -> None:
1225 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1226 qir = qsharp.compile(
1227 """
1228 {
1229 use q = Qubit();
1230 Rz(-1.0 * Std.Math.PI() / 2.0, q);
1231 }
1232 """
1233 )
1234
1235 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1236 DecomposeRzAnglesToCliffordGates().run(module)
1237 transformed_qir = str(module)
1238
1239 assert_expected_inline(
1240 transformed_qir,
1241 """\
1242
1243%Qubit = type opaque
1244
1245@empty_tag = internal constant [1 x i8] zeroinitializer
1246
1247define i64 @ENTRYPOINT__main() #0 {
1248block_0:
1249 call void @__quantum__rt__initialize(i8* null)
1250 call void @__quantum__qis__s__adj(%Qubit* null)
1251 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1252 ret i64 0
1253}
1254
1255declare void @__quantum__rt__initialize(i8*)
1256
1257declare void @__quantum__qis__rz__body(double, %Qubit*)
1258
1259declare void @__quantum__rt__tuple_record_output(i64, i8*)
1260
1261declare void @__quantum__qis__s__body(%Qubit*)
1262
1263declare void @__quantum__qis__s__adj(%Qubit*)
1264
1265declare void @__quantum__qis__z__body(%Qubit*)
1266
1267attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1268
1269!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1270
1271!0 = !{i32 1, !"qir_major_version", i32 1}
1272!1 = !{i32 7, !"qir_minor_version", i32 0}
1273!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1274!3 = !{i32 1, !"dynamic_result_management", i1 false}
1275!4 = !{i32 5, !"int_computations", !5}
1276!5 = !{!"i64"}
1277!6 = !{i32 5, !"float_computations", !7}
1278!7 = !{!"double"}
1279""",
1280 )
1281
1282
1283@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1284def test_rz_pi_clifford_decomposition() -> None:
1285 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1286 qir = qsharp.compile(
1287 """
1288 {
1289 use q = Qubit();
1290 Rz(Std.Math.PI(), q);
1291 }
1292 """
1293 )
1294
1295 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1296 DecomposeRzAnglesToCliffordGates().run(module)
1297 transformed_qir = str(module)
1298
1299 assert_expected_inline(
1300 transformed_qir,
1301 """\
1302
1303%Qubit = type opaque
1304
1305@empty_tag = internal constant [1 x i8] zeroinitializer
1306
1307define i64 @ENTRYPOINT__main() #0 {
1308block_0:
1309 call void @__quantum__rt__initialize(i8* null)
1310 call void @__quantum__qis__z__body(%Qubit* null)
1311 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1312 ret i64 0
1313}
1314
1315declare void @__quantum__rt__initialize(i8*)
1316
1317declare void @__quantum__qis__rz__body(double, %Qubit*)
1318
1319declare void @__quantum__rt__tuple_record_output(i64, i8*)
1320
1321declare void @__quantum__qis__s__body(%Qubit*)
1322
1323declare void @__quantum__qis__s__adj(%Qubit*)
1324
1325declare void @__quantum__qis__z__body(%Qubit*)
1326
1327attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1328
1329!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1330
1331!0 = !{i32 1, !"qir_major_version", i32 1}
1332!1 = !{i32 7, !"qir_minor_version", i32 0}
1333!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1334!3 = !{i32 1, !"dynamic_result_management", i1 false}
1335!4 = !{i32 5, !"int_computations", !5}
1336!5 = !{!"i64"}
1337!6 = !{i32 5, !"float_computations", !7}
1338!7 = !{!"double"}
1339""",
1340 )
1341
1342
1343@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1344def test_rz_neg_pi_clifford_decomposition() -> None:
1345 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1346 qir = qsharp.compile(
1347 """
1348 {
1349 use q = Qubit();
1350 Rz(-1.0 * Std.Math.PI(), q);
1351 }
1352 """
1353 )
1354
1355 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1356 DecomposeRzAnglesToCliffordGates().run(module)
1357 transformed_qir = str(module)
1358
1359 assert_expected_inline(
1360 transformed_qir,
1361 """\
1362
1363%Qubit = type opaque
1364
1365@empty_tag = internal constant [1 x i8] zeroinitializer
1366
1367define i64 @ENTRYPOINT__main() #0 {
1368block_0:
1369 call void @__quantum__rt__initialize(i8* null)
1370 call void @__quantum__qis__z__body(%Qubit* null)
1371 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1372 ret i64 0
1373}
1374
1375declare void @__quantum__rt__initialize(i8*)
1376
1377declare void @__quantum__qis__rz__body(double, %Qubit*)
1378
1379declare void @__quantum__rt__tuple_record_output(i64, i8*)
1380
1381declare void @__quantum__qis__s__body(%Qubit*)
1382
1383declare void @__quantum__qis__s__adj(%Qubit*)
1384
1385declare void @__quantum__qis__z__body(%Qubit*)
1386
1387attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1388
1389!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1390
1391!0 = !{i32 1, !"qir_major_version", i32 1}
1392!1 = !{i32 7, !"qir_minor_version", i32 0}
1393!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1394!3 = !{i32 1, !"dynamic_result_management", i1 false}
1395!4 = !{i32 5, !"int_computations", !5}
1396!5 = !{!"i64"}
1397!6 = !{i32 5, !"float_computations", !7}
1398!7 = !{!"double"}
1399""",
1400 )
1401
1402
1403@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1404def test_rz_pi_over_2_clifford_decomposition() -> None:
1405 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1406 qir = qsharp.compile(
1407 """
1408 {
1409 use q = Qubit();
1410 Rz(Std.Math.PI() / 2.0, q);
1411 }
1412 """
1413 )
1414
1415 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1416 DecomposeRzAnglesToCliffordGates().run(module)
1417 transformed_qir = str(module)
1418
1419 assert_expected_inline(
1420 transformed_qir,
1421 """\
1422
1423%Qubit = type opaque
1424
1425@empty_tag = internal constant [1 x i8] zeroinitializer
1426
1427define i64 @ENTRYPOINT__main() #0 {
1428block_0:
1429 call void @__quantum__rt__initialize(i8* null)
1430 call void @__quantum__qis__s__body(%Qubit* null)
1431 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1432 ret i64 0
1433}
1434
1435declare void @__quantum__rt__initialize(i8*)
1436
1437declare void @__quantum__qis__rz__body(double, %Qubit*)
1438
1439declare void @__quantum__rt__tuple_record_output(i64, i8*)
1440
1441declare void @__quantum__qis__s__body(%Qubit*)
1442
1443declare void @__quantum__qis__s__adj(%Qubit*)
1444
1445declare void @__quantum__qis__z__body(%Qubit*)
1446
1447attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1448
1449!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1450
1451!0 = !{i32 1, !"qir_major_version", i32 1}
1452!1 = !{i32 7, !"qir_minor_version", i32 0}
1453!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1454!3 = !{i32 1, !"dynamic_result_management", i1 false}
1455!4 = !{i32 5, !"int_computations", !5}
1456!5 = !{!"i64"}
1457!6 = !{i32 5, !"float_computations", !7}
1458!7 = !{!"double"}
1459""",
1460 )
1461
1462
1463@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1464def test_rz_neg_3pi_over_2_clifford_decomposition() -> None:
1465 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1466 qir = qsharp.compile(
1467 """
1468 {
1469 use q = Qubit();
1470 Rz(-3.0 * Std.Math.PI() / 2.0, q);
1471 }
1472 """
1473 )
1474
1475 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1476 DecomposeRzAnglesToCliffordGates().run(module)
1477 transformed_qir = str(module)
1478
1479 assert_expected_inline(
1480 transformed_qir,
1481 """\
1482
1483%Qubit = type opaque
1484
1485@empty_tag = internal constant [1 x i8] zeroinitializer
1486
1487define i64 @ENTRYPOINT__main() #0 {
1488block_0:
1489 call void @__quantum__rt__initialize(i8* null)
1490 call void @__quantum__qis__s__body(%Qubit* null)
1491 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1492 ret i64 0
1493}
1494
1495declare void @__quantum__rt__initialize(i8*)
1496
1497declare void @__quantum__qis__rz__body(double, %Qubit*)
1498
1499declare void @__quantum__rt__tuple_record_output(i64, i8*)
1500
1501declare void @__quantum__qis__s__body(%Qubit*)
1502
1503declare void @__quantum__qis__s__adj(%Qubit*)
1504
1505declare void @__quantum__qis__z__body(%Qubit*)
1506
1507attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1508
1509!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1510
1511!0 = !{i32 1, !"qir_major_version", i32 1}
1512!1 = !{i32 7, !"qir_minor_version", i32 0}
1513!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1514!3 = !{i32 1, !"dynamic_result_management", i1 false}
1515!4 = !{i32 5, !"int_computations", !5}
1516!5 = !{!"i64"}
1517!6 = !{i32 5, !"float_computations", !7}
1518!7 = !{!"double"}
1519""",
1520 )
1521
1522
1523@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1524def test_rz_2pi_decomposition() -> None:
1525 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1526 qir = qsharp.compile(
1527 """
1528 {
1529 use q = Qubit();
1530 Rz(2.0 * Std.Math.PI(), q);
1531 }
1532 """
1533 )
1534
1535 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1536 DecomposeRzAnglesToCliffordGates().run(module)
1537 transformed_qir = str(module)
1538
1539 assert_expected_inline(
1540 transformed_qir,
1541 """\
1542
1543%Qubit = type opaque
1544
1545@empty_tag = internal constant [1 x i8] zeroinitializer
1546
1547define i64 @ENTRYPOINT__main() #0 {
1548block_0:
1549 call void @__quantum__rt__initialize(i8* null)
1550 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1551 ret i64 0
1552}
1553
1554declare void @__quantum__rt__initialize(i8*)
1555
1556declare void @__quantum__qis__rz__body(double, %Qubit*)
1557
1558declare void @__quantum__rt__tuple_record_output(i64, i8*)
1559
1560declare void @__quantum__qis__s__body(%Qubit*)
1561
1562declare void @__quantum__qis__s__adj(%Qubit*)
1563
1564declare void @__quantum__qis__z__body(%Qubit*)
1565
1566attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1567
1568!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1569
1570!0 = !{i32 1, !"qir_major_version", i32 1}
1571!1 = !{i32 7, !"qir_minor_version", i32 0}
1572!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1573!3 = !{i32 1, !"dynamic_result_management", i1 false}
1574!4 = !{i32 5, !"int_computations", !5}
1575!5 = !{!"i64"}
1576!6 = !{i32 5, !"float_computations", !7}
1577!7 = !{!"double"}
1578""",
1579 )
1580
1581
1582@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1583def test_rz_neg_2pi_decomposition() -> None:
1584 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1585 qir = qsharp.compile(
1586 """
1587 {
1588 use q = Qubit();
1589 Rz(-2.0 * Std.Math.PI(), q);
1590 }
1591 """
1592 )
1593
1594 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1595 DecomposeRzAnglesToCliffordGates().run(module)
1596 transformed_qir = str(module)
1597
1598 assert_expected_inline(
1599 transformed_qir,
1600 """\
1601
1602%Qubit = type opaque
1603
1604@empty_tag = internal constant [1 x i8] zeroinitializer
1605
1606define i64 @ENTRYPOINT__main() #0 {
1607block_0:
1608 call void @__quantum__rt__initialize(i8* null)
1609 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1610 ret i64 0
1611}
1612
1613declare void @__quantum__rt__initialize(i8*)
1614
1615declare void @__quantum__qis__rz__body(double, %Qubit*)
1616
1617declare void @__quantum__rt__tuple_record_output(i64, i8*)
1618
1619declare void @__quantum__qis__s__body(%Qubit*)
1620
1621declare void @__quantum__qis__s__adj(%Qubit*)
1622
1623declare void @__quantum__qis__z__body(%Qubit*)
1624
1625attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1626
1627!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1628
1629!0 = !{i32 1, !"qir_major_version", i32 1}
1630!1 = !{i32 7, !"qir_minor_version", i32 0}
1631!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1632!3 = !{i32 1, !"dynamic_result_management", i1 false}
1633!4 = !{i32 5, !"int_computations", !5}
1634!5 = !{!"i64"}
1635!6 = !{i32 5, !"float_computations", !7}
1636!7 = !{!"double"}
1637""",
1638 )
1639
1640
1641@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1642def test_rz_non_clifford_decomposition_fails() -> None:
1643 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1644 qir = qsharp.compile(
1645 """
1646 {
1647 use q = Qubit();
1648 Rz(0.1, q);
1649 }
1650 """
1651 )
1652
1653 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1654
1655 with pytest.raises(ValueError) as ex:
1656 DecomposeRzAnglesToCliffordGates().run(module)
1657
1658 assert_expected_inline(
1659 str(ex),
1660 """<ExceptionInfo ValueError('Angle 0.1 used in RZ is not a Clifford compatible rotation angle') tblen=9>""",
1661 )
1662
1663
1664@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1665def test_reset_replaced_by_mresetz() -> None:
1666 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1667 qir = qsharp.compile(
1668 """
1669 {
1670 use q = Qubit();
1671 Reset(q);
1672 }
1673 """
1674 )
1675
1676 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1677 ReplaceResetWithMResetZ().run(module)
1678 transformed_qir = str(module)
1679
1680 assert_expected_inline(
1681 transformed_qir,
1682 """\
1683
1684%Qubit = type opaque
1685%Result = type opaque
1686
1687@empty_tag = internal constant [1 x i8] zeroinitializer
1688
1689define i64 @ENTRYPOINT__main() #0 {
1690block_0:
1691 call void @__quantum__rt__initialize(i8* null)
1692 call void @__quantum__qis__mresetz__body(%Qubit* null, %Result* null)
1693 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1694 ret i64 0
1695}
1696
1697declare void @__quantum__rt__initialize(i8*)
1698
1699declare void @__quantum__qis__reset__body(%Qubit*) #1
1700
1701declare void @__quantum__rt__tuple_record_output(i64, i8*)
1702
1703declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
1704
1705attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1706attributes #1 = { "irreversible" }
1707
1708!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1709
1710!0 = !{i32 1, !"qir_major_version", i32 1}
1711!1 = !{i32 7, !"qir_minor_version", i32 0}
1712!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1713!3 = !{i32 1, !"dynamic_result_management", i1 false}
1714!4 = !{i32 5, !"int_computations", !5}
1715!5 = !{!"i64"}
1716!6 = !{i32 5, !"float_computations", !7}
1717!7 = !{!"double"}
1718""",
1719 )
1720