1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2003 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
8 #include "mpitestconf.h"
13 static char MTEST_Descrip[] = "Test MPI_PROD operations on optional datatypes dupported by MPICH";
16 typedef struct { double r, i; } d_complex;
17 #ifdef HAVE_LONG_DOUBLE
18 typedef struct { long double r, i; } ld_complex;
22 * This test looks at the handling of logical and for types that are not
23 * integers or are not required integers (e.g., long long). MPICH allows
24 * these as well. A strict MPI test should not include this test.
26 int main( int argc, char *argv[] )
29 int rank, size, maxsize, result[6] = { 1, 1, 2, 6, 24, 120 };
31 char cinbuf[3], coutbuf[3];
32 signed char scinbuf[3], scoutbuf[3];
33 unsigned char ucinbuf[3], ucoutbuf[3];
34 d_complex dinbuf[3], doutbuf[3];
36 MTest_Init( &argc, &argv );
38 comm = MPI_COMM_WORLD;
40 MPI_Comm_rank( comm, &rank );
41 MPI_Comm_size( comm, &size );
42 if (size > 5) maxsize = 5;
45 /* General forumula: If we multiple the values from 1 to n, the
46 product is n!. This grows very fast, so we'll only use the first
47 five (1! = 1, 2! = 2, 3! = 6, 4! = 24, 5! = 120), with n!
48 stored in the array result[n] */
50 #ifndef USE_STRICT_MPI
52 MTestPrintfMsg( 10, "Reduce of MPI_CHAR\n" );
53 cinbuf[0] = (rank < maxsize && rank > 0) ? rank : 1;
55 cinbuf[2] = (rank > 1);
60 MPI_Reduce( cinbuf, coutbuf, 3, MPI_CHAR, MPI_PROD, 0, comm );
62 if (coutbuf[0] != (char)result[maxsize-1]) {
64 fprintf( stderr, "char PROD(rank) test failed (%d!=%d)\n",
65 (int)coutbuf[0], (int)result[maxsize]);
69 fprintf( stderr, "char PROD(0) test failed\n" );
71 if (size > 1 && coutbuf[2]) {
73 fprintf( stderr, "char PROD(>) test failed\n" );
76 #endif /* USE_STRICT_MPI */
79 MTestPrintfMsg( 10, "Reduce of MPI_SIGNED_CHAR\n" );
80 scinbuf[0] = (rank < maxsize && rank > 0) ? rank : 1;
82 scinbuf[2] = (rank > 1);
87 MPI_Reduce( scinbuf, scoutbuf, 3, MPI_SIGNED_CHAR, MPI_PROD, 0, comm );
89 if (scoutbuf[0] != (signed char)result[maxsize-1]) {
91 fprintf( stderr, "signed char PROD(rank) test failed (%d!=%d)\n",
92 (int)scoutbuf[0], (int)result[maxsize]);
96 fprintf( stderr, "signed char PROD(0) test failed\n" );
98 if (size > 1 && scoutbuf[2]) {
100 fprintf( stderr, "signed char PROD(>) test failed\n" );
105 MTestPrintfMsg( 10, "Reduce of MPI_UNSIGNED_CHAR\n" );
106 ucinbuf[0] = (rank < maxsize && rank > 0) ? rank : 1;
108 ucinbuf[2] = (rank > 0);
113 MPI_Reduce( ucinbuf, ucoutbuf, 3, MPI_UNSIGNED_CHAR, MPI_PROD, 0, comm );
115 if (ucoutbuf[0] != (unsigned char)result[maxsize-1]) {
117 fprintf( stderr, "unsigned char PROD(rank) test failed\n" );
121 fprintf( stderr, "unsigned char PROD(0) test failed\n" );
123 if (size > 1 && ucoutbuf[2]) {
125 fprintf( stderr, "unsigned char PROD(>) test failed\n" );
129 #ifndef USE_STRICT_MPI
130 /* For some reason, complex is not allowed for sum and prod */
131 if (MPI_DOUBLE_COMPLEX != MPI_DATATYPE_NULL) {
133 #ifdef HAVE_LONG_DOUBLE
134 ld_complex ldinbuf[3], ldoutbuf[3];
136 /* Must determine which C type matches this Fortran type */
137 MPI_Type_size( MPI_DOUBLE_COMPLEX, &dc );
138 if (dc == sizeof(d_complex)) {
139 /* double complex; may be null if we do not have Fortran support */
140 dinbuf[0].r = (rank < maxsize && rank > 0) ? rank : 1;
142 dinbuf[2].r = (rank > 0);
145 dinbuf[2].i = -(rank > 0);
153 MPI_Reduce( dinbuf, doutbuf, 3, MPI_DOUBLE_COMPLEX, MPI_PROD, 0, comm );
156 if (doutbuf[0].r != (double)result[maxsize-1] || doutbuf[0].i != 0) {
158 fprintf( stderr, "double complex PROD(rank) test failed\n" );
160 /* Multiplying the imaginary part depends on size mod 4 */
161 imag = 1.0; real = 0.0; /* Make compiler happy */
163 case 1: imag = 1.0; real = 0.0; break;
164 case 2: imag = 0.0; real = -1.0; break;
165 case 3: imag =-1.0; real = 0.0; break;
166 case 0: imag = 0.0; real = 1.0; break;
168 if (doutbuf[1].r != real || doutbuf[1].i != imag) {
170 fprintf( stderr, "double complex PROD(i) test failed (%f,%f)!=(%f,%f)\n",
171 doutbuf[1].r,doutbuf[1].i,real,imag);
173 if (doutbuf[2].r != 0 || doutbuf[2].i != 0) {
175 fprintf( stderr, "double complex PROD(>) test failed\n" );
179 #ifdef HAVE_LONG_DOUBLE
180 else if (dc == sizeof(ld_complex)) {
181 /* double complex; may be null if we do not have Fortran support */
182 ldinbuf[0].r = (rank < maxsize && rank > 0) ? rank : 1;
184 ldinbuf[2].r = (rank > 0);
187 ldinbuf[2].i = -(rank > 0);
195 MPI_Reduce( ldinbuf, ldoutbuf, 3, MPI_DOUBLE_COMPLEX, MPI_PROD, 0, comm );
197 long double imag, real;
198 if (ldoutbuf[0].r != (double)result[maxsize-1] || ldoutbuf[0].i != 0) {
200 fprintf( stderr, "double complex PROD(rank) test failed\n" );
202 /* Multiplying the imaginary part depends on size mod 4 */
203 imag = 1.0; real = 0.0; /* Make compiler happy */
205 case 1: imag = 1.0; real = 0.0; break;
206 case 2: imag = 0.0; real = -1.0; break;
207 case 3: imag =-1.0; real = 0.0; break;
208 case 0: imag = 0.0; real = 1.0; break;
210 if (ldoutbuf[1].r != real || ldoutbuf[1].i != imag) {
212 fprintf( stderr, "double complex PROD(i) test failed (%Lf,%Lf)!=(%Lf,%Lf)\n",
213 ldoutbuf[1].r,ldoutbuf[1].i,real,imag);
215 if (ldoutbuf[2].r != 0 || ldoutbuf[2].i != 0) {
217 fprintf( stderr, "double complex PROD(>) test failed\n" );
221 #endif /* HAVE_LONG_DOUBLE */
223 #endif /* USE_STRICT_MPI */
225 #ifdef HAVE_LONG_DOUBLE
226 { long double ldinbuf[3], ldoutbuf[3];
228 ldinbuf[0] = (rank < maxsize && rank > 0) ? rank : 1;
230 ldinbuf[2] = (rank > 0);
235 if (MPI_LONG_DOUBLE != MPI_DATATYPE_NULL) {
236 MPI_Reduce( ldinbuf, ldoutbuf, 3, MPI_LONG_DOUBLE, MPI_PROD, 0, comm );
238 if (ldoutbuf[0] != (long double)result[maxsize-1]) {
240 fprintf( stderr, "long double PROD(rank) test failed\n" );
244 fprintf( stderr, "long double PROD(0) test failed\n" );
246 if (size > 1 && ldoutbuf[2] != 0) {
248 fprintf( stderr, "long double PROD(>) test failed\n" );
253 #endif /* HAVE_LONG_DOUBLE */
255 #ifdef HAVE_LONG_LONG
257 long long llinbuf[3], lloutbuf[3];
259 llinbuf[0] = (rank < maxsize && rank > 0) ? rank : 1;
261 llinbuf[2] = (rank > 0);
266 if (MPI_LONG_LONG != MPI_DATATYPE_NULL) {
267 MPI_Reduce( llinbuf, lloutbuf, 3, MPI_LONG_LONG, MPI_PROD, 0, comm );
269 if (lloutbuf[0] != (long long)result[maxsize-1]) {
271 fprintf( stderr, "long long PROD(rank) test failed\n" );
275 fprintf( stderr, "long long PROD(0) test failed\n" );
277 if (size > 1 && lloutbuf[2]) {
279 fprintf( stderr, "long long PROD(>) test failed\n" );
284 #endif /* HAVE_LONG_LONG */
286 MTest_Finalize( errs );