我正在使用MPI编写我的第一个程序,我很难尝试使用MPI_Scatter正确地将数据发送到其他进程,修改它们并使用MPI_Gather接收值。代码如下:
int** matrix;
int m = 2, n = 2;
int status;
// could have been int matrix[2][2];
matrix = malloc(m*sizeof(int*));
for(i = 0; i < m; i++) {
matrix[i] = malloc(n*sizeof(int));
}
matrix[0][0] = 1;
matrix[0][1] = 2;
matrix[1][0] = 2;
matrix[1][1] = 3;
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
printf("My name is %d out of %d\n", rank, size);
MPI_Scatter(&matrix, 1, MPI_INT, &status, 1, MPI_INT, 0, MPI_COMM_WORLD);
printf("My name is %d and my status is %d\n", rank, status);
status += 1;
MPI_Gather(&status,1,MPI_INT,&matrix,1,MPI_INT,0,MPI_COMM_WORLD);
结果如下:
My name is 0 out of 4
My name is 1 out of 4
My name is 1 and my status is 0
My name is 2 out of 4
My name is 2 and my status is 120
My name is 0 and my status is 17773264
My name is 3 out of 4
My name is 3 and my status is 0
当我尝试打印矩阵的内容时MPI_Gather之后我得到分段错误...
这不是我的期望......我怀疑问题是我有一个二维数组并且想要发送单个值。这是正确的吗?如何纠正这个?
答案 0 :(得分:3)
分段错误的原因是,您正在分配2D阵列,但无法保证它使用连续内存。因此,分配一维数组并分散/收集它。这也解释了为什么有些节点会得到错误的数据。
您将接收变量status
命名为误导,因为它会保留接收到的值。因此,当节点收到多个值时,您必须正确分配它。我还建议将其重命名为例如local_matrix
或类似的。
侧节点:您在所有节点上分配matrix
,但您应该只在单个节点上分配。这可以通过检查当前等级并在检查后放置障碍来完成。此外,我假设您还在所有节点上打印,但此代码不可见。与分配一样,打印也应仅在一个节点上完成。
另请查看How are MPI_Scatter and MPI_Gather used from C?,它可以很好地解释它。