Send/Receive using MPI_Type_struct


L

lancer6238

Hi all,
I'm trying to send and receive a structure array "TABLE". I tried
using MPI_Type_struct but I got "Segmentation fault" when the
processor (P1) is supposed to receive the structure.

Assuming there are only 2 processors, my program is as follows:

#include <stdio.h>
#include <mpi.h>

typedef struct
{
int previ;
int prevj;
int prevrank;
double value;
}TABLE;

void Build_derived_type(TABLE *cell, MPI_Datatype *stable)
{
int block_lengths[4];
MPI_Aint displacements[4];
MPI_Aint addresses[5];
MPI_Datatype typelist[4];

typelist[0] = MPI_INT;
typelist[1] = MPI_INT;
typelist[2] = MPI_INT;
typelist[3] = MPI_DOUBLE;

block_lengths[0] = block_lengths[1] = block_lengths[2] =
block_lengths[3] = 1;

MPI_Address(cell, &addresses[0]);
MPI_Address(&(cell->previ), &addresses[1]);
MPI_Address(&(cell->prevj), &addresses[2]);
MPI_Address(&(cell->prevrank), &addresses[3]);
MPI_Address(&(cell->value), &addresses[4]);
displacements[0] = addresses[1] - addresses[0];
displacements[1] = addresses[2] - addresses[0];
displacements[2] = addresses[3] - addresses[0];
displacements[3] = addresses[4] - addresses[0];

MPI_Type_struct(4, block_lengths, displacements, typelist, stable);
MPI_Type_commit(stable);
}

int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);
int rank, size;
TABLE cell, cell1;
int i;
double j;
MPI_Datatype stable;
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);

if (rank == 0)
{
cell.previ = 1;
cell.prevj = 2;
cell.prevrank = 3;
cell.value = 4.5;
Build_derived_type(&cell, &stable);
MPI_Send(&cell, 1, stable, 1, 1, MPI_COMM_WORLD);
}
else
{
MPI_Recv(&cell1, 1, stable, 0, 1, MPI_COMM_WORLD, &status);
printf("%d %d %d %lf\n", cell1.previ, cell1.prevj,
cell1.prevrank, cell1.value);
}

MPI_Finalize();
return 0;
}

What is wrong with my program?

Thank you.

Regards,
Rayne
 
Ad

Advertisements

A

Army1987

Hi all,
I'm trying to send and receive a structure array "TABLE". I tried
using MPI_Type_struct but I got "Segmentation fault" when the
processor (P1) is supposed to receive the structure.

Assuming there are only 2 processors, my program is as follows:

#include <stdio.h>
#include <mpi.h>
This newsgroup deals with standard C. I can't see anything
obviously wrong with the code below, but without knowing what the
MPI_ stuff does, I can't help. Try asking in a newsgroup about
them.

[snip]
void Build_derived_type(TABLE *cell, MPI_Datatype *stable)
{
int block_lengths[4];
MPI_Aint displacements[4];
MPI_Aint addresses[5];
MPI_Datatype typelist[4];

typelist[0] = MPI_INT;
typelist[1] = MPI_INT;
typelist[2] = MPI_INT;
typelist[3] = MPI_DOUBLE;
What's wrong with MPI_Datatype typelist[4] = {MPI_INT, MPI_INT,
MPI_INT, MPI_DOUBLE}; ?
block_lengths[0] = block_lengths[1] = block_lengths[2] =
block_lengths[3] = 1;
What's wrong with int block_lengths[4] = {1, 1, 1, 1}; ?
MPI_Address(cell, &addresses[0]);
MPI_Address(&(cell->previ), &addresses[1]);
Note that cell and &(cell->previ) are required to be the same.
[snip]
displacements[0] = addresses[1] - addresses[0];
displacements[1] = addresses[2] - addresses[0];
displacements[2] = addresses[3] - addresses[0];
displacements[3] = addresses[4] - addresses[0]; Ever heard about for loops?
MPI_Type_struct(4, block_lengths, displacements, typelist, stable);
MPI_Type_commit(stable);
}

