void MPID_nem_dbg_print_all_sendq(FILE *stream) { int i; MPIDI_PG_t *pg; MPIDI_VC_t *vc; MPIDI_PG_iterator iter; fprintf(stream, "========================================\n"); fprintf(stream, "MPI_COMM_WORLD ctx=%#x rank=%d\n", MPIR_Process.comm_world->context_id, MPIR_Process.comm_world->rank); fprintf(stream, "MPI_COMM_SELF ctx=%#x\n", MPIR_Process.comm_self->context_id); if (MPIR_Process.comm_parent) { fprintf(stream, "MPI_COMM_PARENT ctx=%#x recvctx=%#x\n", MPIR_Process.comm_self->context_id, MPIR_Process.comm_parent->recvcontext_id); } else { fprintf(stream, "MPI_COMM_PARENT (NULL)\n"); } MPIDI_PG_Get_iterator(&iter); while (MPIDI_PG_Has_next(&iter)) { MPIDI_PG_Get_next(&iter, &pg); fprintf(stream, "PG ptr=%p size=%d id=%s refcount=%d\n", pg, pg->size, (const char*)pg->id, MPIR_Object_get_ref(pg)); for (i = 0; i < MPIDI_PG_Get_size(pg); ++i) { MPIDI_PG_Get_vc(pg, i, &vc); MPID_nem_dbg_print_vc_sendq(stream, vc); } } fprintf(stream, "========================================\n"); }
int MPID_GPID_ToLpidArray( int size, MPID_Gpid in_gpid[], int lpid[] ) { int i, mpi_errno = MPI_SUCCESS; int pgid; MPIDI_PG_t *pg = 0; MPIDI_PG_iterator iter; int *gpid = (int*)&in_gpid[0]; for (i=0; i<size; i++) { MPIDI_PG_Get_iterator(&iter); do { MPIDI_PG_Get_next( &iter, &pg ); if (!pg) { /* --BEGIN ERROR HANDLING-- */ /* Internal error. This gpid is unknown on this process */ /* A printf is NEVER valid in code that might be executed by the user, even in an error case (use MPL_internal_error_printf if you need to print an error message and its not appropriate to use the regular error code system */ /* printf("No matching pg foung for id = %d\n", pgid ); */ lpid[i] = -1; MPIR_ERR_SET2(mpi_errno,MPI_ERR_INTERN, "**unknowngpid", "**unknowngpid %d %d", gpid[0], gpid[1] ); return mpi_errno; /* --END ERROR HANDLING-- */ } MPIDI_PG_IdToNum( pg, &pgid ); if (pgid == gpid[0]) { /* found the process group. gpid[1] is the rank in this process group */ /* Sanity check on size */ if (pg->size > gpid[1]) { lpid[i] = pg->vct[gpid[1]].lpid; } else { /* --BEGIN ERROR HANDLING-- */ lpid[i] = -1; MPIR_ERR_SET2(mpi_errno,MPI_ERR_INTERN, "**unknowngpid", "**unknowngpid %d %d", gpid[0], gpid[1] ); return mpi_errno; /* --END ERROR HANDLING-- */ } /* printf( "lpid[%d] = %d for gpid = (%d)%d\n", i, lpid[i], gpid[0], gpid[1] ); */ break; } } while (1); gpid += 2; } return mpi_errno; }
int MPID_PG_ForwardPGInfo( MPID_Comm *peer_ptr, MPID_Comm *comm_ptr, int nPGids, const MPID_Gpid in_gpids[], int root ) { int mpi_errno = MPI_SUCCESS; int i, allfound = 1, pgid, pgidWorld; MPIDI_PG_t *pg = 0; MPIDI_PG_iterator iter; MPIR_Errflag_t errflag = MPIR_ERR_NONE; const int *gpids = (const int*)&in_gpids[0]; /* Get the pgid for CommWorld (always attached to the first process group) */ MPIDI_PG_Get_iterator(&iter); MPIDI_PG_Get_next( &iter, &pg ); MPIDI_PG_IdToNum( pg, &pgidWorld ); /* Extract the unique process groups */ for (i=0; i<nPGids && allfound; i++) { if (gpids[0] != pgidWorld) { /* Add this gpid to the list of values to check */ /* FIXME: For testing, we just test in place */ MPIDI_PG_Get_iterator(&iter); do { MPIDI_PG_Get_next( &iter, &pg ); if (!pg) { /* We don't know this pgid */ allfound = 0; break; } MPIDI_PG_IdToNum( pg, &pgid ); } while (pgid != gpids[0]); } gpids += 2; } /* See if everyone is happy */ mpi_errno = MPIR_Allreduce_impl( MPI_IN_PLACE, &allfound, 1, MPI_INT, MPI_LAND, comm_ptr, &errflag ); if (mpi_errno) MPIR_ERR_POP(mpi_errno); MPIR_ERR_CHKANDJUMP(errflag, mpi_errno, MPI_ERR_OTHER, "**coll_fail"); if (allfound) return MPI_SUCCESS; /* FIXME: We need a cleaner way to handle this case than using an ifdef. We could have an empty version of MPID_PG_BCast in ch3u_port.c, but that's a rather crude way of addressing this problem. Better is to make the handling of local and remote PIDS for the dynamic process case part of the dynamic process "module"; devices that don't support dynamic processes (and hence have only COMM_WORLD) could optimize for that case */ #ifndef MPIDI_CH3_HAS_NO_DYNAMIC_PROCESS /* We need to share the process groups. We use routines from ch3u_port.c */ MPID_PG_BCast( peer_ptr, comm_ptr, root ); #endif fn_exit: return MPI_SUCCESS; fn_fail: goto fn_exit; }
int MPID_Create_intercomm_from_lpids( MPID_Comm *newcomm_ptr, int size, const int lpids[] ) { int mpi_errno = MPI_SUCCESS; MPID_Comm *commworld_ptr; int i; MPIDI_PG_iterator iter; commworld_ptr = MPIR_Process.comm_world; /* Setup the communicator's vc table: remote group */ MPIDI_VCRT_Create( size, &newcomm_ptr->dev.vcrt ); for (i=0; i<size; i++) { MPIDI_VC_t *vc = 0; /* For rank i in the new communicator, find the corresponding virtual connection. For lpids less than the size of comm_world, we can just take the corresponding entry from comm_world. Otherwise, we need to search through the process groups. */ /* printf( "[%d] Remote rank %d has lpid %d\n", MPIR_Process.comm_world->rank, i, lpids[i] ); */ if (lpids[i] < commworld_ptr->remote_size) { vc = commworld_ptr->dev.vcrt->vcr_table[lpids[i]]; } else { /* We must find the corresponding vcr for a given lpid */ /* For now, this means iterating through the process groups */ MPIDI_PG_t *pg = 0; int j; MPIDI_PG_Get_iterator(&iter); /* Skip comm_world */ MPIDI_PG_Get_next( &iter, &pg ); do { MPIDI_PG_Get_next( &iter, &pg ); MPIR_ERR_CHKINTERNAL(!pg, mpi_errno, "no pg"); /* FIXME: a quick check on the min/max values of the lpid for this process group could help speed this search */ for (j=0; j<pg->size; j++) { /*printf( "Checking lpid %d against %d in pg %s\n", lpids[i], pg->vct[j].lpid, (char *)pg->id ); fflush(stdout); */ if (pg->vct[j].lpid == lpids[i]) { vc = &pg->vct[j]; /*printf( "found vc %x for lpid = %d in another pg\n", (int)vc, lpids[i] );*/ break; } } } while (!vc); } /* printf( "about to dup vc %x for lpid = %d in another pg\n", (int)vc, lpids[i] ); */ /* Note that his will increment the ref count for the associate PG if necessary. */ MPIDI_VCR_Dup( vc, &newcomm_ptr->dev.vcrt->vcr_table[i] ); } fn_exit: return mpi_errno; fn_fail: goto fn_exit; }