我必须使用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();
}
答案 0 :(得分:1)
问题出在线
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
分配内存时,不能保证该内存是彼此相邻分配的。
因此,您无法使用MPI_Bcast((int **)&(array[0][0]),size*size,MPI_INT,0,MPI_COMM_WORLD);
发送数据,因为&(array[0][0])
到&(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();
}