microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
dmitryv/multiplex-z

Branches

Tags

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

Clone

HTTPS

Download ZIP

library/src/tests/diagnostics.rs

519lines ยท modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use super::test_expression;
5use expect_test::expect;
6use qsc::interpret::Value;
7
8#[test]
9fn check_operations_are_equal() {
10 test_expression(
11 "{
12 import Std.Diagnostics.*;
13 import Std.Arrays.*;
14 operation op1(xs: Qubit[]): Unit is Adj {
15 CCNOT(xs[0], xs[1], xs[2]);
16 }
17 operation op2(xs: Qubit[]): Unit is Adj {
18 Controlled X(Most(xs), Tail(xs));
19 }
20 operation op3(xs: Qubit[]): Unit is Adj {
21 Controlled X(Rest(xs), Head(xs));
22 }
23 [CheckOperationsAreEqual(3, op1, op2),
24 CheckOperationsAreEqual(3, op2, op1),
25 CheckOperationsAreEqual(3, op1, op3),
26 CheckOperationsAreEqual(3, op3, op1),
27 CheckOperationsAreEqual(3, op2, op3),
28 CheckOperationsAreEqual(3, op3, op2)]
29
30 }",
31 &Value::Array(
32 vec![
33 Value::Bool(true),
34 Value::Bool(true),
35 Value::Bool(false),
36 Value::Bool(false),
37 Value::Bool(false),
38 Value::Bool(false),
39 ]
40 .into(),
41 ),
42 );
43}
44
45#[test]
46fn check_dumpoperation_for_i() {
47 let output = test_expression(
48 "Microsoft.Quantum.Diagnostics.DumpOperation(1, qs => I(qs[0]))",
49 &Value::unit(),
50 );
51 expect![[r#"
52 MATRIX:
53 1.0000+0.0000๐‘– 0.0000+0.0000๐‘–
54 0.0000+0.0000๐‘– 1.0000+0.0000๐‘–
55 "#]]
56 .assert_eq(&output);
57}
58
59#[test]
60fn check_dumpoperation_for_x() {
61 let output = test_expression(
62 "Microsoft.Quantum.Diagnostics.DumpOperation(1, qs => X(qs[0]))",
63 &Value::unit(),
64 );
65 expect![[r#"
66 MATRIX:
67 0.0000+0.0000๐‘– 1.0000+0.0000๐‘–
68 1.0000+0.0000๐‘– 0.0000+0.0000๐‘–
69 "#]]
70 .assert_eq(&output);
71}
72
73#[test]
74fn check_dumpoperation_for_h() {
75 let output = test_expression(
76 "Microsoft.Quantum.Diagnostics.DumpOperation(1, qs => H(qs[0]))",
77 &Value::unit(),
78 );
79 expect![[r#"
80 MATRIX:
81 0.7071+0.0000๐‘– 0.7071+0.0000๐‘–
82 0.7071+0.0000๐‘– โˆ’0.7071+0.0000๐‘–
83 "#]]
84 .assert_eq(&output);
85}
86
87#[test]
88fn check_dumpoperation_for_y() {
89 let output = test_expression(
90 "Microsoft.Quantum.Diagnostics.DumpOperation(1, qs => Y(qs[0]))",
91 &Value::unit(),
92 );
93 expect![[r#"
94 MATRIX:
95 0.0000+0.0000๐‘– 0.0000โˆ’1.0000๐‘–
96 0.0000+1.0000๐‘– 0.0000+0.0000๐‘–
97 "#]]
98 .assert_eq(&output);
99}
100
101#[test]
102fn check_dumpoperation_for_ccnot() {
103 let output = test_expression(
104 "Microsoft.Quantum.Diagnostics.DumpOperation(3, qs => CCNOT(qs[0], qs[1], qs[2]))",
105 &Value::unit(),
106 );
107 expect![[r#"
108 MATRIX:
109 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
110 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
111 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
112 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
113 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
114 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
115 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 1.0000+0.0000๐‘–
116 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘–
117 "#]].assert_eq(&output);
118}
119
120#[test]
121fn check_dumpoperation_with_extra_qubits_allocated() {
122 let output = test_expression(
123 "{use qs = Qubit[2]; Microsoft.Quantum.Diagnostics.DumpOperation(1, qs => H(qs[0]))}",
124 &Value::unit(),
125 );
126 expect![[r#"
127 MATRIX:
128 0.7071+0.0000๐‘– 0.7071+0.0000๐‘–
129 0.7071+0.0000๐‘– โˆ’0.7071+0.0000๐‘–
130 "#]]
131 .assert_eq(&output);
132}
133
134#[test]
135fn check_start_stop_counting_operation_called_3_times() {
136 test_expression(
137 "{
138 import Microsoft.Quantum.Diagnostics.StartCountingOperation;
139 import Microsoft.Quantum.Diagnostics.StopCountingOperation;
140
141 operation op1() : Unit {}
142 operation op2() : Unit { op1(); }
143 StartCountingOperation(op1);
144 StartCountingOperation(op2);
145 op1(); op1(); op2();
146 (StopCountingOperation(op1), StopCountingOperation(op2))
147 }",
148 &Value::Tuple([Value::Int(3), Value::Int(1)].into(), None),
149 );
150}
151
152#[test]
153fn check_start_stop_counting_operation_called_0_times() {
154 test_expression(
155 "{
156 import Microsoft.Quantum.Diagnostics.StartCountingOperation;
157 import Microsoft.Quantum.Diagnostics.StopCountingOperation;
158
159 operation op1() : Unit {}
160 operation op2() : Unit { op1(); }
161 StartCountingOperation(op1);
162 StartCountingOperation(op2);
163 (StopCountingOperation(op1), StopCountingOperation(op2))
164 }",
165 &Value::Tuple([Value::Int(0), Value::Int(0)].into(), None),
166 );
167}
168
169#[test]
170fn check_lambda_counted_separately_from_operation() {
171 test_expression(
172 "{
173 import Microsoft.Quantum.Diagnostics.StartCountingOperation;
174 import Microsoft.Quantum.Diagnostics.StopCountingOperation;
175
176 operation op1() : Unit {}
177 StartCountingOperation(op1);
178 let lambda = () => op1();
179 StartCountingOperation(lambda);
180 op1();
181 lambda();
182 (StopCountingOperation(op1), StopCountingOperation(lambda))
183 }",
184 &Value::Tuple([Value::Int(2), Value::Int(1)].into(), None),
185 );
186}
187
188#[test]
189fn check_multiple_controls_counted_together() {
190 test_expression(
191 "{
192 import Microsoft.Quantum.Diagnostics.StartCountingOperation;
193 import Microsoft.Quantum.Diagnostics.StopCountingOperation;
194
195 operation op1() : Unit is Adj + Ctl {}
196 StartCountingOperation(Controlled op1);
197 Controlled op1([], ());
198 Controlled Controlled op1([], ([], ()));
199 Controlled Controlled Controlled op1([], ([], ([], ())));
200 (StopCountingOperation(Controlled op1))
201 }",
202 &Value::Int(3),
203 );
204}
205
206#[test]
207fn check_counting_operation_differentiates_between_body_adj_ctl() {
208 test_expression(
209 "{
210 import Microsoft.Quantum.Diagnostics.StartCountingOperation;
211 import Microsoft.Quantum.Diagnostics.StopCountingOperation;
212
213 operation op1() : Unit is Adj + Ctl {}
214 StartCountingOperation(op1);
215 StartCountingOperation(Adjoint op1);
216 StartCountingOperation(Controlled op1);
217 StartCountingOperation(Adjoint Controlled op1);
218 op1();
219 Adjoint op1(); Adjoint op1();
220 Controlled op1([], ()); Controlled op1([], ()); Controlled op1([], ());
221 Adjoint Controlled op1([], ()); Adjoint Controlled op1([], ());
222 Controlled Adjoint op1([], ()); Controlled Adjoint op1([], ());
223 (StopCountingOperation(op1), StopCountingOperation(Adjoint op1), StopCountingOperation(Controlled op1), StopCountingOperation(Adjoint Controlled op1))
224 }",
225 &Value::Tuple([Value::Int(1), Value::Int(2), Value::Int(3), Value::Int(4)].into(), None),
226 );
227}
228
229#[test]
230fn check_start_stop_counting_function_called_3_times() {
231 test_expression(
232 "{
233 import Microsoft.Quantum.Diagnostics.StartCountingFunction;
234 import Microsoft.Quantum.Diagnostics.StopCountingFunction;
235
236 function f1() : Unit {}
237 function f2() : Unit { f1(); }
238 StartCountingFunction(f1);
239 StartCountingFunction(f2);
240 f1(); f1(); f2();
241 (StopCountingFunction(f1), StopCountingFunction(f2))
242 }",
243 &Value::Tuple([Value::Int(3), Value::Int(1)].into(), None),
244 );
245}
246
247#[test]
248fn check_start_stop_counting_function_called_0_times() {
249 test_expression(
250 "{
251 import Microsoft.Quantum.Diagnostics.StartCountingFunction;
252 import Microsoft.Quantum.Diagnostics.StopCountingFunction;
253
254 function f1() : Unit {}
255 function f2() : Unit { f1(); }
256 StartCountingFunction(f1);
257 StartCountingFunction(f2);
258 (StopCountingFunction(f1), StopCountingFunction(f2))
259 }",
260 &Value::Tuple([Value::Int(0), Value::Int(0)].into(), None),
261 );
262}
263
264#[test]
265fn check_start_counting_qubits_for_one_allocation() {
266 test_expression(
267 "{
268 import Microsoft.Quantum.Diagnostics.StartCountingQubits;
269 import Microsoft.Quantum.Diagnostics.StopCountingQubits;
270
271 StartCountingQubits();
272 use q = Qubit();
273 StopCountingQubits()
274 }",
275 &Value::Int(1),
276 );
277}
278
279#[test]
280fn check_start_counting_qubits_for_tuple_allocation() {
281 test_expression(
282 "{
283 import Microsoft.Quantum.Diagnostics.StartCountingQubits;
284 import Microsoft.Quantum.Diagnostics.StopCountingQubits;
285
286 StartCountingQubits();
287 use (q0, q1) = (Qubit(), Qubit());
288 StopCountingQubits()
289 }",
290 &Value::Int(2),
291 );
292}
293
294#[test]
295fn check_start_counting_qubits_for_array_allocation() {
296 test_expression(
297 "{
298 import Microsoft.Quantum.Diagnostics.StartCountingQubits;
299 import Microsoft.Quantum.Diagnostics.StopCountingQubits;
300
301 StartCountingQubits();
302 use qs = Qubit[2];
303 StopCountingQubits()
304 }",
305 &Value::Int(2),
306 );
307}
308
309#[test]
310fn check_start_counting_qubits_after_allocation_gives_zero() {
311 test_expression(
312 "{
313 import Microsoft.Quantum.Diagnostics.StartCountingQubits;
314 import Microsoft.Quantum.Diagnostics.StopCountingQubits;
315
316 use q = Qubit();
317 StartCountingQubits();
318 StopCountingQubits()
319 }",
320 &Value::Int(0),
321 );
322}
323
324#[test]
325fn check_start_counting_qubits_sees_same_qubit_as_single_count() {
326 test_expression(
327 "{
328 import Microsoft.Quantum.Diagnostics.StartCountingQubits;
329 import Microsoft.Quantum.Diagnostics.StopCountingQubits;
330
331 StartCountingQubits();
332 {
333 use q = Qubit();
334 }
335 {
336 use q = Qubit();
337 }
338 StopCountingQubits()
339 }",
340 &Value::Int(1),
341 );
342}
343
344#[test]
345fn check_start_counting_qubits_works_with_manual_out_of_order_allocation_release() {
346 test_expression(
347 "{
348 import Microsoft.Quantum.Diagnostics.StartCountingQubits;
349 import Microsoft.Quantum.Diagnostics.StopCountingQubits;
350 import QIR.Runtime.__quantum__rt__qubit_allocate;
351 import QIR.Runtime.__quantum__rt__qubit_release;
352
353 let (q0, q1, q2) = (__quantum__rt__qubit_allocate(), __quantum__rt__qubit_allocate(), __quantum__rt__qubit_allocate());
354 StartCountingQubits();
355 __quantum__rt__qubit_release(q2);
356 use q = Qubit();
357 __quantum__rt__qubit_release(q0);
358 __quantum__rt__qubit_release(q1);
359 use qs = Qubit[2];
360 StopCountingQubits()
361 }",
362 &Value::Int(3),
363 );
364}
365
366#[test]
367fn check_counting_qubits_works_with_allocation_in_operation_calls() {
368 test_expression(
369 "{
370 import Microsoft.Quantum.Diagnostics.StartCountingQubits;
371 import Microsoft.Quantum.Diagnostics.StopCountingQubits;
372 import Microsoft.Quantum.Diagnostics.CheckOperationsAreEqual;
373
374 StartCountingQubits();
375 let numQubits = 2;
376 let equal = CheckOperationsAreEqual(2,
377 qs => SWAP(qs[0], qs[1]),
378 qs => { CNOT(qs[0], qs[1]); CNOT(qs[1], qs[0]); CNOT(qs[0], qs[1]); }
379 );
380 (true, 2 * numQubits) == (equal, StopCountingQubits())
381 }",
382 &Value::Bool(true),
383 );
384}
385
386#[test]
387fn check_dumpoperation_with_extra_qubits_in_superposition() {
388 let output = test_expression(
389 "{use qs = Qubit[2]; H(qs[0]); Microsoft.Quantum.Diagnostics.DumpOperation(1, qs => H(qs[0])); Reset(qs[0]);}",
390 &Value::unit(),
391 );
392 expect![[r#"
393 MATRIX:
394 0.7071+0.0000๐‘– 0.7071+0.0000๐‘–
395 0.7071+0.0000๐‘– โˆ’0.7071+0.0000๐‘–
396 "#]]
397 .assert_eq(&output);
398}
399
400#[test]
401fn check_dumpoperation_with_extra_qubits_global_phase_reflected_in_matrix() {
402 let output = test_expression(
403 "{use qs = Qubit[2]; R(PauliI, Std.Math.PI() / 2.0, qs[0]); Microsoft.Quantum.Diagnostics.DumpOperation(1, qs => H(qs[0])); Reset(qs[0]);}",
404 &Value::unit(),
405 );
406 expect![[r#"
407 MATRIX:
408 0.5000โˆ’0.5000๐‘– 0.5000โˆ’0.5000๐‘–
409 0.5000โˆ’0.5000๐‘– โˆ’0.5000+0.5000๐‘–
410 "#]]
411 .assert_eq(&output);
412}
413
414#[test]
415fn check_dumpoperation_with_extra_qubits_relative_phase_not_reflected_in_matrix() {
416 let output = test_expression(
417 "{use qs = Qubit[2]; R1(Std.Math.PI() / 2.0, qs[0]); Microsoft.Quantum.Diagnostics.DumpOperation(1, qs => H(qs[0])); Reset(qs[0]);}",
418 &Value::unit(),
419 );
420 expect![[r#"
421 MATRIX:
422 0.7071+0.0000๐‘– 0.7071+0.0000๐‘–
423 0.7071+0.0000๐‘– โˆ’0.7071+0.0000๐‘–
424 "#]]
425 .assert_eq(&output);
426}
427
428#[test]
429fn check_dump_operation_for_r1_of_pi() {
430 let output = test_expression(
431 "Microsoft.Quantum.Diagnostics.DumpOperation(1, qs => R1(Std.Math.PI(), qs[0]))",
432 &Value::unit(),
433 );
434 expect![[r#"
435 MATRIX:
436 1.0000+0.0000๐‘– 0.0000+0.0000๐‘–
437 0.0000+0.0000๐‘– โˆ’1.0000+0.0000๐‘–
438 "#]]
439 .assert_eq(&output);
440}
441
442#[test]
443fn check_dump_operation_for_r1_of_pi_with_one_control() {
444 let output = test_expression(
445 "Microsoft.Quantum.Diagnostics.DumpOperation(2, qs => Controlled R1(qs[...0], (Std.Math.PI(), qs[1])))",
446 &Value::unit(),
447 );
448 expect![[r#"
449 MATRIX:
450 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
451 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
452 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘–
453 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– โˆ’1.0000+0.0000๐‘–
454 "#]]
455 .assert_eq(&output);
456}
457
458#[test]
459fn check_dump_operation_for_r1_of_pi_with_two_controls() {
460 let output = test_expression(
461 "Microsoft.Quantum.Diagnostics.DumpOperation(3, qs => Controlled R1(qs[...1], (Std.Math.PI(), qs[2])))",
462 &Value::unit(),
463 );
464 expect![[r#"
465 MATRIX:
466 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
467 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
468 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
469 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
470 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
471 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘–
472 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 1.0000+0.0000๐‘– 0.0000+0.0000๐‘–
473 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– 0.0000+0.0000๐‘– โˆ’1.0000+0.0000๐‘–
474 "#]].assert_eq(&output);
475}
476
477#[test]
478fn check_bit_flip_noise_values() {
479 test_expression(
480 "Std.Diagnostics.BitFlipNoise(0.3)",
481 &Value::Tuple(
482 [Value::Double(0.3), Value::Double(0.0), Value::Double(0.0)].into(),
483 None,
484 ),
485 );
486}
487
488#[test]
489fn check_phase_flip_noise_values() {
490 test_expression(
491 "Std.Diagnostics.PhaseFlipNoise(0.3)",
492 &Value::Tuple(
493 [Value::Double(0.0), Value::Double(0.0), Value::Double(0.3)].into(),
494 None,
495 ),
496 );
497}
498
499#[test]
500fn check_depolarizing_noise_values() {
501 test_expression(
502 "Std.Diagnostics.DepolarizingNoise(0.3)",
503 &Value::Tuple(
504 [Value::Double(0.1), Value::Double(0.1), Value::Double(0.1)].into(),
505 None,
506 ),
507 );
508}
509
510#[test]
511fn check_no_noise_values() {
512 test_expression(
513 "Std.Diagnostics.NoNoise()",
514 &Value::Tuple(
515 [Value::Double(0.0), Value::Double(0.0), Value::Double(0.0)].into(),
516 None,
517 ),
518 );
519}
520