您好我希望找到所有进程的局部最大值,然后将所有局部最大值传递给所有进程以生成单个数组,然后使用MPI环拓扑来比较局部最大值,然后最终输出全局最大值。
我可以更高效地执行MPI_ALLreduce并且已经这样做了,但我想测试环形拓扑的效率并产生与allreduce相同的结果。 我正在按照教程使用MPI_Allgather,它返回了一些错误。代码如下:
int main(int argc, char **argv)
{
int rank, size;
MPI_Init (&argc, &argv); // initializes MPI
//MPI_Comm comm;
double max_store[4];
double *rbuf;
//MPI_Comm_size( comm, &rank);
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 = -1;
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;
//}
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);
rbuf = (double *)malloc(rank*4*sizeof(double));
MPI_Allgather( max_store, 4, MPI_DOUBLE, rbuf, 4, MPI_DOUBLE, MPI_COMM_WORLD);
//print the array containing max from each processor
//int k;
//for( int k = 0; k < 4; k++ )
//{
//printf( "%1.5e\n", max_store[k]);
//}
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;
}
我很想知道如何在单个阵列中发送最大值,并且所有进程都可以访问它,这样我就可以比较环形拓扑中的值。非常感谢。
答案 0 :(得分:1)
您没有正确分配接收缓冲区。它需要足够大才能存储每个等级的4个条目。你现在有:
rbuf = (double *)malloc(rank*4*sizeof(double));
什么时候应该
rbuf = (double *)malloc(size*4*sizeof(double));