23 #define REPORT_MPI_ERR( errCode, mpiFunctionName ) \
25 if (errCode != MPI_SUCCESS) { \
26 char errString[MPI_MAX_ERROR_STRING]; \
28 (void) MPI_Error_string (errCode, errString, &len); \
29 TEUCHOS_TEST_FOR_EXCEPTION \
30 (true, std::logic_error, "MPI routine " << mpiFunctionName << " returned " \
31 "err != MPI_SUCCESS. Reported error: \"" << errString << "\"."); \
38 mpiDatatypeIsCustom (MPI_Datatype dt)
42 (
true, std::logic_error,
"mpiDatatypeIsCustom: This function requires MPI "
43 "2.0 at least, since it relies on MPI_Type_get_envelope. MPI 2.0 came "
44 "out in 1996, so I think it's time to upgrade your MPI implementation.");
45 #else // MPI_VERSION >= 2
52 MPI_Type_get_envelope (dt, &numInts, &numAddrs, &numTypes, &combiner);
54 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_get_envelope "
55 "returned err != MPI_SUCCESS.");
58 case MPI_COMBINER_NAMED:
60 case MPI_COMBINER_DUP:
61 case MPI_COMBINER_CONTIGUOUS:
62 case MPI_COMBINER_VECTOR:
63 case MPI_COMBINER_HVECTOR:
64 case MPI_COMBINER_INDEXED:
65 case MPI_COMBINER_HINDEXED:
66 case MPI_COMBINER_INDEXED_BLOCK:
68 case MPI_COMBINER_HINDEXED_BLOCK:
70 case MPI_COMBINER_STRUCT:
71 case MPI_COMBINER_SUBARRAY:
72 case MPI_COMBINER_DARRAY:
73 case MPI_COMBINER_F90_REAL:
74 case MPI_COMBINER_F90_COMPLEX:
75 case MPI_COMBINER_F90_INTEGER:
76 case MPI_COMBINER_RESIZED:
80 #endif // MPI_VERSION >= 2
95 mpiDatatypeIsSame (MPI_Datatype t1, MPI_Datatype t2)
99 (
true, std::logic_error,
"mpiDatatypeIsSame: This function requires MPI "
100 "2.0 at least, since it relies on MPI_Type_get_envelope and "
101 "MPI_Type_get_contents. MPI 2.0 came out in 1996, so I think it's time "
102 "to upgrade your MPI implementation.");
103 #else // MPI_VERSION >= 2
104 int err = MPI_SUCCESS;
106 int numInts1, numAddrs1, numTypes1, combiner1;
108 err = MPI_Type_get_envelope (t1, &numInts1, &numAddrs1, &numTypes1, &combiner1);
109 REPORT_MPI_ERR(err,
"MPI_Type_get_envelope");
110 int numInts2, numAddrs2, numTypes2, combiner2;
112 err = MPI_Type_get_envelope (t2, &numInts2, &numAddrs2, &numTypes2, &combiner2);
113 REPORT_MPI_ERR(err,
"MPI_Type_get_envelope");
115 if (combiner1 != combiner2 ||
116 numInts1 != numInts2 ||
117 numAddrs1 != numAddrs2 ||
118 numTypes1 != numTypes2) {
121 else if (combiner1 == MPI_COMBINER_NAMED) {
128 else if (numTypes1 == 0) {
135 std::vector<MPI_Datatype> theTypes1 (numTypes1);
136 std::vector<MPI_Datatype> theTypes2 (numTypes2);
144 std::vector<int> theInts1 (numInts1);
145 std::vector<int> theInts2 (numInts2);
146 std::vector<MPI_Aint> theAddrs1 (numAddrs1);
147 std::vector<MPI_Aint> theAddrs2 (numAddrs2);
150 err = MPI_Type_get_contents (t1, numInts1, numAddrs1, numTypes1,
151 numInts1 == 0 ? NULL : &theInts1[0],
152 numAddrs1 == 0 ? NULL : &theAddrs1[0],
153 numTypes1 == 0 ? NULL : &theTypes1[0]);
154 REPORT_MPI_ERR(err,
"MPI_Type_get_contents");
156 err = MPI_Type_get_contents (t2, numInts2, numAddrs2, numTypes2,
157 numInts2 == 0 ? NULL : &theInts2[0],
158 numAddrs2 == 0 ? NULL : &theAddrs2[0],
159 numTypes2 == 0 ? NULL : &theTypes2[0]);
160 REPORT_MPI_ERR(err,
"MPI_Type_get_contents");
162 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_get_contents "
163 "returned err != MPI_SUCCESS.");
165 for (
int k = 0; k < numInts1; ++k) {
166 if (theInts1[k] != theInts2[k]) {
170 for (
int k = 0; k < numAddrs1; ++k) {
171 if (theAddrs1[k] != theAddrs2[k]) {
178 for (
int k = 0; k < numTypes1; ++k) {
179 const bool same = mpiDatatypeIsSame (theTypes1[k], theTypes2[k]);
184 if (mpiDatatypeIsCustom (theTypes1[k])) {
185 err = MPI_Type_free (&theTypes1[k]);
187 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_free "
188 "returned err != MPI_SUCCESS.");
190 if (mpiDatatypeIsCustom (theTypes2[k])) {
191 err = MPI_Type_free (&theTypes2[k]);
193 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_free "
194 "returned err != MPI_SUCCESS.");
202 #endif // MPI_VERSION < 2
207 using Teuchos::Details::MpiTypeTraits;
209 int err = MPI_SUCCESS;
211 out <<
"Test mpiDatatypeIsCustom" << endl;
220 err = MPI_Comm_set_errhandler (MPI_COMM_WORLD, MPI_ERRORS_RETURN);
222 (err != MPI_SUCCESS, std::logic_error,
"MPI_Comm_set_errhandler "
223 "returned err != MPI_SUCCESS.");
228 MPI_Datatype mpi3doubles;
229 err = MPI_Type_contiguous (3, MPI_DOUBLE, &mpi3doubles);
231 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_contiguous "
232 "returned err != MPI_SUCCESS.");
236 err = MPI_Type_free (&mpi3doubles);
238 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_free "
239 "returned err != MPI_SUCCESS.");
244 using Teuchos::Details::MpiTypeTraits;
246 int err = MPI_SUCCESS;
248 out <<
"Test mpiDatatypeIsSame" << endl;
251 TEST_ASSERT( mpiDatatypeIsSame (MPI_INT, MPI_INT) );
252 TEST_ASSERT( mpiDatatypeIsSame (MPI_DOUBLE, MPI_DOUBLE) );
253 TEST_ASSERT( ! mpiDatatypeIsSame (MPI_DOUBLE, MPI_INT) );
254 TEST_ASSERT( ! mpiDatatypeIsSame (MPI_INT, MPI_DOUBLE) );
256 MPI_Datatype mpi3doubles;
257 err = MPI_Type_contiguous (3, MPI_DOUBLE, &mpi3doubles);
259 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_contiguous "
260 "returned err != MPI_SUCCESS.");
261 MPI_Datatype mpi4doubles;
262 err = MPI_Type_contiguous (4, MPI_DOUBLE, &mpi4doubles);
264 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_contiguous "
265 "returned err != MPI_SUCCESS.");
267 TEST_ASSERT( ! mpiDatatypeIsSame (mpi3doubles, MPI_DOUBLE) );
268 TEST_ASSERT( ! mpiDatatypeIsSame (MPI_DOUBLE, mpi3doubles) );
269 TEST_ASSERT( ! mpiDatatypeIsSame (mpi3doubles, MPI_INT) );
270 TEST_ASSERT( ! mpiDatatypeIsSame (MPI_INT, mpi3doubles) );
271 TEST_ASSERT( ! mpiDatatypeIsSame (mpi4doubles, MPI_DOUBLE) );
272 TEST_ASSERT( ! mpiDatatypeIsSame (MPI_DOUBLE, mpi4doubles) );
273 TEST_ASSERT( ! mpiDatatypeIsSame (mpi4doubles, MPI_INT) );
274 TEST_ASSERT( ! mpiDatatypeIsSame (MPI_INT, mpi4doubles) );
276 TEST_ASSERT( mpiDatatypeIsSame (mpi3doubles, mpi3doubles) );
277 TEST_ASSERT( mpiDatatypeIsSame (mpi4doubles, mpi4doubles) );
278 TEST_ASSERT( ! mpiDatatypeIsSame (mpi3doubles, mpi4doubles) );
279 TEST_ASSERT( ! mpiDatatypeIsSame (mpi4doubles, mpi3doubles) );
281 err = MPI_Type_free (&mpi3doubles);
283 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_free "
284 "returned err != MPI_SUCCESS.");
285 err = MPI_Type_free (&mpi4doubles);
287 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_free "
288 "returned err != MPI_SUCCESS.");
294 using Teuchos::Details::MpiTypeTraits;
297 out <<
"Compare MpiTypeTraits<T>::getType result with known result" << endl;
299 out <<
"Test one-argument version of MpiTypeTraits<T>::getType" << endl;
301 MPI_Datatype dt_char = MpiTypeTraits<char>::getType (static_cast<char> (
'a'));
303 MPI_Datatype dt_short =
304 MpiTypeTraits<short>::getType (static_cast<short> (42));
305 MPI_Datatype dt_unsigned_short =
306 MpiTypeTraits<unsigned short>::getType (static_cast<unsigned short> (42));
308 MPI_Datatype dt_int =
309 MpiTypeTraits<int>::getType (static_cast<int> (42));
310 MPI_Datatype dt_unsigned_int =
311 MpiTypeTraits<unsigned int>::getType (static_cast<unsigned int> (42));
313 MPI_Datatype dt_long =
314 MpiTypeTraits<long>::getType (static_cast<long> (42));
315 MPI_Datatype dt_unsigned_long =
316 MpiTypeTraits<unsigned long>::getType (static_cast<unsigned long> (42));
318 MPI_Datatype dt_float =
319 MpiTypeTraits<float>::getType (static_cast<float> (4.2));
320 MPI_Datatype dt_double =
321 MpiTypeTraits<double>::getType (static_cast<double> (4.2));
324 TEST_ASSERT( ! mpiDatatypeIsSame (dt_double, dt_int) );
326 TEST_ASSERT( mpiDatatypeIsSame (dt_char, MPI_CHAR) );
327 TEST_ASSERT( mpiDatatypeIsSame (dt_short, MPI_SHORT) );
328 TEST_ASSERT( mpiDatatypeIsSame (dt_unsigned_short, MPI_UNSIGNED_SHORT) );
329 TEST_ASSERT( mpiDatatypeIsSame (dt_int, MPI_INT) );
330 TEST_ASSERT( mpiDatatypeIsSame (dt_unsigned_int, MPI_UNSIGNED) );
331 TEST_ASSERT( mpiDatatypeIsSame (dt_long, MPI_LONG) );
332 TEST_ASSERT( mpiDatatypeIsSame (dt_unsigned_long, MPI_UNSIGNED_LONG) );
334 TEST_ASSERT( mpiDatatypeIsSame (dt_float, MPI_FLOAT) );
335 TEST_ASSERT( mpiDatatypeIsSame (dt_double, MPI_DOUBLE) );
337 out <<
"Test zero-argument version of MpiTypeTraits<T>::getType, "
338 "for types T where that version is known to exist" << endl;
340 dt_char = MpiTypeTraits<char>::getType ();
341 dt_short = MpiTypeTraits<short>::getType ();
342 dt_unsigned_short = MpiTypeTraits<unsigned short>::getType ();
343 dt_int = MpiTypeTraits<int>::getType ();
344 dt_unsigned_int = MpiTypeTraits<unsigned int>::getType ();
345 dt_long = MpiTypeTraits<long>::getType ();
346 dt_unsigned_long = MpiTypeTraits<unsigned long>::getType ();
347 dt_float = MpiTypeTraits<float>::getType ();
348 dt_double = MpiTypeTraits<double>::getType ();
351 TEST_ASSERT( ! mpiDatatypeIsSame (dt_double, dt_int) );
353 TEST_ASSERT( mpiDatatypeIsSame (dt_char, MPI_CHAR) );
354 TEST_ASSERT( mpiDatatypeIsSame (dt_short, MPI_SHORT) );
355 TEST_ASSERT( mpiDatatypeIsSame (dt_unsigned_short, MPI_UNSIGNED_SHORT) );
356 TEST_ASSERT( mpiDatatypeIsSame (dt_int, MPI_INT) );
357 TEST_ASSERT( mpiDatatypeIsSame (dt_unsigned_int, MPI_UNSIGNED) );
358 TEST_ASSERT( mpiDatatypeIsSame (dt_long, MPI_LONG) );
359 TEST_ASSERT( mpiDatatypeIsSame (dt_unsigned_long, MPI_UNSIGNED_LONG) );
361 TEST_ASSERT( mpiDatatypeIsSame (dt_float, MPI_FLOAT) );
362 TEST_ASSERT( mpiDatatypeIsSame (dt_double, MPI_DOUBLE) );
365 TEST_ASSERT( MpiTypeTraits<short>::isSpecialized );
366 TEST_ASSERT( MpiTypeTraits<unsigned short>::isSpecialized );
368 TEST_ASSERT( MpiTypeTraits<unsigned int>::isSpecialized );
370 TEST_ASSERT( MpiTypeTraits<unsigned long>::isSpecialized );
371 TEST_ASSERT( MpiTypeTraits<float>::isSpecialized );
372 TEST_ASSERT( MpiTypeTraits<double>::isSpecialized );
376 TEST_ASSERT( ! MpiTypeTraits<unsigned short>::needsFree );
378 TEST_ASSERT( ! MpiTypeTraits<unsigned int>::needsFree );
380 TEST_ASSERT( ! MpiTypeTraits<unsigned long>::needsFree );
384 #ifdef HAVE_TEUCHOS_COMPLEX
386 TEST_ASSERT( MpiTypeTraits<std::complex<float> >::isSpecialized );
387 TEST_ASSERT( MpiTypeTraits<std::complex<double> >::isSpecialized );
389 MPI_Datatype dt_complex_float =
390 MpiTypeTraits<std::complex<float> >::getType ();
391 MPI_Datatype dt_complex_double =
392 MpiTypeTraits<std::complex<float> >::getType ();
396 TEST_ASSERT( ! MpiTypeTraits<std::complex<float> >::needsFree );
397 TEST_ASSERT( ! MpiTypeTraits<std::complex<double> >::needsFree );
398 #endif // MPI_VERSION >= 3
400 if (MpiTypeTraits<std::complex<float> >::needsFree) {
401 (void) MPI_Type_free (&dt_complex_float);
403 if (MpiTypeTraits<std::complex<double> >::needsFree) {
404 (void) MPI_Type_free (&dt_complex_double);
406 #endif // HAVE_TEUCHOS_COMPLEX
409 #endif // MPI_VERSION >= 2
#define TEST_ASSERT(v1)
Assert the given statement is true.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
Tabbing class for helping to create formated, indented output for a basic_FancyOStream object...
Declaration of Teuchos::Details::MpiTypeTraits (only if building with MPI)