我试着做一些并行计算,然后把它们简化成一个向量。
我试着把for循环分成几个部分,这些部分应该和向量分开计算稍后,我想将所有这些子向量合并到一个主向量中,用从进程中获得的值替换其中的一部分不用说,我不知道怎么做,我的努力都白费了。
任何帮助都将不胜感激。
MPI_Barrier(MPI_COMM_WORLD);
MPI_Bcast(A, n*n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(b, n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(x0, n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
printf("My id: %d, mySize: %d, myStart: %d, myEnd: %d", rank, size, mystart, myend);
while(delta > granica)
{
ii++;
delta = 0;
//if(rank > 0)
//{
for(i = mystart; i < myend; i++)
{
xNowe[i] = b[i];
for(j = 0; j < n; j++)
{
if(i != j)
{
xNowe[i] -= A[i][j] * x0[j];
}
}
xNowe[i] = xNowe[i] / A[i][i];
printf("Result in iteration %d: %d", i, xNowe[i]);
}
MPI_Reduce(xNowe, xNowe,n,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
最佳答案
我将忽略你的计算,假设他们都在做你想他们做的事情,最后,你有一个名为xNowe
的数组,其中有你的排名结果(在某些子数组中)。
你有两个选择。
第一种方法是在当前的操作方式中使用MPI_REDUCE
。
需要做的是,您可能应该将与您的秩无关的所有值都设置为0,然后您就可以做一个大的MPI_REDUCE
(正如您已经做的那样),其中每个进程贡献其xNowe
数组,该数组将类似于这样(取决于输入/秩/etc):
rank: 0 1 2 3 4 5 6 7
value: 0 0 1 2 0 0 0 0
当你做减法(使用
MPI_SUM
作为op)时,你会得到一个数组(在秩0上),每个值都被每个秩贡献的值填充。第二种方法使用
MPI_GATHER
有些人可能认为这是“更合适”的方式。对于这个版本,您只发送根据您的排名计算的数据,而不是使用
MPI_REDUCE
来获得结果你不会有一个大数组所以你的代码应该是这样的:MPI_Barrier(MPI_COMM_WORLD);
MPI_Bcast(A, n*n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(b, n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(x0, n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
printf("My id: %d, mySize: %d, myStart: %d, myEnd: %d", rank, size, mystart, myend);
while(delta > granica)
{
ii++;
delta = 0;
for(i = mystart; i < myend; i++)
{
xNowe[i-mystart] = b[i];
for(j = 0; j < n; j++)
{
if(i != j)
{
xNowe[i] -= A[i][j] * x0[j];
}
}
xNowe[i-mystart] = xNowe[i-mystart] / A[i][i];
printf("Result in iteration %d: %d", i, xNowe[i-mystart]);
}
}
MPI_Gather(xNowe, myend-mystart, MPI_DOUBLE, result, n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
显然,您需要在秩0上创建一个名为
result
的新数组来保存结果值。更新:
正如Hristo在下面的评论中指出的,
MPI_GATHER
在这里可能不起作用,如果myend - mystart
在所有级别上都不相同如果是这样,您需要使用MPI_GATHERV
来为每个列组指定不同的大小。