歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> MPI 加農算法

MPI 加農算法

日期:2017/3/1 10:13:25   编辑:Linux編程

MPI 加農算法計算矩陣相乘 為了實現方便 只實現了矩陣自乘 而且 實際上各線程都可讀取整個矩陣(略去輸入和分配中的通信過程)

在各線程相互交換數據的過程中 一定要注意避免死鎖

  1. #include "mpi.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #define TAG 0
  6. static inline void rtoij(int r,int w,int *i,int *j) {
  7. //rank to i,j
  8. *i=r/w;
  9. *j=r-(*i)*w;
  10. }
  11. static inline void ijtor(int i,int j,int *r,int w) {
  12. //i,j to rank
  13. *r=i*w+j;
  14. }
  15. static inline int aj(int i,int j,int w) {
  16. return (j+i)%w;
  17. }
  18. static inline int bi(int i,int j,int w) {
  19. //initial b distribute
  20. return aj(i,j,w);
  21. }
  22. int main(int argc,char *argv[]) {
  23. float m[][2]={{1,2},
  24. {3,4}};//the matrix
  25. //multiply by itself
  26. int self,size;
  27. MPI_Init(&argc,&argv);
  28. MPI_Comm_rank(MPI_COMM_WORLD,&self);
  29. MPI_Comm_size(MPI_COMM_WORLD,&size);
  30. MPI_Request r;
  31. MPI_Status s;
  32. int w=sqrt(size);
  33. int i,j,an,bn,ap,bp;
  34. rtoij(self,w,&i,&j);
  35. ijtor(i,(j+w-1)%w,&an,w);//next a process
  36. ijtor((i+w-1)%w,j,&bn,w);//next b process
  37. ijtor(i,(j+1)%w,&ap,w);//previous a process
  38. ijtor((i+1)%w,j,&bp,w);
  39. float res,a,b,tmp;
  40. //initialize data distribution
  41. a=m[i][aj(i,j,w)];
  42. b=m[bi(i,j,w)][j];
  43. res=a*b;
  44. for(int i=0;i<w-1;++i) {
  45. MPI_Issend(&a,1,MPI_FLOAT,an,TAG,MPI_COMM_WORLD,&r);//avoid dead lock
  46. MPI_Recv(&tmp,1,MPI_FLOAT,ap,TAG,MPI_COMM_WORLD,&s);
  47. a=tmp;
  48. MPI_Wait(&r,&s);
  49. MPI_Issend(&b,1,MPI_FLOAT,bn,TAG,MPI_COMM_WORLD,&r);//avoid dead lock
  50. MPI_Recv(&tmp,1,MPI_FLOAT,bp,TAG,MPI_COMM_WORLD,&s);
  51. b=tmp;
  52. MPI_Wait(&r,&s);
  53. res+=a*b;
  54. }
  55. if(0==self) {
  56. printf("%f",res);
  57. for(int i=1;i<size;++i) {
  58. MPI_Recv(&res,1,MPI_FLOAT,i,TAG,MPI_COMM_WORLD,&s);
  59. printf(" %f",res);
  60. }
  61. printf("\n");
  62. } else {
  63. MPI_Ssend(&res,1,MPI_FLOAT,0,TAG,MPI_COMM_WORLD);
  64. }
  65. MPI_Finalize();
  66. return 0;
  67. }
Copyright © Linux教程網 All Rights Reserved