/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ /* * (C) 2008 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */ /* * This program was sent in as an example that did not perform as expected. * The program has a bug in that it is sending 3 characters but receiving * three integers, which is not a valid MPI program (the type signatures * must match). However, a good MPI implementation will handle this * gracefully, which is why this test is included in the error directory */ #include #include #include #include "mpi.h" #include "mpitest.h" #define BUFSIZE 128 #define FAIL_ERROR 123 #define RESFAIL_ERROR 123 #define INTERNAL_ERROR 123 void if_error(const char *function, const char *data, int ret); void if_error(const char *function, const char *data, int ret) { if (ret == 0) return; if (data) printf("%s for %s returned %d (%#x)\n", function, data, ret, ret); else printf("%s returned %d (%#x)\n", function, ret, ret); exit(INTERNAL_ERROR); } int main(int argc, char *argv[]) { int ret, errs = 0; char *src, *sendrec; int bufsize = BUFSIZE; int myrank, nprocs; int i; MPI_Status status; int small_non_contig_struct_count = 3; int small_non_contig_struct_blocklens[] = { 1, 1, 1 }; MPI_Aint small_non_contig_struct_disps[] = { 0, 2, 4 }; MPI_Datatype small_non_contig_struct_types[] = { MPI_CHAR, MPI_CHAR, MPI_CHAR }; MPI_Datatype small_non_contig_struct_type; int contig_indexed_count = 3; int contig_indexed_blocklens[] = { 1, 2, 1 }; int contig_indexed_indices[] = { 4, 8, 16 }; int contig_indexed_inner_type = MPI_INT; int contig_indexed_type; MTest_Init(&argc, &argv); ret = MPI_Comm_rank(MPI_COMM_WORLD, &myrank); ret = MPI_Comm_size(MPI_COMM_WORLD, &nprocs); if (nprocs < 2) { printf("Need at least 2 procs\n"); exit(RESFAIL_ERROR); } ret = MPI_Type_struct(small_non_contig_struct_count, small_non_contig_struct_blocklens, small_non_contig_struct_disps, small_non_contig_struct_types, &small_non_contig_struct_type); if_error("MPI_Type_struct", "small_non_contig_struct_type", ret); ret = MPI_Type_commit(&small_non_contig_struct_type); if_error("MPI_Type_commit", "small_non_contig_struct_type", ret); ret = MPI_Type_indexed(contig_indexed_count, contig_indexed_blocklens, contig_indexed_indices, contig_indexed_inner_type, &contig_indexed_type); if_error("MPI_Type_indexed", "contig_indexed_type", ret); ret = MPI_Type_commit(&contig_indexed_type); if_error("MPI_Type_commit", "contig_indexed_type", ret); ret = MPI_Alloc_mem(bufsize, MPI_INFO_NULL, &src); if (ret != 0) { printf("MPI_Alloc_mem src = #%x\n", ret); exit(INTERNAL_ERROR); } ret = MPI_Alloc_mem(bufsize, MPI_INFO_NULL, &sendrec); if (ret != 0) { printf("MPI_Alloc_mem sendrec buf = #%x\n", ret); exit(INTERNAL_ERROR); } for (i = 0; i < bufsize; i++) { src[i] = (char) i + 1; } memset(sendrec, 0, bufsize); MPI_Barrier(MPI_COMM_WORLD); if (myrank == 1) { MPI_Send(src, 1, small_non_contig_struct_type, 0, 0xabc, MPI_COMM_WORLD); } else { MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN); ret = MPI_Recv(sendrec, 1, contig_indexed_type, 1, 0xabc, MPI_COMM_WORLD, &status); if (ret == MPI_SUCCESS) { printf("MPI_Recv succeeded with non-matching datatype signature\n"); errs++; } } MPI_Barrier(MPI_COMM_WORLD); MPI_Type_free(&small_non_contig_struct_type); MPI_Type_free(&contig_indexed_type); MPI_Free_mem(src); MPI_Free_mem(sendrec); MTest_Finalize(errs); MPI_Finalize(); return 0; }