mpi - 使用 MPI_Bcast(...) 广播动态分配的二维数组
问题描述
我必须使用 malloc 动态创建一个数组,根进程执行此操作,然后该数组应该被广播到现在将打印它的所有其他进程,实际上要求是其他进程将独立更改矩阵的值. 我的主要问题是我无法将整个阵列广播到所有进程。
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char **argv)
{
int **array;
int rank,size,i,j;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Datatype data_type;
size= 4;
array = (int **)malloc(size*sizeof(int *));
for(i=0;i<size;i++)
array[i] = (int *)malloc(size*sizeof(int));
if(rank==0)
{
int t= 0;
for(i=0;i<size;i++)
{
for(j=0;j<size;j++){
array[i][j]=t++;
printf("%4d",array[i][j]);
}
printf("\n");
}
printf("size is %zu\n",sizeof(array));
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Bcast(&size,1,MPI_INT,0,MPI_COMM_WORLD);
printf("size %d proec %d\n",size,rank);
MPI_Bcast((int **)&(array[0][0]),size*size,MPI_INT,0,MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
printf("process %d prainting matrix:\n",rank);
for (i= 0; i <size;i++)
{
for(j= 0; j < size; j++)
printf("%d [%d]\t",array[i][j],rank);
printf("\n");
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
}
解决方案
问题在于线路
MPI_Bcast((int **)&(array[0][0]),size*size,MPI_INT,0,MPI_COMM_WORLD);
你应该做
for(i=0;i<size;i++)
{
MPI_Bcast((int **)&(array[i][0]),size,MPI_INT,0,MPI_COMM_WORLD);
}
我不知道您的意图是什么,但sizeof(array)
不返回数组的大小,而是返回(size_t *)
64 位中 8 的大小。
如果你想要一个长的解释。
MPI_Send 或 MPI_Bcast 确实发送了大块内存。
要确定这些块,您必须给出开始(MPI_Bcast 或 MPI_Send 的第一个参数),然后是长度(第二个参数),然后是数据类型(第三个参数)。
在您的示例中,它知道它必须发送&(array[0][0])
至&(array[0][0])+(size*size-1)*sizeof(int)
现在当你做
int main(int argc, char **argv)
{
int **array, * array_un;
int rank,size,i,j;
int **array
size= 4;
array = (int **)malloc(size*sizeof(int *));
for(i=0;i<size;i++)
{
array[i] = (int *)malloc(size*sizeof(int));
printf("Ox%X\n",(size_t)array[i]);
}
printf("end array=Ox%X\n",(size_t) &(array[size-1][size-1]));
printf("end pointer=Ox%X\n",(size_t) array+(size*size-1)*sizeof(int));
}
它输出
Ox13B91A0
Ox13B91C0
Ox13B91E0
Ox13B6B90
end array = Ox13B6B9C
end pointer= Ox13BB06C
正如你所看到的end array
和end pointer
不同的。如果您现在查看每个malloc
增量为 0x20(大于4*size(int)=10
)的地址,然后突然减 0x2650 !
连续malloc
分配内存,但不保证内存是相邻分配的。
因此,您无法发送 using MPI_Bcast((int **)&(array[0][0]),size*size,MPI_INT,0,MPI_COMM_WORLD);
,因为&(array[0][0])
to &之间的数据(array[0][0])+(size*size-1)*sizeof(int)
实际上并不包含您要发送的数据。
然而,malloc
分配一块连续的内存
所以你可以发送MPI_Bcast((int **)&(array[i][0]),size,MPI_INT,0,MPI_COMM_WORLD);
要彻底
设置发送和接收是有成本的,发送也是有成本的。所以 MPI_"something" 调用越少越好。
所以你的矩阵应该真正分配一个malloc
将您修改后的代码与此代码进行比较
#include <mpi.h>
int main(int argc, char **argv)
{
int *array;
int rank,size,i,j;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Datatype data_type;
size= 4;
array = (int *)malloc(size*size*sizeof(int));
if(rank==0)
{
int t= 0;
for(i=0;i<size;i++) { for(j=0;j<size;j++){ array[i*size+j]=t++; } }
}
MPI_Bcast(array,size*size,MPI_INT,0,MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
printf("process %d printing matrix:\n",rank);
for (i= 0; i <size;i++)
{
for(j= 0; j < size; j++)
printf("%d [%d]\t",array[i*size+j],rank);
printf("\n");
}
MPI_Finalize();
}
推荐阅读
- python-3.x - 使用python,如何获取linux上正在运行的服务的名称
- flutter - 如何将普通页面用作对话框 - 颤振
- java - 正确的数据格式和对齐
- arrays - C - 将一维数组设为二维
- python - Python多串口减慢Linux上的USB速度
- firebase - 是否可以使用安全规则仅授予用户访问在 Firestore 中以其 uid 命名的文档的权限?
- javascript - JavaScript Chart.JS - 将图表保持在两行中,而不是将所有内容堆叠成一列
- java - 无法在appium上运行基本程序
- java - Selenium Java:侧栏菜单导航->无法选择无序列表菜单项
- r - 从使用 2 个不同几何图形创建的 ggplot 图例中删除某些值