MPI加入向量

时间:2014-01-27 16:49:19

标签: c parallel-processing mpi

我正在尝试进行一些并行计算,然后将它们减少到一个向量。

我通过将循环划分为应该与向量分开计算的部分来尝试。后来我想将所有这些子向量加入到一个主向量中,方法是用从进程中获取的值替换它的一部分。不用说,我不知道怎么做,我的尝试都是徒劳的。

任何帮助将不胜感激。

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);

1 个答案:

答案 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,这允许您为每个等级指定不同的大小。