gpt4 book ai didi

c++ - 来自环形拓扑的全局最大值,而不是来自 C++ 中的 MPI_REDUCE

转载 作者:行者123 更新时间:2023-11-28 05:25:29 25 4
gpt4 key购买 nike

我希望运行一次效率测试以使用 MPI 找到全局最大值,一次使用环形拓扑并再次使用 MPI_REDUCE 函数。我已经在我的代码中执行了 MPI_REDUCE 并且它工作正常但我想通过环传递产生相同的结果。

我的想法是为每个处理器的局部最大值创建一个数组,然后将这些最大值传递到环中,最后输出全局最大值。

不幸的是,我意识到我无法定义一个单一的数组来保存进程的最大值,而是我最终制作了从 4 个进程生成的 4 个不同的数组。然后我开始从 rank = 0 处理器开始传递 array[0] 值,而不是只传递一个 max ,我必须传递 4 个不同的数组值,因为我生成了 4 个不同的数组。更糟糕的是,即使经过所有这些努力,我也没有得到全局最大值,因为我只从一行 MPI_REDUCE 代码中得到了。必须有一种方法可以从环形拓扑中获得全局最大值,而我只是让事情变得复杂。

主要部分代码如下:

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

MPI_Init (&argc, &argv); // initializes MPI
MPI_Comm_rank (MPI_COMM_WORLD, &rank); // get current MPI-process ID. O, 1, ...
MPI_Comm_size (MPI_COMM_WORLD, &size); // get the total number of processes

/* define how many integrals */
const int n = 10;

double b[n] = {5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,5.0};
double a[n] = {-5.0, -5.0, -5.0, -5.0, -5.0, -5.0, -5.0, -5.0, -5.0,-5.0};

double result, mean;
int m;

const unsigned int N = 5;
double max = 0;
double max_store[4];

cout.precision(6);
cout.setf(ios::fixed | ios::showpoint);

srand(time(NULL) * rank); // each MPI process gets a unique seed

m = 4; // initial number of intervals

// convert command-line input to N = number of points
//N = atoi( argv[1] );
for (unsigned int i=0; i <=N; i++)
{
result = int_mcnd(f, a, b, n, m);
mean = result/(pow(10,10));

m = m*4;
if( mean > max)
{
max = mean;
}
if ( rank < 4 && rank >= 0 )
{
max_store[rank] = max;
}
}

//print the array containing max from each processor
for( int k = 0; k < 4; k++ )
{
printf( "%1.5e\n", max_store[k]);
}

printf("Process ID %i, local_max = %f\n",rank, max);

// All processes get the global max, stored in place of the local max
MPI_Allreduce( MPI_IN_PLACE, &max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD );

printf("Process ID %d, global_max = %f\n",rank, max);

double send_junk = max_store[0];
double rec_junk;
//double global_max;
MPI_Status status;

if(rank==0)
{
MPI_Send(&send_junk, 4, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD); // send data to process 1
}
if(rank==1)
{
MPI_Recv(&rec_junk, 4, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &status); // receive data from process 0
}
//check between process 0 and process 1 maxima
if(rec_junk>=max_store[1])
{
rec_junk = max_store[0];
}
else
{
rec_junk = max_store[1];
}
send_junk = rec_junk;

MPI_Send(&send_junk, 4, MPI_DOUBLE, 2, 0, MPI_COMM_WORLD); // send data to process 2

if(rank==2)
{
MPI_Recv(&rec_junk, 4, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD, &status); // receive data from process 1
}
//check between process 1 and process 2 maxima
if(rec_junk>=max_store[2])
{
rec_junk = rec_junk;
}
else
{
rec_junk = max_store[2];
}
send_junk = rec_junk;

MPI_Send(&send_junk, 4, MPI_DOUBLE, 3, 0, MPI_COMM_WORLD); // send data to process 3

if(rank==3)
{
MPI_Recv(&rec_junk, 4, MPI_DOUBLE, 2, 0, MPI_COMM_WORLD, &status); // receive data from process 2
}
//check between process 2 and process 3 maxima
if(rec_junk>=max_store[3])
{
rec_junk = rec_junk;
}
else
{
rec_junk = max_store[3];
}

printf("global ring max = %f", rec_junk);

MPI_Finalize(); // programs should always perform a "graceful" shutdown
return 0;
}

我有问题:

  1. 我可以轻松打印和查看进程 ID 和局部最大值,但如何将局部最大值存储在单个数组中?

  2. 使用环形拓扑寻找全局最大值的更有效方法是什么?

非常欢迎您的建议。谢谢

最佳答案

要将所有进程的本地结果收集到一个数组中,如果您希望它们都在进程 0 中,请使用 MPI_Gather,或者在每个进程中获取它们时使用 MPI_Allgather

关于c++ - 来自环形拓扑的全局最大值,而不是来自 C++ 中的 MPI_REDUCE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40623595/

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