当您的代码使用 OpenMP 任务时,应该如何放置 try-catch 块?是否应该在每个任务中定义一个 try-catch 块,或者单个 try-catch 块是否可以包含所有任务?换句话说,考虑这段代码:
int main()
{
#pragma omp parallel
{
#pragma omp single
{
try
{
#pragma omp task
{ /*some code here*/ }
#pragma omp task
{ /*some code here*/ }
}
catch(Exception &e)
{
//I want to do something here whenever one of the tasks throws an exception
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我想捕获其中一个任务抛出的任何异常,以便打印与该异常相对应的错误消息并中止程序,上面的代码是否正确?或者我是否需要在每个任务中定义一个 try-catch 块,如下所示?:
int main()
{
#pragma omp parallel
{
#pragma omp single
{
#pragma omp task
{
try
{
/*some code here*/
}
catch(Exception &e)
{
//print an error message here if there is an exception in the task and abort the program
}
}
#pragma omp task
{
try
{
/*some code here*/
}
catch(Exception &e)
{
//print an error message here if there is an exception in the task and abort the program
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
或者我是否需要在每个任务内部有一个 try-catch 块,但也需要围绕所有任务?
OpenMP 5.1 规范指出:
\n\n\n当任何线程遇到任务生成构造时,就会生成一个或多个显式任务。显式生成的任务的执行被分配给当前团队中的线程之一,具体取决于线程\xe2\x80\x99s 执行工作的可用性。因此,新任务的执行可以是立即的,也可以根据任务调度约束和线程可用性推迟到稍后执行。允许线程在任务调度点挂起当前任务区域,以便执行不同的任务。如果挂起的任务区域用于绑定任务,则最初分配的线程稍后将恢复挂起的任务区域的执行。如果挂起的任务区域用于未绑定的任务,则任何线程都可以恢复其执行。在主线程离开该区域末尾的隐式屏障之前,保证完成绑定到给定并行区域的所有显式任务。
\n
该规范还指出:
\n\n\n在并行区域内执行的抛出必须导致执行在同一并行区域内恢复,并且抛出异常的同一线程必须捕获它。
\n
这意味着第一个代码通常不起作用,因为运行时可以稍后执行任务,甚至可以在另一个线程中执行任务(等待工作)。在您的示例中,需要在要跟踪异常的所有任务的内部代码中捕获异常。但是,这并不意味着您需要在每个任务中复制 try-catch 块。如果您需要捕获某些局部变量,您可以为其定义一个函数或带有模板的 lambda。
\n这是一个例子:
\n// You can add more parameter to tune the error message regarding \n// the code of the task. The error management could even be \n// specialized another lambda.\ntemplate <typename FunType>\nvoid catchExceptions(FunType lambda)\n{\n try\n {\n lambda();\n }\n catch(Exception& e)\n {\n // Print an error message here if there is an exception in \n // the task and abort the program.\n }\n}\n\nint main()\n{\n #pragma omp parallel\n #pragma omp single\n {\n #pragma omp task\n catchExceptions([&](){\n /*some code here*/\n });\n\n #pragma omp task\n catchExceptions([&](){\n /*some code here*/\n });\n }\n}\n\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
516 次 |
| 最近记录: |