MPI中的矩阵乘法(C) [英] Matrix multiplication in MPI with(C)

查看:93
本文介绍了MPI中的矩阵乘法(C)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用MPI创建一个简单的矩阵乘法程序,这个代码的思想是按行分割第一个矩阵(a),按列分割第二个矩阵(b)并将这些行和列发送到所有处理器,程序必须是(第一个矩阵按行分割*第二个矩阵按列分割)但我在最终结果中有错误

 4.00 4.00 4.00 4.00 
1.00 1.00 1.00 1.00
2.00 1.00 1.00 1.00
2.00 2.00 1.00 1.00



应该是

 4.00 4.00 4.00 4.00 
4.00 4.00 4.00 4.00
4.00 4.00 4.00 4.00
4.00 4.00 4.00 4.00





我的尝试:



 #include< stdio.h> 
#include< stdlib.h>
#include< mpi.h>

#define SIZE 4
#define FROM_MASTER 1
#define FROM_WORKER 2
#define DEBUG 1

MPI_Status status;

静态双倍[SIZE] [SIZE];
静态双b [SIZE] [SIZE];
静态双c [SIZE] [SIZE];

static void init_matrix(void)
{
int i,j;
for(i = 0; i< SIZE; i ++)
{
for(j = 0; j< SIZE; j ++){
a [i] [j] = 1;
b [i] [j] = 1;

} //结束于i
} //结束为j
} //结束init_matrix()

static void print_matrix(void)
{
int i,j;
for(i = 0; i< SIZE; i ++){
for(j = 0; j< SIZE; j ++){
printf(%7.2f,c [ i] [j]);
} //结束i
printf(\ n);
} //结束于j
} //结束print_matrix

int main(int argc,char ** argv)
{
int myrank, NPROC;
int rows;
int mtype;
int dest,src,offseta,offsetb;
double start_time,end_time;
int i,j,k,l;

MPI_Init(& argc,& argv);
MPI_Comm_size(MPI_COMM_WORLD,& nproc);
MPI_Comm_rank(MPI_COMM_WORLD,& myrank);

rows = SIZE / nproc; //计算块大小
mtype = FROM_MASTER; // = 1

if(myrank == 0){
/ *初始化* /
printf(SIZE =%d,节点数=%d \ n ,SIZE,nproc);
init_matrix();

start_time = MPI_Wtime();

if(nproc == 1){
for(i = 0; i< SIZE; i ++){
for(j = 0; j< SIZE; j ++) ){
for(k = 0; k< SIZE; k ++)
c [i] [j] = c [i] [j] + a [i] [k] * b [j] [K];
} //结束于i
} //结束为j
end_time = MPI_Wtime();
print_matrix(); // ---------------------------------
printf( %2d节点上的执行时间:%f \ n,nproc,end_time-
start_time);
} //结束if(nproc == 1)

else {

for(l = 0; l< nproc; l ++){
offsetb = rows * l; //从(块大小*处理器ID)开始
offseta = rows;
mtype = FROM_MASTER; // tag = 1

for(dest = 1; dest< nproc; dest ++){
MPI_Send(& offseta,1,MPI_INT,dest,mtype,
MPI_COMM_WORLD );
MPI_Send(& offsetb,1,MPI_INT,dest,mtype,
MPI_COMM_WORLD);
MPI_Send(& rows,1,MPI_INT,dest,mtype,MPI_COMM_WORLD);
MPI_Send(& a [offseta] [0],rows * SIZE,MPI_DOUBLE,dest,
mtype,MPI_COMM_WORLD);
MPI_Send(& b [0] [offsetb],行* SIZE,MPI_DOUBLE,dest,
mtype,MPI_COMM_WORLD);

offseta + = rows;
offsetb =(offsetb + rows)%SIZE;

} //结束于目的地

offseta = rows;
offsetb = rows * l;

// - 多个最终本地和打印最终全局多元
(i = 0; i< offseta; i ++){
for(j = offsetb; j < offsetb + rows; j ++){
for(k = 0; k< SIZE; k ++){
c [i] [j] = c [i] [j] + a [i] [K] * b [k]的[D];
} //结束为k
} //结束为j
} //结束为
/ * - 等待所有工人任务的结果* /
mtype = FROM_WORKER;
for(src = 1; src< nproc; src ++){
MPI_Recv(& offseta,1,MPI_INT,src,mtype,MPI_COMM_WORLD,
& status);
MPI_Recv(& offsetb,1,MPI_INT,src,mtype,MPI_COMM_WORLD,
& status);
MPI_Recv(& rows,1,MPI_INT,src,mtype,MPI_COMM_WORLD,
& status);
for(i = 0; i< rows; i ++){
MPI_Recv(& c [offseta + i] [offsetb],offseta,MPI_DOUBLE,
src,mtype,MPI_COMM_WORLD, &安培;状态);
} //结束为scr
} //结束为i
} //结束为l
end_time = MPI_Wtime();
print_matrix();
printf(%2d节点上的执行时间:%f \ n,nproc,end_time-
start_time);
} //结束其他
} //结束if(myrank == 0)

