我正在尝试进行一些并行计算,然后将它们减少到一个向量。
我通过将循环划分为应该与向量分开计算的部分来尝试。后来我想将所有这些子向量加入到一个主向量中,方法是用从进程中获取的值替换它的一部分。不用说,我不知道怎么做,我的尝试都是徒劳的。
任何帮助将不胜感激。
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);
答案 0 :(得分:2)
我将忽略你的计算并假设他们都在做你想做的任何事情,最后,你有一个名为xNowe
的数组,其结果在你的位置内它(在一些子阵列中)。
您有两种选择。
第一种方式使用MPI_REDUCE
,就像您目前的做法一样。
需要做的是你应该将与你的等级无关的所有值设置为0,然后你可以做一个大的MPI_REDUCE
(就像你已经在做的那样),每个进程贡献其xNowe
数组,看起来像这样(取决于输入/等级/等):
rank: 0 1 2 3 4 5 6 7
value: 0 0 1 2 0 0 0 0
当您进行缩减(使用MPI_SUM
作为操作)时,您将得到一个数组(在等级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
,这允许您为每个等级指定不同的大小。