Matrix 块矩阵乘法

Matrix 块矩阵乘法,matrix,mpi,matrix-multiplication,Matrix,Mpi,Matrix Multiplication,我试图生成两个大小为n的矩阵A和B,将它们划分为s*s子矩阵,然后将它们分散到处理器中,在块矩阵之间执行乘法。我已经能够通过处理器成功地生成和分散子矩阵;然而,我被困在每个处理器的子矩阵上执行乘法。我的代码与下面帖子中的代码(答案部分的代码)非常相似,但我修改了两个矩阵: 你能告诉我如何修改这个来执行乘法吗 为了更容易跟进,我保留了相同的标签 #include <stdio.h> #include <stdlib.h> #include <

我试图生成两个大小为n的矩阵A和B,将它们划分为s*s子矩阵,然后将它们分散到处理器中,在块矩阵之间执行乘法。我已经能够通过处理器成功地生成和分散子矩阵;然而,我被困在每个处理器的子矩阵上执行乘法。我的代码与下面帖子中的代码(答案部分的代码)非常相似,但我修改了两个矩阵:

你能告诉我如何修改这个来执行乘法吗

为了更容易跟进,我保留了相同的标签

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

    #define COLSa 10
    #define ROWSa 10

    #define COLSb 10
    #define ROWSb 10
    #define s 2

   int main(int argc, char **argv) {

    MPI_Init(&argc, &argv);
    int p, rank;
    MPI_Comm_size(MPI_COMM_WORLD, &p);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    char i;
    char j;

    char a[ROWSa*COLSa];
    char b[ROWSb*COLSb];
    char c[ROWSa*COLSb];  // c=a*b

    const int NPROWS=s;  /* number of rows in _decomposition_ */
    const int NPCOLS=s;  /* number of cols in _decomposition_ */

    const int BLOCKROWSa = ROWSa/NPROWS;  /* number of rows in _block_ */
    const int BLOCKCOLSa = COLSa/NPCOLS; /* number of cols in _block_ */

    const int BLOCKROWSb = ROWSb/NPROWS;  /* number of rows in _block_ */
    const int BLOCKCOLSb= COLSb/NPCOLS; /* number of cols in _block_ */

    if (rank == 0) {

    for (int ii=0; ii<ROWSa*COLSa; ii++) {
         a[ii]=rand() %10 ;
    }

    for (int ii=0; ii<ROWSb*COLSb; ii++) {
         b[ii]=rand() %10 ;

       }
    }

    char BLa[BLOCKROWSa*BLOCKCOLSa];
    for (int ii=0; ii<BLOCKROWSa*BLOCKCOLSa; ii++)
    BLa[ii] = 0;

    char BLb[BLOCKROWSb*BLOCKCOLSb];
    for (int ii=0; ii<BLOCKROWSb*BLOCKCOLSb; ii++)
    BLb[ii] = 0;  

    char BLc[BLOCKROWSa*BLOCKCOLSb];
    for (int ii=0; ii<BLOCKROWSa*BLOCKCOLSb; ii++)
    BLc[ii] = 0; 

    MPI_Datatype blocktype;
    MPI_Datatype blocktype2;

    MPI_Type_vector(BLOCKROWSa, BLOCKCOLSa, COLSa, MPI_CHAR, &blocktype2);
    MPI_Type_vector(BLOCKROWSb, BLOCKCOLSb, COLSb, MPI_CHAR, &blocktype2);

    MPI_Type_create_resized( blocktype2, 0, sizeof(char), &blocktype);
    MPI_Type_commit(&blocktype);

    int dispsa[NPROWS*NPCOLS];
    int countsa[NPROWS*NPCOLS];
    int dispsb[NPROWS*NPCOLS];
    int countsb[NPROWS*NPCOLS];

    //*******************************Start Time Record****************//

    clock_t t;
    t=clock();

    for (int ii=0; ii<NPROWS; ii++) {
    for (int jj=0; jj<NPCOLS; jj++) {
    dispsa[ii*NPCOLS+jj] = ii*COLSa*BLOCKROWSa+jj*BLOCKCOLSa;
    countsa [ii*NPCOLS+jj] = 1;
        }
    }

    MPI_Scatterv(a, countsa, dispsa, blocktype, BLa, BLOCKROWSa*BLOCKCOLSa, MPI_CHAR, 0,   MPI_COMM_WORLD);


    for (int ii=0; ii<NPROWS; ii++) {
    for (int jj=0; jj<NPCOLS; jj++) {
    dispsb[ii*NPCOLS+jj] = ii*COLSb*BLOCKROWSb+jj*BLOCKCOLSb;
    countsb [ii*NPCOLS+jj] = 1;
         }
    }

    MPI_Scatterv(b, countsb, dispsb, blocktype, BLb, BLOCKROWSb*BLOCKCOLSb, MPI_CHAR, 0, MPI_COMM_WORLD);




     for (int proc=0; proc<p; proc++) {
        if (proc == rank) {

          printf("Rank = %d\n", rank);

                if (rank == 0) {
                  printf("Global matrix A : \n");

                   for (int ii=0; ii<ROWSa; ii++) {
                     for (int jj=0; jj<COLSa; jj++) {
                       printf("%3d ",(int)a[ii*COLSa+jj]);
                }
                        printf("\n");
            }
                 printf("\n");
            printf("Global matrix B : \n");

           for (int ii=0; ii<ROWSb; ii++) {
             for (int jj=0; jj<COLSb; jj++) {
              printf("%3d ",(int)b[ii*COLSb+jj]);
                }
         printf("\n");
            }
        printf("\n");
                  printf("Local Matrix A:\n");
              for (int ii=0; ii<BLOCKROWSa; ii++) {
                for (int jj=0; jj<BLOCKCOLSa; jj++) {
            printf("%3d ",(int)BLa[ii*BLOCKCOLSa+jj]);

                }

             printf("\n");
            }

           printf("\n");
              printf("Local Matrix B:\n");
                for (int ii=0; ii<BLOCKROWSb; ii++) {
                   for (int jj=0; jj<BLOCKCOLSb; jj++) {
                       printf("%3d ",(int)BLb[ii*BLOCKCOLSb+jj]);

                }

          printf("\n");
            }
                }


            printf("Local Matrix A:\n");
                    for (int ii=0; ii<BLOCKROWSa; ii++) {
                   for (int jj=0; jj<BLOCKCOLSa; jj++) {
                       printf("%3d ",(int)BLa[ii*BLOCKCOLSa+jj]);
                  }

             printf("\n");
            }

          printf("Local Matrix B:\n");
            for (int ii=0; ii<BLOCKROWSb; ii++) {
                for (int jj=0; jj<BLOCKCOLSb; jj++) {
                   printf("%3d ",(int)BLb[ii*BLOCKCOLSb+jj]);
                }

        printf("\n");
            }

  //**********************Multiplication***********************//

       for (int i = 0; i < BLOCKROWSa; i++) {
          for (j = 0; j < BLOCKCOLSb; j++) {

        for (k = 0; k < BLOCKCOLSb; k++) {  //I am considering square matrices with the same sizes
               BLc[i + j*BLOCKROWSa] += BLa[i + k*BLOCKROWSa]*BLb[k + BLOCKCOLb*j];
                  printf("%3d ",(int)BLc[i+j*BLOCKROWSa]);
                     }
    printf("\n");

                 }

      printf("\n");

             }

       }

      MPI_Barrier(MPI_COMM_WORLD);
    }

   MPI_Finalize();

   //**********************End Time Record************************//

    t=clock()-t;
     printf("It took %f seconds (%d clicks).\n",t,((float)t)/CLOCKS_PER_SEC);


       return 0;
     }
