是否可以自定义错误函数处理程序以查找与无效通信器(通常为NULL通信器)有关的错误?
似乎我 can 甚至无法通过调用MPI_Comm_set_errhandler( MPI_COMM_NULL, newerr );
示例太简单了,MPI_COMM_NULL是硬编码,但想法是有时通信器在运行时可能为NULL。
那么,在全局库级别有一个错误处理程序来捕获NULL通信器的错误吗?
#include "mpi.h"
#include <stdio.h>
#include<assert.h>
static int calls = 0;
static int errs = 0;
static MPI_Comm mycomm;
void eh( MPI_Comm *comm, int *err, ... )
{
printf( "eh called\n" );fflush(stdout);
if (*err != MPI_ERR_OTHER) {
errs++;
printf( "Unexpected error code\n" );fflush(stdout);
}
if (*comm != mycomm) {
errs++;
printf( "Unexpected communicator\n" );fflush(stdout);
}
calls++;
return;
}
int main( int argc, char *argv[] )
{
MPI_Comm comm;
MPI_Errhandler newerr;
MPI_Init( &argc, &argv );
comm = MPI_COMM_NULL;//MPI_COMM_WORLD;
mycomm = comm;
MPI_Comm_create_errhandler( eh, &newerr );
int s = MPI_Comm_set_errhandler( comm, newerr ); // Gives fatal error
assert(s == MPI_SUCCESS);
int rank = -1;
MPI_Comm_rank( comm, &rank );
MPI_Comm_call_errhandler( comm, MPI_ERR_OTHER );
MPI_Errhandler_free( &newerr );
if (calls != 1) {
errs++;
printf( "Error handler not called\n" );fflush(stdout);
}
MPI_Finalize();
return 0;
}
我同时使用MPICH
和OpenMPI
,结果相同。
我检查了MPICH的实现,这是在文件include/mpiimpl.h
中签入无效/ null通信器的点(例如从int MPI_Comm_rank( MPI_Comm comm, int *rank )
调用)
我没有立即看到一个允许捕获此错误的自定义点。
/* Check not only for a null pointer but for an invalid communicator,
such as one that has been freed. Let's try the ref_count as the test
for now */
/* ticket #1441: check (refcount<=0) to cover the case of 0, an "over-free" of
* -1 or similar, and the 0xecec... case when --enable-g=mem is used */
#define MPID_Comm_valid_ptr(ptr,err,ignore_rev) { \
MPID_Valid_ptr_class(Comm,ptr,MPI_ERR_COMM,err); \
if ((ptr) && MPIU_Object_get_ref(ptr) <= 0) { \
MPIR_ERR_SET(err,MPI_ERR_COMM,"**comm"); \
ptr = 0; \
} else if ((ptr) && (ptr)->revoked && !(ignore_rev)) { \
MPIR_ERR_SET(err,MPIX_ERR_REVOKED,"**comm"); \
} \
}
答案 0 :(得分:1)
是否可以自定义错误函数处理程序以解决与无效通信器(通常为NULL通信器)有关的错误?
不,你不能。文件明确说明:
错误
所有MPI例程(MPI_Wtime和MPI_Wtick除外)都返回错误值;
...
MPI_ERR_COMM
无效的传播者。常见的错误是在调用中使用空通信器(甚至在MPI_Comm_rank中都不允许)。
您认为此调用已成功,因为您尚未检查返回值