I have coded a program in C using MPI wherein the struct variable is to be sent in a ring fashion to the processes and, based on the value received from that variable, the work for that particular process is assigned.
The problem is I need to know how to to send a struct variable in the MPI_Send()
function as it is giving INVALID DATATYPE at the runtime , Consider the following example
struct info{
int ne, n, u, v, process, min, strip, mincost, b;
} stat;
MPI_Send(&stat,sizeof(stat),sizeof(struct info),1,2,MPI_COMM_WORLD);
You have to do some operation before send a struct.
I wrote the code for your example but to understand better you should read some documentation.
Anyway, here some tips:
- If you have a struct made of just one kind of elements, like in your example that all the vars are int, it's better to send a vector taking care the position of each variable.
- If you had other kinds, you have to set count to 2 or more and change all the other arrays (e.g: array_of_types, array_of_blocklengths et cetera).
- You can calculate the values of array_of_displaysments on your own in that case take care of the Data structure alignment.
If for example you have the struct that follows, x will start from 0 but y from 8, because a padding of 4 bytes will be add to align the elements.
struct point{ int x; double y; };
- If you don't want to calculate the array_of_displaysments always use MPI_Get_Address and do not rely on the & operator.
Here the code:
struct info{
int ne, n, u, v, process,min,strip,mincost,b;
}stat;
int main(...){
/*MPI INIT*/
struct info _info,
int count; //Says how many kinds of data your structure has
count = 1; //1, 'cause you just have int
// Says the type of every block
MPI_Datatype array_of_types[count];
// You just have int
array_of_types[0] = MPI_INT;
// Says how many elements for block
int array_of_blocklengths[count];
// You have 8 int
array_of_blocklengths[0] = {8};
/* Says where every block starts in memory, counting from the beginning of the struct. */
MPI_Aint array_of_displaysments[coun];
MPI_Aint address1, address2;
MPI_Get_address(&_info,&address1);
MPI_Get_address(&_info.ne,&address2);
array_of_displaysments[0] = address2 - address1;
/*Create MPI Datatype and commit*/
MPI_Datatype stat_type;
MPI_Type_create_struct(count, array_of_blocklengths, array_of_displaysments, array_of_types, &stat_type);
MPI_Type_commit(&stat_type);
// Now we are ready to send
MPI_Send(&_info, 1, stat_type, dest, tag, comm),
/* . . . */
// Free datatype
MPI_Type_free(&stat_type);
// MPI finalization
MPI_Finalize();
}
try this
MPI_Send(&stat,sizeof(struct info),MPI_CHAR,1,2,MPI_COMM_WORLD);
MPI_Recv(&data,sizeof(struct info), MPI_CHAR, 0, DEFAULT_TAG, MPI_COMM_WORLD, &status);
stat = (struct info *) data;