| #include <stdio.h> |
| #include <mpi.h> |
| #include <unistd.h> |
| #include <stdlib.h> |
| |
| #define S 4 |
| #define RB 8 |
| #define B RB*RB |
| #define N S*RB |
| #define BS S+2 |
| #define T 2 |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void printRows(int pid,float rows[BS][BS]) |
| { |
| printf("result in %d\n",pid); |
| for(int i=0;i<BS;i++) |
| { |
| for(int j=0;j<BS;j++) |
| printf("%.3f\t",rows[i][j]); |
| printf("\n"); |
| } |
| } |
| |
| void RequestStart(int count,MPI_Request arr_request[]) |
| { |
| for(int i=0;i<count;i++) |
| MPI_Start(&arr_request[i]); |
| } |
| |
| void RequestFree(int count,MPI_Request arr_request[]) |
| { |
| for(int i=0;i<count;i++) |
| MPI_Request_free(&arr_request[i]); |
| } |
| |
| int main(int argc,char* argv[]) |
| { |
| float rows[BS][BS],rows2[BS][BS],temprows[S][S],temprows1[N][N],finalrows[N][N]; |
| |
| |
| |
| MPI_Status arr_status[2+S*2]={0}; |
| MPI_Request* arr_requestS = calloc(2+S*2,sizeof(MPI_Request)); |
| MPI_Request* arr_requestR = calloc(2+S*2,sizeof(MPI_Request)); |
| int dims[2]={N/S,N/S}; |
| int periods[2] = {0,0}; |
| MPI_Comm cartcomm; |
| int pid; |
| int size=0; |
| int coords[2] ={0}; |
| int nbrs[4] ={0}; |
| enum DIR{UP,DOWN,LEFT,RIGHT}; |
| |
| MPI_Init(&argc,&argv); |
| MPI_Comm_size(MPI_COMM_WORLD,&size); |
| MPI_Comm_rank(MPI_COMM_WORLD,&pid); |
| if(size == B) |
| { |
| MPI_Cart_create(MPI_COMM_WORLD,2,dims,periods,0,&cartcomm); |
| MPI_Cart_coords(cartcomm,pid,2,coords); |
| |
| |
| for(int i=0; i<BS; i++) |
| { |
| for(int j=0; j<BS; j++) |
| { |
| rows[i][j] = 0.0; |
| rows2[i][j] = 0.0; |
| } |
| } |
| |
| MPI_Cart_shift(cartcomm,0,1,&nbrs[UP],&nbrs[DOWN]); |
| MPI_Cart_shift(cartcomm,1,1,&nbrs[LEFT],&nbrs[RIGHT]); |
| |
| if(pid%RB == 0) |
| { |
| for(int i=1;i<BS-1;i++) |
| rows[i][1] = 8.0; |
| } |
| if(pid%RB==RB-1) |
| { |
| for(int i=1;i<BS-1;i++) |
| rows[i][BS-2] = 8.0; |
| } |
| if(pid>=0 && pid<RB) |
| { |
| for(int i=1;i<BS-1;i++) |
| rows[1][i] = 8.0; |
| } |
| if(pid<B && pid>=B-RB) |
| { |
| for(int i=1;i<BS-1;i++) |
| rows[BS-2][i] = 8.0; |
| } |
| |
| |
| |
| for(int i=0;i<4;i++) |
| { |
| if(nbrs[i] == -1) |
| nbrs[i] = MPI_PROC_NULL; |
| } |
| |
| MPI_Recv_init(&rows[0][1],S,MPI_FLOAT,nbrs[UP],0,cartcomm,&arr_requestR[0]); |
| MPI_Recv_init(&rows[BS-1][1],S,MPI_FLOAT,nbrs[DOWN],0,cartcomm,&arr_requestR[1]); |
| for(int i=1,k=2;i<BS-1;i++,k+=2) |
| { |
| MPI_Recv_init(&rows[i][0],1,MPI_FLOAT,nbrs[LEFT],0,cartcomm,&arr_requestR[k]); |
| MPI_Recv_init(&rows[i][BS-1],1,MPI_FLOAT,nbrs[RIGHT],0,cartcomm,&arr_requestR[k+1]); |
| } |
| |
| MPI_Send_init(&rows[1][1],S,MPI_FLOAT,nbrs[UP],0,cartcomm,&arr_requestS[0]); |
| MPI_Send_init(&rows[BS-2][1],S,MPI_FLOAT,nbrs[DOWN],0,cartcomm,&arr_requestS[1]); |
| for(int i=1,k=2;i<BS-1;i++,k+=2) |
| { |
| MPI_Send_init(&rows[i][1],1,MPI_FLOAT,nbrs[LEFT],0,cartcomm,&arr_requestS[k]); |
| MPI_Send_init(&rows[i][BS-2],1,MPI_FLOAT,nbrs[RIGHT],0,cartcomm,&arr_requestS[k+1]); |
| } |
| |
| |
| int rbegin,rend; |
| int cbegin,cend; |
| rbegin = (pid>=0 && pid<RB)?2:1; |
| rend = (pid<B && pid>=B-RB)?BS-3:BS-2; |
| cbegin =(pid%RB == 0)?2:1; |
| cend = (pid%RB == RB-1)?BS-3:BS-2; |
| |
| |
| for(int step=0; step<T; step++) |
| { |
| |
| RequestStart(2+S*2,arr_requestR); |
| RequestStart(2+S*2,arr_requestS); |
| MPI_Waitall(2+S*2,arr_requestR,arr_status); |
| MPI_Waitall(2+S*2,arr_requestS,arr_status); |
| |
| |
| for(int i=rbegin;i<=rend;i++) |
| { |
| for(int j=cbegin;j<=cend;j++) |
| rows2[i][j] =0.25*(rows[i-1][j]+rows[i][j-1]+rows[i][j+1]+rows[i+1][j]); |
| } |
| |
| for(int i=rbegin;i<=rend;i++) |
| { |
| for(int j=cbegin;j<=cend;j++) |
| rows[i][j] = rows2[i][j]; |
| } |
| } |
| |
| sleep(pid); |
| printRows(pid,rows); |
| |
| |
| for(int i=1,m=0;i<BS-1;i++,m++) |
| { |
| for(int j=1,n=0;j<BS-1;j++,n++) |
| temprows[m][n] = rows[i][j]; |
| } |
| MPI_Barrier(MPI_COMM_WORLD); |
| MPI_Gather(temprows,S*S,MPI_FLOAT,temprows1,S*S,MPI_FLOAT,0,MPI_COMM_WORLD); |
| |
| |
| |
| int index=0; |
| for(int rb=0;rb<RB;rb++) |
| { |
| for(int cb=0;cb<RB;cb++) |
| { |
| for(int r=0;r<S;r++) |
| { |
| for(int c=0;c<S;c++) |
| { |
| finalrows[rb*S+r][cb*S+c] = *((float*)&temprows1+index++); |
| } |
| } |
| } |
| } |
| if(pid==0) |
| { |
| fprintf(stderr,"\nResult after gathering data:\n"); |
| for(int i = 0; i < N; i++) |
| { |
| for(int j = 0; j < N; j++) |
| fprintf(stderr,"%.3f\t", finalrows[i][j]); |
| fprintf(stderr,"\n"); |
| } |
| fprintf(stderr,"\n"); |
| } |
| RequestFree(2+S*2,arr_requestR); |
| RequestFree(2+S*2,arr_requestS); |
| } |
| else if(pid==0) |
| { |
| printf("parameter:should -n %d\n",B); |
| } |
| free(arr_requestS); |
| free(arr_requestR); |
| MPI_Finalize(); |
| return 0; |
| } |
| |
| |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?