如何解决似乎MPI_BarrierMPI_COMM_WORLD不能完成工作
我没有给出所有代码,因为我试图使这一部分尽可能地可读,而程序的其余部分并不是那么重要。 E
是单位矩阵,A
是可逆矩阵。从Solve(...)
中调用函数int main()
并转换E
和A
。结果,我们应该在A
中得到E
的逆,而在A
中得到单位矩阵。
当我用1个进程运行该程序时,它的运行效果非常好。当我添加另一个过程时,生成的矩阵远不是所需的。动作似乎执行顺序错误。我已经读过(例如,在这里OpenMPI MPI_Barrier problems),MPI与输出杂乱无章,因此在操作之间添加一些输出无助于发现正在发生的事情。另外,由于该程序可以很好地完成一个过程,因此该算法是正确的,整个问题都来自MPI,如果MPI_Barrier(MPI_COMM_WORLD)
正确完成了工作,就不应该出现。
MPI_Barrier(MPI_COMM_WORLD)
是否在此处同步进程?为什么程序在1个进程中可以正常工作而在2个进程中却失败?
谢谢。
struct Matrix{
vector<vector<double>> mat;
size_t m; //rows
size_t n; //columns
};
void Solve(Matrix &A,Matrix &E,size_t rank,size_t size)
{
size_t n=A.m;
size_t ind;
for(size_t k=0; k<n; k++)
{
if(rank==0) // initial action are executed by 0th process
{
ind=A.MainElement_Row(k,k);
E.SwapColumns(k,ind);
A.SwapColumns(k,ind);
E.MultColumn(k,1/A.mat[k][k]);
A.MultColumn(k,1/A.mat[k][k]);
}
MPI_Barrier(MPI_COMM_WORLD); // I don't want other processes to go further until 0th did its work
for(size_t i=0; i<n; i++)
MPI_Bcast(&E.mat[i][0],n,MPI_DOUBLE,MPI_COMM_WORLD);
for(size_t i=0; i<n; i++)
MPI_Bcast(&A.mat[i][0],MPI_COMM_WORLD); // now all processes know how the matrices look
MPI_Barrier(MPI_COMM_WORLD); // Me making sure they all got it
for(size_t i=rank; i<n; i=i+size) // here parallel programming starts. Every process works with its share of columns. i-th process is responsible for changing i-th,(i+size)th,(i+2*size)th etc. columns. Processes' areas of work don't intersect
{
if(i!=k)
{
E.SubtractColumns(i,k,A.mat[k][i]);
A.SubtractColumns(i,A.mat[k][i]);
}
}
MPI_Barrier(MPI_COMM_WORLD); // Let's make sure all processes did their job
for(size_t i=0; i<size; i++)
{
for(size_t j=0; j<n; j++)
MPI_Bcast(&E.mat[j][0],i,MPI_COMM_WORLD);
for(size_t j=0; j<n; j++)
MPI_Bcast(&A.mat[j][0],MPI_COMM_WORLD); // May be it's not the best choice of function,but anyway now all processes broadcasted what they did to the matrix
}
MPI_Barrier(MPI_COMM_WORLD); // we make sure,they all understood how the matrices look now
}
}
(编辑,改进的代码版本)
void SendColumn(Matrix &A,size_t root,size_t n,size_t num)
{
for(size_t m=0; m<n; m++)
{
MPI_Bcast(&E.mat[m][num],1,root,MPI_COMM_WORLD);
MPI_Bcast(&A.mat[m][num],MPI_COMM_WORLD);
}
}
void Solve(Matrix &A,size_t size)
{
size_t n=A.m;
size_t ind;
for(size_t k=0; k<n; k++)
{
if(rank==0)
{
ind=A.MainElement_Row(k,ind);
A.SwapColumns(k,1/A.mat[k][k]);
A.MultColumn(k,1/A.mat[k][k]);
}
MPI_Barrier(MPI_COMM_WORLD);
SendColumn(A,E,k);
SendColumn(A,ind);
MPI_Barrier(MPI_COMM_WORLD);
for(size_t i=rank; i<n; i=i+size)
{
if(i!=k)
{
E.SubtractColumns(i,A.mat[k][i]);
A.SubtractColumns(i,A.mat[k][i]);
}
}
MPI_Barrier(MPI_COMM_WORLD);
for(size_t root=0; root<size; root++)
{
for(size_t i=root; i<n; i=i+size)
{
if(i!=k)
SendColumn(A,i);
}
}
MPI_Barrier(MPI_COMM_WORLD);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。