Elegant exception handling in OpenMP

OpenMP forbids code that leaves the openmp block through an exception. Therefore, I am looking for a good way to get exceptions from the openmp block in order to drag it into the main stream and process it at a later point. So far, the best I could come up with is the following:

class ThreadException { std::exception_ptr Ptr; std::mutex Lock; public: ThreadException(): Ptr(nullptr) {} ~ThreadException(){ this->Rethrow(); } void Rethrow(){ if(this->Ptr) std::rethrow_exception(this->Ptr); } void CaptureException() { std::unique_lock<std::mutex> guard(this->Lock); this->Ptr = std::current_exception(); } }; //... ThreadException except; #pragma omp parallel { try { //some possibly throwing code } catch(...) { except.CaptureException(); } } 

Although this works well, reorganizing possible exceptions from the parallel section as soon as the ThreadException is destroyed, this construct is still a bit cumbersome to use when placing try {}catch(...){} around each section and necessary manually catch the exception.

So my question is: does anyone know a more elegant (less detailed) way to do this (and if so, what does it look like)?

+6
source share
1 answer

You can use some more C ++ 11 tools to clear the syntax. Add this member function variable to the ThreadException class:

 class ThreadException { // ... template <typename Function, typename... Parameters> void Run(Function f, Parameters... params) { try { f(params...); } catch (...) { CaptureException(); } } }; 

Then, when calling inside the OpenMP construct, use the lambda function as follows:

 ThreadException e; #pragma omp parallel for for (int i = 0; i < n; i++) { e.Run([=]{ // code that might throw // ... }); } e.Rethrow() 
+8
source

Source: https://habr.com/ru/post/922215/


All Articles