gpt4 book ai didi

c - MPI_Bcast 动态二维数组

转载 作者:太空狗 更新时间:2023-10-29 16:50:36 27 4
gpt4 key购买 nike

我正在尝试将带有 bcast 的动态二维数组传递给所有级别。我有以下代码。

#include <stdlib.h>
#include <mpi.h>

int main(int argc, char **argv)
{
float **array;
int rank,size,i,j;

MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);

if(rank==0)
{
array = (float **)malloc(10*sizeof(float));
for(i=0;i<10;i++)
array[i] = (float *)malloc(10*sizeof(float));

for(i=0;i<10;i++)
for(j=0;j<10;j++)
array[i][j]=i+j;
}
MPI_Bcast(array,10*10,MPI_FLOAT,0,MPI_COMM_WORLD);
MPI_Finalize();
}

出于某种原因,我无法理解我遇到的段错误。任何人都知道这是什么问题?

最佳答案

这里有三个问题 - 一个涉及分配,一个涉及分配的位置,一个涉及 MPI 如何工作,其他答案都没有涉及所有这些问题。

第一个也是最严重的问题是事物的分配位置。正如@davidb 正确指出的那样,就目前而言,您只在任务零上分配内存,因此其他任务没有内存来接收广播。

一般来说,对于 C 中的 2d 分配,您的代码几乎完全正确。在这段代码中:

     array = (float **)malloc(10*sizeof(float));
for(i=0;i<10;i++)
array[i] = (float *)malloc(10*sizeof(float));

唯一真正的问题是第一个 malloc 应该是 10 个浮点指针,而不是 float :

     array = (float **)malloc(10*sizeof(float *));
for(i=0;i<10;i++)
array[i] = (float *)malloc(10*sizeof(float));

@eznme 指出了这一点。第一种方法实际上可能会起作用,具体取决于您正在编译/链接的内存模型等,并且几乎肯定会在 32 位操作系统/机器上起作用 - 但仅仅因为它起作用并不总是意味着它是正确的:)

现在,最后一个问题是您已经在 C 中声明了一个完美的二维数组,但这不是 MPI 所期望的。当您调用此电话时

MPI_Bcast(array,10*10,MPI_FLOAT,0,MPI_COMM_WORLD);

您要告诉 MPI 发送 100 个 连续 float ,由 array 指向。您注意到库例程无法知道 array 是否是指向 2d 或 3d 或 12d array 开头的指针,或者各个维度是多少;它不知道是否必须遵循指针,如果需要,它也不知道要遵循多少指针。

所以你想发送一个浮点指针到 100 个连续的 float - 而在分配伪多维数组 (*) 的正常 C 方法中,你不一定有那个。您不一定知道此布局中第二行与第一行的距离 - 甚至在哪个方向。所以你真正想做的是这样的:

int malloc2dfloat(float ***array, int n, int m) {

/* allocate the n*m contiguous items */
float *p = (float *)malloc(n*m*sizeof(float));
if (!p) return -1;

/* allocate the row pointers into the memory */
(*array) = (float **)malloc(n*sizeof(float*));
if (!(*array)) {
free(p);
return -1;
}

/* set up the pointers into the contiguous memory */
for (int i=0; i<n; i++)
(*array)[i] = &(p[i*m]);

return 0;
}

int free2dfloat(float ***array) {
/* free the memory - the first element of the array is at the start */
free(&((*array)[0][0]));

/* free the pointers into the memory */
free(*array);

return 0;
}

这样,也只有这样,才能保证内存是连续的。然后你可以做

float **array;
/* ... */
malloc2dfloat(&array, 10, 10);
if (rank == 0) {
for(i=0;i<10;i++)
for(j=0;j<10;j++)
array[i][j]=i+j;
}
MPI_Bcast(&(array[0][0]), 10*10, MPI_FLOAT, 0, MPI_COMM_WORLD);

请注意,对于任意排列的数据,您仍然可以通过定义 MPI 数据类型来执行 Bcast,该数据类型描述了二维数组实际上在内存中的布局方式;但这更简单,更接近您可能真正想要的。

(*) 这里的真正问题是 C 和 C 派生语言没有真正的多维数组作为一等对象——这对于系统编程语言来说很好,但在进行科学编程时却无可避免地令人恼火。

关于c - MPI_Bcast 动态二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5104847/

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