请求:每个进程都需要计算自己的组与所有点之间的距离。 我的代码如下:
#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 进行通信。 但我无法一直解决这个问题。任何人都可以帮助我吗?谢谢!
答案 0 :(得分:0)
所以每个进程都是从文件中读取一个子集,你想计算从子集中每个点到所有点的距离吗?
为什么有一个带有“循环”变量的循环?
如果您需要进行一次迭代来计算距离,那么让每个进程完全读取整个文件,计算子集的距离并使用MPI_Gather将所有距离发送到根节点可能会更快会写出结果。
如果您计划进行多次迭代,在每次迭代中您还会更新点的位置,那么您还需要使用MPI_Allgather从其他进程发送/回收点。