microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/replace-qsharp-with-qdk-python-tests

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/compiler/qsc_circuit/src/circuit/tests.rs

471lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use super::*;
5use expect_test::expect;
6
7/// Converts a 2D grid of operations into a component grid.
8///
9/// # Arguments
10///
11/// * `operations` - A 2D vector of operations to be converted.
12///
13/// # Returns
14///
15/// A component grid representing the operations.
16pub fn op_grid_to_comp_grid(operations: Vec<Vec<Operation>>) -> ComponentGrid {
17 let mut component_grid = vec![];
18 for col in operations {
19 let column = ComponentColumn { components: col };
20 component_grid.push(column);
21 }
22 component_grid
23}
24
25fn qubit(id: usize) -> Qubit {
26 Qubit {
27 id,
28 num_results: 0,
29 declarations: vec![],
30 }
31}
32
33fn qubit_with_results(id: usize, num_results: usize) -> Qubit {
34 Qubit {
35 id,
36 num_results,
37 declarations: vec![],
38 }
39}
40
41fn q_reg(id: usize) -> Register {
42 Register::quantum(id)
43}
44
45fn c_reg(q_id: usize, c_id: usize) -> Register {
46 Register::classical(q_id, c_id)
47}
48
49fn measurement(q_id: usize, c_id: usize) -> Operation {
50 Operation::Measurement(Measurement {
51 gate: "Measure".to_string(),
52 args: vec![],
53 qubits: vec![Register::quantum(q_id)],
54 results: vec![Register::classical(q_id, c_id)],
55 children: vec![],
56 metadata: None,
57 })
58}
59
60fn unitary(gate: &str, targets: Vec<Register>) -> Operation {
61 Operation::Unitary(Unitary {
62 gate: gate.to_string(),
63 args: vec![],
64 is_adjoint: false,
65 controls: vec![],
66 targets,
67 children: vec![],
68 metadata: None,
69 is_conditional: false,
70 })
71}
72
73fn ctl_unitary(gate: &str, targets: Vec<Register>, controls: Vec<Register>) -> Operation {
74 Operation::Unitary(Unitary {
75 gate: gate.to_string(),
76 args: vec![],
77 is_adjoint: false,
78 controls,
79 targets,
80 children: vec![],
81 metadata: None,
82 is_conditional: false,
83 })
84}
85
86fn unitary_with_children(gate: &str, targets: Vec<Register>, children: ComponentGrid) -> Operation {
87 Operation::Unitary(Unitary {
88 gate: gate.to_string(),
89 args: vec![],
90 is_adjoint: false,
91 controls: vec![],
92 targets,
93 children,
94 metadata: None,
95 is_conditional: false,
96 })
97}
98
99fn ctl_unitary_with_children(
100 gate: &str,
101 targets: Vec<Register>,
102 controls: Vec<Register>,
103 children: ComponentGrid,
104) -> Operation {
105 Operation::Unitary(Unitary {
106 gate: gate.to_string(),
107 args: vec![],
108 is_adjoint: false,
109 controls,
110 targets,
111 children,
112 metadata: None,
113 is_conditional: false,
114 })
115}
116
117#[test]
118fn deserialize_circuit() {
119 let contents = r#"
120{
121 "qubits": [ { "id": 0 }, { "id": 1 } ],
122 "componentGrid": [
123 {
124 "components": [
125 { "kind": "unitary", "gate": "H", "targets": [{ "qubit": 0 }] },
126 { "kind": "unitary", "gate": "X", "targets": [{ "qubit": 1 }] }
127 ]
128 },
129 {
130 "components": [
131 { "kind": "unitary", "gate": "Z", "targets": [{ "qubit": 0 }] }
132 ]
133 },
134 {
135 "components": [
136 { "kind": "unitary", "gate": "X", "targets": [{ "qubit": 1 }], "controls": [{ "qubit": 0 }] }
137 ]
138 }
139 ]
140}"#;
141
142 let c = serde_json::from_str::<Circuit>(contents).expect("Was not able to deserialize");
143
144 expect![[r#"
145 q_0 ── H ──── Z ──── ● ──
146 q_1 ── X ─────────── X ──
147 "#]]
148 .assert_eq(&c.to_string());
149}
150
151#[test]
152fn empty() {
153 let c = Circuit {
154 qubits: vec![],
155 component_grid: vec![],
156 };
157 expect![[""]].assert_eq(&c.to_string());
158}
159
160#[test]
161fn no_gates() {
162 let c = Circuit {
163 qubits: vec![qubit(0), qubit(1)],
164 component_grid: vec![],
165 };
166
167 expect![[r"
168 q_0
169 q_1
170 "]]
171 .assert_eq(&c.to_string());
172}
173
174#[test]
175fn bell() {
176 let operations = vec![
177 unitary("H", vec![q_reg(0)]),
178 ctl_unitary("X", vec![q_reg(1)], vec![q_reg(0)]),
179 measurement(0, 0),
180 measurement(1, 0),
181 ];
182 let qubits = vec![qubit_with_results(0, 1), qubit_with_results(1, 1)];
183 let component_grid = operation_list_to_grid(operations, &qubits);
184 let c = Circuit {
185 qubits,
186 component_grid,
187 };
188
189 expect![[r"
190 q_0 ── H ──── ● ──── M ──
191 │ ╘═══
192 q_1 ───────── X ──── M ──
193 ╘═══
194 "]]
195 .assert_eq(&c.to_string());
196}
197
198#[test]
199fn control_classical() {
200 let operations = vec![
201 measurement(0, 0),
202 ctl_unitary("X", vec![q_reg(2)], vec![c_reg(0, 0)]),
203 ctl_unitary("X", vec![q_reg(2)], vec![q_reg(0)]),
204 ];
205 let qubits = vec![qubit_with_results(0, 1), qubit(1), qubit(2)];
206 let component_grid = operation_list_to_grid(operations, &qubits);
207 let c = Circuit {
208 qubits,
209 component_grid,
210 };
211
212 expect![[r"
213 q_0 ── M ─────────── ● ──
214 ╘═════ ● ═════╪═══
215 q_1 ──────────┼──────┼───
216 q_2 ───────── X ──── X ──
217 "]]
218 .assert_eq(&c.to_string());
219}
220
221#[test]
222fn two_measurements() {
223 let operations = vec![measurement(0, 0), measurement(0, 1)];
224 let qubits = vec![qubit_with_results(0, 2)];
225 let component_grid = operation_list_to_grid(operations, &qubits);
226 let c = Circuit {
227 qubits,
228 component_grid,
229 };
230
231 expect![[r"
232 q_0 ── M ──── M ──
233 ╘══════╪═══
234 ╘═══
235 "]]
236 .assert_eq(&c.to_string());
237}
238
239#[test]
240fn with_args() {
241 let c = Circuit {
242 qubits: vec![qubit(0)],
243 component_grid: op_grid_to_comp_grid(vec![vec![Operation::Unitary(Unitary {
244 gate: "rx".to_string(),
245 args: vec!["1.5708".to_string()],
246 is_adjoint: false,
247 controls: vec![],
248 targets: vec![Register::quantum(0)],
249 is_conditional: false,
250 children: vec![],
251 metadata: None,
252 })]]),
253 };
254
255 expect![[r"
256 q_0 ─ rx(1.5708) ──
257 "]]
258 .assert_eq(&c.to_string());
259}
260
261#[test]
262fn two_targets() {
263 let c = Circuit {
264 qubits: vec![qubit(0), qubit(1), qubit(2)],
265 component_grid: op_grid_to_comp_grid(vec![vec![Operation::Unitary(Unitary {
266 gate: "rzz".to_string(),
267 args: vec!["1.0000".to_string()],
268 is_adjoint: false,
269 is_conditional: false,
270 controls: vec![],
271 targets: vec![Register::quantum(0), Register::quantum(2)],
272 children: vec![],
273 metadata: None,
274 })]]),
275 };
276
277 expect![[r"
278 q_0 ─ rzz(1.0000) ─
279 q_1 ───────┆───────
280 q_2 ─ rzz(1.0000) ─
281 "]]
282 .assert_eq(&c.to_string());
283}
284
285#[test]
286fn respect_column_info() {
287 let c = Circuit {
288 qubits: vec![qubit(0), qubit(1)],
289 component_grid: op_grid_to_comp_grid(vec![
290 vec![unitary("X", vec![q_reg(0)])],
291 vec![unitary("Y", vec![q_reg(0)]), unitary("S", vec![q_reg(1)])],
292 vec![unitary("Z", vec![q_reg(0)])],
293 ]),
294 };
295
296 expect![[r#"
297 q_0 ── X ──── Y ──── Z ──
298 q_1 ───────── S ─────────
299 "#]]
300 .assert_eq(&c.to_string());
301}
302
303#[test]
304fn group_single_row() {
305 let c = Circuit {
306 qubits: vec![qubit(0), qubit_with_results(1, 1)],
307 component_grid: vec![
308 ComponentColumn {
309 components: vec![unitary("H", vec![q_reg(0)])],
310 },
311 ComponentColumn {
312 components: vec![unitary_with_children(
313 "group",
314 vec![q_reg(0)],
315 vec![ComponentColumn {
316 components: vec![unitary("X", vec![q_reg(0)])],
317 }],
318 )],
319 },
320 ComponentColumn {
321 components: vec![measurement(1, 0)],
322 },
323 ComponentColumn {
324 components: vec![unitary("Z", vec![q_reg(0)])],
325 },
326 ],
327 };
328
329 expect![[r#"
330 q_0 ── H ─── [ [group] ─── X ──── ] ─────────── Z ──
331 q_1 ──────────────────────────────────── M ─────────
332 ╘══════════
333 "#]]
334 .assert_eq(&c.display_with_groups().to_string());
335}
336
337#[test]
338fn group_multiple_rows() {
339 let c = Circuit {
340 qubits: vec![qubit(0), qubit_with_results(1, 1)],
341 component_grid: vec![
342 ComponentColumn {
343 components: vec![unitary("H", vec![q_reg(0)])],
344 },
345 ComponentColumn {
346 components: vec![unitary_with_children(
347 "group",
348 vec![q_reg(0), q_reg(1)],
349 vec![
350 ComponentColumn {
351 components: vec![unitary("X", vec![q_reg(0)])],
352 },
353 ComponentColumn {
354 components: vec![unitary("Y", vec![q_reg(1)])],
355 },
356 ],
357 )],
358 },
359 ComponentColumn {
360 components: vec![measurement(1, 0)],
361 },
362 ComponentColumn {
363 components: vec![unitary("Z", vec![q_reg(0)])],
364 },
365 ],
366 };
367
368 expect![[r#"
369 q_0 ── H ─── group[1] ─────────── Z ──
370
371 q_1 ──────── group[1] ──── M ─────────
372 ╘══════════
373
374 [1] group:
375 q_0 ── X ─────────
376 q_1 ───────── Y ──
377
378 "#]]
379 .assert_eq(&c.display_with_groups().to_string());
380}
381
382#[test]
383fn controlled_group() {
384 let c = Circuit {
385 qubits: vec![qubit_with_results(0, 1), qubit_with_results(1, 1)],
386 component_grid: vec![
387 ComponentColumn {
388 components: vec![unitary("H", vec![q_reg(0)])],
389 },
390 ComponentColumn {
391 components: vec![measurement(0, 0)],
392 },
393 ComponentColumn {
394 components: vec![measurement(1, 0)],
395 },
396 ComponentColumn {
397 components: vec![ctl_unitary_with_children(
398 "group",
399 vec![q_reg(0), q_reg(1)],
400 vec![q_reg(1)],
401 vec![ComponentColumn {
402 components: vec![unitary("X", vec![q_reg(0)])],
403 }],
404 )],
405 },
406 ComponentColumn {
407 components: vec![unitary("Z", vec![q_reg(0)])],
408 },
409 ],
410 };
411
412 expect![[r#"
413 q_0 ── H ──── M ────────── group[1] ──── Z ──
414 ╘════════════════╪═════════════
415 q_1 ──────────────── M ─────── ● ────────────
416 ╘═══════════════════════
417
418 [1] group:
419 q_0 ── X ──
420
421 q_1 ───────
422
423 "#]]
424 .assert_eq(&c.display_with_groups().to_string());
425}
426
427#[test]
428fn classical_controlled_group() {
429 let c = Circuit {
430 qubits: vec![qubit_with_results(0, 0), qubit_with_results(1, 1)],
431 component_grid: vec![
432 ComponentColumn {
433 components: vec![unitary("H", vec![q_reg(0)])],
434 },
435 ComponentColumn {
436 components: vec![measurement(1, 0)],
437 },
438 ComponentColumn {
439 components: vec![ctl_unitary_with_children(
440 "group",
441 vec![q_reg(0), q_reg(1)],
442 vec![c_reg(1, 0)],
443 vec![
444 ComponentColumn {
445 components: vec![unitary("X", vec![q_reg(0)])],
446 },
447 ComponentColumn {
448 components: vec![unitary("Y", vec![q_reg(1)])],
449 },
450 ],
451 )],
452 },
453 ComponentColumn {
454 components: vec![unitary("Z", vec![q_reg(0)])],
455 },
456 ],
457 };
458
459 expect![[r#"
460 q_0 ── H ────────── group[1] ──── Z ──
461
462 q_1 ───────── M ─── group[1] ─────────
463 ╘════════ ● ════════════
464
465 [1] group:
466 q_0 ── X ─────────
467 q_1 ───────── Y ──
468
469 "#]]
470 .assert_eq(&c.display_with_groups().to_string());
471}
472