/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ /* * (C) 2007 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */ /* a test to exercise very large extents: on most platforms with 32 bit * integers, we'd expect these tests to give unexpected values. On platforms * with 64 bit integers, these tests will be fine. On BlueGene we're not sure * yet :> */ #include #include #include #include #define CHECK(fn) {int errcode; errcode = (fn); if (errcode != MPI_SUCCESS) handle_error(errcode, NULL); } static void handle_error(int errcode, char *str) { char msg[MPI_MAX_ERROR_STRING]; int resultlen; MPI_Error_string(errcode, msg, &resultlen); fprintf(stderr, "%s: %s\n", str, msg); MPI_Abort(MPI_COMM_WORLD, 1); } static void typestats(MPI_Datatype type) { MPI_Aint lb, extent; MPI_Count size; MPI_Type_get_extent(type, &lb, &extent); MPI_Type_size_x(type, &size); printf("dtype %d: lb = %ld extent = %ld size = %ld...", type, (long) lb, (long) extent, size); } static int verify_type(char *filename, MPI_Datatype type, int64_t expected_extent, int do_coll) { int rank, canary; MPI_Count tsize; int compare = -1; int errs = 0, toterrs = 0; MPI_Status status; MPI_File fh; MPI_Comm_rank(MPI_COMM_WORLD, &rank); CHECK(MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh)); CHECK(MPI_File_set_view(fh, rank * sizeof(int), MPI_BYTE, type, "native", MPI_INFO_NULL)); MPI_Type_size_x(type, &tsize); canary = rank + 1000000; /* skip over first instance of type */ if (do_coll) { CHECK(MPI_File_write_at_all(fh, tsize, &canary, 1, MPI_INT, &status)); } else { CHECK(MPI_File_write_at(fh, tsize, &canary, 1, MPI_INT, &status)); } CHECK(MPI_File_set_view(fh, 0, MPI_INT, MPI_INT, "native", MPI_INFO_NULL)); if (do_coll) { CHECK(MPI_File_read_at_all(fh, expected_extent / sizeof(int) + rank, &compare, 1, MPI_INT, &status)); } else { CHECK(MPI_File_read_at(fh, expected_extent / sizeof(int) + rank, &compare, 1, MPI_INT, &status)); } if (compare != canary) errs = 1; MPI_Allreduce(&errs, &toterrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); MPI_File_close(&fh); if (toterrs) { printf("%d: got %d expected %d\n", rank, compare, canary); /* keep file if there's an error */ } else { if (rank == 0) MPI_File_delete(filename, MPI_INFO_NULL); } return (toterrs); } static int testtype(char *filename, MPI_Datatype type, int64_t expected_extent) { int rank, ret, errs = 0; int collective = 1, nocollective = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (!rank) typestats(type); ret = verify_type(filename, type, expected_extent, nocollective); if (ret) { errs++; fprintf(stderr, "type %d failed indep\n", type); } else if (!rank) printf("indep: OK "); ret = verify_type(filename, type, expected_extent, collective); if (ret) { errs++; fprintf(stderr, "type %d failed collective\n", type); } else if (!rank) printf("coll: OK\n"); return errs; } int main(int argc, char **argv) { int count = 2; int blocks[2]; int disps[2]; int ndims = 2; int sizes[2]; int subs[2]; int starts[2]; MPI_Datatype baseindex, indexed1G, indexed3G, indexed6G; MPI_Datatype subarray1G, subarray3G, subarray6G; int ret, rank; MPI_Init(&argc, &argv); if (argc != 2) { fprintf(stderr, "usage: %s \n", argv[0]); MPI_Abort(MPI_COMM_WORLD, 1); } MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* base type: 1MB indexed type of ints */ count = 2; blocks[0] = 1; disps[0] = 0; blocks[1] = 1; disps[1] = 1024 * 256 - 1; MPI_Type_indexed(count, blocks, disps, MPI_INT, &baseindex); /* simple case: 1GB extent */ MPI_Type_contiguous(1024, baseindex, &indexed1G); MPI_Type_commit(&indexed1G); /* a little trickier: 3Gb extent */ MPI_Type_contiguous(3072, baseindex, &indexed3G); MPI_Type_commit(&indexed3G); /* and finally 6GB extent */ MPI_Type_contiguous(6144, baseindex, &indexed6G); MPI_Type_commit(&indexed6G); /* TODO: * - add a darray test * - add a test with crazy extents */ sizes[0] = 1024 * 16; sizes[1] = 1024 * 16; subs[0] = subs[1] = 256; starts[0] = starts[1] = 0; MPI_Type_create_subarray(ndims, sizes, subs, starts, MPI_ORDER_C, MPI_INT, &subarray1G); MPI_Type_commit(&subarray1G); sizes[1] = 1024 * 16 * 3; MPI_Type_create_subarray(ndims, sizes, subs, starts, MPI_ORDER_C, MPI_INT, &subarray3G); MPI_Type_commit(&subarray3G); sizes[1] = 1024 * 16 * 6; MPI_Type_create_subarray(ndims, sizes, subs, starts, MPI_ORDER_C, MPI_INT, &subarray6G); MPI_Type_commit(&subarray6G); /* assume command line arguments make it out to all processes */ ret = testtype(argv[1], indexed1G, (int64_t) 1024 * 1024 * 1024); ret = testtype(argv[1], indexed3G, (int64_t) 1024 * 1024 * 1024 * 3); ret = testtype(argv[1], indexed6G, (int64_t) 1024 * 1024 * 1024 * 6); ret = testtype(argv[1], subarray1G, (int64_t) 1024 * 1024 * 1024); ret = testtype(argv[1], subarray3G, (int64_t) 1024 * 1024 * 1024 * 3); ret = testtype(argv[1], subarray6G, (int64_t) 1024 * 1024 * 1024 * 6); if (!ret && !rank) fprintf(stderr, " No Errors\n"); MPI_Finalize(); return (-ret); } /* * vim: ts=8 sts=4 sw=4 noexpandtab */