gpt4 book ai didi

c - 具有 2D 数组的 MPI_Allgather

转载 作者:行者123 更新时间:2023-11-30 16:12:17 25 4
gpt4 key购买 nike

我正在尝试计算一些基于其先前位置的物体的位置。因此,在每个 k 循环中,我需要使用计算并存储在 Cw 数组中的物体的新坐标 (x,y,z) 来更新每个 C 数组。我尝试了 MPI_Allgather 但找不到正确的语法来实现它。

我已经检查了 k=1 问题的串行版本的输出,并且 F、V 和 Cw 数组的值是正确的,因此唯一的问题是 MPI_Allgather。为了简单起见,dt 变量现在等于 1。我已经尝试过这个,但没有一个起作用。第一个仅更新 Cw 的第一行 C 数组和另外 2 个值,但位置错误,其余部分与开始时填充时相同。第二个给出了段错误

MPI_Allgather(&(Cw[0][0]),length*3,MPI_FLOAT,&(C[0][0]),length*3,MPI_FLOAT,MPI_COMM_WORLD);

MPI_Allgather(Cw,length*3,MPI_FLOAT,C,length*3,MPI_FLOAT,MPI_COMM_WORLD);

这是代码

float **C,**Cw;

C=malloc(N*sizeof(float*));
Cw=malloc(length*sizeof(float*));

for(i=0;i<length;i++)
{
Cw[i]=malloc(3*sizeof(float));
}

for(i=0;i<N;i++)
{
C[i]=malloc(3*sizeof(float));
}


for(k=0;k<loop;k++)
{
for(i=start;i<=end;i++)
{
for(j=0;j<N;j++)
{
if(i!=j)
{
dx=C[j][0]-C[i][0];
dy=C[j][1]-C[i][1];
dz=C[j][2]-C[i][2];

d=sqrt(pow(dx,2)+pow(dy,2)+pow(dz,2));

F[i-start][0] -= G*M[i]*M[j]/pow(d,3)*dx;
F[i-start][1] -= G*M[i]*M[j]/pow(d,3)*dy;
F[i-start][2] -= G*M[i]*M[j]/pow(d,3)*dz;
}
}
}

for(i=0;i<length;i++)
{
for(j=0;j<3;j++)
{
a=F[i][j]/M[i+start]; // α=F/m
V[i][j]=V[i][j]+a*1; // V(n+1)=Vn+α*Δt
Cw[i][j]=C[i+start][j]+V[i][j]*1; // R(n+1)=Rn+Vn*Δt
}
}

// where MPI_Allgather takes place
}

我期望的输出是由串行程序提供的 https://drive.google.com/open?id=1fwLu8Jk3JEorFTvNJyOtti3K_zIw0ncw

包含此代码的 mpi 版本

MPI_Allgather(&(Cw[0][0]),length*3,MPI_FLOAT,&(C[0][0]),length*3,MPI_FLOAT,MPI_COMM_WORLD);

给出此输出 https://drive.google.com/open?id=14cEFFRvNGUN_RK3u8Z31iRDtiTJs6_8I

最佳答案

再一次,这个指针到指针的废话(对于 scicomp):您通过 MPI 将指针传递到行,而不是内容。

我建议您避免将数组分配为 N 个独立行,如下所示:

float **C,**Cw;

// I guess that you missed to paste these two lines
C = malloc( N * sizeof(float*) );
Cw = malloc( length * sizeof(float*) );

for(i=0;i<length;i++)
{
Cw[i]=malloc(3*sizeof(float));
}

for(i=0;i<N;i++)
{
C[i]=malloc(3*sizeof(float));
}

以这种方式分配的数组在内存中不是线性的,并且不能被 MPI 函数全局使用。当您传递C时,您仅传递指针数组。传递 &C[0][0] 时,您将传递前 3 个元素的数组,但其他 3 个元素数组在内存中并不连续,因为它们是独立分配的。因此,段错误是您可以实现的最好结果,而随机结果是最坏的结果。

在单个 block 中分配所需的内存是正确的,MPI 函数可以正确处理:

float *C,*Cw;
C = malloc( N * 3 * sizeof(float) );
Cw = malloc( length * 3 * sizeof(float) );

并将任何内存访问替换为

            dx=C[j][0]-C[i][0];
dy=C[j][1]-C[i][1];
dz=C[j][2]-C[i][2];

            dx=C[3*j+0]-C[3*i+0];
dy=C[3*j+1]-C[3*i+1];
dz=C[3*j+2]-C[3*i+2];

这样,传递C将导致正确传递数组内容。

关于c - 具有 2D 数组的 MPI_Allgather,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58364672/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com