57 #define REPORT_MPI_ERR( errCode, mpiFunctionName ) \
59 if (errCode != MPI_SUCCESS) { \
60 char errString[MPI_MAX_ERROR_STRING]; \
62 (void) MPI_Error_string (errCode, errString, &len); \
63 TEUCHOS_TEST_FOR_EXCEPTION \
64 (true, std::logic_error, "MPI routine " << mpiFunctionName << " returned " \
65 "err != MPI_SUCCESS. Reported error: \"" << errString << "\"."); \
72 mpiDatatypeIsCustom (MPI_Datatype dt)
76 (
true, std::logic_error,
"mpiDatatypeIsCustom: This function requires MPI "
77 "2.0 at least, since it relies on MPI_Type_get_envelope. MPI 2.0 came "
78 "out in 1996, so I think it's time to upgrade your MPI implementation.");
79 #else // MPI_VERSION >= 2
86 MPI_Type_get_envelope (dt, &numInts, &numAddrs, &numTypes, &combiner);
88 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_get_envelope "
89 "returned err != MPI_SUCCESS.");
92 case MPI_COMBINER_NAMED:
94 case MPI_COMBINER_DUP:
95 case MPI_COMBINER_CONTIGUOUS:
96 case MPI_COMBINER_VECTOR:
97 case MPI_COMBINER_HVECTOR:
98 case MPI_COMBINER_INDEXED:
99 case MPI_COMBINER_HINDEXED:
100 case MPI_COMBINER_INDEXED_BLOCK:
102 case MPI_COMBINER_HINDEXED_BLOCK:
104 case MPI_COMBINER_STRUCT:
105 case MPI_COMBINER_SUBARRAY:
106 case MPI_COMBINER_DARRAY:
107 case MPI_COMBINER_F90_REAL:
108 case MPI_COMBINER_F90_COMPLEX:
109 case MPI_COMBINER_F90_INTEGER:
110 case MPI_COMBINER_RESIZED:
114 #endif // MPI_VERSION >= 2
129 mpiDatatypeIsSame (MPI_Datatype t1, MPI_Datatype t2)
133 (
true, std::logic_error,
"mpiDatatypeIsSame: This function requires MPI "
134 "2.0 at least, since it relies on MPI_Type_get_envelope and "
135 "MPI_Type_get_contents. MPI 2.0 came out in 1996, so I think it's time "
136 "to upgrade your MPI implementation.");
137 #else // MPI_VERSION >= 2
138 int err = MPI_SUCCESS;
140 int numInts1, numAddrs1, numTypes1, combiner1;
142 err = MPI_Type_get_envelope (t1, &numInts1, &numAddrs1, &numTypes1, &combiner1);
143 REPORT_MPI_ERR(err,
"MPI_Type_get_envelope");
144 int numInts2, numAddrs2, numTypes2, combiner2;
146 err = MPI_Type_get_envelope (t2, &numInts2, &numAddrs2, &numTypes2, &combiner2);
147 REPORT_MPI_ERR(err,
"MPI_Type_get_envelope");
149 if (combiner1 != combiner2 ||
150 numInts1 != numInts2 ||
151 numAddrs1 != numAddrs2 ||
152 numTypes1 != numTypes2) {
155 else if (combiner1 == MPI_COMBINER_NAMED) {
162 else if (numTypes1 == 0) {
169 std::vector<MPI_Datatype> theTypes1 (numTypes1);
170 std::vector<MPI_Datatype> theTypes2 (numTypes2);
178 std::vector<int> theInts1 (numInts1);
179 std::vector<int> theInts2 (numInts2);
180 std::vector<MPI_Aint> theAddrs1 (numAddrs1);
181 std::vector<MPI_Aint> theAddrs2 (numAddrs2);
184 err = MPI_Type_get_contents (t1, numInts1, numAddrs1, numTypes1,
185 numInts1 == 0 ? NULL : &theInts1[0],
186 numAddrs1 == 0 ? NULL : &theAddrs1[0],
187 numTypes1 == 0 ? NULL : &theTypes1[0]);
188 REPORT_MPI_ERR(err,
"MPI_Type_get_contents");
190 err = MPI_Type_get_contents (t2, numInts2, numAddrs2, numTypes2,
191 numInts2 == 0 ? NULL : &theInts2[0],
192 numAddrs2 == 0 ? NULL : &theAddrs2[0],
193 numTypes2 == 0 ? NULL : &theTypes2[0]);
194 REPORT_MPI_ERR(err,
"MPI_Type_get_contents");
196 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_get_contents "
197 "returned err != MPI_SUCCESS.");
199 for (
int k = 0; k < numInts1; ++k) {
200 if (theInts1[k] != theInts2[k]) {
204 for (
int k = 0; k < numAddrs1; ++k) {
205 if (theAddrs1[k] != theAddrs2[k]) {
212 for (
int k = 0; k < numTypes1; ++k) {
213 const bool same = mpiDatatypeIsSame (theTypes1[k], theTypes2[k]);
218 if (mpiDatatypeIsCustom (theTypes1[k])) {
219 err = MPI_Type_free (&theTypes1[k]);
221 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_free "
222 "returned err != MPI_SUCCESS.");
224 if (mpiDatatypeIsCustom (theTypes2[k])) {
225 err = MPI_Type_free (&theTypes2[k]);
227 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_free "
228 "returned err != MPI_SUCCESS.");
236 #endif // MPI_VERSION < 2
241 using Teuchos::Details::MpiTypeTraits;
243 int err = MPI_SUCCESS;
245 out <<
"Test mpiDatatypeIsCustom" << endl;
254 err = MPI_Comm_set_errhandler (MPI_COMM_WORLD, MPI_ERRORS_RETURN);
256 (err != MPI_SUCCESS, std::logic_error,
"MPI_Comm_set_errhandler "
257 "returned err != MPI_SUCCESS.");
262 MPI_Datatype mpi3doubles;
263 err = MPI_Type_contiguous (3, MPI_DOUBLE, &mpi3doubles);
265 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_contiguous "
266 "returned err != MPI_SUCCESS.");
270 err = MPI_Type_free (&mpi3doubles);
272 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_free "
273 "returned err != MPI_SUCCESS.");
278 using Teuchos::Details::MpiTypeTraits;
280 int err = MPI_SUCCESS;
282 out <<
"Test mpiDatatypeIsSame" << endl;
285 TEST_ASSERT( mpiDatatypeIsSame (MPI_INT, MPI_INT) );
286 TEST_ASSERT( mpiDatatypeIsSame (MPI_DOUBLE, MPI_DOUBLE) );
287 TEST_ASSERT( ! mpiDatatypeIsSame (MPI_DOUBLE, MPI_INT) );
288 TEST_ASSERT( ! mpiDatatypeIsSame (MPI_INT, MPI_DOUBLE) );
290 MPI_Datatype mpi3doubles;
291 err = MPI_Type_contiguous (3, MPI_DOUBLE, &mpi3doubles);
293 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_contiguous "
294 "returned err != MPI_SUCCESS.");
295 MPI_Datatype mpi4doubles;
296 err = MPI_Type_contiguous (4, MPI_DOUBLE, &mpi4doubles);
298 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_contiguous "
299 "returned err != MPI_SUCCESS.");
301 TEST_ASSERT( ! mpiDatatypeIsSame (mpi3doubles, MPI_DOUBLE) );
302 TEST_ASSERT( ! mpiDatatypeIsSame (MPI_DOUBLE, mpi3doubles) );
303 TEST_ASSERT( ! mpiDatatypeIsSame (mpi3doubles, MPI_INT) );
304 TEST_ASSERT( ! mpiDatatypeIsSame (MPI_INT, mpi3doubles) );
305 TEST_ASSERT( ! mpiDatatypeIsSame (mpi4doubles, MPI_DOUBLE) );
306 TEST_ASSERT( ! mpiDatatypeIsSame (MPI_DOUBLE, mpi4doubles) );
307 TEST_ASSERT( ! mpiDatatypeIsSame (mpi4doubles, MPI_INT) );
308 TEST_ASSERT( ! mpiDatatypeIsSame (MPI_INT, mpi4doubles) );
310 TEST_ASSERT( mpiDatatypeIsSame (mpi3doubles, mpi3doubles) );
311 TEST_ASSERT( mpiDatatypeIsSame (mpi4doubles, mpi4doubles) );
312 TEST_ASSERT( ! mpiDatatypeIsSame (mpi3doubles, mpi4doubles) );
313 TEST_ASSERT( ! mpiDatatypeIsSame (mpi4doubles, mpi3doubles) );
315 err = MPI_Type_free (&mpi3doubles);
317 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_free "
318 "returned err != MPI_SUCCESS.");
319 err = MPI_Type_free (&mpi4doubles);
321 (err != MPI_SUCCESS, std::logic_error,
"MPI_Type_free "
322 "returned err != MPI_SUCCESS.");
328 using Teuchos::Details::MpiTypeTraits;
331 out <<
"Compare MpiTypeTraits<T>::getType result with known result" << endl;
333 out <<
"Test one-argument version of MpiTypeTraits<T>::getType" << endl;
335 MPI_Datatype dt_char = MpiTypeTraits<char>::getType (static_cast<char> (
'a'));
337 MPI_Datatype dt_short =
338 MpiTypeTraits<short>::getType (static_cast<short> (42));
339 MPI_Datatype dt_unsigned_short =
340 MpiTypeTraits<unsigned short>::getType (static_cast<unsigned short> (42));
342 MPI_Datatype dt_int =
343 MpiTypeTraits<int>::getType (static_cast<int> (42));
344 MPI_Datatype dt_unsigned_int =
345 MpiTypeTraits<unsigned int>::getType (static_cast<unsigned int> (42));
347 MPI_Datatype dt_long =
348 MpiTypeTraits<long>::getType (static_cast<long> (42));
349 MPI_Datatype dt_unsigned_long =
350 MpiTypeTraits<unsigned long>::getType (static_cast<unsigned long> (42));
352 MPI_Datatype dt_float =
353 MpiTypeTraits<float>::getType (static_cast<float> (4.2));
354 MPI_Datatype dt_double =
355 MpiTypeTraits<double>::getType (static_cast<double> (4.2));
358 TEST_ASSERT( ! mpiDatatypeIsSame (dt_double, dt_int) );
360 TEST_ASSERT( mpiDatatypeIsSame (dt_char, MPI_CHAR) );
361 TEST_ASSERT( mpiDatatypeIsSame (dt_short, MPI_SHORT) );
362 TEST_ASSERT( mpiDatatypeIsSame (dt_unsigned_short, MPI_UNSIGNED_SHORT) );
363 TEST_ASSERT( mpiDatatypeIsSame (dt_int, MPI_INT) );
364 TEST_ASSERT( mpiDatatypeIsSame (dt_unsigned_int, MPI_UNSIGNED) );
365 TEST_ASSERT( mpiDatatypeIsSame (dt_long, MPI_LONG) );
366 TEST_ASSERT( mpiDatatypeIsSame (dt_unsigned_long, MPI_UNSIGNED_LONG) );
368 TEST_ASSERT( mpiDatatypeIsSame (dt_float, MPI_FLOAT) );
369 TEST_ASSERT( mpiDatatypeIsSame (dt_double, MPI_DOUBLE) );
371 out <<
"Test zero-argument version of MpiTypeTraits<T>::getType, "
372 "for types T where that version is known to exist" << endl;
374 dt_char = MpiTypeTraits<char>::getType ();
375 dt_short = MpiTypeTraits<short>::getType ();
376 dt_unsigned_short = MpiTypeTraits<unsigned short>::getType ();
377 dt_int = MpiTypeTraits<int>::getType ();
378 dt_unsigned_int = MpiTypeTraits<unsigned int>::getType ();
379 dt_long = MpiTypeTraits<long>::getType ();
380 dt_unsigned_long = MpiTypeTraits<unsigned long>::getType ();
381 dt_float = MpiTypeTraits<float>::getType ();
382 dt_double = MpiTypeTraits<double>::getType ();
385 TEST_ASSERT( ! mpiDatatypeIsSame (dt_double, dt_int) );
387 TEST_ASSERT( mpiDatatypeIsSame (dt_char, MPI_CHAR) );
388 TEST_ASSERT( mpiDatatypeIsSame (dt_short, MPI_SHORT) );
389 TEST_ASSERT( mpiDatatypeIsSame (dt_unsigned_short, MPI_UNSIGNED_SHORT) );
390 TEST_ASSERT( mpiDatatypeIsSame (dt_int, MPI_INT) );
391 TEST_ASSERT( mpiDatatypeIsSame (dt_unsigned_int, MPI_UNSIGNED) );
392 TEST_ASSERT( mpiDatatypeIsSame (dt_long, MPI_LONG) );
393 TEST_ASSERT( mpiDatatypeIsSame (dt_unsigned_long, MPI_UNSIGNED_LONG) );
395 TEST_ASSERT( mpiDatatypeIsSame (dt_float, MPI_FLOAT) );
396 TEST_ASSERT( mpiDatatypeIsSame (dt_double, MPI_DOUBLE) );
399 TEST_ASSERT( MpiTypeTraits<short>::isSpecialized );
400 TEST_ASSERT( MpiTypeTraits<unsigned short>::isSpecialized );
402 TEST_ASSERT( MpiTypeTraits<unsigned int>::isSpecialized );
404 TEST_ASSERT( MpiTypeTraits<unsigned long>::isSpecialized );
405 TEST_ASSERT( MpiTypeTraits<float>::isSpecialized );
406 TEST_ASSERT( MpiTypeTraits<double>::isSpecialized );
410 TEST_ASSERT( ! MpiTypeTraits<unsigned short>::needsFree );
412 TEST_ASSERT( ! MpiTypeTraits<unsigned int>::needsFree );
414 TEST_ASSERT( ! MpiTypeTraits<unsigned long>::needsFree );
418 #ifdef HAVE_TEUCHOS_COMPLEX
420 TEST_ASSERT( MpiTypeTraits<std::complex<float> >::isSpecialized );
421 TEST_ASSERT( MpiTypeTraits<std::complex<double> >::isSpecialized );
423 MPI_Datatype dt_complex_float =
424 MpiTypeTraits<std::complex<float> >::getType ();
425 MPI_Datatype dt_complex_double =
426 MpiTypeTraits<std::complex<float> >::getType ();
430 TEST_ASSERT( ! MpiTypeTraits<std::complex<float> >::needsFree );
431 TEST_ASSERT( ! MpiTypeTraits<std::complex<double> >::needsFree );
432 #endif // MPI_VERSION >= 3
434 if (MpiTypeTraits<std::complex<float> >::needsFree) {
435 (void) MPI_Type_free (&dt_complex_float);
437 if (MpiTypeTraits<std::complex<double> >::needsFree) {
438 (void) MPI_Type_free (&dt_complex_double);
440 #endif // HAVE_TEUCHOS_COMPLEX
443 #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)