当前位置:编程学习 > C/C++ >>

MPI 实现 SUMMA 矩阵乘法

SUMMA 算法

 

SUMMA 算法和Fox 算法一样,将A , B 和C 划分为相同大小的矩阵,对应放在r×c 二维 mesh 上. 但
SUMMA 算法将矩阵乘法分解为一系列的秩nb 修正,即各处理器中的A 和B 分别被分解为nb 大小的列块
和行块进行相乘, nb≤min( k/ r , k / c) , 前面所说的分块尺寸就是指nb 的大小. 算法中, 广播实现为逻辑处理
器行环或列环上的流水线传送, 达到了计算与通信的重叠.具体描述如算法1所示.

 

算法1. 二维mesh 上的SUMMA 算法
C= 0
for i= 0 t o k- 1 step nb do
 cur col = i×c/ n
 cur r ow = i×r / m
 if my col = curr ol 向本行广播 A 从 i mo d ( k/ c) 列开始的 nb 列,存于 A′
 if my r ow = curr ow 向本列广播 B 从 i mod ( k / r )行开始的 nb 行,存于 B′
 C= C+ A′ ×B′
end fo r
SUMMA 算法的计算量为 ( n^3/ p ) . 算法中通信部分采用了流水线广播的技术, 其通信开销应为( k/ nb+ 2c- 3) ( ts + m×nb tw / r) + ( k / nb+ 2r - 3) ( t s+ n×nbtw / c) ,当m= k= n 且r = c= p 时通信开销为2( n/ nb+ 2 p - 3) ( ts+ n×nb tw / p ) .由于每个处理器上需要存放A , B 和C 三个子矩阵,再加上接收消息所需空间,总共需要的空间为 ( 3^n2/ p + 2nb×n/ p ) .
SUMMA 算法的计算复杂度和Fo x 算法相当,而所需的辅助空间小于Fox 算法, 在处理器数目相同时,
SUMMA 算法可以求解更大规模的问题.另外又由于SUMMA 算法采用了流水线广播的技术,其通信开销
中不含lo gP 因子,故SUMMA 算法具有更好的可扩放性,对于大规模并行机, SUMMA 算法要优于Fox 算法.

 

 

实现代码:


[cpp] 
/****************summa***************************************/ 
/**********  2012.11.17   YingfengChen    *******************/ 
/************************************************************/  
#include <mpi.h> 
#include <stdio.h> 
#include <math.h> 
#include <stdlib.h> 
#include <time.h> 
#include <sys/time.h> 
 
 
 
void PrintMatrixForVector(int * matrix,int high,int len) 

    int i; 
    for(i=0;i<high*len;i++) 
    { 
         
        printf("%6d  ",matrix[i]); 
         
        if(i%len==len-1&&i!=0) 
            printf("\n"); 
         
         
    } 
     
     

 
/*******可以利用open MP并行优化**********/ 
void MatrixMultiply(int * A,int *B,int *C,unsigned m,unsigned n,unsigned p) 
{   int i,j,k; 
     
    /*printf("A: \n");
    PrintMatrixForVector(A,m,n);
 
    printf("B: \n");
    PrintMatrixForVector(B,n,p);*/ 
 
 
    for(i=0;i<m;i++) 
       for(j=0;j<p;j++) 
            
       { 
           int result=0;  
           for(k=0;k<n;k++) 
            { 
               result=A[i*n+k]*B[k*p+j]+result; 
                
            } 
           C[i*p+j]=result; 
            
 
 
       } 
     
 
 
 

 
 
/*******可以利用open MP并行优化**********/ 
void MatrixAdd(int * A,int *B,unsigned m,unsigned n) //the result remain in A 
{  int i,j; 
   for(i=0;i<m;i++) 
      for(j=0;j<n;j++) 
        { 
            A[i*n+j]=A[i*n+j]+B[i*n+j]; 
        } 
 
 

 
 
void PrintMatrix(int ** matrix,int high,int len) 

    int i,j; 
    for(i=0;i<high;i++) 
    { 
        for(j=0;j<len;j++) 
        { 
            printf("%6d  ",matrix[i][j]); 
 
        } 
        printf("\n"); 
    } 
 
 

 
 
 
/****随机数据以待计算****/ 
void RandomMatrix(int *matrix,int len) 

   struct timeval tpstart;  //使数据更均匀 
   gettimeofday(&tpstart,NULL); 
   srand(tpstart.tv_usec); 
   int i=0; 
   for(i=0;i<len;i++) 
   matrix[i]=rand()%8; 
 
 
 

int main(int argc,char **argv) 

 
 
 
    int rank; 
    MPI_Status status; 
    MPI_Init(&argc,&argv); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
 
    int nodeNum;  //节点数,必须为可开平方 
     
    int matrixHighA;// 矩阵A行数 
    int matrixLenA;//矩阵A列数 
     
     
    int matrixHighB; 
    int matrixLenB; 
 
 
 
    /****   参数检查  参数错误用默认参数*****/ 
    if(argc!=5&&rank==0) 
    { 
 
         printf("The para is wrong!using default para\n"); 
 
 
 
         nodeNum=4; 
          
         matrixHighA=6; 
         matrixLenA=8; 
          
          
         matrixHighB=8; 
&nb

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,