MPI中的问题:使用mpi将程序重写为并行程序

时间:2017-07-22 02:49:18

标签: c mpi

请求:每个进程都需要计算自己的组与所有点之间的距离。 我的代码如下:

#include stdio.h
#include stdlib.h
#include math.h
#include string.h
#include "mpi.h"

double **malloc_Array2D(int row, int col)
{

    int size = sizeof(double);
    int point_size = sizeof(double*);
    double **arr = (double **) malloc(point_size * row + size * row * col);
    if (arr != NULL)
    {
        memset(arr, 0, point_size * row + size * row * col);
        double *head = (double*)(arr + row);
        while (row--)
            arr[row] = head + row * col;
    }
    return (double**)arr;
}

void free_Aarray2D(void **arr)
{

    if (arr != NULL)
        free(arr);
}

double distance(double *pos1, double *pos2, int dim)
{

    int i;
    double dist = 0.0;
    for(i=0;i<dim;i++)
        dist += pow((pos2[i]-pos1[i]), 2.0);

    return sqrt(dist);
}

int main(int argc,char *argv[])
{

    int np, myid;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &np);
    MPI_Comm_rank(MPI_COMM_WORLD, &myid);
    //open file
    FILE *fp;
    if((fp=fopen("points.dat","r"))==NULL)
    {
        printf("open file failure! exit!\n");
        return -1;
    }

    //read the number of points
    int npoints;
    fscanf(fp, "There are %d points\n", &npoints);
    if(0==myid)
        printf("There are %d points\n", npoints);
    int nptsl_max = npoints/np; 
    if((npoints%np)!=0)
        nptsl_max++;

    double (*xi)[3];
    double **dist;
    int *ind = (int *)malloc(sizeof(int)*nptsl_max);
    xi  = (double (*)[3])malloc(sizeof(double)*nptsl_max*3);
    dist= malloc_Array2D(nptsl_max, npoints);

    int nptsl = 0; //local number of points
    char str[200];
    for(int i=0; i<npoints; i++)
    {
        if(myid == (i%np))
        {
            fscanf(fp, "%d %lf %lf %lf", ind+nptsl, &xi[nptsl][0], &xi[nptsl][1], &xi[nptsl][2]);
            nptsl++;
        }
        else
            fgets(str, 200, fp);
    }
    fclose(fp);

    for(int i=0; i<nptsl; i++)
        printf("point %4d on process %d\n", *(ind+i), myid);

    dist   = (myid == (np-1))?0     :(myid+1);
    source = (myid == 0)     ?(np-1):(myid-1);

    double (*yi)[3];
    yi  = (double (*)[3])malloc(sizeof(double)*nptsl_max*3);
    for(int i=0; i<nptsl; i++)
        for(int j=0; j<3; j++)
            yi[i][j] = xi[i][j];

    for(int loop=0; loop < np)
    {
        for(int i=0; i<nptsl; i++)
        {
            for(int j=0; j<npoints; j++)
            {
                dist[i][j] = distance(xi[i], xi[j], 3);
            }
        }
    }


    sprintf(filename, "dist_%d.dat",myid);
    fp = fopen(filename, "w");
    for(i=0; i<npoints; i++)
    {
        fprintf(fp, "%4d", ind[i]);
        for(j=0; j<npoints; j++)
        {
            fprintf(fp, "  %f", dist[i][j]);
        }
        fprintf(fp, "\n");
    }
    fclose(fp);

    free(ind);
    free(xi);
    free_Aarray2D((void **)dist);

}

我不知道如何传达讯息。 我认为应该使用 MPI_Bcas t或 MPI_Gather 进行通信。 但我无法一直解决这个问题。任何人都可以帮助我吗?谢谢!

1 个答案:

答案 0 :(得分:0)

所以每个进程都是从文件中读取一个子集,你想计算从子集中每个点到所有点的距离吗?

为什么有一个带有“循环”变量的循环?

如果您需要进行一次迭代来计算距离,那么让每个进程完全读取整个文件,计算子集的距离并使用MPI_Gather将所有距离发送到根节点可能会更快会写出结果。

如果您计划进行多次迭代,在每次迭代中您还会更新点的位置,那么您还需要使用MPI_Allgather从其他进程发送/回收点。