您可以使用 MPI_MIN 来获取通过归约传递的最小值。
让我们检查一下函数声明:
int MPI_Reduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype
datatype, MPI_Op op, int root, MPI_Comm comm)
每个进程使用缓冲区sendbuff 发送它的值(或值数组)。
由root id 标识的进程接收缓冲区并将它们存储在缓冲区recvbuf 中。从每个其他进程接收的元素数量在 count 中指定,因此必须为 recvbuff 分配维度 sizeof(datatype)*count。
如果每个进程只有一个整数要发送(count = 1),那么recvbuff 它也是一个整数,如果每个进程都有两个整数,那么recvbuff 它是一个大小为 2 的整数数组。请参阅这个不错的post 了解更多信息解释和漂亮的图片。
现在应该清楚你的代码是错误的,sendbuff 和recvbuff 的大小必须相同,并且不需要条件:if(myrank==0)。简单地说,recvbuff 仅对 root 进程有意义,sendbuff 对其他进程有意义。
在您的示例中,您可以将数组的一个或多个元素分配给不同的进程,然后计算最小值(如果进程数与数组中的值一样多)或最小值数组(如果值多于进程)。
这是一个工作示例,说明在简单值(不是数组)的情况下,MPI_MIN、MPI_MAX 和 MPI_SUM(从 this 稍作修改)的用法。
每个进程根据它们的等级做一些工作,并将花在工作上的时间发送给根进程。根进程收集时间并输出时间的最小值、最大值和平均值。
#include <stdio.h>
#include <mpi.h>
int myrank, numprocs;
/* just a function to waste some time */
float work()
{
float x, y;
if (myrank%2) {
for (int i = 0; i < 100000000; ++i) {
x = i/0.001;
y += x;
}
} else {
for (int i = 0; i < 100000; ++i) {
x = i/0.001;
y += x;
}
}
return y;
}
int main(int argc, char **argv)
{
int node;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD, &node);
printf("Hello World from Node %d\n",node);
/*variables used for gathering timing statistics*/
double mytime,
maxtime,
mintime,
avgtime;
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Barrier(MPI_COMM_WORLD); /*synchronize all processes*/
mytime = MPI_Wtime(); /*get time just before work section */
work();
mytime = MPI_Wtime() - mytime; /*get time just after work section*/
/*compute max, min, and average timing statistics*/
MPI_Reduce(&mytime, &maxtime, 1, MPI_DOUBLE,MPI_MAX, 0, MPI_COMM_WORLD);
MPI_Reduce(&mytime, &mintime, 1, MPI_DOUBLE, MPI_MIN, 0,MPI_COMM_WORLD);
MPI_Reduce(&mytime, &avgtime, 1, MPI_DOUBLE, MPI_SUM, 0,MPI_COMM_WORLD);
/* plot the output */
if (myrank == 0) {
avgtime /= numprocs;
printf("Min: %lf Max: %lf Avg: %lf\n", mintime, maxtime,avgtime);
}
MPI_Finalize();
return 0;
}
如果我在我的 OSX 笔记本电脑上运行它,这就是我得到的:
urcaurca$ mpirun -n 4 ./a.out
Hello World from Node 3
Hello World from Node 0
Hello World from Node 2
Hello World from Node 1
Min: 0.000974 Max: 0.985291 Avg: 0.493081