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 int main(int argc, char *argv[])
31 int size, elements, count;
33 MPI_Count size_x, lb_x, extent_x, elements_x;
34 MPI_Count imx4i_true_extent;
35 MPI_Datatype imax_contig = MPI_DATATYPE_NULL;
36 MPI_Datatype four_ints = MPI_DATATYPE_NULL;
37 MPI_Datatype imx4i = MPI_DATATYPE_NULL;
38 MPI_Datatype imx4i_rsz = MPI_DATATYPE_NULL;
41 MPI_Init(&argc, &argv);
42 MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
43 MPI_Comm_size(MPI_COMM_WORLD, &wsize);
45 check(sizeof(MPI_Count) >= sizeof(int));
46 check(sizeof(MPI_Count) >= sizeof(MPI_Aint));
47 check(sizeof(MPI_Count) >= sizeof(MPI_Offset));
49 /* the following two checks aren't explicitly required by the standard, but
50 * it's hard to imagine a world without them holding true and so most of the
51 * subsequent code probably depends on them to some degree */
52 check(sizeof(MPI_Aint) >= sizeof(int));
53 check(sizeof(MPI_Offset) >= sizeof(int));
55 /* not much point in checking for integer overflow cases if MPI_Count is
56 * only as large as an int */
57 if (sizeof(MPI_Count) == sizeof(int))
60 /* a very large type */
61 MPI_Type_contiguous(INT_MAX, MPI_CHAR, &imax_contig);
62 MPI_Type_commit(&imax_contig);
64 /* a small-ish contig */
65 MPI_Type_contiguous(4, MPI_INT, &four_ints);
66 MPI_Type_commit(&four_ints);
68 /* a type with size>INT_MAX */
69 MPI_Type_vector(INT_MAX/2, 1, 3, four_ints, &imx4i);
70 MPI_Type_commit(&imx4i);
71 /* don't forget, ub for dtype w/ stride doesn't include any holes at the end
72 * of the type, hence the more complicated calculation below */
73 imx4i_true_extent = 3LL*4LL*sizeof(int)*((INT_MAX/2)-1) + 4LL*sizeof(int);
75 /* sanity check that the MPI_COUNT predefined named datatype exists */
76 MPI_Send(&imx4i_true_extent, 1, MPI_COUNT, MPI_PROC_NULL, 0, MPI_COMM_SELF);
78 /* the same oversized type but with goofy extents */
79 MPI_Type_create_resized(imx4i, /*lb=*/INT_MAX, /*extent=*/-1024, &imx4i_rsz);
80 MPI_Type_commit(&imx4i_rsz);
83 MPI_Type_size(imax_contig, &size);
84 check(size == INT_MAX);
85 MPI_Type_size(four_ints, &size);
86 check(size == 4*sizeof(int));
87 MPI_Type_size(imx4i, &size);
88 check(size == MPI_UNDEFINED); /* should overflow an int */
89 MPI_Type_size(imx4i_rsz, &size);
90 check(size == MPI_UNDEFINED); /* should overflow an int */
93 MPI_Type_size_x(imax_contig, &size_x);
94 check(size_x == INT_MAX);
95 MPI_Type_size_x(four_ints, &size_x);
96 check(size_x == 4*sizeof(int));
97 MPI_Type_size_x(imx4i, &size_x);
98 check(size_x == 4LL*sizeof(int)*(INT_MAX/2)); /* should overflow an int */
99 MPI_Type_size_x(imx4i_rsz, &size_x);
100 check(size_x == 4LL*sizeof(int)*(INT_MAX/2)); /* should overflow an int */
102 /* MPI_Type_get_extent */
103 MPI_Type_get_extent(imax_contig, &lb, &extent);
105 check(extent == INT_MAX);
106 MPI_Type_get_extent(four_ints, &lb, &extent);
108 check(extent == 4*sizeof(int));
109 MPI_Type_get_extent(imx4i, &lb, &extent);
111 if (sizeof(MPI_Aint) == sizeof(int))
112 check(extent == MPI_UNDEFINED);
114 check(extent == imx4i_true_extent);
116 MPI_Type_get_extent(imx4i_rsz, &lb, &extent);
117 check(lb == INT_MAX);
118 check(extent == -1024);
120 /* MPI_Type_get_extent_x */
121 MPI_Type_get_extent_x(imax_contig, &lb_x, &extent_x);
123 check(extent_x == INT_MAX);
124 MPI_Type_get_extent_x(four_ints, &lb_x, &extent_x);
126 check(extent_x == 4*sizeof(int));
127 MPI_Type_get_extent_x(imx4i, &lb_x, &extent_x);
129 check(extent_x == imx4i_true_extent);
130 MPI_Type_get_extent_x(imx4i_rsz, &lb_x, &extent_x);
131 check(lb_x == INT_MAX);
132 check(extent_x == -1024);
134 /* MPI_Type_get_true_extent */
135 MPI_Type_get_true_extent(imax_contig, &lb, &extent);
137 check(extent == INT_MAX);
138 MPI_Type_get_true_extent(four_ints, &lb, &extent);
140 check(extent == 4*sizeof(int));
141 MPI_Type_get_true_extent(imx4i, &lb, &extent);
143 if (sizeof(MPI_Aint) == sizeof(int))
144 check(extent == MPI_UNDEFINED);
146 check(extent == imx4i_true_extent);
147 MPI_Type_get_true_extent(imx4i_rsz, &lb, &extent);
149 if (sizeof(MPI_Aint) == sizeof(int))
150 check(extent == MPI_UNDEFINED);
152 check(extent == imx4i_true_extent);
154 /* MPI_Type_get_true_extent_x */
155 MPI_Type_get_true_extent_x(imax_contig, &lb_x, &extent_x);
157 check(extent_x == INT_MAX);
158 MPI_Type_get_true_extent_x(four_ints, &lb_x, &extent_x);
160 check(extent_x == 4*sizeof(int));
161 MPI_Type_get_true_extent_x(imx4i, &lb_x, &extent_x);
163 check(extent_x == imx4i_true_extent);
164 MPI_Type_get_true_extent_x(imx4i_rsz, &lb_x, &extent_x);
166 check(extent_x == imx4i_true_extent);
169 /* MPI_{Status_set_elements,Get_elements}{,_x} */
172 MPI_Status_set_elements(&status, MPI_INT, 10);
173 MPI_Get_elements(&status, MPI_INT, &elements);
174 MPI_Get_elements_x(&status, MPI_INT, &elements_x);
175 MPI_Get_count(&status, MPI_INT, &count);
176 check(elements == 10);
177 check(elements_x == 10);
181 MPI_Status_set_elements_x(&status, MPI_INT, 10);
182 MPI_Get_elements(&status, MPI_INT, &elements);
183 MPI_Get_elements_x(&status, MPI_INT, &elements_x);
184 MPI_Get_count(&status, MPI_INT, &count);
185 check(elements == 10);
186 check(elements_x == 10);
189 /* Sets elements corresponding to count=1 of the given MPI datatype, using
190 * set_elements and set_elements_x. Checks expected values are returned by
191 * get_elements, get_elements_x, and get_count (including MPI_UNDEFINED
193 #define check_set_elements(type_, elts_) \
195 elements = elements_x = count = 0xfeedface; \
196 /* can't use legacy "set" for large element counts */ \
197 if ((elts_) <= INT_MAX) { \
198 MPI_Status_set_elements(&status, (type_), 1); \
199 MPI_Get_elements(&status, (type_), &elements); \
200 MPI_Get_elements_x(&status, (type_), &elements_x); \
201 MPI_Get_count(&status, (type_), &count); \
202 check(elements == (elts_)); \
203 check(elements_x == (elts_)); \
207 elements = elements_x = count = 0xfeedface; \
208 MPI_Status_set_elements_x(&status, (type_), 1); \
209 MPI_Get_elements(&status, (type_), &elements); \
210 MPI_Get_elements_x(&status, (type_), &elements_x); \
211 MPI_Get_count(&status, (type_), &count); \
212 if ((elts_) > INT_MAX) { \
213 check(elements == MPI_UNDEFINED); \
216 check(elements == (elts_)); \
218 check(elements_x == (elts_)); \
222 check_set_elements(imax_contig, INT_MAX);
223 check_set_elements(four_ints, 4);
224 check_set_elements(imx4i, 4LL*(INT_MAX/2));
225 check_set_elements(imx4i_rsz, 4LL*(INT_MAX/2));
228 if (imax_contig != MPI_DATATYPE_NULL) MPI_Type_free(&imax_contig);
229 if (four_ints != MPI_DATATYPE_NULL) MPI_Type_free(&four_ints);
230 if (imx4i != MPI_DATATYPE_NULL) MPI_Type_free(&imx4i);
231 if (imx4i_rsz != MPI_DATATYPE_NULL) MPI_Type_free(&imx4i_rsz);
233 MPI_Reduce((wrank == 0 ? MPI_IN_PLACE : &errs), &errs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
236 printf("found %d errors\n", errs);
239 printf(" No errors\n");