microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
cesarzc/ssa-panic

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_codegen/src/remapper.rs

88lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use qsc_data_structures::index_map::IndexMap;
5
6/// Provides support for qubit id allocation, measurement and
7/// reset operations for Base Profile targets.
8///
9/// Since qubit reuse is disallowed, a mapping is maintained
10/// from allocated qubit ids to hardware qubit ids. Each time
11/// a qubit is reset, it is remapped to a fresh hardware qubit.
12///
13/// Note that even though qubit reset & reuse is disallowed,
14/// qubit ids are still reused for new allocations.
15/// Measurements are tracked and deferred.
16#[derive(Default)]
17pub struct Remapper {
18 next_meas_id: usize,
19 next_qubit_id: usize,
20 next_qubit_hardware_id: HardwareId,
21 qubit_map: IndexMap<usize, HardwareId>,
22 measurements: Vec<(HardwareId, usize)>,
23}
24
25impl Remapper {
26 pub fn map(&mut self, qubit: usize) -> HardwareId {
27 if let Some(mapped) = self.qubit_map.get(qubit) {
28 *mapped
29 } else {
30 let mapped = self.next_qubit_hardware_id;
31 self.next_qubit_hardware_id.0 += 1;
32 self.qubit_map.insert(qubit, mapped);
33 mapped
34 }
35 }
36
37 pub fn m(&mut self, q: usize) -> usize {
38 let mapped_q = self.map(q);
39 let id = self.get_meas_id();
40 self.measurements.push((mapped_q, id));
41 id
42 }
43
44 pub fn mreset(&mut self, q: usize) -> usize {
45 let id = self.m(q);
46 self.reset(q);
47 id
48 }
49
50 pub fn reset(&mut self, q: usize) {
51 self.qubit_map.remove(q);
52 }
53
54 pub fn qubit_allocate(&mut self) -> usize {
55 let id = self.next_qubit_id;
56 self.next_qubit_id += 1;
57 let _ = self.map(id);
58 id
59 }
60
61 pub fn qubit_release(&mut self, _q: usize) {
62 self.next_qubit_id -= 1;
63 }
64
65 pub fn measurements(&self) -> impl Iterator<Item = &(HardwareId, usize)> {
66 self.measurements.iter()
67 }
68
69 #[must_use]
70 pub fn num_qubits(&self) -> usize {
71 self.next_qubit_hardware_id.0
72 }
73
74 #[must_use]
75 pub fn num_measurements(&self) -> usize {
76 self.next_meas_id
77 }
78
79 #[must_use]
80 fn get_meas_id(&mut self) -> usize {
81 let id = self.next_meas_id;
82 self.next_meas_id += 1;
83 id
84 }
85}
86
87#[derive(Copy, Clone, Default)]
88pub struct HardwareId(pub usize);
89