Здесь происходит пара вещей.Хорошая новость заключается в том, что самые сложные вещи - создание типа данных mpi и базовая структура вызова MPI_Scatter - правильны.
Первая проблема заключается в том, что строка MPI_Scatter использует & (A [0] [0]) - но во всех случаях, кроме ранга ноль, вы не установили A, чтобы указывать на что-либо!Таким образом, вы разыменовываете случайный указатель дважды, и это ваш segfault.
Более тонкая проблема, как предполагает suszterpatt, заключается в том, что нет гарантии, что ваши строки выделенной памяти являются смежными, поэтому ваша операция разброса может не работатьдаже если вы исправите вышеуказанное.Вы пытаетесь отправить удвоения strip_size * A_col откуда-то из A в strip_A, но strip_A может не состоять из такого количества удваивающихся последовательных чисел - это может быть удвоение A_col, а затем некоторый отступ, затем удвоение A_col - или, действительно, различные строки могутбыть разбросанным по всей памяти.Три способа исправления, которые в порядке простоты (ИМХО): (a) делают данные непрерывными в памяти путем создания всего массива и последующего создания двумерных массивов C, указывающих на правильные места;(б) отправлять по одной строке за раз;или (c) создать тип данных MPI, который фактически отражает, как ваши данные отображаются (возможно, случайным образом) в памяти.
Подход, использующий (a), который, кажется, работает (для A_row, равномерно разделенного по размеру, в любом случае)) выглядит следующим образом:
#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
int main(int argc, char** argv) {
int rank, size;
int strip_size, A_row, A_col;
double **A, **strip_A, *Adata, *stripdata;
MPI_Datatype strip;
int i,j;
MPI_Init(&argc,&argv) ;
MPI_Comm_rank(MPI_COMM_WORLD,&rank) ;
MPI_Comm_size(MPI_COMM_WORLD,&size) ;
if(rank == 0) {
A_row = 10;
A_col = 10;
/* calculate the strip size */
strip_size = A_row / size;
/* genarate Matrix A */
Adata = (double *)malloc(sizeof(double)*A_row*A_col);
A = (double **)malloc(sizeof(double*) * A_row);
for(i = 0; i < A_row; i++) {
A[i] = &(Adata[i*A_col]);
}
int k = 0;
for(i = 0; i < A_row; i++) {
for(j = 0; j < A_col; j++) {
A[i][j] = k;
k++;
}
}
}
/* Broadcasting the row, column size of Matrix A as well as strip size and Matrix B*/
MPI_Bcast(&A_row, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&A_col, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&strip_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
/* defining a datatype for sub-matrix */
MPI_Type_vector(strip_size, A_col, A_col, MPI_DOUBLE, &strip);
MPI_Type_commit(&strip);
stripdata = (double *)malloc(sizeof(double)*strip_size*A_col);
strip_A = (double **)malloc(sizeof(double*)*strip_size);
for(i= 0; i< strip_size; i++) {
strip_A[i] = &(stripdata[i*A_col]);
}
MPI_Scatter(Adata, 1, strip, &(strip_A[0][0]), 1, strip, 0, MPI_COMM_WORLD);
//MPI_Scatter(Adata, A_col*strip_size, MPI_DOUBLE, &(strip_A[0][0]), A_col*strip_size, MPI_DOUBLE, 0, MPI_COMM_WORLD);
for(i = 0; i < strip_size; i++) {
if(i == 0) {
printf("rank = %d\n", rank);
}
for(j = 0; j < A_col; j++) {
printf("%lf ", strip_A[i][j]);
}
printf("\n");
}
MPI_Type_free(&strip);
free(strip_A);
free(stripdata);
free(Adata);
free(A);
return 0;
}