microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.18.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/pip/tests/test_qasm.py

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