【发布时间】:2017-05-11 06:41:10
【问题描述】:
我在 C 中有这个函数 Sum(),我想使用 MPI 进行并行化:
double Sum(double* x, double* y, int n)
{
double V = 0.0;
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (i != j)
V += F(x[i], y[j]);
}
}
return V;
}
其中F(x[i],y[j]) 只是一个函数,用于计算两个元素之间的差异或类似的二元运算。
现在我认为我可以将各个处理器上的总和分开 p 使用 MPI_Scatter() 以生成本地 vecotr,然后使用 MPI_Reduce() 将本地总和合并在一起,不幸的是,我似乎无法做到它。这是我的解决方案,但它似乎不起作用:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
double Parallel_Sum(double (*)(double, double), double*, double*, int, int);
double F(double, double);
int main(int argc, char** argv)
{
int my_rank, p;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
int n = 10;
double *y = calloc(n, sizeof(double)), *x = calloc(n, sizeof(double));
/*just for trial*/
y[5] = 1;
x[5] = 1;
double* local_x = calloc(n / p, sizeof(double));
MPI_Scatter(x, n / p, MPI_DOUBLE, local_x, n / p, MPI_DOUBLE, 0, MPI_COMM_WORLD);
double local_S, S = 0.0;
local_S = Parallel_Sum(F, local_x, y, n, p);
MPI_Reduce(&local_S, &S, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if (my_rank == 0)
{
printf("%lf\n", S);
}
MPI_Finalize();
return 0;
}
double F(double a, double b)
{
return a - b;
}
double Parallel_Sum(double (*OP)(double, double), double* local_x, double* y, int n, int p)
{
double local_V = 0.0;
int i, j;
for (i = 0; i < n / p; i++)
{
for (j = 0; j < n; j++)
{
if (i != j)
local_V += OP(local_x[i], y[j]);
}
}
return local_V;
}
在这个例子中,总和应该是 0,因为除了 y[5] = 1; x[5] = 1; 之外的向量都是零,不幸的是对于 p > 1 它永远不会是零。我做错了什么?
【问题讨论】:
-
好像不行?请具体并提供最小且可验证的代码。
-
是的,抱歉,我编辑了问题
-
if (i != j)在最内层循环中应该是if ((n/p) * my_rank + i != j),否则您将本地索引与全局索引进行比较。