gpt4 book ai didi

sum - 如何使用 MPI_Reduce 独立地对不同处理器组的不同值求和

转载 作者:行者123 更新时间:2023-12-01 19:09:07 25 4
gpt4 key购买 nike

我试图将我的处理器分成几组,然后添加每组的总和独立地......但直到现在我还无法正确找到结果。一个简单的例子如下:

int main(int argc, char** argv) 
{
int size, rank,i=0,localsum1=0,globalsum1=0,localsum2=0,globalsum2=0;

MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);

if(rank==0)
{
}
else if(rank==1)
{
localsum1 += 5;
MPI_Reduce(&localsum1,&globalsum1,2,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
}
else if(rank==2)
{
localsum2 += 10;
MPI_Reduce(&localsum2,&globalsum2,2,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
}

if(rank==0)
{
printf("globalsum1 = %d \n",globalsum1);
printf("globalsum2 = %d \n",globalsum2);
}
MPI_Finalize();

return (EXIT_SUCCESS);
}

我不知道这里缺少什么......任何人都可以帮忙吗?

最佳答案

MPI_Reducecollective operation 。这意味着参与通信器中的所有任务都必须进行 MPI_Reduce() 调用。在上面,rank 0 从不调用 MPI_Reduce(),因此该程序将挂起,因为其他一些处理器会等待 rank 0 的参与,而该参与永远不会到来。

另外,因为是对整个通信器的集体操作,所以需要做一些分区归约的工作。一种方法是减少整数数组,并让每个处理器仅贡献数组中的元素:

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

int main(int argc, char** argv)
{
int size, rank;

MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);

int localsum[2] = {0,0};
int globalsum[2] = {0,0};

if(rank % 2 == 1)
{
localsum[0] += 5;
}
else if( rank > 0 && (rank % 2 == 0))
{
localsum[1] += 10;
}

MPI_Reduce(localsum,globalsum,2,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);

if(rank==0)
{
printf("globalsum1 = %d \n",globalsum[0]);
printf("globalsum2 = %d \n",globalsum[1]);
}

MPI_Finalize();

return (EXIT_SUCCESS);
}

现在运行会给出

$ mpicc -o reduce reduce.c
$ mpirun -np 3 ./reduce
globalsum1 = 5
globalsum2 = 10

否则,您可以创建仅连接您想要参与每个总和的处理器的通信器,并在每个通信器内进行归约。下面是一个不太漂亮的方法来做到这一点。一般来说,这非常强大,但比第一个解决方案更复杂:

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

int main(int argc, char** argv)
{
int size, rank;

MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);

int localsum = 0;
int globalsum = 0;

MPI_Comm comm_evens_plus_root, comm_odds_plus_root;
MPI_Group grp_evens_plus_root, grp_odds_plus_root, grp_world;

MPI_Comm_group(MPI_COMM_WORLD, &grp_world);
int *ranks = malloc((size/2 + 1) * sizeof(rank));
int i,j;
for (i=1, j=0; i<size; i+=2, j+=1)
ranks[j] = i;
MPI_Group_excl(grp_world, j, ranks, &grp_evens_plus_root);
MPI_Comm_create(MPI_COMM_WORLD, grp_evens_plus_root, &comm_evens_plus_root);

for (i=2, j=0; i<size; i+=2, j+=1)
ranks[j] = i;
MPI_Group_excl(grp_world, j, ranks, &grp_odds_plus_root);
MPI_Comm_create(MPI_COMM_WORLD, grp_odds_plus_root, &comm_odds_plus_root);

free(ranks);

if(rank % 2 == 1)
{
localsum += 5;
MPI_Reduce(&localsum,&globalsum,1,MPI_INT,MPI_SUM,0,comm_odds_plus_root);
}
else if( rank > 0 && (rank % 2 == 0))
{
localsum += 10;
MPI_Reduce(&localsum,&globalsum,1,MPI_INT,MPI_SUM,0,comm_evens_plus_root);
}

if(rank==0)
{
MPI_Reduce(&localsum,&globalsum,1,MPI_INT,MPI_SUM,0,comm_odds_plus_root);
printf("globalsum1 = %d \n",globalsum);
MPI_Reduce(&localsum,&globalsum,1,MPI_INT,MPI_SUM,0,comm_evens_plus_root);
printf("globalsum2 = %d \n",globalsum);
}

MPI_Comm_free(&comm_odds_plus_root);
MPI_Comm_free(&comm_evens_plus_root);
MPI_Group_free(&grp_odds_plus_root);
MPI_Group_free(&grp_evens_plus_root);
MPI_Finalize();

return (EXIT_SUCCESS);
}

运行给予

$ mpicc -o reduce2 reduce2.c 
$ mpirun -np 3 ./reduce
globalsum1 = 5
globalsum2 = 10

关于sum - 如何使用 MPI_Reduce 独立地对不同处理器组的不同值求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14813595/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com