microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/pythontelem

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_eval/src/intrinsic/tests.rs

1599lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#![allow(clippy::needless_raw_string_hashes)]
5
6use std::f64::consts;
7
8use crate::backend::{Backend, SparseSim};
9use crate::tests::eval_graph;
10use crate::Env;
11use crate::{
12 output::{GenericReceiver, Receiver},
13 val::Value,
14 Error,
15};
16use expect_test::{expect, Expect};
17use indoc::indoc;
18use num_bigint::BigInt;
19use qsc_data_structures::language_features::LanguageFeatures;
20use qsc_data_structures::target::TargetCapabilityFlags;
21use qsc_fir::fir;
22use qsc_frontend::compile::{self, compile, PackageStore, SourceMap};
23use qsc_lowerer::map_hir_package_to_fir;
24use qsc_passes::{run_core_passes, run_default_passes, PackageType};
25
26#[derive(Default)]
27struct CustomSim {
28 sim: SparseSim,
29}
30
31impl Backend for CustomSim {
32 type ResultType = bool;
33
34 fn ccx(&mut self, ctl0: usize, ctl1: usize, q: usize) {
35 self.sim.ccx(ctl0, ctl1, q);
36 }
37
38 fn cx(&mut self, ctl: usize, q: usize) {
39 self.sim.cx(ctl, q);
40 }
41
42 fn cy(&mut self, ctl: usize, q: usize) {
43 self.sim.cy(ctl, q);
44 }
45
46 fn cz(&mut self, ctl: usize, q: usize) {
47 self.sim.cz(ctl, q);
48 }
49
50 fn h(&mut self, q: usize) {
51 self.sim.h(q);
52 }
53
54 fn m(&mut self, q: usize) -> Self::ResultType {
55 self.sim.m(q)
56 }
57
58 fn mresetz(&mut self, q: usize) -> Self::ResultType {
59 self.sim.mresetz(q)
60 }
61
62 fn reset(&mut self, q: usize) {
63 self.sim.reset(q);
64 }
65
66 fn rx(&mut self, theta: f64, q: usize) {
67 self.sim.rx(theta, q);
68 }
69
70 fn rxx(&mut self, theta: f64, q0: usize, q1: usize) {
71 self.sim.rxx(theta, q0, q1);
72 }
73
74 fn ry(&mut self, theta: f64, q: usize) {
75 self.sim.ry(theta, q);
76 }
77
78 fn ryy(&mut self, theta: f64, q0: usize, q1: usize) {
79 self.sim.ryy(theta, q0, q1);
80 }
81
82 fn rz(&mut self, theta: f64, q: usize) {
83 self.sim.rz(theta, q);
84 }
85
86 fn rzz(&mut self, theta: f64, q0: usize, q1: usize) {
87 self.sim.rzz(theta, q0, q1);
88 }
89
90 fn sadj(&mut self, q: usize) {
91 self.sim.sadj(q);
92 }
93
94 fn s(&mut self, q: usize) {
95 self.sim.s(q);
96 }
97
98 fn swap(&mut self, q0: usize, q1: usize) {
99 self.sim.swap(q0, q1);
100 }
101
102 fn tadj(&mut self, q: usize) {
103 self.sim.tadj(q);
104 }
105
106 fn t(&mut self, q: usize) {
107 self.sim.t(q);
108 }
109
110 fn x(&mut self, q: usize) {
111 self.sim.x(q);
112 }
113
114 fn y(&mut self, q: usize) {
115 self.sim.y(q);
116 }
117
118 fn z(&mut self, q: usize) {
119 self.sim.z(q);
120 }
121
122 fn qubit_allocate(&mut self) -> usize {
123 self.sim.qubit_allocate()
124 }
125
126 fn qubit_release(&mut self, q: usize) {
127 self.sim.qubit_release(q);
128 }
129
130 fn qubit_swap_id(&mut self, q0: usize, q1: usize) {
131 self.sim.qubit_swap_id(q0, q1);
132 }
133
134 fn capture_quantum_state(
135 &mut self,
136 ) -> (Vec<(num_bigint::BigUint, num_complex::Complex<f64>)>, usize) {
137 self.sim.capture_quantum_state()
138 }
139
140 fn qubit_is_zero(&mut self, q: usize) -> bool {
141 self.sim.qubit_is_zero(q)
142 }
143
144 fn custom_intrinsic(&mut self, name: &str, arg: Value) -> Option<Result<Value, String>> {
145 match name {
146 "Add1" => Some(Ok(Value::Int(arg.unwrap_int() + 1))),
147 "Check" => Some(Err("cannot verify input".to_string())),
148 _ => None,
149 }
150 }
151}
152
153fn check_intrinsic(file: &str, expr: &str, out: &mut impl Receiver) -> Result<Value, Error> {
154 let mut core = compile::core();
155 run_core_passes(&mut core);
156 let fir_store = fir::PackageStore::new();
157 let core_fir = qsc_lowerer::Lowerer::new().lower_package(&core.package, &fir_store);
158 let mut store = PackageStore::new(core);
159
160 let mut std = compile::std(&store, TargetCapabilityFlags::all());
161 assert!(std.errors.is_empty());
162 assert!(run_default_passes(store.core(), &mut std, PackageType::Lib).is_empty());
163 let std_fir = qsc_lowerer::Lowerer::new().lower_package(&std.package, &fir_store);
164 let std_id = store.insert(std);
165
166 let sources = SourceMap::new([("test".into(), file.into())], Some(expr.into()));
167 let mut unit = compile(
168 &store,
169 &[(std_id, None)],
170 sources,
171 TargetCapabilityFlags::all(),
172 LanguageFeatures::default(),
173 );
174 assert!(unit.errors.is_empty());
175 assert!(run_default_passes(store.core(), &mut unit, PackageType::Lib).is_empty());
176 let unit_fir = qsc_lowerer::Lowerer::new().lower_package(&unit.package, &fir_store);
177 let entry = unit_fir.entry_exec_graph.clone();
178
179 let id = store.insert(unit);
180
181 let mut fir_store = fir::PackageStore::new();
182 fir_store.insert(
183 map_hir_package_to_fir(qsc_hir::hir::PackageId::CORE),
184 core_fir,
185 );
186 fir_store.insert(map_hir_package_to_fir(std_id), std_fir);
187 fir_store.insert(map_hir_package_to_fir(id), unit_fir);
188
189 eval_graph(
190 entry,
191 &mut CustomSim::default(),
192 &fir_store,
193 map_hir_package_to_fir(id),
194 &mut Env::default(),
195 out,
196 )
197 .map_err(|e| e.0)
198}
199
200fn check_intrinsic_result(file: &str, expr: &str, expect: &Expect) {
201 let mut stdout = vec![];
202 let mut out = GenericReceiver::new(&mut stdout);
203 match check_intrinsic(file, expr, &mut out) {
204 Ok(result) => expect.assert_eq(&result.to_string()),
205 Err(e) => expect.assert_eq(&e.to_string()),
206 }
207}
208
209fn check_intrinsic_output(file: &str, expr: &str, expect: &Expect) {
210 let mut stdout = vec![];
211 let mut out = GenericReceiver::new(&mut stdout);
212 match check_intrinsic(file, expr, &mut out) {
213 Ok(..) => expect.assert_eq(
214 &String::from_utf8(stdout).expect("content should be convertable to string"),
215 ),
216 Err(e) => expect.assert_eq(&e.to_string()),
217 }
218}
219
220fn check_intrinsic_value(file: &str, expr: &str, val: &Value) {
221 let mut stdout = vec![];
222 let mut out = GenericReceiver::new(&mut stdout);
223 match check_intrinsic(file, expr, &mut out) {
224 Ok(result) => assert_eq!(&result, val),
225 Err(e) => panic!("{e:?}"),
226 }
227}
228
229#[test]
230fn int_as_double() {
231 check_intrinsic_result(
232 "",
233 "Microsoft.Quantum.Convert.IntAsDouble(2)",
234 &expect!["2.0"],
235 );
236}
237
238#[test]
239fn int_as_double_precision_loss() {
240 check_intrinsic_result(
241 "",
242 "Microsoft.Quantum.Convert.IntAsDouble(9_223_372_036_854_775_807)",
243 &expect!["9223372036854775808.0"],
244 );
245}
246
247#[test]
248fn double_as_string_with_precision() {
249 check_intrinsic_result(
250 "",
251 "Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.8414709848078965, 4)",
252 &expect!["0.8415"],
253 );
254}
255
256#[test]
257fn double_as_string_with_precision_extend() {
258 check_intrinsic_result(
259 "",
260 "Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.8, 5)",
261 &expect!["0.80000"],
262 );
263}
264
265#[test]
266fn double_as_string_with_precision_negative_error() {
267 check_intrinsic_result(
268 "",
269 "Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.8, -5)",
270 &expect!["negative integers cannot be used here: -5"],
271 );
272}
273
274#[test]
275fn double_as_string_with_zero_precision() {
276 check_intrinsic_result(
277 "",
278 "Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.47, 0)",
279 &expect!["0."],
280 );
281}
282
283#[test]
284fn double_as_string_with_zero_precision_rounding() {
285 check_intrinsic_result(
286 "",
287 "Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.913, 0)",
288 &expect!["1."],
289 );
290}
291
292#[test]
293fn dump_machine() {
294 check_intrinsic_output(
295 "",
296 "Microsoft.Quantum.Diagnostics.DumpMachine()",
297 &expect![[r#"
298 STATE:
299 |0⟩: 1.0000+0.0000𝑖
300 "#]],
301 );
302}
303
304#[test]
305fn dump_machine_qubit_count() {
306 check_intrinsic_output(
307 "",
308 indoc! {"{
309 use qs = Qubit[4];
310 Microsoft.Quantum.Diagnostics.DumpMachine();
311 }"},
312 &expect![[r#"
313 STATE:
314 |0000⟩: 1.0000+0.0000𝑖
315 "#]],
316 );
317}
318
319#[test]
320fn dump_machine_endianness() {
321 check_intrinsic_output(
322 "",
323 indoc! {"{
324 use qs = Qubit[4];
325 X(qs[1]);
326 Microsoft.Quantum.Diagnostics.DumpMachine();
327 X(qs[1]);
328 }"},
329 &expect![[r#"
330 STATE:
331 |0100⟩: 1.0000+0.0000𝑖
332 "#]],
333 );
334}
335
336#[test]
337fn dump_register_all_qubits() {
338 check_intrinsic_output(
339 "",
340 indoc! {"{
341 use qs = Qubit[4];
342 X(qs[1]);
343 Microsoft.Quantum.Diagnostics.DumpRegister(qs);
344 X(qs[1]);
345 }"},
346 &expect![[r#"
347 STATE:
348 |0100⟩: 1.0000+0.0000𝑖
349 "#]],
350 );
351}
352
353#[test]
354fn dump_register_subset_qubits() {
355 check_intrinsic_output(
356 "",
357 indoc! {"{
358 use qs = Qubit[4];
359 X(qs[1]);
360 Microsoft.Quantum.Diagnostics.DumpRegister([qs[1], qs[2]]);
361 X(qs[1]);
362 }"},
363 &expect![[r#"
364 STATE:
365 |10⟩: 1.0000+0.0000𝑖
366 "#]],
367 );
368}
369
370#[test]
371fn dump_register_subset_entangled_within_subset_is_separable() {
372 check_intrinsic_output(
373 "",
374 indoc! {"{
375 use (q1, q2, q3) = (Qubit(), Qubit(), Qubit());
376 H(q1);
377 CNOT(q1, q3);
378 Microsoft.Quantum.Diagnostics.DumpRegister([q1, q3]);
379 Reset(q1);
380 Reset(q2);
381 Reset(q3);
382 }"},
383 &expect![[r#"
384 STATE:
385 |00⟩: 0.7071+0.0000𝑖
386 |11⟩: 0.7071+0.0000𝑖
387 "#]],
388 );
389}
390
391#[test]
392fn dump_register_subset_entangled_with_other_qubits_not_separable() {
393 check_intrinsic_result(
394 "",
395 indoc! {"{
396 use (q1, q2, q3) = (Qubit(), Qubit(), Qubit());
397 H(q1);
398 CNOT(q1, q3);
399 Microsoft.Quantum.Diagnostics.DumpRegister([q1, q2]);
400 }"},
401 &expect!["qubits are not separable"],
402 );
403}
404
405#[test]
406fn dump_register_other_qubits_superposition_is_separable() {
407 check_intrinsic_output(
408 "",
409 indoc! {"{
410 use qs = Qubit[3];
411 H(qs[0]);
412 H(qs[2]);
413 Microsoft.Quantum.Diagnostics.DumpRegister(qs[...1]);
414 ResetAll(qs);
415 }"},
416 &expect![[r#"
417 STATE:
418 |00⟩: 0.7071+0.0000𝑖
419 |10⟩: 0.7071+0.0000𝑖
420 "#]],
421 );
422}
423
424#[test]
425fn dump_register_other_qubits_one_state_is_separable() {
426 check_intrinsic_output(
427 "",
428 indoc! {"{
429 use qs = Qubit[3];
430 H(qs[0]);
431 X(qs[2]);
432 Microsoft.Quantum.Diagnostics.DumpRegister(qs[...1]);
433 ResetAll(qs);
434 }"},
435 &expect![[r#"
436 STATE:
437 |00⟩: 0.7071+0.0000𝑖
438 |10⟩: 0.7071+0.0000𝑖
439 "#]],
440 );
441}
442
443#[test]
444fn dump_register_other_qubits_phase_reflected_in_subset() {
445 check_intrinsic_output(
446 "",
447 indoc! {"{
448 use qs = Qubit[3];
449 H(qs[0]);
450 X(qs[2]);
451 Z(qs[2]);
452 Microsoft.Quantum.Diagnostics.DumpRegister(qs[...1]);
453 ResetAll(qs);
454 }"},
455 &expect![[r#"
456 STATE:
457 |00⟩: −0.7071+0.0000𝑖
458 |10⟩: −0.7071+0.0000𝑖
459 "#]],
460 );
461}
462
463#[test]
464fn dump_register_qubits_reorder_output() {
465 check_intrinsic_output(
466 "",
467 indoc! {"{
468 use qs = Qubit[5];
469 H(qs[0]);
470 X(qs[2]);
471 Microsoft.Quantum.Diagnostics.DumpMachine();
472 Microsoft.Quantum.Diagnostics.DumpRegister(qs[2..-1...]);
473 ResetAll(qs);
474 }"},
475 &expect![[r#"
476 STATE:
477 |00100⟩: 0.7071+0.0000𝑖
478 |10100⟩: 0.7071+0.0000𝑖
479 STATE:
480 |100⟩: 0.7071+0.0000𝑖
481 |101⟩: 0.7071+0.0000𝑖
482 "#]],
483 );
484}
485
486#[test]
487fn dump_register_qubits_reorder_output_should_be_sorted() {
488 check_intrinsic_output(
489 "",
490 indoc! {"{
491 use qs = Qubit[5];
492 H(qs[0]);
493 H(qs[2]);
494 Microsoft.Quantum.Diagnostics.DumpMachine();
495 Microsoft.Quantum.Diagnostics.DumpRegister(qs[0..2..3]);
496 ResetAll(qs);
497 }"},
498 &expect![[r#"
499 STATE:
500 |00000⟩: 0.5000+0.0000𝑖
501 |00100⟩: 0.5000+0.0000𝑖
502 |10000⟩: 0.5000+0.0000𝑖
503 |10100⟩: 0.5000+0.0000𝑖
504 STATE:
505 |00⟩: 0.5000+0.0000𝑖
506 |01⟩: 0.5000+0.0000𝑖
507 |10⟩: 0.5000+0.0000𝑖
508 |11⟩: 0.5000+0.0000𝑖
509 "#]],
510 );
511}
512
513#[test]
514fn dump_register_qubits_not_unique_fails() {
515 check_intrinsic_result(
516 "",
517 indoc! {"{
518 use qs = Qubit[3];
519 H(qs[0]);
520 Microsoft.Quantum.Diagnostics.DumpRegister([qs[0], qs[0]]);
521 }"},
522 &expect!["qubits in invocation are not unique"],
523 );
524}
525
526#[test]
527fn dump_register_target_in_minus_with_other_in_zero() {
528 check_intrinsic_output(
529 "",
530 indoc! {"{
531 use qs = Qubit[2];
532 X(qs[0]);
533 H(qs[0]);
534 Microsoft.Quantum.Diagnostics.DumpRegister([qs[0]]);
535 ResetAll(qs);
536 }"},
537 &expect![[r#"
538 STATE:
539 |0⟩: 0.7071+0.0000𝑖
540 |1⟩: −0.7071+0.0000𝑖
541 "#]],
542 );
543}
544
545#[test]
546fn dump_register_target_in_minus_with_other_in_one() {
547 check_intrinsic_output(
548 "",
549 indoc! {"{
550 use qs = Qubit[2];
551 X(qs[1]);
552 X(qs[0]);
553 H(qs[0]);
554 Microsoft.Quantum.Diagnostics.DumpRegister([qs[0]]);
555 ResetAll(qs);
556 }"},
557 &expect![[r#"
558 STATE:
559 |0⟩: 0.7071+0.0000𝑖
560 |1⟩: −0.7071+0.0000𝑖
561 "#]],
562 );
563}
564
565#[test]
566fn dump_register_all_qubits_normalized_is_same_as_dump_machine() {
567 check_intrinsic_output(
568 "",
569 indoc! {
570 "{
571 import Std.Diagnostics.*;
572 use qs = Qubit[2];
573
574 let alpha = -4.20025;
575 let beta = 2.04776;
576 let gamma = -5.47097;
577
578 within{
579 Ry(alpha, qs[0]);
580 Ry(beta, qs[1]);
581 CNOT(qs[0], qs[1]);
582 Ry(gamma, qs[1]);
583 }
584 apply{
585 DumpRegister(qs);
586 DumpMachine();
587 }
588 }"
589 },
590 &expect![[r#"
591 STATE:
592 |00⟩: 0.0709+0.0000𝑖
593 |01⟩: 0.5000+0.0000𝑖
594 |10⟩: 0.5000+0.0000𝑖
595 |11⟩: 0.7036+0.0000𝑖
596 STATE:
597 |00⟩: 0.0709+0.0000𝑖
598 |01⟩: 0.5000+0.0000𝑖
599 |10⟩: 0.5000+0.0000𝑖
600 |11⟩: 0.7036+0.0000𝑖
601 "#]],
602 );
603}
604
605#[test]
606fn message() {
607 check_intrinsic_output(
608 "",
609 r#"Message("Hello, World!")"#,
610 &expect![[r#"
611 Hello, World!
612 "#]],
613 );
614}
615
616#[test]
617fn check_zero() {
618 check_intrinsic_result(
619 "",
620 "{use q = Qubit(); Microsoft.Quantum.Diagnostics.CheckZero(q)}",
621 &expect!["true"],
622 );
623}
624
625#[test]
626fn check_zero_false() {
627 check_intrinsic_result(
628 "",
629 indoc! {"{
630 use q = Qubit();
631 X(q);
632 let isZero = Microsoft.Quantum.Diagnostics.CheckZero(q);
633 X(q);
634 isZero
635 }"},
636 &expect!["false"],
637 );
638}
639
640#[test]
641fn length() {
642 check_intrinsic_value("", "Length([1, 2, 3])", &Value::Int(3));
643}
644
645#[test]
646fn arccos() {
647 check_intrinsic_value(
648 "",
649 "Microsoft.Quantum.Math.ArcCos(0.3)",
650 &Value::Double((0.3f64).acos()),
651 );
652}
653
654#[test]
655fn arcsin() {
656 check_intrinsic_value(
657 "",
658 "Microsoft.Quantum.Math.ArcSin(0.3)",
659 &Value::Double((0.3f64).asin()),
660 );
661}
662
663#[test]
664fn arctan() {
665 check_intrinsic_value(
666 "",
667 "Microsoft.Quantum.Math.ArcTan(0.3)",
668 &Value::Double((0.3f64).atan()),
669 );
670}
671
672#[test]
673fn arctan2() {
674 check_intrinsic_value(
675 "",
676 "Microsoft.Quantum.Math.ArcTan2(0.3, 0.7)",
677 &Value::Double((0.3f64).atan2(0.7)),
678 );
679}
680
681#[test]
682fn cos() {
683 check_intrinsic_value(
684 "",
685 "Microsoft.Quantum.Math.Cos(Microsoft.Quantum.Math.PI())",
686 &Value::Double((consts::PI).cos()),
687 );
688}
689
690#[test]
691fn cosh() {
692 check_intrinsic_value(
693 "",
694 "Microsoft.Quantum.Math.Cosh(Microsoft.Quantum.Math.PI())",
695 &Value::Double((consts::PI).cosh()),
696 );
697}
698
699#[test]
700fn sin() {
701 check_intrinsic_value(
702 "",
703 "Microsoft.Quantum.Math.Sin(Microsoft.Quantum.Math.PI())",
704 &Value::Double((consts::PI).sin()),
705 );
706}
707
708#[test]
709fn sinh() {
710 check_intrinsic_value(
711 "",
712 "Microsoft.Quantum.Math.Sinh(Microsoft.Quantum.Math.PI())",
713 &Value::Double((consts::PI).sinh()),
714 );
715}
716
717#[test]
718fn tan() {
719 check_intrinsic_value(
720 "",
721 "Microsoft.Quantum.Math.Tan(Microsoft.Quantum.Math.PI())",
722 &Value::Double((consts::PI).tan()),
723 );
724}
725
726#[test]
727fn tanh() {
728 check_intrinsic_value(
729 "",
730 "Microsoft.Quantum.Math.Tanh(Microsoft.Quantum.Math.PI())",
731 &Value::Double((consts::PI).tanh()),
732 );
733}
734
735#[test]
736fn draw_random_int() {
737 check_intrinsic_value(
738 "",
739 "Microsoft.Quantum.Random.DrawRandomInt(5,5)",
740 &Value::Int(5),
741 );
742}
743
744#[test]
745fn draw_random_double() {
746 check_intrinsic_value(
747 "",
748 "Microsoft.Quantum.Random.DrawRandomDouble(5.0,5.0)",
749 &Value::Double(5.0),
750 );
751}
752
753#[test]
754fn draw_random_bool() {
755 check_intrinsic_value(
756 "",
757 "Microsoft.Quantum.Random.DrawRandomBool(0.0)",
758 &Value::Bool(false),
759 );
760 check_intrinsic_value(
761 "",
762 "Microsoft.Quantum.Random.DrawRandomBool(1.0)",
763 &Value::Bool(true),
764 );
765}
766
767#[test]
768fn truncate() {
769 check_intrinsic_value("", "Microsoft.Quantum.Math.Truncate(3.1)", &Value::Int(3));
770 check_intrinsic_value("", "Microsoft.Quantum.Math.Truncate(3.9)", &Value::Int(3));
771 check_intrinsic_value("", "Microsoft.Quantum.Math.Truncate(-3.1)", &Value::Int(-3));
772 check_intrinsic_value("", "Microsoft.Quantum.Math.Truncate(-3.9)", &Value::Int(-3));
773}
774
775#[test]
776fn sqrt() {
777 check_intrinsic_value("", "Microsoft.Quantum.Math.Sqrt(0.0)", &Value::Double(0.0));
778 check_intrinsic_value("", "Microsoft.Quantum.Math.Sqrt(81.0)", &Value::Double(9.0));
779}
780
781#[test]
782fn log() {
783 check_intrinsic_value("", "Microsoft.Quantum.Math.Log(1.0)", &Value::Double(0.0));
784 check_intrinsic_value(
785 "",
786 "Microsoft.Quantum.Math.Log(Microsoft.Quantum.Math.E())",
787 &Value::Double(1.0),
788 );
789}
790
791#[test]
792fn int_as_bigint() {
793 check_intrinsic_value(
794 "",
795 "Microsoft.Quantum.Convert.IntAsBigInt(0)",
796 &Value::BigInt(BigInt::from(0)),
797 );
798 check_intrinsic_value(
799 "",
800 "Microsoft.Quantum.Convert.IntAsBigInt(-10000)",
801 &Value::BigInt(BigInt::from(-10000)),
802 );
803}
804
805#[test]
806fn ccx() {
807 check_intrinsic_result(
808 "",
809 indoc! {r#"{
810 use (q1, q2, q3) = (Qubit(), Qubit(), Qubit());
811 QIR.Intrinsic.__quantum__qis__ccx__body(q1, q2, q3);
812 if not Microsoft.Quantum.Diagnostics.CheckZero(q3) {
813 fail "Qubit should still be in zero state.";
814 }
815 X(q1);
816 X(q2);
817 QIR.Intrinsic.__quantum__qis__ccx__body(q1, q2, q3);
818 if Microsoft.Quantum.Diagnostics.CheckZero(q3) {
819 fail "Qubit should be in one state.";
820 }
821 X(q3);
822 X(q2);
823 X(q1);
824 Microsoft.Quantum.Diagnostics.CheckZero(q3)
825 }"#},
826 &expect!["true"],
827 );
828}
829
830#[test]
831fn cx() {
832 check_intrinsic_result(
833 "",
834 indoc! {r#"{
835 use (q1, q2) = (Qubit(), Qubit());
836 QIR.Intrinsic.__quantum__qis__cx__body(q1, q2);
837 if not Microsoft.Quantum.Diagnostics.CheckZero(q2) {
838 fail "Qubit should still be in zero state.";
839 }
840 X(q1);
841 QIR.Intrinsic.__quantum__qis__cx__body(q1, q2);
842 if Microsoft.Quantum.Diagnostics.CheckZero(q2) {
843 fail "Qubit should be in one state.";
844 }
845 X(q2);
846 X(q1);
847 Microsoft.Quantum.Diagnostics.CheckZero(q2)
848 }"#},
849 &expect!["true"],
850 );
851}
852
853#[test]
854fn cy() {
855 check_intrinsic_result(
856 "",
857 indoc! {r#"{
858 use (q1, q2) = (Qubit(), Qubit());
859 QIR.Intrinsic.__quantum__qis__cy__body(q1, q2);
860 if not Microsoft.Quantum.Diagnostics.CheckZero(q2) {
861 fail "Qubit should still be in zero state.";
862 }
863 X(q1);
864 QIR.Intrinsic.__quantum__qis__cy__body(q1, q2);
865 if Microsoft.Quantum.Diagnostics.CheckZero(q2) {
866 fail "Qubit should be in one state.";
867 }
868 Y(q2);
869 X(q1);
870 Microsoft.Quantum.Diagnostics.CheckZero(q2)
871 }"#},
872 &expect!["true"],
873 );
874}
875
876#[test]
877fn cz() {
878 check_intrinsic_result(
879 "",
880 indoc! {r#"{
881 use (q1, q2) = (Qubit(), Qubit());
882 H(q2);
883 QIR.Intrinsic.__quantum__qis__cz__body(q1, q2);
884 H(q2);
885 if not Microsoft.Quantum.Diagnostics.CheckZero(q2) {
886 fail "Qubit should still be in zero state.";
887 }
888 X(q1);
889 H(q2);
890 QIR.Intrinsic.__quantum__qis__cz__body(q1, q2);
891 H(q2);
892 if Microsoft.Quantum.Diagnostics.CheckZero(q2) {
893 fail "Qubit should be in one state.";
894 }
895 X(q2);
896 X(q1);
897 Microsoft.Quantum.Diagnostics.CheckZero(q2)
898 }"#},
899 &expect!["true"],
900 );
901}
902
903#[test]
904fn rx() {
905 check_intrinsic_result(
906 "",
907 indoc! {r#"{
908 use q1 = Qubit();
909 let pi = Microsoft.Quantum.Math.PI();
910 QIR.Intrinsic.__quantum__qis__rx__body(pi, q1);
911 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
912 fail "Qubit should be in one state.";
913 }
914 X(q1);
915 Microsoft.Quantum.Diagnostics.CheckZero(q1)
916 }"#},
917 &expect!["true"],
918 );
919}
920
921#[test]
922fn rxx() {
923 check_intrinsic_result(
924 "",
925 indoc! {r#"{
926 use (q1, q2) = (Qubit(), Qubit());
927 let pi = Microsoft.Quantum.Math.PI();
928 QIR.Intrinsic.__quantum__qis__rxx__body(pi, q1, q2);
929 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
930 fail "Qubit should be in one state.";
931 }
932 if Microsoft.Quantum.Diagnostics.CheckZero(q2) {
933 fail "Qubit 2 should be in one state.";
934 }
935 X(q2);
936 X(q1);
937 (Microsoft.Quantum.Diagnostics.CheckZero(q1), Microsoft.Quantum.Diagnostics.CheckZero(q2))
938 }"#},
939 &expect!["(true, true)"],
940 );
941}
942
943#[test]
944fn ry() {
945 check_intrinsic_result(
946 "",
947 indoc! {r#"{
948 use q1 = Qubit();
949 let pi = Microsoft.Quantum.Math.PI();
950 QIR.Intrinsic.__quantum__qis__ry__body(pi, q1);
951 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
952 fail "Qubit should be in one state.";
953 }
954 Y(q1);
955 Microsoft.Quantum.Diagnostics.CheckZero(q1)
956 }"#},
957 &expect!["true"],
958 );
959}
960
961#[test]
962fn ryy() {
963 check_intrinsic_result(
964 "",
965 indoc! {r#"{
966 use (q1, q2) = (Qubit(), Qubit());
967 let pi = Microsoft.Quantum.Math.PI();
968 QIR.Intrinsic.__quantum__qis__ryy__body(pi, q1, q2);
969 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
970 fail "Qubit should be in one state.";
971 }
972 if Microsoft.Quantum.Diagnostics.CheckZero(q2) {
973 fail "Qubit 2 should be in one state.";
974 }
975 Y(q2);
976 Y(q1);
977 (Microsoft.Quantum.Diagnostics.CheckZero(q1), Microsoft.Quantum.Diagnostics.CheckZero(q2))
978 }"#},
979 &expect!["(true, true)"],
980 );
981}
982
983#[test]
984fn rz() {
985 check_intrinsic_result(
986 "",
987 indoc! {r#"{
988 use q1 = Qubit();
989 let pi = Microsoft.Quantum.Math.PI();
990 H(q1);
991 QIR.Intrinsic.__quantum__qis__rz__body(pi, q1);
992 H(q1);
993 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
994 fail "Qubit should be in one state.";
995 }
996 H(q1);
997 Z(q1);
998 H(q1);
999 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1000 }"#},
1001 &expect!["true"],
1002 );
1003}
1004
1005#[test]
1006fn rzz() {
1007 check_intrinsic_result(
1008 "",
1009 indoc! {r#"{
1010 use (q1, q2) = (Qubit(), Qubit());
1011 let pi = Microsoft.Quantum.Math.PI();
1012 H(q1);
1013 H(q2);
1014 QIR.Intrinsic.__quantum__qis__rzz__body(pi, q1, q2);
1015 H(q1);
1016 H(q2);
1017 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1018 fail "Qubit should be in one state.";
1019 }
1020 if Microsoft.Quantum.Diagnostics.CheckZero(q2) {
1021 fail "Qubit 2 should be in one state.";
1022 }
1023 H(q2);
1024 H(q1);
1025 Z(q2);
1026 Z(q1);
1027 H(q2);
1028 H(q1);
1029 (Microsoft.Quantum.Diagnostics.CheckZero(q1), Microsoft.Quantum.Diagnostics.CheckZero(q2))
1030 }"#},
1031 &expect!["(true, true)"],
1032 );
1033}
1034
1035#[test]
1036fn h() {
1037 check_intrinsic_result(
1038 "",
1039 indoc! {r#"{
1040 use q1 = Qubit();
1041 QIR.Intrinsic.__quantum__qis__h__body(q1);
1042 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1043 fail "Qubit should be in one state.";
1044 }
1045 H(q1);
1046 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1047 }"#},
1048 &expect!["true"],
1049 );
1050}
1051
1052#[test]
1053fn s() {
1054 check_intrinsic_result(
1055 "",
1056 indoc! {r#"{
1057 use q1 = Qubit();
1058 H(q1);
1059 QIR.Intrinsic.__quantum__qis__s__body(q1);
1060 H(q1);
1061 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1062 fail "Qubit should be in one state.";
1063 }
1064 H(q1);
1065 QIR.Intrinsic.__quantum__qis__s__body(q1);
1066 QIR.Intrinsic.__quantum__qis__s__body(q1);
1067 QIR.Intrinsic.__quantum__qis__s__body(q1);
1068 H(q1);
1069 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1070 }"#},
1071 &expect!["true"],
1072 );
1073}
1074
1075#[test]
1076fn sadj() {
1077 check_intrinsic_result(
1078 "",
1079 indoc! {r#"{
1080 use q1 = Qubit();
1081 H(q1);
1082 QIR.Intrinsic.__quantum__qis__s__adj(q1);
1083 H(q1);
1084 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1085 fail "Qubit should be in one state.";
1086 }
1087 H(q1);
1088 QIR.Intrinsic.__quantum__qis__s__adj(q1);
1089 QIR.Intrinsic.__quantum__qis__s__adj(q1);
1090 QIR.Intrinsic.__quantum__qis__s__adj(q1);
1091 H(q1);
1092 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1093 }"#},
1094 &expect!["true"],
1095 );
1096}
1097
1098#[test]
1099fn t() {
1100 check_intrinsic_result(
1101 "",
1102 indoc! {r#"{
1103 use q1 = Qubit();
1104 H(q1);
1105 QIR.Intrinsic.__quantum__qis__t__body(q1);
1106 QIR.Intrinsic.__quantum__qis__t__body(q1);
1107 H(q1);
1108 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1109 fail "Qubit should be in one state.";
1110 }
1111 H(q1);
1112 QIR.Intrinsic.__quantum__qis__t__body(q1);
1113 QIR.Intrinsic.__quantum__qis__t__body(q1);
1114 QIR.Intrinsic.__quantum__qis__t__body(q1);
1115 QIR.Intrinsic.__quantum__qis__t__body(q1);
1116 QIR.Intrinsic.__quantum__qis__t__body(q1);
1117 QIR.Intrinsic.__quantum__qis__t__body(q1);
1118 H(q1);
1119 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1120 }"#},
1121 &expect!["true"],
1122 );
1123}
1124
1125#[test]
1126fn tadj() {
1127 check_intrinsic_result(
1128 "",
1129 indoc! {r#"{
1130 use q1 = Qubit();
1131 H(q1);
1132 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1133 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1134 H(q1);
1135 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1136 fail "Qubit should be in one state.";
1137 }
1138 H(q1);
1139 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1140 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1141 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1142 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1143 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1144 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1145 H(q1);
1146 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1147 }"#},
1148 &expect!["true"],
1149 );
1150}
1151
1152#[test]
1153fn x() {
1154 check_intrinsic_result(
1155 "",
1156 indoc! {r#"{
1157 use q1 = Qubit();
1158 QIR.Intrinsic.__quantum__qis__x__body(q1);
1159 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1160 fail "Qubit should be in one state.";
1161 }
1162 QIR.Intrinsic.__quantum__qis__x__body(q1);
1163 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1164 }"#},
1165 &expect!["true"],
1166 );
1167}
1168
1169#[test]
1170fn y() {
1171 check_intrinsic_result(
1172 "",
1173 indoc! {r#"{
1174 use q1 = Qubit();
1175 QIR.Intrinsic.__quantum__qis__y__body(q1);
1176 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1177 fail "Qubit should be in one state.";
1178 }
1179 QIR.Intrinsic.__quantum__qis__y__body(q1);
1180 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1181 }"#},
1182 &expect!["true"],
1183 );
1184}
1185
1186#[test]
1187fn z() {
1188 check_intrinsic_result(
1189 "",
1190 indoc! {r#"{
1191 use q1 = Qubit();
1192 H(q1);
1193 QIR.Intrinsic.__quantum__qis__z__body(q1);
1194 H(q1);
1195 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1196 fail "Qubit should be in one state.";
1197 }
1198 H(q1);
1199 QIR.Intrinsic.__quantum__qis__z__body(q1);
1200 H(q1);
1201 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1202 }"#},
1203 &expect!["true"],
1204 );
1205}
1206
1207#[test]
1208fn swap() {
1209 check_intrinsic_result(
1210 "",
1211 indoc! {r#"{
1212 use (q1, q2) = (Qubit(), Qubit());
1213 X(q2);
1214 QIR.Intrinsic.__quantum__qis__swap__body(q1, q2);
1215 if not Microsoft.Quantum.Diagnostics.CheckZero(q2) {
1216 fail "Qubit should be swapped to zero state.";
1217 }
1218 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1219 fail "Qubit should swapped to one state.";
1220 }
1221 X(q1);
1222 (Microsoft.Quantum.Diagnostics.CheckZero(q2), Microsoft.Quantum.Diagnostics.CheckZero(q2))
1223 }"#},
1224 &expect!["(true, true)"],
1225 );
1226}
1227
1228#[test]
1229fn reset() {
1230 check_intrinsic_result(
1231 "",
1232 indoc! {r#"{
1233 use q1 = Qubit();
1234 QIR.Intrinsic.__quantum__qis__reset__body(q1);
1235 if not Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1236 fail "Qubit should be in zero state.";
1237 }
1238 X(q1);
1239 QIR.Intrinsic.__quantum__qis__reset__body(q1);
1240 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1241 }"#},
1242 &expect!["true"],
1243 );
1244}
1245
1246#[test]
1247fn reset_all() {
1248 check_intrinsic_result(
1249 "",
1250 indoc! {r#"{
1251 use register = Qubit[2];
1252 ResetAll(register);
1253 if not Microsoft.Quantum.Diagnostics.CheckAllZero(register) {
1254 fail "Qubits should be in zero state.";
1255 }
1256
1257 for q in register {
1258 X(q);
1259 }
1260
1261 ResetAll(register);
1262 Microsoft.Quantum.Diagnostics.CheckAllZero(register)
1263 }"#},
1264 &expect!["true"],
1265 );
1266}
1267
1268#[test]
1269fn m() {
1270 check_intrinsic_result(
1271 "",
1272 indoc! {r#"{
1273 use q1 = Qubit();
1274 if not Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1275 fail "Qubit should be in zero state.";
1276 }
1277 let res1 = QIR.Intrinsic.__quantum__qis__m__body(q1);
1278 if One == res1 {
1279 fail "Qubit should measure Zero"
1280 }
1281 if not Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1282 fail "Qubit should be in zero state.";
1283 }
1284 X(q1);
1285 let res2 = (QIR.Intrinsic.__quantum__qis__m__body(q1), Microsoft.Quantum.Diagnostics.CheckZero(q1));
1286 X(q1);
1287 res2
1288 }"#},
1289 &expect!["(One, false)"],
1290 );
1291}
1292
1293#[test]
1294fn mresetz() {
1295 check_intrinsic_result(
1296 "",
1297 indoc! {r#"{
1298 use q1 = Qubit();
1299 if not Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1300 fail "Qubit should be in zero state.";
1301 }
1302 let res1 = QIR.Intrinsic.__quantum__qis__mresetz__body(q1);
1303 if One == res1 {
1304 fail "Qubit should measure Zero"
1305 }
1306 if not Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1307 fail "Qubit should be in zero state.";
1308 }
1309 X(q1);
1310 let res2 = QIR.Intrinsic.__quantum__qis__mresetz__body(q1);
1311 (res2, Microsoft.Quantum.Diagnostics.CheckZero(q1))
1312 }"#},
1313 &expect!["(One, true)"],
1314 );
1315}
1316
1317#[test]
1318fn unknown_intrinsic() {
1319 check_intrinsic_result(
1320 indoc! {"
1321 namespace Test {
1322 function Foo() : Int {
1323 body intrinsic;
1324 }
1325 }
1326 "},
1327 "Test.Foo()",
1328 &expect!["unknown intrinsic `Foo`"],
1329 );
1330}
1331
1332#[test]
1333fn custom_intrinsic_success() {
1334 check_intrinsic_result(
1335 indoc! {"
1336 namespace Test {
1337 function Add1(input : Int) : Int {
1338 body intrinsic;
1339 }
1340 }
1341 "},
1342 "Test.Add1(1)",
1343 &expect!["2"],
1344 );
1345}
1346
1347#[test]
1348fn custom_intrinsic_failure() {
1349 check_intrinsic_result(
1350 indoc! {"
1351 namespace Test {
1352 function Check(input : Int) : Int {
1353 body intrinsic;
1354 }
1355 }
1356 "},
1357 "Test.Check(1)",
1358 &expect!["intrinsic callable `Check` failed: cannot verify input"],
1359 );
1360}
1361
1362#[test]
1363fn qubit_nested_bind_not_released() {
1364 check_intrinsic_output(
1365 "",
1366 indoc! {"{
1367 use aux = Qubit();
1368 use q = Qubit();
1369 {
1370 let temp = q;
1371 X(temp);
1372 }
1373 Microsoft.Quantum.Diagnostics.DumpMachine();
1374 X(q);
1375 }"},
1376 &expect![[r#"
1377 STATE:
1378 |01⟩: 1.0000+0.0000𝑖
1379 "#]],
1380 );
1381}
1382
1383#[test]
1384fn qubit_release_non_zero_failure() {
1385 check_intrinsic_output(
1386 "",
1387 indoc! {"{
1388 use q = Qubit();
1389 X(q);
1390 }"},
1391 &expect!["Qubit0 released while not in |0⟩ state"],
1392 );
1393}
1394
1395#[test]
1396fn qubit_not_unique_two_qubit_error() {
1397 check_intrinsic_output(
1398 "",
1399 indoc! {"{
1400 use q = Qubit();
1401 CNOT(q , q);
1402 }"},
1403 &expect!["qubits in invocation are not unique"],
1404 );
1405}
1406
1407#[test]
1408fn qubit_not_unique_two_qubit_rotation_error() {
1409 check_intrinsic_output(
1410 "",
1411 indoc! {"{
1412 use q = Qubit();
1413 Rxx(0.1, q, q);
1414 }"},
1415 &expect!["qubits in invocation are not unique"],
1416 );
1417}
1418
1419#[test]
1420fn qubit_not_unique_three_qubit_error_first_second() {
1421 check_intrinsic_output(
1422 "",
1423 indoc! {"{
1424 use q = Qubit();
1425 use a = Qubit();
1426 CCNOT(q , q, a);
1427 }"},
1428 &expect!["qubits in invocation are not unique"],
1429 );
1430}
1431
1432#[test]
1433fn qubit_not_unique_three_qubit_error_first_third() {
1434 check_intrinsic_output(
1435 "",
1436 indoc! {"{
1437 use q = Qubit();
1438 use a = Qubit();
1439 CCNOT(q , a, q);
1440 }"},
1441 &expect!["qubits in invocation are not unique"],
1442 );
1443}
1444
1445#[test]
1446fn qubit_not_unique_three_qubit_error_second_third() {
1447 check_intrinsic_output(
1448 "",
1449 indoc! {"{
1450 use q = Qubit();
1451 use a = Qubit();
1452 CCNOT(a , q, q);
1453 }"},
1454 &expect!["qubits in invocation are not unique"],
1455 );
1456}
1457
1458#[test]
1459fn single_qubit_rotation_nan_error() {
1460 check_intrinsic_output(
1461 "",
1462 indoc! {"{
1463 use q = Qubit();
1464 Rx(Microsoft.Quantum.Math.ArcSin(2.0), q);
1465 }"},
1466 &expect!["invalid rotation angle: NaN"],
1467 );
1468}
1469
1470#[test]
1471fn two_qubit_rotation_nan_error() {
1472 check_intrinsic_output(
1473 "",
1474 indoc! {"{
1475 use (q1, q2) = (Qubit(), Qubit());
1476 Rxx(Microsoft.Quantum.Math.ArcSin(2.0), q1, q2);
1477 }"},
1478 &expect!["invalid rotation angle: NaN"],
1479 );
1480}
1481
1482#[test]
1483fn single_qubit_rotation_inf_error() {
1484 check_intrinsic_output(
1485 "",
1486 indoc! {"{
1487 use q = Qubit();
1488 Rx(-Microsoft.Quantum.Math.Log(0.0), q);
1489 }"},
1490 &expect!["invalid rotation angle: inf"],
1491 );
1492}
1493
1494#[test]
1495fn two_qubit_rotation_inf_error() {
1496 check_intrinsic_output(
1497 "",
1498 indoc! {"{
1499 use (q1, q2) = (Qubit(), Qubit());
1500 Rxx(-Microsoft.Quantum.Math.Log(0.0), q1, q2);
1501 }"},
1502 &expect!["invalid rotation angle: inf"],
1503 );
1504}
1505
1506#[test]
1507fn single_qubit_rotation_neg_inf_error() {
1508 check_intrinsic_output(
1509 "",
1510 indoc! {"{
1511 use q = Qubit();
1512 Rx(Microsoft.Quantum.Math.Log(0.0), q);
1513 }"},
1514 &expect!["invalid rotation angle: -inf"],
1515 );
1516}
1517
1518#[test]
1519fn two_qubit_rotation_neg_inf_error() {
1520 check_intrinsic_output(
1521 "",
1522 indoc! {"{
1523 use (q1, q2) = (Qubit(), Qubit());
1524 Rxx(Microsoft.Quantum.Math.Log(0.0), q1, q2);
1525 }"},
1526 &expect!["invalid rotation angle: -inf"],
1527 );
1528}
1529
1530#[test]
1531fn stop_counting_operation_before_start_fails() {
1532 check_intrinsic_output(
1533 "",
1534 indoc! {"{
1535 Std.Diagnostics.StopCountingOperation(I);
1536 }"},
1537 &expect!["callable not counted"],
1538 );
1539}
1540
1541#[test]
1542fn stop_counting_function_before_start_fails() {
1543 check_intrinsic_output(
1544 "",
1545 indoc! {"{
1546 function Foo() : Unit {}
1547 Std.Diagnostics.StopCountingFunction(Foo);
1548 }"},
1549 &expect!["callable not counted"],
1550 );
1551}
1552
1553#[test]
1554fn start_counting_operation_called_twice_before_stop_fails() {
1555 check_intrinsic_output(
1556 "",
1557 indoc! {"{
1558 Std.Diagnostics.StartCountingOperation(I);
1559 Std.Diagnostics.StartCountingOperation(I);
1560 }"},
1561 &expect!["callable already counted"],
1562 );
1563}
1564
1565#[test]
1566fn start_counting_function_called_twice_before_stop_fails() {
1567 check_intrinsic_output(
1568 "",
1569 indoc! {"{
1570 function Foo() : Unit {}
1571 Std.Diagnostics.StartCountingFunction(Foo);
1572 Std.Diagnostics.StartCountingFunction(Foo);
1573 }"},
1574 &expect!["callable already counted"],
1575 );
1576}
1577
1578#[test]
1579fn stop_counting_qubits_before_start_fails() {
1580 check_intrinsic_output(
1581 "",
1582 indoc! {"{
1583 Std.Diagnostics.StopCountingQubits();
1584 }"},
1585 &expect!["qubits not counted"],
1586 );
1587}
1588
1589#[test]
1590fn start_counting_qubits_called_twice_before_stop_fails() {
1591 check_intrinsic_output(
1592 "",
1593 indoc! {"{
1594 Std.Diagnostics.StartCountingQubits();
1595 Std.Diagnostics.StartCountingQubits();
1596 }"},
1597 &expect!["qubits already counted"],
1598 );
1599}
1600