@ -1,39 +1,39 @@
# include "MatchBoxPC.h"
# include "MatchBoxPC.h"
//#define DEBUG_HANG_
void processMatchedVerticesAndSendMessages (
void processMatchedVerticesAndSendMessages (
MilanLongInt NLVer ,
MilanLongInt NLVer ,
vector < MilanLongInt > & UChunkBeingProcessed ,
vector < MilanLongInt > & UChunkBeingProcessed ,
vector < MilanLongInt > & U ,
vector < MilanLongInt > & U ,
vector < MilanLongInt > & privateU ,
vector < MilanLongInt > & privateU ,
MilanLongInt StartIndex ,
MilanLongInt StartIndex ,
MilanLongInt EndIndex ,
MilanLongInt EndIndex ,
MilanLongInt * myCard ,
MilanLongInt * myCard ,
MilanLongInt * msgInd ,
MilanLongInt * msgInd ,
MilanLongInt * NumMessagesBundled ,
MilanLongInt * NumMessagesBundled ,
MilanLongInt * SPtr ,
MilanLongInt * SPtr ,
MilanLongInt * verLocPtr ,
MilanLongInt * verLocPtr ,
MilanLongInt * verLocInd ,
MilanLongInt * verLocInd ,
MilanLongInt * verDistance ,
MilanLongInt * verDistance ,
MilanLongInt * PCounter ,
MilanLongInt * PCounter ,
vector < MilanLongInt > & Counter ,
vector < MilanLongInt > & Counter ,
MilanInt myRank ,
MilanInt myRank ,
MilanInt numProcs ,
MilanInt numProcs ,
MilanLongInt * candidateMate ,
MilanLongInt * candidateMate ,
vector < MilanLongInt > & GMate ,
vector < MilanLongInt > & GMate ,
MilanLongInt * Mate ,
MilanLongInt * Mate ,
map < MilanLongInt , MilanLongInt > & Ghost2LocalMap ,
map < MilanLongInt , MilanLongInt > & Ghost2LocalMap ,
MilanReal * edgeLocWeight ,
MilanReal * edgeLocWeight ,
vector < MilanLongInt > & QLocalVtx ,
vector < MilanLongInt > & QLocalVtx ,
vector < MilanLongInt > & QGhostVtx ,
vector < MilanLongInt > & QGhostVtx ,
vector < MilanLongInt > & QMsgType ,
vector < MilanLongInt > & QMsgType ,
vector < MilanInt > & QOwner ,
vector < MilanInt > & QOwner ,
vector < MilanLongInt > & privateQLocalVtx ,
vector < MilanLongInt > & privateQLocalVtx ,
vector < MilanLongInt > & privateQGhostVtx ,
vector < MilanLongInt > & privateQGhostVtx ,
vector < MilanLongInt > & privateQMsgType ,
vector < MilanLongInt > & privateQMsgType ,
vector < MilanInt > & privateQOwner ,
vector < MilanInt > & privateQOwner ,
MPI_Comm comm ,
MPI_Comm comm ,
MilanLongInt * msgActual ,
MilanLongInt * msgActual ,
vector < MilanLongInt > & Message )
vector < MilanLongInt > & Message )
{
{
MilanLongInt initialSize = QLocalVtx . size ( ) ;
MilanLongInt initialSize = QLocalVtx . size ( ) ;
@ -50,245 +50,231 @@ void processMatchedVerticesAndSendMessages(
# 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, option) \
/ / # pragma omp parallel private ( k , w , v , k1 , adj1 , adj2 , adj11 , adj12 , ghostOwner , option ) \
firstprivate ( Message , privateU , StartIndex , EndIndex , privateQLocalVtx , privateQGhostVtx , privateQMsgType , privateQOwner , UChunkBeingProcessed ) default ( shared ) \
firstprivate ( Message , privateU , StartIndex , EndIndex , privateQLocalVtx , privateQGhostVtx , \
num_threads ( NUM_THREAD ) \
privateQMsgType , privateQOwner , UChunkBeingProcessed ) default ( shared ) \
reduction ( + \
num_threads ( NUM_THREAD ) \
: msgInd [ : 1 ] , PCounter \
reduction ( + \
[ : numProcs ] , myCard \
: msgInd [ : 1 ] , PCounter \
[ : 1 ] , NumMessagesBundled \
[ : numProcs ] , myCard \
[ : 1 ] , msgActual \
[ : 1 ] , NumMessagesBundled \
[ : 1 ] , msgActual \
[ : 1 ] )
[ : 1 ] )
{
{
while ( ! U . empty ( ) )
while ( ! U . empty ( ) ) {
{
extractUChunk ( UChunkBeingProcessed , U , privateU ) ;
extractUChunk ( UChunkBeingProcessed , U , privateU ) ;
for ( MilanLongInt u : UChunkBeingProcessed )
for ( MilanLongInt u : UChunkBeingProcessed ) {
{
# ifdef PRINT_DEBUG_INFO_
# ifdef PRINT_DEBUG_INFO_
cout < < " \n ( " < < myRank < < " )u: " < < u ;
cout < < " \n ( " < < myRank < < " )u: " < < u ;
fflush ( stdout ) ;
fflush ( stdout ) ;
# endif
# endif
if ( ( u > = StartIndex ) & & ( u < = EndIndex ) )
if ( ( u > = StartIndex ) & & ( u < = EndIndex ) ) { // Process Only the Local Vertices
{ // Process Only the Local Vertices
# ifdef COUNT_LOCAL_VERTEX
# ifdef COUNT_LOCAL_VERTEX
localVertices + + ;
localVertices + + ;
# endif
# endif
// Get the Adjacency list for u
// Get the Adjacency list for u
adj1 = verLocPtr [ u - StartIndex ] ; // Pointer
adj1 = verLocPtr [ u - StartIndex ] ; // Pointer
adj2 = verLocPtr [ u - StartIndex + 1 ] ;
adj2 = verLocPtr [ u - StartIndex + 1 ] ;
for ( k = adj1 ; k < adj2 ; k + + )
for ( k = adj1 ; k < adj2 ; k + + ) {
{
option = - 1 ;
option = - 1 ;
v = verLocInd [ k ] ;
v = verLocInd [ k ] ;
if ( ( v > = StartIndex ) & & ( v < = EndIndex ) )
if ( ( v > = StartIndex ) & & ( v < = EndIndex ) ) { // If Local Vertex:
{ // 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 ) ;
# endif
# endif
# pragma omp atomic read
# pragma omp atomic read
mateVal = Mate [ v - StartIndex ] ;
mateVal = Mate [ v - StartIndex ] ;
// 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
if ( mateVal < 0 )
if ( mateVal < 0 ) {
{
# pragma omp critical
# pragma omp critical
{
{
if ( candidateMate [ v - StartIndex ] = = u )
if ( candidateMate [ v - StartIndex ] = = u ) {
{
// Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
// Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
w = computeCandidateMate ( verLocPtr [ v - StartIndex ] ,
w = computeCandidateMate ( verLocPtr [ v - StartIndex ] ,
verLocPtr [ v - StartIndex + 1 ] ,
verLocPtr [ v - StartIndex + 1 ] ,
edgeLocWeight , 0 ,
edgeLocWeight , 0 ,
verLocInd ,
verLocInd ,
StartIndex ,
StartIndex ,
EndIndex ,
EndIndex ,
GMate ,
GMate ,
Mate ,
Mate ,
Ghost2LocalMap ) ;
Ghost2LocalMap ) ;
candidateMate [ v - StartIndex ] = w ;
candidateMate [ v - StartIndex ] = w ;
# 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 ) {
{
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
option = 2 ;
option = 2 ;
if ( candidateMate [ NLVer + Ghost2LocalMap [ w ] ] = = v )
if ( candidateMate [ NLVer + Ghost2LocalMap [ w ] ] = = v ) {
{
option = 1 ;
option = 1 ;
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
} // 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
if ( candidateMate [ w - StartIndex ] = = v ) {
{ // w is a local vertex
option = 3 ;
if ( candidateMate [ w - StartIndex ] = = v )
Mate [ v - StartIndex ] = w ; // v is a local vertex
{
Mate [ w - StartIndex ] = v ; // w is a local vertex
option = 3 ;
Mate [ v - StartIndex ] = w ; // v is a local vertex
Mate [ w - StartIndex ] = v ; // w is a local vertex
# ifdef PRINT_DEBUG_INFO_
# ifdef PRINT_DEBUG_INFO_
cout < < " \n ( " < < myRank < < " )MATCH: ( " < < v < < " , " < < w < < " ) " ;
cout < < " \n ( " < < myRank < < " )MATCH: ( " < < v < < " , " < < w < < " ) " ;
fflush ( stdout ) ;
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
option = 4 ; // End of Else: w == -1
option = 4 ; // End of Else: w == -1
// End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
// End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
} // End of If (candidateMate[v-StartIndex] == u
} // End of If (candidateMate[v-StartIndex] == u
} // End of task
} // End of task
} // mateval < 0
} // mateval < 0
} // 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
# 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 ] )
if ( v ! = Mate [ u - StartIndex ] )
option = 5 ; // u is local
option = 5 ; // u is local
} // End of critical
} // End of critical
} // End of Else //A Ghost Vertex
} // End of Else //A Ghost Vertex
switch ( option )
switch ( option )
{
{
case - 1 :
case - 1 :
// No things to do
// No things to do
break ;
break ;
case 1 :
case 1 :
// Found a dominating edge, it is a ghost and candidateMate[NLVer + Ghost2LocalMap[w]] == v
// Found a dominating edge, it is a ghost and candidateMate[NLVer + Ghost2LocalMap[w]] == v
privateU . push_back ( v ) ;
privateU . push_back ( v ) ;
privateU . push_back ( w ) ;
privateU . push_back ( w ) ;
( * myCard ) + + ;
( * myCard ) + + ;
# ifdef PRINT_DEBUG_INFO_
# ifdef PRINT_DEBUG_INFO_
cout < < " \n ( " < < myRank < < " )MATCH: ( " < < v < < " , " < < w < < " ) " ;
cout < < " \n ( " < < myRank < < " )MATCH: ( " < < v < < " , " < < w < < " ) " ;
fflush ( stdout ) ;
fflush ( stdout ) ;
# endif
# endif
// Decrement the counter:
// Decrement the counter:
PROCESS_CROSS_EDGE ( & Counter [ Ghost2LocalMap [ w ] ] , SPtr ) ;
PROCESS_CROSS_EDGE ( & Counter [ Ghost2LocalMap [ w ] ] , SPtr ) ;
case 2 :
case 2 :
// Found a dominating edge, it is a ghost
// Found a dominating edge, it is a ghost
ghostOwner = findOwnerOfGhost ( w , verDistance , myRank , numProcs ) ;
ghostOwner = findOwnerOfGhost ( w , verDistance , myRank , numProcs ) ;
// Build the Message Packet:
// Build the Message Packet:
// Message[0] = v; // LOCAL
// Message[0] = v; // LOCAL
// Message[1] = w; // GHOST
// Message[1] = w; // GHOST
// Message[2] = REQUEST; // TYPE
// Message[2] = REQUEST; // TYPE
// Send a Request (Asynchronous)
// Send a Request (Asynchronous)
// MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
// MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
( * msgActual ) + + ;
( * msgActual ) + + ;
( * msgInd ) + + ;
( * msgInd ) + + ;
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 ) ;
break ;
break ;
case 3 :
case 3 :
privateU . push_back ( v ) ;
privateU . push_back ( v ) ;
privateU . push_back ( w ) ;
privateU . push_back ( w ) ;
( * myCard ) + + ;
( * myCard ) + + ;
break ;
break ;
case 4 :
case 4 :
// Could not find a dominating vertex
// Could not find a dominating vertex
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
# 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
ghostOwner = findOwnerOfGhost ( w , verDistance , myRank , numProcs ) ;
ghostOwner = findOwnerOfGhost ( w , verDistance , myRank , numProcs ) ;
// Build the Message Packet:
// Build the Message Packet:
// Message[0] = v; // LOCAL
// Message[0] = v; // LOCAL
// Message[1] = w; // GHOST
// Message[1] = w; // GHOST
// Message[2] = FAILURE; // TYPE
// Message[2] = FAILURE; // TYPE
// Send a Request (Asynchronous)
// Send a Request (Asynchronous)
// MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
// MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
( * msgActual ) + + ;
( * msgActual ) + + ;
( * msgInd ) + + ;
( * msgInd ) + + ;
privateQLocalVtx . push_back ( v ) ;
privateQLocalVtx . push_back ( v ) ;
privateQGhostVtx . push_back ( w ) ;
privateQGhostVtx . push_back ( w ) ;
privateQMsgType . push_back ( FAILURE ) ;
privateQMsgType . push_back ( FAILURE ) ;
privateQOwner . push_back ( ghostOwner ) ;
privateQOwner . push_back ( ghostOwner ) ;
} // End of if(GHOST)
} // End of if(GHOST)
} // End of for loop
} // End of for loop
break ;
break ;
case 5 :
case 5 :
default :
default :
# 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
ghostOwner = findOwnerOfGhost ( v , verDistance , myRank , numProcs ) ;
ghostOwner = findOwnerOfGhost ( v , verDistance , myRank , numProcs ) ;
// Build the Message Packet:
// Build the Message Packet:
// Message[0] = u; // LOCAL
// Message[0] = u; // LOCAL
// Message[1] = v; // GHOST
// Message[1] = v; // GHOST
// Message[2] = SUCCESS; // TYPE
// Message[2] = SUCCESS; // TYPE
// Send a Request (Asynchronous)
// Send a Request (Asynchronous)
// MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
// MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
( * msgActual ) + + ;
( * msgActual ) + + ;
( * msgInd ) + + ;
( * msgInd ) + + ;
privateQLocalVtx . push_back ( u ) ;
privateQLocalVtx . push_back ( u ) ;
privateQGhostVtx . push_back ( v ) ;
privateQGhostVtx . push_back ( v ) ;
privateQMsgType . push_back ( SUCCESS ) ;
privateQMsgType . push_back ( SUCCESS ) ;
privateQOwner . push_back ( ghostOwner ) ;
privateQOwner . push_back ( ghostOwner ) ;
break ;
break ;
} // End of switch
} // End of switch
} // End of inner for
} // End of inner for
}
}
} // End of outer for
} // End of outer for
queuesTransfer ( U , privateU , QLocalVtx ,
queuesTransfer ( U , privateU , QLocalVtx ,
QGhostVtx ,
QGhostVtx ,
QMsgType , QOwner , privateQLocalVtx ,
QMsgType , QOwner , privateQLocalVtx ,
privateQGhostVtx ,
privateQGhostVtx ,
privateQMsgType ,
privateQMsgType ,
privateQOwner ) ;
privateQOwner ) ;
} // End of while ( !U.empty() )
} // End of while ( !U.empty() )
@ -302,14 +288,21 @@ void processMatchedVerticesAndSendMessages(
} // End of parallel region
} // End of parallel region
// Send the messages
// Send the messages
for ( int i = initialSize ; i < QOwner . size ( ) ; i + + )
# ifdef DEBUG_HANG_
{
cout < < myRank < < " Sending: " < < QOwner . size ( ) - initialSize < < " messages " < < endl ;
# endif
for ( int i = initialSize ; i < QOwner . size ( ) ; i + + ) {
Message [ 0 ] = QLocalVtx [ i ] ;
Message [ 0 ] = QLocalVtx [ i ] ;
Message [ 1 ] = QGhostVtx [ i ] ;
Message [ 1 ] = QGhostVtx [ i ] ;
Message [ 2 ] = QMsgType [ i ] ;
Message [ 2 ] = QMsgType [ i ] ;
ghostOwner = QOwner [ i ] ;
ghostOwner = QOwner [ i ] ;
MPI_Bsend ( & Message [ 0 ] , 3 , TypeMap < MilanLongInt > ( ) , ghostOwner , ComputeTag , comm ) ;
//MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
//cout << myRank<<" Sending to "<<ghostOwner<<endl;
MPI_Bsend ( & Message [ 0 ] , 3 , TypeMap < MilanLongInt > ( ) , ghostOwner , ComputeTag , comm ) ;
}
}
# ifdef DEBUG_HANG_
cout < < myRank < < " Done sending messages " < < endl ;
# endif
}
}