00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "ampiimpl.h"
00010 #include "tcharm.h"
00011 #include "ampiEvents.h"
00012 #include "ampiProjections.h"
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00060
00062
00063 #ifndef MAX
00064 int MAX(int a, int b){
00065 if(a>b)
00066 return a;
00067 else
00068 return b;
00069 }
00070 #endif
00071
00072 #if 0
00073 int MPI_Pack_size(int incount, MPI_Datatype type, MPI_Comm comm, int *size)
00074 {
00075 CkDDT_DataType *ddt = getAmpiInstance(comm)->getDDT()->getType(type);
00076 int typesize = ddt->getSize();
00077 *size = incount * typesize;
00078 return MPI_SUCCESS;
00079 }
00080 #endif
00081
00082
00083
00084
00085 void MPICH_Localcopy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
00086 void *recvbuf, int recvcount, MPI_Datatype recvtype)
00087 {
00088 int rank;
00089
00090 AMPI_Comm_rank (MPI_COMM_WORLD, &rank);
00091 AMPI_Sendrecv ( sendbuf, sendcount, sendtype,
00092 rank, MPI_ATA_TAG,
00093 recvbuf, recvcount, recvtype,
00094 rank, MPI_ATA_TAG,
00095 MPI_COMM_WORLD, MPI_STATUS_IGNORE);
00096 }
00097
00098
00099 inline void MPID_Datatype_get_extent_macro(MPI_Datatype &type, MPI_Aint &extent){
00100 CkDDT_DataType *ddt = getAmpiInstance(MPI_COMM_WORLD)->getDDT()->getType(type);
00101 extent = ddt->getExtent();
00102 }
00103
00104 inline void MPID_Datatype_get_size_macro(MPI_Datatype &type, MPI_Aint &size){
00105 CkDDT_DataType *ddt = getAmpiInstance(MPI_COMM_WORLD)->getDDT()->getType(type);
00106 size = ddt->getSize();
00107 }
00108
00109
00111
00113
00114
00115
00116
00117
00118
00119 int MPICH_AlltoAll_long(
00120 void *sendbuf,
00121 int sendcount,
00122 MPI_Datatype sendtype,
00123 void *recvbuf,
00124 int recvcount,
00125 MPI_Datatype recvtype,
00126 MPI_Comm comm )
00127 {
00128
00129 int comm_size, i, pof2;
00130 MPI_Aint sendtype_extent, recvtype_extent;
00131
00132 int mpi_errno=MPI_SUCCESS, src, dst, rank, nbytes;
00133 MPI_Status status;
00134 int sendtype_size;
00135
00136 if (sendcount == 0) return MPI_SUCCESS;
00137
00138 MPI_Comm_rank (MPI_COMM_WORLD, &rank);
00139 MPI_Comm_size (MPI_COMM_WORLD, &comm_size);
00140
00141
00142
00143 MPID_Datatype_get_extent_macro(recvtype, recvtype_extent);
00144 MPID_Datatype_get_extent_macro(sendtype, sendtype_extent);
00145
00146 MPID_Datatype_get_size_macro(sendtype, sendtype_size);
00147 nbytes = sendtype_size * sendcount;
00148
00149
00150
00151 MPICH_Localcopy(((char *)sendbuf +
00152 rank*sendcount*sendtype_extent),
00153 sendcount, sendtype,
00154 ((char *)recvbuf +
00155 rank*recvcount*recvtype_extent),
00156 recvcount, recvtype);
00157
00158
00159
00160 i = 1;
00161 while (i < comm_size)
00162 i *= 2;
00163 if (i == comm_size)
00164 pof2 = 1;
00165 else
00166 pof2 = 0;
00167
00168
00169 for (i=1; i<comm_size; i++) {
00170 if (pof2 == 1) {
00171
00172 src = dst = rank ^ i;
00173 }
00174 else {
00175 src = (rank - i + comm_size) % comm_size;
00176 dst = (rank + i) % comm_size;
00177 }
00178
00179 mpi_errno = AMPI_Sendrecv(((char *)sendbuf +
00180 dst*sendcount*sendtype_extent),
00181 sendcount, sendtype, dst,
00182 MPI_ATA_TAG,
00183 ((char *)recvbuf +
00184 src*recvcount*recvtype_extent),
00185 recvcount, recvtype, src,
00186 MPI_ATA_TAG, comm, &status);
00187 }
00188
00189 return (mpi_errno);
00190 }
00191
00192
00194
00196
00197 #if 0
00198 int MPICH_AlltoAll_short(
00199 void *sendbuf,
00200 int sendcount,
00201 MPI_Datatype sendtype,
00202 void *recvbuf,
00203 int recvcount,
00204 MPI_Datatype recvtype,
00205 MPI_Comm comm )
00206 {
00207
00208 int comm_size, i, pof2;
00209 MPI_Aint sendtype_extent, recvtype_extent;
00210
00211 int mpi_errno=MPI_SUCCESS, src, dst, rank, nbytes;
00212 MPI_Status status;
00213 void *tmp_buf;
00214 int sendtype_size, pack_size, block, position, *displs, count;
00215
00216 MPI_Datatype newtype;
00217 MPI_Aint recvtype_true_extent, recvbuf_extent, recvtype_true_lb;
00218
00219
00220 if (sendcount == 0) return MPI_SUCCESS;
00221
00222 MPI_Comm_rank (MPI_COMM_WORLD, &rank);
00223 MPI_Comm_size (MPI_COMM_WORLD, &comm_size);
00224
00225
00226 MPID_Datatype_get_extent_macro(recvtype, recvtype_extent);
00227 MPID_Datatype_get_extent_macro(sendtype, sendtype_extent);
00228
00229 MPID_Datatype_get_size_macro(sendtype, sendtype_size);
00230 nbytes = sendtype_size * sendcount;
00231
00232
00233
00234
00235
00236 MPI_Pack_size(recvcount*comm_size, recvtype, comm, &pack_size);
00237 tmp_buf = malloc(pack_size);
00238 CkAssert(tmp_buf);
00239
00240
00241
00242 MPICH_Localcopy((char *) sendbuf + rank*sendcount*sendtype_extent,
00243 (comm_size - rank)*sendcount, sendtype, recvbuf,
00244 (comm_size - rank)*recvcount, recvtype);
00245
00246 MPICH_Localcopy(sendbuf, rank*sendcount, sendtype,
00247 (char *) recvbuf + (comm_size-rank)*recvcount*recvtype_extent,
00248 rank*recvcount, recvtype);
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 displs = (int*)malloc(comm_size * sizeof(int));
00261 CkAssert(displs);
00262
00263
00264 pof2 = 1;
00265 while (pof2 < comm_size) {
00266 dst = (rank + pof2) % comm_size;
00267 src = (rank - pof2 + comm_size) % comm_size;
00268
00269
00270
00271
00272 count = 0;
00273 for (block=1; block<comm_size; block++) {
00274 if (block & pof2) {
00275 displs[count] = block * recvcount;
00276 count++;
00277 }
00278 }
00279
00280 mpi_errno = MPI_Type_create_indexed_block(count, recvcount, displs, recvtype, &newtype);
00281
00282 if (mpi_errno)
00283 return mpi_errno;
00284
00285 mpi_errno = MPI_Type_commit(&newtype);
00286
00287 if (mpi_errno)
00288 return mpi_errno;
00289
00290 position = 0;
00291 mpi_errno = MPI_Pack(recvbuf, 1, newtype, tmp_buf, pack_size,
00292 &position, comm);
00293
00294 mpi_errno = AMPI_Sendrecv(tmp_buf, position, MPI_PACKED, dst,
00295 MPI_ATA_TAG, recvbuf, 1, newtype,
00296 src, MPI_ATA_TAG, comm,
00297 MPI_STATUS_IGNORE);
00298
00299 if (mpi_errno)
00300 return mpi_errno;
00301
00302
00303 mpi_errno = MPI_Type_free(&newtype);
00304
00305 if (mpi_errno)
00306 return mpi_errno;
00307
00308 pof2 *= 2;
00309 }
00310
00311 free(displs);
00312 free(tmp_buf);
00313
00314
00315
00316
00317
00318 mpi_errno = MPI_Type_get_true_extent(recvtype, &recvtype_true_lb,
00319 &recvtype_true_extent);
00320
00321 if (mpi_errno)
00322 return mpi_errno;
00323
00324 recvbuf_extent = recvcount * comm_size *
00325 (MAX(recvtype_true_extent, recvtype_extent));
00326 tmp_buf = malloc(recvbuf_extent);
00327 CkAssert(tmp_buf);
00328
00329
00330 tmp_buf = (void *)((char*)tmp_buf - recvtype_true_lb);
00331
00332 MPICH_Localcopy((char *) recvbuf + (rank+1)*recvcount*recvtype_extent,
00333 (comm_size - rank - 1)*recvcount, recvtype, tmp_buf,
00334 (comm_size - rank - 1)*recvcount, recvtype);
00335
00336 MPICH_Localcopy(recvbuf, (rank+1)*recvcount, recvtype,
00337 (char *) tmp_buf + (comm_size-rank-1)*recvcount*recvtype_extent,
00338 (rank+1)*recvcount, recvtype);
00339
00340
00341
00342
00343
00344 for (i=0; i<comm_size; i++)
00345 MPICH_Localcopy((char *) tmp_buf + i*recvcount*recvtype_extent,
00346 recvcount, recvtype,
00347 (char *) recvbuf + (comm_size-i-1)*recvcount*recvtype_extent,
00348 recvcount, recvtype);
00349
00350 free((char*)tmp_buf + recvtype_true_lb);
00351
00352 }
00353 #endif
00354
00356
00358
00359 int MPICH_AlltoAll_medium(
00360 void *sendbuf,
00361 int sendcount,
00362 MPI_Datatype sendtype,
00363 void *recvbuf,
00364 int recvcount,
00365 MPI_Datatype recvtype,
00366 MPI_Comm comm )
00367 {
00368
00369 int comm_size, i, pof2;
00370 MPI_Aint sendtype_extent, recvtype_extent;
00371
00372 int mpi_errno=MPI_SUCCESS, src, dst, rank, nbytes;
00373 MPI_Status status;
00374 int sendtype_size;
00375
00376 MPI_Request *reqarray;
00377 MPI_Status *starray;
00378
00379 if (sendcount == 0) return MPI_SUCCESS;
00380
00381 MPI_Comm_rank (MPI_COMM_WORLD, &rank);
00382 MPI_Comm_size (MPI_COMM_WORLD, &comm_size);
00383
00384
00385 MPID_Datatype_get_extent_macro(recvtype, recvtype_extent);
00386 MPID_Datatype_get_extent_macro(sendtype, sendtype_extent);
00387
00388 MPID_Datatype_get_size_macro(sendtype, sendtype_size);
00389 nbytes = sendtype_size * sendcount;
00390
00391
00392
00393 reqarray = (MPI_Request *) malloc(2*comm_size*sizeof(MPI_Request));
00394
00395 if (!reqarray)
00396 return MPI_ERR_OTHER;
00397
00398 starray = (MPI_Status *) malloc(2*comm_size*sizeof(MPI_Status));
00399 if (!starray)
00400 return MPI_ERR_OTHER;
00401
00402
00403 for ( i=0; i<comm_size; i++ ) {
00404 dst = (rank+i) % comm_size;
00405 mpi_errno = AMPI_Irecv((char *)recvbuf +
00406 dst*recvcount*recvtype_extent,
00407 recvcount, recvtype, dst,
00408 MPI_ATA_TAG, comm,
00409 &reqarray[i]);
00410
00411 if (mpi_errno)
00412 return MPI_ERR_OTHER;
00413 }
00414
00415 for ( i=0; i<comm_size; i++ ) {
00416 dst = (rank+i) % comm_size;
00417 mpi_errno = AMPI_Isend((char *)sendbuf +
00418 dst*sendcount*sendtype_extent,
00419 sendcount, sendtype, dst,
00420 MPI_ATA_TAG, comm,
00421 &reqarray[i+comm_size]);
00422 if (mpi_errno)
00423 return mpi_errno;
00424 }
00425
00426
00427 mpi_errno = AMPI_Waitall(2*comm_size,reqarray,starray);
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 free(starray);
00439 free(reqarray);
00440
00441 return mpi_errno;
00442 }
00443
00444
00445
00447
00449
00450