Q2NS dev
ns-3 module
Loading...
Searching...
No Matches
q2nsviz-trace.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#pragma once
10
11#include "ns3/nstime.h"
12#include "ns3/q2nsviz-trace-writer.h"
13#include <initializer_list>
14#include <sstream>
15#include <string>
16#include <utility>
17#include <vector>
18
19/*
20 v2 NDJSON schema (viewer.html expects these):
21 - createNode {t_ns, label, x, y}
22 - createChannel {t_ns, from, to, kind}
23 - createQubit {t_ns, node, label}
24 - createCbit {t_ns, node, label}
25 - entangle {t_ns, bits:[...]} // or {t_ns, duration_ns, bits:[...]}
26 - measure {t_ns, bit, base} // or {t_ns, duration_ns, bit, base}
27 - graphMeasure {t_ns, bit, base, supportNode} // or {t_ns, duration_ns, bit, base, supportNode}
28 - sendQubit {t0_ns, t1_ns, bit, from, to}
29 - sendCbit {t0_ns, t1_ns, bit, from, to}
30 - sendPacket {t0_ns, t1_ns, from, to, label[, protocol]}
31 - removeQubit {t_ns, bit, reason} // reason: "lost" | "discarded"
32 - removeCbit {t_ns, bit}
33 - traceText {t_ns, text} // trace panel (persistent)
34 - traceText {t_ns, node, text} // node-local (one step)
35*/
36
37/*-----------------------------------------------------------------------------
38 * StrCat: concatenate any streamable parts into a std::string
39 *---------------------------------------------------------------------------*/
40template <typename... Ts> inline std::string StrCat(Ts&&... parts) {
41 std::ostringstream _oss;
42 (void) std::initializer_list<int>{((_oss << std::forward<Ts>(parts)), 0)...};
43 return _oss.str();
44}
45
46inline uint64_t NowNs() {
47 return ns3::Simulator::Now().GetNanoSeconds();
48}
49
50
51/*-----------------------------------------------------------------------------
52 * Nodes & Channels
53 *---------------------------------------------------------------------------*/
54inline void TraceCreateNode(const std::string& label, int xPct, int yPct) {
55 std::ostringstream o;
56 o << "{"
57 << "\"type\":\"createNode\",\"t_ns\":0,"
58 << "\"label\":" << J(label) << ",\"x\":" << xPct << ",\"y\":" << yPct << "}";
60}
61
62inline void TraceCreateChannel(const std::string& from, const std::string& to,
63 const std::string& kind) {
64 std::ostringstream o;
65 o << "{"
66 << "\"type\":\"createChannel\",\"t_ns\":0,"
67 << "\"from\":" << J(from) << ",\"to\":" << J(to) << ",\"kind\":" << J(kind) << "}";
69}
70
71/*-----------------------------------------------------------------------------
72 * Qubits: create / entangle / measure
73 *---------------------------------------------------------------------------*/
74inline void TraceCreateQubit(const std::string& node, const std::string& bitLabel) {
75 std::ostringstream o;
76 o << "{"
77 << "\"type\":\"createQubit\",\"t_ns\":" << JTns() << ",\"node\":" << J(node)
78 << ",\"label\":" << J(bitLabel) << "}";
80}
81
82/*-----------------------------------------------------------------------------
83 * Classical bits: create / remove
84 *---------------------------------------------------------------------------*/
85inline void TraceCreateCbit(const std::string& node, const std::string& bitLabel) {
86 std::ostringstream o;
87 o << "{"
88 << "\"type\":\"createCbit\",\"t_ns\":" << JTns() << ",\"node\":" << J(node)
89 << ",\"label\":" << J(bitLabel) << "}";
91}
92
93inline void TraceRemoveCbit(const std::string& bitLabel, uint64_t t_ns = NowNs()) {
94 std::ostringstream o;
95 o << "{"
96 << "\"type\":\"removeCbit\","
97 << "\"t_ns\":" << t_ns << ",\"bit\":" << J(bitLabel) << "}";
99}
100
101/*-----------------------------------------------------------------------------
102 * Qubit entanglement and measurement
103 *---------------------------------------------------------------------------*/
104inline void TraceEntangle(const std::vector<std::string>& bits) {
105 std::ostringstream o;
106 o << "{"
107 << "\"type\":\"entangle\",\"t_ns\":" << JTns() << ",\"bits\":[";
108 for (size_t i = 0; i < bits.size(); ++i) {
109 if (i)
110 o << ",";
111 o << J(bits[i]);
112 }
113 o << "]}";
114 TraceWriter::Instance().Write(o.str());
115}
116
117/* TraceEntangle with gate duration for physical accuracy.
118 The visualizer computes t0 = t_ns - duration_ns. */
119inline void TraceEntangle(const std::vector<std::string>& bits, uint64_t duration_ns) {
120 std::ostringstream o;
121 o << "{"
122 << "\"type\":\"entangle\",\"t_ns\":" << JTns() << ",\"duration_ns\":" << duration_ns
123 << ",\"bits\":[";
124 for (size_t i = 0; i < bits.size(); ++i) {
125 if (i)
126 o << ",";
127 o << J(bits[i]);
128 }
129 o << "]}";
130 TraceWriter::Instance().Write(o.str());
131}
132inline void TraceEntangle(const std::vector<std::string>& bits, ns3::Time duration) {
133 TraceEntangle(bits, duration.GetNanoSeconds());
134}
135
136/* Measure/collapse a bit: removes the bit from any entanglement going forward.
137 Optional measurement basis (default "Z"). */
138inline void TraceMeasure(const std::string& bitLabel, const std::string& base = "Z") {
139 std::ostringstream o;
140 o << "{"
141 << "\"type\":\"measure\",\"t_ns\":" << JTns() << ",\"bit\":" << J(bitLabel)
142 << ",\"base\":" << J(base) << "}";
143 TraceWriter::Instance().Write(o.str());
144}
145
146/* TraceMeasure with gate duration for physical accuracy.
147 The visualizer computes t0 = t_ns - duration_ns. */
148inline void TraceMeasure(const std::string& bitLabel, uint64_t duration_ns,
149 const std::string& base = "Z") {
150 std::ostringstream o;
151 o << "{"
152 << "\"type\":\"measure\",\"t_ns\":" << JTns() << ",\"duration_ns\":" << duration_ns
153 << ",\"bit\":" << J(bitLabel) << ",\"base\":" << J(base) << "}";
154 TraceWriter::Instance().Write(o.str());
155}
156inline void TraceMeasure(const std::string& bitLabel, ns3::Time duration,
157 const std::string& base = "Z") {
158 TraceMeasure(bitLabel, duration.GetNanoSeconds(), base);
159}
160
161/* Graph state measurement: visualization for graph-state operations. */
162inline void TraceGraphMeasure(const std::string& bitLabel, const std::string& base = "Z",
163 const std::string& supportNode = "") {
164 std::ostringstream o;
165 o << "{"
166 << "\"type\":\"graphMeasure\",\"t_ns\":" << JTns() << ",\"bit\":" << J(bitLabel)
167 << ",\"base\":" << J(base);
168 if (!supportNode.empty()) {
169 o << ",\"supportNode\":" << J(supportNode);
170 }
171 o << "}";
172 TraceWriter::Instance().Write(o.str());
173}
174
175/* TraceGraphMeasure with gate duration for physical accuracy.
176 The visualizer computes t0 = t_ns - duration_ns. */
177inline void TraceGraphMeasure(const std::string& bitLabel, uint64_t duration_ns,
178 const std::string& base = "Z",
179 const std::string& supportNode = "") {
180 std::ostringstream o;
181 o << "{"
182 << "\"type\":\"graphMeasure\",\"t_ns\":" << JTns() << ",\"duration_ns\":" << duration_ns
183 << ",\"bit\":" << J(bitLabel) << ",\"base\":" << J(base);
184 if (!supportNode.empty()) {
185 o << ",\"supportNode\":" << J(supportNode);
186 }
187 o << "}";
188 TraceWriter::Instance().Write(o.str());
189}
190inline void TraceGraphMeasure(const std::string& bitLabel, ns3::Time duration,
191 const std::string& base = "Z",
192 const std::string& supportNode = "") {
193 TraceGraphMeasure(bitLabel, duration.GetNanoSeconds(), base, supportNode);
194}
195
196inline void TraceRemoveQubit(const std::string& bitLabel,
197 const std::string& reason = "discarded",
198 uint64_t t_ns = NowNs()) {
199 std::ostringstream o;
200 o << "{"
201 << "\"type\":\"removeQubit\","
202 << "\"t_ns\":" << t_ns << ",\"bit\":" << J(bitLabel)
203 << ",\"reason\":" << J(reason) << "}";
204 TraceWriter::Instance().Write(o.str());
205}
206
207
208/*-----------------------------------------------------------------------------
209 * Movement: sendQubit, sendCbit & sendPacket
210 *---------------------------------------------------------------------------*/
211inline void TraceSendQubit(const std::string& bitLabel, const std::string& from,
212 const std::string& to, uint64_t t0_ns, uint64_t t1_ns) {
213 std::ostringstream o;
214 o << "{"
215 << "\"type\":\"sendQubit\",\"t0_ns\":" << t0_ns << ",\"t1_ns\":" << t1_ns
216 << ",\"bit\":" << J(bitLabel) << ",\"from\":" << J(from) << ",\"to\":" << J(to) << "}";
217 TraceWriter::Instance().Write(o.str());
218}
219inline void TraceSendQubit(const std::string& bitLabel, const std::string& from,
220 const std::string& to, ns3::Time t0, ns3::Time t1) {
221 TraceSendQubit(bitLabel, from, to, t0.GetNanoSeconds(), t1.GetNanoSeconds());
222}
223
224inline void TraceSendCbit(const std::string& bitLabel, const std::string& from,
225 const std::string& to, uint64_t t0_ns, uint64_t t1_ns) {
226 std::ostringstream o;
227 o << "{"
228 << "\"type\":\"sendCbit\",\"t0_ns\":" << t0_ns << ",\"t1_ns\":" << t1_ns
229 << ",\"bit\":" << J(bitLabel) << ",\"from\":" << J(from) << ",\"to\":" << J(to) << "}";
230 TraceWriter::Instance().Write(o.str());
231}
232inline void TraceSendCbit(const std::string& bitLabel, const std::string& from,
233 const std::string& to, ns3::Time t0, ns3::Time t1) {
234 TraceSendCbit(bitLabel, from, to, t0.GetNanoSeconds(), t1.GetNanoSeconds());
235}
236
237inline void TraceSendPacket(const std::string& from, const std::string& to, uint64_t t0_ns,
238 uint64_t t1_ns, const std::string& label,
239 const std::string& protocol = "") {
240 std::ostringstream o;
241 o << "{"
242 << "\"type\":\"sendPacket\",\"t0_ns\":" << t0_ns << ",\"t1_ns\":" << t1_ns
243 << ",\"from\":" << J(from) << ",\"to\":" << J(to) << ",\"label\":" << J(label);
244 if (!protocol.empty()) { o << ",\"protocol\":" << J(protocol); }
245 o << "}";
246 TraceWriter::Instance().Write(o.str());
247}
248inline void TraceSendPacket(const std::string& from, const std::string& to, ns3::Time t0,
249 ns3::Time t1, const std::string& label,
250 const std::string& protocol = "") {
251 TraceSendPacket(from, to, t0.GetNanoSeconds(), t1.GetNanoSeconds(), label, protocol);
252}
253
254/*-----------------------------------------------------------------------------
255 * Traces: HUD (persistent) and node-local (one-step)
256 *---------------------------------------------------------------------------*/
257inline void _TraceString(const std::string& text) {
258 std::ostringstream o;
259 o << "{"
260 << "\"type\":\"traceText\",\"t_ns\":" << JTns() << ",\"text\":" << J(text) << "}";
261 TraceWriter::Instance().Write(o.str());
262}
263
264inline void Trace(const std::string& text) {
265 _TraceString(text);
266}
267
268template <typename... Ts> inline void Trace(Ts&&... parts) {
269 _TraceString(StrCat(std::forward<Ts>(parts)...));
270}
271
272inline void _TraceNodeTextString(const std::string& node, const std::string& text) {
273 std::ostringstream o;
274 o << "{"
275 << "\"type\":\"traceText\",\"t_ns\":" << JTns() << ",\"node\":" << J(node)
276 << ",\"text\":" << J(text) << "}";
277 TraceWriter::Instance().Write(o.str());
278}
279
280inline void TraceNodeText(const std::string& node, const std::string& text) {
281 _TraceNodeTextString(node, text);
282}
283
284template <typename... Ts> inline void TraceNodeText(const std::string& node, Ts&&... parts) {
285 _TraceNodeTextString(node, StrCat(std::forward<Ts>(parts)...));
286}
static TraceWriter & Instance()
void Write(const std::string &line)
std::string J(const std::string &s)
uint64_t JTns()
void TraceRemoveQubit(const std::string &bitLabel, const std::string &reason="discarded", uint64_t t_ns=NowNs())
std::string StrCat(Ts &&... parts)
void TraceSendCbit(const std::string &bitLabel, const std::string &from, const std::string &to, uint64_t t0_ns, uint64_t t1_ns)
void Trace(const std::string &text)
void TraceSendQubit(const std::string &bitLabel, const std::string &from, const std::string &to, uint64_t t0_ns, uint64_t t1_ns)
void TraceCreateQubit(const std::string &node, const std::string &bitLabel)
void TraceNodeText(const std::string &node, const std::string &text)
void TraceEntangle(const std::vector< std::string > &bits)
void TraceRemoveCbit(const std::string &bitLabel, uint64_t t_ns=NowNs())
void TraceMeasure(const std::string &bitLabel, const std::string &base="Z")
void TraceGraphMeasure(const std::string &bitLabel, const std::string &base="Z", const std::string &supportNode="")
void TraceCreateCbit(const std::string &node, const std::string &bitLabel)
uint64_t NowNs()
void TraceCreateNode(const std::string &label, int xPct, int yPct)
void TraceCreateChannel(const std::string &from, const std::string &to, const std::string &kind)
void _TraceString(const std::string &text)
void _TraceNodeTextString(const std::string &node, const std::string &text)
void TraceSendPacket(const std::string &from, const std::string &to, uint64_t t0_ns, uint64_t t1_ns, const std::string &label, const std::string &protocol="")