MPI_Bcast在if语句中?
我正在尝试MPI,当我在命令行上通过mpirun运行它时,我一直收到此错误。
---------------------------------------------------------------------------------------------- mpirun noticed that the job aborted, but has no info as to the process that caused that situation. ----------------------------------------------------------------------------------------------
我不确定为什么,因为其他mpi程序运行完全正常。
这是我的代码。
#include #include int func(int num){ int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (num == 0){ num = 5; MPI_Bcast(&num, 1, MPI_INT, rank, MPI_COMM_WORLD); } return num; } int main(int argc, char **argv){ int rank, size; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); printf("On processor %d, func returns %d\n", rank, func(rank)); MPI_Finalize(); return 0; }
该程序仍然给我同样的错误。 MPI_Bcast是否在if语句中无效? 如果你在不是根的情况下尝试广播,它仍然有效吗?
我在任何参考文档中看到的MPI_Bcast
的签名是int MPI_Bcast(void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
。 但是,您只传递了四个参数,看起来您忘记了第一个或第二个参数。
你的情况是多少,你的缓冲区是什么? 答案可能会解决您的问题,但我也不确定为什么您的代码甚至会编译。 如果num
是您要广播的内容,请尝试MPI_Bcast(& num, 1, MPI_INT, rank, MPI_COMM_WORLD)
是否适合您。
还有另一个非常严重的独立问题。 你有一些int rank;
在您的堆栈上,并在初始化之前将其传递给MPI_Bcast
。 谁在发送? 如果是root,你也可以传递0
,或者通过int rank = 0;
正确初始化int rank = 0;
。
rank
未确定值几乎肯定是您的工作中止的原因,因为实例将随机发送或接收。
这段代码毫无意义。 MPI_Bcast
是一个集体通信调用 ,这意味着,为了使操作成功完成,所提供的通信器中的所有等级(在您的情况下为MPI_COMM_WORLD
) 必须调用它。 MPI_Bcast
也是一个有根的操作,这意味着有一个指定的信息源,这是具有指定等级的进程。 因此除了要求所有排名必须调用MPI_Bcast
,他们都必须为root提供相同的排名。
仅当func
的num
参数为0
,您的程序才会调用MPI_Bcast
,这只发生在0
级。 在所有其他等级中, func
不会调用MPI_Bcast
,它们只是完成库并退出。 这导致MPI_Bcast
最终失败,因为它试图将消息发送到不再可用的进程,最终导致错误(“最终”,因为标准允许早期本地完成,在某些情况下,特别是对于您的情况下的小消息,发送缓冲)。 默认情况下,MPI通过中止作业而不是返回错误代码来处理错误。
没有任何东西可以阻止你从条件中调用任何MPI集合函数,但你必须小心并确保所有级别最终都进行集体调用,无论他们采取什么代码路径来执行此操作。
你的func
的正确版本是:
int func(int num) { if (num == 0) { num = 5; } MPI_Bcast(&num, 1, MPI_INT, 0, MPI_COMM_WORLD); return num; }
通过“从条件内调用”可能是:
int func(int num) { int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { num = 5; MPI_Bcast(&num, 1, MPI_INT, 0, MPI_COMM_WORLD); } else MPI_Bcast(&num, 1, MPI_INT, 0, MPI_COMM_WORLD); return num; }
(但这显然是不必要的)