1 /* -*- Mode: c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
3 * (C) 2012 by Argonne National Laboratory.
4 * See COPYRIGHT in top-level directory.
7 /* This test checks for large count functionality ("MPI_Count") mandated by
8 * MPI-3, as well as behavior of corresponding pre-MPI-3 interfaces that now
9 * have better defined behavior when an "int" quantity would overflow. */
16 /* assert-like macro that bumps the err count and emits a message */
22 fprintf(stderr, "check failed: (%s), line %d\n", #x_, __LINE__); \
27 /* Abort when using unimplemented functions. Currently, it should not happen,
28 * since sizeof(MPI_Count) == sizeof(int), but it avoids compile errors about
29 * undefined functions. */
30 #define err_unimpl(func) do { \
31 fprintf(stderr, "ERROR: %s is not implemented\n", #func); \
35 #define MPI_Type_size_x(a,b) err_unimpl(MPI_Type_size_x)
36 #define MPI_Type_get_extent_x(a,b,c) err_unimpl(MPI_Type_get_extent_x)
37 #define MPI_Type_get_true_extent_x(a,b,c) err_unimpl(MPI_Type_get_true_extent_x)
38 #define MPI_Get_elements_x(a,b,c) err_unimpl(MPI_Get_elements_x)
39 #define MPI_Status_set_elements_x(a,b,c) err_unimpl(MPI_Status_set_elements_x)
41 int main(int argc, char *argv[])
45 int size, elements, count;
47 MPI_Count size_x, lb_x, extent_x, elements_x;
48 double imx4i_true_extent;
49 MPI_Datatype imax_contig = MPI_DATATYPE_NULL;
50 MPI_Datatype four_ints = MPI_DATATYPE_NULL;
51 MPI_Datatype imx4i = MPI_DATATYPE_NULL;
52 MPI_Datatype imx4i_rsz = MPI_DATATYPE_NULL;
55 MPI_Init(&argc, &argv);
56 MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
57 MPI_Comm_size(MPI_COMM_WORLD, &wsize);
59 check(sizeof(MPI_Count) >= sizeof(int));
60 check(sizeof(MPI_Count) >= sizeof(MPI_Aint));
61 check(sizeof(MPI_Count) >= sizeof(MPI_Offset));
63 /* the following two checks aren't explicitly required by the standard, but
64 * it's hard to imagine a world without them holding true and so most of the
65 * subsequent code probably depends on them to some degree */
66 check(sizeof(MPI_Aint) >= sizeof(int));
67 check(sizeof(MPI_Offset) >= sizeof(int));
69 /* not much point in checking for integer overflow cases if MPI_Count is
70 * only as large as an int */
71 if (sizeof(MPI_Count) == sizeof(int))
74 /* a very large type */
75 MPI_Type_contiguous(INT_MAX, MPI_CHAR, &imax_contig);
76 MPI_Type_commit(&imax_contig);
78 /* a small-ish contig */
79 MPI_Type_contiguous(4, MPI_INT, &four_ints);
80 MPI_Type_commit(&four_ints);
82 /* a type with size>INT_MAX */
83 MPI_Type_vector(INT_MAX/2, 1, 3, four_ints, &imx4i);
84 MPI_Type_commit(&imx4i);
85 /* don't forget, ub for dtype w/ stride doesn't include any holes at the end
86 * of the type, hence the more complicated calculation below */
87 imx4i_true_extent = 3LL*4LL*sizeof(int)*((INT_MAX/2)-1) + 4LL*sizeof(int);
89 /* sanity check that the MPI_COUNT predefined named datatype exists */
90 MPI_Send(&imx4i_true_extent, 1, MPI_COUNT, MPI_PROC_NULL, 0, MPI_COMM_SELF);
92 /* the same oversized type but with goofy extents */
93 MPI_Type_create_resized(imx4i, /*lb=*/INT_MAX, /*extent=*/-1024, &imx4i_rsz);
94 MPI_Type_commit(&imx4i_rsz);
97 MPI_Type_size(imax_contig, &size);
98 check(size == INT_MAX);
99 MPI_Type_size(four_ints, &size);
100 check(size == 4*sizeof(int));
101 MPI_Type_size(imx4i, &size);
102 check(size == MPI_UNDEFINED); /* should overflow an int */
103 MPI_Type_size(imx4i_rsz, &size);
104 check(size == MPI_UNDEFINED); /* should overflow an int */
106 /* MPI_Type_size_x */
107 MPI_Type_size_x(imax_contig, &size_x);
108 check(size_x == INT_MAX);
109 MPI_Type_size_x(four_ints, &size_x);
110 check(size_x == 4*sizeof(int));
111 MPI_Type_size_x(imx4i, &size_x);
112 check(size_x == 4LL*sizeof(int)*(INT_MAX/2)); /* should overflow an int */
113 MPI_Type_size_x(imx4i_rsz, &size_x);
114 check(size_x == 4LL*sizeof(int)*(INT_MAX/2)); /* should overflow an int */
116 /* MPI_Type_get_extent */
117 MPI_Type_get_extent(imax_contig, &lb, &extent);
119 check(extent == INT_MAX);
120 MPI_Type_get_extent(four_ints, &lb, &extent);
122 check(extent == 4*sizeof(int));
123 MPI_Type_get_extent(imx4i, &lb, &extent);
125 if (sizeof(MPI_Aint) == sizeof(int))
126 check(extent == MPI_UNDEFINED);
128 check(extent == imx4i_true_extent);
130 MPI_Type_get_extent(imx4i_rsz, &lb, &extent);
131 check(lb == INT_MAX);
132 check(extent == -1024);
134 /* MPI_Type_get_extent_x */
135 MPI_Type_get_extent_x(imax_contig, &lb_x, &extent_x);
137 check(extent_x == INT_MAX);
138 MPI_Type_get_extent_x(four_ints, &lb_x, &extent_x);
140 check(extent_x == 4*sizeof(int));
141 MPI_Type_get_extent_x(imx4i, &lb_x, &extent_x);
143 check(extent_x == imx4i_true_extent);
144 MPI_Type_get_extent_x(imx4i_rsz, &lb_x, &extent_x);
145 check(lb_x == INT_MAX);
146 check(extent_x == -1024);
148 /* MPI_Type_get_true_extent */
149 MPI_Type_get_true_extent(imax_contig, &lb, &extent);
151 check(extent == INT_MAX);
152 MPI_Type_get_true_extent(four_ints, &lb, &extent);
154 check(extent == 4*sizeof(int));
155 MPI_Type_get_true_extent(imx4i, &lb, &extent);
157 if (sizeof(MPI_Aint) == sizeof(int))
158 check(extent == MPI_UNDEFINED);
160 check(extent == imx4i_true_extent);
161 MPI_Type_get_true_extent(imx4i_rsz, &lb, &extent);
163 if (sizeof(MPI_Aint) == sizeof(int))
164 check(extent == MPI_UNDEFINED);
166 check(extent == imx4i_true_extent);
168 /* MPI_Type_get_true_extent_x */
169 MPI_Type_get_true_extent_x(imax_contig, &lb_x, &extent_x);
171 check(extent_x == INT_MAX);
172 MPI_Type_get_true_extent_x(four_ints, &lb_x, &extent_x);
174 check(extent_x == 4*sizeof(int));
175 MPI_Type_get_true_extent_x(imx4i, &lb_x, &extent_x);
177 check(extent_x == imx4i_true_extent);
178 MPI_Type_get_true_extent_x(imx4i_rsz, &lb_x, &extent_x);
180 check(extent_x == imx4i_true_extent);
183 /* MPI_{Status_set_elements,Get_elements}{,_x} */
186 MPI_Status_set_elements(&status, MPI_INT, 10);
187 MPI_Get_elements(&status, MPI_INT, &elements);
188 MPI_Get_elements_x(&status, MPI_INT, &elements_x);
189 MPI_Get_count(&status, MPI_INT, &count);
190 check(elements == 10);
191 check(elements_x == 10);
195 MPI_Status_set_elements_x(&status, MPI_INT, 10);
196 MPI_Get_elements(&status, MPI_INT, &elements);
197 MPI_Get_elements_x(&status, MPI_INT, &elements_x);
198 MPI_Get_count(&status, MPI_INT, &count);
199 check(elements == 10);
200 check(elements_x == 10);
203 /* Sets elements corresponding to count=1 of the given MPI datatype, using
204 * set_elements and set_elements_x. Checks expected values are returned by
205 * get_elements, get_elements_x, and get_count (including MPI_UNDEFINED
207 #define check_set_elements(type_, elts_) \
209 elements = elements_x = count = 0xfeedface; \
210 /* can't use legacy "set" for large element counts */ \
211 if ((elts_) <= INT_MAX) { \
212 MPI_Status_set_elements(&status, (type_), 1); \
213 MPI_Get_elements(&status, (type_), &elements); \
214 MPI_Get_elements_x(&status, (type_), &elements_x); \
215 MPI_Get_count(&status, (type_), &count); \
216 check(elements == (elts_)); \
217 check(elements_x == (elts_)); \
221 elements = elements_x = count = 0xfeedface; \
222 MPI_Status_set_elements_x(&status, (type_), 1); \
223 MPI_Get_elements(&status, (type_), &elements); \
224 MPI_Get_elements_x(&status, (type_), &elements_x); \
225 MPI_Get_count(&status, (type_), &count); \
226 if ((elts_) > INT_MAX) { \
227 check(elements == MPI_UNDEFINED); \
230 check(elements == (elts_)); \
232 check(elements_x == (elts_)); \
236 check_set_elements(imax_contig, INT_MAX);
237 check_set_elements(four_ints, 4);
238 check_set_elements(imx4i, 4LL*(INT_MAX/2));
239 check_set_elements(imx4i_rsz, 4LL*(INT_MAX/2));
242 if (imax_contig != MPI_DATATYPE_NULL) MPI_Type_free(&imax_contig);
243 if (four_ints != MPI_DATATYPE_NULL) MPI_Type_free(&four_ints);
244 if (imx4i != MPI_DATATYPE_NULL) MPI_Type_free(&imx4i);
245 if (imx4i_rsz != MPI_DATATYPE_NULL) MPI_Type_free(&imx4i_rsz);
247 MPI_Reduce((wrank == 0 ? MPI_IN_PLACE : &errs), &errs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
250 printf("found %d errors\n", errs);
253 printf(" No errors\n");