diff --git a/.project b/.project
new file mode 100644
index 000000000..0f4eb150e
--- /dev/null
+++ b/.project
@@ -0,0 +1,11 @@
+
+
+ quisp
+
+
+
+
+
+
+
+
diff --git a/quisp/.cproject b/quisp/.cproject
index 9992fc358..f708e1696 100644
--- a/quisp/.cproject
+++ b/quisp/.cproject
@@ -1,210 +1,106 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/quisp/.tmp16996 b/quisp/.tmp16996
new file mode 100644
index 000000000..e6fbd2402
--- /dev/null
+++ b/quisp/.tmp16996
@@ -0,0 +1 @@
+out/clang-release//channels/QuantumChannel.o out/clang-release//modules/dummyModule.o out/clang-release//modules/Application/Application.o out/clang-release//modules/Common/Queue.o out/clang-release//modules/Common/Router.o out/clang-release//modules/PhysicalConnection/BSA/BellStateAnalyzer.o out/clang-release//modules/PhysicalConnection/BSA/HoMController.o out/clang-release//modules/PhysicalConnection/EPPS/EntangledPhotonPairSource.o out/clang-release//modules/PhysicalConnection/EPPS/SPDC_Controller.o out/clang-release//modules/QNIC/PhotonicSwitch/PhotonicSwitch.o out/clang-release//modules/QNIC/StationaryQubit/StationaryQubit.o out/clang-release//modules/QRSA/ConnectionManager/ConnectionManager.o out/clang-release//modules/QRSA/HardwareMonitor/HardwareMonitor.o out/clang-release//modules/QRSA/RealTimeController/RealTimeController.o out/clang-release//modules/QRSA/RoutingDaemon/RoutingDaemon.o out/clang-release//modules/QRSA/RuleEngine/BellPairStore.o out/clang-release//modules/QRSA/RuleEngine/RuleEngine.o out/clang-release//rules/Condition.o out/clang-release//rules/example.o out/clang-release//rules/Rule.o out/clang-release//rules/RuleSet.o out/clang-release//rules/actions/Action.o out/clang-release//rules/actions/DoublePurifyAction.o out/clang-release//rules/actions/DoubleSelectionAction.o out/clang-release//rules/actions/DoubleSelectionDualAction.o out/clang-release//rules/actions/DoubleSelectionDualActionSecond.o out/clang-release//rules/actions/GeneralizedSwappingAction.o out/clang-release//rules/actions/PurifyAction.o out/clang-release//rules/actions/RandomMeasureAction.o out/clang-release//rules/actions/SimultaneousSwappingAction.o out/clang-release//rules/actions/SwappingAction.o out/clang-release//rules/clauses/EnoughResourceClause.o out/clang-release//rules/clauses/FidelityClause.o out/clang-release//rules/clauses/MeasureCountClause.o out/clang-release//rules/clauses/PurificationCountClause.o out/clang-release//rules/clauses/WaitClause.o out/clang-release//test_utils/Gate.o out/clang-release//test_utils/QNode.o out/clang-release//test_utils/Simulation.o out/clang-release//test_utils/StaticEnv.o out/clang-release//test_utils/UtilFunctions.o out/clang-release//utils/ComponentProvider.o out/clang-release//utils/DefaultComponentProviderStrategy.o out/clang-release//PhotonicQubit_m.o out/clang-release//messages/base_messages_m.o out/clang-release//messages/connection_setup_messages_m.o out/clang-release//messages/entanglement_swapping_messages_m.o out/clang-release//messages/HoM_ipc_messages_m.o out/clang-release//messages/link_generation_messages_m.o out/clang-release//messages/purification_messages_m.o out/clang-release//messages/QNode_ipc_messages_m.o out/clang-release//messages/tomography_messages_m.o
diff --git a/quisp/.tmplib16996 b/quisp/.tmplib16996
new file mode 100644
index 000000000..72af404a2
Binary files /dev/null and b/quisp/.tmplib16996 differ
diff --git a/quisp/messages/connection_setup_messages.msg b/quisp/messages/connection_setup_messages.msg
index d8d7d360c..5fec21f52 100644
--- a/quisp/messages/connection_setup_messages.msg
+++ b/quisp/messages/connection_setup_messages.msg
@@ -24,6 +24,8 @@ packet ConnectionSetupRequest extends Header
int stack_of_QNodeIndexes[];
int stack_of_linkCosts[];
QNIC_pair_info stack_of_QNICs[];
+
+ int number_of_clients;
}
packet RejectConnectionSetupRequest extends Header
@@ -41,4 +43,7 @@ packet ConnectionSetupResponse extends Header
RuleSetField RuleSet;
int application_type;
int stack_of_QNodeIndexes[];
+
+ bool isMultipartite;
+ string label;
}
diff --git a/quisp/messages/entanglement_swapping_messages.msg b/quisp/messages/entanglement_swapping_messages.msg
index f3134aeea..6cc387f62 100644
--- a/quisp/messages/entanglement_swapping_messages.msg
+++ b/quisp/messages/entanglement_swapping_messages.msg
@@ -76,3 +76,21 @@ packet SimultaneousSwappingResult extends Header{
int index_in_path;
int path_length_exclude_IR;
}
+
+packet GeneralizedSwappingResult extends Header{
+ unsigned long RuleSet_id;
+ unsigned long Rule_id;
+ int action_index;
+ bool is_for_root; //maybe soon to be obsolete
+
+ int measurement_result;
+ int number_of_corr;
+ int correction_type;
+ string label;
+
+ //Used only for internal communication
+ int size_of_arrays;
+ int responder_dests[];
+ int responder_number_of_corr[];
+ int measurement_results[];
+}
diff --git a/quisp/modules/Application/Application.cc b/quisp/modules/Application/Application.cc
index 669193047..b13a82874 100644
--- a/quisp/modules/Application/Application.cc
+++ b/quisp/modules/Application/Application.cc
@@ -23,6 +23,7 @@ Application::Application() : provider(utils::ComponentProvider{this}) {}
*/
void Application::initialize() {
// Since we only need this module in EndNode, delete it otherwise.
+
if (!gate("toRouter")->isConnected()) {
deleteThisModule *msg = new deleteThisModule("DeleteThisModule");
scheduleAt(simTime(), msg);
@@ -36,6 +37,7 @@ void Application::initialize() {
WATCH_VECTOR(other_end_node_addresses);
storeEndNodeAddresses();
+
if (!is_e2e_connection) {
return;
}
@@ -70,7 +72,30 @@ void Application::initialize() {
scheduleAt(simTime() + 0.00001 * my_address, pk);
return;
}
-
+ /*
+ Simple GHZ distribution setup, not logic to have number_of_clients sent by clients.
+ The Lone initiator should send a message to itself to define the number of clients,
+ clients should send a setup request with a bool (and not a int) specifying the connection
+ is multipartite. This is to ensure, QNIC are locked not in the setup phase but on the response phase.
+ */
+ if (traffic_pattern == 3) {
+ int initiator_adress = par("LoneInitiatorAddress");
+ int number_of_clients = par("NumberOfClients");
+ if (my_address != initiator_adress) {
+
+ EV_INFO << "My multipartite connection setup request will be sent from " << my_address << " to " << initiator_adress << "\n";
+ EV_INFO << number_of_clients;
+ ConnectionSetupRequest *pk = createMultiConnectionSetupRequest(initiator_adress, number_of_resources, number_of_clients);
+ // delay to avoid conflict
+ scheduleAt(simTime() + 0.00001 * my_address, pk);
+ } else {
+ EV_INFO << "Initiator setup" << "\n";
+ ConnectionSetupRequest *pk = createMultiConnectionSetupRequest(initiator_adress, number_of_resources, number_of_clients);
+ // delay to avoid conflict
+ scheduleAt(simTime() + 0.00001 * my_address, pk);
+ }
+ return;
+ }
error("Invalid TrafficPattern specified.");
}
@@ -86,9 +111,22 @@ ConnectionSetupRequest *Application::createConnectionSetupRequest(int dest_addr,
pk->setSrcAddr(my_address);
pk->setNum_measure(num_measure);
pk->setKind(7);
+ pk->setNumber_of_clients(1); //CM
return pk;
}
+//CM
+ConnectionSetupRequest *Application::createMultiConnectionSetupRequest(int dest_addr, int num_of_required_resources, int number_of_clients) {
+ ConnectionSetupRequest *pk = new ConnectionSetupRequest("ConnSetupRequest");
+ pk->setActual_srcAddr(my_address);
+ pk->setActual_destAddr(dest_addr);
+ pk->setDestAddr(my_address);
+ pk->setSrcAddr(my_address);
+ pk->setNum_measure(num_measure);
+ pk->setKind(7);
+ pk->setNumber_of_clients(number_of_clients); // CM
+ return pk;
+}
/**
* \brief Message handler
*
diff --git a/quisp/modules/Application/Application.h b/quisp/modules/Application/Application.h
index 3c2e539cf..1fc33beb9 100644
--- a/quisp/modules/Application/Application.h
+++ b/quisp/modules/Application/Application.h
@@ -45,6 +45,7 @@ class Application : public IApplication {
int getOneRandomEndNodeAddress();
messages::ConnectionSetupRequest *createConnectionSetupRequest(int dest_addr, int num_of_required_resources);
+ messages::ConnectionSetupRequest *createMultiConnectionSetupRequest(int dest_addr, int num_of_required_resources, int number_of_clients);
utils::ComponentProvider provider;
};
diff --git a/quisp/modules/Application/Application.ned b/quisp/modules/Application/Application.ned
index 7cf2796ed..cecea4c4c 100644
--- a/quisp/modules/Application/Application.ned
+++ b/quisp/modules/Application/Application.ned
@@ -14,6 +14,8 @@ simple Application
// int TrafficPattern = default(1);
int TrafficPattern;
int LoneInitiatorAddress;
+ int NumberOfResources = default(1);
+ int NumberOfClients;
int distant_measure_count = default(7000);
// Maybe don't have to set the default here.
diff --git a/quisp/modules/Common/Router.cc b/quisp/modules/Common/Router.cc
index 56d593854..ed78122b5 100644
--- a/quisp/modules/Common/Router.cc
+++ b/quisp/modules/Common/Router.cc
@@ -26,7 +26,7 @@ class Router : public cSimpleModule {
protected:
virtual void initialize(int stage) override;
- virtual void handleMessage(cMessage *msg) override;
+ virtual void handleMessage(cMessage* msg) override;
virtual int numInitStages() const override { return 1; };
};
@@ -37,13 +37,13 @@ void Router::initialize(int stage) {
myAddress = getParentModule()->par("address");
// Topology creation for routing table
- cTopology *topo = new cTopology("topo");
+ cTopology* topo = new cTopology("topo");
topo->extractByParameter("includeInTopo", "\"yes\""); // Any node that has a parameter includeInTopo will be included in routing
if (topo->getNumNodes() == 0 || topo == nullptr) { // If no node with the parameter & value found, do nothing.
return;
}
- cTopology::Node *thisNode = topo->getNodeFor(getParentModule()); // The parent node with this specific router
+ cTopology::Node* thisNode = topo->getNodeFor(getParentModule()); // The parent node with this specific router
int number_of_links_total = 0;
@@ -80,7 +80,7 @@ void Router::initialize(int stage) {
// Check the number of shortest paths towards the target node. This may be more than 1 if multiple paths have the same minimum cost.
if (thisNode->getNumPaths() == 0) continue; // not connected
- cGate *parentModuleGate = thisNode->getPath(0)->getLocalGate(); // Returns the next link/gate in the ith shortest paths towards the target node.
+ cGate* parentModuleGate = thisNode->getPath(0)->getLocalGate(); // Returns the next link/gate in the ith shortest paths towards the target node.
int gateIndex = parentModuleGate->getIndex();
int address = topo->getNode(i)->getModule()->par("address");
rtable[address] = gateIndex; // Store gate index per destination from this node
@@ -96,83 +96,87 @@ void Router::initialize(int stage) {
delete topo;
}
-void Router::handleMessage(cMessage *msg) {
+void Router::handleMessage(cMessage* msg) {
// check the header of the received package
- Header *pk = check_and_cast(msg);
+ Header* pk = check_and_cast(msg);
int destAddr = pk->getDestAddr(); // read destination from the packet
int who_are_you = pk->getKind(); // read the type of packet // This might be better fixed
+
if (destAddr == myAddress && who_are_you == 1) { // If destination is this node: Path selection
send(pk, "toApp"); // send to Application locally
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) { // Timing for BSM
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) { // Timing for BSM
bubble("Timing Notifier from HoM (stand-alone or internal) received");
send(pk, "rePort$o"); // send to Application locally
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) { // Timing for BSM
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) { // Timing for BSM
bubble("Timing Notifier from EPPS received");
send(pk, "rePort$o"); // send to Application locally
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("Connection setup request received");
send(pk, "cmPort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("Connection setup response received");
send(pk, "cmPort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("Reject connection setup response received");
send(pk, "cmPort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("Internal RuleSet Forwarding packet received");
send(pk, "rePort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("Internal RuleSet Forwarding Application packet received");
send(pk, "rePort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("Swapping Result packet received");
send(pk, "rePort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("Swapping Result packet received");
send(pk, "rePort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("Link tomography request received");
send(pk, "hmPort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("Link tomography ack received");
send(pk, "hmPort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("Link tomography rule set received");
send(pk, "rePort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("Link tomography result received");
send(pk, "hmPort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("Purification result received");
send(pk, "rePort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("DoublePurification result received");
send(pk, "rePort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("DS_DoublePurification result received");
send(pk, "rePort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
bubble("DS_DoublePurificationSecond result received");
send(pk, "rePort$o");
return;
- } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
+ send(pk, "rePort$o");
+ return;
+ } else if (destAddr == myAddress && dynamic_cast(msg) != nullptr) {
send(pk, "rePort$o");
return;
}
diff --git a/quisp/modules/PhysicalConnection/BSA/BellStateAnalyzer.cc b/quisp/modules/PhysicalConnection/BSA/BellStateAnalyzer.cc
index cff7f1084..2126dea7e 100644
--- a/quisp/modules/PhysicalConnection/BSA/BellStateAnalyzer.cc
+++ b/quisp/modules/PhysicalConnection/BSA/BellStateAnalyzer.cc
@@ -100,6 +100,8 @@ void BellStateAnalyzer::initialize() {
error_rate = par("error_rate");
// duration = par("duration");
required_precision = par("required_precision");
+ //CM Waiting for a better solution
+ //required_precision = 0.00001;
left_arrived_at = -1;
right_arrived_at = -1;
left_last_photon_detected = false;
@@ -348,8 +350,8 @@ void BellStateAnalyzer::forDEBUG_countErrorTypes(cMessage *msg) {
count_I++;
}
count_total++;
- EV << "Y%=" << (double)count_Y / (double)count_total << ", X%=" << (double)count_X / (double)count_total << ", Z%=" << (double)count_Z / (double)count_total
- << ", L%=" << (double)count_L / (double)count_total << ", I% =" << (double)count_I / (double)count_total << "\n";
+ //EV << "Y%=" << (double)count_Y / (double)count_total << ", X%=" << (double)count_X / (double)count_total << ", Z%=" << (double)count_Z / (double)count_total
+ // << ", L%=" << (double)count_L / (double)count_total << ", I% =" << (double)count_I / (double)count_total << "\n";
}
bool BellStateAnalyzer::isPhotonLost(cMessage *msg) {
diff --git a/quisp/modules/PhysicalConnection/BSA/BellStateAnalyzer.ned b/quisp/modules/PhysicalConnection/BSA/BellStateAnalyzer.ned
index b4b394591..c51b8e82e 100644
--- a/quisp/modules/PhysicalConnection/BSA/BellStateAnalyzer.ned
+++ b/quisp/modules/PhysicalConnection/BSA/BellStateAnalyzer.ned
@@ -7,7 +7,8 @@ simple BellStateAnalyzer
double loss_rate = default(0);
double error_rate = default(0);
double duration = default(0);
- double required_precision = default(1.5e-9);
+ // double required_precision = default(1.5e-9); CM
+ double required_precision = default(1.5e-5);
int photon_detection_per_sec = default(10000);
int address;
@signal[Num_Bell_state](type=long);
diff --git a/quisp/modules/QNIC/StationaryQubit/IQubit.h b/quisp/modules/QNIC/StationaryQubit/IQubit.h
new file mode 100644
index 000000000..e69de29bb
diff --git a/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h b/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h
index 5b9c5d2eb..2fd655a08 100644
--- a/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h
+++ b/quisp/modules/QNIC/StationaryQubit/IStationaryQubit.h
@@ -6,16 +6,16 @@ namespace quisp {
namespace types {
enum class MeasureXResult : int {
- NO_ERROR,
- HAS_Z_ERROR,
+ NO_X_ERROR,
+ HAS_X_ERROR,
};
enum class MeasureYResult : int {
- NO_ERROR,
+ NO_Y_ERROR,
HAS_XZ_ERROR,
};
enum class MeasureZResult : int {
- NO_ERROR,
- HAS_X_ERROR,
+ NO_Z_ERROR,
+ HAS_Z_ERROR,
};
} // namespace types
@@ -169,6 +169,9 @@ class IStationaryQubit : public cSimpleModule {
int qnic_address;
int qnic_type;
int qnic_index;
+ //CM
+ bool is_in_multipartite = false;
+ std::string label = "";
int action_index;
bool no_density_matrix_nullptr_entangled_partner_ok;
diff --git a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc
index f14fa9c67..1c29aaf7b 100644
--- a/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc
+++ b/quisp/modules/QNIC/StationaryQubit/StationaryQubit.cc
@@ -219,9 +219,9 @@ void StationaryQubit::setTwoQubitGateErrorCeilings(TwoQubitGateErrorModel &model
MeasureXResult StationaryQubit::measure_X() {
applySingleQubitGateError(Measurement_error);
if (par("GOD_Zerror").boolValue()) {
- return MeasureXResult::HAS_Z_ERROR;
+ return MeasureXResult::HAS_X_ERROR;
}
- return MeasureXResult::NO_ERROR;
+ return MeasureXResult::NO_X_ERROR;
}
MeasureYResult StationaryQubit::measure_Y() {
@@ -236,15 +236,16 @@ MeasureYResult StationaryQubit::measure_Y() {
if (error) {
return MeasureYResult::HAS_XZ_ERROR;
}
- return MeasureYResult::NO_ERROR;
+ return MeasureYResult::NO_Y_ERROR;
+ return MeasureYResult::NO_Y_ERROR;
}
MeasureZResult StationaryQubit::measure_Z() {
applySingleQubitGateError(Measurement_error);
if (par("GOD_Xerror")) {
- return MeasureZResult::HAS_X_ERROR;
+ return MeasureZResult::HAS_Z_ERROR;
}
- return MeasureZResult::NO_ERROR;
+ return MeasureZResult::NO_Z_ERROR;
}
// Convert X to Z, and Z to X error. Therefore, Y error stays as Y.
@@ -539,7 +540,7 @@ bool StationaryQubit::Xpurify(IStationaryQubit *resource_qubit /*Controlled*/) {
applyMemoryError();
check_and_cast(resource_qubit)->applyMemoryError();
/*Target qubit*/ this->CNOT_gate(resource_qubit /*controlled qubit*/);
- bool meas = this->measure_Z() == MeasureZResult::NO_ERROR;
+ bool meas = this->measure_Z() == MeasureZResult::NO_Z_ERROR;
return meas;
}
@@ -549,7 +550,7 @@ bool StationaryQubit::Zpurify(IStationaryQubit *resource_qubit /*Target*/) {
check_and_cast(resource_qubit)->applyMemoryError();
/*Target qubit*/ resource_qubit->CNOT_gate(this /*controlled qubit*/);
this->Hadamard_gate();
- bool meas = this->measure_Z() == MeasureZResult::NO_ERROR;
+ bool meas = this->measure_Z() == MeasureZResult::NO_Z_ERROR;
return meas;
}
diff --git a/quisp/modules/QNode.ned b/quisp/modules/QNode.ned
index 5698b3d8a..64a106ce6 100644
--- a/quisp/modules/QNode.ned
+++ b/quisp/modules/QNode.ned
@@ -33,6 +33,12 @@ module QNode
submodules:
app: Application {
parameters:
+ //CM Begin
+ TrafficPattern = 3;
+ LoneInitiatorAddress = 10000;
+ NumberOfClients = 4;
+
+ //CM End
address = address;//share the same address within all inner modules
@display("p=30,43");
}
diff --git a/quisp/modules/QRSA/ConnectionManager/ConnectionManager.cc b/quisp/modules/QRSA/ConnectionManager/ConnectionManager.cc
index f1b2ead77..0b99c0435 100644
--- a/quisp/modules/QRSA/ConnectionManager/ConnectionManager.cc
+++ b/quisp/modules/QRSA/ConnectionManager/ConnectionManager.cc
@@ -30,7 +30,6 @@ void ConnectionManager::initialize() {
simultaneous_es_enabled = par("simultaneous_es_enabled");
es_with_purify = par("entanglement_swapping_with_purification");
num_remote_purification = par("num_remote_purification");
-
if (simultaneous_es_enabled && es_with_purify) {
error("Currently, simultaneous entanglement swapping cannot be simulated with purification");
}
@@ -86,16 +85,23 @@ void ConnectionManager::handleMessage(cMessage *msg) {
int initiator_addr = resp->getActual_destAddr();
int responder_addr = resp->getActual_srcAddr();
- if (initiator_addr == my_address || responder_addr == my_address) {
- // this node is not a swapper
- storeRuleSetForApplication(resp);
+ if (resp->getIsMultipartite() == false)
+ {
+ if (initiator_addr == my_address || responder_addr == my_address) {
+ // this node is not a swapper
+ storeRuleSetForApplication(resp);
+ } else {
+ // this node is a swapper (intermediate node)
+ // currently, destinations are separated. (Not accumulated.)
+ storeRuleSet(resp);
+ }
+ delete msg;
+ return;
} else {
- // this node is a swapper (intermediate node)
- // currently, destinations are separated. (Not accumulated.)
- storeRuleSet(resp);
+ storeRuleSetForApplication(resp);
+ //QNIC reservation ?
}
- delete msg;
- return;
+
}
if (dynamic_cast(msg) != nullptr) {
@@ -217,6 +223,13 @@ void ConnectionManager::respondToRequest(ConnectionSetupRequest *req) {
int actual_dst = req->getActual_destAddr();
int actual_src = req->getActual_srcAddr(); // initiator address (to get input qnic)
+ // CM BEGIN
+ // Should be check multipartite bool
+ if (req->getNumber_of_clients() != 1) {
+ handleMultipartiteRequest(req, actual_dst, actual_src);
+ return;
+ }
+ // CM END
// This must be -1
int local_qnic_address_to_actual_dst = routing_daemon->return_QNIC_address_to_destAddr(actual_dst);
if (local_qnic_address_to_actual_dst != -1) {
@@ -557,6 +570,189 @@ QNIC_id ConnectionManager::getQnicInterface(int owner_address, int partner_addre
return qnic_interface;
}
+
+// CM To refactor
+void ConnectionManager::handleMultipartiteRequest(ConnectionSetupRequest *req, int actual_dst, int actual_src) {
+ static int number_of_received_connection = 0;
+ static int number_of_incoming_connections = 0;
+ int current_node;
+ int path_size_without_end;
+ QNIC_pair_info current_qnic_info;
+
+ if (actual_src == my_address) {
+ number_of_incoming_connections = req->getNumber_of_clients();
+ return;
+ }
+
+ int local_qnic_address_to_actual_dst = routing_daemon->return_QNIC_address_to_destAddr(actual_dst);
+ if (local_qnic_address_to_actual_dst != -1) {
+ error("something error happen!");
+ }
+
+ // TODO: premise only one connection allowed btw, two nodes.
+ int local_qnic_address_to_actual_src = routing_daemon->return_QNIC_address_to_destAddr(actual_src);
+ if (local_qnic_address_to_actual_src == -1) {
+ error("This shouldn't happen!");
+ }
+
+ auto dst_info = std::make_unique(NULL_CONNECTION_SETUP_INFO);
+ auto src_info = hardware_monitor->findConnectionInfoByQnicAddr(local_qnic_address_to_actual_src);
+ if (src_info == nullptr) {
+ error("src_info not found");
+ }
+ QNIC_pair_info pair_info = {.fst = src_info->qnic, .snd = dst_info->qnic};
+
+ bool is_src_qnic_reserved = isQnicBusy(src_info->qnic.address);
+ bool is_dst_qnic_reserved = isQnicBusy(dst_info->qnic.address);
+
+ // the number of steps
+ int hop_count = req->getStack_of_QNodeIndexesArraySize();
+
+ // path from source to destination
+ std::vector path;
+ for (int i = 0; i < hop_count; i++)
+ {
+ path.push_back(req->getStack_of_QNodeIndexes(i));
+ }
+ path.push_back(my_address);
+ path_size_without_end = path.size() - 2;
+
+ int qnic_array_size = req->getStack_of_QNICsArraySize();
+ req->setStack_of_QNICsArraySize(qnic_array_size + 1);
+ req->setStack_of_QNICs(qnic_array_size, pair_info);
+
+ std::vector qnics = {};
+ for (int i = qnic_array_size - 1; i >= 0; i--) {
+ qnics.push_back(req->getStack_of_QNICs(i));
+ }
+
+ if (number_of_received_connection == 0)
+ {
+ tree_path_test.clear();
+ }
+
+
+ while (path.size() > 1)
+ {
+ current_node = path.back();
+ current_qnic_info = qnics.back();
+ path.pop_back();
+ qnics.pop_back();
+ if (tree_path_test.find(current_node) == tree_path_test.end())
+ {
+ PathLink new_path_link = {
+ path.back(),
+ current_qnic_info,
+ actual_src
+ };
+ EV_INFO << "actual src: " << actual_src << "\n";
+ std::vector child = {new_path_link};
+ tree_path_test.insert(std::make_pair(current_node, child));
+ }
+ else
+ {
+ bool is_in_child = false;
+ std::vector *current_childs = &tree_path_test.at(current_node);
+ for (auto it = current_childs->begin(); it != current_childs->end(); ++it)
+ {
+ if (it->children == path.back())
+ {
+ is_in_child = true;
+ break;
+ }
+ }
+ if (is_in_child == false)
+ {
+ PathLink new_path_link = {
+ path.back(),
+ current_qnic_info,
+ actual_src
+ };
+ current_childs->push_back(new_path_link);
+ }
+ }
+ }
+ current_node = path.back();
+ correction_number_for_node.insert(std::make_pair(current_node, path_size_without_end));
+ std::vector child = {};
+ tree_path_test.insert(std::make_pair(current_node, child));
+
+ number_of_received_connection += 1;
+ if (number_of_received_connection == number_of_incoming_connections)
+ {
+ number_of_received_connection = 0;
+ int size_of_tree = 0;
+ for (auto it = tree_path_test.begin(); it != tree_path_test.end(); ++it) {
+ PathLink father = getFather(it->first);
+ if (!(father.children == -1 || it->second.size() == 0)) {
+ size_of_tree++;
+ }
+ }
+ EV_INFO << "Size of the Leafless tree " << size_of_tree << "\n";
+ for (auto it = tree_path_test.begin(); it != tree_path_test.end(); ++it) {
+ auto *pkr = new ConnectionSetupResponse("ConnSetupResponse(GHZDistrib)");
+
+ RuleSet *rule = generateGeneralizedEntanglementSwappingRuleSet(it->first, it->second, size_of_tree);
+ if (rule != nullptr)
+ {
+ pkr->setRuleSet(rule);
+ pkr->setDestAddr(it->first);
+ pkr->setSrcAddr(my_address);
+ pkr->setKind(2);
+ pkr->setIsMultipartite(true);
+ pkr->setActual_srcAddr(path.at(0));
+ pkr->setActual_destAddr(my_address);
+ pkr->setApplication_type(0);
+ send(pkr, "RouterPort$o");
+ }
+
+ }
+ if (actual_dst != my_address) {
+ reserveQnic(src_info->qnic.address);
+ reserveQnic(dst_info->qnic.address);
+ } else {
+ reserveQnic(src_info->qnic.address);
+ }
+ number_of_state_initiated++;
+ }
+
+}
+
+
+//To refactor in one method
+PathLink ConnectionManager::getFather(int node) {
+ for (auto it = tree_path_test.begin(); it != tree_path_test.end(); ++it) {
+ auto childs = it->second;
+
+ for (auto path_link_it = childs.begin(); path_link_it != childs.end(); ++path_link_it) {
+ if (path_link_it->children == node) {
+ //EV_INFO << "Found father link with " << path_link_it->children << " and QNIC address " << path_link_it->QNIC_pair.fst.address << " and "
+ //<< path_link_it->QNIC_pair.snd.address
+ //<< "\n";
+ return (*path_link_it);
+ }
+ }
+ }
+ //EV_INFO << "Did not found father address\n";
+ PathLink default_path_link;
+ default_path_link.children = -1;
+ return (default_path_link);
+}
+
+int ConnectionManager::getFatherAdress(int node) {
+ for (auto it = tree_path_test.begin(); it != tree_path_test.end(); ++it) {
+ auto childs = it->second;
+
+ for (auto path_link_it = childs.begin(); path_link_it != childs.end(); ++path_link_it) {
+ if (path_link_it->children == node) {
+ //EV_INFO << "Found father address " << it->first << "\n";
+ return (it->first);
+ }
+ }
+ }
+ return (-1);
+}
+
/**
* This function is for selecting the order of entanglement swapping
* \param swapper_address node address; could be any intermediate in the path (not an end point)
@@ -776,9 +972,11 @@ void ConnectionManager::tryRelayRequestToNextHop(ConnectionSetupRequest *req) {
QNIC_pair_info pair_info = {.fst = inbound_info->qnic, .snd = outbound_info->qnic};
req->setStack_of_QNICs(num_accumulated_pair_info, pair_info);
- reserveQnic(inbound_info->qnic.address);
- reserveQnic(outbound_info->qnic.address);
-
+ // CM For now we do not lock QNIC at all in multipartite, should lock them in the response phase
+ if (req->getNumber_of_clients() == 1) {
+ reserveQnic(inbound_info->qnic.address);
+ reserveQnic(outbound_info->qnic.address);
+ }
send(req, "RouterPort$o");
}
@@ -938,31 +1136,104 @@ std::unique_ptr ConnectionManager::swappingRule(SwappingConfig conf, unsig
return rule_entanglement_swapping;
}
-std::unique_ptr ConnectionManager::simultaneousSwappingRule(SwappingConfig conf, std::vector path, unsigned long ruleset_id, unsigned long rule_id) {
- // From @poramet implementations
- std::vector partners = {conf.left_partner, conf.right_partner};
- std::string rule_name = "Simultaneous Entanglement Swapping with " + std::to_string(conf.left_partner) + " : " + std::to_string(conf.right_partner);
- int index_in_path = conf.index;
- int path_length_exclude_IR = path.size() - 2;
- auto rule_simultaneous_entanglement_swapping = std::make_unique(ruleset_id, rule_id, rule_name, partners);
+//CM
+RuleSet *ConnectionManager::generateGeneralizedEntanglementSwappingRuleSet(int node, std::vector children_link, int size_of_tree) {
+ unsigned long ruleset_id = createUniqueId();
+ int rule_index = 0;
+ PathLink father = getFather(node);
+ int father_address = getFatherAdress(node);
+ std::string label = "GHZ_" + std::to_string(my_address) + "_" + std::to_string(number_of_state_initiated);
+ std::vector clauses;
+ std::vector config_partners;
+ std::vector config_associated_end_nodes;
+ std::vector config_types;
+ std::vector config_ids;
+ std::vector config_addresses;
+ std::vector config_self_ids;
+ std::vector config_self_types;
+ std::vector config_resource;
Condition *condition = new Condition();
- Clause *resource_clause_left = new EnoughResourceClause(conf.left_partner, 1);
- Clause *resource_clause_right = new EnoughResourceClause(conf.right_partner, 1);
- condition->addClause(resource_clause_left);
- condition->addClause(resource_clause_right);
-
- quisp::rules::Action *action = new SimultaneousSwappingAction(
- ruleset_id, rule_id, conf.left_partner, conf.lqnic_type, conf.lqnic_index, conf.lqnic_address, conf.lres, conf.right_partner, conf.rqnic_type, conf.rqnic_index,
- conf.rqnic_address, conf.rres, conf.self_left_qnic_index, conf.self_left_qnic_type, conf.self_right_qnic_index, conf.self_right_qnic_type, conf.initiator,
- conf.initiator_qnic_type, conf.initiator_qnic_index, conf.initiator_qnic_address, conf.initiator_res, conf.responder, conf.responder_qnic_type, conf.responder_qnic_index,
- conf.responder_qnic_address, conf.responder_res, index_in_path, path_length_exclude_IR);
- rule_simultaneous_entanglement_swapping->setCondition(condition);
- rule_simultaneous_entanglement_swapping->setAction(action);
- return rule_simultaneous_entanglement_swapping;
+ if (father.children == -1 || children_link.size() == 0) {
+ return (nullptr);
+ }
+ else {
+ EV_INFO << "Label we put in ruleset " << label << "\n";
+ for (auto link_it = children_link.begin(); link_it != children_link.end(); ++link_it) {
+ config_resource.push_back(1);
+ Clause *resource_clause = new EnoughResourceClause(link_it->children, config_resource.back());
+ condition->addClause(resource_clause);
+ QNIC_id children_qnic = link_it->QNIC_pair.snd;
+ config_partners.push_back(link_it->children);
+ config_associated_end_nodes.push_back(link_it->end_node);
+ config_types.push_back(children_qnic.type);
+ config_ids.push_back(children_qnic.index);
+ config_addresses.push_back(children_qnic.address);
+
+ QNIC_id self_qnic = link_it->QNIC_pair.fst;
+ config_self_ids.push_back(self_qnic.index);
+ config_self_types.push_back(self_qnic.type);
+ }
+ Clause *resource_clause = new EnoughResourceClause(father_address, config_resource.back());
+ condition->addClause(resource_clause);
+ QNIC_id father_qnic = father.QNIC_pair.fst;
+ config_partners.push_back(father_address);
+ config_associated_end_nodes.push_back(my_address);
+ config_types.push_back(father_qnic.type);
+ // config_ids.push_back(father_qnic.index); It is curiously -1
+ config_ids.push_back(0);
+ config_addresses.push_back(father_qnic.address);
+
+ QNIC_id self_qnic = father.QNIC_pair.snd;
+ config_self_ids.push_back(self_qnic.index);
+ config_self_types.push_back(self_qnic.type);
+
+ config_resource.push_back(1);
+ rules::Action *action = new rules::actions::GeneralizedSwappingAction(ruleset_id, rule_index, config_partners, config_associated_end_nodes, config_types, config_ids,
+ config_addresses, config_resource, config_self_ids, config_self_types, label, size_of_tree, correction_number_for_node);
+ auto rule = std::make_unique(ruleset_id, rule_index, "generalized entanglement swapping", config_partners);
+ rule->setCondition(condition);
+ rule->setAction(action);
+
+ RuleSet *ruleset = new RuleSet(ruleset_id, node, config_partners);
+ ruleset->addRule(std::move(rule));
+
+ return ruleset;
+ }
}
+ // RuleSet *ConnectionManager::generateSimultaneousEntanglementSwappingRuleSet(int owner, SwappingConfig conf, std::vector path) {
+ // unsigned long ruleset_id = createUniqueId();
+ // int rule_index = 0;
+
+ std::unique_ptr ConnectionManager::simultaneousSwappingRule(SwappingConfig conf, std::vector path, unsigned long ruleset_id, unsigned long rule_id) {
+ // From @poramet implementations
+ std::vector partners = {conf.left_partner, conf.right_partner};
+ std::string rule_name = "Simultaneous Entanglement Swapping with " + std::to_string(conf.left_partner) + " : " + std::to_string(conf.right_partner);
+
+ int index_in_path = conf.index;
+ int path_length_exclude_IR = path.size() - 2;
+
+ auto rule_simultaneous_entanglement_swapping = std::make_unique(ruleset_id, rule_id, rule_name, partners);
+ Condition *condition = new Condition();
+ Clause *resource_clause_left = new EnoughResourceClause(conf.left_partner, 1);
+ Clause *resource_clause_right = new EnoughResourceClause(conf.right_partner, 1);
+ condition->addClause(resource_clause_left);
+ condition->addClause(resource_clause_right);
+
+ quisp::rules::Action *action = new SimultaneousSwappingAction(
+ ruleset_id, rule_id, conf.left_partner, conf.lqnic_type, conf.lqnic_index, conf.lqnic_address, conf.lres, conf.right_partner, conf.rqnic_type, conf.rqnic_index,
+ conf.rqnic_address, conf.rres, conf.self_left_qnic_index, conf.self_left_qnic_type, conf.self_right_qnic_index, conf.self_right_qnic_type, conf.initiator,
+ conf.initiator_qnic_type, conf.initiator_qnic_index, conf.initiator_qnic_address, conf.initiator_res, conf.responder, conf.responder_qnic_type, conf.responder_qnic_index,
+ conf.responder_qnic_address, conf.responder_res, index_in_path, path_length_exclude_IR);
+
+ rule_simultaneous_entanglement_swapping->setCondition(condition);
+ rule_simultaneous_entanglement_swapping->setAction(action);
+ return (rule_simultaneous_entanglement_swapping);
+ }
+
+
std::unique_ptr ConnectionManager::waitRule(int partner_address, int next_parter_address, unsigned long ruleset_id, unsigned long rule_id) {
// This is used for waiting swapping result from partner
std::vector partners = {partner_address};
diff --git a/quisp/modules/QRSA/ConnectionManager/ConnectionManager.h b/quisp/modules/QRSA/ConnectionManager/ConnectionManager.h
index cf3cc3f4c..991c59b72 100644
--- a/quisp/modules/QRSA/ConnectionManager/ConnectionManager.h
+++ b/quisp/modules/QRSA/ConnectionManager/ConnectionManager.h
@@ -8,6 +8,7 @@
#ifndef MODULES_CONNECTIONMANAGER_H_
#define MODULES_CONNECTIONMANAGER_H_
+#include
#include "IConnectionManager.h"
using namespace omnetpp;
@@ -17,6 +18,13 @@ using namespace quisp::rules;
namespace quisp {
namespace modules {
+
+ typedef struct {
+ int children;
+ QNIC_pair_info QNIC_pair;
+ int end_node;
+ } PathLink; //CM
+
/** \class ConnectionManager ConnectionManager.cc
*
* \brief ConnectionManager
@@ -50,11 +58,17 @@ class ConnectionManager : public IConnectionManager {
int num_of_qnics;
std::map> connection_setup_buffer; // key is qnic address
std::map connection_retry_count; // key is qnic address
+
+ std::map> tree_path_test; // CM: Taking both into a struct after
+ std::map> tree_path;
+ std::map correction_number_for_node;
+
std::map qnic_res_table;
std::vector request_send_timing; // self message, notification for sending out request
bool simultaneous_es_enabled;
bool es_with_purify;
int num_remote_purification;
+ int number_of_state_initiated = 0; // To label created states
IRoutingDaemon *routing_daemon;
IHardwareMonitor *hardware_monitor;
@@ -69,7 +83,8 @@ class ConnectionManager : public IConnectionManager {
void initiateApplicationRequest(int qnic_address);
void scheduleRequestRetry(int qnic_address);
void popApplicationRequest(int qnic_address);
-
+ void handleMultipartiteRequest(ConnectionSetupRequest *req, int actual_dst, int actual_src); //CM
+ void relayRequestToNextHop(ConnectionSetupRequest *pk);
void storeRuleSetForApplication(ConnectionSetupResponse *pk);
void storeRuleSet(ConnectionSetupResponse *pk);
@@ -100,8 +115,11 @@ class ConnectionManager : public IConnectionManager {
unsigned long createUniqueId();
static int computePathDivisionSize(int l);
static int fillPathDivision(std::vector path, int i, int l, int *link_left, int *link_right, int *swapper, int fill_start);
-};
+ PathLink getFather(int node); // CM
+ int getFatherAdress(int node);
+ RuleSet *generateGeneralizedEntanglementSwappingRuleSet(int node, std::vector children_link, int size_tree); // CM
+};
} // namespace modules
} // namespace quisp
#endif /* MODULES_CONNECTIONMANAGER_H_ */
diff --git a/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.ned b/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.ned
index 00495f41d..3857c802f 100644
--- a/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.ned
+++ b/quisp/modules/QRSA/HardwareMonitor/HardwareMonitor.ned
@@ -9,16 +9,16 @@ simple HardwareMonitor
int number_of_qnics_rp;
string ntable = "";
// XYZ --rdv defaults removed so that users will be asked; 200402
- // bool link_tomography = default(false);
- // int initial_purification = default(0);
- // int Purification_type = default(-1);
- bool link_tomography;
+ bool link_tomography = default(false);
+ int initial_purification = default(0);
+ int Purification_type = default(-1);
+ // bool link_tomography;
int num_measure = default(3000);
string tomography_output_filename = default("default");
string file_dir_name = default("results/");
// purification control
- int initial_purification;
- int Purification_type;
+ //int initial_purification;
+ //int Purification_type;
// these two are obsolete controls for purification
bool X_purification = default(false);
bool Z_purification = default(false);
@@ -26,4 +26,4 @@ simple HardwareMonitor
inout RuleEnginePort;
inout RouterPort;
-}
\ No newline at end of file
+}
diff --git a/quisp/modules/QRSA/RuleEngine/RuleEngine.cc b/quisp/modules/QRSA/RuleEngine/RuleEngine.cc
index c19596662..03e1f03d2 100644
--- a/quisp/modules/QRSA/RuleEngine/RuleEngine.cc
+++ b/quisp/modules/QRSA/RuleEngine/RuleEngine.cc
@@ -56,6 +56,8 @@ void RuleEngine::initialize() {
tracker_accessible.push_back(true);
}
+ generalized_results.clear(); // CM
+
// running_processes = new RuleSetPtr[QNIC_N];//One process per QNIC for now. No multiplexing.
// WATCH(assigned);
}
@@ -97,6 +99,7 @@ void RuleEngine::handleMessage(cMessage *msg) {
}
else if (dynamic_cast(msg) != nullptr) {
+ EV_INFO << "Received combined\n";
// First, keep all the qubits that were successfully entangled, and reinitialize the failed ones.
CombinedBSAresults *pk_result = check_and_cast(msg);
BSMtimingNotifier *pk = check_and_cast(msg);
@@ -164,7 +167,8 @@ void RuleEngine::handleMessage(cMessage *msg) {
EV_DEBUG << "This BSA request is internal\n";
scheduleFirstPhotonEmission(pk, QNIC_R);
}
- } else if (dynamic_cast(msg) != nullptr) {
+ }
+ else if (dynamic_cast(msg) != nullptr) {
bubble("EPPS");
error("EPPS is not implemented yet");
}
@@ -186,7 +190,8 @@ void RuleEngine::handleMessage(cMessage *msg) {
} else {
error("Empty rule set...");
}
- } else if (dynamic_cast(msg) != nullptr) {
+ }
+ else if (dynamic_cast(msg) != nullptr) {
PurificationResult *pkt = check_and_cast(msg);
process_id purification_id;
purification_result pr;
@@ -196,7 +201,8 @@ void RuleEngine::handleMessage(cMessage *msg) {
pr.id = purification_id;
pr.outcome = pkt->getOutput_is_plus();
storeCheck_Purification_Agreement(pr);
- } else if (dynamic_cast(msg) != nullptr) {
+ }
+ else if (dynamic_cast(msg) != nullptr) {
DoublePurificationResult *pkt = check_and_cast(msg);
process_id purification_id;
Doublepurification_result pr;
@@ -207,7 +213,8 @@ void RuleEngine::handleMessage(cMessage *msg) {
pr.Xpurification_outcome = pkt->getXOutput_is_plus();
pr.Zpurification_outcome = pkt->getZOutput_is_plus();
storeCheck_DoublePurification_Agreement(pr);
- } else if (dynamic_cast(msg) != nullptr) {
+ }
+ else if (dynamic_cast(msg) != nullptr) {
// std::cout<<"!!!!Purification result reveid!!! node["<(msg);
// std::cout<<"Presult from node["<getSrcAddr()<<"]\n";
@@ -225,7 +232,8 @@ void RuleEngine::handleMessage(cMessage *msg) {
// std::cout<<"Purification result is from node["<getSrcAddr()<<"] rid="<< pkt->getRuleset_id()<<"Must be qnic["<getEntangled_with()<<"in node["<node_address<<"] \n";
storeCheck_QuatroPurification_Agreement(pr);
- } else if (dynamic_cast(msg) != nullptr) {
+ }
+ else if (dynamic_cast(msg) != nullptr) {
// std::cout<<"!!!!Purification result reveid!!! node["<(msg);
process_id purification_id;
@@ -238,13 +246,13 @@ void RuleEngine::handleMessage(cMessage *msg) {
pr.Zpurification_outcome = pkt->getZOutput_is_plus();
pr.DS_purification_outcome = pkt->getDS_Output_is_plus();
storeCheck_TriplePurification_Agreement(pr);
- } else if (dynamic_cast(msg) != nullptr) {
+ }
+ else if (dynamic_cast(msg) != nullptr) {
SwappingResult *pkt = check_and_cast(msg);
process_id swapping_id;
swapping_id.ruleset_id = pkt->getRuleSet_id(); // just in case
swapping_id.rule_id = pkt->getRule_id();
swapping_id.index = pkt->getAction_index();
-
swapping_result swapr; // result of entanglement swapping
swapr.id = swapping_id;
swapr.new_partner = pkt->getNew_partner();
@@ -287,6 +295,11 @@ void RuleEngine::handleMessage(cMessage *msg) {
updateResources_SimultaneousEntanglementSwapping(swapr);
}
}
+ else if (dynamic_cast(msg) != nullptr) {
+ correction_GeneralizedEntanglementSwapping(check_and_cast(msg));
+ return;
+ }
+
else if (dynamic_cast(msg) != nullptr) {
InternalRuleSetForwarding *pkt = check_and_cast(msg);
@@ -305,7 +318,8 @@ void RuleEngine::handleMessage(cMessage *msg) {
} else {
error("Empty rule set...");
}
- } else if (dynamic_cast(msg) != nullptr) {
+ }
+ else if (dynamic_cast(msg) != nullptr) {
InternalRuleSetForwarding_Application *pkt = check_and_cast(msg);
// doing end to end tomography
if (pkt->getApplication_type() == 0) {
@@ -325,7 +339,8 @@ void RuleEngine::handleMessage(cMessage *msg) {
} else {
error("This application is not recognized yet");
}
- } else if (dynamic_cast(msg) != nullptr) {
+ }
+ else if (dynamic_cast(msg) != nullptr) {
StopEmitting *pkt = check_and_cast(msg);
terminated_qnic[pkt->getQnic_address()] = true;
}
@@ -972,13 +987,16 @@ void RuleEngine::updateResources_EntanglementSwapping(swapping_result swapr) {
error("RuleEngine. Entanglement swapping went wrong");
}
// FOR DEBUGGING
- if (qubit->entangled_partner != nullptr) {
- if (qubit->entangled_partner->entangled_partner == nullptr) {
- error("1. Entanglement tracking is not doing its job. in update resource E.S.");
- }
- if (qubit->entangled_partner->entangled_partner != qubit) {
- error("2. Entanglement tracking is not doing its job. in update resource E.S.");
- }
+ if (qubit->label == "") {
+ if (qubit->entangled_partner != nullptr) {
+ if (qubit->entangled_partner->entangled_partner == nullptr) {
+ error("1. Entanglement tracking is not doing its job. in update resource E.S.");
+ }
+ if (qubit->entangled_partner->entangled_partner != qubit) {
+ error("2. Entanglement tracking is not doing its job. in update resource E.S.");
+ }
+ }
+
}
bool promoted = false;
@@ -1009,7 +1027,7 @@ void RuleEngine::updateResources_EntanglementSwapping(swapping_result swapr) {
}
} else if ((*rule)->rule_index == next_rule_id) {
// next rule id is properly updated
- (*rule)->addResource(new_partner, qubit);
+ (*rule)->addResource(new_partner, qubit);its
promoted = true;
return;
}
@@ -1037,17 +1055,21 @@ void RuleEngine::updateResources_SimultaneousEntanglementSwapping(swapping_resul
if (operation_type == 0) {
// nothing
- } else if (operation_type == 1) {
+ }
+ else if (operation_type == 1) {
// do Z
qubit->Z_gate();
- } else if (operation_type == 2) {
+ }
+ else if (operation_type == 2) {
// do X
qubit->Z_gate();
- } else if (operation_type == 3) {
+ }
+ else if (operation_type == 3) {
// do XZ
qubit->Z_gate();
qubit->X_gate();
- } else {
+ }
+ else {
error("something error happened! This operation type doesn't recorded!");
}
@@ -1066,18 +1088,65 @@ void RuleEngine::updateResources_SimultaneousEntanglementSwapping(swapping_resul
error("qubit is locked");
}
bell_pair_store.insertEntangledQubit(new_partner, qubit);
- if (qubit->entangled_partner != nullptr) {
- if (qubit->entangled_partner->entangled_partner == nullptr) {
- error("1. Entanglement tracking is not doing its job. in update resource E.S.");
- }
- if (qubit->entangled_partner->entangled_partner != qubit) {
- error("2. Entanglement tracking is not doing its job. in update resource E.S.");
+ if (qubit->label == "") {
+ if (qubit->entangled_partner != nullptr) {
+ if (qubit->entangled_partner->entangled_partner == nullptr) {
+ error("1. Entanglement tracking is not doing its job. in update resource E.S.");
+ }
+ if (qubit->entangled_partner->entangled_partner != qubit) {
+ error("2. Entanglement tracking is not doing its job. in update resource E.S.");
+ }
}
}
+
ResourceAllocation(qnic_type, qnic_index);
traverseThroughAllProcesses2(); // New resource added to QNIC with qnic_type qnic_index.
}
+//CM Quick and dirty
+void RuleEngine::correction_GeneralizedEntanglementSwapping(GeneralizedSwappingResult *pkt) {
+ std::string label = pkt->getLabel();
+ int correction = pkt->getCorrection_type();
+
+ EV_INFO << "Received correction with label " << label << " and correction " << correction;
+
+ if (pkt->getIs_for_root()) {
+ EV_INFO << "Z\n";
+ } else {
+ EV_INFO << "X\n";
+ }
+
+
+ if (generalized_results.find(label) == generalized_results.end()) {
+ generalized_results.insert(std::make_pair(label, correction));
+ }
+ else {
+ generalized_results.at(label) = generalized_results.at(label) ^ correction;
+ }
+ received_correction += 1;
+ if (received_correction == pkt->getNumber_of_corr()) {
+ EV_INFO << "Received Enough correction lezzugo\n";
+ auto info = hardware_monitor->findConnectionInfoByQnicAddr(0);
+ int qnic_index = info->qnic.index;
+ QNIC_type qnic_type = info->qnic.type;
+
+ for (int i = 0; i < 10; i++) {
+ StationaryQubit *qubit = provider.getStationaryQubit(0, i, qnic_type);
+ if (qubit->label == label && generalized_results.at(label) > 0) {
+ if (pkt->getIs_for_root()) {
+ EV_INFO << "ZGATE\n";
+ qubit->Z_gate();
+ } else {
+ EV_INFO << "XGATE\n";
+ qubit->X_gate();
+ }
+ }
+ received_correction = 0;
+ }
+ }
+
+}
+
// Only for MIM and MM
void RuleEngine::freeFailedQubits_and_AddAsResource(int destAddr, int internal_qnic_address, int internal_qnic_index, CombinedBSAresults *pk_result) {
// get the size of failed bsa
@@ -1098,7 +1167,6 @@ void RuleEngine::freeFailedQubits_and_AddAsResource(int destAddr, int internal_q
qnic_type = QNIC_R;
neighborQNodeAddress = getInterface_toNeighbor_Internal(qnic_address).neighborQNode_address;
}
-
// How many photons are bursted?
int num_emitted_in_this_burstTrial = tracker[qnic_address].size();
// start iteration from 0 .. number of failed bsm
@@ -1120,23 +1188,27 @@ void RuleEngine::freeFailedQubits_and_AddAsResource(int destAddr, int internal_q
StationaryQubit *qubit = provider.getStationaryQubit(qnic_index, it->second.qubit_index, qnic_type);
// if the partner is null, not correct
- if (qubit->entangled_partner != nullptr) {
- if (qubit->entangled_partner->entangled_partner == nullptr) {
- // my instance is null (no way)
- error("1. Entanglement tracking is not doing its job.");
- }
- if (qubit->entangled_partner->entangled_partner != qubit) {
- // partner's qubit doesn't point this qubit -> wrong
- error("2. Entanglement tracking is not doing its job.");
+ if (qubit->label == "") {
+ if (qubit->entangled_partner != nullptr) {
+ if (qubit->entangled_partner->entangled_partner == nullptr) {
+ // my instance is null (no way)
+ error("1. Entanglement tracking is not doing its job.");
+ }
+ if (qubit->entangled_partner->entangled_partner != qubit) {
+ // partner's qubit doesn't point this qubit -> wrong
+ error("2. Entanglement tracking is not doing its job.");
+ }
}
}
+
if (qubit->entangled_partner == nullptr && qubit->Density_Matrix_Collapsed(0, 0).real() == -111 && !qubit->no_density_matrix_nullptr_entangled_partner_ok) {
EV << "entangle partner null?" << qubit->entangled_partner << " == nullptr?\n";
EV << "density matrix collapsed?" << qubit->Density_Matrix_Collapsed(0, 0).real() << "==-111?\n";
EV << "here should be true" << qubit->no_density_matrix_nullptr_entangled_partner_ok << "\n";
error("RuleEngine. Ebit succeed. but wrong");
}
+ EV_INFO << "C'est ajouté avec " << neighborQNodeAddress << "\n";
// Add qubit as available resource between NeighborQNodeAddress.
bell_pair_store.insertEntangledQubit(neighborQNodeAddress, qubit);
}
@@ -1226,7 +1298,6 @@ void RuleEngine::ResourceAllocation(int qnic_type, int qnic_index) {
void RuleEngine::traverseThroughAllProcesses2() {
int number_of_process = rp.size(); // Number of running processes (in all QNICs).
-
if (number_of_process == 0) {
return;
}
@@ -1238,12 +1309,10 @@ void RuleEngine::traverseThroughAllProcesses2() {
for (auto rule = process->cbegin(), end = process->cend(); rule != end; rule++) {
bool process_done = false;
bool terminate_this_rule = false;
-
while (true) {
if (!((*rule)->resources.size() > 0)) {
break; // No more resource left for now.
}
-
cPacket *pk = (*rule)->checkrun(this); // Do something on qubits entangled with resource_entangled_with_address.
if (pk != nullptr) {
@@ -1259,35 +1328,40 @@ void RuleEngine::traverseThroughAllProcesses2() {
}
send(pk, "RouterPort$o");
send(pk_for_self, "RouterPort$o");
- } else if (dynamic_cast(pk) != nullptr) {
+ }
+ else if (dynamic_cast(pk) != nullptr) {
PurificationResult *pkt = check_and_cast(pk);
pkt->setSrcAddr(parentAddress);
PurificationResult *pk_for_self = pkt->dup();
pk_for_self->setDestAddr(parentAddress);
send(pkt, "RouterPort$o");
send(pk_for_self, "RouterPort$o");
- } else if (dynamic_cast(pk) != nullptr) {
+ }
+ else if (dynamic_cast(pk) != nullptr) {
DoublePurificationResult *pkt = check_and_cast(pk);
pkt->setSrcAddr(parentAddress);
DoublePurificationResult *pk_for_self = pkt->dup();
pk_for_self->setDestAddr(parentAddress);
send(pkt, "RouterPort$o");
send(pk_for_self, "RouterPort$o");
- } else if (dynamic_cast(pk) != nullptr) {
+ }
+ else if (dynamic_cast(pk) != nullptr) {
DS_DoublePurificationResult *pkt = check_and_cast(pk);
pkt->setSrcAddr(parentAddress);
DS_DoublePurificationResult *pk_for_self = pkt->dup();
pk_for_self->setDestAddr(parentAddress);
send(pkt, "RouterPort$o");
send(pk_for_self, "RouterPort$o");
- } else if (dynamic_cast(pk) != nullptr) {
+ }
+ else if (dynamic_cast(pk) != nullptr) {
DS_DoublePurificationSecondResult *pkt = check_and_cast(pk);
pkt->setSrcAddr(parentAddress);
DS_DoublePurificationSecondResult *pk_for_self = pkt->dup();
pk_for_self->setDestAddr(parentAddress);
send(pkt, "RouterPort$o");
send(pk_for_self, "RouterPort$o");
- } else if (dynamic_cast(pk) != nullptr) {
+ }
+ else if (dynamic_cast(pk) != nullptr) {
SwappingResult *pkt = check_and_cast(pk);
EV << "done swapping at " << parentAddress << " left: " << pkt->getLeft_Dest() << " right: " << pkt->getRight_Dest() << "\n";
// here this packet goes to two destination.
@@ -1324,7 +1398,8 @@ void RuleEngine::traverseThroughAllProcesses2() {
send(pkt_for_left, "RouterPort$o");
send(pkt_for_right, "RouterPort$o");
- } else if (dynamic_cast(pk) != nullptr) {
+ }
+ else if (dynamic_cast(pk) != nullptr) {
SimultaneousSwappingResult *pkt = check_and_cast(pk);
EV << "done swapping at " << parentAddress << "\n";
@@ -1355,12 +1430,33 @@ void RuleEngine::traverseThroughAllProcesses2() {
send(pkt_for_initiator, "RouterPort$o");
send(pkt_for_responder, "RouterPort$o");
}
+ else if (dynamic_cast(pk) != nullptr) {
+ GeneralizedSwappingResult *result_packet = check_and_cast(pk);
+
+ for (int i = 0; i < result_packet->getSize_of_arrays(); i++) {
+ std::string tmp = std::to_string(result_packet->getResponder_dests(i));
+ char const *address = tmp.c_str();
+ GeneralizedSwappingResult *packet_to_send = new GeneralizedSwappingResult(address);
+ packet_to_send->setDestAddr(result_packet->getResponder_dests(i));
+ packet_to_send->setSrcAddr(parentAddress);
+ if (i < result_packet->getSize_of_arrays() - 1) {
+ packet_to_send->setIs_for_root(false);
+ }else {
+ packet_to_send->setIs_for_root(true);
+ }
+ packet_to_send->setNumber_of_corr(result_packet->getResponder_number_of_corr(i));
+ packet_to_send->setLabel(result_packet->getLabel());
+ packet_to_send->setMeasurement_result(result_packet->getMeasurement_results(i));
+ send(packet_to_send, "RouterPort$o");
+ }
+ }
else if (dynamic_cast(pk) != nullptr) {
Error *err = check_and_cast(pk);
error(err->getError_text());
delete pk;
- } else if (dynamic_cast(pk) != nullptr) {
+ }
+ else if (dynamic_cast(pk) != nullptr) {
// Condition does not meet. Go to next rule. e.g. Fidelity is good enough by doing purification. Next could be swap.
delete pk;
break;
@@ -1375,6 +1471,7 @@ void RuleEngine::traverseThroughAllProcesses2() {
// std::cout<<"Is it done?";
process_done = (*rule)->checkTerminate(); // The entire process is done. e.g. enough measurement for tomography.
if (process_done) { // Delete rule set if done
+ EV_INFO << "FINI !";
// std::cout<<"!!!!!!!!!!!!!!!!!!!!! TERMINATING!!!!!!!!!!!!!!!!!!!!!!!!!";
std::cout << "RuleSet_id=" << process->ruleset_id << "\n";
// todo:Also need to deallocate resources!!!!!!!!!!!!not implemented yet.
diff --git a/quisp/modules/QRSA/RuleEngine/RuleEngine.h b/quisp/modules/QRSA/RuleEngine/RuleEngine.h
index f53cd4352..62911d1be 100644
--- a/quisp/modules/QRSA/RuleEngine/RuleEngine.h
+++ b/quisp/modules/QRSA/RuleEngine/RuleEngine.h
@@ -10,6 +10,7 @@
#include
#include
#include
+#include