Неустранимая ошибка в MPI_Recv: сообщение обрезано, стек ошибок - PullRequest
0 голосов
/ 13 марта 2020

Я делаю параллельную программу для умножения двух матриц (master-slave) с использованием библиотеки mpi, получаю ошибку в заголовке: «Сообщение с ранга 0, тег 99 усечен, получены 16 байтов, но размер буфера равен 0» , я подумал, что это происходит сбой при получении части матрицы на ведомых устройствах, и когда я пытался использовать stati c 2 darrays с постоянным размером, он работал просто отлично, поэтому я думаю, что проблема с n, m, n2, m2, которая содержит Размеры матриц, такие как когда они предопределены, работают, но при их вводе в программу происходит сбой, любая помощь будет принята.

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

int ** make_array(int n,int m)
{
    int i,j;
    int **arr = (int**)malloc(n*sizeof(int *));
    for(i=0;i<m;++i) arr[i] = (int*)malloc(m*sizeof(int));
    printf("Enter array elements:\n");
    for(i=0;i<n;++i)
        for(j=0;j<m;++j) scanf("%d",&arr[i][j]);
    return arr;
}
int main (int argc, char *argv[])
{

   int processes,rank,workers,rows, extra, offset,i, j, k, **a,**b,**c, n,m,n2,m2, split;

   MPI_Status status;
   MPI_Init(&argc,&argv);
   MPI_Comm_rank(MPI_COMM_WORLD,&rank);
   MPI_Comm_size(MPI_COMM_WORLD,&processes);
   if(processes<2){
    printf("Number of processes must be greater than 1 (there are no slaves like this)");
    return 0;
   }
   workers = processes-1;

   if (rank == 0)
   {
      printf("Enter dimensions of first matrix\n");
      scanf("%d %d",&n,&m);
      a = make_array(n,m);
      printf("Enter dimensions of second matrix\n");
      scanf("%d %d",&n2,&m2);
      b = make_array(n2,m2);
      if(m!=n2){
        printf("The dimensions of matrices are not suitable for multiplying, exiting .....\n");
        return 0;
      }
      c = (int**)malloc(n*sizeof(int *));
      for(i = 0;i<m2;++i) c[i] = (int*)malloc(m2*sizeof(int));

      split = n/workers;
      extra = n%workers;
      offset = 0;

      for (i=1; i<=workers; i++)
      {
         rows = (i <= extra) ? split+1 : split;
         printf("Sending %d rows to task %d offset=%d\n",rows,i,offset);
         MPI_Send(&offset, 1, MPI_INT, i, 99, MPI_COMM_WORLD);
         MPI_Send(&rows, 1, MPI_INT, i, 99, MPI_COMM_WORLD);
         MPI_Send(&a[offset][0], rows*m, MPI_INT, i, 99,
                   MPI_COMM_WORLD);
         MPI_Send(&b, m*m2, MPI_INT, i, 99, MPI_COMM_WORLD);
         offset = offset + rows;
      }

      /* Receive results from worker tasks */

      for (i=1; i<=workers; i++)
      {
          //printf("Heere");

         MPI_Recv(&offset, 1, MPI_INT, i, 99, MPI_COMM_WORLD, &status);
         MPI_Recv(&rows, 1, MPI_INT, i, 99, MPI_COMM_WORLD, &status);
         MPI_Recv(&c[offset][0], rows*m2, MPI_DOUBLE, i, 99,
                  MPI_COMM_WORLD, &status);
         printf("Received results from task %d\n",i);
      }

      /* Print results */
      printf("******************************************************\n");
      printf("Result Matrix:\n");
      for (i=0; i<n; i++)
      {
         printf("\n");
         for (j=0; j<m2; j++)
            printf("%d  ", c[i][j]);
      }
      printf("\n******************************************************\n");
      printf ("Done.\n");
   }

   if (rank > 0)
   {

      MPI_Recv(&offset, 1, MPI_INT, 0, 99, MPI_COMM_WORLD, &status);

      MPI_Recv(&rows, 1, MPI_INT, 0, 99, MPI_COMM_WORLD, &status);

      MPI_Recv(&a, rows*m, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD, &status);

      MPI_Recv(&b, m*m2, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD, &status);

      for (k=0; k<m2; k++)
         for (i=0; i<rows; i++)
         {
            c[i][k] = 0;
            for (j=0; j<m; j++)
               c[i][k] = c[i][k] + a[i][j] * b[j][k];
         }

      MPI_Send(&offset, 1, MPI_INT, 0, 99, MPI_COMM_WORLD);
      MPI_Send(&rows, 1, MPI_INT, 0, 99, MPI_COMM_WORLD);
      MPI_Send(&c, rows*m2, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD);
   }
   MPI_Finalize();
}
...