logo资料库

LU 分解,给出采用行连续划分方式下的MPI实现.doc

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
LU 分解,给出采用行连续划分方式下的 MPI 实现 ㈠实验并行算法描述: ⑴首先从 dataIn.txt 中读取矩阵数据,读取工作由进程 0 完成,然后是数据的 分发。文件中的头两个元素是矩阵的行列 M,N,它们必须相等,否则输入错误。 为 A 开辟一个 M*M 个 floatsize 大小的内存空间,并将文件中的矩阵数据发给它。 ⑵0 号处理器将 M 广播给所有处理器。通信域中的处理器数为 p,则分配至各处理 器的子矩阵大小为 m*M,其中 m=M/p,开辟一个 m*M*floatsize 大小的内存 a 存放 子矩阵,再开辟 M*floatsize 大小内存 f 作为各处理器为主行元素建立发送和接 受缓冲区。0 号处理器再为 l 和 u 矩阵分配内存。 ⑶0 号处理器采用连续划分将矩阵 A 划分为大小 m*M 的 p 块子矩阵,依次发送给 1 至 p-1 号处理器 ⑷对矩阵进行 LU 分解,外层循环 i 代表处理器号,内存循环 j 是每个处理器中 子矩阵的行数。若当前处理的主行在本处理器,v=i*m+j,是当前处理的主行号, 将主行元素都存到数组 f,向其他所有处理器广播主行元素;若当前处理的主行 不在本处理器,则接收主行所在处理器广播来的主元素。若 i=my_rank,利用主 行元素对其 j+1 至 m-1 行数据作行变换,若 my_rank>i,利用主行元素对其 0 至 m-1 行数据作行变换。 ⑸0 号处理器从其余各进程中接收子矩阵 a,得到经过变换的矩阵 A,l 就是其下 三角矩阵,u 就是其上三角矩阵。 ㈡程序源代码: #include "stdio.h" #include "stdlib.h" #include "mpi.h" #define a(x,y) a[x*M+y] /*A 为 M*M 矩阵*/ #define A(x,y) A[x*M+y] #define l(x,y) l[x*M+y] #define u(x,y) u[x*M+y] #define floatsize sizeof(float) #define intsize sizeof(int) int M,N; int m; float *A; int my_rank; int p; MPI_Status status; void fatal(char *message)
{ } printf("%s\n",message); exit(1); void Environment_Finalize(float *a,float *f) { free(a); free(f); } int main(int argc, char **argv) { int i,j,k,my_rank,group_size; int i1,i2; int v,w,MM; float *a,*f,*l,*u; FILE *fdA; double time1,time2; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&group_size); MPI_Comm_rank(MPI_COMM_WORLD,&my_rank); p=group_size; time1=MPI_Wtime(); if (my_rank==0) { fdA=fopen("dataIn.txt","r"); fscanf(fdA,"%d",&M); A=(float *)malloc(floatsize*M*M); for(i = 0; i < M; i ++) for(j = 0; j < M; j ++) fscanf(fdA, "%f", A+i*M+j); fclose(fdA); } /*0 号进程将 M 广播给所有进程*/ MPI_Bcast(&M,1,MPI_INT,0,MPI_COMM_WORLD); m=M/p; if (M%p!=0) m++; /*分配至各进程的子矩阵大小为 m*M*/ a=(float*)malloc(floatsize*m*M);
/*各进程为主行元素建立发送和接收缓冲区*/ f=(float*)malloc(floatsize*M); /*0 号进程为 l 和 u 矩阵分配内存,以分离出经过变换后的 A 矩阵中的 l 和 u 矩阵*/ if (my_rank==0) { l=(float*)malloc(floatsize*M*M); u=(float*)malloc(floatsize*M*M); } if (a==NULL) fatal("allocate error\n"); if (my_rank==0) { for(i=0;i=M) break; MPI_Recv(&a(i,0),M,MPI_FLOAT,0,i,MPI_COMM_WORLD,&status); } } for(i=0;i=M) break; for(j=0;j=M) break; if (my_rank==i)
{ v=i*m+j; for (k=v;ki) for(k=0;k=M) break;
MPI_Send(&a(i,0),M,MPI_FLOAT,0,m*my_rank+i,MPI_COMM_WORLD); } } if(my_rank==0) { for(i=1;i=M) break; MPI_Recv(&a(j,0),M,MPI_FLOAT,i,m*i+j,MPI_COMM_WORLD,&status); for(k=0;kj) l(i,j)=A(i,j); else u(i,j)=A(i,j); printf("Input of file \"dataIn.txt\"\n"); printf("%d\t\n",M); for(i=0;i
for(i=0;i
⑶设置通信域中的进程数为 9 ⑷设置通信域中的进程数为 18
⑸设置通信域中的进程数为 25
分享到:
收藏