microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
minestarks/circuit-magic

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/pip/tests/test_qasm.py

936lines · modecode

1# Copyright (c) Microsoft Corporation.
2# Licensed under the MIT License.
3
4from math import pi
5from textwrap import dedent
6import pytest
7from qsharp import (
8 init,
9 TargetProfile,
10 set_quantum_seed,
11 BitFlipNoise,
12 QSharpError,
13 Result,
14)
15from qsharp.estimator import EstimatorParams, QubitParams, QECScheme, LogicalCounts
16from qsharp.openqasm import (
17 import_openqasm,
18 run,
19 compile,
20 circuit,
21 estimate,
22 ProgramType,
23 QasmError,
24)
25import qsharp.code as code
26
27# Run
28
29
30def test_run_with_noise_produces_noisy_results() -> None:
31 set_quantum_seed(0)
32 result = run(
33 """
34 include "stdgates.inc";
35 qubit q1;
36 qubit q2;
37 output int errors;
38 for int i in [0:100] {
39 h q1;
40 cx q1, q2;
41 bit[2] c;
42 c[0] = measure q1;
43 c[1] = measure q2;
44 reset q1;
45 reset q2;
46 if (c[0] != c[1]) { errors += 1; }
47 }
48 """,
49 shots=1,
50 noise=BitFlipNoise(0.1),
51 )
52 assert result[0] > 5
53 result = run(
54 """
55 include "stdgates.inc";
56 output int errors;
57 qubit q;
58 for int i in [0:100] {
59 bit c = measure q;
60 reset q;
61 if (c != 0) { errors+=1; }
62 }
63 """,
64 shots=1,
65 noise=BitFlipNoise(0.1),
66 )
67 assert result[0] > 5
68
69
70def test_run_with_qubit_loss_produces_lossy_results() -> None:
71 set_quantum_seed(0)
72 result = run(
73 """
74 qubit q1;
75 bit c1;
76 c1 = measure q1;
77 """,
78 shots=1,
79 qubit_loss=1.0,
80 )
81 assert result[0] == Result.Loss
82
83
84def test_run_with_qubit_loss_detects_loss_with_mresetzchecked() -> None:
85 set_quantum_seed(0)
86 result = run(
87 """
88 include "qdk.inc";
89 qubit q1;
90 int r;
91 r = mresetz_checked(q1);
92 """,
93 shots=1,
94 qubit_loss=1.0,
95 )
96 assert result[0] == 2
97
98
99def test_run_without_qubit_loss_does_not_detect_loss_with_mresetzchecked() -> None:
100 set_quantum_seed(0)
101 result = run(
102 """
103 include "qdk.inc";
104 qubit q1;
105 int r;
106 r = mresetz_checked(q1);
107 """,
108 shots=1,
109 )
110 assert result[0] == 0
111
112
113def test_mresetzchecked_not_present_without_qdk_inc() -> None:
114 set_quantum_seed(0)
115 with pytest.raises(QasmError) as excinfo:
116 run(
117 """
118 include "stdgates.inc";
119 qubit q1;
120 bit[2] r;
121 r = mresetz_checked(q1);
122 """,
123 shots=1,
124 )
125 assert "undefined symbol: mresetz_checked" in str(excinfo.value)
126
127
128def test_run_with_result(capsys) -> None:
129 results = run("output bit c;", 3)
130 assert results == [Result.Zero, Result.Zero, Result.Zero]
131
132
133# Import
134
135
136def test_import_creates_python_callable_by_default_named_program() -> None:
137 init(target_profile=TargetProfile.Base)
138 import_openqasm("")
139 assert code.program is not None
140
141
142def test_import_python_callable_name_can_be_set() -> None:
143 init(target_profile=TargetProfile.Base)
144 import_openqasm("", name="Foo")
145 assert code.Foo is not None
146
147
148def test_import_can_process_fragments_to_modify_intereter_state() -> None:
149 init(target_profile=TargetProfile.Base)
150 import_openqasm("int x = 42;", program_type=ProgramType.Fragments)
151 from qsharp import eval as qsharp_eval
152
153 assert qsharp_eval("x") == 42
154
155
156def test_import_can_declare_callables_from_fragments() -> None:
157 init(target_profile=TargetProfile.Base)
158 import_openqasm(
159 "def Foo() -> int { return 42; }", program_type=ProgramType.Fragments
160 )
161 from qsharp import eval as qsharp_eval
162
163 assert qsharp_eval("Foo()") == 42
164
165
166def test_import_can_declare_files_with_namespaces() -> None:
167 init(target_profile=TargetProfile.Adaptive_RI)
168 import_openqasm("output int x; x = 42;", program_type=ProgramType.File)
169 from qsharp import eval as qsharp_eval
170
171 assert qsharp_eval("qasm_import.program()") == 42
172
173
174# Import + Run
175
176
177def test_run_imported_with_noise_produces_noisy_results() -> None:
178 init()
179 set_quantum_seed(0)
180 import_openqasm(
181 """
182 include "stdgates.inc";
183 qubit q1;
184 qubit q2;
185 output int errors;
186 for int i in [0:100] {
187 h q1;
188 cx q1, q2;
189 bit[2] c;
190 c[0] = measure q1;
191 c[1] = measure q2;
192 reset q1;
193 reset q2;
194 if (c[0] != c[1]) { errors += 1; }
195 }
196 """,
197 name="Program0",
198 )
199 result = run(code.Program0, shots=1, noise=BitFlipNoise(0.1))
200 assert result[0] > 5
201
202 result = import_openqasm(
203 """
204 include "stdgates.inc";
205 output int errors;
206 qubit q;
207 for int i in [0:100] {
208 bit c = measure q;
209 reset q;
210 if (c != 0) { errors+=1; }
211 }
212 """,
213 name="Program1",
214 )
215 result = run(code.Program1, shots=1, noise=BitFlipNoise(0.1))
216 assert result[0] > 5
217
218
219def test_run_with_result_from_callable(capsys) -> None:
220 init()
221 import_openqasm("output bit c;", name="Foo")
222 results = run(code.Foo, 3)
223 assert results == [Result.Zero, Result.Zero, Result.Zero]
224
225
226def test_run_with_result_callback(capsys) -> None:
227 def on_result(result):
228 nonlocal called
229 called = True
230 assert result["result"] == Result.Zero
231
232 called = False
233 init()
234 import_openqasm("output bit c;", name="Foo")
235 results = run(code.Foo, 3, on_result=on_result, save_events=True)
236 assert (
237 str(results)
238 == "[{'result': Zero, 'events': [], 'matrices': [], 'dumps': [], 'messages': []}, {'result': Zero, 'events': [], 'matrices': [], 'dumps': [], 'messages': []}, {'result': Zero, 'events': [], 'matrices': [], 'dumps': [], 'messages': []}]"
239 )
240 stdout = capsys.readouterr().out
241 assert stdout == ""
242 assert called
243
244
245def test_run_with_result_callback_from_callable_with_args(capsys) -> None:
246 def on_result(result):
247 nonlocal called
248 called = True
249 assert result["result"] == [Result.Zero, Result.Zero]
250
251 called = False
252 init()
253 import_openqasm("input int a; output bit[2] c;", name="Foo")
254 results = run(code.Foo, 3, 2, on_result=on_result, save_events=True)
255 assert (
256 str(results)
257 == "[{'result': [Zero, Zero], 'events': [], 'matrices': [], 'dumps': [], 'messages': []}, {'result': [Zero, Zero], 'events': [], 'matrices': [], 'dumps': [], 'messages': []}, {'result': [Zero, Zero], 'events': [], 'matrices': [], 'dumps': [], 'messages': []}]"
258 )
259
260 assert called
261
262
263def test_run_with_invalid_shots_produces_error() -> None:
264 init()
265 import_openqasm("output bit[2] c;", name="Foo")
266 try:
267 run(code.Foo, -1)
268 except ValueError as e:
269 assert str(e) == "The number of shots must be greater than 0."
270 else:
271 assert False
272
273 try:
274 run(code.Foo, 0)
275 except ValueError as e:
276 assert str(e) == "The number of shots must be greater than 0."
277 else:
278 assert False
279
280
281# Compile
282
283
284def test_compile_qir_input_data() -> None:
285 operation = compile("qubit q; output bit c; c = measure q;")
286 qir = operation._repr_qir_()
287 assert isinstance(qir, bytes)
288
289
290def test_compile_qir_str() -> None:
291 qir = str(compile("qubit q; output bit c; c = measure q;"))
292 assert "define void @ENTRYPOINT__main()" in qir
293 assert '"required_num_qubits"="1" "required_num_results"="1"' in qir
294
295
296def test_compile_qir_str_with_single_arg_raises_error() -> None:
297 init(target_profile=TargetProfile.Base)
298 with pytest.raises(QSharpError) as excinfo:
299 compile(
300 """
301 include "stdgates.inc";
302 input float f;
303 qubit q;
304 rx(f) q;
305 output bit c;
306 c = measure q;
307 """
308 )
309 assert (
310 str(excinfo.value)
311 == """Circuit has unbound input parameters
312 help: Parameters: f: Double"""
313 )
314
315
316# Import + Compile
317
318
319def test_compile_qir_str_from_python_callable() -> None:
320 init(target_profile=TargetProfile.Base)
321 import_openqasm("qubit q; output bit c; c = measure q;", name="Program")
322 operation = compile(code.Program)
323 qir = str(operation)
324 assert "define void @ENTRYPOINT__main()" in qir
325 assert '"required_num_qubits"="1" "required_num_results"="1"' in qir
326
327
328def test_compile_qir_str_from_python_callable_with_single_arg() -> None:
329 init(target_profile=TargetProfile.Base)
330 import_openqasm(
331 """
332 include "stdgates.inc";
333 input float f;
334 qubit q;
335 rx(f) q;
336 output bit c;
337 c = measure q;
338 """
339 )
340
341 operation = compile(code.program, pi)
342 qir = str(operation)
343 assert "define void @ENTRYPOINT__main()" in qir
344 assert (
345 "call void @__quantum__qis__rx__body(double 3.141592653589793, %Qubit* inttoptr (i64 0 to %Qubit*))"
346 in qir
347 )
348 assert (
349 "call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)"
350 in qir
351 )
352 assert '"required_num_qubits"="1" "required_num_results"="1"' in qir
353
354
355def test_compile_qir_str_from_python_callable_with_multiple_args() -> None:
356 init(target_profile=TargetProfile.Base)
357 import_openqasm(
358 """
359 include "stdgates.inc";
360 input float f;
361 input float d;
362 qubit q;
363 rx(f/d) q;
364 output bit c;
365 c = measure q;
366 """,
367 name="Program",
368 )
369 operation = compile(code.Program, 2 * pi, 2.0)
370 qir = str(operation)
371 assert "define void @ENTRYPOINT__main()" in qir
372 assert (
373 "call void @__quantum__qis__rx__body(double 3.141592653589793, %Qubit* inttoptr (i64 0 to %Qubit*))"
374 in qir
375 )
376 assert (
377 "call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)"
378 in qir
379 )
380 assert '"required_num_qubits"="1" "required_num_results"="1"' in qir
381
382
383def test_compile_qir_str_from_python_callable_with_multiple_args_passed_as_tuple() -> (
384 None
385):
386 init(target_profile=TargetProfile.Base)
387 import_openqasm(
388 """
389 include "stdgates.inc";
390 input float f;
391 input float d;
392 qubit q;
393 rx(f/d) q;
394 output bit c;
395 c = measure q;
396 """,
397 name="Program",
398 )
399 args = (2 * pi, 2.0)
400 operation = compile(code.Program, args)
401 qir = str(operation)
402 assert "define void @ENTRYPOINT__main()" in qir
403 assert (
404 "call void @__quantum__qis__rx__body(double 3.141592653589793, %Qubit* inttoptr (i64 0 to %Qubit*))"
405 in qir
406 )
407 assert (
408 "call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)"
409 in qir
410 )
411 assert '"required_num_qubits"="1" "required_num_results"="1"' in qir
412
413
414def test_compile_qir_str_from_callable_with_mresetzchecked() -> None:
415 init(target_profile=TargetProfile.Adaptive_RI)
416 import_openqasm(
417 """
418 include "qdk.inc";
419 qubit q1;
420 int r;
421 r = mresetz_checked(q1);
422 """,
423 name="Program",
424 )
425 operation = compile(code.Program)
426 qir = str(operation)
427 assert "define void @ENTRYPOINT__main()" in qir
428 assert (
429 "call i1 @__quantum__rt__read_loss(%Result* inttoptr (i64 0 to %Result*))"
430 in qir
431 )
432 assert '"required_num_qubits"="1" "required_num_results"="1"' in qir
433 assert "call void @__quantum__rt__int_record_output" in qir
434
435
436def test_callables_exposed_into_env() -> None:
437 init()
438 import_openqasm(
439 "def Four() -> int { return 4; }", program_type=ProgramType.Fragments
440 )
441 assert code.Four() == 4, "callable should be available"
442 import_openqasm(
443 "def Add(int a, int b) -> int { return a + b; }",
444 program_type=ProgramType.Fragments,
445 )
446 assert code.Four() == 4, "first callable should still be available"
447 assert code.Add(2, 3) == 5, "second callable should be available"
448 # After init, the callables should be cleared and no longer available
449 init()
450 with pytest.raises(AttributeError):
451 code.Four()
452
453
454def test_callable_with_int_exposed_into_env_fails_incorrect_types() -> None:
455 init()
456 import_openqasm(
457 "def Identity(int a) -> int { return a; }", program_type=ProgramType.Fragments
458 )
459 assert code.Identity(4) == 4
460 with pytest.raises(TypeError):
461 code.Identity("4")
462 with pytest.raises(TypeError):
463 code.Identity(4.0)
464 with pytest.raises(OverflowError):
465 code.Identity(4000000000000000000000)
466 with pytest.raises(TypeError):
467 code.Identity([4])
468
469
470def test_callable_with_double_exposed_into_env_fails_incorrect_types() -> None:
471 init()
472 import_openqasm(
473 "def Identity(float a) -> float { return a; }",
474 program_type=ProgramType.Fragments,
475 )
476 assert code.Identity(4.0) == 4.0
477 assert code.Identity(4) == 4.0
478 with pytest.raises(TypeError):
479 code.Identity("4")
480 with pytest.raises(TypeError):
481 code.Identity([4])
482
483
484def test_callable_with_bigint_exposed_into_env_fails_incorrect_types() -> None:
485 init()
486 import_openqasm(
487 "def Identity(int[128] a) -> int[128] { return a; }",
488 program_type=ProgramType.Fragments,
489 )
490 assert code.Identity(4000000000000000000000) == 4000000000000000000000
491 with pytest.raises(TypeError):
492 code.Identity("4")
493 with pytest.raises(TypeError):
494 code.Identity(4.0)
495
496
497def test_callable_with_bool_exposed_into_env_fails_incorrect_types() -> None:
498 init()
499 import_openqasm(
500 "def Identity(bool a) -> bool { return a; }", program_type=ProgramType.Fragments
501 )
502 assert code.Identity(True) == True
503 with pytest.raises(TypeError):
504 code.Identity("4")
505 with pytest.raises(TypeError):
506 code.Identity(4)
507 with pytest.raises(TypeError):
508 code.Identity(4.0)
509 with pytest.raises(TypeError):
510 code.Identity([4])
511
512
513def test_callable_with_array_exposed_into_env_fails_incorrect_types() -> None:
514 init()
515 import_openqasm(
516 "def fst(readonly array[int, #dim = 1] arr_arg) -> int { return arr_arg[0]; }",
517 program_type=ProgramType.Fragments,
518 )
519 assert code.fst([4, 5, 6]) == 4
520 assert code.fst((5, 6, 7)) == 5
521 with pytest.raises(QSharpError): # out of range
522 code.fst([])
523 with pytest.raises(TypeError):
524 code.fst((4, 5.0, 6))
525 with pytest.raises(TypeError):
526 code.fst(4)
527 with pytest.raises(TypeError):
528 code.fst("4")
529 with pytest.raises(TypeError):
530 code.fst(4.0)
531 with pytest.raises(TypeError):
532 code.fst([1, 2, 3.0])
533
534
535@pytest.mark.xfail(
536 reason="When compiling fragments, input/output angles should be converted to floats"
537)
538def test_callables_with_unsupported_types_raise_errors_on_call() -> None:
539 init()
540 import_openqasm("def Unsupported(angle a) { }", program_type=ProgramType.Fragments)
541 with pytest.raises(QSharpError, match='unsupported input type: `UDT<"Angle":'):
542 code.Unsupported()
543
544
545def test_callable_with_complex_input() -> None:
546 init()
547 import_openqasm(
548 "def ComplexInput(complex a) { }", program_type=ProgramType.Fragments
549 )
550 code.ComplexInput(2 + 3j)
551
552
553def test_callable_with_complex_output() -> None:
554 init()
555 import_openqasm(
556 "def ComplexOutput() -> complex { return 2 + 3im; }",
557 program_type=ProgramType.Fragments,
558 )
559 assert code.ComplexOutput() == 2 + 3j
560
561
562def test_callable_with_complex_input_output() -> None:
563 init()
564 import_openqasm(
565 "def ComplexOutput(complex a) -> complex { return 2 * a; }",
566 program_type=ProgramType.Fragments,
567 )
568 assert code.ComplexOutput(2 + 3j) == 4 + 6j
569
570
571def test_identity_returning_complex_udt() -> None:
572 init()
573 import_openqasm(
574 "def ComplexOutput(complex a) -> complex { return a; }",
575 program_type=ProgramType.Fragments,
576 )
577 assert code.ComplexOutput(2 + 3j) == 2 + 3j
578
579
580def test_callable_with_angle_input() -> None:
581 init()
582 import_openqasm("def AngleInput(angle a) { }", program_type=ProgramType.Fragments)
583 code.AngleInput(3.14)
584
585
586def test_callable_with_angle_output() -> None:
587 init()
588 import_openqasm(
589 "def AngleOutput() -> angle { return pi; }",
590 program_type=ProgramType.Fragments,
591 )
592 assert code.AngleOutput() == pi
593
594
595def test_callable_with_angle_input_output() -> None:
596 init()
597 import_openqasm(
598 "def AngleOutput(angle a) -> angle { return a; }",
599 program_type=ProgramType.Fragments,
600 )
601 assert code.AngleOutput(pi) == pi
602
603
604def test_circuit_from_program() -> None:
605 init()
606
607 c = circuit(
608 """
609 include "stdgates.inc";
610 qubit q1;
611 qubit q2;
612 x q1;
613 """,
614 )
615 assert str(c) == dedent(
616 """\
617 q_0 ── X ──
618 q_1 ───────
619 """
620 )
621
622
623def test_circuit_from_callable() -> None:
624 init()
625 import_openqasm(
626 """
627 include "stdgates.inc";
628 qubit q1;
629 qubit q2;
630 x q1;
631 """,
632 program_type=ProgramType.Operation,
633 name="Foo",
634 )
635 c = circuit(code.Foo)
636 assert str(c) == dedent(
637 """\
638 q_0 ── X ──
639 q_1 ───────
640 """
641 )
642
643
644def test_circuit_from_callable_with_args() -> None:
645 init()
646 import_openqasm(
647 """
648 include "stdgates.inc";
649 qubit[2] qs;
650 input int nQubits;
651 for int i in [0:nQubits-1] {
652 x qs[i];
653 }
654 """,
655 name="Foo",
656 )
657 c = circuit(code.Foo, 2)
658 assert str(c) == dedent(
659 """\
660 q_0 ── X ──
661 q_1 ── X ──
662 """
663 )
664
665
666def test_circuit_with_measure_from_callable() -> None:
667 init()
668 import_openqasm(
669 """include "stdgates.inc"; qubit q; h q; bit c; c = measure q;""",
670 name="Foo",
671 )
672 c = circuit(code.Foo)
673 assert str(c) == dedent(
674 """\
675 q_0 ── H ──── M ──
676 ╘═══
677 """
678 )
679
680
681# Estimate
682
683
684def test_qasm_estimation() -> None:
685 res = estimate(
686 """
687 include "stdgates.inc";
688 const int SIZE = 10;
689 qubit[SIZE] q;
690 for int i in [0:SIZE-1] {
691 t q[i];
692 measure q[i];
693 }
694 """
695 )
696 assert res["status"] == "success"
697 assert res["physicalCounts"] is not None
698 assert res.logical_counts == LogicalCounts(
699 {
700 "numQubits": 10,
701 "tCount": 10,
702 "rotationCount": 0,
703 "rotationDepth": 0,
704 "cczCount": 0,
705 "measurementCount": 10,
706 }
707 )
708
709
710def test_qasm_estimation_with_single_params() -> None:
711 params = EstimatorParams()
712 params.error_budget = 0.333
713 params.qubit_params.name = QubitParams.MAJ_NS_E4
714 assert params.as_dict() == {
715 "qubitParams": {"name": "qubit_maj_ns_e4"},
716 "errorBudget": 0.333,
717 }
718
719 res = estimate(
720 """
721 include "stdgates.inc";
722 const int SIZE = 10;
723 qubit[SIZE] q;
724 for int i in [0:SIZE-1] {
725 t q[i];
726 measure q[i];
727 }
728 """,
729 params=params,
730 )
731
732 assert res["status"] == "success"
733 assert res["physicalCounts"] is not None
734 assert res["jobParams"]["qubitParams"]["name"] == "qubit_maj_ns_e4"
735 assert res.logical_counts == LogicalCounts(
736 {
737 "numQubits": 10,
738 "tCount": 10,
739 "rotationCount": 0,
740 "rotationDepth": 0,
741 "cczCount": 0,
742 "measurementCount": 10,
743 }
744 )
745
746
747def test_qasm_estimation_with_multiple_params() -> None:
748 params = EstimatorParams(3)
749 params.items[0].qubit_params.name = QubitParams.GATE_US_E3
750 params.items[0].error_budget = 0.333
751 params.items[1].qubit_params.name = QubitParams.GATE_US_E4
752 params.items[1].error_budget = 0.333
753 params.items[2].qubit_params.name = QubitParams.MAJ_NS_E6
754 params.items[2].qec_scheme.name = QECScheme.FLOQUET_CODE
755 params.items[2].error_budget = 0.333
756 assert params.as_dict() == {
757 "items": [
758 {
759 "qubitParams": {"name": "qubit_gate_us_e3"},
760 "errorBudget": 0.333,
761 },
762 {
763 "qubitParams": {"name": "qubit_gate_us_e4"},
764 "errorBudget": 0.333,
765 },
766 {
767 "qubitParams": {"name": "qubit_maj_ns_e6"},
768 "qecScheme": {"name": "floquet_code"},
769 "errorBudget": 0.333,
770 },
771 ],
772 "resumeAfterFailedItem": True,
773 }
774
775 res = estimate(
776 """
777 include "stdgates.inc";
778 const int SIZE = 10;
779 qubit[SIZE] q;
780 for int i in [0:SIZE-1] {
781 t q[i];
782 measure q[i];
783 }
784 """,
785 params=params,
786 )
787
788 for idx in res:
789 assert res[idx]["status"] == "success"
790 assert res[idx]["physicalCounts"] is not None
791 assert (
792 res[idx]["jobParams"]["qubitParams"]["name"]
793 == params.items[idx].qubit_params.name
794 )
795 assert res[idx]["logicalCounts"] == LogicalCounts(
796 {
797 "numQubits": 10,
798 "tCount": 10,
799 "rotationCount": 0,
800 "rotationDepth": 0,
801 "cczCount": 0,
802 "measurementCount": 10,
803 }
804 )
805 assert res[2]["jobParams"]["qecScheme"]["name"] == QECScheme.FLOQUET_CODE
806
807
808def test_qasm_estimation_with_multiple_params_from_python_callable() -> None:
809 init(target_profile=TargetProfile.Unrestricted)
810
811 params = EstimatorParams(3)
812 params.items[0].qubit_params.name = QubitParams.GATE_US_E3
813 params.items[0].error_budget = 0.333
814 params.items[1].qubit_params.name = QubitParams.GATE_US_E4
815 params.items[1].error_budget = 0.333
816 params.items[2].qubit_params.name = QubitParams.MAJ_NS_E6
817 params.items[2].qec_scheme.name = QECScheme.FLOQUET_CODE
818 params.items[2].error_budget = 0.333
819 assert params.as_dict() == {
820 "items": [
821 {
822 "qubitParams": {"name": "qubit_gate_us_e3"},
823 "errorBudget": 0.333,
824 },
825 {
826 "qubitParams": {"name": "qubit_gate_us_e4"},
827 "errorBudget": 0.333,
828 },
829 {
830 "qubitParams": {"name": "qubit_maj_ns_e6"},
831 "qecScheme": {"name": "floquet_code"},
832 "errorBudget": 0.333,
833 },
834 ],
835 "resumeAfterFailedItem": True,
836 }
837
838 import_openqasm(
839 """
840 include "stdgates.inc";
841 const int SIZE = 10;
842 qubit[SIZE] q;
843 for int i in [0:SIZE-1] {
844 t q[i];
845 measure q[i];
846 }
847 """,
848 name="Test",
849 )
850
851 res = estimate(code.Test, params=params)
852
853 for idx in res:
854 assert res[idx]["status"] == "success"
855 assert res[idx]["physicalCounts"] is not None
856 assert (
857 res[idx]["jobParams"]["qubitParams"]["name"]
858 == params.items[idx].qubit_params.name
859 )
860 assert res[idx]["logicalCounts"] == LogicalCounts(
861 {
862 "numQubits": 10,
863 "tCount": 10,
864 "rotationCount": 0,
865 "rotationDepth": 0,
866 "cczCount": 0,
867 "measurementCount": 10,
868 }
869 )
870 assert res[2]["jobParams"]["qecScheme"]["name"] == QECScheme.FLOQUET_CODE
871
872
873def test_qasm_estimation_with_multiple_params_from_python_callable_with_arg() -> None:
874 init(target_profile=TargetProfile.Unrestricted)
875
876 params = EstimatorParams(3)
877 params.items[0].qubit_params.name = QubitParams.GATE_US_E3
878 params.items[0].error_budget = 0.333
879 params.items[1].qubit_params.name = QubitParams.GATE_US_E4
880 params.items[1].error_budget = 0.333
881 params.items[2].qubit_params.name = QubitParams.MAJ_NS_E6
882 params.items[2].qec_scheme.name = QECScheme.FLOQUET_CODE
883 params.items[2].error_budget = 0.333
884 assert params.as_dict() == {
885 "items": [
886 {
887 "qubitParams": {"name": "qubit_gate_us_e3"},
888 "errorBudget": 0.333,
889 },
890 {
891 "qubitParams": {"name": "qubit_gate_us_e4"},
892 "errorBudget": 0.333,
893 },
894 {
895 "qubitParams": {"name": "qubit_maj_ns_e6"},
896 "qecScheme": {"name": "floquet_code"},
897 "errorBudget": 0.333,
898 },
899 ],
900 "resumeAfterFailedItem": True,
901 }
902
903 import_openqasm(
904 """
905 include "stdgates.inc";
906 input int discard;
907 const int SIZE = 7;
908 qubit[SIZE] q;
909 for int i in [0:SIZE-1] {
910 t q[i];
911 measure q[i];
912 }
913 """,
914 name="Test",
915 )
916
917 res = estimate(code.Test, params, 8)
918
919 for idx in res:
920 assert res[idx]["status"] == "success"
921 assert res[idx]["physicalCounts"] is not None
922 assert (
923 res[idx]["jobParams"]["qubitParams"]["name"]
924 == params.items[idx].qubit_params.name
925 )
926 assert res[idx]["logicalCounts"] == LogicalCounts(
927 {
928 "numQubits": 7,
929 "tCount": 7,
930 "rotationCount": 0,
931 "rotationDepth": 0,
932 "cczCount": 0,
933 "measurementCount": 7,
934 }
935 )
936 assert res[2]["jobParams"]["qecScheme"]["name"] == QECScheme.FLOQUET_CODE
937