1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3  *
4  *  (C) 2003 by Argonne National Laboratory.
5  *      See COPYRIGHT in top-level directory.
6  */
7 #include "mpi.h"
8 #include "mpitestconf.h"
9 #include <stdio.h>
10 #include "mpitest.h"
11 
12 /*
13 static char MTEST_Descrip[] = "Test MPI_MINLOC operations on datatypes dupported by MPICH2";
14 */
15 
16 /*
17  * This test looks at the handling of char and types that  are not required
18  * integers (e.g., long long).  MPICH2 allows
19  * these as well.  A strict MPI test should not include this test.
20  *
21  * The rule on min loc is that if there is a tie in the value, the minimum
22  * rank is used (see 4.9.3 in the MPI-1 standard)
23  */
main(int argc,char * argv[])24 int main( int argc, char *argv[] )
25 {
26     int errs = 0;
27     int rank, size;
28     MPI_Comm      comm;
29 
30     MTest_Init( &argc, &argv );
31 
32     comm = MPI_COMM_WORLD;
33 
34     MPI_Comm_rank( comm, &rank );
35     MPI_Comm_size( comm, &size );
36 
37     /* 2 int */
38     {
39 	struct twoint { int val; int loc; } cinbuf[3], coutbuf[3];
40 
41 	cinbuf[0].val = 1;
42 	cinbuf[0].loc = rank;
43 	cinbuf[1].val = 0;
44 	cinbuf[1].loc = rank;
45 	cinbuf[2].val = (rank & 0x7f);
46 	cinbuf[2].loc = rank;
47 
48 	coutbuf[0].val = 0;
49 	coutbuf[0].loc = -1;
50 	coutbuf[1].val = 1;
51 	coutbuf[1].loc = -1;
52 	coutbuf[2].val = 1;
53 	coutbuf[2].loc = -1;
54 	MPI_Reduce( cinbuf, coutbuf, 3, MPI_2INT, MPI_MINLOC, 0, comm );
55 	if (rank == 0) {
56 	    if (coutbuf[0].val != 1 && coutbuf[0].loc != -1) {
57 		errs++;
58 		fprintf( stderr, "2int MINLOC(1) test failed\n" );
59 	    }
60 	    if (coutbuf[1].val != 0 && coutbuf[1].loc != -1) {
61 		errs++;
62 		fprintf( stderr, "2int MINLOC(0) test failed\n" );
63 	    }
64 	    if (coutbuf[2].val != 0 && coutbuf[2].loc != 0) {
65 		errs++;
66 		fprintf( stderr, "2int MINLOC(>) test failed\n" );
67 	    }
68 	}
69     }
70 
71     /* float int */
72     {
73 	struct floatint { float val; int loc; } cinbuf[3], coutbuf[3];
74 
75 	cinbuf[0].val = 1;
76 	cinbuf[0].loc = rank;
77 	cinbuf[1].val = 0;
78 	cinbuf[1].loc = rank;
79 	cinbuf[2].val = (float)rank;
80 	cinbuf[2].loc = rank;
81 
82 	coutbuf[0].val = 0;
83 	coutbuf[0].loc = -1;
84 	coutbuf[1].val = 1;
85 	coutbuf[1].loc = -1;
86 	coutbuf[2].val = 1;
87 	coutbuf[2].loc = -1;
88 	MPI_Reduce( cinbuf, coutbuf, 3, MPI_FLOAT_INT, MPI_MINLOC, 0, comm );
89 	if (rank == 0) {
90 	    if (coutbuf[0].val != 1 && coutbuf[0].loc != -1) {
91 		errs++;
92 		fprintf( stderr, "float-int MINLOC(1) test failed\n" );
93 	    }
94 	    if (coutbuf[1].val != 0 && coutbuf[1].loc != -1) {
95 		errs++;
96 		fprintf( stderr, "float-int MINLOC(0) test failed\n" );
97 	    }
98 	    if (coutbuf[2].val != 0 && coutbuf[2].loc != 0) {
99 		errs++;
100 		fprintf( stderr, "float-int MINLOC(>) test failed\n" );
101 	    }
102 	}
103     }
104 
105     /* long int */
106     {
107 	struct longint { long val; int loc; } cinbuf[3], coutbuf[3];
108 
109 	cinbuf[0].val = 1;
110 	cinbuf[0].loc = rank;
111 	cinbuf[1].val = 0;
112 	cinbuf[1].loc = rank;
113 	cinbuf[2].val = rank;
114 	cinbuf[2].loc = rank;
115 
116 	coutbuf[0].val = 0;
117 	coutbuf[0].loc = -1;
118 	coutbuf[1].val = 1;
119 	coutbuf[1].loc = -1;
120 	coutbuf[2].val = 1;
121 	coutbuf[2].loc = -1;
122 	MPI_Reduce( cinbuf, coutbuf, 3, MPI_LONG_INT, MPI_MINLOC, 0, comm );
123 	if (rank == 0) {
124 	    if (coutbuf[0].val != 1 || coutbuf[0].loc != 0) {
125 		errs++;
126 		fprintf( stderr, "long-int MINLOC(1) test failed\n" );
127 	    }
128 	    if (coutbuf[1].val != 0 || coutbuf[1].loc != 0) {
129 		errs++;
130 		fprintf( stderr, "long-int MINLOC(0) test failed\n" );
131 	    }
132 	    if (coutbuf[2].val != 0 || coutbuf[2].loc != 0) {
133 		errs++;
134 		fprintf( stderr, "long-int MINLOC(>) test failed\n" );
135 	    }
136 	}
137     }
138 
139     /* short int */
140     {
141 	struct shortint { short val; int loc; } cinbuf[3], coutbuf[3];
142 
143 	cinbuf[0].val = 1;
144 	cinbuf[0].loc = rank;
145 	cinbuf[1].val = 0;
146 	cinbuf[1].loc = rank;
147 	cinbuf[2].val = rank;
148 	cinbuf[2].loc = rank;
149 
150 	coutbuf[0].val = 0;
151 	coutbuf[0].loc = -1;
152 	coutbuf[1].val = 1;
153 	coutbuf[1].loc = -1;
154 	coutbuf[2].val = 1;
155 	coutbuf[2].loc = -1;
156 	MPI_Reduce( cinbuf, coutbuf, 3, MPI_SHORT_INT, MPI_MINLOC, 0, comm );
157 	if (rank == 0) {
158 	    if (coutbuf[0].val != 1 || coutbuf[0].loc != 0) {
159 		errs++;
160 		fprintf( stderr, "short-int MINLOC(1) test failed\n" );
161 	    }
162 	    if (coutbuf[1].val != 0 || coutbuf[1].loc != 0) {
163 		errs++;
164 		fprintf( stderr, "short-int MINLOC(0) test failed\n" );
165 	    }
166 	    if (coutbuf[2].val != 0 || coutbuf[2].loc != 0) {
167 		errs++;
168 		fprintf( stderr, "short-int MINLOC(>) test failed\n" );
169 	    }
170 	}
171     }
172 
173     /* double int */
174     {
175 	struct doubleint { double val; int loc; } cinbuf[3], coutbuf[3];
176 
177 	cinbuf[0].val = 1;
178 	cinbuf[0].loc = rank;
179 	cinbuf[1].val = 0;
180 	cinbuf[1].loc = rank;
181 	cinbuf[2].val = rank;
182 	cinbuf[2].loc = rank;
183 
184 	coutbuf[0].val = 0;
185 	coutbuf[0].loc = -1;
186 	coutbuf[1].val = 1;
187 	coutbuf[1].loc = -1;
188 	coutbuf[2].val = 1;
189 	coutbuf[2].loc = -1;
190 	MPI_Reduce( cinbuf, coutbuf, 3, MPI_DOUBLE_INT, MPI_MINLOC, 0, comm );
191 	if (rank == 0) {
192 	    if (coutbuf[0].val != 1 || coutbuf[0].loc != 0) {
193 		errs++;
194 		fprintf( stderr, "double-int MINLOC(1) test failed\n" );
195 	    }
196 	    if (coutbuf[1].val != 0 || coutbuf[1].loc != 0) {
197 		errs++;
198 		fprintf( stderr, "double-int MINLOC(0) test failed\n" );
199 	    }
200 	    if (coutbuf[2].val != 0 || coutbuf[2].loc != 0) {
201 		errs++;
202 		fprintf( stderr, "double-int MINLOC(>) test failed\n" );
203 	    }
204 	}
205     }
206 
207 #ifdef HAVE_LONG_DOUBLE
208     /* long double int */
209     {
210 	struct longdoubleint { long double val; int loc; } cinbuf[3], coutbuf[3];
211 
212 	cinbuf[0].val = 1;
213 	cinbuf[0].loc = rank;
214 	cinbuf[1].val = 0;
215 	cinbuf[1].loc = rank;
216 	cinbuf[2].val = rank;
217 	cinbuf[2].loc = rank;
218 
219 	coutbuf[0].val = 0;
220 	coutbuf[0].loc = -1;
221 	coutbuf[1].val = 1;
222 	coutbuf[1].loc = -1;
223 	coutbuf[2].val = 1;
224 	coutbuf[2].loc = -1;
225 	if (MPI_LONG_DOUBLE != MPI_DATATYPE_NULL) {
226 	    MPI_Reduce( cinbuf, coutbuf, 3, MPI_LONG_DOUBLE_INT, MPI_MINLOC,
227 			0, comm );
228 	    if (rank == 0) {
229 		if (coutbuf[0].val != 1 || coutbuf[0].loc != 0) {
230 		    errs++;
231 		    fprintf( stderr, "long double-int MINLOC(1) test failed\n" );
232 		}
233 		if (coutbuf[1].val != 0 || coutbuf[1].loc != 0) {
234 		    errs++;
235 		    fprintf( stderr, "long double-int MINLOC(0) test failed\n" );
236 		}
237 		if (coutbuf[2].val != 0 || coutbuf[2].loc != 0) {
238 		    errs++;
239 		    fprintf( stderr, "long double-int MINLOC(>) test failed\n" );
240 		}
241 	    }
242 	}
243     }
244 #endif
245 
246     MTest_Finalize( errs );
247     MPI_Finalize();
248     return 0;
249 }
250