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