Q2NS dev
ns-3 module
Loading...
Searching...
No Matches
q2ns-qstate-registry.h
Go to the documentation of this file.
1/*-----------------------------------------------------------------------------
2 * Q2NS - Quantum Network Simulator
3 * Copyright (c) 2026 quantuminternet.it
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *---------------------------------------------------------------------------*/
9/**
10 * @file q2ns-qstate-registry.h
11 * @brief Declares q2ns::QStateRegistry and related types for tracking quantum
12 * states, qubit membership, and qubit locations.
13 */
14
15#pragma once
16
17#include "ns3/q2ns-types.h"
18
19#include <functional>
20#include <memory>
21#include <unordered_map>
22#include <unordered_set>
23#include <vector>
24
25namespace q2ns {
26
27class Qubit;
28class QState;
29
30/**
31 * @struct CreateStateResult
32 * @brief Result of creating a new backend state.
33 *
34 * The returned indices are the initial in-state qubit indices for that state,
35 * typically 0 through N-1.
36 */
38 StateId stateId = 0; //!< Assigned state id.
39 std::vector<unsigned int> indices; //!< Initial in-state qubit indices.
40};
41
42/**
43 * @ingroup q2ns_qstate
44 * @class QStateRegistry
45 * @brief Internal registry that owns backend states and tracks qubit membership
46 * and location.
47 *
48 * QStateRegistry is not intended to be a primary user-facing API. It acts as
49 * the central source of truth for:
50 * - backend state ownership
51 * - qubit membership within each state
52 * - current qubit location
53 * - qubit-id to handle resolution
54 *
55 * QNode, QProcessor, QNetworker, and NetController rely on this registry to
56 * coordinate state evolution, movement, and lookup.
57 *
58 * @see QNode
59 * @see QProcessor
60 * @see QNetworker
61 * @see NetController
62 */
64public:
65 /**
66 * @brief Callback type used to assign RNG streams to newly registered states.
67 */
68 using StreamAssigner = std::function<void(QState&)>;
69
70 /**
71 * @brief Set the callback used to assign streams to newly created states.
72 *
73 * This is typically installed by NetController so states created after stream
74 * assignment receive deterministic streams automatically.
75 *
76 * @param fn Stream-assignment callback.
77 *
78 * @see GetStatesSortedById
79 */
81 streamAssigner_ = std::move(fn);
82 }
83
84 /**
85 * @brief Set the default backend used for newly created states.
86 * @param b Backend enum value.
87 *
88 * @see GetDefaultBackend
89 * @see BackendFromString
90 */
92
93 /**
94 * @brief Get the default backend used for newly created states.
95 * @return Current backend enum value.
96 *
97 * @see SetDefaultBackend
98 */
100
101 /**
102 * @brief Create a new state with n qubits initialized in the |0...0> state.
103 * @param n Number of qubits in the new state.
104 * @return Result containing the assigned state id and initial qubit indices.
105 *
106 * @see CreateStateFromExisting
107 */
108 CreateStateResult CreateState(unsigned int n);
109
110 /**
111 * @brief Register an already-constructed backend state object.
112 *
113 * The caller is responsible for binding qubits to the returned state id and
114 * indices and then calling Register() for each qubit handle.
115 *
116 * @param state Backend state to register.
117 * @return Result containing the assigned state id and initial qubit indices.
118 *
119 * @see CreateState
120 * @see Register
121 */
122 CreateStateResult CreateStateFromExisting(const std::shared_ptr<QState>& state);
123
124 /**
125 * @brief Ensure the provided qubits belong to a single backend state.
126 *
127 * If all qubits already belong to one state, that state is returned
128 * unchanged. Otherwise, the involved states are merged, qubits are rebound to
129 * the merged state with compacted indices, and empty predecessor states are
130 * removed.
131 *
132 * @param qs Qubits that must share one backend state.
133 * @return Shared pointer to the resulting backend state, or nullptr if the
134 * merge is rejected.
135 *
136 * @see GetState
137 * @see RemoveState
138 */
139 std::shared_ptr<QState> MergeStates(const std::vector<std::shared_ptr<Qubit>>& qs);
140
141 /**
142 * @brief Remove a backend state and its membership tracking.
143 * @param id State id to remove.
144 *
145 * @see MergeStates
146 */
147 void RemoveState(StateId id);
148
149 /**
150 * @brief Get a backend state by state id.
151 * @param stateId State identifier.
152 * @return Shared pointer to the state, or nullptr if unknown.
153 *
154 * @see GetState(const std::shared_ptr<Qubit>&)
155 */
156 std::shared_ptr<QState> GetState(StateId stateId) const;
157
158 /**
159 * @brief Get the backend state associated with a qubit handle.
160 * @param q Qubit handle.
161 * @return Shared pointer to the state, or nullptr if the qubit is null or unknown.
162 *
163 * @see GetState(StateId)
164 */
165 std::shared_ptr<QState> GetState(const std::shared_ptr<Qubit>& q) const;
166
167 /**
168 * @brief Register a qubit handle as a member of its current state.
169 *
170 * If the qubit does not yet have a stable qubit id, one is assigned here.
171 * If the qubit does not yet have a tracked location, it is marked Unset.
172 *
173 * @param q Qubit handle.
174 *
175 * @see Unregister
176 * @see SetLocation
177 */
178 void Register(const std::shared_ptr<Qubit>& q);
179
180 /**
181 * @brief Unregister a qubit handle from its current state membership list.
182 * @param q Qubit handle.
183 *
184 * @see Register
185 * @see UnregisterEverywhere
186 */
187 void Unregister(const std::shared_ptr<Qubit>& q);
188
189 /**
190 * @brief Remove a qubit handle from membership lists across all states.
191 * @param q Qubit handle.
192 *
193 * @see Unregister
194 */
195 void UnregisterEverywhere(const std::shared_ptr<Qubit>& q);
196
197 /**
198 * @brief Set the tracked location for a qubit handle.
199 *
200 * This also ensures the global qubit-id directory can resolve the qubit id
201 * back to the handle.
202 *
203 * @param q Qubit handle.
204 * @param loc Location descriptor.
205 *
206 * @see GetLocation
207 */
208 void SetLocation(const std::shared_ptr<Qubit>& q, Location loc);
209
210 /**
211 * @brief Set the tracked location for a qubit id.
212 * @param id Qubit id.
213 * @param loc Location descriptor.
214 *
215 * @see GetLocation
216 */
217 void SetLocation(QubitId id, Location loc);
218
219 /**
220 * @brief Get the tracked location for a qubit handle.
221 * @param q Qubit handle.
222 * @return Current location if tracked, otherwise an Unset location.
223 *
224 * @see GetLocation(QubitId)
225 */
226 Location GetLocation(const std::shared_ptr<Qubit>& q) const;
227
228 /**
229 * @brief Get the tracked location for a qubit id.
230 * @param id Qubit id.
231 * @return Current location if tracked, otherwise an Unset location.
232 *
233 * @see GetLocation(const std::shared_ptr<Qubit>&)
234 */
235 Location GetLocation(QubitId id) const;
236
237 /**
238 * @brief Return qubit ids currently located at a given node.
239 *
240 * Only qubits whose tracked location is LocationType::Node with matching
241 * ownerId are returned.
242 *
243 * @param nodeId Node identifier.
244 * @return Snapshot of qubit ids currently local to that node.
245 *
246 * @see GetLocalQubits
247 */
248 std::vector<QubitId> GetQubitsAtNode(uint32_t nodeId) const;
249
250 /**
251 * @brief Return a tracked qubit handle by qubit id.
252 * @param id Qubit identifier.
253 * @return Shared pointer to the qubit handle, or nullptr if unknown.
254 *
255 * @see GetQubitsAtNode
256 * @see GetLocalQubits
257 */
258 std::shared_ptr<Qubit> GetQubitHandle(QubitId id) const;
259
260 /**
261 * @brief Return qubit handles currently located at a given node.
262 *
263 * The returned vector is a snapshot taken at call time. Element order is not guaranteed.
264 *
265 * @param nodeId Node identifier.
266 * @return Snapshot of qubit handles currently local to that node.
267 *
268 * @see GetQubitsAtNode
269 */
270 std::vector<std::shared_ptr<Qubit>> GetLocalQubits(uint32_t nodeId) const;
271
272 /**
273 * @brief Return qubit handles that currently belong to a given state.
274 * @param stateId State identifier.
275 * @return Snapshot of qubit handles in that state.
276 *
277 * @see GetState
278 */
279 std::vector<std::shared_ptr<Qubit>> QubitsOf(StateId stateId) const;
280
281 /**
282 * @brief Return all registered states sorted by state id.
283 *
284 * This provides deterministic iteration order for operations such as delayed
285 * RNG stream assignment.
286 *
287 * @return Vector of states sorted by state id.
288 *
289 * @see SetStreamAssigner
290 */
291 std::vector<std::shared_ptr<QState>> GetStatesSortedById() const;
292
293private:
294 StreamAssigner streamAssigner_{}; //!< Callback used when a new state is registered.
295
296 QStateBackend defaultBackend_ = QStateBackend::Ket; //!< Default backend for CreateState().
297
298 StateId nextStateId_ = 1; //!< Next state id to assign.
299 QubitId nextQubitId_ = 1; //!< Next qubit id to assign.
300
301 std::unordered_map<StateId, std::shared_ptr<QState>> states_; //!< State id to backend state.
302 std::unordered_map<StateId, std::vector<std::shared_ptr<Qubit>>>
303 members_; //!< State id to shared member qubit handles.
304 std::unordered_map<QubitId, Location> location_; //!< Qubit id to current location.
305 std::unordered_map<uint32_t, std::unordered_set<QubitId>>
306 qubitsAtNode_; //!< Node id to currently local qubit ids.
307 std::unordered_map<QubitId, std::shared_ptr<Qubit>> qubitById_; //!< Qubit id to shared handle.
308};
309
310/**
311 * @brief Convert a backend name string to a QStateBackend enum value.
312 *
313 * Unrecognized names fall back to QStateBackend::Ket.
314 *
315 * @param s Backend name string.
316 * @return Corresponding backend enum value.
317 */
318QStateBackend BackendFromString(std::string_view s);
319
320} // namespace q2ns
Internal registry that owns backend states and tracks qubit membership and location.
QStateBackend GetDefaultBackend() const
Get the default backend used for newly created states.
void Unregister(const std::shared_ptr< Qubit > &q)
Unregister a qubit handle from its current state membership list.
void RemoveState(StateId id)
Remove a backend state and its membership tracking.
std::unordered_map< QubitId, std::shared_ptr< Qubit > > qubitById_
Qubit id to shared handle.
std::unordered_map< StateId, std::vector< std::shared_ptr< Qubit > > > members_
State id to shared member qubit handles.
StreamAssigner streamAssigner_
Callback used when a new state is registered.
QStateBackend defaultBackend_
Default backend for CreateState().
void Register(const std::shared_ptr< Qubit > &q)
Register a qubit handle as a member of its current state.
void SetLocation(const std::shared_ptr< Qubit > &q, Location loc)
Set the tracked location for a qubit handle.
void SetDefaultBackend(QStateBackend b)
Set the default backend used for newly created states.
std::vector< std::shared_ptr< QState > > GetStatesSortedById() const
Return all registered states sorted by state id.
QubitId nextQubitId_
Next qubit id to assign.
CreateStateResult CreateState(unsigned int n)
Create a new state with n qubits initialized in the |0...0> state.
std::shared_ptr< QState > GetState(StateId stateId) const
Get a backend state by state id.
std::vector< QubitId > GetQubitsAtNode(uint32_t nodeId) const
Return qubit ids currently located at a given node.
void UnregisterEverywhere(const std::shared_ptr< Qubit > &q)
Remove a qubit handle from membership lists across all states.
std::vector< std::shared_ptr< Qubit > > GetLocalQubits(uint32_t nodeId) const
Return qubit handles currently located at a given node.
CreateStateResult CreateStateFromExisting(const std::shared_ptr< QState > &state)
Register an already-constructed backend state object.
std::shared_ptr< Qubit > GetQubitHandle(QubitId id) const
Return a tracked qubit handle by qubit id.
StateId nextStateId_
Next state id to assign.
Location GetLocation(const std::shared_ptr< Qubit > &q) const
Get the tracked location for a qubit handle.
std::unordered_map< StateId, std::shared_ptr< QState > > states_
State id to backend state.
std::shared_ptr< QState > MergeStates(const std::vector< std::shared_ptr< Qubit > > &qs)
Ensure the provided qubits belong to a single backend state.
std::function< void(QState &)> StreamAssigner
Callback type used to assign RNG streams to newly registered states.
std::unordered_map< uint32_t, std::unordered_set< QubitId > > qubitsAtNode_
Node id to currently local qubit ids.
std::unordered_map< QubitId, Location > location_
Qubit id to current location.
std::vector< std::shared_ptr< Qubit > > QubitsOf(StateId stateId) const
Return qubit handles that currently belong to a given state.
void SetStreamAssigner(StreamAssigner fn)
Set the callback used to assign streams to newly created states.
Backend-agnostic interface for a quantum state object.
Definition q2ns-qstate.h:51
std::uint64_t QubitId
Stable identifier for a registered qubit handle.
Definition q2ns-types.h:61
std::uint64_t StateId
Stable identifier for a registered backend state.
Definition q2ns-types.h:55
QStateBackend BackendFromString(std::string_view s)
Convert a backend name string to a QStateBackend enum value.
QStateBackend
Backend family used when creating new quantum states.
Definition q2ns-types.h:94
@ Ket
State-vector backend.
Result of creating a new backend state.
StateId stateId
Assigned state id.
std::vector< unsigned int > indices
Initial in-state qubit indices.
Current tracked location of a qubit.
Definition q2ns-types.h:136