Проблема со строкой
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 *)
, который равен 8 в 64 битах.
Длинное объяснение, если вы хотите его.
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);
To thout через
Настройка отправки иПолучение имеет стоимость, а отправка имеет стоимость.Таким образом, чем меньше MPI_ «чего-то» вы звоните, тем лучше.
Таким образом, ваша матрица должна быть действительно выделена одним 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();
}