int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);

<ot> Is the type of the second argument of MPI_Init *actually*
a pointer to pointer to pointer to char? said:
int rank, size;
Note that in C89 you can't mix declarations and statements.
 
M

Malcolm McLean

Hi all,
I'm trying to send and receive a structure array "TABLE". I tried
using MPI_Type_struct but I got "Segmentation fault" when the
processor (P1) is supposed to receive the structure.

Assuming there are only 2 processors, my program is as follows:

#include <stdio.h>
#include <mpi.h>

typedef struct
{
int previ;
int prevj;
int prevrank;
double value;
}TABLE;

void Build_derived_type(TABLE *cell, MPI_Datatype *stable)
{
int block_lengths[4];
MPI_Aint displacements[4];
MPI_Aint addresses[5];
MPI_Datatype typelist[4];

typelist[0] = MPI_INT;
typelist[1] = MPI_INT;
typelist[2] = MPI_INT;
typelist[3] = MPI_DOUBLE;

block_lengths[0] = block_lengths[1] = block_lengths[2] =
block_lengths[3] = 1;

MPI_Address(cell, &addresses[0]);
MPI_Address(&(cell->previ), &addresses[1]);
MPI_Address(&(cell->prevj), &addresses[2]);
MPI_Address(&(cell->prevrank), &addresses[3]);
MPI_Address(&(cell->value), &addresses[4]);
displacements[0] = addresses[1] - addresses[0];
displacements[1] = addresses[2] - addresses[0];
displacements[2] = addresses[3] - addresses[0];
displacements[3] = addresses[4] - addresses[0];

MPI_Type_struct(4, block_lengths, displacements, typelist, stable);
MPI_Type_commit(stable);
}

int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);
int rank, size;
TABLE cell, cell1;
int i;
double j;
MPI_Datatype stable;
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);

if (rank == 0)
{
cell.previ = 1;
cell.prevj = 2;
cell.prevrank = 3;
cell.value = 4.5;
Build_derived_type(&cell, &stable);
MPI_Send(&cell, 1, stable, 1, 1, MPI_COMM_WORLD);
}
else
{
MPI_Recv(&cell1, 1, stable, 0, 1, MPI_COMM_WORLD, &status);
printf("%d %d %d %lf\n", cell1.previ, cell1.prevj,
cell1.prevrank, cell1.value);
}

MPI_Finalize();
return 0;
}

What is wrong with my program?
MPI is off topic here.
However I've written a tutorial, on my webiste. Almost never do you need
fancy types building up. C will let you pass stuctures without embedded
pointers as raw streams of bytes.
 
K

Keith Thompson

I'm trying to send and receive a structure array "TABLE". I tried
using MPI_Type_struct but I got "Segmentation fault" when the
processor (P1) is supposed to receive the structure.
[...]

Try comp.parallel.mpi.
 
K

Keith Thompson

Malcolm McLean said:
MPI is off topic here.
However I've written a tutorial, on my webiste. Almost never do you
need fancy types building up. C will let you pass stuctures without
embedded pointers as raw streams of bytes.

Yes, you *can* pass raw structures around, but it's likely to fail if
you pass them to another machine with different data representations.
That's why MPI (apparently) provides the routines that the OP is
using.
 
Ad

Advertisements

M

Malcolm McLean

Keith Thompson said:
Yes, you *can* pass raw structures around, but it's likely to fail if
you pass them to another machine with different data representations.
That's why MPI (apparently) provides the routines that the OP is
using.
MPI is not topical here, but you are probably right that high level types
are permitted in messages as a hook for extensions.
However I suspect that the OP doesn't realise that, for most purposes, the
raw representation will be a lot simpler and perfectly adequate. The reasons
are mainly to with C, not MPI.
 
Ad

Advertisements


Top