|
|
@ -1,6 +1,7 @@
|
|
|
|
#include "MatchBoxPC.h"
|
|
|
|
#include "MatchBoxPC.h"
|
|
|
|
#include <omp.h>
|
|
|
|
#include <omp.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
|
|
// ***********************************************************************
|
|
|
|
// ***********************************************************************
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// MatchboxP: A C++ library for approximate weighted matching
|
|
|
|
// MatchboxP: A C++ library for approximate weighted matching
|
|
|
@ -602,8 +603,6 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
|
|
|
|
|
|
|
|
|
|
|
|
} //End of if(w >=0)
|
|
|
|
} //End of if(w >=0)
|
|
|
|
|
|
|
|
|
|
|
|
//This piece of code is executed a really small amount of times, I will not allocate a
|
|
|
|
|
|
|
|
//huge amount of memory to the private data structures.
|
|
|
|
|
|
|
|
adj11 = verLocPtr[v];
|
|
|
|
adj11 = verLocPtr[v];
|
|
|
|
adj12 = verLocPtr[v + 1];
|
|
|
|
adj12 = verLocPtr[v + 1];
|
|
|
|
for (k1 = adj11; k1 < adj12; k1++) {
|
|
|
|
for (k1 = adj11; k1 < adj12; k1++) {
|
|
|
@ -622,16 +621,28 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
|
|
|
|
assert(ghostOwner != -1);
|
|
|
|
assert(ghostOwner != -1);
|
|
|
|
assert(ghostOwner != myRank);
|
|
|
|
assert(ghostOwner != myRank);
|
|
|
|
PCounter[ghostOwner]++;
|
|
|
|
PCounter[ghostOwner]++;
|
|
|
|
QLocalVtx.push_back(v + StartIndex);
|
|
|
|
privateQLocalVtx.push_back(v + StartIndex);
|
|
|
|
QGhostVtx.push_back(w);
|
|
|
|
privateQGhostVtx.push_back(w);
|
|
|
|
QMsgType.push_back(FAILURE);
|
|
|
|
privateQMsgType.push_back(FAILURE);
|
|
|
|
QOwner.push_back(ghostOwner);
|
|
|
|
privateQOwner.push_back(ghostOwner);
|
|
|
|
|
|
|
|
|
|
|
|
} //End of if(GHOST)
|
|
|
|
} //End of if(GHOST)
|
|
|
|
} //End of for loop
|
|
|
|
} //End of for loop
|
|
|
|
//End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
|
|
|
|
//End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
|
|
|
|
} //End of for ( v=0; v < NLVer; v++ )
|
|
|
|
} //End of for ( v=0; v < NLVer; v++ )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma omp critical(privateMsg)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
while (!privateQLocalVtx.empty()) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QLocalVtx.push_back(privateQLocalVtx.pop_back());
|
|
|
|
|
|
|
|
QGhostVtx.push_back(privateQGhostVtx.pop_back());
|
|
|
|
|
|
|
|
QMsgType.push_back(privateQMsgType.pop_back());
|
|
|
|
|
|
|
|
QOwner.push_back(privateQOwner.pop_back());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#pragma omp critical(U)
|
|
|
|
#pragma omp critical(U)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
while (!privateU.empty())
|
|
|
|
while (!privateU.empty())
|
|
|
@ -658,8 +669,7 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
|
|
|
|
MilanLongInt localVertices = 0;
|
|
|
|
MilanLongInt localVertices = 0;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
while( true )
|
|
|
|
while (true) {
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma omp critical(U)
|
|
|
|
#pragma omp critical(U)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -671,7 +681,7 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
|
|
|
|
#ifdef PRINT_DEBUG_INFO_
|
|
|
|
#ifdef PRINT_DEBUG_INFO_
|
|
|
|
cout<<"\n("<<myRank<<")u: "<<u; fflush(stdout);
|
|
|
|
cout<<"\n("<<myRank<<")u: "<<u; fflush(stdout);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
if ( (u >= StartIndex) && (u <= EndIndex) ) { //Process Only the Local Vertices
|
|
|
|
if ((u >= StartIndex) && (u <= EndIndex)) { //Process Only the Local Vertices
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef COUNT_LOCAL_VERTEX
|
|
|
|
#ifdef COUNT_LOCAL_VERTEX
|
|
|
|
localVertices ++;
|
|
|
|
localVertices ++;
|
|
|
@ -683,10 +693,13 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
|
|
|
|
for (k = adj1; k < adj2; k++) {
|
|
|
|
for (k = adj1; k < adj2; k++) {
|
|
|
|
v = verLocInd[k];
|
|
|
|
v = verLocInd[k];
|
|
|
|
|
|
|
|
|
|
|
|
if ((v >= StartIndex) && (v <= EndIndex)) { //If Local Vertex:
|
|
|
|
|
|
|
|
#pragma omp critical
|
|
|
|
#pragma omp critical
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((v >= StartIndex) && (v <= EndIndex)) { //If Local Vertex:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef PRINT_DEBUG_INFO_
|
|
|
|
#ifdef PRINT_DEBUG_INFO_
|
|
|
|
cout<<"\n("<<myRank<<")v: "<<v<<" c(v)= "<<candidateMate[v-StartIndex]<<" Mate[v]: "<<Mate[v];
|
|
|
|
cout<<"\n("<<myRank<<")v: "<<v<<" c(v)= "<<candidateMate[v-StartIndex]<<" Mate[v]: "<<Mate[v];
|
|
|
|
fflush(stdout);
|
|
|
|
fflush(stdout);
|
|
|
@ -694,9 +707,10 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
|
|
|
|
|
|
|
|
|
|
|
|
//If the current vertex is pointing to a matched vertex and is not matched
|
|
|
|
//If the current vertex is pointing to a matched vertex and is not matched
|
|
|
|
//FIXME is there a way to make candidateMate private?
|
|
|
|
//FIXME is there a way to make candidateMate private?
|
|
|
|
// for the moment it could generate an error.
|
|
|
|
// for the moment it could generate errors.
|
|
|
|
if (not isAlreadyMatched(v, StartIndex, EndIndex, GMate, Mate, Ghost2LocalMap) and
|
|
|
|
if (not isAlreadyMatched(v, StartIndex, EndIndex, GMate, Mate, Ghost2LocalMap) and
|
|
|
|
candidateMate[v - StartIndex] == u) {
|
|
|
|
candidateMate[v - StartIndex] == u) {
|
|
|
|
|
|
|
|
|
|
|
|
//Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
|
|
|
|
//Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
|
|
|
|
//Start: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v)
|
|
|
|
//Start: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v)
|
|
|
|
w = computeCandidateMate(verLocPtr[v - StartIndex],
|
|
|
|
w = computeCandidateMate(verLocPtr[v - StartIndex],
|
|
|
@ -716,23 +730,28 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
|
|
|
|
cout<<"\n("<<myRank<<")"<<v<<" Points to: "<<w; fflush(stdout);
|
|
|
|
cout<<"\n("<<myRank<<")"<<v<<" Points to: "<<w; fflush(stdout);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
//If found a dominating edge:
|
|
|
|
//If found a dominating edge:
|
|
|
|
|
|
|
|
|
|
|
|
if (w >= 0) {
|
|
|
|
if (w >= 0) {
|
|
|
|
|
|
|
|
|
|
|
|
if ((w < StartIndex) || (w > EndIndex)) { //A ghost
|
|
|
|
if ((w < StartIndex) || (w > EndIndex)) { //A ghost
|
|
|
|
#ifdef PRINT_DEBUG_INFO_
|
|
|
|
#ifdef PRINT_DEBUG_INFO_
|
|
|
|
cout<<"\n("<<myRank<<")Sending a request message:";
|
|
|
|
cout<<"\n("<<myRank<<")Sending a request message:";
|
|
|
|
cout<<"\n("<<myRank<<")Ghost is "<<w<<" Owner is: "<<findOwnerOfGhost(w, verDistance, myRank, numProcs);
|
|
|
|
cout<<"\n("<<myRank<<")Ghost is "<<w<<" Owner is: "<<findOwnerOfGhost(w, verDistance, myRank, numProcs);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
QLocalVtx.push_back(v);
|
|
|
|
|
|
|
|
QGhostVtx.push_back(w);
|
|
|
|
|
|
|
|
QMsgType.push_back(REQUEST);
|
|
|
|
|
|
|
|
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
|
|
|
|
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
|
|
|
|
assert(ghostOwner != -1);
|
|
|
|
assert(ghostOwner != -1);
|
|
|
|
assert(ghostOwner != myRank);
|
|
|
|
assert(ghostOwner != myRank);
|
|
|
|
QOwner.push_back(ghostOwner);
|
|
|
|
QOwner.push_back(ghostOwner);
|
|
|
|
|
|
|
|
QLocalVtx.push_back(v);
|
|
|
|
|
|
|
|
QGhostVtx.push_back(w);
|
|
|
|
|
|
|
|
QMsgType.push_back(REQUEST);
|
|
|
|
PCounter[ghostOwner]++;
|
|
|
|
PCounter[ghostOwner]++;
|
|
|
|
NumMessagesBundled++;
|
|
|
|
NumMessagesBundled++;
|
|
|
|
msgInd++;
|
|
|
|
msgInd++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (candidateMate[NLVer + Ghost2LocalMap[w]] == v) {
|
|
|
|
if (candidateMate[NLVer + Ghost2LocalMap[w]] == v) {
|
|
|
|
Mate[v - StartIndex] = w; //v is a local vertex
|
|
|
|
Mate[v - StartIndex] = w; //v is a local vertex
|
|
|
|
GMate[Ghost2LocalMap[w]] = v; //w is a ghost vertex
|
|
|
|
GMate[Ghost2LocalMap[w]] = v; //w is a ghost vertex
|
|
|
@ -755,14 +774,16 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} //End of if Counter[w] > 0
|
|
|
|
} //End of if Counter[w] > 0
|
|
|
|
|
|
|
|
|
|
|
|
//End: PARALLEL_PROCESS_CROSS_EDGE_B(v,w)
|
|
|
|
//End: PARALLEL_PROCESS_CROSS_EDGE_B(v,w)
|
|
|
|
} //End of if CandidateMate[w] = v
|
|
|
|
} //End of if CandidateMate[w] = v
|
|
|
|
|
|
|
|
|
|
|
|
} //End of if a Ghost Vertex
|
|
|
|
} //End of if a Ghost Vertex
|
|
|
|
else { //w is a local vertex
|
|
|
|
else { //w is a local vertex
|
|
|
|
|
|
|
|
|
|
|
|
if (candidateMate[w - StartIndex] == v) {
|
|
|
|
if (candidateMate[w - StartIndex] == v) {
|
|
|
|
Mate[v - StartIndex] = w; //v is a local vertex
|
|
|
|
Mate[v - StartIndex] = w; //v is a local vertex
|
|
|
|
Mate[w - StartIndex] = v; //w is a local vertex
|
|
|
|
Mate[w - StartIndex] = v; //w is a local vertex
|
|
|
|
//Q.push_back(u);
|
|
|
|
|
|
|
|
privateU.push_back(v);
|
|
|
|
privateU.push_back(v);
|
|
|
|
privateU.push_back(w);
|
|
|
|
privateU.push_back(w);
|
|
|
|
privateMyCard++;
|
|
|
|
privateMyCard++;
|
|
|
@ -770,34 +791,30 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
|
|
|
|
cout<<"\n("<<myRank<<")MATCH: ("<<v<<","<<w<<") "; fflush(stdout);
|
|
|
|
cout<<"\n("<<myRank<<")MATCH: ("<<v<<","<<w<<") "; fflush(stdout);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
} //End of if(CandidateMate(w) = v
|
|
|
|
} //End of if(CandidateMate(w) = v
|
|
|
|
|
|
|
|
|
|
|
|
} //End of Else
|
|
|
|
} //End of Else
|
|
|
|
|
|
|
|
|
|
|
|
} //End of if(w >=0)
|
|
|
|
} //End of if(w >=0)
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
|
|
adj11 = verLocPtr[v - StartIndex];
|
|
|
|
adj11 = verLocPtr[v - StartIndex];
|
|
|
|
adj12 = verLocPtr[v - StartIndex + 1];
|
|
|
|
adj12 = verLocPtr[v - StartIndex + 1];
|
|
|
|
for (k1 = adj11; k1 < adj12; k1++) {
|
|
|
|
for (k1 = adj11; k1 < adj12; k1++) {
|
|
|
|
w = verLocInd[k1];
|
|
|
|
w = verLocInd[k1];
|
|
|
|
if ((w < StartIndex) || (w > EndIndex)) { //A ghost
|
|
|
|
if ((w < StartIndex) || (w > EndIndex)) { //A ghost
|
|
|
|
//Build the Message Packet:
|
|
|
|
|
|
|
|
//Message[0] = v; //LOCAL
|
|
|
|
|
|
|
|
//Message[1] = w; //GHOST
|
|
|
|
|
|
|
|
//Message[2] = FAILURE; //TYPE
|
|
|
|
|
|
|
|
//Send a Request (Asynchronous)
|
|
|
|
|
|
|
|
#ifdef PRINT_DEBUG_INFO_
|
|
|
|
#ifdef PRINT_DEBUG_INFO_
|
|
|
|
cout<<"\n("<<myRank<<")Sending a failure message: ";
|
|
|
|
cout<<"\n("<<myRank<<")Sending a failure message: ";
|
|
|
|
cout<<"\n("<<myRank<<")Ghost is "<<w<<" Owner is: "<<findOwnerOfGhost(w, verDistance, myRank, numProcs);
|
|
|
|
cout<<"\n("<<myRank<<")Ghost is "<<w<<" Owner is: "<<findOwnerOfGhost(w, verDistance, myRank, numProcs);
|
|
|
|
fflush(stdout);
|
|
|
|
fflush(stdout);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/* MPI_Bsend(&Message[0], 3, MPI_INT, inputSubGraph.findOwner(w),
|
|
|
|
|
|
|
|
ComputeTag, comm); */
|
|
|
|
|
|
|
|
QLocalVtx.push_back(v);
|
|
|
|
|
|
|
|
QGhostVtx.push_back(w);
|
|
|
|
|
|
|
|
QMsgType.push_back(FAILURE);
|
|
|
|
|
|
|
|
//ghostOwner = inputSubGraph.findOwner(w);
|
|
|
|
|
|
|
|
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
|
|
|
|
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
|
|
|
|
|
|
|
|
privateQLocalVtx.push_back(v);
|
|
|
|
|
|
|
|
privateQGhostVtx.push_back(w);
|
|
|
|
|
|
|
|
privateQMsgType.push_back(FAILURE);
|
|
|
|
|
|
|
|
privateQOwner.push_back(ghostOwner);
|
|
|
|
assert(ghostOwner != -1);
|
|
|
|
assert(ghostOwner != -1);
|
|
|
|
assert(ghostOwner != myRank);
|
|
|
|
assert(ghostOwner != myRank);
|
|
|
|
QOwner.push_back(ghostOwner);
|
|
|
|
|
|
|
|
PCounter[ghostOwner]++;
|
|
|
|
PCounter[ghostOwner]++;
|
|
|
|
NumMessagesBundled++;
|
|
|
|
NumMessagesBundled++;
|
|
|
|
msgInd++;
|
|
|
|
msgInd++;
|
|
|
@ -805,55 +822,52 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
|
|
|
|
} //End of for loop
|
|
|
|
} //End of for loop
|
|
|
|
} // End of Else: w == -1
|
|
|
|
} // End of Else: w == -1
|
|
|
|
//End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
|
|
|
|
//End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//} //End of critical region if
|
|
|
|
|
|
|
|
|
|
|
|
} //End of If (candidateMate[v-StartIndex] == u)
|
|
|
|
} //End of If (candidateMate[v-StartIndex] == u)
|
|
|
|
|
|
|
|
|
|
|
|
} //End of critical region if
|
|
|
|
//}//End of critical region
|
|
|
|
|
|
|
|
|
|
|
|
} //End of if ( (v >= StartIndex) && (v <= EndIndex) ) //If Local Vertex:
|
|
|
|
} //End of if ( (v >= StartIndex) && (v <= EndIndex) ) //If Local Vertex:
|
|
|
|
else { //Neighbor is a ghost vertex
|
|
|
|
else { //Neighbor is a ghost vertex
|
|
|
|
|
|
|
|
|
|
|
|
#pragma omp critical
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (candidateMate[NLVer + Ghost2LocalMap[v]] == u)
|
|
|
|
if (candidateMate[NLVer + Ghost2LocalMap[v]] == u)
|
|
|
|
candidateMate[NLVer + Ghost2LocalMap[v]] = -1;
|
|
|
|
candidateMate[NLVer + Ghost2LocalMap[v]] = -1;
|
|
|
|
|
|
|
|
|
|
|
|
if (v != Mate[u - StartIndex]) { //u is local
|
|
|
|
if (v != Mate[u - StartIndex]) { //u is local
|
|
|
|
//Build the Message Packet:
|
|
|
|
|
|
|
|
//Message[0] = u; //LOCAL
|
|
|
|
|
|
|
|
//Message[1] = v; //GHOST
|
|
|
|
|
|
|
|
//Message[2] = SUCCESS; //TYPE
|
|
|
|
|
|
|
|
//Send a Request (Asynchronous)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef PRINT_DEBUG_INFO_
|
|
|
|
#ifdef PRINT_DEBUG_INFO_
|
|
|
|
cout<<"\n("<<myRank<<")Sending a success message: ";
|
|
|
|
cout<<"\n("<<myRank<<")Sending a success message: ";
|
|
|
|
cout<<"\n("<<myRank<<")Ghost is "<<v<<" Owner is: "<<findOwnerOfGhost(v, verDistance, myRank, numProcs)<<"\n"; fflush(stdout);
|
|
|
|
cout<<"\n("<<myRank<<")Ghost is "<<v<<" Owner is: "<<findOwnerOfGhost(v, verDistance, myRank, numProcs)<<"\n"; fflush(stdout);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ghostOwner = findOwnerOfGhost(v, verDistance, myRank, numProcs);
|
|
|
|
QLocalVtx.push_back(u);
|
|
|
|
QLocalVtx.push_back(u);
|
|
|
|
QGhostVtx.push_back(v);
|
|
|
|
QGhostVtx.push_back(v);
|
|
|
|
QMsgType.push_back(SUCCESS);
|
|
|
|
QMsgType.push_back(SUCCESS);
|
|
|
|
ghostOwner = findOwnerOfGhost(v, verDistance, myRank, numProcs);
|
|
|
|
QOwner.push_back(ghostOwner);
|
|
|
|
assert(ghostOwner != -1);
|
|
|
|
assert(ghostOwner != -1);
|
|
|
|
assert(ghostOwner != myRank);
|
|
|
|
assert(ghostOwner != myRank);
|
|
|
|
QOwner.push_back(ghostOwner);
|
|
|
|
|
|
|
|
PCounter[ghostOwner]++;
|
|
|
|
PCounter[ghostOwner]++;
|
|
|
|
NumMessagesBundled++;
|
|
|
|
NumMessagesBundled++;
|
|
|
|
msgInd++;
|
|
|
|
msgInd++;
|
|
|
|
} //End of If( v != Mate[u] )
|
|
|
|
} //End of If( v != Mate[u] )
|
|
|
|
} //End of critical region
|
|
|
|
|
|
|
|
} //End of Else //A Ghost Vertex
|
|
|
|
} //End of Else //A Ghost Vertex
|
|
|
|
|
|
|
|
}// end of critical section
|
|
|
|
} //End of For Loop adj(u)
|
|
|
|
} //End of For Loop adj(u)
|
|
|
|
} //End of if ( (u >= StartIndex) && (u <= EndIndex) ) //Process Only If a Local Vertex
|
|
|
|
} //End of if ( (u >= StartIndex) && (u <= EndIndex) ) //Process Only If a Local Vertex
|
|
|
|
|
|
|
|
|
|
|
|
#pragma omp critical(U)
|
|
|
|
#pragma omp critical(U)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
while(!privateU.empty()) {
|
|
|
|
while (!privateU.empty()) {
|
|
|
|
U.push_back(privateU.pop_front());
|
|
|
|
U.push_back(privateU.pop_front());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
myCard += privateMyCard;
|
|
|
|
myCard += privateMyCard;
|
|
|
|
} //End of critical U
|
|
|
|
} //End of critical U
|
|
|
|
|
|
|
|
|
|
|
|
} //End of while ( /*!Q.empty()*/ !U.empty() )
|
|
|
|
} //End of while
|
|
|
|
|
|
|
|
|
|
|
|
#pragma omp critical(privateMsg)
|
|
|
|
#pragma omp critical(privateMsg)
|
|
|
|
{
|
|
|
|
{
|
|
|
|