1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/*
* Copyright (C) by Argonne National Laboratory
* See COPYRIGHT in top-level directory
*/
/*
throwtest.cxx
This test was based on code provided with a bug report submitted by
Eric Eidson edeidso@sandia.gov
*/
#include <mpi.h>
#include <iostream>
#include "mpitestconf.h"
#include "mpitestcxx.h"
/* #define VERBOSE */
/* returns number of errors found */
template < class T >
int testCallErrhandler(T & obj, int errorClass, int errorCode, std::string errorString)
{
int errs = 0;
try {
obj.Call_errhandler(errorCode);
std::cerr << "Do Not See This" << std::endl;
errs++;
}
catch(MPI::Exception & ex) {
#ifdef VERBOSE
std::cerr << "MPI Exception: " << ex.Get_error_string() << std::endl;
#endif
if (ex.Get_error_code() != errorCode) {
std::cout << "errorCode does not match" << std::endl;
errs++;
}
if (ex.Get_error_class() != errorClass) {
std::cout << "errorClass does not match" << std::endl;
errs++;
}
if (ex.Get_error_string() != errorString) {
std::cout << "errorString does not match" << std::endl;
errs++;
}
}
catch(...) {
std::cerr << "Caught Unknown Exception" << std::endl;
errs++;
}
return errs;
}
int main(int argc, char *argv[])
{
int errs = 0;
MPI::Win win = MPI::WIN_NULL;
MTest_Init();
const unsigned int rank = MPI::COMM_WORLD.Get_rank();
const unsigned int size = MPI::COMM_WORLD.Get_size();
int errorClass = MPI::Add_error_class();
int errorCode = MPI::Add_error_code(errorClass);
std::string errorString = "Internal-use Error Code";
MPI::Add_error_string(errorCode, errorString.c_str());
win = MPI::Win::Create(NULL, 0, 1, MPI::INFO_NULL, MPI_COMM_WORLD);
// first sanity check that ERRORS_RETURN actually returns in erroneous
// conditions and doesn't throw an exception
MPI::COMM_WORLD.Set_errhandler(MPI::ERRORS_RETURN);
win.Set_errhandler(MPI::ERRORS_RETURN);
try {
// Do something that should cause an exception.
MPI::COMM_WORLD.Get_attr(MPI::KEYVAL_INVALID, NULL);
}
catch(...) {
std::cerr << "comm threw when it shouldn't have" << std::endl;
++errs;
}
try {
// Do something that should cause an exception.
win.Get_attr(MPI::KEYVAL_INVALID, NULL);
}
catch(...) {
std::cerr << "win threw when it shouldn't have" << std::endl;
++errs;
}
// now test that when ERRORS_THROW_EXCEPTIONS actually throws an exception
MPI::COMM_WORLD.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS);
win.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS);
if (0 == rank) {
errs += testCallErrhandler(MPI::COMM_WORLD, errorClass, errorCode, errorString);
errs += testCallErrhandler(win, errorClass, errorCode, errorString);
// induce actual errors and make sure that they throw
try {
char buf[10];
MPI::COMM_WORLD.Send(&buf, 1, MPI::CHAR, size + 1, 1);
std::cout << "Invalid Send did not throw" << std::endl;
errs++;
}
catch(MPI::Exception & ex) {
// expected
}
catch(...) {
std::cout << "Caught Unknown Exception" << std::endl;
errs++;
}
try {
char buf[10];
win.Get(&buf, 0, MPI::CHAR, size + 1, 0, 0, MPI::CHAR);
std::cout << "Invalid Get did not throw" << std::endl;
errs++;
}
catch(MPI::Exception & ex) {
// expected
}
catch(...) {
std::cout << "Caught Unknown Exception" << std::endl;
errs++;
}
}
win.Free();
MTest_Finalize(errs);
return 0;
}
|