码迷,mamicode.com
首页 > 其他好文 > 详细

高斯消去法解线性方程组(MPI)

时间:2015-11-28 11:56:15      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:

用一上午的时间,用MPI编写了高斯消去法解线性方程组。这次只是针对单线程负责一个线程方程的求解,对于超大规模的方程组,需要按行分块,后面会在这个基础上进行修改。总结一下这次遇到的问题:

(1)MPI_Allreduce()函数的使用;

(2)MPI_Allgather()函数的使用;

(3)线程之间不使用通信函数进行值传递(地址传递)是没有办法使用其他线程的数据,这是设计并行程序中最容易忽视的一点。

  1 #include "stdio.h"
  2 #include "mpi.h"
  3 #include "malloc.h"
  4 
  5 #define n 4
  6 #define BLOCK_LOW(id,p,n) ((id) * (n)/(p))
  7 #define BLOCK_HIGH(id,p,n) (BLOCK_LOW((id)+1,p,n)-1)
  8 #define BLOCK_SIZE(id,p,n) (BLOCK_LOW((id)+1,p,n)-BLOCK_LOW((id),p,n))
  9 #define BLOCK_OWNER(index,p,n) (((p) * ((index)+1)-1)/(n))
 10 #define MIN(a,b) ((a)<(b)?(a):(b))
11 int NotIn(int id,int *picked);
12 struct { 13 double value; 14 int index; 15 }local,global; 16 17 int main(int argc,char *argv[]) 18 { 19 int id,p; 20 MPI_Init(&argc,&argv); 21 MPI_Comm_rank(MPI_COMM_WORLD,&id); 22 MPI_Comm_size(MPI_COMM_WORLD,&p); 23 24 //double a[n][n+1] = {{4,6,2,-2,8},{2,0,5,-2,4},{-4,-3,-5,4,1},{8,18,-2,3,40}}; 25 double a[n][n+1] = {{2,1,-5,1,8},{1,-3,0,-6,9},{0,2,-1,2,-5},{1,4,-7,6,0}}; 26 27 int i,j; 28 int index; 29 30 int *picked; 31 picked = (int *)malloc(sizeof(int) * n); //记录已被选中的行 32 for(i=0;i<n;i++) 33 picked[i] = -1; 34 35 for(i=0;i<n;i++) 36 { 37 38 if(NotIn(id,picked)) //判断该行是否已被选中,没有选择则进行下一步 39 { 40 local.value = a[id][i]; 41 local.index = id; 42 } 43 else 44 { 45 local.value = -100; //假设各个参数最小值不小于-100 46 local.index = id; 47 } 48 49 MPI_Allreduce(&local,&global,1,MPI_DOUBLE_INT,MPI_MAXLOC,MPI_COMM_WORLD); // 归约最大的值,并存入到global中 50 // printf(" i = %d,id =%d,value = %f,index = %d\n",i,id,global.value,global.index); 51 picked[i] = global.index; 52 53 if(id == global.index) 54 { 55 MPI_Bcast(&global.index,1,MPI_INT,id,MPI_COMM_WORLD); 56 } 57 58 MPI_Allgather(&a[id][0],n+1,MPI_DOUBLE,a,n+1,MPI_DOUBLE,MPI_COMM_WORLD);
//每个线程解决的是对应行的求解,例如:线程号为0的线程仅得到0行的解,但是第1行的改动,0线程没有办法得到,只有1线程自己才知道,所以需要使用MPI_Allg ather()函数进行去收集,并将结果存入到各个线程中,最后各个线程得到a为最新解
59 60 if(NotIn(id,picked)) 61 { 62 double temp = 0 - a[id][i] / a[picked[i]][i]; 63 for(j=i;j<n+1;j++) 64 { 65 a[id][j] += a[picked[i]][j] * temp; 66 } 67 } 68 69 } 70 71 MPI_Gather(&a[id][0],n+1,MPI_DOUBLE,a,n+1,MPI_DOUBLE,0,MPI_COMM_WORLD); //
//解上三角形,因为都需要使用到上一线程的数值,这样造成通信开销增大,不如直接让单一线程去求解上三角形矩阵
72 if(id == 0) 73 { 74 for(i=0;i<n;i++) 75 { 76 for(j=0;j<n+1;j++) 77 { 78 printf("%f\t",a[i][j]); 79 } 80 printf("\n"); 81 } 82 83 /* for(i=0;i<n;i++) 84 { 85 printf("%d\t",picked[i]); 86 } 87 */ 88 double *x; 89 x = (double *)malloc(sizeof(double) * n); 90 for(i=(n-1);i>=0;i--) //这里还有一个小插曲,在这一行的后面加了”;“,导致i变成-1,使程序报错 Segmentation fault (11),在Linux下经常遇到这个问题,大体2点:1.占用的内存超出了系统内存 2.循环中,数组越界
 91      {
 92         //printf("\n n =%d,i = %d",n,i);
 93         x[i] = a[picked[i]][n] / a[picked[i]][i];
 94         printf("x[%d] = %f\n",i,x[i]);
 95         for(j=0;j<n;j++)
 96         {
 97             a[picked[j]][n] = a[picked[j]][n] - x[i] * a[picked[j]][i] ;
 98             a[picked[j]][i] = 0;
 99         }
100      
101      }
102    }
103 
104 
105   MPI_Finalize();
106   return 0;
107 }
108 
109 
110 int NotIn(int id,int *picked)
111 {
112   int i;
113   for(i=0;i<n;i++)
114   {
115     if(id == picked[i])
116     {
117       return 0;
118     }
119   }
120   return 1;
121 }

 

高斯消去法解线性方程组(MPI)

标签:

原文地址:http://www.cnblogs.com/zhangjxblog/p/5002406.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!