X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/4263281a2286d2509215da95b78d72ad3cbbc6ed..6b0d7da249c3fd6b9ab682bdcdabdf6a26705140:/src/smpi/smpi_mpi.c diff --git a/src/smpi/smpi_mpi.c b/src/smpi/smpi_mpi.c index ed453021b5..79ad9bf43e 100644 --- a/src/smpi/smpi_mpi.c +++ b/src/smpi/smpi_mpi.c @@ -172,6 +172,10 @@ int SMPI_MPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag, return retval; } +int SMPI_MPI_Wait(MPI_Request *request, MPI_Status *status) { + return smpi_mpi_wait(*request, status); +} + int SMPI_MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm) { int retval = MPI_SUCCESS; @@ -199,6 +203,23 @@ int SMPI_MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Co return retval; } +// FIXME: should be in utilities +int smpi_compare_rankkeys(const void *a, const void *b); +int smpi_compare_rankkeys(const void *a, const void *b) { + int *x = (int *)a; + int *y = (int *)b; + + if (x[1] < y[1]) return -1; + + if (x[1] == y[1]) { + if (x[0] < y[0]) return -1; + if (x[0] == y[0]) return 0; + return 1; + } + + return 1; +} + // FIXME: needs to return null in event of MPI_UNDEFINED color... // FIXME: seriously, this isn't pretty int SMPI_MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *comm_out) @@ -218,79 +239,69 @@ int SMPI_MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *comm_out) rank = comm->index_to_rank_map[index]; if (0 == rank) { - int *colors = xbt_new(int, comm->size); - int *keys = xbt_new(int, comm->size); - int i, j, k; + int colormap[comm->size]; + int keymap[comm->size]; + int rankkeymap[comm->size * 2]; + int i, j; smpi_mpi_communicator_t tempcomm = NULL; int colortmp; int keycount; - int *keystmp = xbt_new(int, comm->size); - int *rankstmp = xbt_new(int, comm->size); - int tmpval; int indextmp; - colors[0] = color; - keys[0] = key; + colormap[0] = color; + keymap[0] = key; - // FIXME: not efficient + // FIXME: use scatter/gather or similar instead of individual comms for (i = 1; i < comm->size; i++) { - retval = smpi_create_request(colorkey, 2, MPI_INT, MPI_ANY_SOURCE, rank, MPI_ANY_TAG, comm, &request); + retval = smpi_create_request(colorkey, 2, MPI_INT, MPI_ANY_SOURCE, + rank, MPI_ANY_TAG, comm, &request); smpi_mpi_irecv(request); smpi_mpi_wait(request, &status); + colormap[status.MPI_SOURCE] = colorkey[0]; + keymap[status.MPI_SOURCE] = colorkey[1]; xbt_mallocator_release(smpi_global->request_mallocator, request); - colors[i] = colorkey[0]; - keys[i] = colorkey[1]; } for (i = 0; i < comm->size; i++) { - if (-1 == colors[i]) { + if (-1 == colormap[i]) { continue; } - colortmp = colors[i]; + colortmp = colormap[i]; keycount = 0; for (j = i; j < comm->size; j++) { - if(colortmp == colors[j]) { - colors[j] = -1; - keystmp[keycount] = keys[j]; - rankstmp[keycount] = j; + if(colortmp == colormap[j]) { + colormap[j] = -1; + rankkeymap[keycount * 2] = j; + rankkeymap[keycount * 2 + 1] = keymap[j]; keycount++; } } - if (0 < keycount) { - // FIXME: yes, mock me, bubble sort... - for (j = 0; j < keycount; j++) { - for (k = keycount - 1; k > j; k--) { - if (keystmp[k] < keystmp[k - 1]) { - tmpval = keystmp[k]; - keystmp[k] = keystmp[k - 1]; - keystmp[k - 1] = tmpval; - - tmpval = rankstmp[k]; - rankstmp[k] = rankstmp[k - 1]; - rankstmp[k - 1] = tmpval; - } - } - } - tempcomm = xbt_new(s_smpi_mpi_communicator_t, 1); - tempcomm->barrier_count = 0; - tempcomm->barrier_mutex = SIMIX_mutex_init(); - tempcomm->barrier_cond = SIMIX_cond_init(); - tempcomm->rank_to_index_map = xbt_new(int, keycount); - tempcomm->index_to_rank_map = xbt_new(int, smpi_global->host_count); - for (j = 0; j < smpi_global->host_count; j++) { - tempcomm->index_to_rank_map[j] = -1; - } - for (j = 0; j < keycount; j++) { - indextmp = comm->rank_to_index_map[rankstmp[j]]; - tempcomm->rank_to_index_map[j] = indextmp; - tempcomm->index_to_rank_map[indextmp] = j; - } - for (j = 0; j < keycount; j++) { - retval = smpi_create_request(&j, 1, MPI_INT, 0, rankstmp[j], 0, comm, &request); + qsort(rankkeymap, keycount, sizeof(int) * 2, &smpi_compare_rankkeys); + tempcomm = xbt_new(s_smpi_mpi_communicator_t, 1); + tempcomm->barrier_count = 0; + tempcomm->size = keycount; + tempcomm->barrier_mutex = SIMIX_mutex_init(); + tempcomm->barrier_cond = SIMIX_cond_init(); + tempcomm->rank_to_index_map = xbt_new(int, keycount); + tempcomm->index_to_rank_map = xbt_new(int, smpi_global->host_count); + for (j = 0; j < smpi_global->host_count; j++) { + tempcomm->index_to_rank_map[j] = -1; + } + for (j = 0; j < keycount; j++) { + indextmp = comm->rank_to_index_map[rankkeymap[j*2]]; + tempcomm->rank_to_index_map[j] = indextmp; + tempcomm->index_to_rank_map[indextmp] = j; + } + for (j = 0; j < keycount; j++) { + if (rankkeymap[j*2]) { + retval = smpi_create_request(&j, 1, MPI_INT, 0, + rankkeymap[j*2], 0, comm, &request); request->data = tempcomm; smpi_mpi_isend(request); smpi_mpi_wait(request, &status); xbt_mallocator_release(smpi_global->request_mallocator, request); + } else { + *comm_out = tempcomm; } } }