Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C语言对MPI中的2D矩阵进行MPI_散射和聚集_C_Matrix_Mpi - Fatal编程技术网

使用C语言对MPI中的2D矩阵进行MPI_散射和聚集

使用C语言对MPI中的2D矩阵进行MPI_散射和聚集,c,matrix,mpi,C,Matrix,Mpi,我正在尝试学习MPI并尝试使用这些示例 我会犯这样的错误 Fatal error in PMPI_Scatter: Invalid buffer pointer, error stack: PMPI_Scatter(783): MPI_Scatter(sbuf=0x6021e0, scount=16, MPI_INT, rbuf=0x6021e0, rcount=16, MPI_INT, root=0, MPI_COMM_WORLD) failed PMPI_Sca

我正在尝试学习MPI并尝试使用这些示例

我会犯这样的错误

     Fatal error in PMPI_Scatter: Invalid buffer pointer, error stack:
     PMPI_Scatter(783): MPI_Scatter(sbuf=0x6021e0, scount=16, MPI_INT, rbuf=0x6021e0, rcount=16, MPI_INT, root=0, MPI_COMM_WORLD) failed
     PMPI_Scatter(710): Buffers must not be aliased

 ===================================================================================
 =   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
 =   EXIT CODE: 1
 =   CLEANING UP REMAINING PROCESSES
 =   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
我的代码是:

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

   #define SIZE 8           /* Size of matrices */
   #define MAX_RAND     100

   int A[SIZE][SIZE], B[SIZE][1], C[SIZE][1],D[SIZE][SIZE],E[SIZE][1];

   void fill_matrix(int m[SIZE][SIZE])
   {
   //static int n=0;
    int i, j;

    printf("\n*****************************\n");
    for (i=0; i<SIZE; i++)
        {
            for (j=0; j<SIZE; j++){     
                m[i][j] = rand() % MAX_RAND;
                printf("%2d ", m[i][j]);
          }
        printf("\n");
        }
         printf("\n*****************************\n");
     }



    void fill_vector(int m[SIZE][1])
    {
    //static int n=0;
     int i, j;

     printf("\n*****************************\n");
      for (i=0; i<SIZE; i++)
       {
            for (j=0; j<1; j++){     
                m[i][j] = rand() % MAX_RAND;
                printf("%2d ", m[i][j]);
          }
        printf("\n");
        }
         printf("\n*****************************\n");
     }


    void print_matrix(int m[SIZE][SIZE])
    {
      int i, j = 0;
      for (i=0; i<SIZE; i++) {
        printf("\n\t| ");
        for (j=0; j<SIZE; j++)
          printf("%2d ", m[i][j]);
        printf("|");
      }
    }




    void print_vector(int m[SIZE][1])
    {
      int i, j = 0;
      for (i=0; i<SIZE; i++) {
        printf("\n\t| ");
        for (j=0; j<1; j++)
          printf("%2d ", m[i][j]);
        printf("|");
      }
    }


    int main(int argc, char *argv[])
    {
      int myrank, P, from, to, i, j, k;
    //  int tag = 666;      /* any value will do */
    //  MPI_Status status;

      MPI_Init (&argc, &argv);
      MPI_Comm_rank(MPI_COMM_WORLD, &myrank);   /* who am i */
      MPI_Comm_size(MPI_COMM_WORLD, &P); /* number of processors */


      if (SIZE%P!=0) {
        if (myrank==0) printf("Matrix size not divisible by number of processors\n");
        MPI_Finalize();
        exit(-1);
      }

      from = myrank * SIZE/P;
      to = ((myrank+1) * SIZE/P);

      /* Process 0 fills the input matrices and broadcasts them to the rest */
      /* (actually, only the relevant stripe of A is sent to each process) */

      if (myrank==0) {

    {
      //static int n=0;
      int i, j;

         printf("\n*****************************\n");
      for (i=0; i<SIZE; i++)
        {
            for (j=0; j<SIZE; j++){     
                A[i][j] = rand() % MAX_RAND;        
                printf("%d ", A[i][j]);
          }
        printf("\n");
        }
         printf("\n*****************************\n");
     }
        fill_vector(B);
      }

        int s=SIZE*SIZE/P;
     // printf("computing slice %d (from row %d to %d)\n", myrank, from, to-1);
      MPI_Bcast (B, SIZE*1, MPI_INT, 0, MPI_COMM_WORLD);
    //    printf("\n\n%d",s);
        //print_vector(s);
    //printf("\n\n");

      MPI_Scatter (&A, SIZE*SIZE/P, MPI_INT, &A[from], SIZE*SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);


      printf("computing slice %d (from row %d to %d)\n", myrank, from, to-1);
      for (i=from; i<to; i++) 
        for (j=0; j<SIZE; j++) {
          C[i][0]=0;
          for (k=0; k<SIZE; k++){
            C[i][0] += A[i][k]*B[k][0];
        }
        }

      MPI_Gather (&C[from], SIZE*SIZE/P, MPI_INT, &C, SIZE*SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);

      if (myrank==0) {
        printf("\n\n");

        {
            int i, j = 0;
                for (i=0; i<SIZE; i++) {
                        printf("\n\t| ");
                    for (j=0; j<SIZE; j++)
                        printf("%d ", A[i][j]);
                        printf("|");
            }
            }

        printf("\n\n");
        print_matrix(D);
        printf("\n\n\t       * \n");
        print_vector(B);
        printf("\n\n\t       = \n");
        print_vector(C);
        printf("\n\n");
        print_vector(E);
        printf("\n\n");
      }

      MPI_Finalize();
      return 0;
    }