#包括
#包括
#包括
#包括
#定义COLSa 10
#定义第10行
#定义COLSb 10
#定义第10行
#定义s2
int main(int argc,字符**argv){
MPI_Init(&argc,&argv);
int p,秩;
MPI通信大小(MPI通信世界和p);
MPI通信等级(MPI通信世界和等级);
char i;
查尔j;
字符a[ROWSa*COLSa];
字符b[ROWSb*COLSb];
字符c[ROWSa*COLSb];//c=a*b
const int NPROWS=s;/*分解中的行数*/
const int NPCOLS=s;/*分解中的列数*/
const int BLOCKROWSa=ROWSa/NPROWS;/*块中的行数*/
const int BLOCKCOLSa=COLSa/NPCOLS;/*块中的列数*/
const int BLOCKROWSb=ROWSb/NPROWS;/*块中的行数*/
const int BLOCKCOLSb=COLSb/NPCOLS;/*块中的列数*/
如果(秩==0){

对于(int ii=0;ii要将块返回到进程0上的矩阵中,您可以使用
MPI\u Scatterv()
的“对立面”,称为
MPI\u Gatherv()

MPI_Gatherv(BLc、BLOCKROWSb*BLOCKCOLSb、MPI_字符、c、countsb、dispsb、blocktype、0、MPI_COMM_WORLD);
如果(秩==0){
printf(“全局矩阵C:\n”);

对于(intii=0;ii,除了缺少的
intk;
BLc[i+j*BLOCKROWSa]+=BLa[i+k*BLOCKROWSa]*BLb[k+BLOCKCOLb*j];
变成
BLc[i+j*BLOCKROWSa]+=BLa[i+k*BLOCKROWSa]*BLb[k+BLOCKCOLSb*j];
(一个
S
更多),只要你想在块矩阵之间执行乘法,你的代码就没有什么特别奇怪的地方。你为什么觉得自己被卡住了?你为什么对你的代码不满意?它与mpicc main.c-o main-std=c99和mpirun-np 4 main一起工作。你好,弗朗西斯。谢谢你的评论和更正。你好ver,通过这段代码,我无法在每个处理器上得到一个矩阵作为乘法的结果,出于某种原因,我在每个处理器上得到5个矩阵!!好的,我设法修复了那个部分,现在得到了一个乘积结果。但是乘法不正确!数学有问题!一个小加法,与您的问题无关。哟您使用的是rand(),但尚未使用srand启动种子。因此每次运行实际上都使用相同的矩阵。您可以添加一个“srand(time(NULL))“”来解决这个问题。弗朗西斯,非常感谢这一有用的观点。我刚刚意识到问题所在。我的矩阵乘法实际上是正确的,但元素从256中减去并显示出来。我的意思是,例如,我得到的不是135,而是(135-256)=-121。我试图将矩阵定义为浮点而不是字符,并相应地更改了MPI命令参数,但仍然不起作用。@THTH:只要您使用
char
!我使用了float,并在我的MPI命令中将MPI_字符更改为MPI_float,但我没有得到任何输出!您不从256中减去小数。您只需使用
有符号字符
s,这些字符通常可以保存-128到127之间的值。大于127的值在2的补码表示中被解释为负数。实际上,135是121的2的补码。感谢Hristo。那么这是否意味着如果我使用MPI_UNSIGNED_char,这将我能修好吗?
MPI_Gatherv(BLc, BLOCKROWSb*BLOCKCOLSb,MPI_CHAR, c, countsb, dispsb,blocktype, 0, MPI_COMM_WORLD);

if (rank == 0) {
    printf("Global matrix C : \n");

    for (int ii=0; ii<ROWSa; ii++) {
        for (int jj=0; jj<COLSa; jj++) {
            printf("%3d ",(int)c[ii*COLSa+jj]);
        }
        printf("\n");
    }
}