Matrix 散布矩阵-MPI
我试图将矩阵逐行分散到所有处理器,但这导致了分割错误。。我不知道我做错了什么。。这是我的密码Matrix 散布矩阵-MPI,matrix,mpi,Matrix,Mpi,我试图将矩阵逐行分散到所有处理器,但这导致了分割错误。。我不知道我做错了什么。。这是我的密码 if(rank == 0) { A_row = 10; A_col = 10; /* calculate the strip size */ strip_size = A_row / size;
if(rank == 0) {
A_row = 10;
A_col = 10;
/* calculate the strip size */
strip_size = A_row / size;
/* genarate Matrix A */
A = (double **)malloc(sizeof(double*) * 10);
int k = 0;
for(i = 0; i < 10; i++) {
A[i] = (double*)malloc(sizeof(double) * 10);
for(j = 0; j < 10; j++) {
A[i][j] = k;
k++;
printf("%lf ", A[i][j]);
}
printf("\n");
}
}
/* 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);
strip_A = (double **)malloc(sizeof(double*)*strip_size);
for(i= 0; i< strip_size; i++) {
strip_A[i] = (double*)malloc(sizeof(double)*A_col);
}
MPI_Scatter(&A[0][0], 1, strip, &strip_A[0][0], 1, strip, 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数据类型和mpi_分散调用的基本结构——是正确的 第一个问题是MPI_散点线使用&(A[0][0])——但是在除秩0之外的所有情况下,您没有将A设置为指向任何东西!所以你两次去引用一个随机指针,这就是你的错误 suszterpatt提出的一个更微妙的问题是,无法保证分配的内存行是连续的,因此即使修复了上述问题,分散操作也可能无法工作。您正试图将strip_size*A_col double从A中的某个位置发送到strip_A,但是strip_A可能不连续地包含那么多的double-它可能是A_col double,然后是一些padding,然后是A_col double-或者实际上,不同的行可能分散在内存中。三种修复方法是,为了方便起见(IMHO):(a)通过创建整个数组,然后创建指向正确位置的二维C数组,使内存中的数据连续;(b) 一次只发送一行;或者(c)创建一个MPI数据类型,它实际上反映了数据在内存中的映射方式(可能是随机的) 使用(a)的方法似乎有效(无论如何,对于按大小平均划分的_行),如下所示:
#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;
}
#包括
#包括
#包括
int main(int argc,字符**argv){
int等级、大小;
整条尺寸,一行,一列;
双**A、**条带A、*数据、*条带数据;
MPI_数据类型条;
int i,j;
MPI_Init(&argc,&argv);
MPI通信等级(MPI通信世界和等级);
MPI_通信大小(MPI_通信世界和大小);
如果(秩==0){
一行=10;
A_col=10;
/*计算带钢尺寸*/
条带尺寸=行/尺寸;
/*再生基质A*/
Adata=(双精度*)malloc(双精度)*行数*列数);
A=(双**)malloc(sizeof(双*)*A_行);
对于(i=0;i
只需添加MPI_Finalize();听从你的命令
请参阅下面的代码和输出。输出正确,但由于存在障碍,无法正确打印。您可以使用MPI_Barrier()或使用MPI_Isend()和MPI_Irecv()。享受
首先,你把segfault放在哪一行?那么,我能把矩阵分散成一个数组吗。。。如果你能确保数据在内存中是连续的,那么实现它就不可能了,因为这是分散的要求,而不仅仅是分散的要求!在创建向量类型时,您声明该类型由一个_cols*strip_大小的连续双精度块组成(一个_cols double的strip_大小块,每个块由一个_cols double分隔)。因此,任何使用这种类型的通信(send、recv、allreduce,无论什么)都需要连续的数据。我认为代码的最后一行会有分段错误,因为每个进程或节点都会试图从原始矩阵中释放内存。如果(rank==0){free(Adata);free(A);}这应该是对已接受答案的(有效)注释,我可以这样写。
#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;
}
#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");
}
if(rank == 0){
MPI_Type_free(&strip);
free(strip_A);
free(stripdata);
free(Adata);
free(A);}
MPI_Finalize();
return 0;
}
rank = 0
0.000000 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000 9.000000
rank = 2
20.000000 21.000000 22.000000 23.000000 24.000000 25.000000 26.000000 27.000000 28.000000 29.000000
rank = 6
60.000000 61.000000 62.000000 63.000000 64.000000 65.000000 66.000000 67.000000 68.000000 69.000000
rank = 1
10.000000 11.000000 12.000000 13.000000 14.000000 15.000000 16.000000 17.000000 18.000000 19.000000
rank = 3
30.000000 31.000000 32.000000 33.000000 34.000000 35.000000 36.000000 37.000000 38.000000 39.000000
rank = 5
50.000000 51.000000 52.000000 53.000000 54.000000 55.000000 56.000000 57.000000 58.000000 59.000000
rank = 8
80.000000 81.000000 82.000000 83.000000 84.000000 85.000000 86.000000 87.000000 88.000000 89.000000
rank = 7
70.000000 71.000000 72.000000 73.000000 74.000000 75.000000 76.000000 77.000000 78.000000 79.000000
rank = 9
90.000000 91.000000 92.000000 93.000000 94.000000 95.000000 96.000000 97.000000 98.000000 99.000000
rank = 4
40.000000 41.000000 42.000000 43.000000 44.000000 45.000000 46.000000 47.000000 48.000000 49.000000