Skip to content

Can you send an array within an array using MPI_Send and MPI_Recv?

An answer to this question on Stack Overflow.

Question

This is the very basic function of my program, and as such is not necessarily reproducible. However, I was wondering if there is a way to send an array of arrays using MPI? Or is this something that is not possible and I should flatten my array? Any help would be greatly appreciated as I've been struggling with trying to figure this out.

int *individual_topIds;
int **cell_topIds;
cell_topIds = (int**) malloc(sizeof(int*)*25*boxes);
if(rank == 0) {
    for (int i = 0; i < boxes; i++) {
        individual_topIds = (int*) malloc(sizeof(int)*25);
        for(int j = 0; j < cellMatrix[i].numTop; j++){
            individual_topIds[j] = cellMatrix[i].aTopIds[j];
        }
        cell_topIds[i] = individual_topIds;
     }
     MPI_Send(cell_topIds, boxes*25, MPI_INT, 1, 10, MPI_COMM_WORLD);
}

Then in my rank == 1 section. I have tried send and receive with just boxes, and not boxes*25 as well.

for 1 -> boxes
  MPI_Recv(cell_topIds, boxes*25, MPI_INT, 0, 10, MPI_COMM_WORLD, &status);
  int *ptop;
  ptop = (int*) malloc(sizeof(int)*25);
  ptop = cell_topIds[i];
  printf("1\n");
  for(int j = 0; j < sizeof(&ptop)/sizeof(int); j++){
         printf("%d, ", ptop[j]);
  }
  printf("2\n");
end for i -> boxes
free(ptop);

Edit: Forgot to mention that the output of the print is a seg fault Caught error: Segmentation fault (signal 11)

Answer

This is not a particularly well-worded question.

However, MPI will let you send arrays of arrays if you use a custom type, as below:

#include "mpi.h"
#include <stdio.h>
struct Partstruct
{
    char c;
    double d[6];
    char b[7];
};
int main(int argc, char *argv[])
{
    struct Partstruct particle[1000];
    int i, j, myrank;
    MPI_Status status;
    MPI_Datatype Particletype;
    MPI_Datatype type[3] = { MPI_CHAR, MPI_DOUBLE, MPI_CHAR };
    int blocklen[3] = { 1, 6, 7 };
    MPI_Aint disp[3];
 
    MPI_Init(&argc, &argv);
 
    disp[0] = &particle[0].c - &particle[0];
    disp[1] = &particle[0].d - &particle[0];
    disp[2] = &particle[0].b - &particle[0];
    MPI_Type_create_struct(3, blocklen, disp, type, &Particletype);
    MPI_Type_commit(&Particletype);
 
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
 
    if (myrank == 0)
    {
        MPI_Send(particle, 1000, Particletype, 1, 123, MPI_COMM_WORLD);
    }
    else if (myrank == 1)
    {
        MPI_Recv(particle, 1000, Particletype, 0, 123, MPI_COMM_WORLD, &status);
    }
    MPI_Finalize();
    return 0;
}

Alternatively, use a flat array design (this is a good idea for performance reasons as well as easy compatibility with MPI).