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_optimize.py

2080lines · 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._optimize import (
9 PruneUnusedFunctions,
10 OptimizeSingleQubitGates,
11)
12
13try:
14 import pyqir
15
16 PYQIR_AVAILABLE = True
17except ImportError:
18 PYQIR_AVAILABLE = False
19
20SKIP_REASON = "PyQIR is not available"
21
22
23@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
24def test_prune_init_handled_by_unused_functions_pass() -> None:
25 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
26 qir = qsharp.compile(
27 """
28 {
29 use q = Qubit();
30 X(q);
31 }
32 """
33 )
34
35 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
36 PruneUnusedFunctions().run(module)
37
38 assert_expected_inline(
39 str(module),
40 """\
41
42%Qubit = type opaque
43
44@empty_tag = internal constant [1 x i8] zeroinitializer
45
46define i64 @ENTRYPOINT__main() #0 {
47block_0:
48 call void @__quantum__qis__x__body(%Qubit* null)
49 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
50 ret i64 0
51}
52
53declare void @__quantum__qis__x__body(%Qubit*)
54
55declare void @__quantum__rt__tuple_record_output(i64, i8*)
56
57attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
58
59!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
60
61!0 = !{i32 1, !"qir_major_version", i32 1}
62!1 = !{i32 7, !"qir_minor_version", i32 0}
63!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
64!3 = !{i32 1, !"dynamic_result_management", i1 false}
65!4 = !{i32 5, !"int_computations", !5}
66!5 = !{!"i64"}
67!6 = !{i32 5, !"float_computations", !7}
68!7 = !{!"double"}
69""",
70 )
71
72
73@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
74def test_optimize_removes_h_h_gates() -> None:
75 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
76 qir = qsharp.compile(
77 """
78 {
79 use q = Qubit();
80 H(q);
81 H(q);
82 X(q);
83 H(q);
84 H(q);
85 }
86 """
87 )
88
89 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
90 OptimizeSingleQubitGates().run(module)
91
92 assert_expected_inline(
93 str(module),
94 """\
95
96%Qubit = type opaque
97%Result = type opaque
98
99@empty_tag = internal constant [1 x i8] zeroinitializer
100
101define i64 @ENTRYPOINT__main() #0 {
102block_0:
103 call void @__quantum__rt__initialize(i8* null)
104 call void @__quantum__qis__x__body(%Qubit* null)
105 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
106 ret i64 0
107}
108
109declare void @__quantum__rt__initialize(i8*)
110
111declare void @__quantum__qis__h__body(%Qubit*)
112
113declare void @__quantum__qis__x__body(%Qubit*)
114
115declare void @__quantum__rt__tuple_record_output(i64, i8*)
116
117declare void @__quantum__qis__sx__body(%Qubit*)
118
119declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
120
121attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
122
123!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
124
125!0 = !{i32 1, !"qir_major_version", i32 1}
126!1 = !{i32 7, !"qir_minor_version", i32 0}
127!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
128!3 = !{i32 1, !"dynamic_result_management", i1 false}
129!4 = !{i32 5, !"int_computations", !5}
130!5 = !{!"i64"}
131!6 = !{i32 5, !"float_computations", !7}
132!7 = !{!"double"}
133""",
134 )
135
136
137@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
138def test_optimize_removes_s_sadj_gates() -> None:
139 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
140 qir = qsharp.compile(
141 """
142 {
143 use q = Qubit();
144 S(q);
145 Adjoint S(q);
146 X(q);
147 Adjoint S(q);
148 S(q);
149 }
150 """
151 )
152
153 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
154 OptimizeSingleQubitGates().run(module)
155
156 assert_expected_inline(
157 str(module),
158 """\
159
160%Qubit = type opaque
161%Result = type opaque
162
163@empty_tag = internal constant [1 x i8] zeroinitializer
164
165define i64 @ENTRYPOINT__main() #0 {
166block_0:
167 call void @__quantum__rt__initialize(i8* null)
168 call void @__quantum__qis__x__body(%Qubit* null)
169 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
170 ret i64 0
171}
172
173declare void @__quantum__rt__initialize(i8*)
174
175declare void @__quantum__qis__s__body(%Qubit*)
176
177declare void @__quantum__qis__s__adj(%Qubit*)
178
179declare void @__quantum__qis__x__body(%Qubit*)
180
181declare void @__quantum__rt__tuple_record_output(i64, i8*)
182
183declare void @__quantum__qis__sx__body(%Qubit*)
184
185declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
186
187attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
188
189!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
190
191!0 = !{i32 1, !"qir_major_version", i32 1}
192!1 = !{i32 7, !"qir_minor_version", i32 0}
193!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
194!3 = !{i32 1, !"dynamic_result_management", i1 false}
195!4 = !{i32 5, !"int_computations", !5}
196!5 = !{!"i64"}
197!6 = !{i32 5, !"float_computations", !7}
198!7 = !{!"double"}
199""",
200 )
201
202
203@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
204def test_optimize_removes_t_tadj_gates() -> None:
205 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
206 qir = qsharp.compile(
207 """
208 {
209 use q = Qubit();
210 T(q);
211 Adjoint T(q);
212 X(q);
213 Adjoint T(q);
214 T(q);
215 }
216 """
217 )
218
219 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
220 OptimizeSingleQubitGates().run(module)
221
222 assert_expected_inline(
223 str(module),
224 """\
225
226%Qubit = type opaque
227%Result = type opaque
228
229@empty_tag = internal constant [1 x i8] zeroinitializer
230
231define i64 @ENTRYPOINT__main() #0 {
232block_0:
233 call void @__quantum__rt__initialize(i8* null)
234 call void @__quantum__qis__x__body(%Qubit* null)
235 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
236 ret i64 0
237}
238
239declare void @__quantum__rt__initialize(i8*)
240
241declare void @__quantum__qis__t__body(%Qubit*)
242
243declare void @__quantum__qis__t__adj(%Qubit*)
244
245declare void @__quantum__qis__x__body(%Qubit*)
246
247declare void @__quantum__rt__tuple_record_output(i64, i8*)
248
249declare void @__quantum__qis__sx__body(%Qubit*)
250
251declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
252
253attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
254
255!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
256
257!0 = !{i32 1, !"qir_major_version", i32 1}
258!1 = !{i32 7, !"qir_minor_version", i32 0}
259!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
260!3 = !{i32 1, !"dynamic_result_management", i1 false}
261!4 = !{i32 5, !"int_computations", !5}
262!5 = !{!"i64"}
263!6 = !{i32 5, !"float_computations", !7}
264!7 = !{!"double"}
265""",
266 )
267
268
269@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
270def test_optimize_combines_h_s_h_gates() -> None:
271 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
272 qir = qsharp.compile(
273 """
274 {
275 use q = Qubit();
276 H(q);
277 S(q);
278 H(q);
279 }
280 """
281 )
282
283 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
284 OptimizeSingleQubitGates().run(module)
285
286 assert_expected_inline(
287 str(module),
288 """\
289
290%Qubit = type opaque
291%Result = type opaque
292
293@empty_tag = internal constant [1 x i8] zeroinitializer
294
295define i64 @ENTRYPOINT__main() #0 {
296block_0:
297 call void @__quantum__rt__initialize(i8* null)
298 call void @__quantum__qis__sx__body(%Qubit* null)
299 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
300 ret i64 0
301}
302
303declare void @__quantum__rt__initialize(i8*)
304
305declare void @__quantum__qis__h__body(%Qubit*)
306
307declare void @__quantum__qis__s__body(%Qubit*)
308
309declare void @__quantum__rt__tuple_record_output(i64, i8*)
310
311declare void @__quantum__qis__sx__body(%Qubit*)
312
313declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
314
315attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
316
317!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
318
319!0 = !{i32 1, !"qir_major_version", i32 1}
320!1 = !{i32 7, !"qir_minor_version", i32 0}
321!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
322!3 = !{i32 1, !"dynamic_result_management", i1 false}
323!4 = !{i32 5, !"int_computations", !5}
324!5 = !{!"i64"}
325!6 = !{i32 5, !"float_computations", !7}
326!7 = !{!"double"}
327""",
328 )
329
330
331@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
332def test_optimize_removes_x_x_gates() -> None:
333 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
334 qir = qsharp.compile(
335 """
336 {
337 use q = Qubit();
338 X(q);
339 X(q);
340 Z(q);
341 X(q);
342 X(q);
343 }
344 """
345 )
346
347 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
348 OptimizeSingleQubitGates().run(module)
349
350 assert_expected_inline(
351 str(module),
352 """\
353
354%Qubit = type opaque
355%Result = type opaque
356
357@empty_tag = internal constant [1 x i8] zeroinitializer
358
359define i64 @ENTRYPOINT__main() #0 {
360block_0:
361 call void @__quantum__rt__initialize(i8* null)
362 call void @__quantum__qis__z__body(%Qubit* null)
363 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
364 ret i64 0
365}
366
367declare void @__quantum__rt__initialize(i8*)
368
369declare void @__quantum__qis__x__body(%Qubit*)
370
371declare void @__quantum__qis__z__body(%Qubit*)
372
373declare void @__quantum__rt__tuple_record_output(i64, i8*)
374
375declare void @__quantum__qis__sx__body(%Qubit*)
376
377declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
378
379attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
380
381!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
382
383!0 = !{i32 1, !"qir_major_version", i32 1}
384!1 = !{i32 7, !"qir_minor_version", i32 0}
385!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
386!3 = !{i32 1, !"dynamic_result_management", i1 false}
387!4 = !{i32 5, !"int_computations", !5}
388!5 = !{!"i64"}
389!6 = !{i32 5, !"float_computations", !7}
390!7 = !{!"double"}
391""",
392 )
393
394
395@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
396def test_optimize_removes_y_y_gates() -> None:
397 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
398 qir = qsharp.compile(
399 """
400 {
401 use q = Qubit();
402 Y(q);
403 Y(q);
404 Z(q);
405 Y(q);
406 Y(q);
407 }
408 """
409 )
410
411 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
412 OptimizeSingleQubitGates().run(module)
413
414 assert_expected_inline(
415 str(module),
416 """\
417
418%Qubit = type opaque
419%Result = type opaque
420
421@empty_tag = internal constant [1 x i8] zeroinitializer
422
423define i64 @ENTRYPOINT__main() #0 {
424block_0:
425 call void @__quantum__rt__initialize(i8* null)
426 call void @__quantum__qis__z__body(%Qubit* null)
427 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
428 ret i64 0
429}
430
431declare void @__quantum__rt__initialize(i8*)
432
433declare void @__quantum__qis__y__body(%Qubit*)
434
435declare void @__quantum__qis__z__body(%Qubit*)
436
437declare void @__quantum__rt__tuple_record_output(i64, i8*)
438
439declare void @__quantum__qis__sx__body(%Qubit*)
440
441declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
442
443attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
444
445!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
446
447!0 = !{i32 1, !"qir_major_version", i32 1}
448!1 = !{i32 7, !"qir_minor_version", i32 0}
449!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
450!3 = !{i32 1, !"dynamic_result_management", i1 false}
451!4 = !{i32 5, !"int_computations", !5}
452!5 = !{!"i64"}
453!6 = !{i32 5, !"float_computations", !7}
454!7 = !{!"double"}
455""",
456 )
457
458
459@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
460def test_optimize_removes_z_z_gates() -> None:
461 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
462 qir = qsharp.compile(
463 """
464 {
465 use q = Qubit();
466 Z(q);
467 Z(q);
468 X(q);
469 Z(q);
470 Z(q);
471 }
472 """
473 )
474
475 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
476 OptimizeSingleQubitGates().run(module)
477
478 assert_expected_inline(
479 str(module),
480 """\
481
482%Qubit = type opaque
483%Result = type opaque
484
485@empty_tag = internal constant [1 x i8] zeroinitializer
486
487define i64 @ENTRYPOINT__main() #0 {
488block_0:
489 call void @__quantum__rt__initialize(i8* null)
490 call void @__quantum__qis__x__body(%Qubit* null)
491 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
492 ret i64 0
493}
494
495declare void @__quantum__rt__initialize(i8*)
496
497declare void @__quantum__qis__z__body(%Qubit*)
498
499declare void @__quantum__qis__x__body(%Qubit*)
500
501declare void @__quantum__rt__tuple_record_output(i64, i8*)
502
503declare void @__quantum__qis__sx__body(%Qubit*)
504
505declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
506
507attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
508
509!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
510
511!0 = !{i32 1, !"qir_major_version", i32 1}
512!1 = !{i32 7, !"qir_minor_version", i32 0}
513!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
514!3 = !{i32 1, !"dynamic_result_management", i1 false}
515!4 = !{i32 5, !"int_computations", !5}
516!5 = !{!"i64"}
517!6 = !{i32 5, !"float_computations", !7}
518!7 = !{!"double"}
519""",
520 )
521
522
523@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
524def test_optimize_combines_rx_rotation_angles() -> None:
525 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
526 qir = qsharp.compile(
527 """
528 {
529 import Std.Math.PI;
530 use q = Qubit();
531 Rx(PI() / 2.0, q);
532 Rx(PI() / 2.0, q);
533 X(q);
534 Rx(PI() / -2.0, q);
535 Rx(PI() / 2.0, q);
536 Y(q);
537 Rx(PI(), q);
538 Rx(PI(), q);
539 }
540 """
541 )
542
543 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
544 OptimizeSingleQubitGates().run(module)
545
546 assert_expected_inline(
547 str(module),
548 """\
549
550%Qubit = type opaque
551%Result = type opaque
552
553@empty_tag = internal constant [1 x i8] zeroinitializer
554
555define i64 @ENTRYPOINT__main() #0 {
556block_0:
557 call void @__quantum__rt__initialize(i8* null)
558 call void @__quantum__qis__rx__body(double 0x400921FB54442D18, %Qubit* null)
559 call void @__quantum__qis__x__body(%Qubit* null)
560 call void @__quantum__qis__y__body(%Qubit* null)
561 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
562 ret i64 0
563}
564
565declare void @__quantum__rt__initialize(i8*)
566
567declare void @__quantum__qis__rx__body(double, %Qubit*)
568
569declare void @__quantum__qis__x__body(%Qubit*)
570
571declare void @__quantum__qis__y__body(%Qubit*)
572
573declare void @__quantum__rt__tuple_record_output(i64, i8*)
574
575declare void @__quantum__qis__sx__body(%Qubit*)
576
577declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
578
579attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
580
581!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
582
583!0 = !{i32 1, !"qir_major_version", i32 1}
584!1 = !{i32 7, !"qir_minor_version", i32 0}
585!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
586!3 = !{i32 1, !"dynamic_result_management", i1 false}
587!4 = !{i32 5, !"int_computations", !5}
588!5 = !{!"i64"}
589!6 = !{i32 5, !"float_computations", !7}
590!7 = !{!"double"}
591""",
592 )
593
594
595@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
596def test_optimize_combines_ry_rotation_angles() -> None:
597 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
598 qir = qsharp.compile(
599 """
600 {
601 import Std.Math.PI;
602 use q = Qubit();
603 Ry(PI() / 2.0, q);
604 Ry(PI() / 2.0, q);
605 X(q);
606 Ry(PI() / -2.0, q);
607 Ry(PI() / 2.0, q);
608 Y(q);
609 Ry(PI(), q);
610 Ry(PI(), q);
611 }
612 """
613 )
614
615 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
616 OptimizeSingleQubitGates().run(module)
617
618 assert_expected_inline(
619 str(module),
620 """\
621
622%Qubit = type opaque
623%Result = type opaque
624
625@empty_tag = internal constant [1 x i8] zeroinitializer
626
627define i64 @ENTRYPOINT__main() #0 {
628block_0:
629 call void @__quantum__rt__initialize(i8* null)
630 call void @__quantum__qis__ry__body(double 0x400921FB54442D18, %Qubit* null)
631 call void @__quantum__qis__x__body(%Qubit* null)
632 call void @__quantum__qis__y__body(%Qubit* null)
633 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
634 ret i64 0
635}
636
637declare void @__quantum__rt__initialize(i8*)
638
639declare void @__quantum__qis__ry__body(double, %Qubit*)
640
641declare void @__quantum__qis__x__body(%Qubit*)
642
643declare void @__quantum__qis__y__body(%Qubit*)
644
645declare void @__quantum__rt__tuple_record_output(i64, i8*)
646
647declare void @__quantum__qis__sx__body(%Qubit*)
648
649declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
650
651attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
652
653!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
654
655!0 = !{i32 1, !"qir_major_version", i32 1}
656!1 = !{i32 7, !"qir_minor_version", i32 0}
657!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
658!3 = !{i32 1, !"dynamic_result_management", i1 false}
659!4 = !{i32 5, !"int_computations", !5}
660!5 = !{!"i64"}
661!6 = !{i32 5, !"float_computations", !7}
662!7 = !{!"double"}
663""",
664 )
665
666
667@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
668def test_optimize_combines_rz_rotation_angles() -> None:
669 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
670 qir = qsharp.compile(
671 """
672 {
673 import Std.Math.PI;
674 use q = Qubit();
675 Rz(PI() / 2.0, q);
676 Rz(PI() / 2.0, q);
677 X(q);
678 Rz(PI() / -2.0, q);
679 Rz(PI() / 2.0, q);
680 Y(q);
681 Rz(PI(), q);
682 Rz(PI(), q);
683 }
684 """
685 )
686
687 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
688 OptimizeSingleQubitGates().run(module)
689
690 assert_expected_inline(
691 str(module),
692 """\
693
694%Qubit = type opaque
695%Result = type opaque
696
697@empty_tag = internal constant [1 x i8] zeroinitializer
698
699define i64 @ENTRYPOINT__main() #0 {
700block_0:
701 call void @__quantum__rt__initialize(i8* null)
702 call void @__quantum__qis__rz__body(double 0x400921FB54442D18, %Qubit* null)
703 call void @__quantum__qis__x__body(%Qubit* null)
704 call void @__quantum__qis__y__body(%Qubit* null)
705 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
706 ret i64 0
707}
708
709declare void @__quantum__rt__initialize(i8*)
710
711declare void @__quantum__qis__rz__body(double, %Qubit*)
712
713declare void @__quantum__qis__x__body(%Qubit*)
714
715declare void @__quantum__qis__y__body(%Qubit*)
716
717declare void @__quantum__rt__tuple_record_output(i64, i8*)
718
719declare void @__quantum__qis__sx__body(%Qubit*)
720
721declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
722
723attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
724
725!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
726
727!0 = !{i32 1, !"qir_major_version", i32 1}
728!1 = !{i32 7, !"qir_minor_version", i32 0}
729!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
730!3 = !{i32 1, !"dynamic_result_management", i1 false}
731!4 = !{i32 5, !"int_computations", !5}
732!5 = !{!"i64"}
733!6 = !{i32 5, !"float_computations", !7}
734!7 = !{!"double"}
735""",
736 )
737
738
739@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
740def test_optimize_removes_adjoint_gates_after_removing_other_adjoint_gates() -> None:
741 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
742 qir = qsharp.compile(
743 """
744 {
745 use q = Qubit();
746 S(q);
747 X(q);
748 H(q);
749
750 H(q);
751 X(q);
752 Adjoint S(q);
753 }
754 """
755 )
756
757 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
758 OptimizeSingleQubitGates().run(module)
759
760 assert_expected_inline(
761 str(module),
762 """\
763
764%Qubit = type opaque
765%Result = type opaque
766
767@empty_tag = internal constant [1 x i8] zeroinitializer
768
769define i64 @ENTRYPOINT__main() #0 {
770block_0:
771 call void @__quantum__rt__initialize(i8* null)
772 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
773 ret i64 0
774}
775
776declare void @__quantum__rt__initialize(i8*)
777
778declare void @__quantum__qis__s__body(%Qubit*)
779
780declare void @__quantum__qis__x__body(%Qubit*)
781
782declare void @__quantum__qis__h__body(%Qubit*)
783
784declare void @__quantum__qis__s__adj(%Qubit*)
785
786declare void @__quantum__rt__tuple_record_output(i64, i8*)
787
788declare void @__quantum__qis__sx__body(%Qubit*)
789
790declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
791
792attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
793
794!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
795
796!0 = !{i32 1, !"qir_major_version", i32 1}
797!1 = !{i32 7, !"qir_minor_version", i32 0}
798!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
799!3 = !{i32 1, !"dynamic_result_management", i1 false}
800!4 = !{i32 5, !"int_computations", !5}
801!5 = !{!"i64"}
802!6 = !{i32 5, !"float_computations", !7}
803!7 = !{!"double"}
804""",
805 )
806
807
808@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
809def test_optimize_leaves_gates_with_intervening_gates() -> None:
810 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
811 qir = qsharp.compile(
812 """
813 {
814 use q = Qubit();
815 H(q);
816 S(q);
817 Adjoint S(q);
818 X(q);
819 H(q);
820 }
821 """
822 )
823
824 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
825 OptimizeSingleQubitGates().run(module)
826
827 assert_expected_inline(
828 str(module),
829 """\
830
831%Qubit = type opaque
832%Result = 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__h__body(%Qubit* null)
840 call void @__quantum__qis__x__body(%Qubit* null)
841 call void @__quantum__qis__h__body(%Qubit* null)
842 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
843 ret i64 0
844}
845
846declare void @__quantum__rt__initialize(i8*)
847
848declare void @__quantum__qis__h__body(%Qubit*)
849
850declare void @__quantum__qis__s__body(%Qubit*)
851
852declare void @__quantum__qis__s__adj(%Qubit*)
853
854declare void @__quantum__qis__x__body(%Qubit*)
855
856declare void @__quantum__rt__tuple_record_output(i64, i8*)
857
858declare void @__quantum__qis__sx__body(%Qubit*)
859
860declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
861
862attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
863
864!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
865
866!0 = !{i32 1, !"qir_major_version", i32 1}
867!1 = !{i32 7, !"qir_minor_version", i32 0}
868!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
869!3 = !{i32 1, !"dynamic_result_management", i1 false}
870!4 = !{i32 5, !"int_computations", !5}
871!5 = !{!"i64"}
872!6 = !{i32 5, !"float_computations", !7}
873!7 = !{!"double"}
874""",
875 )
876
877
878@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
879def test_optimize_treats_rxx_as_barrier() -> None:
880 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
881 qir = qsharp.compile(
882 """
883 {
884 use q1 = Qubit();
885 use q2 = Qubit();
886 X(q1);
887 Rxx(0.5, q1, q2);
888 X(q1);
889 }
890 """
891 )
892
893 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
894 OptimizeSingleQubitGates().run(module)
895
896 assert_expected_inline(
897 str(module),
898 """\
899
900%Qubit = type opaque
901%Result = type opaque
902
903@empty_tag = internal constant [1 x i8] zeroinitializer
904
905define i64 @ENTRYPOINT__main() #0 {
906block_0:
907 call void @__quantum__rt__initialize(i8* null)
908 call void @__quantum__qis__x__body(%Qubit* null)
909 call void @__quantum__qis__rxx__body(double 5.000000e-01, %Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
910 call void @__quantum__qis__x__body(%Qubit* null)
911 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
912 ret i64 0
913}
914
915declare void @__quantum__rt__initialize(i8*)
916
917declare void @__quantum__qis__x__body(%Qubit*)
918
919declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
920
921declare void @__quantum__rt__tuple_record_output(i64, i8*)
922
923declare void @__quantum__qis__sx__body(%Qubit*)
924
925declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
926
927attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
928
929!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
930
931!0 = !{i32 1, !"qir_major_version", i32 1}
932!1 = !{i32 7, !"qir_minor_version", i32 0}
933!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
934!3 = !{i32 1, !"dynamic_result_management", i1 false}
935!4 = !{i32 5, !"int_computations", !5}
936!5 = !{!"i64"}
937!6 = !{i32 5, !"float_computations", !7}
938!7 = !{!"double"}
939""",
940 )
941
942
943@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
944def test_optimize_treats_ryy_as_barrier() -> None:
945 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
946 qir = qsharp.compile(
947 """
948 {
949 use q1 = Qubit();
950 use q2 = Qubit();
951 X(q1);
952 Ryy(0.5, q1, q2);
953 X(q1);
954 }
955 """
956 )
957
958 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
959 OptimizeSingleQubitGates().run(module)
960
961 assert_expected_inline(
962 str(module),
963 """\
964
965%Qubit = type opaque
966%Result = type opaque
967
968@empty_tag = internal constant [1 x i8] zeroinitializer
969
970define i64 @ENTRYPOINT__main() #0 {
971block_0:
972 call void @__quantum__rt__initialize(i8* null)
973 call void @__quantum__qis__x__body(%Qubit* null)
974 call void @__quantum__qis__ryy__body(double 5.000000e-01, %Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
975 call void @__quantum__qis__x__body(%Qubit* null)
976 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
977 ret i64 0
978}
979
980declare void @__quantum__rt__initialize(i8*)
981
982declare void @__quantum__qis__x__body(%Qubit*)
983
984declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
985
986declare void @__quantum__rt__tuple_record_output(i64, i8*)
987
988declare void @__quantum__qis__sx__body(%Qubit*)
989
990declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
991
992attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
993
994!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
995
996!0 = !{i32 1, !"qir_major_version", i32 1}
997!1 = !{i32 7, !"qir_minor_version", i32 0}
998!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
999!3 = !{i32 1, !"dynamic_result_management", i1 false}
1000!4 = !{i32 5, !"int_computations", !5}
1001!5 = !{!"i64"}
1002!6 = !{i32 5, !"float_computations", !7}
1003!7 = !{!"double"}
1004""",
1005 )
1006
1007
1008@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1009def test_optimize_treats_rzz_as_barrier() -> None:
1010 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1011 qir = qsharp.compile(
1012 """
1013 {
1014 use q1 = Qubit();
1015 use q2 = Qubit();
1016 X(q1);
1017 Rzz(0.5, q1, q2);
1018 X(q1);
1019 }
1020 """
1021 )
1022
1023 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1024 OptimizeSingleQubitGates().run(module)
1025
1026 assert_expected_inline(
1027 str(module),
1028 """\
1029
1030%Qubit = type opaque
1031%Result = type opaque
1032
1033@empty_tag = internal constant [1 x i8] zeroinitializer
1034
1035define i64 @ENTRYPOINT__main() #0 {
1036block_0:
1037 call void @__quantum__rt__initialize(i8* null)
1038 call void @__quantum__qis__x__body(%Qubit* null)
1039 call void @__quantum__qis__rzz__body(double 5.000000e-01, %Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
1040 call void @__quantum__qis__x__body(%Qubit* null)
1041 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1042 ret i64 0
1043}
1044
1045declare void @__quantum__rt__initialize(i8*)
1046
1047declare void @__quantum__qis__x__body(%Qubit*)
1048
1049declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
1050
1051declare void @__quantum__rt__tuple_record_output(i64, i8*)
1052
1053declare void @__quantum__qis__sx__body(%Qubit*)
1054
1055declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
1056
1057attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
1058
1059!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1060
1061!0 = !{i32 1, !"qir_major_version", i32 1}
1062!1 = !{i32 7, !"qir_minor_version", i32 0}
1063!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1064!3 = !{i32 1, !"dynamic_result_management", i1 false}
1065!4 = !{i32 5, !"int_computations", !5}
1066!5 = !{!"i64"}
1067!6 = !{i32 5, !"float_computations", !7}
1068!7 = !{!"double"}
1069""",
1070 )
1071
1072
1073@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1074def test_optimize_treats_ccx_as_barrier() -> None:
1075 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1076 qir = qsharp.compile(
1077 """
1078 {
1079 use q1 = Qubit();
1080 use q2 = Qubit();
1081 use q3 = Qubit();
1082 X(q1);
1083 CCNOT(q1, q2, q3);
1084 X(q1);
1085 }
1086 """
1087 )
1088
1089 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1090 OptimizeSingleQubitGates().run(module)
1091
1092 assert_expected_inline(
1093 str(module),
1094 """\
1095
1096%Qubit = type opaque
1097%Result = type opaque
1098
1099@empty_tag = internal constant [1 x i8] zeroinitializer
1100
1101define i64 @ENTRYPOINT__main() #0 {
1102block_0:
1103 call void @__quantum__rt__initialize(i8* null)
1104 call void @__quantum__qis__x__body(%Qubit* null)
1105 call void @__quantum__qis__ccx__body(%Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
1106 call void @__quantum__qis__x__body(%Qubit* null)
1107 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1108 ret i64 0
1109}
1110
1111declare void @__quantum__rt__initialize(i8*)
1112
1113declare void @__quantum__qis__x__body(%Qubit*)
1114
1115declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
1116
1117declare void @__quantum__rt__tuple_record_output(i64, i8*)
1118
1119declare void @__quantum__qis__sx__body(%Qubit*)
1120
1121declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
1122
1123attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="3" "required_num_results"="0" }
1124
1125!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1126
1127!0 = !{i32 1, !"qir_major_version", i32 1}
1128!1 = !{i32 7, !"qir_minor_version", i32 0}
1129!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1130!3 = !{i32 1, !"dynamic_result_management", i1 false}
1131!4 = !{i32 5, !"int_computations", !5}
1132!5 = !{!"i64"}
1133!6 = !{i32 5, !"float_computations", !7}
1134!7 = !{!"double"}
1135""",
1136 )
1137
1138
1139@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1140def test_optimize_treats_cx_as_barrier() -> None:
1141 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1142 qir = qsharp.compile(
1143 """
1144 {
1145 use q1 = Qubit();
1146 use q2 = Qubit();
1147 X(q1);
1148 CX(q1, q2);
1149 X(q1);
1150 }
1151 """
1152 )
1153
1154 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1155 OptimizeSingleQubitGates().run(module)
1156
1157 assert_expected_inline(
1158 str(module),
1159 """\
1160
1161%Qubit = type opaque
1162%Result = type opaque
1163
1164@empty_tag = internal constant [1 x i8] zeroinitializer
1165
1166define i64 @ENTRYPOINT__main() #0 {
1167block_0:
1168 call void @__quantum__rt__initialize(i8* null)
1169 call void @__quantum__qis__x__body(%Qubit* null)
1170 call void @__quantum__qis__cx__body(%Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
1171 call void @__quantum__qis__x__body(%Qubit* null)
1172 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1173 ret i64 0
1174}
1175
1176declare void @__quantum__rt__initialize(i8*)
1177
1178declare void @__quantum__qis__x__body(%Qubit*)
1179
1180declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
1181
1182declare void @__quantum__rt__tuple_record_output(i64, i8*)
1183
1184declare void @__quantum__qis__sx__body(%Qubit*)
1185
1186declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
1187
1188attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
1189
1190!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1191
1192!0 = !{i32 1, !"qir_major_version", i32 1}
1193!1 = !{i32 7, !"qir_minor_version", i32 0}
1194!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1195!3 = !{i32 1, !"dynamic_result_management", i1 false}
1196!4 = !{i32 5, !"int_computations", !5}
1197!5 = !{!"i64"}
1198!6 = !{i32 5, !"float_computations", !7}
1199!7 = !{!"double"}
1200""",
1201 )
1202
1203
1204@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1205def test_optimize_treats_cy_as_barrier() -> None:
1206 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1207 qir = qsharp.compile(
1208 """
1209 {
1210 use q1 = Qubit();
1211 use q2 = Qubit();
1212 X(q1);
1213 CY(q1, q2);
1214 X(q1);
1215 }
1216 """
1217 )
1218
1219 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1220 OptimizeSingleQubitGates().run(module)
1221
1222 assert_expected_inline(
1223 str(module),
1224 """\
1225
1226%Qubit = type opaque
1227%Result = type opaque
1228
1229@empty_tag = internal constant [1 x i8] zeroinitializer
1230
1231define i64 @ENTRYPOINT__main() #0 {
1232block_0:
1233 call void @__quantum__rt__initialize(i8* null)
1234 call void @__quantum__qis__x__body(%Qubit* null)
1235 call void @__quantum__qis__cy__body(%Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
1236 call void @__quantum__qis__x__body(%Qubit* null)
1237 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1238 ret i64 0
1239}
1240
1241declare void @__quantum__rt__initialize(i8*)
1242
1243declare void @__quantum__qis__x__body(%Qubit*)
1244
1245declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
1246
1247declare void @__quantum__rt__tuple_record_output(i64, i8*)
1248
1249declare void @__quantum__qis__sx__body(%Qubit*)
1250
1251declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
1252
1253attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
1254
1255!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1256
1257!0 = !{i32 1, !"qir_major_version", i32 1}
1258!1 = !{i32 7, !"qir_minor_version", i32 0}
1259!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1260!3 = !{i32 1, !"dynamic_result_management", i1 false}
1261!4 = !{i32 5, !"int_computations", !5}
1262!5 = !{!"i64"}
1263!6 = !{i32 5, !"float_computations", !7}
1264!7 = !{!"double"}
1265""",
1266 )
1267
1268
1269@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1270def test_optimize_treats_cz_as_barrier() -> None:
1271 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1272 qir = qsharp.compile(
1273 """
1274 {
1275 use q1 = Qubit();
1276 use q2 = Qubit();
1277 X(q1);
1278 CZ(q1, q2);
1279 X(q1);
1280 }
1281 """
1282 )
1283
1284 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1285 OptimizeSingleQubitGates().run(module)
1286
1287 assert_expected_inline(
1288 str(module),
1289 """\
1290
1291%Qubit = type opaque
1292%Result = type opaque
1293
1294@empty_tag = internal constant [1 x i8] zeroinitializer
1295
1296define i64 @ENTRYPOINT__main() #0 {
1297block_0:
1298 call void @__quantum__rt__initialize(i8* null)
1299 call void @__quantum__qis__x__body(%Qubit* null)
1300 call void @__quantum__qis__cz__body(%Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
1301 call void @__quantum__qis__x__body(%Qubit* null)
1302 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1303 ret i64 0
1304}
1305
1306declare void @__quantum__rt__initialize(i8*)
1307
1308declare void @__quantum__qis__x__body(%Qubit*)
1309
1310declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
1311
1312declare void @__quantum__rt__tuple_record_output(i64, i8*)
1313
1314declare void @__quantum__qis__sx__body(%Qubit*)
1315
1316declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
1317
1318attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
1319
1320!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1321
1322!0 = !{i32 1, !"qir_major_version", i32 1}
1323!1 = !{i32 7, !"qir_minor_version", i32 0}
1324!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1325!3 = !{i32 1, !"dynamic_result_management", i1 false}
1326!4 = !{i32 5, !"int_computations", !5}
1327!5 = !{!"i64"}
1328!6 = !{i32 5, !"float_computations", !7}
1329!7 = !{!"double"}
1330""",
1331 )
1332
1333
1334@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1335def test_optimize_treats_swap_as_barrier() -> None:
1336 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1337 qir = qsharp.compile(
1338 """
1339 {
1340 use q1 = Qubit();
1341 use q2 = Qubit();
1342 X(q1);
1343 SWAP(q1, q2);
1344 X(q1);
1345 }
1346 """
1347 )
1348
1349 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1350 OptimizeSingleQubitGates().run(module)
1351
1352 assert_expected_inline(
1353 str(module),
1354 """\
1355
1356%Qubit = type opaque
1357%Result = type opaque
1358
1359@empty_tag = internal constant [1 x i8] zeroinitializer
1360
1361define i64 @ENTRYPOINT__main() #0 {
1362block_0:
1363 call void @__quantum__rt__initialize(i8* null)
1364 call void @__quantum__qis__x__body(%Qubit* null)
1365 call void @__quantum__qis__swap__body(%Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
1366 call void @__quantum__qis__x__body(%Qubit* null)
1367 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1368 ret i64 0
1369}
1370
1371declare void @__quantum__rt__initialize(i8*)
1372
1373declare void @__quantum__qis__x__body(%Qubit*)
1374
1375declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
1376
1377declare void @__quantum__rt__tuple_record_output(i64, i8*)
1378
1379declare void @__quantum__qis__sx__body(%Qubit*)
1380
1381declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
1382
1383attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
1384
1385!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1386
1387!0 = !{i32 1, !"qir_major_version", i32 1}
1388!1 = !{i32 7, !"qir_minor_version", i32 0}
1389!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1390!3 = !{i32 1, !"dynamic_result_management", i1 false}
1391!4 = !{i32 5, !"int_computations", !5}
1392!5 = !{!"i64"}
1393!6 = !{i32 5, !"float_computations", !7}
1394!7 = !{!"double"}
1395""",
1396 )
1397
1398
1399@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1400def test_optimize_treats_m_as_barrier() -> None:
1401 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1402 qir = qsharp.compile(
1403 """
1404 {
1405 use q = Qubit();
1406 X(q);
1407 M(q);
1408 X(q);
1409 }
1410 """
1411 )
1412
1413 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1414 OptimizeSingleQubitGates().run(module)
1415
1416 assert_expected_inline(
1417 str(module),
1418 """\
1419
1420%Qubit = type opaque
1421%Result = type opaque
1422
1423@empty_tag = internal constant [1 x i8] zeroinitializer
1424
1425define i64 @ENTRYPOINT__main() #0 {
1426block_0:
1427 call void @__quantum__rt__initialize(i8* null)
1428 call void @__quantum__qis__x__body(%Qubit* null)
1429 call void @__quantum__qis__m__body(%Qubit* null, %Result* null)
1430 call void @__quantum__qis__x__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__x__body(%Qubit*)
1438
1439declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
1440
1441declare void @__quantum__rt__tuple_record_output(i64, i8*)
1442
1443declare void @__quantum__qis__sx__body(%Qubit*)
1444
1445declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
1446
1447attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="1" }
1448attributes #1 = { "irreversible" }
1449
1450!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1451
1452!0 = !{i32 1, !"qir_major_version", i32 1}
1453!1 = !{i32 7, !"qir_minor_version", i32 0}
1454!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1455!3 = !{i32 1, !"dynamic_result_management", i1 false}
1456!4 = !{i32 5, !"int_computations", !5}
1457!5 = !{!"i64"}
1458!6 = !{i32 5, !"float_computations", !7}
1459!7 = !{!"double"}
1460""",
1461 )
1462
1463
1464@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1465def test_optimize_treats_mresetz_as_barrier() -> None:
1466 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1467 qir = qsharp.compile(
1468 """
1469 {
1470 use q = Qubit();
1471 X(q);
1472 MResetZ(q);
1473 X(q);
1474 }
1475 """
1476 )
1477
1478 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1479 OptimizeSingleQubitGates().run(module)
1480
1481 assert_expected_inline(
1482 str(module),
1483 """\
1484
1485%Qubit = type opaque
1486%Result = type opaque
1487
1488@empty_tag = internal constant [1 x i8] zeroinitializer
1489
1490define i64 @ENTRYPOINT__main() #0 {
1491block_0:
1492 call void @__quantum__rt__initialize(i8* null)
1493 call void @__quantum__qis__x__body(%Qubit* null)
1494 call void @__quantum__qis__mresetz__body(%Qubit* null, %Result* null)
1495 call void @__quantum__qis__x__body(%Qubit* null)
1496 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1497 ret i64 0
1498}
1499
1500declare void @__quantum__rt__initialize(i8*)
1501
1502declare void @__quantum__qis__x__body(%Qubit*)
1503
1504declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*) #1
1505
1506declare void @__quantum__rt__tuple_record_output(i64, i8*)
1507
1508declare void @__quantum__qis__sx__body(%Qubit*)
1509
1510attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="1" }
1511attributes #1 = { "irreversible" }
1512
1513!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1514
1515!0 = !{i32 1, !"qir_major_version", i32 1}
1516!1 = !{i32 7, !"qir_minor_version", i32 0}
1517!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1518!3 = !{i32 1, !"dynamic_result_management", i1 false}
1519!4 = !{i32 5, !"int_computations", !5}
1520!5 = !{!"i64"}
1521!6 = !{i32 5, !"float_computations", !7}
1522!7 = !{!"double"}
1523""",
1524 )
1525
1526
1527@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1528def test_optimize_treats_reset_as_barrier() -> None:
1529 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1530 qir = qsharp.compile(
1531 """
1532 {
1533 use q = Qubit();
1534 X(q);
1535 Reset(q);
1536 X(q);
1537 }
1538 """
1539 )
1540
1541 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1542 OptimizeSingleQubitGates().run(module)
1543
1544 assert_expected_inline(
1545 str(module),
1546 """\
1547
1548%Qubit = type opaque
1549%Result = type opaque
1550
1551@empty_tag = internal constant [1 x i8] zeroinitializer
1552
1553define i64 @ENTRYPOINT__main() #0 {
1554block_0:
1555 call void @__quantum__rt__initialize(i8* null)
1556 call void @__quantum__qis__x__body(%Qubit* null)
1557 call void @__quantum__qis__reset__body(%Qubit* null)
1558 call void @__quantum__qis__x__body(%Qubit* null)
1559 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1560 ret i64 0
1561}
1562
1563declare void @__quantum__rt__initialize(i8*)
1564
1565declare void @__quantum__qis__x__body(%Qubit*)
1566
1567declare void @__quantum__qis__reset__body(%Qubit*) #1
1568
1569declare void @__quantum__rt__tuple_record_output(i64, i8*)
1570
1571declare void @__quantum__qis__sx__body(%Qubit*)
1572
1573declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
1574
1575attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
1576attributes #1 = { "irreversible" }
1577
1578!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1579
1580!0 = !{i32 1, !"qir_major_version", i32 1}
1581!1 = !{i32 7, !"qir_minor_version", i32 0}
1582!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1583!3 = !{i32 1, !"dynamic_result_management", i1 false}
1584!4 = !{i32 5, !"int_computations", !5}
1585!5 = !{!"i64"}
1586!6 = !{i32 5, !"float_computations", !7}
1587!7 = !{!"double"}
1588""",
1589 )
1590
1591
1592@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1593def test_optimize_works_within_blocks_not_across_blocks() -> None:
1594 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1595 qir = qsharp.compile(
1596 """
1597 {
1598 use q = Qubit();
1599 X(q);
1600 if MResetZ(q) == One {
1601 H(q);
1602 H(q);
1603 X(q);
1604 } else {
1605 X(q);
1606 Z(q);
1607 Z(q);
1608 Y(q);
1609 X(q);
1610 }
1611 X(q);
1612 }
1613 """
1614 )
1615
1616 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1617 OptimizeSingleQubitGates().run(module)
1618
1619 assert_expected_inline(
1620 str(module),
1621 """\
1622
1623%Qubit = type opaque
1624%Result = type opaque
1625
1626@empty_tag = internal constant [1 x i8] zeroinitializer
1627
1628define i64 @ENTRYPOINT__main() #0 {
1629block_0:
1630 call void @__quantum__rt__initialize(i8* null)
1631 call void @__quantum__qis__x__body(%Qubit* null)
1632 call void @__quantum__qis__mresetz__body(%Qubit* null, %Result* null)
1633 %var_0 = call i1 @__quantum__rt__read_result(%Result* null)
1634 br i1 %var_0, label %block_1, label %block_2
1635
1636block_1: ; preds = %block_0
1637 call void @__quantum__qis__x__body(%Qubit* null)
1638 br label %block_3
1639
1640block_2: ; preds = %block_0
1641 call void @__quantum__qis__x__body(%Qubit* null)
1642 call void @__quantum__qis__y__body(%Qubit* null)
1643 call void @__quantum__qis__x__body(%Qubit* null)
1644 br label %block_3
1645
1646block_3: ; preds = %block_2, %block_1
1647 call void @__quantum__qis__x__body(%Qubit* null)
1648 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1649 ret i64 0
1650}
1651
1652declare void @__quantum__rt__initialize(i8*)
1653
1654declare void @__quantum__qis__x__body(%Qubit*)
1655
1656declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*) #1
1657
1658declare i1 @__quantum__rt__read_result(%Result*)
1659
1660declare void @__quantum__qis__h__body(%Qubit*)
1661
1662declare void @__quantum__qis__z__body(%Qubit*)
1663
1664declare void @__quantum__qis__y__body(%Qubit*)
1665
1666declare void @__quantum__rt__tuple_record_output(i64, i8*)
1667
1668declare void @__quantum__qis__sx__body(%Qubit*)
1669
1670attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="1" }
1671attributes #1 = { "irreversible" }
1672
1673!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1674
1675!0 = !{i32 1, !"qir_major_version", i32 1}
1676!1 = !{i32 7, !"qir_minor_version", i32 0}
1677!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1678!3 = !{i32 1, !"dynamic_result_management", i1 false}
1679!4 = !{i32 5, !"int_computations", !5}
1680!5 = !{!"i64"}
1681!6 = !{i32 5, !"float_computations", !7}
1682!7 = !{!"double"}
1683""",
1684 )
1685
1686
1687@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1688def test_optimize_combines_m_and_reset_into_mresetz() -> None:
1689 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1690 qir = qsharp.compile(
1691 """
1692 {
1693 use q = Qubit();
1694 X(q);
1695 M(q);
1696 Reset(q);
1697 X(q);
1698 }
1699 """
1700 )
1701
1702 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1703 OptimizeSingleQubitGates().run(module)
1704
1705 assert_expected_inline(
1706 str(module),
1707 """\
1708
1709%Qubit = type opaque
1710%Result = type opaque
1711
1712@empty_tag = internal constant [1 x i8] zeroinitializer
1713
1714define i64 @ENTRYPOINT__main() #0 {
1715block_0:
1716 call void @__quantum__rt__initialize(i8* null)
1717 call void @__quantum__qis__x__body(%Qubit* null)
1718 call void @__quantum__qis__mresetz__body(%Qubit* null, %Result* null)
1719 call void @__quantum__qis__x__body(%Qubit* null)
1720 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1721 ret i64 0
1722}
1723
1724declare void @__quantum__rt__initialize(i8*)
1725
1726declare void @__quantum__qis__x__body(%Qubit*)
1727
1728declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
1729
1730declare void @__quantum__qis__reset__body(%Qubit*) #1
1731
1732declare void @__quantum__rt__tuple_record_output(i64, i8*)
1733
1734declare void @__quantum__qis__sx__body(%Qubit*)
1735
1736declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
1737
1738attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="1" }
1739attributes #1 = { "irreversible" }
1740
1741!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1742
1743!0 = !{i32 1, !"qir_major_version", i32 1}
1744!1 = !{i32 7, !"qir_minor_version", i32 0}
1745!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1746!3 = !{i32 1, !"dynamic_result_management", i1 false}
1747!4 = !{i32 5, !"int_computations", !5}
1748!5 = !{!"i64"}
1749!6 = !{i32 5, !"float_computations", !7}
1750!7 = !{!"double"}
1751""",
1752 )
1753
1754
1755@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1756def test_optimize_removes_mresetz_and_reset_into_mresetz() -> None:
1757 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1758 qir = qsharp.compile(
1759 """
1760 {
1761 use q = Qubit();
1762 X(q);
1763 MResetZ(q);
1764 Reset(q);
1765 X(q);
1766 }
1767 """
1768 )
1769
1770 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1771 OptimizeSingleQubitGates().run(module)
1772
1773 assert_expected_inline(
1774 str(module),
1775 """\
1776
1777%Qubit = type opaque
1778%Result = type opaque
1779
1780@empty_tag = internal constant [1 x i8] zeroinitializer
1781
1782define i64 @ENTRYPOINT__main() #0 {
1783block_0:
1784 call void @__quantum__rt__initialize(i8* null)
1785 call void @__quantum__qis__x__body(%Qubit* null)
1786 call void @__quantum__qis__mresetz__body(%Qubit* null, %Result* null)
1787 call void @__quantum__qis__x__body(%Qubit* null)
1788 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1789 ret i64 0
1790}
1791
1792declare void @__quantum__rt__initialize(i8*)
1793
1794declare void @__quantum__qis__x__body(%Qubit*)
1795
1796declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*) #1
1797
1798declare void @__quantum__qis__reset__body(%Qubit*) #1
1799
1800declare void @__quantum__rt__tuple_record_output(i64, i8*)
1801
1802declare void @__quantum__qis__sx__body(%Qubit*)
1803
1804attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="1" }
1805attributes #1 = { "irreversible" }
1806
1807!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1808
1809!0 = !{i32 1, !"qir_major_version", i32 1}
1810!1 = !{i32 7, !"qir_minor_version", i32 0}
1811!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1812!3 = !{i32 1, !"dynamic_result_management", i1 false}
1813!4 = !{i32 5, !"int_computations", !5}
1814!5 = !{!"i64"}
1815!6 = !{i32 5, !"float_computations", !7}
1816!7 = !{!"double"}
1817""",
1818 )
1819
1820
1821@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1822def test_optimize_removes_reset_of_unused_qubits() -> None:
1823 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1824 qir = qsharp.compile(
1825 """
1826 {
1827 use q1 = Qubit();
1828 use q2 = Qubit();
1829 X(q1);
1830 Reset(q1);
1831 Reset(q2);
1832 X(q1);
1833 X(q2);
1834 }
1835 """
1836 )
1837
1838 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1839 OptimizeSingleQubitGates().run(module)
1840
1841 assert_expected_inline(
1842 str(module),
1843 """\
1844
1845%Qubit = type opaque
1846%Result = type opaque
1847
1848@empty_tag = internal constant [1 x i8] zeroinitializer
1849
1850define i64 @ENTRYPOINT__main() #0 {
1851block_0:
1852 call void @__quantum__rt__initialize(i8* null)
1853 call void @__quantum__qis__x__body(%Qubit* null)
1854 call void @__quantum__qis__reset__body(%Qubit* null)
1855 call void @__quantum__qis__x__body(%Qubit* null)
1856 call void @__quantum__qis__x__body(%Qubit* inttoptr (i64 1 to %Qubit*))
1857 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1858 ret i64 0
1859}
1860
1861declare void @__quantum__rt__initialize(i8*)
1862
1863declare void @__quantum__qis__x__body(%Qubit*)
1864
1865declare void @__quantum__qis__reset__body(%Qubit*) #1
1866
1867declare void @__quantum__rt__tuple_record_output(i64, i8*)
1868
1869declare void @__quantum__qis__sx__body(%Qubit*)
1870
1871declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
1872
1873attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="0" }
1874attributes #1 = { "irreversible" }
1875
1876!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1877
1878!0 = !{i32 1, !"qir_major_version", i32 1}
1879!1 = !{i32 7, !"qir_minor_version", i32 0}
1880!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1881!3 = !{i32 1, !"dynamic_result_management", i1 false}
1882!4 = !{i32 5, !"int_computations", !5}
1883!5 = !{!"i64"}
1884!6 = !{i32 5, !"float_computations", !7}
1885!7 = !{!"double"}
1886""",
1887 )
1888
1889
1890@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1891def test_optimize_turns_final_m_into_mresetz() -> None:
1892 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1893 qir = qsharp.compile(
1894 """
1895 {
1896 use q = Qubit();
1897 X(q);
1898 M(q);
1899 }
1900 """
1901 )
1902
1903 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1904 OptimizeSingleQubitGates().run(module)
1905
1906 assert_expected_inline(
1907 str(module),
1908 """\
1909
1910%Qubit = type opaque
1911%Result = type opaque
1912
1913@empty_tag = internal constant [1 x i8] zeroinitializer
1914
1915define i64 @ENTRYPOINT__main() #0 {
1916block_0:
1917 call void @__quantum__rt__initialize(i8* null)
1918 call void @__quantum__qis__x__body(%Qubit* null)
1919 call void @__quantum__qis__mresetz__body(%Qubit* null, %Result* null)
1920 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1921 ret i64 0
1922}
1923
1924declare void @__quantum__rt__initialize(i8*)
1925
1926declare void @__quantum__qis__x__body(%Qubit*)
1927
1928declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
1929
1930declare void @__quantum__rt__tuple_record_output(i64, i8*)
1931
1932declare void @__quantum__qis__sx__body(%Qubit*)
1933
1934declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
1935
1936attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="1" }
1937attributes #1 = { "irreversible" }
1938
1939!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
1940
1941!0 = !{i32 1, !"qir_major_version", i32 1}
1942!1 = !{i32 7, !"qir_minor_version", i32 0}
1943!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1944!3 = !{i32 1, !"dynamic_result_management", i1 false}
1945!4 = !{i32 5, !"int_computations", !5}
1946!5 = !{!"i64"}
1947!6 = !{i32 5, !"float_computations", !7}
1948!7 = !{!"double"}
1949""",
1950 )
1951
1952
1953@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
1954def test_optimize_removes_reset_after_reset() -> None:
1955 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
1956 qir = qsharp.compile(
1957 """
1958 {
1959 use q = Qubit();
1960 X(q);
1961 Reset(q);
1962 Reset(q);
1963 Y(q);
1964 }
1965 """
1966 )
1967
1968 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
1969 OptimizeSingleQubitGates().run(module)
1970
1971 assert_expected_inline(
1972 str(module),
1973 """\
1974
1975%Qubit = type opaque
1976%Result = type opaque
1977
1978@empty_tag = internal constant [1 x i8] zeroinitializer
1979
1980define i64 @ENTRYPOINT__main() #0 {
1981block_0:
1982 call void @__quantum__rt__initialize(i8* null)
1983 call void @__quantum__qis__x__body(%Qubit* null)
1984 call void @__quantum__qis__reset__body(%Qubit* null)
1985 call void @__quantum__qis__y__body(%Qubit* null)
1986 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
1987 ret i64 0
1988}
1989
1990declare void @__quantum__rt__initialize(i8*)
1991
1992declare void @__quantum__qis__x__body(%Qubit*)
1993
1994declare void @__quantum__qis__reset__body(%Qubit*) #1
1995
1996declare void @__quantum__qis__y__body(%Qubit*)
1997
1998declare void @__quantum__rt__tuple_record_output(i64, i8*)
1999
2000declare void @__quantum__qis__sx__body(%Qubit*)
2001
2002declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
2003
2004attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
2005attributes #1 = { "irreversible" }
2006
2007!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
2008
2009!0 = !{i32 1, !"qir_major_version", i32 1}
2010!1 = !{i32 7, !"qir_minor_version", i32 0}
2011!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
2012!3 = !{i32 1, !"dynamic_result_management", i1 false}
2013!4 = !{i32 5, !"int_computations", !5}
2014!5 = !{!"i64"}
2015!6 = !{i32 5, !"float_computations", !7}
2016!7 = !{!"double"}
2017""",
2018 )
2019
2020
2021@pytest.mark.skipif(not PYQIR_AVAILABLE, reason=SKIP_REASON)
2022def test_optimize_removes_final_reset() -> None:
2023 qsharp.init(target_profile=qsharp.TargetProfile.Adaptive_RIF)
2024 qir = qsharp.compile(
2025 """
2026 {
2027 use q = Qubit();
2028 X(q);
2029 Reset(q);
2030 }
2031 """
2032 )
2033
2034 module = pyqir.Module.from_ir(pyqir.Context(), str(qir))
2035 OptimizeSingleQubitGates().run(module)
2036
2037 assert_expected_inline(
2038 str(module),
2039 """\
2040
2041%Qubit = type opaque
2042%Result = type opaque
2043
2044@empty_tag = internal constant [1 x i8] zeroinitializer
2045
2046define i64 @ENTRYPOINT__main() #0 {
2047block_0:
2048 call void @__quantum__rt__initialize(i8* null)
2049 call void @__quantum__qis__x__body(%Qubit* null)
2050 call void @__quantum__rt__tuple_record_output(i64 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty_tag, i64 0, i64 0))
2051 ret i64 0
2052}
2053
2054declare void @__quantum__rt__initialize(i8*)
2055
2056declare void @__quantum__qis__x__body(%Qubit*)
2057
2058declare void @__quantum__qis__reset__body(%Qubit*) #1
2059
2060declare void @__quantum__rt__tuple_record_output(i64, i8*)
2061
2062declare void @__quantum__qis__sx__body(%Qubit*)
2063
2064declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*)
2065
2066attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="0" }
2067attributes #1 = { "irreversible" }
2068
2069!llvm.module.flags = !{!0, !1, !2, !3, !4, !6}
2070
2071!0 = !{i32 1, !"qir_major_version", i32 1}
2072!1 = !{i32 7, !"qir_minor_version", i32 0}
2073!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
2074!3 = !{i32 1, !"dynamic_result_management", i1 false}
2075!4 = !{i32 5, !"int_computations", !5}
2076!5 = !{!"i64"}
2077!6 = !{i32 5, !"float_computations", !7}
2078!7 = !{!"double"}
2079""",
2080 )
2081