gpt4 book ai didi

c - MPI_Allreduce 的高效使用

转载 作者:太空宇宙 更新时间:2023-11-04 03:25:11 24 4
gpt4 key购买 nike

我在每个处理器上都有一个列表 range 和数字。我想确定这些列表 range 中每一行的最大数量。

enter image description here

前四个列出了每个处理器 P0-P3 的 range。红色列表包含 MPI_Allreduce 之后的每个处理器获取的每一行的最大值。

这是我的代码的工作版本:

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

//#define KEY_MAX 100

typedef struct{
int myrank;
int numprocs;
int *range;
} SubDomainKeyTree;

void compRange(SubDomainKeyTree *s, int myrank, int numprocs){
s->myrank = myrank;
s->numprocs = numprocs;

// Allocate memory for (numprocs+1) ranges
s->range = malloc((numprocs+1) * sizeof(int));
// Compute range values
for(int p=0; p<=numprocs; p++){
s->range[p] = rand()%100;
}

for(int p=0; p<s->numprocs; p++){
if(s->myrank == p){
for(int k=0; k<=s->numprocs; k++){
printf("Processor %d: %d random number is %d\n", p, k, s->range[k]);
}
printf("\n");
}
}
}

void compDynRange(SubD *s){

int rangeForAll[s->numprocs+1];
//////////////////////////////////
// This is not really efficient //
//////////////////////////////////
for(int r=0; r<=s->numprocs; r++){
MPI_Allreduce(&s->range[r], &rangeForAll[r], 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
}

for(int p=0; p<s->numprocs; p++){
if(s->myrank == p){
for(int k=0; k<=s->numprocs; k++){
s->range[k] = rangeForAll[k];
printf("Processor %d: %d random number after MPI_Allreduce is %d\n", p, k, s->range[k]);
}
printf("\n");
}
}
}

int main(int argc, char **argv){

int nameLen;
char processorName[MPI_MAX_PROCESSOR_NAME];

int myrank; // Rank of processor
int numprocs; // Number of processes
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Get_processor_name(processorName,&nameLen);
MPI_Status status;

time_t t;
srand((unsigned)time(NULL)+myrank*numprocs+nameLen);

SubD s;
compRange(&s, myrank, numprocs);

compDynRange(&s);
MPI_Finalize();
return 0;
}

我使用的 for 循环对我来说似乎非常低效。这里我依次计算所有列表的每一行的最大值。

但是我可以在没有 for 循环的情况下使用 MPI_Allreduce 吗?

我已经尝试过用它代替无效的 for 循环。

MPI_Allreduce(&s->range, &rangeForAll, s->numprocs+1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);

有人可以提示我该怎么做吗?

最佳答案

正如评论中已经暗示的那样,您在代码中遇到的错误是您没有传递包含发送和接收缓冲区的数组,而是传递了一些指向它们的指针。我想这个错误只是来自最初使用的单个元素(如 &s->range[r])的变化,这是完全正确的,通过删除索引访问(即 &s->range) 这是错误的。

如前所述,使用:

MPI_Allreduce(s->range, rangeForAll, s->numprocs+1, MPI_INT, MPI_MAX, MPI_COMM_WORLD)

就可以了。但是,由于您希望将结果放入 s->range 数组而不是临时的 rangeFarAll 数组,所以最好不要定义后者,并且使用 MPI_IN_PLACE 关键字作为发送参数,使用 s->range 作为接收参数。调用变为:

MPI_Allreduce(MPI_IN_PLACE, s->range, s->numprocs+1, MPI_INT, MPI_MAX, MPI_COMM_WORLD)

s->range 同时充当发送和接收缓冲区。因此,最终结果将在调用后全部位于 s->range 缓冲区中,您无需显式复制。

关于c - MPI_Allreduce 的高效使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41741488/

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