[Mpi-forum] how to get MPI::Exception behavior from C bindings?
Cownie, James H
james.h.cownie at intel.com
Wed Nov 2 06:08:29 CDT 2011
> For example, if you have a call stack A->B->C->D->E, and E throws an exception, if the only matching "catch" statement
> for that specific exception is way up in B, then it effectively bypasses the rest of E, D, and C, and jumps up to the
> matching "catch" in B.
But, critically, the runtime also executes destructors for any local variables that have them in the frames that are being unwound
(E,D,C here), so it's not *just* a longjump...
-- Jim
James Cownie <james.h.cownie at intel.com>
SSG/DPD/TCAR (Technical Computing, Analyzers and Runtimes)
Tel: +44 117 9071438
-----Original Message-----
From: mpi-forum-bounces at lists.mpi-forum.org [mailto:mpi-forum-bounces at lists.mpi-forum.org] On Behalf Of Jeff Squyres
Sent: Tuesday, November 01, 2011 11:46 PM
To: Main MPI Forum mailing list
Subject: Re: [Mpi-forum] how to get MPI::Exception behavior from C bindings?
My $0.02:
1. Darius is right that you can write your own error handler function, register it with MPI_<foo>_CREATE_ERRHANDLER, and just throw an exception in your user-defined function that is caught in the same way that Jeff's sample madness code. This is the easiest conversion (it's essentially what we did for the first generation of the portable C++ bindings package in the mid-90's; the versions integrated into various MPI implementations these days are basically the same idea).
You'll need to ensure that your MPI library is compiled to pass C++ exceptions through C code (you need to do this today, anyway, but it may no longer be the default if MPI implementations actually remove the C++ bindings. FWIW, OMPI doesn't enable this by default because there's a slight performance penalty at every function call, even in the we-never-threw-an-exception case).
2. If you keep this purely in C, it's a little messy. The benefit of exceptions is that they're kinda like longjumps.
For example, if you have a call stack A->B->C->D->E, and E throws an exception, if the only matching "catch" statement for that specific exception is way up in B, then it effectively bypasses the rest of E, D, and C, and jumps up to the matching "catch" in B.
So to convert this to C, you'll need to set ERRORS_RETURN and then check the return value from all MPI functions and all functions that call MPI functions. Eg:
void A() { ... B(); ... }
void B() { ... if (C() != MPI_SUCCESS) error(); ... } void C() { ... if ((ret = D()) != MPI_SUCCESS) return ret; ... } void D() { ... if ((ret = E()) != MPI_SUCCESS) return ret; ... } void E() { ... if ((ret = MPI_<whatever>()) != MPI_SUCCESS) return ret; ... }
In Jeff's example below, if the MPI function is invoked directly in ((ThreadBase*)(self))->run(), then it's not quite as ugly as this, but the idea is the same.
Of course, both 1) and 2) are somewhat of a losing game anyway since not many MPI implementations have well-defined semantics for what happens inside MPI after ERRORS_RETURN, anyway. :-)
On Nov 1, 2011, at 6:29 PM, Darius Buntinas wrote:
>
> Create an error handler (function) that throws a C++ exception, then wherever the original code set the error handler to MPI:ERRORS_THROW_EXCEPTIONS, use your new error handler.
>
> I haven't looked up the standard here, but it might say that the error handler must return. If it does, then this would not be allowed, otherwise, this should work.
>
> -d
>
>
> On Nov 1, 2011, at 4:18 PM, Jeff Hammond wrote:
>
>> Can someone explain how one can migrate (backwards) from the C++ to
>> the C bindings if they currently use MPI::Exception in a try-catch
>> block like this:
>>
>> ===================================
>> try {
>> ((ThreadBase*)(self))->run();
>> }
>> catch (const MPI::Exception& e) {
>> error("caught an MPI exception");
>> }
>> ===================================
>>
>> This is taken from MADNESS, btw.
>>
>> I think it is only fair for those who want to kill the C++ bindings
>> to provide a clear description of how this will not break existing
>> codes that use C++ bindings. Clearly, many things, e.g. MPI::BYTE ->
>> MPI_BYTE, are trivial, but I see error handling as being
>> fundamentally nontrivial.
>>
>> Thanks,
>>
>> Jeff
>>
>> --
>> Jeff Hammond
>> Argonne Leadership Computing Facility University of Chicago
>> Computation Institute jhammond at alcf.anl.gov / (630) 252-5381
>> http://www.linkedin.com/in/jeffhammond
>> https://wiki.alcf.anl.gov/index.php/User:Jhammond
>> _______________________________________________
>> mpi-forum mailing list
>> mpi-forum at lists.mpi-forum.org
>> http://lists.mpi-forum.org/mailman/listinfo.cgi/mpi-forum
>
>
> _______________________________________________
> mpi-forum mailing list
> mpi-forum at lists.mpi-forum.org
> http://lists.mpi-forum.org/mailman/listinfo.cgi/mpi-forum
--
Jeff Squyres
jsquyres at cisco.com
For corporate legal information go to:
http://www.cisco.com/web/about/doing_business/legal/cri/
_______________________________________________
mpi-forum mailing list
mpi-forum at lists.mpi-forum.org
http://lists.mpi-forum.org/mailman/listinfo.cgi/mpi-forum
---------------------------------------------------------------------
Intel Corporation (UK) Limited
Registered No. 1134945 (England)
Registered Office: Pipers Way, Swindon SN3 1RJ
VAT No: 860 2173 47
This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
More information about the mpi-forum
mailing list