2010-09-21 119 views
11

这些都是我在设计错误处理的算法是应该并行运行使用MPI面临的一些一般性的问题(在C++):我可以在MPI并行代码中抛出异常吗?

  • 不要例外内部的并行执行代码的工作?行为是否定义?
  • 它们是如何工作的?这对不同的实现有所不同吗?
  • 这是好的做法 - 还是应该使用返回码?

回答

6

异常在MPI代码中与串行代码的工作方式相同,但如果在通信器中的所有进程中不会引发异常,或者您可能容易死锁,则必须非常小心。

MPI_Barrier(comm);   /* Or any synchronous call */ 
if (!rank) throw Exception("early exit on rank=0"); 
MPI_Barrier(comm);   /* rank>0 deadlocks here because rank=0 exited early */ 

所有的错误处理方法都有这个问题,很难从通信器中不一致的错误中恢复。在上面的情况下,您可以执行MPI_Allreduce,以便所有等级都选择相同的分支。

我的偏好是调用错误处理程序并将它们传播到堆栈上,因为这往往会给我提供最有用/详细的错误消息,并且很容易捕捉到断点(或者错误处理程序可以将调试程序附加到自身以及发送到您的工作站在xterm)。

0

无论例外将并行执行过程中发挥作用,取决于你的编译器和MPI库实现。如果你想要可移植的行为,我会避免在这种情况下抛出异常。

如果您想了解的不仅仅是一个数字返回码错误的更多详细信息,您当然可以返回和/或通过(当然在同一进程中或通过MPI)左右误差字符串或其他对象。

7

在理想的世界中,你可以用它们来做你所要求的。对于“理想世界”,我的意思是你可以选择MPI实现并且能够自己管理它(而不是说服集群所有者为你重新配置它)。例外的最小配置将包括:- 带例外标志,可能还有其他几个。

我最常使用LAM,默认情况下,异常是禁用的。我相信这是其他实现的默认设置。

他们的工作方式与'香草'C++异常相同。他们在并行执行的代码中工作。

在你的启动代码的某个时刻,你希望让他们:

MPI::COMM_WORLD.Set_errhandler (MPI::ERRORS_THROW_EXCEPTIONS); 

(如果你的库没有配置为允许例外,这可能是一个坏主意 - 行为“不确定”,根据以LAM)

然后:

try { /* something that can fail */ } 
catch (MPI::Exception e) { 

    cout << "Oops: " << e.Get_error_string() << e.Get_error_code(); 
    MPI::COMM_WORLD.Abort (-1) ; 
} 

至于它是好还是不好的做法,我真的不能说。我还没有看到MPI黑客编写的代码中广泛使用它们,但这可能是因为根据我的经验,代码通常比C++更具有C语言特性。

错误代码和例外之间的中间地带可能是错误处理,概括地说,你可以指定当一个特定的错误(由代码表示)发生时将被调用的函数。如果您的管理员无法启用启用例外,这可能是一种选择。

相关问题