59int main(
int argc,
char** argv) {
60 std::cout <<
"[DEMO] Entanglement distribution (3 nodes) starting\n";
62 RngSeedManager::SetSeed(1);
63 RngSeedManager::SetRun(1);
66 cmd.Parse(argc, argv);
69 "examples/example_traces/q2nsviz-entanglement-distribution-example.json");
71 Trace(
"Entanglement Distribution with 3 nodes");
73 Time::SetResolution(Time::NS);
89 const Time kSingleGate = NanoSeconds(100);
90 const Time kTwoQGate = NanoSeconds(300);
91 const Time kQDelay = NanoSeconds(100);
92 const Time kClassical = kQDelay;
98 ch12->SetAttribute(
"Delay", TimeValue(kQDelay));
99 ch13->SetAttribute(
"Delay", TimeValue(kQDelay));
100 ch23->SetAttribute(
"Delay", TimeValue(kQDelay));
110 InternetStackHelper internet;
111 internet.Install(node1);
112 internet.Install(node2);
113 internet.Install(node3);
115 PointToPointHelper p2p;
116 p2p.SetDeviceAttribute(
"DataRate", StringValue(
"100Mbps"));
117 p2p.SetChannelAttribute(
"Delay", StringValue(
"100ns"));
119 Ipv4AddressHelper ipv4;
121 ipv4.SetBase(
"10.1.1.0",
"255.255.255.0");
122 auto ifs12 = ipv4.Assign(p2p.Install(node1, node2));
124 ipv4.SetBase(
"10.1.2.0",
"255.255.255.0");
125 auto ifs13 = ipv4.Assign(p2p.Install(node1, node3));
127 ipv4.SetBase(
"10.1.3.0",
"255.255.255.0");
128 auto ifs23 = ipv4.Assign(p2p.Install(node2, node3));
130 Ipv4GlobalRoutingHelper::PopulateRoutingTables();
140 auto node1AckRx = Socket::CreateSocket(node1, UdpSocketFactory::GetTypeId());
141 node1AckRx->Bind(InetSocketAddress(Ipv4Address::GetAny(),
kAckPort));
142 int node1AcksReceived = 0;
143 node1AckRx->SetRecvCallback([&](Ptr<Socket> sock) {
145 while (sock->RecvFrom(from)) {
147 TraceNodeText(
"Node1", StrCat(
"ACK received (", node1AcksReceived,
"/2 links confirmed)"));
148 std::cout <<
"[NODE1] ACK received (" << node1AcksReceived <<
"/2)\n";
149 if (node1AcksReceived == 2)
150 Trace(
"Node1: both Bell pair links confirmed");
155 auto node2AckRx = Socket::CreateSocket(node2, UdpSocketFactory::GetTypeId());
156 node2AckRx->Bind(InetSocketAddress(Ipv4Address::GetAny(),
kAckPort));
157 node2AckRx->SetRecvCallback([&](Ptr<Socket> sock) {
159 while (sock->RecvFrom(from)) {
160 TraceNodeText(
"Node2",
"ACK from Node3: Bell pair 2 link confirmed");
161 Trace(
"Node2: Bell pair 2 confirmed by Node3");
162 std::cout <<
"[NODE2] ACK from Node3 received\n";
168 auto node2TxSock = Socket::CreateSocket(node2, UdpSocketFactory::GetTypeId());
169 node2TxSock->Connect(InetSocketAddress(ifs12.GetAddress(0),
kAckPort));
171 auto node3ToNode1Sock = Socket::CreateSocket(node3, UdpSocketFactory::GetTypeId());
172 node3ToNode1Sock->Connect(InetSocketAddress(ifs13.GetAddress(0),
kAckPort));
174 auto node3ToNode2Sock = Socket::CreateSocket(node3, UdpSocketFactory::GetTypeId());
175 node3ToNode2Sock->Connect(InetSocketAddress(ifs23.GetAddress(0),
kAckPort));
178 node2->SetRecvCallback([&](std::shared_ptr<Qubit> q) {
180 TraceNodeText(
"Node2",
StrCat(
"Qubit ", q->GetLabel(),
" arrived - entangled with Node1"));
181 std::cout <<
"[NODE2] Qubit " << q->GetLabel() <<
" arrived\n";
182 node2TxSock->Send(Create<Packet>(1));
183 TraceSendPacket(
"Node2",
"Node1", Simulator::Now(), Simulator::Now() + kClassical,
184 StrCat(
"ACK: ", q->GetLabel(),
" received"));
189 int node3QubitCount = 0;
190 node3->SetRecvCallback([&](std::shared_ptr<Qubit> q) {
193 TraceNodeText(
"Node3",
StrCat(
"Qubit ", q->GetLabel(),
" arrived (", node3QubitCount,
"/2)"));
194 std::cout <<
"[NODE3] Qubit " << q->GetLabel() <<
" arrived\n";
195 if (node3QubitCount == 1) {
196 node3ToNode1Sock->Send(Create<Packet>(1));
197 TraceSendPacket(
"Node3",
"Node1", Simulator::Now(), Simulator::Now() + kClassical,
198 StrCat(
"ACK: ", q->GetLabel(),
" received"));
200 node3ToNode2Sock->Send(Create<Packet>(1));
201 TraceSendPacket(
"Node3",
"Node2", Simulator::Now(), Simulator::Now() + kClassical,
202 StrCat(
"ACK: ", q->GetLabel(),
" received"));
207 Simulator::Schedule(MicroSeconds(1), [&] {
208 Trace(
"Step 1: Node1 initializes Bell pair 0 (for Node2)");
211 auto q0a = node1->CreateQubit();
212 q0a->SetLabel(
"bell_0_a");
213 auto q0b = node1->CreateQubit();
214 q0b->SetLabel(
"bell_0_b");
220 Simulator::Schedule(kSingleGate, [=]() {
226 Simulator::Schedule(kTwoQGate, [=]() {
232 Simulator::Schedule(kSingleGate, [=]() {
233 auto t0 = Simulator::Now();
234 node1->Send(q0b, node2->GetId());
235 TraceSendBit(
"bell_0_b",
"Node1",
"Node2",
"quantum", t0, t0 + kQDelay);
238 std::cout <<
"[STEP 1] Bell pair 0 sent: Node1 -> Node2\n";
246 Simulator::Schedule(MicroSeconds(3), [&] {
247 Trace(
"Step 2: Node1 initializes Bell pair 1 (for Node3)");
250 auto q1a = node1->CreateQubit();
251 q1a->SetLabel(
"bell_1_a");
252 auto q1b = node1->CreateQubit();
253 q1b->SetLabel(
"bell_1_b");
258 Simulator::Schedule(kSingleGate, [=]() {
263 Simulator::Schedule(kTwoQGate, [=]() {
268 Simulator::Schedule(kSingleGate, [=]() {
269 auto t0 = Simulator::Now();
270 node1->Send(q1b, node3->GetId());
271 TraceSendBit(
"bell_1_b",
"Node1",
"Node3",
"quantum", t0, t0 + kQDelay);
274 std::cout <<
"[STEP 2] Bell pair 1 sent: Node1 -> Node3\n";
281 Simulator::Schedule(MicroSeconds(5), [&] {
282 Trace(
"Step 3: Node2 initializes Bell pair 2 (for Node3)");
285 auto q2a = node2->CreateQubit();
286 q2a->SetLabel(
"bell_2_a");
287 auto q2b = node2->CreateQubit();
288 q2b->SetLabel(
"bell_2_b");
293 Simulator::Schedule(kSingleGate, [=]() {
298 Simulator::Schedule(kTwoQGate, [=]() {
303 Simulator::Schedule(kSingleGate, [=]() {
304 auto t0 = Simulator::Now();
305 node2->Send(q2b, node3->GetId());
306 TraceSendBit(
"bell_2_b",
"Node2",
"Node3",
"quantum", t0, t0 + kQDelay);
309 std::cout <<
"[STEP 3] Bell pair 2 sent: Node2 -> Node3\n";
316 Simulator::Schedule(MicroSeconds(20), [&] {
317 Trace(
"All Bell pairs distributed and confirmed - full-mesh entanglement established");
318 std::cout <<
"[DONE] All Bell pairs distributed\n";
321 Simulator::Stop(MilliSeconds(1));
323 Simulator::Destroy();
326 std::cout <<
"[DONE] Entanglement distribution finished\n";