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;
}

Reply via email to