processMatchedVertices partially working mixed critical and lock version

omp-walther
StefanoPetrilli 3 years ago
parent 561cadee0f
commit a9bb6b26fa

@ -66,7 +66,7 @@
using namespace std; using namespace std;
#define NUM_THREAD 4 #define NUM_THREAD 4
#define UCHUNK 100000 #define UCHUNK 1000
const MilanLongInt REQUEST = 1; const MilanLongInt REQUEST = 1;
const MilanLongInt SUCCESS = 2; const MilanLongInt SUCCESS = 2;
@ -323,7 +323,8 @@ extern "C"
staticQueue &privateQLocalVtx, staticQueue &privateQLocalVtx,
staticQueue &privateQGhostVtx, staticQueue &privateQGhostVtx,
staticQueue &privateQMsgType, staticQueue &privateQMsgType,
staticQueue &privateQOwner); staticQueue &privateQOwner,
omp_lock_t *MateLock);
void sendBundledMessages(MilanLongInt *numGhostEdgesPtr, void sendBundledMessages(MilanLongInt *numGhostEdgesPtr,
MilanInt *BufferSizePtr, MilanInt *BufferSizePtr,

@ -281,6 +281,7 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
vector<MilanLongInt> UChunkBeingProcessed; vector<MilanLongInt> UChunkBeingProcessed;
UChunkBeingProcessed.reserve(UCHUNK); UChunkBeingProcessed.reserve(UCHUNK);
//#define PRINT_DEBUG_INFO_
processMatchedVertices(NLVer, processMatchedVertices(NLVer,
UChunkBeingProcessed, UChunkBeingProcessed,
U, U,
@ -310,7 +311,8 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
privateQLocalVtx, privateQLocalVtx,
privateQGhostVtx, privateQGhostVtx,
privateQMsgType, privateQMsgType,
privateQOwner); privateQOwner,
MateLock);
///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////// SEND BUNDLED MESSAGES ///////////////////////////////////// ///////////////////////////// SEND BUNDLED MESSAGES /////////////////////////////////////

@ -32,30 +32,24 @@ void processMatchedVertices(
staticQueue &privateQLocalVtx, staticQueue &privateQLocalVtx,
staticQueue &privateQGhostVtx, staticQueue &privateQGhostVtx,
staticQueue &privateQMsgType, staticQueue &privateQMsgType,
staticQueue &privateQOwner) staticQueue &privateQOwner,
omp_lock_t *MateLock)
{ {
MilanLongInt adj1, adj2, adj11, adj12, k, k1, v = -1, w = -1, ghostOwner; MilanLongInt adj1, adj2, adj11, adj12, k, k1, v = -1, w = -1, ghostOwner;
MilanLongInt myCard = *myCardPtr, msgInd = *msgIndPtr, NumMessagesBundled = *NumMessagesBundledPtr, S = *SPtr, privateMyCard = 0; MilanLongInt myCard = *myCardPtr, msgInd = *msgIndPtr, NumMessagesBundled = *NumMessagesBundledPtr, S = *SPtr, privateMyCard = 0;
// TODO check that the queues arrives empty
assert(privateQGhostVtx.empty());
assert(privateQLocalVtx.empty());
assert(privateQMsgType.empty());
assert(privateQOwner.empty());
#pragma omp parallel private(k, w, v, k1, adj1, adj2, adj11, adj12, ghostOwner) firstprivate(privateMyCard, privateU, StartIndex, EndIndex, privateQLocalVtx, privateQGhostVtx, privateQMsgType, privateQOwner) default(shared) num_threads(NUM_THREAD)
{
#ifdef PRINT_DEBUG_INFO_ #ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << "=========================************===============================" << endl; cout << "\n(" << myRank << "=========================************===============================" << endl;
fflush(stdout); fflush(stdout);
fflush(stdout); fflush(stdout);
#endif #endif
#ifdef COUNT_LOCAL_VERTEX #ifdef COUNT_LOCAL_VERTEX
MilanLongInt localVertices = 0; MilanLongInt localVertices = 0;
#endif #endif
#pragma omp parallel private(k, w, v, k1, adj1, adj2, adj11, adj12, ghostOwner) firstprivate(privateMyCard, privateU, StartIndex, EndIndex, privateQLocalVtx, privateQGhostVtx, privateQMsgType, privateQOwner) default(shared) num_threads(NUM_THREAD)
{
// TODO what would be the optimal UCHUNK // TODO what would be the optimal UCHUNK
// TODO refactor // TODO refactor
@ -89,23 +83,29 @@ void processMatchedVertices(
if ((v >= StartIndex) && (v <= EndIndex)) if ((v >= StartIndex) && (v <= EndIndex))
{ // If Local Vertex: { // If Local Vertex:
#pragma omp critical(innerProcessMatched)
{
#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);
#endif #endif
// 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 an error.
if (not isAlreadyMatched(v, StartIndex, EndIndex, GMate, Mate, Ghost2LocalMap) and if (not isAlreadyMatched(v, StartIndex, EndIndex, GMate, Mate, Ghost2LocalMap))
candidateMate[v - StartIndex] == u) {
bool seh = false;
#pragma omp critical(prova)
{ {
seh = candidateMate[v - StartIndex] != u;
}
if (seh)
continue;
#pragma omp critical(prova)
{
// Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v) // Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
// Start: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v)
w = computeCandidateMate(verLocPtr[v - StartIndex], w = computeCandidateMate(verLocPtr[v - StartIndex],
verLocPtr[v - StartIndex + 1], verLocPtr[v - StartIndex + 1],
edgeLocWeight, 0, edgeLocWeight, 0,
@ -117,48 +117,44 @@ void processMatchedVertices(
Ghost2LocalMap); Ghost2LocalMap);
candidateMate[v - StartIndex] = w; candidateMate[v - StartIndex] = w;
}
// End: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v)
#ifdef PRINT_DEBUG_INFO_ #ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")" << v << " Points to: " << w; cout << "\n(" << myRank << ")" << v << " Points to: " << w;
fflush(stdout); fflush(stdout);
#endif #endif
// If found a dominating edge: // If found a dominating edge:
if (w >= 0) if (w >= 0)
{ {
// TODO is it possible to lock without a critical region?
// TODO there must be a more elegant and efficient way to do this
/*
while(true) {
if (omp_test_lock(&MateLock[v - StartIndex])) {
if (omp_test_lock(&MateLock[w - StartIndex])) break;
else omp_unset_lock(&MateLock[v - StartIndex]);
}
}
*/
if ((w < StartIndex) || (w > EndIndex)) if ((w < StartIndex) || (w > EndIndex))
{ // A ghost { // 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
msgInd++; ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
NumMessagesBundled++; assert(ghostOwner != -1);
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs); assert(ghostOwner != myRank);
assert(ghostOwner != -1); #pragma omp atomic
assert(ghostOwner != myRank); PCounter[ghostOwner]++;
PCounter[ghostOwner]++; #pragma omp atomic
msgInd++;
#pragma omp atomic
NumMessagesBundled++;
privateQLocalVtx.push_back(v); privateQLocalVtx.push_back(v);
privateQGhostVtx.push_back(w); privateQGhostVtx.push_back(w);
privateQMsgType.push_back(REQUEST); privateQMsgType.push_back(REQUEST);
privateQOwner.push_back(ghostOwner); privateQOwner.push_back(ghostOwner);
#pragma omp critical(prova)
{
if (candidateMate[NLVer + Ghost2LocalMap[w]] == v) if (candidateMate[NLVer + Ghost2LocalMap[w]] == v)
{ {
while (!omp_test_lock(&MateLock[v - StartIndex]))
;
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
// Q.push_back(u); // Q.push_back(u);
@ -170,16 +166,23 @@ void processMatchedVertices(
fflush(stdout); fflush(stdout);
#endif #endif
// TODO refactor this
// Decrement the counter: // Decrement the counter:
PROCESS_CROSS_EDGE(Counter, Ghost2LocalMap[w], &S); PROCESS_CROSS_EDGE(Counter, Ghost2LocalMap[w], &S);
omp_unset_lock(&MateLock[v - StartIndex]);
} // End of if CandidateMate[w] = v } // End of if CandidateMate[w] = v
} // End of if a Ghost Vertex }
else } // End of if a Ghost Vertex
{ // w is a local vertex else
{ // w is a local vertex
#pragma omp critical(prova)
{
if (candidateMate[w - StartIndex] == v) if (candidateMate[w - StartIndex] == v)
{ {
while (!omp_test_lock(&MateLock[v - StartIndex]))
;
while (!omp_test_lock(&MateLock[w - StartIndex]))
;
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); // Q.push_back(u);
@ -190,121 +193,120 @@ void processMatchedVertices(
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") "; cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") ";
fflush(stdout); fflush(stdout);
#endif #endif
omp_unset_lock(&MateLock[v - StartIndex]);
omp_unset_lock(&MateLock[w - StartIndex]);
} // End of if(CandidateMate(w) = v } // End of if(CandidateMate(w) = v
} // End of Else }
} // End of Else
// omp_unset_lock(&MateLock[v - StartIndex]);
// omp_unset_lock(&MateLock[w - StartIndex]);
} // End of if(w >=0) } // End of if(w >=0)
else else
{
adj11 = verLocPtr[v - StartIndex];
adj12 = verLocPtr[v - StartIndex + 1];
for (k1 = adj11; k1 < adj12; k1++)
{ {
adj11 = verLocPtr[v - StartIndex]; w = verLocInd[k1];
adj12 = verLocPtr[v - StartIndex + 1]; if ((w < StartIndex) || (w > EndIndex))
for (k1 = adj11; k1 < adj12; k1++) { // A ghost
{
w = verLocInd[k1];
if ((w < StartIndex) || (w > EndIndex))
{ // A ghost
#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
msgInd++;
NumMessagesBundled++;
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
assert(ghostOwner != -1);
assert(ghostOwner != myRank);
PCounter[ghostOwner]++;
privateQLocalVtx.push_back(v); ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
privateQGhostVtx.push_back(w); assert(ghostOwner != -1);
privateQMsgType.push_back(FAILURE); assert(ghostOwner != myRank);
privateQOwner.push_back(ghostOwner); #pragma omp atomic
PCounter[ghostOwner]++;
#pragma omp atomic
msgInd++;
#pragma omp atomic
NumMessagesBundled++;
} // End of if(GHOST) privateQLocalVtx.push_back(v);
} // End of for loop privateQGhostVtx.push_back(w);
} // End of Else: w == -1 privateQMsgType.push_back(FAILURE);
// End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v) privateQOwner.push_back(ghostOwner);
} // End of If (candidateMate[v-StartIndex] == u } // End of if(GHOST)
} // End of for loop
} // End of Else: w == -1
// End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
} // End of critical region if } // End of If (candidateMate[v-StartIndex] == u
} // End of if ( (v >= StartIndex) && (v <= EndIndex) ) //If Local Vertex: } // End of if ( (v >= StartIndex) && (v <= EndIndex) ) //If Local Vertex:
else else
{ // Neighbor is a ghost vertex { // Neighbor is a ghost vertex
#pragma omp critical(innerProcessMatched) while (!omp_test_lock(&MateLock[u - StartIndex]))
;
#pragma omp critical(prova)
{ {
// while(!omp_test_lock(&MateLock[u - StartIndex]));
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])
// Build the Message Packet: { // u is local
// 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"; cout << "\n(" << myRank << ")Ghost is " << v << " Owner is: " << findOwnerOfGhost(v, verDistance, myRank, numProcs) << "\n";
fflush(stdout); fflush(stdout);
#endif #endif
msgInd++; ghostOwner = findOwnerOfGhost(v, verDistance, myRank, numProcs);
NumMessagesBundled++; assert(ghostOwner != -1);
ghostOwner = findOwnerOfGhost(v, verDistance, myRank, numProcs); assert(ghostOwner != myRank);
assert(ghostOwner != -1); #pragma omp atomic
assert(ghostOwner != myRank); PCounter[ghostOwner]++;
PCounter[ghostOwner]++; #pragma omp atomic
msgInd++;
privateQLocalVtx.push_back(u); #pragma omp atomic
privateQGhostVtx.push_back(v); NumMessagesBundled++;
privateQMsgType.push_back(SUCCESS);
privateQOwner.push_back(ghostOwner);
} // End of If( v != Mate[u] )
// omp_unset_lock(&MateLock[u - StartIndex]); privateQLocalVtx.push_back(u);
privateQGhostVtx.push_back(v);
privateQMsgType.push_back(SUCCESS);
privateQOwner.push_back(ghostOwner);
} // End of critical region } // End of If( v != Mate[u] )
} // End of Else //A Ghost Vertex
} // End of For Loop adj(u) omp_unset_lock(&MateLock[u - StartIndex]);
} // End of if ( (u >= StartIndex) && (u <= EndIndex) ) //Process Only If a Local Vertex } // End of Else //A Ghost Vertex
// Ask for the critical section only when a certain amount } // End of for
// of data have been accumulated in the private queue
if (privateU.size() < UCHUNK && !U.empty())
continue;
printf("Executed \n"); // TODO commenting that part of code might generate errors
#ifdef error // Ask for the critical section only when there are no more data to
// compute.
if (/*privateU.size() < UCHUNK &&*/ !U.empty())
continue;
#pragma omp critical(U) #pragma omp critical(U)
{ {
while (!privateU.empty()) while (!privateU.empty())
U.push_back(privateU.pop_back()); U.push_back(privateU.pop_back());
} }
#endif
#ifndef error #ifndef error
queuesTransfer(U, privateU, QLocalVtx, #pragma omp critical(privateMsg)
QGhostVtx, {
QMsgType, QOwner, privateQLocalVtx, while (!privateQLocalVtx.empty())
privateQGhostVtx, {
privateQMsgType, QLocalVtx.push_back(privateQLocalVtx.pop_back());
privateQOwner); QGhostVtx.push_back(privateQGhostVtx.pop_back());
QMsgType.push_back(privateQMsgType.pop_back());
QOwner.push_back(privateQOwner.pop_back());
}
}
#endif #endif
}
} }
} // End of while ( !U.empty() ) } // End of while ( !U.empty() )
queuesTransfer(U, privateU, QLocalVtx, queuesTransfer(U, privateU, QLocalVtx,
QGhostVtx, QGhostVtx,
QMsgType, QOwner, privateQLocalVtx, QMsgType, QOwner, privateQLocalVtx,
@ -329,4 +331,4 @@ void processMatchedVertices(
*msgIndPtr = msgInd; *msgIndPtr = msgInd;
*NumMessagesBundledPtr = NumMessagesBundled; *NumMessagesBundledPtr = NumMessagesBundled;
*SPtr = S; *SPtr = S;
} }

Loading…
Cancel
Save