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);
}
|