gpt4 book ai didi

用 MPI 并行实现高斯消元法

转载 作者:行者123 更新时间:2023-11-30 18:31:15 24 4
gpt4 key购买 nike

我对 MPI 非常陌生,我被要求编写一个用于高斯消除的 C 并行实现(无需旋转)。
我尝试了一下(我使用了按行分解),但我的代码不起作用。我希望有人可以在这里给我一些指示。我几天来一直在寻找问题所在,但没有成功:(
先感谢您 !

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

int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);

int i,j,k;
int map[500];
float A[500][500],b[500],c[500],x[500],sum=0.0;
double range=1.0;
int n=3;
int rank, nprocs;
clock_t begin1, end1, begin2, end2;
MPI_Status status;

MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* get current process id */
MPI_Comm_size(MPI_COMM_WORLD, &nprocs); /* get number of processes */

//////////////////////////////////////////////////////////////////////////////////

if (rank==0)
{
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
A[i][j]=range*(1.0-2.0*(double)rand()/RAND_MAX);
b[i]=range*(1.0-2.0*(double)rand()/RAND_MAX);
}
printf("\n Matrix A (generated randomly):\n");
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
printf("%9.6lf ",A[i][j]);
printf("\n");
}
printf("\n Vector b (generated randomly):\n");
for (i=0; i<n; i++)
printf("%9.6lf ",b[i]);
printf("\n\n");
}

//////////////////////////////////////////////////////////////////////////////////

begin1 =clock();

MPI_Bcast (A,n*n,MPI_DOUBLE,0,MPI_COMM_WORLD);
MPI_Bcast (b,n,MPI_DOUBLE,0,MPI_COMM_WORLD);

for(i=0; i<n; i++)
{
map[i]= i % nprocs;
}

for(k=0;k<n;k++)
{
MPI_Bcast (&A[k][k],n-k,MPI_DOUBLE,map[k],MPI_COMM_WORLD);
MPI_Bcast (&b[k],1,MPI_DOUBLE,map[k],MPI_COMM_WORLD);
for(i= k+1; i<n; i++)
{
if(map[i] == rank)
{
c[i]=A[i][k]/A[k][k];
}
}
for(i= k+1; i<n; i++)
{
if(map[i] == rank)
{
for(j=0;j<n;j++)
{
A[i][j]=A[i][j]-( c[i]*A[k][j] );
}
b[i]=b[i]-( c[i]*b[k] );
}
}
}
end1 = clock();

//////////////////////////////////////////////////////////////////////////////////

begin2 =clock();

if (rank==0)
{
x[n-1]=b[n-1]/A[n-1][n-1];
for(i=n-2;i>=0;i--)
{
sum=0;

for(j=i+1;j<n;j++)
{
sum=sum+A[i][j]*x[j];
}
x[i]=(b[i]-sum)/A[i][i];
}

end2 = clock();
}
//////////////////////////////////////////////////////////////////////////////////
if (rank==0)
{
printf("\nThe solution is:");
for(i=0;i<n;i++)
{
printf("\nx%d=%f\t",i,x[i]);

}

printf("\n\nLU decomposition time: %f", (double)(end1 - begin1) / CLOCKS_PER_SEC);
printf("\nBack substitution time: %f\n", (double)(end2 - begin2) / CLOCKS_PER_SEC);
}

return(0);

MPI_Finalize();
}

这是我收到的错误:
mpirun 已退出,因为节点 XXXX 上的 PID XXXX 的进程等级 1 未调用“finalize”就退出。这可能导致应用程序中的其他进程被 mpirun 发送的信号终止(如此处报告)。

最佳答案

正如 High Performance Mark 所注意到的,在 return(0) 之前添加 MPI_Finalize()。这段代码将运行,不会提示任何问题...但结果仍然不正确。同时,它会打印 nan 作为结果,这是错误的。

问题来自于MPI_Bcast(A,n*n,MPI_DOUBLE,...)A 定义为 float A[500][500]

  • 您需要广播指向第一个元素&A[0][0]的指针,而不是指向第一个元素的指针。
  • 如果您发送 n*n 个元素 (n=3),您将发送 A[0][0],...,A[0][8]A[1][1] 将保持未初始化状态。这可能会导致错误的结果,例如 nan。为了追求简单(懒惰……),您可以更改为 500*500
  • MPI_DOUBLE 对应于 double ...解决方案是更改为 double A[500][500]MPI_Bcast(&A[0][ 0],500*500,MPI_FLOAT,...)。对 b 执行同样的操作。

这种确定性的使用 rand() 对于调试目的非常有用...不要忘记使用 srand() 来为随机生成器提供种子!

编辑:这是代码:

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

int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);

int i,j,k;
int map[500];
double A[500][500],b[500],c[500],x[500],sum=0.0;
double range=1.0;
int n=3;
int rank, nprocs;
clock_t begin1, end1, begin2, end2;
MPI_Status status;

MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* get current process id */
MPI_Comm_size(MPI_COMM_WORLD, &nprocs); /* get number of processes */

//////////////////////////////////////////////////////////////////////////////////

if (rank==0)
{
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
A[i][j]=range*(1.0-2.0*(double)rand()/RAND_MAX);
b[i]=range*(1.0-2.0*(double)rand()/RAND_MAX);
}
printf("\n Matrix A (generated randomly):\n");
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
printf("%9.6lf ",A[i][j]);
printf("\n");
}
printf("\n Vector b (generated randomly):\n");
for (i=0; i<n; i++)
printf("%9.6lf ",b[i]);
printf("\n\n");
}

//////////////////////////////////////////////////////////////////////////////////

begin1 =clock();

MPI_Bcast (&A[0][0],500*500,MPI_DOUBLE,0,MPI_COMM_WORLD);
MPI_Bcast (b,n,MPI_DOUBLE,0,MPI_COMM_WORLD);

for(i=0; i<n; i++)
{
map[i]= i % nprocs;
}

for(k=0;k<n;k++)
{
MPI_Bcast (&A[k][k],n-k,MPI_DOUBLE,map[k],MPI_COMM_WORLD);
MPI_Bcast (&b[k],1,MPI_DOUBLE,map[k],MPI_COMM_WORLD);
for(i= k+1; i<n; i++)
{
if(map[i] == rank)
{
c[i]=A[i][k]/A[k][k];
}
}
for(i= k+1; i<n; i++)
{
if(map[i] == rank)
{
for(j=0;j<n;j++)
{
A[i][j]=A[i][j]-( c[i]*A[k][j] );
}
b[i]=b[i]-( c[i]*b[k] );
}
}
}
end1 = clock();

//////////////////////////////////////////////////////////////////////////////////

begin2 =clock();

if (rank==0)
{
x[n-1]=b[n-1]/A[n-1][n-1];
for(i=n-2;i>=0;i--)
{
sum=0;

for(j=i+1;j<n;j++)
{
sum=sum+A[i][j]*x[j];
}
x[i]=(b[i]-sum)/A[i][i];
}

end2 = clock();
}
//////////////////////////////////////////////////////////////////////////////////
if (rank==0)
{
printf("\nThe solution is:");
for(i=0;i<n;i++)
{
printf("\nx%d=%f\t",i,x[i]);

}

printf("\n\nLU decomposition time: %f", (double)(end1 - begin1) / CLOCKS_PER_SEC);
printf("\nBack substitution time: %f\n", (double)(end2 - begin2) / CLOCKS_PER_SEC);
}
MPI_Finalize();
return(0);


}

关于用 MPI 并行实现高斯消元法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25236369/

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