1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2013 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
12 static MPI_Datatype make_largexfer_type_struct(MPI_Offset nbytes)
14 int typechunk_size = 1024 * 1024; /* in bytes: TODO: figure out how big a
15 * chunk is really needed */
18 MPI_Datatype memtype, chunktype;
20 /* need to cook up a new datatype to accommodate large datatypes */
21 /* first pass: chunks of 1 MiB plus an additional remainder. Does require
22 * 8 byte MPI_Aint, which should have been checked for earlier */
24 chunk_count = nbytes / typechunk_size;
25 remainder = nbytes % typechunk_size;
26 MPI_Type_contiguous(typechunk_size, MPI_BYTE, &chunktype);
27 MPI_Type_commit(&chunktype);
29 /* a zero remainder means we can just count contigs */
31 MPI_Type_contiguous(chunk_count, chunktype, &memtype);
32 MPI_Type_free(&chunktype);
35 if (sizeof(MPI_Aint) <= sizeof(int)) {
36 return MPI_DATATYPE_NULL;
38 /* struct type: some number of chunks plus remaining bytes tacked
40 int lens[] = { chunk_count, remainder };
41 MPI_Aint disp[] = { 0, (MPI_Aint) typechunk_size * (MPI_Aint) chunk_count };
42 MPI_Datatype types[] = { chunktype, MPI_BYTE };
44 MPI_Type_struct(2, lens, disp, types, &memtype);
45 MPI_Type_free(&chunktype);
47 MPI_Type_commit(&memtype);
51 static MPI_Datatype make_largexfer_type_hindexed(MPI_Offset nbytes)
54 int chunk_size = 1024 * 1024;
59 /* need to cook up a new datatype to accommodate large datatypes */
60 /* Does require 8 byte MPI_Aint, which should have been checked for earlier
63 if (sizeof(MPI_Aint) <= sizeof(int)) {
64 return MPI_DATATYPE_NULL;
67 /* ceiling division */
68 count = 1 + ((nbytes - 1) / chunk_size);
70 blocklens = calloc(count, sizeof(int));
71 disp = calloc(count, sizeof(MPI_Aint));
74 for (i = 0; i < (count - 1); i++) {
75 blocklens[i] = chunk_size;
76 disp[i] = (MPI_Aint) chunk_size *i;
78 blocklens[count - 1] = nbytes - ((MPI_Aint) chunk_size * i);
79 disp[count - 1] = (MPI_Aint) chunk_size *(count - 1);
81 MPI_Type_create_hindexed(count, blocklens, disp, MPI_BYTE, &memtype);
82 MPI_Type_commit(&memtype);
90 int testtype(MPI_Datatype type, MPI_Offset expected)
92 MPI_Count size, lb, extent;
94 MPI_Type_size_x(type, &size);
97 printf("ERROR: type size apparently overflowed integer\n");
101 if (size != expected) {
102 printf("reported type size %lld does not match expected %lld\n", size, expected);
106 MPI_Type_get_true_extent_x(type, &lb, &extent);
108 printf("ERROR: type should have lb of 0, reported %lld\n", lb);
112 if (extent != size) {
113 printf("ERROR: extent should match size, not %lld\n", extent);
120 int main(int argc, char **argv)
125 MPI_Init(&argc, &argv);
126 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
127 MPI_Comm_size(MPI_COMM_WORLD, &size);
130 MPI_Offset expected_sizes[NR_TYPES] = { 1024UL * 1024UL * 2400UL,
134 MPI_Datatype types[NR_TYPES];
136 /* a contig type, itself large, but does not need 8 byte aints */
137 types[0] = make_largexfer_type_struct(expected_sizes[0]);
138 /* struct with addresses out past 2 GiB */
139 types[1] = make_largexfer_type_struct(expected_sizes[1]);
140 /* similar, but with hindexed type */
141 types[2] = make_largexfer_type_hindexed(expected_sizes[2]);
143 for (i = 0; i < NR_TYPES; i++) {
144 if (types[i] != MPI_DATATYPE_NULL) {
145 nerrors += testtype(types[i], expected_sizes[i]);
146 MPI_Type_free(&(types[i]));
153 printf("found %d errors\n", nerrors);
156 printf(" No errors\n");