Changeset 850

Show
Ignore:
Timestamp:
04/14/08 17:03:38 (20 months ago)
Author:
goodell
Message:

Fix for req#3999. MPI::{Comm,Win,File}::Call_errhandler now does the right
thing for MPI::ERRORS_THROW_EXCEPTIONS. Also, beef up the test a bit.

Location:
mpich2/trunk
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • mpich2/trunk/src/binding/cxx/buildiface

    r100 r850  
    406406#                   'Create_keyval' => 'int', 
    407407                    'Free_keyval' =>  'static:0:1', 
    408                     'Call_errhandler' => 0, 
     408# this routine is special and cannot be auto-generated 
     409#                   'Call_errhandler' => 0, 
    409410                    'Set_name' => '0:2', 
    410411                    'Get_name' => '0:3', 
     
    526527                   'Get_errhandler' => 'MPI_Errhandler', 
    527528                   'Set_errhandler' => 0, 
    528                    'Call_errhandler' => 0, 
     529                   # this routine is special and cannot be autogenerated 
     530                   #'Call_errhandler' => 0, 
    529531                   );            
    530532#     %class_mpi2file = (  
     
    590592                    'Fence' => '0',  
    591593                    'Get_group' => 'MPI_Group', 
    592                     'Call_errhandler' => 0, 
     594                    # this routine is special and cannot be auto-generated 
     595                    #'Call_errhandler' => 0, 
    593596                    'Get_attr' => '0', 
    594597                    'Start' => '0', 
     
    17311734        # Errors_return is not quite right for errors-throw-exceptions, 
    17321735        # but it is close. 
    1733         print $OUTFD "const Errhandler ERRORS_THROW_EXCEPTIONS(MPI_ERRORS_RETURN);\n"; 
     1736        print $OUTFD "const Errhandler ERRORS_THROW_EXCEPTIONS(MPI_ERRORS_THROW_EXCEPTIONS);\n"; 
    17341737    } 
    17351738    else { 
     
    23392342    return e1; 
    23402343} 
     2344 
     2345 
     2346// Call_errhandler implementations.  These sadly must contain a bit of logic to 
     2347// cover the ERRORS_THROW_EXCEPTIONS case. 
     2348void Comm::Call_errhandler( int errorcode ) const 
     2349{ 
     2350    if (Get_errhandler() == ERRORS_THROW_EXCEPTIONS) { 
     2351        throw Exception(errorcode); // throw by value, catch by reference 
     2352    } 
     2353    MPIX_CALL( MPI_Comm_call_errhandler( (MPI_Comm) the_real_comm, errorcode )); 
     2354} 
     2355 
     2356void Win::Call_errhandler( int errorcode ) const 
     2357{ 
     2358    if (Get_errhandler() == ERRORS_THROW_EXCEPTIONS) { 
     2359        throw Exception(errorcode); // throw by value, catch by reference 
     2360    } 
     2361    MPIX_CALL( MPI_Win_call_errhandler( (MPI_Win) the_real_win, errorcode )); 
     2362} 
     2363 
     2364void File::Call_errhandler( int errorcode ) const 
     2365{ 
     2366    if (Get_errhandler() == MPI_ERRORS_THROW_EXCEPTIONS) { 
     2367        throw Exception(errorcode); // throw by value, catch by reference 
     2368    } 
     2369    MPIX_CALL( MPI_File_call_errhandler( (MPI_File) the_real_file, errorcode )); 
     2370} 
     2371 
    23412372\n"; 
    23422373 
     
    26022633# Add the routine to initialize MPI datatype names for the C++ datatypes 
    26032634print $OUTFD " 
     2635/* MT FIXME: this is not thread-safe */ 
    26042636void MPIR_CXX_InitDatatypeNames( void ) 
    26052637{ 
     
    30563088    *(void **)attr_out = attr_in; return 0;}  
    30573089    static Errhandler Create_errhandler( Errhandler_fn * ); 
     3090    virtual void Call_errhandler( int errcode ) const; 
    30583091\n"; 
    30593092} 
     
    30663099 
    30673100    static Errhandler Create_errhandler( Errhandler_fn * ); 
     3101    virtual void Call_errhandler( int errcode ) const; 
    30683102\n"; 
    30693103} 
     
    30763110 
    30773111    static Errhandler Create_errhandler( Errhandler_fn * ); 
     3112    virtual void Call_errhandler( int errcode ) const; 
    30783113 
    30793114    typedef int Copy_attr_function(const Win& oldwin, int win_keyval, void* extra_state, void* attribute_val_in, void* attribute_val_out, bool& flag);  
  • mpich2/trunk/src/include/mpi.h.in

    r820 r850  
    211211#define MPI_ERRORS_ARE_FATAL ((MPI_Errhandler)0x54000000) 
    212212#define MPI_ERRORS_RETURN    ((MPI_Errhandler)0x54000001) 
    213       /* #define MPIR_ERRORS_WARN     ((MPI_Errhandler)0x54000002) */ 
     213/* MPI_ERRORS_THROW_EXCEPTIONS is not part of the MPI standard, it is here to 
     214   facilitate the c++ binding which has MPI::ERRORS_THROW_EXCEPTIONS. */ 
     215#define MPI_ERRORS_THROW_EXCEPTIONS ((MPI_Errhandler)0x54000002) 
    214216typedef int MPI_Errhandler; 
    215217 
  • mpich2/trunk/src/mpi/errhan/errutil.c

    r100 r850  
    113113 
    114114/* Preallocated errorhandler objects */ 
    115 MPID_Errhandler MPID_Errhandler_builtin[2] =  
     115MPID_Errhandler MPID_Errhandler_builtin[3] =  
    116116          { { MPI_ERRORS_ARE_FATAL, 0}, 
    117             { MPI_ERRORS_RETURN, 0} };  
     117            { MPI_ERRORS_RETURN, 0}, 
     118            { MPI_ERRORS_THROW_EXCEPTIONS, 0} };  
    118119MPID_Errhandler MPID_Errhandler_direct[MPID_ERRHANDLER_PREALLOC] = { {0} }; 
    119120MPIU_Object_alloc_t MPID_Errhandler_mem = { 0, 0, 0, 0, MPID_ERRHANDLER,  
  • mpich2/trunk/test/mpi/errors/cxx/errhan/throwtest.cxx

    r781 r850  
    1313/* #define VERBOSE */ 
    1414 
     15/* returns number of errors found */ 
     16template <class T> 
     17int testCallErrhandler(T &obj, int errorClass, int errorCode, std::string errorString) 
     18{ 
     19    int errs = 0; 
     20 
     21    try { 
     22        obj.Call_errhandler(errorCode); 
     23        std::cerr << "Do Not See This" << std::endl; 
     24        errs++; 
     25    } 
     26    catch (MPI::Exception &ex) { 
     27#ifdef VERBOSE 
     28        std::cerr << "MPI Exception: " << ex.Get_error_string() << std::endl; 
     29#endif 
     30        if (ex.Get_error_code() != errorCode) { 
     31            std::cout << "errorCode does not match" << std::endl; 
     32            errs++; 
     33        } 
     34        if (ex.Get_error_class() != errorClass) { 
     35            std::cout << "errorClass does not match" << std::endl; 
     36            errs++; 
     37        } 
     38        if (ex.Get_error_string() != errorString) { 
     39            std::cout << "errorString does not match" << std::endl; 
     40            errs++; 
     41        } 
     42    } 
     43    catch (...) { 
     44        std::cerr << "Caught Unknown Exception" << std::endl; 
     45        errs++; 
     46    } 
     47 
     48    return errs; 
     49} 
     50 
    1551int main( int argc, char *argv[] ) 
    1652{ 
    1753    int errs = 0; 
    18    
     54    MPI::Win win = MPI::WIN_NULL; 
     55    MPI::File file = MPI::FILE_NULL; 
     56 
    1957    MPI::Init(); 
    2058 
     
    2361    int errorClass = MPI::Add_error_class(); 
    2462    int errorCode = MPI::Add_error_code(errorClass); 
    25     MPI::Add_error_string(errorCode, "Internal-use Error Code"); 
     63    std::string errorString = "Internal-use Error Code"; 
     64    MPI::Add_error_string(errorCode, errorString.c_str()); 
     65 
     66    win = MPI::Win::Create(NULL, 0, 1, MPI::INFO_NULL, MPI_COMM_WORLD); 
     67    file = MPI::File::Open(MPI::COMM_WORLD, "testfile", MPI::MODE_WRONLY | MPI::MODE_CREATE | MPI::MODE_DELETE_ON_CLOSE, MPI::INFO_NULL); 
    2668 
    2769    MPI::COMM_WORLD.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS); 
    28      
    29     try { 
    30       if (rank == 0) { 
    31         MPI::COMM_WORLD.Call_errhandler(errorCode); 
    32         std::cerr << "Do Not See This\n"; 
    33         errs++; 
    34       } 
    35     } 
    36     catch (MPI::Exception ex) { 
    37 #ifdef VERBOSE 
    38     std::cerr << "MPI Exception: " << ex.Get_error_string() << std::endl; 
    39 #endif 
    40     } 
    41     catch (...) { 
    42       std::cerr << "Caught Unknown Exception\n"; 
    43       errs++; 
     70    win.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS); 
     71    file.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS); 
     72 
     73    if (0 == rank) { 
     74        errs += testCallErrhandler(MPI::COMM_WORLD, errorClass, errorCode, errorString); 
     75        errs += testCallErrhandler(win,             errorClass, errorCode, errorString); 
     76        errs += testCallErrhandler(file,            errorClass, errorCode, errorString); 
    4477    } 
    4578 
    4679    if (errs == 0) { 
    47       std::cout << " No Errors" << std::endl; 
     80        std::cout << " No Errors" << std::endl; 
    4881    } 
    4982    else { 
    50       std::cout << " Found " << errs << " errors" << std::endl; 
     83        std::cout << " Found " << errs << " errors" << std::endl; 
    5184    } 
    5285