MPI程序例子:对等模式的MPI程序,Jacobi迭代 (MPI_Send、MPI_Recv)

NOTE:

         这里首先需要弄明白 Jacobi迭代是做什么的,怎么操作。

 网上找到的一篇讲解使用 MPI解决Jacobi迭代并行化的文章,这个与都志辉 并行程序一书的例子有相似之处。链接http://www.doc88.com/p-99830356011.html。下边程序算法主要步骤代码段为,这个步骤为矩阵每个数取相邻四个数的中值。                               

[cpp] for(j=begin_col;j<=end_col;j++)  
  1.                  for(i=1;i<totalsize-1;i++)  
  2.                          b[i][j]=0.25*(a[i][j+1]+a[i][j-1]+a[i+1][j]+a[i-1][j]);  
  3.            
  4.   
  5.          for(j=begin_col;j<=end_col;j++)  
  6.                   for(i=1;i<totalsize-1;i++)  
  7.                          a[i][j]=b[i][j];  
for(j=begin_col;j<=end_col;j++)
                 for(i=1;i<totalsize-1;i++)
                         b[i][j]=0.25*(a[i][j+1]+a[i][j-1]+a[i+1][j]+a[i-1][j]);
         

         for(j=begin_col;j<=end_col;j++)
                  for(i=1;i<totalsize-1;i++)
                         a[i][j]=b[i][j];
[cpp] /* 
  1.         对等模式的MPI程序:test_8_1_2.c 
  2.         Jacobi迭代:迭代数据按列进行分割, 
  3.         并假设一共有4个进程同时并行计算。 
  4. */  
  5. #include "mpi.h"   
  6. #include <stdio.h>   
  7.   
  8. #define totalsize 16   
  9. #define mysize totalsize/4    //分成四块,每块大小  
  10. #define steps 10   
  11.   
  12. void main(int argc,char* argv[])  
  13. {  
  14.     int myid,numprocs,n,i,j,rc;  
  15.     float a[totalsize][mysize+2],b[totalsize][mysize+2];  //除分块大小外,还包括左右两边各一列  
  16.     float temp[totalsize];  /* 临时数组 */  
  17.     int begin_col,end_col,ierr;  
  18.     MPI_Status status;  
  19.     MPI_Init(&argc,&argv);  
  20.   
  21.     /* 得到当前进程标识和总的进程个数 */  
  22.     MPI_Comm_rank(MPI_COMM_WORLD,&myid);  
  23.     MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  
  24.     fprintf(stderr,"Process %d of %d is alive.\n",myid,numprocs);  
  25.      
  26.     /* 数组初始化 */  
  27.     //NOTE: 整个数组置值为0, 行数为 totalsize, 列数为 mysize+2  
  28.     for(j=0;j<mysize+2;j++)  
  29.         for(i=0;i<totalsize;i++)  
  30.             a[i][j]=0.0;  
  31.     if(myid==0)  
  32.         for(i=0;i<totalsize;i++)  
  33.             a[i][1]=8.0;  
  34.   
  35.     if(myid==3)  
  36.         for(i=0;i<totalsize;i++)  
  37.             a[i][mysize]=8.0;  
  38.     for(i=1;i<mysize+1;i++){     
  39.         a[0][i]=8.0;  
  40.         a[totalsize-1][i]=8.0;  
  41.     }      
  42.     /* Jacobi迭代部分 */  
  43.     for(n=1;n<=steps;n++)  
  44.     {  
  45.         //这里从两边分别"获取数据"和"发送数据",每次获取或发送数据时先判断是否会越界  
  46.         /* 从右侧的邻居得到数据 */  
  47.         if(myid<3)  
  48.         {  
  49.             MPI_Recv(&temp[0],totalsize,MPI_FLOAT,myid+1,10,MPI_COMM_WORLD,&status);  
  50.             for(i=0;i<totalsize;i++)  
  51.                     a[i][mysize+1]=temp[i];  
  52.             //a[i][mysize+1]为块最右一列,表示相邻右侧一块最左边一列  
  53.         }  
  54.         /* 向左侧的邻居发送数据 */  
  55.         if(myid>0)  
  56.         {  
  57.             for(i=0;i<totalsize;i++)  
  58.                     temp[i]=a[i][1];  
  59.             MPI_Send(&temp[0],totalsize,MPI_FLOAT,myid-1,10,MPI_COMM_WORLD);  
  60.         }  
  61.         /* 向右侧的邻居发送数据 */  
  62.         if(myid<3)  
  63.         {  
  64.                 for(i=0;i<totalsize;i++)  
  65.                         temp[i]=a[i][mysize];  
  66.                 MPI_Send(&temp[0],totalsize,MPI_FLOAT,myid+1,10,MPI_COMM_WORLD);  
  67.         }  
  68.         /* 从左侧的邻居得到数据 */  
  69.         if(myid<3)  
  70.         {  
  71.             MPI_Recv(&temp[0],totalsize,MPI_FLOAT,myid-1,10,MPI_COMM_WORLD,&status);  
  72.             for(i=0;i<totalsize;i++)  
  73.                     a[i][0]=temp[i];  
  74.             //a[i][0] 为块最左一列,表示相邻左侧一块最右一列  
  75.         }  
  76.                
  77.         begin_col=1;  
  78.         end_col=mysize;  
  79.         if(myid==0)  
  80.                 begin_col=2;  
  81.         if(myid==3)  
  82.                 end_col=mysize-1;  
  83.         for(j=begin_col;j<=end_col;j++)  
  84.                 for(i=1;i<totalsize-1;i++)  
  85.                         b[i][j]=0.25*(a[i][j+1]+a[i][j-1]+a[i+1][j]+a[i-1][j]);  
  86.         for(j=begin_col;j<=end_col;j++)  
  87.                 for(i=1;i<totalsize-1;i++)  
  88.                         a[i][j]=b[i][j];  
  89.         //      MPI_Barrier(MPI_COMM_WORLD);  
  90.     }/*     迭代结束 */  
  91.     MPI_Barrier(MPI_COMM_WORLD);  
  92.     /* 输出结果 */  
  93.     fprintf(stderr,"\nProcess %d :\n",myid);  
  94.     begin_col=1;  
  95.     end_col=mysize;  
  96.     for(i=0;i<totalsize;i++)  
  97.     {  
  98.         for(j=begin_col;j<=end_col;j++)  
  99.             fprintf(stderr,"%.2fP%d\t",a[i][j],myid);  
  100.         fprintf(stderr,"\n");  
  101.     }  
  102.     fprintf(stderr,"\n");  
  103.     MPI_Finalize();  
  104. }  
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值