else {
/ * ---------- ------------------ worker ---------------------- * /
if(nproc > 1){
for(l = 0; l< nproc; l ++){
mtype = FROM_MASTER;
MPI_Recv(& offseta,1,MPI_INT,0,mtype,MPI_COMM_WORLD,
& status);
MPI_Recv(& offsetb,1,MPI_INT,0,mtype,MPI_COMM_WORLD,
& status);
MPI_Recv(& rows,1,MPI_INT,0,mtype,MPI_COMM_WORLD,
& status);

MPI_Recv(& a [offseta] [0],行* SIZE,MPI_DOUBLE,0,mtype,
MPI_COMM_WORLD,& status);
MPI_Recv(& b [0] [offsetb],行* SIZE,MPI_DOUBLE,0,mtype,
MPI_COMM_WORLD,& status);

for(i = offseta; i< offseta + rows; i ++){
for(j = offsetb; j< offsetb + rows; j ++){
for(
for( k = 0; k c [i] [j] = c [i] [j] + a [i] [k] * b [k] [j];
} //结束为j
} //结束为i

} //结束为l

mtype = FROM_WORKER;
MPI_Send(& offseta,1,MPI_INT,0,mtype,MPI_COMM_WORLD);
MPI_Send(& offsetb,1,MPI_INT,0,mtype,MPI_COMM_WORLD);
MPI_Send(& rows,1,MPI_INT,0,mtype,MPI_COMM_WORLD);
for(i = 0; i< rows; i ++){
MPI_Send(& c [offseta + i] [offsetb],offseta,MPI_DOUBLE,0,
mtype,MPI_COMM_WORLD) ;

} //结束为i
} //结束为l

} //结束if(nproc> 1)
} //结束其他

MPI_Finalize();
返回0;
} //结束main()

解决方案

这对我来说似乎不对:

 for(i = 0; i< SIZE; i ++){
for(j = 0; j< SIZE; j ++){
for(k = 0; k< SIZE; k ++)
c [i] [j] = c [i] [j] + a [i] [k] * b [j] [k];
} //结束为i
} //结束为j

应该是:

 c [ i] [j] = c [i] [j] + a [i] [k] * b [k] [j]; 



或?


I'm trying to create a simple Matrix Multiplication program with MPI ,the idea of this code is split the first matrix (a) by row and the second matrix(b)by column and send these rows and columns to all processors ,the program must be (first matrix split by rows * second matrix split by columns) but I have error in the final result

4.00   4.00   4.00   4.00
1.00   1.00   1.00   1.00
2.00   1.00   1.00   1.00
2.00   2.00   1.00   1.00


it should be

4.00   4.00   4.00   4.00
4.00   4.00   4.00   4.00
4.00   4.00   4.00   4.00
4.00   4.00   4.00   4.00



What I have tried:

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

#define SIZE 4
#define FROM_MASTER 1
#define FROM_WORKER 2
#define DEBUG 1 

MPI_Status status;

static double a[SIZE][SIZE];
static double b[SIZE][SIZE];
static double c[SIZE][SIZE];

static void init_matrix(void)
{
    int i, j;
    for (i = 0; i < SIZE; i++)
    {
        for (j = 0; j < SIZE; j++) {
              a[i][j] = 1;
              b[i][j] = 1;

       } //end for i
    }  //end for j
} //end init_matrix()

static void print_matrix(void)
{
int i, j;
for(i = 0; i < SIZE; i++) {
    for(j = 0; j < SIZE; j++) {
        printf("%7.2f", c[i][j]);
    } //end for i
printf("\n");
   }    //end for j
  }        //end print_matrix

