cqlib_core/compile/resource/model.rs
1// This code is part of Cqlib.
2//
3// (C) Copyright China Telecom Quantum Group 2025-2026
4//
5// This code is licensed under the Apache License, Version 2.0.
6// You may obtain a copy of this license in the LICENSE.txt file in
7// the root directory of this source tree or at
8// http://www.apache.org/licenses/LICENSE-2.0.
9//
10// Any modifications or derivative works of this code must retain this
11// copyright notice, and modified files need to carry a notice indicating
12// that they have been altered from the originals.
13
14use crate::circuit::Qubit;
15use std::collections::BTreeSet;
16
17/// Source from which a compiler-visible logical qubit entered the resource pool.
18///
19/// Origins determine which usage contracts a qubit may satisfy. They are
20/// bookkeeping facts, not conclusions inferred by quantum-state analysis.
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub(crate) enum QubitOrigin {
23 /// A qubit present in the circuit before compiler resource management began.
24 Input,
25 /// A clean logical ancillary qubit created by the compiler before layout.
26 CompilerAllocated,
27}
28
29/// State-restoration contract required by an ancillary-resource consumer.
30///
31/// A consumer must satisfy the selected contract before releasing its lease.
32/// The resource manager records this requirement but does not prove it.
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
34pub enum AncillaRequirement {
35 /// The qubit must enter and leave the consumer in `|0>`.
36 CleanZero,
37 /// The qubit may enter in an unknown state and must be restored exactly.
38 Dirty,
39}
40
41impl AncillaRequirement {
42 pub(super) const fn diagnostic_name(self) -> &'static str {
43 match self {
44 Self::CleanZero => "clean-zero",
45 Self::Dirty => "dirty",
46 }
47 }
48}
49
50/// Request for a temporary ancillary-qubit lease.
51///
52/// A planner constructs a request for each algorithm candidate and passes it to
53/// [`super::ResourceManager::preview`]. The request does not reserve resources.
54#[derive(Debug, Clone, PartialEq, Eq)]
55pub struct ResourceRequest {
56 /// State-restoration contract required by the consuming algorithm.
57 pub requirement: AncillaRequirement,
58 /// Number of ancillary qubits required by the algorithm.
59 pub count: usize,
60 /// Qubits that the current algorithm must not consume as ancillary resources.
61 ///
62 /// This normally includes the algorithm's data, control, and target qubits.
63 /// Every excluded qubit must already be registered with the manager.
64 pub excluded: BTreeSet<Qubit>,
65}
66
67/// Side-effect-free preview of resources that can satisfy a request.
68///
69/// A plan is produced by [`super::ResourceManager::preview`] and may be
70/// inspected while comparing algorithm candidates. It does not reserve qubits
71/// or mutate the circuit. A caller must pass the selected plan to
72/// [`super::ResourceManager::commit`] before using its qubits.
73///
74/// Plans are manager-specific snapshots. Any successful resource-pool mutation
75/// makes older plans stale.
76#[derive(Debug, Clone, PartialEq, Eq)]
77pub struct ResourcePlan {
78 manager_id: u64,
79 requirement: AncillaRequirement,
80 qubits: Vec<Qubit>,
81 new_qubits: Vec<Qubit>,
82 revision: u64,
83}
84
85impl ResourcePlan {
86 pub(super) const fn new(
87 manager_id: u64,
88 requirement: AncillaRequirement,
89 qubits: Vec<Qubit>,
90 new_qubits: Vec<Qubit>,
91 revision: u64,
92 ) -> Self {
93 Self {
94 manager_id,
95 requirement,
96 qubits,
97 new_qubits,
98 revision,
99 }
100 }
101
102 /// Returns the logical qubits selected for the prospective lease.
103 pub fn qubits(&self) -> &[Qubit] {
104 &self.qubits
105 }
106
107 /// Returns the ancillary-resource contract captured by this plan.
108 pub const fn requirement(&self) -> AncillaRequirement {
109 self.requirement
110 }
111
112 /// Returns how many logical qubits must be added when this plan is committed.
113 pub fn num_new_qubits(&self) -> usize {
114 self.new_qubits.len()
115 }
116
117 pub(super) const fn revision(&self) -> u64 {
118 self.revision
119 }
120
121 pub(super) const fn manager_id(&self) -> u64 {
122 self.manager_id
123 }
124
125 pub(super) fn new_qubits(&self) -> &[Qubit] {
126 &self.new_qubits
127 }
128}
129
130/// Credential representing an active ancillary-resource lease.
131///
132/// A lease is returned by [`super::ResourceManager::commit`] after its qubits
133/// have been reserved. A consuming algorithm may use [`Self::qubits`] until it
134/// has restored the contract reported by [`Self::requirement`], then must pass
135/// the lease to [`super::ResourceManager::release`].
136#[derive(Debug, Clone, PartialEq, Eq)]
137pub struct ResourceLease {
138 manager_id: u64,
139 id: u64,
140 requirement: AncillaRequirement,
141 qubits: Vec<Qubit>,
142}
143
144impl ResourceLease {
145 pub(super) const fn new(
146 manager_id: u64,
147 id: u64,
148 requirement: AncillaRequirement,
149 qubits: Vec<Qubit>,
150 ) -> Self {
151 Self {
152 manager_id,
153 id,
154 requirement,
155 qubits,
156 }
157 }
158
159 /// Returns the manager-local identifier for this lease.
160 pub const fn id(&self) -> u64 {
161 self.id
162 }
163
164 pub(super) const fn manager_id(&self) -> u64 {
165 self.manager_id
166 }
167
168 /// Returns the leased logical qubits.
169 pub fn qubits(&self) -> &[Qubit] {
170 &self.qubits
171 }
172
173 /// Returns the ancillary-resource contract captured by this lease.
174 pub const fn requirement(&self) -> AncillaRequirement {
175 self.requirement
176 }
177}