static void mpifake_pack_struct(void *dest, void *src, int num, MPI_Datatype dtype) { char *s; int *len; int *disp; MPI_Datatype *type; int extent = dtype->upper - dtype->lower; int blksize; int i, j; for (i=0; i<num; i++, src+=extent) { s = src; len = dtype->lengths; disp = dtype->disps; type = dtype->dtypes; for (j=0; j<dtype->count; j++, len++, disp++, type++) { blksize = *len * (*type)->size; if (blksize >0) { mpifake_pack(dest, s + *disp, *len, *type); dest += blksize; } } } }
static void mpifake_pack(void *dest, void *src, int count, MPI_Datatype dtype) { switch (dtype->format) { case LAM_DTSTRUCT: mpifake_pack_struct(dest, src, count, dtype); break; case LAM_DTCONTIG: mpifake_pack(dest, src, count * dtype->count, dtype->dtype); break; case LAM_DTVECTOR: mpifake_pack_hvector(dest, src, count, dtype, 1); break; case LAM_DTHVECTOR: mpifake_pack_hvector(dest, src, count, dtype, 0); break; default: memcpy((char *)dest, (char *)src, count *dtype->size); } }
static void mpifake_pack_hvector(void *_dest, void *_src, int num, MPI_Datatype dtype, int vflag) { char* dest = static_cast<char*>(_dest); char* src = static_cast<char*>(_src); MPI_Datatype subtype = dtype->dtype; char *s; int count = dtype->count; int stride = dtype->stride; int extent = dtype->upper - dtype->lower; int blksize = dtype->length * subtype->size; int i, j; if (vflag) { stride *= subtype->upper - subtype->lower; } for (i=0; i<num; i++, src += extent) { s = src; for (j=0; j<count; j++) { mpifake_pack(dest, s, dtype->length, dtype->dtype); dest += blksize; s += stride; } } }
int mpifake_sendrecv(void *s, int scount, MPI_Datatype sdtype, void *r, int rcount, MPI_Datatype rdtype) { char *packbuf; if (sdtype == rdtype) { if (scount > rcount) { fprintf(stderr, "MPI_Gather: scount > rcount\n"); errexit(); } else { mpifake_copy(s, r, &rcount, &rdtype); } } else { packbuf = malloc(scount * sdtype->size); mpifake_pack(packbuf, s, scount, sdtype); mpifake_unpack(r, packbuf, rcount, rdtype); free(packbuf); } return MPI_SUCCESS; }