114 NS_LOG_WARN(
"MergeStates rejected: empty qubit list.");
118 for (
const auto& q : qs) {
120 NS_LOG_WARN(
"MergeStates rejected: null qubit in input list.");
125 std::vector<StateId> sids;
126 sids.reserve(qs.size());
127 for (
const auto& q : qs) {
128 sids.push_back(q->GetStateId());
130 std::sort(sids.begin(), sids.end());
131 sids.erase(std::unique(sids.begin(), sids.end()), sids.end());
133 if (sids.size() == 1) {
141 std::shared_ptr<QState> state;
143 std::vector<std::shared_ptr<Qubit>> members;
146 std::vector<StateBucket> buckets;
147 buckets.reserve(sids.size());
149 for (
auto sid : sids) {
154 NS_LOG_WARN(
"MergeStates failed: referenced state was not found.");
160 std::sort(bucket.members.begin(), bucket.members.end(), [](
const auto& x,
const auto& y) {
161 return x->GetIndexInState() < y->GetIndexInState();
164 bucket.leadingQubitId = bucket.members.empty() ? 0 : bucket.members.front()->GetQubitId();
166 buckets.push_back(std::move(bucket));
169 std::sort(buckets.begin(), buckets.end(), [](
const StateBucket& a,
const StateBucket& b) {
170 if (a.leadingQubitId != b.leadingQubitId) {
171 return a.leadingQubitId < b.leadingQubitId;
173 return a.sid < b.sid;
176 std::vector<std::shared_ptr<Qubit>> allQs;
177 for (
const auto& bucket : buckets) {
178 allQs.insert(allQs.end(), bucket.members.begin(), bucket.members.end());
181 auto merged = buckets.front().state;
182 for (std::size_t i = 1; i < buckets.size(); ++i) {
183 merged = merged->MergeDisjoint(*buckets[i].state);
185 NS_LOG_WARN(
"MergeStates failed: backend merge returned null.");
190 auto created = CreateStateFromExisting(merged);
191 if (created.stateId == 0) {
195 for (std::size_t i = 0; i < allQs.size(); ++i) {
196 const auto& q = allQs[i];
197 auto loc = GetLocation(q);
199 UnregisterEverywhere(q);
200 q->SetStateId(created.stateId);
201 q->SetIndexInState(created.indices[i]);
206 for (
const auto& bucket : buckets) {
207 if (QubitsOf(bucket.sid).empty()) {
208 RemoveState(bucket.sid);
212 return GetState(created.stateId);
220std::vector<std::shared_ptr<QState>> QStateRegistry::GetStatesSortedById()
const {
221 std::vector<std::pair<StateId, std::shared_ptr<QState>>> items;
222 items.reserve(states_.size());
224 for (
const auto& kv : states_) {
225 items.emplace_back(kv.first, kv.second);
228 std::sort(items.begin(), items.end(),
229 [](
const auto& a,
const auto& b) { return a.first < b.first; });
231 std::vector<std::shared_ptr<QState>> out;
232 out.reserve(items.size());
233 for (
auto& kv : items) {
234 out.push_back(std::move(kv.second));
240void QStateRegistry::Register(
const std::shared_ptr<Qubit>& q) {
242 NS_LOG_WARN(
"Register rejected: null qubit.");
248 if (q->GetQubitId() == 0) {
249 q->SetQubitId(nextQubitId_++);
252 if (location_.count(q->GetQubitId()) == 0) {
256 auto& vec = members_[
sid];
257 const auto raw = q.get();
259 for (
const auto& sp : vec) {
260 if (sp && sp.get() == raw) {
268void QStateRegistry::Unregister(
const std::shared_ptr<Qubit>& q) {
270 NS_LOG_WARN(
"Unregister rejected: null qubit.");
275 auto it = members_.find(
sid);
276 if (it == members_.end()) {
280 auto& vec = it->second;
281 const auto raw = q.get();
284 std::remove_if(vec.begin(), vec.end(),
285 [&](
const std::shared_ptr<Qubit>& sp) { return !sp || sp.get() == raw; }),
289void QStateRegistry::UnregisterEverywhere(
const std::shared_ptr<Qubit>& q) {
291 NS_LOG_WARN(
"UnregisterEverywhere rejected: null qubit.");
295 const auto raw = q.get();
297 for (
auto& [
sid, vec] : members_) {
300 std::remove_if(vec.begin(), vec.end(),
301 [&](
const std::shared_ptr<Qubit>& sp) {
return !sp || sp.get() == raw; }),
306void QStateRegistry::SetLocation(
const std::shared_ptr<Qubit>& q,
Location loc) {
308 NS_LOG_WARN(
"SetLocation rejected: null qubit.");
312 qubitById_[q->GetQubitId()] = q;
313 SetLocation(q->GetQubitId(), loc);
317 auto itOld = location_.find(
id);
318 if (itOld != location_.end()) {
319 const auto& oldLoc = itOld->second;
320 if (oldLoc.type == LocationType::Node) {
321 auto itSet = qubitsAtNode_.find(oldLoc.ownerId);
322 if (itSet != qubitsAtNode_.end()) {
323 itSet->second.erase(
id);
324 if (itSet->second.empty()) {
325 qubitsAtNode_.erase(itSet);
333 if (loc.
type == LocationType::Node) {
334 qubitsAtNode_[loc.
ownerId].insert(
id);
361std::vector<QubitId> QStateRegistry::GetQubitsAtNode(uint32_t nodeId)
const {
362 std::vector<QubitId> out;
364 auto it = qubitsAtNode_.find(nodeId);
365 if (it == qubitsAtNode_.end()) {
369 out.reserve(it->second.size());
370 for (
const auto id : it->second) {
386std::vector<std::shared_ptr<Qubit>> QStateRegistry::GetLocalQubits(uint32_t nodeId)
const {
387 std::vector<std::shared_ptr<Qubit>> out;
389 auto it = qubitsAtNode_.find(nodeId);
390 if (it == qubitsAtNode_.end()) {
394 out.reserve(it->second.size());
395 for (
const auto id : it->second) {
396 if (
auto q = GetQubitHandle(
id)) {