diff --git a/amgprec/impl/aggregator/MatchBoxPC.h b/amgprec/impl/aggregator/MatchBoxPC.h index 1e84b7ca..e8a2e2cc 100644 --- a/amgprec/impl/aggregator/MatchBoxPC.h +++ b/amgprec/impl/aggregator/MatchBoxPC.h @@ -292,6 +292,7 @@ extern "C" void processMatchedVertices( MilanLongInt NLVer, + vector &UChunkBeingProcessed, staticQueue &U, staticQueue &privateU, MilanLongInt StartIndex, diff --git a/amgprec/impl/aggregator/algoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP.cpp b/amgprec/impl/aggregator/algoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP.cpp index ab031f68..a4fb68e5 100644 --- a/amgprec/impl/aggregator/algoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP.cpp +++ b/amgprec/impl/aggregator/algoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP.cpp @@ -274,8 +274,12 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP( /////////////////////////// PROCESS MATCHED VERTICES ////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// + // TODO what would be the optimal UCHUNK + vector UChunkBeingProcessed; + UChunkBeingProcessed.reserve(UCHUNK); + processMatchedVertices(NLVer, - //UChunkBeingProcessed, + UChunkBeingProcessed, U, privateU, StartIndex, @@ -382,117 +386,47 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP( v = verLocInd[k]; if ((v >= StartIndex) && (v <= EndIndex)) { // v is a Local Vertex: - if (Mate[v - StartIndex] >= 0) // v is already matched - continue; + //if (Mate[v - StartIndex] >= 0) // v is already matched + // continue; #ifdef PRINT_DEBUG_INFO_ cout << "\n(" << myRank << ")v: " << v << " c(v)= " << candidateMate[v - StartIndex] << " Mate[v]: " << Mate[v]; fflush(stdout); #endif - if (candidateMate[v - StartIndex] == u) - { // Only if pointing to the matched vertex - // Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v) - // Start: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v) - adj11 = verLocPtr[v - StartIndex]; - adj12 = verLocPtr[v - StartIndex + 1]; - w = -1; - heaviestEdgeWt = MilanRealMin; // Assign the smallest Value possible first LDBL_MIN - for (k1 = adj11; k1 < adj12; k1++) - { - if ((verLocInd[k1] < StartIndex) || (verLocInd[k1] > EndIndex)) - { // Is it a ghost vertex? - if (GMate[Ghost2LocalMap[verLocInd[k1]]] >= 0) // Already matched - continue; - } - else - { // A local vertex - if (Mate[verLocInd[k1] - StartIndex] >= 0) // Already matched - continue; - } - - if ((edgeLocWeight[k1] > heaviestEdgeWt) || - ((edgeLocWeight[k1] == heaviestEdgeWt) && (w < verLocInd[k1]))) - { - heaviestEdgeWt = edgeLocWeight[k1]; - w = verLocInd[k1]; - } - } // End of for loop - candidateMate[v - StartIndex] = w; - // End: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v) -#ifdef PRINT_DEBUG_INFO_ - cout << "\n(" << myRank << ")" << v << " Points to: " << w; - fflush(stdout); -#endif - // If found a dominating edge: - if (w >= 0) - { - if ((w < StartIndex) || (w > EndIndex)) - { // w is a ghost - // Build the Message Packet: - Message[0] = v; // LOCAL - Message[1] = w; // GHOST - Message[2] = REQUEST; // TYPE - // Send a Request (Asynchronous) -#ifdef PRINT_DEBUG_INFO_ - cout << "\n(" << myRank << ")Sending a request message:"; - cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs); - fflush(stdout); -#endif - ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs); - assert(ghostOwner != -1); - assert(ghostOwner != myRank); - MPI_Bsend(&Message[0], 3, TypeMap(), ghostOwner, ComputeTag, comm); - msgInd++; - msgActual++; - if (candidateMate[NLVer + Ghost2LocalMap[w]] == v) - { - Mate[v - StartIndex] = w; // v is local - GMate[Ghost2LocalMap[w]] = v; // w is ghost - // Q.push_back(u); - U.push_back(v); - U.push_back(w); - myCard++; -#ifdef PRINT_DEBUG_INFO_ - cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") "; - fflush(stdout); -#endif - - PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[w]], &S); - - } // End of if CandidateMate[w] = v - } // End of if a Ghost Vertex - else - { // w is a local vertex - if (candidateMate[w - StartIndex] == v) - { - Mate[v - StartIndex] = w; // v is local - Mate[w - StartIndex] = v; // w is local - // Q.push_back(u); - U.push_back(v); - U.push_back(w); - myCard++; + // If the current vertex is pointing to a matched vertex and is not matched + if (Mate[v - StartIndex] < 0) + { + if (candidateMate[v - StartIndex] == u) + { // Only if pointing to the matched vertex + // Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v) + // Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v) + w = computeCandidateMate(verLocPtr[v - StartIndex], + verLocPtr[v - StartIndex + 1], + edgeLocWeight, 0, + verLocInd, + StartIndex, + EndIndex, + GMate, + Mate, + Ghost2LocalMap); + + candidateMate[v - StartIndex] = w; + // End: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v) #ifdef PRINT_DEBUG_INFO_ - cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") "; - fflush(stdout); + cout << "\n(" << myRank << ")" << v << " Points to: " << w; + fflush(stdout); #endif - } // End of if(CandidateMate(w) = v - } // End of Else - } // End of if(w >=0) - else - { // no dominating edge found: w == -1 - adj11 = verLocPtr[v - StartIndex]; - adj12 = verLocPtr[v - StartIndex + 1]; - for (k1 = adj11; k1 < adj12; k1++) + // If found a dominating edge: + if (w >= 0) { - w = verLocInd[k1]; if ((w < StartIndex) || (w > EndIndex)) - { // A ghost + { // w is a ghost // Build the Message Packet: Message[0] = v; // LOCAL Message[1] = w; // GHOST - Message[2] = FAILURE; // TYPE + Message[2] = REQUEST; // TYPE // Send a Request (Asynchronous) #ifdef PRINT_DEBUG_INFO_ - cout << "\n(" << myRank << ")Sending a failure message: "; + cout << "\n(" << myRank << ")Sending a request message:"; cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs); fflush(stdout); #endif @@ -502,12 +436,72 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP( MPI_Bsend(&Message[0], 3, TypeMap(), ghostOwner, ComputeTag, comm); msgInd++; msgActual++; - } // End of if(GHOST) - } // End of for loop - } // End of Else: w == -1 - // End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v) - } // End of If (candidateMate[v-StartIndex] == u) - } // End of if ( (v >= StartIndex) && (v <= EndIndex) ) //If Local Vertex: + if (candidateMate[NLVer + Ghost2LocalMap[w]] == v) + { + Mate[v - StartIndex] = w; // v is local + GMate[Ghost2LocalMap[w]] = v; // w is ghost + // Q.push_back(u); + U.push_back(v); + U.push_back(w); + myCard++; +#ifdef PRINT_DEBUG_INFO_ + cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") "; + fflush(stdout); +#endif + + PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[w]], &S); + + } // End of if CandidateMate[w] = v + } // End of if a Ghost Vertex + else + { // w is a local vertex + if (candidateMate[w - StartIndex] == v) + { + Mate[v - StartIndex] = w; // v is local + Mate[w - StartIndex] = v; // w is local + // Q.push_back(u); + U.push_back(v); + U.push_back(w); + myCard++; +#ifdef PRINT_DEBUG_INFO_ + cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") "; + fflush(stdout); +#endif + } // End of if(CandidateMate(w) = v + } // End of Else + } // End of if(w >=0) + else + { // no dominating edge found: w == -1 + adj11 = verLocPtr[v - StartIndex]; + adj12 = verLocPtr[v - StartIndex + 1]; + for (k1 = adj11; k1 < adj12; k1++) + { + w = verLocInd[k1]; + 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_ + cout << "\n(" << myRank << ")Sending a failure message: "; + cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs); + fflush(stdout); +#endif + ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs); + assert(ghostOwner != -1); + assert(ghostOwner != myRank); + MPI_Bsend(&Message[0], 3, TypeMap(), ghostOwner, ComputeTag, comm); + msgInd++; + msgActual++; + } // End of if(GHOST) + } // End of for loop + } // End of Else: w == -1 + // End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v) + } // End of If (candidateMate[v-StartIndex] == u) + } + } // End of if ( (v >= StartIndex) && (v <= EndIndex) ) //If Local Vertex: else { // Neighbor v is a ghost vertex if (candidateMate[NLVer + Ghost2LocalMap[v]] == u) diff --git a/amgprec/impl/aggregator/isAlreadyMatched.cpp b/amgprec/impl/aggregator/isAlreadyMatched.cpp index 38ae73f5..d4efd416 100644 --- a/amgprec/impl/aggregator/isAlreadyMatched.cpp +++ b/amgprec/impl/aggregator/isAlreadyMatched.cpp @@ -1,5 +1,6 @@ #include "MatchBoxPC.h" +//TODO can be optimized!! /** * //TODO documentation * @param k diff --git a/amgprec/impl/aggregator/processMatchedVertices.cpp b/amgprec/impl/aggregator/processMatchedVertices.cpp index fe983285..0054ffa2 100644 --- a/amgprec/impl/aggregator/processMatchedVertices.cpp +++ b/amgprec/impl/aggregator/processMatchedVertices.cpp @@ -4,6 +4,7 @@ void processMatchedVertices( MilanLongInt NLVer, + vector &UChunkBeingProcessed, staticQueue &U, staticQueue &privateU, MilanLongInt StartIndex, @@ -36,6 +37,8 @@ void processMatchedVertices( MilanLongInt adj1, adj2, adj11, adj12, k, k1, v = -1, w = -1, ghostOwner; int option; + MilanLongInt mateVal; + #ifdef PRINT_DEBUG_INFO_ cout << "\n(" << myRank << "=========================************===============================" << endl; fflush(stdout); @@ -45,14 +48,9 @@ void processMatchedVertices( #ifdef COUNT_LOCAL_VERTEX MilanLongInt localVertices = 0; #endif -#pragma omp parallel private(k, w, v, k1, adj1, adj2, adj11, adj12, ghostOwner, option) firstprivate(privateU, StartIndex, EndIndex, privateQLocalVtx, privateQGhostVtx, privateQMsgType, privateQOwner) default(shared) num_threads(NUM_THREAD) +#pragma omp parallel private(k, w, v, k1, adj1, adj2, adj11, adj12, ghostOwner, option) firstprivate(privateU, StartIndex, EndIndex, privateQLocalVtx, privateQGhostVtx, privateQMsgType, privateQOwner, UChunkBeingProcessed) default(shared) num_threads(NUM_THREAD) { - // TODO what would be the optimal UCHUNK - // TODO refactor - vector UChunkBeingProcessed; - UChunkBeingProcessed.reserve(UCHUNK); - while (!U.empty()) { @@ -86,9 +84,10 @@ void processMatchedVertices( cout << "\n(" << myRank << ")v: " << v << " c(v)= " << candidateMate[v - StartIndex] << " Mate[v]: " << Mate[v]; fflush(stdout); #endif - +#pragma omp atomic read + mateVal = Mate[v - StartIndex]; // If the current vertex is pointing to a matched vertex and is not matched - if (not isAlreadyMatched(v, StartIndex, EndIndex, GMate, Mate, Ghost2LocalMap)) + if (mateVal < 0) { #pragma omp critical {