#包括
#包括
#定义大小8/*矩阵的大小*/
#定义最大值为100
int A[大小][SIZE],B[大小][1],C[大小][1],D[大小][SIZE],E[大小][1];;
空洞填充矩阵(int m[SIZE][SIZE])
{
//静态int n=0;
int i,j;
printf(“\n*********************************\n”);

对于(i=0;i您的代码产生了两件事:

  • 正如您所猜测的,其中一个是与指针相关的错误。
    MPI\u Scatter()
    需要指向要发送的数据的指针和指向将接收数据的缓冲区的指针。例如,由于
    a
    是二维数组(在内存中连续):

其中,
&A[0][0]
是指向发送缓冲区的指针,
&A[from][0]
是指向接收缓冲区的指针

  • 第二个问题出现在
    MPI_Gather()
    中。当然,与第一个问题相同的错误也会出现。此外,
    C
    是一个向量,而不是一个矩阵:要发送的整数数量远低于
    SIZE*SIZE/p
    。因此,要发送的整数数量是
    SIZE/p

     MPI_Gather (&C[from][0], SIZE/P, MPI_INT, &C[0][0], SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
    
    其中
    int C[SIZE][1]
    是一个向量

以下是经过一些修改的代码:

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

#define SIZE 8           /* Size of matrices */
#define MAX_RAND     100

int A[SIZE][SIZE], B[SIZE][1], C[SIZE][1];//D[SIZE][SIZE],E[SIZE][1];

void fill_matrix(int m[SIZE][SIZE])
{
    //static int n=0;
    int i, j;

    printf("\n*****************************\n");
    for (i=0; i<SIZE; i++)
    {
        for (j=0; j<SIZE; j++){     
            m[i][j] = rand() % MAX_RAND;
            printf("%2d ", m[i][j]);
        }
        printf("\n");
    }
    printf("\n*****************************\n");
}



void fill_vector(int m[SIZE][1])
{
    //static int n=0;
    int i, j;

    printf("\n*****************************\n");
    for (i=0; i<SIZE; i++)
    {
        for (j=0; j<1; j++){     
            m[i][j] = rand() % MAX_RAND;
            printf("%2d ", m[i][j]);
        }
        printf("\n");
    }
    printf("\n*****************************\n");
}


void print_matrix(int m[SIZE][SIZE])
{
    int i, j = 0;
    for (i=0; i<SIZE; i++) {
        printf("\n\t| ");
        for (j=0; j<SIZE; j++)
            printf("%2d ", m[i][j]);
        printf("|");
    }
}




void print_vector(int m[SIZE][1])
{
    int i, j = 0;
    for (i=0; i<SIZE; i++) {
        printf("\n\t| ");
        for (j=0; j<1; j++)
            printf("%2d ", m[i][j]);
        printf("|");
    }
}


int main(int argc, char *argv[])
{
    int myrank, P, from, to, i, j, k;
    //  int tag = 666;      /* any value will do */
    //  MPI_Status status;

    MPI_Init (&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);   /* who am i */
    MPI_Comm_size(MPI_COMM_WORLD, &P); /* number of processors */


    if (SIZE%P!=0) {
        if (myrank==0) printf("Matrix size not divisible by number of processors\n");
        MPI_Finalize();
        exit(-1);
    }

    from = myrank * SIZE/P;
    to = ((myrank+1) * SIZE/P);

    /* Process 0 fills the input matrices and broadcasts them to the rest */
    /* (actually, only the relevant stripe of A is sent to each process) */

    if (myrank==0) {


        //static int n=0;
        int i, j;

        printf("\n*****************************\n");
        for (i=0; i<SIZE; i++)
        {
            for (j=0; j<SIZE; j++){     
                A[i][j] = rand() % MAX_RAND;        
                printf("%d ", A[i][j]);
            }
            printf("\n");

            printf("\n*****************************\n");
        }
        fill_vector(B);
    }

    //int s=SIZE*SIZE/P;
    // printf("computing slice %d (from row %d to %d)\n", myrank, from, to-1);
    MPI_Bcast (B, SIZE*1, MPI_INT, 0, MPI_COMM_WORLD);
    //    printf("\n\n%d",s);
    //print_vector(s);
    //printf("\n\n");
    if(myrank==0){
        MPI_Scatter (&A[0][0], SIZE*SIZE/P, MPI_INT, MPI_IN_PLACE, SIZE*SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
    }else{
        MPI_Scatter (&A[0][0], SIZE*SIZE/P, MPI_INT, &A[from][0], SIZE*SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
    }


    printf("computing slice %d (from row %d to %d)\n", myrank, from, to-1);
    for (i=from; i<to; i++) 
        for (j=0; j<SIZE; j++) {
            C[i][0]=0;
            for (k=0; k<SIZE; k++){
                C[i][0] += A[i][k]*B[k][0];
            }
        }

    if(myrank==0){
         MPI_Gather (MPI_IN_PLACE, SIZE/P, MPI_INT, &C[0][0], SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
    }else{
         MPI_Gather (&C[from][0], SIZE/P, MPI_INT, &C[0][0], SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
    }

    if (myrank==0) {
        printf("\n\n");

        {
            int i, j = 0;
            for (i=0; i<SIZE; i++) {
                printf("\n\t| ");
                for (j=0; j<SIZE; j++)
                    printf("%d ", A[i][j]);
                printf("|");
            }
        }

        printf("\n\n");
        //   print_matrix(D);
        printf("\n\n\t       * \n");
        print_vector(B);
        printf("\n\n\t       = \n");
        print_vector(C);
        printf("\n\n");
        //   print_vector(E);
        //   printf("\n\n");
    }

    MPI_Finalize();
    return 0;
}
#包括
#包括
#包括
#定义大小8/*矩阵的大小*/
#定义最大值为100
int A[SIZE][SIZE],B[SIZE][1],C[SIZE][1];//D[SIZE][SIZE],E[SIZE][1];
空洞填充矩阵(int m[SIZE][SIZE])
{
//静态int n=0;
int i,j;
printf(“\n*********************************\n”);
对于(i=0;i
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>

#define SIZE 8           /* Size of matrices */
#define MAX_RAND     100

int A[SIZE][SIZE], B[SIZE][1], C[SIZE][1];//D[SIZE][SIZE],E[SIZE][1];

void fill_matrix(int m[SIZE][SIZE])
{
    //static int n=0;
    int i, j;

    printf("\n*****************************\n");
    for (i=0; i<SIZE; i++)
    {
        for (j=0; j<SIZE; j++){     
            m[i][j] = rand() % MAX_RAND;
            printf("%2d ", m[i][j]);
        }
        printf("\n");
    }
    printf("\n*****************************\n");
}



void fill_vector(int m[SIZE][1])
{
    //static int n=0;
    int i, j;

    printf("\n*****************************\n");
    for (i=0; i<SIZE; i++)
    {
        for (j=0; j<1; j++){     
            m[i][j] = rand() % MAX_RAND;
            printf("%2d ", m[i][j]);
        }
        printf("\n");
    }
    printf("\n*****************************\n");
}


void print_matrix(int m[SIZE][SIZE])
{
    int i, j = 0;
    for (i=0; i<SIZE; i++) {
        printf("\n\t| ");
        for (j=0; j<SIZE; j++)
            printf("%2d ", m[i][j]);
        printf("|");
    }
}




void print_vector(int m[SIZE][1])
{
    int i, j = 0;
    for (i=0; i<SIZE; i++) {
        printf("\n\t| ");
        for (j=0; j<1; j++)
            printf("%2d ", m[i][j]);
        printf("|");
    }
}


int main(int argc, char *argv[])
{
    int myrank, P, from, to, i, j, k;
    //  int tag = 666;      /* any value will do */
    //  MPI_Status status;

    MPI_Init (&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);   /* who am i */
    MPI_Comm_size(MPI_COMM_WORLD, &P); /* number of processors */


    if (SIZE%P!=0) {
        if (myrank==0) printf("Matrix size not divisible by number of processors\n");
        MPI_Finalize();
        exit(-1);
    }

    from = myrank * SIZE/P;
    to = ((myrank+1) * SIZE/P);

    /* Process 0 fills the input matrices and broadcasts them to the rest */
    /* (actually, only the relevant stripe of A is sent to each process) */

    if (myrank==0) {


        //static int n=0;
        int i, j;

        printf("\n*****************************\n");
        for (i=0; i<SIZE; i++)
        {
            for (j=0; j<SIZE; j++){     
                A[i][j] = rand() % MAX_RAND;        
                printf("%d ", A[i][j]);
            }
            printf("\n");

            printf("\n*****************************\n");
        }
        fill_vector(B);
    }

    //int s=SIZE*SIZE/P;
    // printf("computing slice %d (from row %d to %d)\n", myrank, from, to-1);
    MPI_Bcast (B, SIZE*1, MPI_INT, 0, MPI_COMM_WORLD);
    //    printf("\n\n%d",s);
    //print_vector(s);
    //printf("\n\n");
    if(myrank==0){
        MPI_Scatter (&A[0][0], SIZE*SIZE/P, MPI_INT, MPI_IN_PLACE, SIZE*SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
    }else{
        MPI_Scatter (&A[0][0], SIZE*SIZE/P, MPI_INT, &A[from][0], SIZE*SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
    }


    printf("computing slice %d (from row %d to %d)\n", myrank, from, to-1);
    for (i=from; i<to; i++) 
        for (j=0; j<SIZE; j++) {
            C[i][0]=0;
            for (k=0; k<SIZE; k++){
                C[i][0] += A[i][k]*B[k][0];
            }
        }

    if(myrank==0){
         MPI_Gather (MPI_IN_PLACE, SIZE/P, MPI_INT, &C[0][0], SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
    }else{
         MPI_Gather (&C[from][0], SIZE/P, MPI_INT, &C[0][0], SIZE/P, MPI_INT, 0, MPI_COMM_WORLD);
    }

    if (myrank==0) {
        printf("\n\n");

        {
            int i, j = 0;
            for (i=0; i<SIZE; i++) {
                printf("\n\t| ");
                for (j=0; j<SIZE; j++)
                    printf("%d ", A[i][j]);
                printf("|");
            }
        }

        printf("\n\n");
        //   print_matrix(D);
        printf("\n\n\t       * \n");
        print_vector(B);
        printf("\n\n\t       = \n");
        print_vector(C);
        printf("\n\n");
        //   print_vector(E);
        //   printf("\n\n");
    }

    MPI_Finalize();
    return 0;
}