使用 MPI 分散连续的二维数组
Scattering a contiguous 2D Array using MPI
我好像没弄对,我想散布一个二维块然后只打印散布的部分,这是为了测试目的
这就是我想要做的...
#include <stdio.h>
#include <stdlib.h>
#include "mpi/mpi.h"
void print2D(int**, int, int);
int main(int argc, char* argv[])
{
int rank, pSize, r1, c1, rowsPerProcess, i, j;
int** matA = NULL, **partMat = NULL;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &pSize);
if(rank == 0)
{
scanf("%d%d", &r1, &c1);
rowsPerProcess = r1/pSize; // number of rows assigned to each process (Assume this produces no remainder)
//Contiguous allocation
int* mat1D = (int*)malloc(r1 * c1 * sizeof(int));
matA = (int**)malloc(r1 * sizeof(int*));
for(i=0; i<r1; i++)
matA[i] = &mat1D[i * c1];
for(i=0; i<r1; i++) //Fill the 2D array
for(j=0; j<c1; j++)
matA[i][j] = i + j;
printf("Original Matrix:\n");
print2D(matA, r1, c1);
}
MPI_Bcast(&c1, 1, MPI_INT, 0, MPI_COMM_WORLD); //Columns
MPI_Bcast(&rowsPerProcess, 1, MPI_INT, 0, MPI_COMM_WORLD); //Rows in every process
//Again, contiguous allocation for the partial 2D array
int* partMat1D = (int*)malloc(rowsPerProcess * c1 * sizeof(int));
partMat = (int**)malloc(rowsPerProcess * sizeof(int*));
for(i=0; i<rowsPerProcess; i++)
partMat[i] = &partMat1D[i * c1];
MPI_Scatter(&(matA[0][0]), rowsPerProcess * c1, MPI_INT, &(partMat[0][0]),
rowsPerProcess * c1, MPI_INT, 0, MPI_COMM_WORLD);
printf("FROM PROCESS %d:\n", rank);
print2D(partMat, rowsPerProcess, c1);
MPI_Finalize();
return 0;
}
void print2D(int** mat, int row, int col)
{
if(mat != NULL)
{
int i, j;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
printf("%d ", mat[i][j]);
printf("\n");
}
}
}
并且我在 运行 上收到一个分段错误错误,有 4 个进程
例如
8 3
Original Matrix:
0 1 2
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
FROM PROCESS 0:
0 1 2
1 2 3
===================================================================================
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= PID 2637 RUNNING AT minix-VirtualBox
= EXIT CODE: 139
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions
只有进程 0 正确打印了它的部分。
我使用 MPI_Scatter 错了吗?我该如何解决这个问题?
我如何正确地散布这个二维块?
在非主进程上,您将 matA
初始化为 NULL
,然后继续计算表达式 &matA[0][0]
。这会取消引用 matA
,甚至在进入 MPI_Scatter()
.
之前就会使您的进程崩溃
由于您是用 C 编程的,因此可以避免那些双指针:自 C99 以来,C 就内置了相当不错的多维数组支持,您可以使用它来简化您的工作。只需将 matA
声明为指向线数组的指针
int (*matA)[c1];
然后为其分配 r1
行的数组
matA = malloc(r1*sizeof(*matA));
之后,您可以使用与上述代码相同的代码填充数组:
for(i=0; i<r1; i++) //Fill the 2D array
for(j=0; j<c1; j++)
matA[i][j] = i + j;
此外,由于您的二维数组只需要一次 malloc()
调用,您也可以通过一次 free()
调用来处理它:
free(matA);
注意:您不能在 C++ 中执行此操作,它不像 C 那样支持可变长度数组,而且可能永远不会。这是 C 比 C++ 强大得多的几个地方之一。
我好像没弄对,我想散布一个二维块然后只打印散布的部分,这是为了测试目的
这就是我想要做的...
#include <stdio.h>
#include <stdlib.h>
#include "mpi/mpi.h"
void print2D(int**, int, int);
int main(int argc, char* argv[])
{
int rank, pSize, r1, c1, rowsPerProcess, i, j;
int** matA = NULL, **partMat = NULL;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &pSize);
if(rank == 0)
{
scanf("%d%d", &r1, &c1);
rowsPerProcess = r1/pSize; // number of rows assigned to each process (Assume this produces no remainder)
//Contiguous allocation
int* mat1D = (int*)malloc(r1 * c1 * sizeof(int));
matA = (int**)malloc(r1 * sizeof(int*));
for(i=0; i<r1; i++)
matA[i] = &mat1D[i * c1];
for(i=0; i<r1; i++) //Fill the 2D array
for(j=0; j<c1; j++)
matA[i][j] = i + j;
printf("Original Matrix:\n");
print2D(matA, r1, c1);
}
MPI_Bcast(&c1, 1, MPI_INT, 0, MPI_COMM_WORLD); //Columns
MPI_Bcast(&rowsPerProcess, 1, MPI_INT, 0, MPI_COMM_WORLD); //Rows in every process
//Again, contiguous allocation for the partial 2D array
int* partMat1D = (int*)malloc(rowsPerProcess * c1 * sizeof(int));
partMat = (int**)malloc(rowsPerProcess * sizeof(int*));
for(i=0; i<rowsPerProcess; i++)
partMat[i] = &partMat1D[i * c1];
MPI_Scatter(&(matA[0][0]), rowsPerProcess * c1, MPI_INT, &(partMat[0][0]),
rowsPerProcess * c1, MPI_INT, 0, MPI_COMM_WORLD);
printf("FROM PROCESS %d:\n", rank);
print2D(partMat, rowsPerProcess, c1);
MPI_Finalize();
return 0;
}
void print2D(int** mat, int row, int col)
{
if(mat != NULL)
{
int i, j;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
printf("%d ", mat[i][j]);
printf("\n");
}
}
}
并且我在 运行 上收到一个分段错误错误,有 4 个进程
例如
8 3
Original Matrix:
0 1 2
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
FROM PROCESS 0:
0 1 2
1 2 3
===================================================================================
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= PID 2637 RUNNING AT minix-VirtualBox
= EXIT CODE: 139
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions
只有进程 0 正确打印了它的部分。
我使用 MPI_Scatter 错了吗?我该如何解决这个问题?
我如何正确地散布这个二维块?
在非主进程上,您将 matA
初始化为 NULL
,然后继续计算表达式 &matA[0][0]
。这会取消引用 matA
,甚至在进入 MPI_Scatter()
.
由于您是用 C 编程的,因此可以避免那些双指针:自 C99 以来,C 就内置了相当不错的多维数组支持,您可以使用它来简化您的工作。只需将 matA
声明为指向线数组的指针
int (*matA)[c1];
然后为其分配 r1
行的数组
matA = malloc(r1*sizeof(*matA));
之后,您可以使用与上述代码相同的代码填充数组:
for(i=0; i<r1; i++) //Fill the 2D array
for(j=0; j<c1; j++)
matA[i][j] = i + j;
此外,由于您的二维数组只需要一次 malloc()
调用,您也可以通过一次 free()
调用来处理它:
free(matA);
注意:您不能在 C++ 中执行此操作,它不像 C 那样支持可变长度数组,而且可能永远不会。这是 C 比 C++ 强大得多的几个地方之一。