George, Thanks. I've confirmed your patch. I wrote a simple program to test your patch and no problems are found. The test program is attached to this mail.
Regards, KAWASHIMA Takahiro > Takahiro, > > Please find below another patch, this time hopefully fixing all issues. The > problem with my original patch and with yours was that they try to address > the packing of the data representation without fixing the computation of the > required length. As a result the length on the packer and unpacker differs > and the unpacking of the subsequent data is done from a wrong location. > > I changed the code to force the preparation of the packed data representation > before returning the length the first time. This way we can compute exactly > how many bytes we need, including the potential alignment requirements. As a > result the amount on both sides (the packer and the unpacker) are now > identical, and the entire process works flawlessly (or so I hope). > > Let me know if you still notice issues with this patch. I'll push the > tomorrow in the trunk, so it can soak for a few days before propagation to > the branches.
#include <stdint.h> #include <stdio.h> #include <string.h> #include <mpi.h> static MPI_Datatype types[100]; static MPI_Win win; static int obuf[1], tbuf[100]; static void do_put(int expected, int index, char *description) { int i; for (i = 1; types[i] != MPI_DATATYPE_NULL; i++); i--; if (i != 0) { MPI_Type_commit(&types[i]); } memset(tbuf, 0, sizeof(tbuf)); MPI_Win_fence(0, win); MPI_Put(obuf, 1, types[0], 0, 0, 1, types[i], win); MPI_Win_fence(0, win); if (tbuf[index] != expected) { printf("NG %s (expected: %d, actual: %d, index: %d)\n", description, expected, tbuf[index], index); } else { printf("OK %s\n", description); } for (i = 1; types[i] != MPI_DATATYPE_NULL; i++) { MPI_Type_free(&types[i]); } } int main(int argc, char *argv[]) { int i; int displs[] = {1}; int blens[] = {1}; types[0] = MPI_INT; for (i = 1; i < sizeof(types) / sizeof(types[0]); i++) { types[i] = MPI_DATATYPE_NULL; } obuf[0] = 77; MPI_Init(&argc, &argv); MPI_Win_create(tbuf, sizeof(tbuf[0]), sizeof(tbuf) / sizeof(tbuf[0]), MPI_INFO_NULL, MPI_COMM_SELF, &win); do_put(77, 0, "predefined"); MPI_Type_dup(types[0], &types[1]); do_put(77, 0, "dup"); MPI_Type_contiguous(1, types[0], &types[1]); do_put(77, 0, "contiguous"); MPI_Type_vector(1, 1, 1, types[0], &types[1]); do_put(77, 0, "vector"); MPI_Type_indexed(1, blens, displs, types[0], &types[1]); do_put(77, 1, "indexed"); MPI_Type_contiguous(1, types[0], &types[1]); MPI_Type_dup(types[1], &types[2]); do_put(77, 0, "contiguous+dup"); MPI_Type_dup(types[0], &types[1]); MPI_Type_contiguous(1, types[1], &types[2]); do_put(77, 0, "dup+contiguous"); MPI_Type_indexed(1, blens, displs, types[0], &types[1]); MPI_Type_contiguous(1, types[1], &types[2]); do_put(77, 1, "indexed+contiguous"); MPI_Type_contiguous(1, types[0], &types[1]); MPI_Type_indexed(1, blens, displs, types[1], &types[2]); do_put(77, 1, "contiguous+indexed"); MPI_Type_contiguous(1, types[0], &types[1]); MPI_Type_dup(types[1], &types[2]); MPI_Type_contiguous(1, types[2], &types[3]); do_put(77, 0, "contiguous+dup+contiguous"); MPI_Type_dup(types[0], &types[1]); MPI_Type_contiguous(1, types[1], &types[2]); MPI_Type_dup(types[2], &types[3]); do_put(77, 0, "dup+contiguous+dup"); MPI_Type_dup(types[0], &types[1]); MPI_Type_dup(types[1], &types[2]); MPI_Type_dup(types[2], &types[3]); do_put(77, 0, "dup+dup+dup"); MPI_Type_indexed(1, blens, displs, types[0], &types[1]); MPI_Type_contiguous(1, types[1], &types[2]); MPI_Type_vector(1, 1, 1, types[2], &types[3]); do_put(77, 1, "indexed+contiguous+vector"); MPI_Type_dup(types[0], &types[1]); MPI_Type_contiguous(1, types[1], &types[2]); MPI_Type_dup(types[2], &types[3]); MPI_Type_dup(types[3], &types[4]); do_put(77, 0, "dup+contiguous+dup+dup"); MPI_Type_contiguous(1, types[0], &types[1]); MPI_Type_dup(types[1], &types[2]); MPI_Type_dup(types[2], &types[3]); MPI_Type_dup(types[3], &types[4]); do_put(77, 0, "contiguous+dup+dup+dup"); MPI_Type_dup(types[0], &types[1]); MPI_Type_dup(types[1], &types[2]); MPI_Type_dup(types[2], &types[3]); MPI_Type_contiguous(1, types[3], &types[4]); do_put(77, 0, "dup+dup+dup+contiguous"); MPI_Type_indexed(1, blens, displs, types[0], &types[1]); MPI_Type_dup(types[1], &types[2]); MPI_Type_dup(types[2], &types[3]); MPI_Type_contiguous(1, types[3], &types[4]); do_put(77, 1, "indexed+dup+dup+contiguous"); MPI_Type_indexed(1, blens, displs, types[0], &types[1]); MPI_Type_contiguous(1, types[1], &types[2]); MPI_Type_dup(types[2], &types[3]); MPI_Type_dup(types[3], &types[4]); do_put(77, 1, "indexed+contiguous+dup+dup"); MPI_Type_dup(types[0], &types[1]); MPI_Type_dup(types[1], &types[2]); MPI_Type_indexed(1, blens, displs, types[2], &types[3]); MPI_Type_contiguous(1, types[3], &types[4]); do_put(77, 1, "dup+dup+indexed+contiguous"); MPI_Win_free(&win); MPI_Finalize(); printf("finished\n"); return 0; }