Open MPI logo

Open MPI User's Mailing List Archives

  |   Home   |   Support   |   FAQ   |   all Open MPI User's mailing list

Subject: [OMPI users] MPI with dynamic arrays
From: Sylvestre Ledru (sylvestre.ledru_at_[hidden])
Date: 2011-08-10 11:57:12


Hello,

I would like to know what could be the best way to send three variables
with the following types:
double * data; (which can be also int *, float * but that is a different
issue)
int row; // number of row
int col; // number of cols

On the nodes, I have no way to know a priori what is going to be the
size of myArray.

After playing with various solutions MPI_Pack or MPI_Type_contiguous
(which were failures...), I started to play with MPI_Type_Create_Struct.

Unfortunately, as the following (long) code [1] shows, it won't send the
actual content of "data" but just the pointer.
Is there any way to specify that I want to send the actual data ?
(or what could be a good way to do so)

Thanks,
Sylvestre

PS: I tried with a two steps MPI_Send/MPI_Recv (first sending the
size/type, then receiving the data). It is working but I am afraid of
bad performances... I would prefer send everything at once.

[1]
#include <mpi.h>
#include <string.h>
#include <stdio.h>

#define N 1
#define NUMBER_PARAM 3
typedef struct particule {
    char myString[6];
    int mass;
    double *data;
// double data[2];
} PARTICULE;

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

  int rang, code, i;
  const int TAG=100;
  int block_length[NUMBER_PARAM];
  MPI_Aint adresses[NUMBER_PARAM],displacements[NUMBER_PARAM];
  MPI_Datatype type_particule,types[NUMBER_PARAM];
  MPI_Status statut;
  PARTICULE p[N];

  MPI_Init(&argc,&argv);
  MPI_Comm_rank(MPI_COMM_WORLD,&rang);

  if (rang == 0){
    for (i=0; i<N ; i++) {
      strcpy(p[i].myString,"CELL0");
      p[i].mass= 0;
      p[i].data=(double*) malloc(2*sizeof(double));
      p[i].data[0]=21.0;
      p[i].data[1]=3.0;
    }
  }

  types[0] = MPI_CHAR;
  types[1] = MPI_INT;
  types[2] = MPI_DOUBLE;
  block_length[0] = 6;
  block_length[1] = 1;
  block_length[2] = 2; /* cf malloc of data */

  MPI_Get_address(&p[0].myString,&adresses[0]);
  MPI_Get_address(&p[0].mass,&adresses[1]);
  MPI_Get_address(&p[0].data,&adresses[2]);

  for (i=0; i<NUMBER_PARAM ; i++)
    displacements[i] = adresses[i]-adresses[0];

MPI_Type_create_struct(NUMBER_PARAM,block_length,displacements,types,&type_particule);
  MPI_Type_commit(&type_particule);

  if (rang == 0)
    MPI_Send(&p,N,type_particule,1,TAG,MPI_COMM_WORLD);
  else {
    MPI_Recv(&p,N,type_particule,0,TAG,MPI_COMM_WORLD,&statut);
    printf ("Struct received by CPU 1 \n");
    for (i=0; i<N ; i++) {
        printf ("%s ",p[i].myString);
        printf ("%d ",p[i].mass);
        printf ("%d ",p[i].data);
        fflush(NULL);
        printf ("%f ",p[i].data[0]); // Crashes.
        printf ("\n");
    }

  }

  MPI_Type_free(&type_particule);
  MPI_Finalize();
  return(0);
}