int main(int argc, char **argv)
{
int myrank, nproc;
int rows;   
int mtype;   
int dest, src, offseta, offsetb;
double start_time, end_time;
int i, j, k, l;

MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

rows = SIZE/nproc;  //compute the block size
mtype = FROM_MASTER; //  =1

   if (myrank == 0) {
    /*Initialization*/
    printf("SIZE = %d, number of nodes = %d\n", SIZE, nproc);
    init_matrix();

    start_time = MPI_Wtime();

    if(nproc == 1) { 
        for(i = 0; i < SIZE; i++) {
            for(j = 0; j < SIZE; j++) {
                for(k = 0; k < SIZE; k++)
                    c[i][j] = c[i][j] + a[i][k]*b[j][k];
            } //end for i
        }  //end for j
        end_time = MPI_Wtime();
        print_matrix();//---------------------------------
        printf("Execution time on %2d nodes: %f\n", nproc, end_time-
                    start_time);
    } // end  if(nproc == 1)

    else {

          for(l = 0; l < nproc; l++){
            offsetb = rows*l;  //start from (block size * processor id)
            offseta = rows; 
            mtype = FROM_MASTER; // tag =1

              for(dest = 1; dest < nproc; dest++){
                MPI_Send(&offseta, 1, MPI_INT, dest, mtype,
                            MPI_COMM_WORLD);
                MPI_Send(&offsetb, 1, MPI_INT, dest, mtype, 
                            MPI_COMM_WORLD);
                MPI_Send(&rows, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
                MPI_Send(&a[offseta][0], rows*SIZE, MPI_DOUBLE, dest,
                             mtype, MPI_COMM_WORLD);
                MPI_Send(&b[0][offsetb], rows*SIZE, MPI_DOUBLE, dest, 
                          mtype, MPI_COMM_WORLD);

                offseta += rows;
                offsetb = (offsetb+rows)%SIZE;

            } // end for dest

            offseta = rows;
            offsetb = rows*l;

     //--mult the final local and print final global mult
            for(i = 0; i < offseta; i++) {
                for(j = offsetb; j < offsetb+rows; j++) {
                        for(k = 0; k < SIZE; k++){
                            c[i][j] = c[i][j] + a[i][k]*b[k][j];
                    }//end for k
                } //end for j
            }// end for i
               /*- wait for results from all worker tasks */
            mtype = FROM_WORKER;
            for(src = 1; src < nproc; src++){
                MPI_Recv(&offseta, 1, MPI_INT, src, mtype, MPI_COMM_WORLD,
                           &status);
                MPI_Recv(&offsetb, 1, MPI_INT, src, mtype, MPI_COMM_WORLD,
                            &status);
                MPI_Recv(&rows, 1, MPI_INT, src, mtype, MPI_COMM_WORLD, 
                           &status);
                for(i = 0; i < rows; i++) {
                    MPI_Recv(&c[offseta+i][offsetb], offseta, MPI_DOUBLE,
           src, mtype, MPI_COMM_WORLD, &status);
                } //end for scr
            }//end for i
        } //end for l
        end_time = MPI_Wtime();          
        print_matrix();
        printf("Execution time on %2d nodes: %f\n", nproc, end_time-
             start_time);
       }//end else
   } //end if (myrank == 0) 

   else{  
          /*---------------------------- worker----------------------*/
      if(nproc > 1) {
            for(l = 0; l < nproc; l++){
               mtype = FROM_MASTER;
               MPI_Recv(&offseta, 1, MPI_INT, 0, mtype, MPI_COMM_WORLD,
                       &status);
               MPI_Recv(&offsetb, 1, MPI_INT, 0, mtype, MPI_COMM_WORLD,
                       &status);
            MPI_Recv(&rows, 1, MPI_INT, 0, mtype, MPI_COMM_WORLD, 
                      &status);

            MPI_Recv(&a[offseta][0], rows*SIZE, MPI_DOUBLE, 0, mtype, 
            MPI_COMM_WORLD, &status);
            MPI_Recv(&b[0][offsetb], rows*SIZE, MPI_DOUBLE, 0, mtype, 
            MPI_COMM_WORLD, &status);

            for(i = offseta; i < offseta+rows; i++) {
                for(j = offsetb; j < offsetb+rows; j++) {
                    for(k = 0; k < SIZE; k++){
                        c[i][j] = c[i][j] + a[i][k]*b[k][j];  
                    } //end for j
                } //end for i    

            } //end for l

            mtype = FROM_WORKER;
            MPI_Send(&offseta, 1, MPI_INT, 0, mtype, MPI_COMM_WORLD);
            MPI_Send(&offsetb, 1, MPI_INT, 0, mtype, MPI_COMM_WORLD);
            MPI_Send(&rows, 1, MPI_INT, 0, mtype, MPI_COMM_WORLD);
                for(i = 0; i < rows; i++){
                MPI_Send(&c[offseta+i][offsetb], offseta, MPI_DOUBLE,   0, 
                 mtype, MPI_COMM_WORLD);

               } //end for i
            }//end for l

        } //end if (nproc > 1)
    } // end else

    MPI_Finalize();
    return 0;
} //end main()

解决方案

This seems wrong to me:

for(i = 0; i < SIZE; i++) {
    for(j = 0; j < SIZE; j++) {
        for(k = 0; k < SIZE; k++)
            c[i][j] = c[i][j] + a[i][k]*b[j][k];
    } //end for i
}  //end for j

should be:

c[i][j] = c[i][j] + a[i][k]*b[k][j];


or?


这篇关于MPI中的矩阵乘法(C)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