0

I am trying to share a dynamically allocated 2D array from a master thread to several other threads using MPI in c, from within a function.

A simplified representation of the relevant code is as follows:

//Initialize program, start up the desired number of threads.
//Master thread takes input from user, dynamically allocates and constructs 2d array.
//All threads call method analyze_inputs(**array), which takes the array as input (all threads other than master simply pass NULL as argument)
//The master thread shares the array, along with work division to all other threads:
{//Master thread
  MPI_Send(&x, 1, MPI_INT, recievingThread, 0, MPI_COMM_WORLD);
  MPI_Send(&y, 1, MPI_INT, recievingThread, 0, MPI_COMM_WORLD);
  MPI_Send(&(array[0][0]), x*y, MPI_INT, recievingThread, 0, MPI_COMM_WORLD);
}

{//Subthreads
  MPI_Recv(&x, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  MPI_Recv(&y, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  MPI_Recv(&(array[0][0]), x*y, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}

This is a soulution i found on this site for sending dynamically allocated 2d arrays, but i get segmentation error for the array recieve.

How can i do this?

edit: Minimal reproducible example

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

int analyze_inputs (int x, int y, int** array);

int main (int argc, char **argv)
{
  int x = 10;
  int y = 8;
  int rank;
  int **array = NULL;

  MPI_Init (&argc, &argv);
  MPI_Comm_rank (MPI_COMM_WORLD, &rank);
  if (rank == 0)
  {
    array = malloc(x * sizeof(int*));
    for (int i = 0; i < x; i++)
    {
      array[i] = malloc(y * sizeof(int));
    }

    for (int i = 0; i < x; i++)
    {
      for (int j = 0; j < y; j++)
      {
        array[i][j] = rand();
      }
    }
  }
  analyze_inputs(x,y,array);
  MPI_Finalize ();
}

int analyze_inputs(int x,int y, int** array)
{
  int rank, x_temp, y_temp, **array_temp;
  MPI_Comm_rank (MPI_COMM_WORLD, &rank);

  if (rank == 0)
  {
    MPI_Send(&x, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
    MPI_Send(&y, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
    MPI_Send(&(array[0][0]), x*y, MPI_INT, 1, 0, MPI_COMM_WORLD);
  }
  else
  {
    MPI_Recv(&x_temp, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    MPI_Recv(&y_temp, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    printf("Works to here.\n");
    MPI_Recv(&(array_temp[0][0]), x_temp*y_temp, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    printf("Crashes before here.\n");
  }
}
Silver
  • 3
  • 2
  • Please post a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). How did you allocate `array`? – MikeCAT May 02 '20 at 16:42
  • Edited in Minimal, Reproducible Example. array is allocated dynamically. – Silver May 02 '20 at 17:34

1 Answers1

0

Each row of array is allocated separately in your code, so simple

MPI_Send(&(array[0][0]), x*y, MPI_INT, 1, 0, MPI_COMM_WORLD);

won't work in this case.

An simple solution is to allocate a single block of memory like this:

array = malloc(x * sizeof(int*));
array[0] = malloc(y * x * sizeof(int));
for (int i = 1; i < x; i++)
{
  array[i] = array[0] + y * i;
}

And freeing this array will be

free(array[0]);
free(array);

Do not free array[1], array[2], ... in this case because they are already freed by free(array[0]);.

MikeCAT
  • 61,086
  • 10
  • 41
  • 58