I need to send my own structure with MPI_Send(). The problem is, I am not sure how to use structures in MPI properly. Of course I've tried to find it by myself, but I haven't found any example which suits exactly my needs.
Now, when I run Makefile, I got this error:
probe_and_struct.c: In function ‘main’:
probe_and_struct.c:72:13: error: expected ‘;’ before ‘buf’
myStruct buf;
^
probe_and_struct.c:73:4: error: ‘buf’ undeclared (first use in this function)
buf = (myStruct *) malloc( sizeof(myStruct) * status_size );
^
probe_and_struct.c:73:4: note: each undeclared identifier is reported only once for each function it appears in
probe_and_struct.c:73:21: error: expected expression before ‘)’ token
buf = (myStruct *) malloc( sizeof(myStruct) * status_size );
^
make: *** [probe_and_struct] Error 1
So, could you please tell me, what am I doing wrong and how should I use the structure correctly?
EDIT: I've rewritten the code, but now the program crashes with Segmentation fault - on MPI_Send().
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define ARR_LEN 2 // length of test array and the size sent
int main() {
//---------------------------------------------------------------------------------------------------------------------------------------
// Create own structure
//----------------------
// Structure of structure :-)
struct {
int id;
char c;
} value;
// Declare parts of structure
MPI_Datatype myStruct;
int blockLengths[2];
MPI_Aint indices[2];
MPI_Datatype types[2];
// Initialize parts of structure
blockLengths[0] = 1; // stucture's attributes' sizes
blockLengths[1] = 1;
types[0] = MPI_INT; // structure's attributes' data types
types[1] = MPI_CHAR;
MPI_Address( &value.id, &indices[0] );
MPI_Address( &value.c, &indices[1] );
// Create and commit new structure
MPI_Type_struct( 2, blockLengths, indices, types, &myStruct );
MPI_Type_commit( &myStruct );
//---------------------------------------------------------------------------------------------------------------------------------------
// Message passing
//-----------------
MPI_Init(NULL, NULL);
value.id = 0;
value.c = 'a';
// Number of processes, ID of current process
int world_size;
MPI_Comm_size( MPI_COMM_WORLD, &world_size );
int world_rank;
MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
// Test array to send
int arr[ 2 ] = {10,20};
MPI_Status status;
switch( world_rank ) {
case 0:
printf("This is the process number %d.\n\t", world_rank);
MPI_Send( &value, 2, myStruct, 1, 0, MPI_COMM_WORLD);
printf("The array of INT was sent.\n");
break;
case 1:
// Recognize the size of the message
MPI_Probe( 0, 0, MPI_COMM_WORLD, &status );
// Number of blocks sent
int status_size;
MPI_Get_count( &status, myStruct, &status_size );
// Allocate buffer with the size needed
myStruct buf;
buf = (myStruct *) malloc( sizeof(myStruct) * status_size );
// Receive and print message
MPI_Recv( buf, status_size, myStruct, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
printf("This is the process number %d.\n\t[ ", world_rank);
for( int i = 0; i < status_size; i++ ) {
printf( "%d ", buf[i] );
}
printf("]\n");
break;
default:
printf("This is the process number %d.\n", world_rank);
break;
}
MPI_Type_free( &myStruct );
MPI_Finalize();
return 0;
}
Makefile:
CC=mpicc
STD=-std=c11
all: probe_and_struct
probe_and_struct: probe_and_struct.c
$(CC) -o probe_and_struct probe_and_struct.c $(STD)
clean:
rm -f probe_and_struct
My code - 2nd version:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define ARR_LEN 2 // length of test array and the size sent
int main()
{
MPI_Init(NULL, NULL);
//---------------------------------------------------------------------------------------------------------------------------------------
// Create own structure
//----------------------
// Structure of structure :-)
typedef struct Values
{
int id;
char c;
} Values;
Values value;
// Declare parts of structure
MPI_Datatype myStruct;
int blockLengths[2];
MPI_Aint indices[2];
MPI_Datatype types[2];
// Initialize parts of structure
blockLengths[0] = 1; // stucture's attributes' sizes
blockLengths[1] = 1;
types[0] = MPI_INT; // structure's attributes' data types
types[1] = MPI_CHAR;
MPI_Address( &value.id, &indices[0] );
MPI_Address( &value.c, &indices[1] );
// Create and commit new structure
MPI_Type_struct( 2, blockLengths, indices, types, &myStruct );
MPI_Type_commit( &myStruct );
//---------------------------------------------------------------------------------------------------------------------------------------
// Message passing
//-----------------
value.id = 0;
value.c = 'a';
// Number of processes, ID of current process
int world_size;
MPI_Comm_size( MPI_COMM_WORLD, &world_size );
int world_rank;
MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
// Test array to send
//int arr[ 2 ] = {10,20};
MPI_Status status;
switch( world_rank ) {
case 0:
printf("Toto je proces cislo %d.\n\t", world_rank);
MPI_Send( &value, sizeof(struct Values), myStruct, 1, 0, MPI_COMM_WORLD);
printf("Odeslano pole INTu.\n");
break;
case 1:
// Recognize the size of the message
MPI_Probe( 0, 0, MPI_COMM_WORLD, &status );
// Number of blocks sent
int status_size;
MPI_Get_count( &status, myStruct, &status_size );
puts("b");
// Allocate buffer with the size needed
Values * buf;
buf = (Values *) malloc( sizeof(Values) * status_size );
puts("b");
// Receive and print message
//MPI_Recv( buf, status_size, myStruct, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
printf("Toto je proces cislo %d.\n\t[ ", world_rank);
for( int i = 0; i < status_size; i++ ) {
printf( "%d %c", buf[i].id, buf[i].c );
}
printf("]\n");
break;
default:
printf("Toto je proces cislo %d.\n", world_rank);
break;
}
MPI_Type_free( &myStruct );
MPI_Finalize();
return 0;
}