Skip to main content

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}