microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
billti/num2-sim

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/pip/tests/test_qasm.py

896lines · 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
513# mark this test xfail until we support arrays as arguments
514@pytest.mark.xfail(reason="Arrays as arguments are not supported yet")
515def test_callable_with_array_exposed_into_env_fails_incorrect_types() -> None:
516 init()
517 import_openqasm(
518 "def fst(readonly array[int, #dim = 1] arr_arg) -> int { return arr_arg[0]; }",
519 program_type=ProgramType.Fragments,
520 )
521 assert code.fst([4, 5, 6]) == 4
522 with pytest.raises(TypeError):
523 code.Identity([])
524 with pytest.raises(TypeError):
525 code.Identity((4, 5, 6))
526 with pytest.raises(TypeError):
527 code.Identity(4)
528 with pytest.raises(TypeError):
529 code.Identity("4")
530 with pytest.raises(TypeError):
531 code.Identity(4.0)
532 with pytest.raises(TypeError):
533 code.Identity([1, 2, 3.0])
534
535
536@pytest.mark.xfail(
537 reason="When compiling fragments, input/output angles should be converted to floats"
538)
539def test_callables_with_unsupported_types_raise_errors_on_call() -> None:
540 init()
541 import_openqasm("def Unsupported(angle a) { }", program_type=ProgramType.Fragments)
542 with pytest.raises(QSharpError, match='unsupported input type: `UDT<"Angle":'):
543 code.Unsupported()
544
545
546def test_callables_with_unsupported_udt_types_raise_errors_on_call() -> None:
547 init()
548 import_openqasm(
549 "def Unsupported(complex a) { }", program_type=ProgramType.Fragments
550 )
551 with pytest.raises(QSharpError, match='unsupported input type: `UDT<"Complex":'):
552 code.Unsupported()
553
554
555def test_callable_with_unsupported_udt_return_types_raise_errors_on_call() -> None:
556 init()
557 import_openqasm(
558 "def Unsupported() -> complex { end; }", program_type=ProgramType.Fragments
559 )
560 with pytest.raises(QSharpError, match='unsupported output type: `UDT<"Complex":'):
561 code.Unsupported()
562
563
564def test_circuit_from_program() -> None:
565 init()
566
567 c = circuit(
568 """
569 include "stdgates.inc";
570 qubit q1;
571 qubit q2;
572 x q1;
573 """,
574 )
575 assert str(c) == dedent(
576 """\
577 q_0 ── X ──
578 q_1 ───────
579 """
580 )
581
582
583def test_circuit_from_callable() -> None:
584 init()
585 import_openqasm(
586 """
587 include "stdgates.inc";
588 qubit q1;
589 qubit q2;
590 x q1;
591 """,
592 program_type=ProgramType.Operation,
593 name="Foo",
594 )
595 c = circuit(code.Foo)
596 assert str(c) == dedent(
597 """\
598 q_0 ── X ──
599 q_1 ───────
600 """
601 )
602
603
604def test_circuit_from_callable_with_args() -> None:
605 init()
606 import_openqasm(
607 """
608 include "stdgates.inc";
609 qubit[2] qs;
610 input int nQubits;
611 for int i in [0:nQubits-1] {
612 x qs[i];
613 }
614 """,
615 name="Foo",
616 )
617 c = circuit(code.Foo, 2)
618 assert str(c) == dedent(
619 """\
620 q_0 ── X ──
621 q_1 ── X ──
622 """
623 )
624
625
626def test_circuit_with_measure_from_callable() -> None:
627 init()
628 import_openqasm(
629 """include "stdgates.inc"; qubit q; h q; bit c; c = measure q;""",
630 name="Foo",
631 )
632 c = circuit(code.Foo)
633 assert str(c) == dedent(
634 """\
635 q_0 ── H ──── M ──
636 ╘═══
637 """
638 )
639
640
641# Estimate
642
643
644def test_qasm_estimation() -> None:
645 res = estimate(
646 """
647 include "stdgates.inc";
648 const int SIZE = 10;
649 qubit[SIZE] q;
650 for int i in [0:SIZE-1] {
651 t q[i];
652 measure q[i];
653 }
654 """
655 )
656 assert res["status"] == "success"
657 assert res["physicalCounts"] is not None
658 assert res.logical_counts == LogicalCounts(
659 {
660 "numQubits": 10,
661 "tCount": 10,
662 "rotationCount": 0,
663 "rotationDepth": 0,
664 "cczCount": 0,
665 "measurementCount": 10,
666 }
667 )
668
669
670def test_qasm_estimation_with_single_params() -> None:
671 params = EstimatorParams()
672 params.error_budget = 0.333
673 params.qubit_params.name = QubitParams.MAJ_NS_E4
674 assert params.as_dict() == {
675 "qubitParams": {"name": "qubit_maj_ns_e4"},
676 "errorBudget": 0.333,
677 }
678
679 res = estimate(
680 """
681 include "stdgates.inc";
682 const int SIZE = 10;
683 qubit[SIZE] q;
684 for int i in [0:SIZE-1] {
685 t q[i];
686 measure q[i];
687 }
688 """,
689 params=params,
690 )
691
692 assert res["status"] == "success"
693 assert res["physicalCounts"] is not None
694 assert res["jobParams"]["qubitParams"]["name"] == "qubit_maj_ns_e4"
695 assert res.logical_counts == LogicalCounts(
696 {
697 "numQubits": 10,
698 "tCount": 10,
699 "rotationCount": 0,
700 "rotationDepth": 0,
701 "cczCount": 0,
702 "measurementCount": 10,
703 }
704 )
705
706
707def test_qasm_estimation_with_multiple_params() -> None:
708 params = EstimatorParams(3)
709 params.items[0].qubit_params.name = QubitParams.GATE_US_E3
710 params.items[0].error_budget = 0.333
711 params.items[1].qubit_params.name = QubitParams.GATE_US_E4
712 params.items[1].error_budget = 0.333
713 params.items[2].qubit_params.name = QubitParams.MAJ_NS_E6
714 params.items[2].qec_scheme.name = QECScheme.FLOQUET_CODE
715 params.items[2].error_budget = 0.333
716 assert params.as_dict() == {
717 "items": [
718 {
719 "qubitParams": {"name": "qubit_gate_us_e3"},
720 "errorBudget": 0.333,
721 },
722 {
723 "qubitParams": {"name": "qubit_gate_us_e4"},
724 "errorBudget": 0.333,
725 },
726 {
727 "qubitParams": {"name": "qubit_maj_ns_e6"},
728 "qecScheme": {"name": "floquet_code"},
729 "errorBudget": 0.333,
730 },
731 ],
732 "resumeAfterFailedItem": True,
733 }
734
735 res = estimate(
736 """
737 include "stdgates.inc";
738 const int SIZE = 10;
739 qubit[SIZE] q;
740 for int i in [0:SIZE-1] {
741 t q[i];
742 measure q[i];
743 }
744 """,
745 params=params,
746 )
747
748 for idx in res:
749 assert res[idx]["status"] == "success"
750 assert res[idx]["physicalCounts"] is not None
751 assert (
752 res[idx]["jobParams"]["qubitParams"]["name"]
753 == params.items[idx].qubit_params.name
754 )
755 assert res[idx]["logicalCounts"] == LogicalCounts(
756 {
757 "numQubits": 10,
758 "tCount": 10,
759 "rotationCount": 0,
760 "rotationDepth": 0,
761 "cczCount": 0,
762 "measurementCount": 10,
763 }
764 )
765 assert res[2]["jobParams"]["qecScheme"]["name"] == QECScheme.FLOQUET_CODE
766
767
768def test_qasm_estimation_with_multiple_params_from_python_callable() -> None:
769 init(target_profile=TargetProfile.Unrestricted)
770
771 params = EstimatorParams(3)
772 params.items[0].qubit_params.name = QubitParams.GATE_US_E3
773 params.items[0].error_budget = 0.333
774 params.items[1].qubit_params.name = QubitParams.GATE_US_E4
775 params.items[1].error_budget = 0.333
776 params.items[2].qubit_params.name = QubitParams.MAJ_NS_E6
777 params.items[2].qec_scheme.name = QECScheme.FLOQUET_CODE
778 params.items[2].error_budget = 0.333
779 assert params.as_dict() == {
780 "items": [
781 {
782 "qubitParams": {"name": "qubit_gate_us_e3"},
783 "errorBudget": 0.333,
784 },
785 {
786 "qubitParams": {"name": "qubit_gate_us_e4"},
787 "errorBudget": 0.333,
788 },
789 {
790 "qubitParams": {"name": "qubit_maj_ns_e6"},
791 "qecScheme": {"name": "floquet_code"},
792 "errorBudget": 0.333,
793 },
794 ],
795 "resumeAfterFailedItem": True,
796 }
797
798 import_openqasm(
799 """
800 include "stdgates.inc";
801 const int SIZE = 10;
802 qubit[SIZE] q;
803 for int i in [0:SIZE-1] {
804 t q[i];
805 measure q[i];
806 }
807 """,
808 name="Test",
809 )
810
811 res = estimate(code.Test, params=params)
812
813 for idx in res:
814 assert res[idx]["status"] == "success"
815 assert res[idx]["physicalCounts"] is not None
816 assert (
817 res[idx]["jobParams"]["qubitParams"]["name"]
818 == params.items[idx].qubit_params.name
819 )
820 assert res[idx]["logicalCounts"] == LogicalCounts(
821 {
822 "numQubits": 10,
823 "tCount": 10,
824 "rotationCount": 0,
825 "rotationDepth": 0,
826 "cczCount": 0,
827 "measurementCount": 10,
828 }
829 )
830 assert res[2]["jobParams"]["qecScheme"]["name"] == QECScheme.FLOQUET_CODE
831
832
833def test_qasm_estimation_with_multiple_params_from_python_callable_with_arg() -> None:
834 init(target_profile=TargetProfile.Unrestricted)
835
836 params = EstimatorParams(3)
837 params.items[0].qubit_params.name = QubitParams.GATE_US_E3
838 params.items[0].error_budget = 0.333
839 params.items[1].qubit_params.name = QubitParams.GATE_US_E4
840 params.items[1].error_budget = 0.333
841 params.items[2].qubit_params.name = QubitParams.MAJ_NS_E6
842 params.items[2].qec_scheme.name = QECScheme.FLOQUET_CODE
843 params.items[2].error_budget = 0.333
844 assert params.as_dict() == {
845 "items": [
846 {
847 "qubitParams": {"name": "qubit_gate_us_e3"},
848 "errorBudget": 0.333,
849 },
850 {
851 "qubitParams": {"name": "qubit_gate_us_e4"},
852 "errorBudget": 0.333,
853 },
854 {
855 "qubitParams": {"name": "qubit_maj_ns_e6"},
856 "qecScheme": {"name": "floquet_code"},
857 "errorBudget": 0.333,
858 },
859 ],
860 "resumeAfterFailedItem": True,
861 }
862
863 import_openqasm(
864 """
865 include "stdgates.inc";
866 input int discard;
867 const int SIZE = 7;
868 qubit[SIZE] q;
869 for int i in [0:SIZE-1] {
870 t q[i];
871 measure q[i];
872 }
873 """,
874 name="Test",
875 )
876
877 res = estimate(code.Test, params, 8)
878
879 for idx in res:
880 assert res[idx]["status"] == "success"
881 assert res[idx]["physicalCounts"] is not None
882 assert (
883 res[idx]["jobParams"]["qubitParams"]["name"]
884 == params.items[idx].qubit_params.name
885 )
886 assert res[idx]["logicalCounts"] == LogicalCounts(
887 {
888 "numQubits": 7,
889 "tCount": 7,
890 "rotationCount": 0,
891 "rotationDepth": 0,
892 "cczCount": 0,
893 "measurementCount": 7,
894 }
895 )
896 assert res[2]["jobParams"]["qecScheme"]["name"] == QECScheme.FLOQUET_CODE
897