Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Update comm, datatype from mpich trunk
[simgrid.git] / teshsuite / smpi / mpich3-test / datatype / large-count.c
1 /* -*- Mode: c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *  (C) 2012 by Argonne National Laboratory.
4  *      See COPYRIGHT in top-level directory.
5  */
6
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. */
10
11 #include <limits.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <mpi.h>
15
16 /* assert-like macro that bumps the err count and emits a message */
17 #define check(x_)                                                                 \
18     do {                                                                          \
19         if (!(x_)) {                                                              \
20             ++errs;                                                               \
21             if (errs < 10) {                                                      \
22                 fprintf(stderr, "check failed: (%s), line %d\n", #x_, __LINE__); \
23             }                                                                     \
24         }                                                                         \
25     } while (0)
26
27 int main(int argc, char *argv[])
28 {
29     int errs = 0;
30     int wrank, wsize;
31     int size, elements, count;
32     MPI_Aint lb, extent;
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;
39     MPI_Status status;
40
41     MPI_Init(&argc, &argv);
42     MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
43     MPI_Comm_size(MPI_COMM_WORLD, &wsize);
44
45     check(sizeof(MPI_Count) >= sizeof(int));
46     check(sizeof(MPI_Count) >= sizeof(MPI_Aint));
47     check(sizeof(MPI_Count) >= sizeof(MPI_Offset));
48
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));
54
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))
58         goto epilogue;
59
60     /* a very large type */
61     MPI_Type_contiguous(INT_MAX, MPI_CHAR, &imax_contig);
62     MPI_Type_commit(&imax_contig);
63
64     /* a small-ish contig */
65     MPI_Type_contiguous(4, MPI_INT, &four_ints);
66     MPI_Type_commit(&four_ints);
67
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);
74
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);
77
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);
81
82     /* MPI_Type_size */
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 */
91
92     /* MPI_Type_size_x */
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 */
101
102     /* MPI_Type_get_extent */
103     MPI_Type_get_extent(imax_contig, &lb, &extent);
104     check(lb == 0);
105     check(extent == INT_MAX);
106     MPI_Type_get_extent(four_ints, &lb, &extent);
107     check(lb == 0);
108     check(extent == 4*sizeof(int));
109     MPI_Type_get_extent(imx4i, &lb, &extent);
110     check(lb == 0);
111     if (sizeof(MPI_Aint) == sizeof(int))
112         check(extent == MPI_UNDEFINED);
113     else
114         check(extent == imx4i_true_extent);
115
116     MPI_Type_get_extent(imx4i_rsz, &lb, &extent);
117     check(lb == INT_MAX);
118     check(extent == -1024);
119
120     /* MPI_Type_get_extent_x */
121     MPI_Type_get_extent_x(imax_contig, &lb_x, &extent_x);
122     check(lb_x == 0);
123     check(extent_x == INT_MAX);
124     MPI_Type_get_extent_x(four_ints, &lb_x, &extent_x);
125     check(lb_x == 0);
126     check(extent_x == 4*sizeof(int));
127     MPI_Type_get_extent_x(imx4i, &lb_x, &extent_x);
128     check(lb_x == 0);
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);
133
134     /* MPI_Type_get_true_extent */
135     MPI_Type_get_true_extent(imax_contig, &lb, &extent);
136     check(lb == 0);
137     check(extent == INT_MAX);
138     MPI_Type_get_true_extent(four_ints, &lb, &extent);
139     check(lb == 0);
140     check(extent == 4*sizeof(int));
141     MPI_Type_get_true_extent(imx4i, &lb, &extent);
142     check(lb == 0);
143     if (sizeof(MPI_Aint) == sizeof(int))
144         check(extent == MPI_UNDEFINED);
145     else
146         check(extent == imx4i_true_extent);
147     MPI_Type_get_true_extent(imx4i_rsz, &lb, &extent);
148     check(lb == 0);
149     if (sizeof(MPI_Aint) == sizeof(int))
150         check(extent == MPI_UNDEFINED);
151     else
152         check(extent == imx4i_true_extent);
153
154     /* MPI_Type_get_true_extent_x */
155     MPI_Type_get_true_extent_x(imax_contig, &lb_x, &extent_x);
156     check(lb_x == 0);
157     check(extent_x == INT_MAX);
158     MPI_Type_get_true_extent_x(four_ints, &lb_x, &extent_x);
159     check(lb_x == 0);
160     check(extent_x == 4*sizeof(int));
161     MPI_Type_get_true_extent_x(imx4i, &lb_x, &extent_x);
162     check(lb_x == 0);
163     check(extent_x == imx4i_true_extent);
164     MPI_Type_get_true_extent_x(imx4i_rsz, &lb_x, &extent_x);
165     check(lb_x == 0);
166     check(extent_x == imx4i_true_extent);
167
168
169     /* MPI_{Status_set_elements,Get_elements}{,_x} */
170
171     /* set simple */
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);
178     check(count == 10);
179
180     /* set_x simple */
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);
187     check(count == 10);
188
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
192      * clipping) */
193 #define check_set_elements(type_, elts_)                          \
194     do {                                                          \
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_));                         \
204             check(count == 1);                                    \
205         }                                                         \
206                                                                   \
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);                     \
214         }                                                         \
215         else {                                                    \
216             check(elements == (elts_));                           \
217         }                                                         \
218         check(elements_x == (elts_));                             \
219         check(count == 1);                                        \
220     } while (0)                                                   \
221
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));
226
227 epilogue:
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);
232
233     MPI_Reduce((wrank == 0 ? MPI_IN_PLACE : &errs), &errs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
234     if (wrank == 0) {
235         if (errs) {
236             printf("found %d errors\n", errs);
237         }
238         else {
239             printf(" No errors\n");
240         }
241     }
242
243     MPI_Finalize();
244
245     return 0;
246 }