int ompi_comm_neighbors_count(MPI_Comm comm, int *indegree, int *outdegree, int *weighted) { int res; if (OMPI_COMM_IS_CART(comm)) { int ndims; res = MPI_Cartdim_get(comm, &ndims) ; if (MPI_SUCCESS != res) { return res; } /* outdegree is always 2*ndims because we need to iterate over empty buffers for MPI_PROC_NULL */ *outdegree = *indegree = 2*ndims; *weighted = 0; } else if (OMPI_COMM_IS_GRAPH(comm)) { int rank, nneighbors; rank = ompi_comm_rank ((ompi_communicator_t *) comm); res = MPI_Graph_neighbors_count(comm, rank, &nneighbors); if (MPI_SUCCESS != res) { return res; } *outdegree = *indegree = nneighbors; *weighted = 0; } else if (OMPI_COMM_IS_DIST_GRAPH(comm)) { res = MPI_Dist_graph_neighbors_count(comm, indegree, outdegree, weighted); } else { return MPI_ERR_ARG; } return MPI_SUCCESS; }
FORTRAN_API void FORT_CALL mpi_graph_neighbors_count_ ( MPI_Fint *comm, MPI_Fint *rank, MPI_Fint *nneighbors, MPI_Fint *__ierr ) { int lnneighbors; *__ierr = MPI_Graph_neighbors_count(MPI_Comm_f2c(*comm), (int)*rank, &lnneighbors); *nneighbors = (MPI_Fint)lnneighbors; }
int NBC_Comm_neighbors_count(MPI_Comm comm, int *indegree, int *outdegree, int *weighted) { int topo, res; res = MPI_Topo_test(comm, &topo); if (MPI_SUCCESS != res) { printf("MPI Error in MPI_Topo_test() (%i)\n", res); return res; } switch(topo) { case MPI_CART: /* cartesian */ { int ndims; res = MPI_Cartdim_get(comm, &ndims) ; if (MPI_SUCCESS != res) { printf("MPI Error in MPI_Cartdim_get() (%i)\n", res); return res; } /* outdegree is always 2*ndims because we need to iterate over empty buffers for MPI_PROC_NULL */ *outdegree = *indegree = 2*ndims; *weighted = 0; } break; case MPI_GRAPH: /* graph */ { int rank, nneighbors; MPI_Comm_rank(comm, &rank); res = MPI_Graph_neighbors_count(comm, rank, &nneighbors); if (MPI_SUCCESS != res) { printf("MPI Error in MPI_Graph_neighbors_count() (%i)\n", res); return res; } *outdegree = *indegree = nneighbors; *weighted = 0; } break; case MPI_DIST_GRAPH: /* graph */ { res = MPI_Dist_graph_neighbors_count(comm, indegree, outdegree, weighted); if (MPI_SUCCESS != res) { printf("MPI Error in MPI_Dist_graph_neighbors_count() (%i)\n", res); return res; } } break; case MPI_UNDEFINED: return NBC_INVALID_TOPOLOGY_COMM; break; default: return NBC_INVALID_PARAM; break; } return NBC_OK; }
JNIEXPORT jintArray JNICALL Java_mpi_GraphComm_getNeighbors( JNIEnv *env, jobject jthis, jlong comm, jint rank) { int maxNs; int rc = MPI_Graph_neighbors_count((MPI_Comm)comm, rank, &maxNs); if(ompi_java_exceptionCheck(env, rc)) return NULL; jintArray neighbors = (*env)->NewIntArray(env, maxNs); jint *jNeighbors; int *cNeighbors; ompi_java_getIntArray(env, neighbors, &jNeighbors, &cNeighbors); rc = MPI_Graph_neighbors((MPI_Comm)comm, rank, maxNs, cNeighbors); ompi_java_exceptionCheck(env, rc); ompi_java_releaseIntArray(env, neighbors, jNeighbors, cNeighbors); return neighbors; }
static int create_proclists_from_mpi_comm_topology(MPI_Comm comm, int rank, int *nsend_procs, int **send_procs, int *nrecv_procs, int **recv_procs) { int status; int n, i; MPI_Topo_test(comm, &status); switch (status) { case MPI_CART: MPI_Cartdim_get(comm, &n); *nsend_procs = *nrecv_procs = 2 * n; *send_procs = *recv_procs = z_alloc(2 * n, sizeof(int)); for (i = 0; i < n; ++i) MPI_Cart_shift(comm, i, -1, &(*send_procs)[2 * i + 1], &(*send_procs)[2 * i + 0]); break; case MPI_GRAPH: MPI_Graph_neighbors_count(comm, rank, &n); *nsend_procs = *nrecv_procs = n; *send_procs = *recv_procs = z_alloc(n, sizeof(int)); MPI_Graph_neighbors(comm, rank, n, *send_procs); break; #if MPI_VERSION >= 2 && MPI_SUBVERSION >= 2 case MPI_DIST_GRAPH: MPI_Dist_graph_neighbors_count(comm, nrecv_procs, nsend_procs, &n); *send_procs = z_alloc(*nsend_procs + *nrecv_procs, sizeof(int)); *recv_procs = *send_procs + *nsend_procs; MPI_Dist_graph_neighbors(comm, *nrecv_procs, *recv_procs, MPI_UNWEIGHTED, *nsend_procs, *send_procs, MPI_UNWEIGHTED); break; #endif default: return 0; } return 1; }
FORT_DLL_SPEC void FORT_CALL mpi_graph_neighbors_count_ ( MPI_Fint *v1, MPI_Fint *v2, MPI_Fint *v3, MPI_Fint *ierr ){ *ierr = MPI_Graph_neighbors_count( (MPI_Comm)(*v1), (int)*v2, v3 ); }
int main(int argc, char *argv[]) { srand(time(NULL)); MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &_numprocs); MPI_Comm_rank(MPI_COMM_WORLD, &_rank); if(create_graph() != 0) { printf("This program needs 6 nodes.\n"); return 1; } int running = 1; //i iterator, neighbors - tabs of my neighbors int i, rank, neighbor_count, *neighbors; int participated = 0; int father = -1; int next_recv; MPI_Comm_rank(graph_comm, &rank); MPI_Graph_neighbors_count(graph_comm, rank, &neighbor_count); neighbors = malloc (neighbor_count * sizeof(int)); MPI_Graph_neighbors(graph_comm, rank, neighbor_count, neighbors); printf("node %d : start ! my neighbors : ", _rank); for(i=0; i<neighbor_count;i++){ printf("%d ", neighbors[i]); } printf("\n"); if(_rank == 0){ printf("******************start algorithm***********************\n"); participated = 1; next_recv=pick_recv(neighbors, neighbor_count); printf("Master %d : send tag : forward, to node %d\n", _rank, next_recv); MPI_Send(NULL, 0, MPI_INT, next_recv, FORWARD, graph_comm); } while (running){ MPI_Recv(NULL, 0, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, graph_comm, &status); // this printf is a control to see all messages received. //printf("node %d receive message tag : %s from node %d\n", _rank, (status.MPI_TAG==FORWARD?"forward":"return"), status.MPI_SOURCE); switch((int)status.MPI_TAG){ case FORWARD: neighbor_count = delete_source(neighbors, neighbor_count, status.MPI_SOURCE); if (participated==0&&neighbor_count!=0){ father=status.MPI_SOURCE; participated=1; printf("node %d : my neighbors : ", _rank); for(i=0; i<neighbor_count;i++){ printf("%d ", neighbors[i]); } printf("\n"); next_recv = pick_recv(neighbors, neighbor_count); printf("node %d : send tag : forward, to node %d\n", _rank, next_recv); MPI_Send(NULL, 0, MPI_INT, next_recv, FORWARD, graph_comm); } else { printf("node %d : send tag : return, to node %d\n", _rank, status.MPI_SOURCE); MPI_Send(NULL, 0, MPI_INT, status.MPI_SOURCE, END_RETURN, graph_comm); if(participated==0){ running=0; } } break; case END_RETURN: neighbor_count = delete_source(neighbors, neighbor_count, status.MPI_SOURCE); if (neighbor_count==0){ if(father==-1){ printf("Master : End of programm !\n"); } else { printf("node %d : send tag : return, to node %d\n", _rank, father); MPI_Send(NULL, 0, MPI_INT, father, END_RETURN, graph_comm); } participated=0; running=0; } else { next_recv = pick_recv(neighbors, neighbor_count); printf("node %d : send tag : forward, to node %d\n", _rank, next_recv); MPI_Send(NULL, 0, MPI_INT, next_recv, FORWARD, graph_comm); } break; } } printf("node %d : end of work\n", _rank); MPI_Finalize(); }
int main(int argc, char** argv){ int numberOfNodes = 9; int nodesIndex[] = { 3, 7, 9, 12, 16, 22, 25, 28, 30 }; int edges[] = { 1, 2, 5, 0, 3, 4, 5, 0, 3, 1, 2, 4, 1, 3, 5, 6, 0, 1, 4, 6, 7, 8, 4, 5, 7, 5, 6, 8, 5, 7 }; int reorder = 0; int rank, size; int neighborsCount; int *neighbors; int tag = 99; int parentRank = 1, parent = -1; char message[8]; MPI_Comm graph; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Graph_create(MPI_COMM_WORLD, numberOfNodes, nodesIndex, edges, reorder, &graph); MPI_Graph_neighbors_count(graph, rank, &neighborsCount); neighbors = (int*) malloc(neighborsCount * sizeof(int)); MPI_Graph_neighbors(graph, rank, neighborsCount, neighbors); int i = 0, other = 0, children = 0; /* case of receiving no message: if pi == pr and parent == NULL then parent = pi send <M> to all neighbors */ if(rank == parentRank && parent == -1) { parent = rank; strcpy(message, "message"); for(i = 0; i< neighborsCount; i++) { MPI_Send(message, strlen(message) + 1, MPI_CHAR, neighbors[i], tag, graph); printf("process %d sent \"message\" neighbor %d \n", rank, neighbors[i]); } } int flag = 1; while(flag) { MPI_Recv(message, 8, MPI_CHAR, MPI_ANY_SOURCE, tag, graph, &status); switch(message[0]) { case 'm': /* case of receiving <M> from pj: if parent == NULL then parent = pj send <parent> to parent send <M> to all neighbors, except parent */ if (parent == -1) { parent = status.MPI_SOURCE; strcpy(message, "parent"); MPI_Send(message, strlen(message) + 1, MPI_CHAR, parent, tag, graph); printf("process %d sent \"parent\" neighbor %d\n", rank, parent); strcpy(message, "message"); for (i = 0; i < neighborsCount; i++) { if (neighbors[i] != parent) { MPI_Send(message, strlen(message) + 1, MPI_CHAR, neighbors[i], tag, graph); printf("process %d sent \"message\" neighbor %d\n",rank, neighbors[i]); } } } else { /* else sent <already> to pj */ strcpy(message, "already"); MPI_Send(message, strlen(message) + 1, MPI_CHAR,status.MPI_SOURCE, tag, graph); printf("process %d sent \"already\" neighbor %d\n",rank, status.MPI_SOURCE); } break; case 'p': /* case of receiving <parent> from pj: add pj to children if children U other contains all neighbors, except parent then terminate */ children++; if ((neighborsCount - 1) == other + children) { printf(" process %d parent: %d\n", rank,parent); flag = 0; } break; case 'a': /* case of receiving <already> from pj: add pj to other if children U other contains all neighbors, except parent then terminate */ other++; if ((neighborsCount - 1) == other + children) { printf(" process %d parent: %d\n", rank,parent); flag = 0; } break; } MPI_Barrier(graph); } printf("terminate %d", rank); MPI_Finalize(); return 0; }