gpt4 book ai didi

c - MPI_Bcast 通信的 MPI 段错误

转载 作者:太空宇宙 更新时间:2023-11-04 03:46:25 28 4
gpt4 key购买 nike

我有一个 MPI 程序,如果我使用一个节点,它可以正常工作,如果我有多个节点且通信关闭,它也可以正常运行(尽管由于计算需要通信而导致数值结果错误)。但是,当我通过通信运行它时,我得到一个地址未映射的段错误。

我已将我的程序缩减为以下基本大纲。我在主程序之外定义了一个结构。然后我们有这些结构的数组,这个结构数组在 MPI 节点之间划分,例如我们可能有 500 个粒子和 5 个节点,因此第一个节点在 0-99 上运行,依此类推。然而,在每次操作之后,所有节点都需要同步它们的数据,我尝试使用 MPI_Bcast 来实现这一点。

在 MPI 节点之间的通信中使用全局结构是否存在问题?或者为什么这种通信结构会产生段错误。

#define BUFFER 2

typedef struct {
double X[BUFFER];
} Particle;

Particle *body;

void Communication(int i_buf, int size){

// there are N particles which have been operated on by the various MPI nodes
// we seek to synchronize this data between all nodes
#pragma omp parallel for
for(int nbody = 0; nbody < N; nbody++)
{
// below returns the node number which operated on this particle
int node = IsNode(nbody, size);

MPI_Bcast(&(body[nbody].X[i_buf]), 1, MPI_DOUBLE, node, MPI_COMM_WORLD);
}

}

void main() {

MPI_Init(&argc, &argv);

int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);

body = (Particle*) calloc((size_t)N, sizeof(Particle));

int adjust_a, adjust_b, a, b;
adjust_a = Min(rank, N % size);
adjust_b = Min(rank + 1, N % size);
a = N / size * rank + adjust_a;
b = N / size * (rank + 1) + adjust_b;


int i_buf, i_buf_old;

for(int i_time = 0; i_time <= time_steps; i_time++)
{

i_buf = Mod(i_time, BUFFER);
i_buf_old = Mod(i_time - 1, BUFFER);

#pragma omp sections
{
#pragma omp section
{
Compute(i_buf, i_buf_old, a, b); // just does some calc
Communication(i_buf, size);
}
#pragma omp section
{
if((i_time != 0) && (rank == 0))
LogThread(i_buf_old); // just writes to a file
}
}

}

我的完整结构是:

typedef struct {
double mass;
double X[BUFFER];
double Y[BUFFER];
double Z[BUFFER];
double Vx[BUFFER];
double Vy[BUFFER];
double Vz[BUFFER];
double Fx[BUFFER];
double Fy[BUFFER];
double Fz[BUFFER];
} Particle;

最佳答案

听起来您可能使用了错误的工具来完成这项工作。如果您尝试聚合来自所有进程的数据数组并确保所有进程都有该聚合的结果,您可能应该使用 MPI_ALLGATHER .

这个函数几乎可以满足您的需求。如果您处于每个进程都有一些数据(例如整数)的情况,如下所示:

0)    0
1) 1
2) 2
3) 3

当你做 allgather 时,结果将是这样的:

0) 0 1 2 3
1) 0 1 2 3
2) 0 1 2 3
3) 0 1 2 3

例如,如果您只需要将数据聚合在一个地方(例如排名 0),您可以只使用 MPI_GATHER ,看起来像这样:

0) 0 1 2 3
1) 1
2) 2
3) 3

关于c - MPI_Bcast 通信的 MPI 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24020214/

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