Open MPI logo

Open MPI User's Mailing List Archives

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

Subject: [OMPI users] Similar question about MPI_Create_type
From: Prentice Bisbal (prentice_at_[hidden])
Date: 2010-02-08 13:54:10


Hello, again MPU Users:

This question is similar to my earlier one about MPI_Pack/Unpack,

I'm trying to send the following structure, which has a dynamically
allocated array in it, as a MPI derived type using MPI_Create_type_struct():

typedef struct{
   int index;
   int* coords;
}point;

I would think that this can't be done since the coords array will not be
  contiguous in memory with the rest of the structure, so calculating
the displacements between point.index and point.coords will be
meaningless. However, I'm pretty sure that Pacheco's book implies that
this can be done (I'd list the exact page(s), but I don't have that book
handy).

Am I wrong or right?

Below my signature is a the code I'm using to test this, which fails as
I'd expect. Is my thinking right, or is my program wrong? When I run the
program I get this error:

 *** An error occurred in MPI_Address
 *** on communicator MPI_COMM_WORLD
 *** MPI_ERR_ARG: invalid argument of some other kind
 *** MPI_ERRORS_ARE_FATAL (goodbye)
mpirun noticed that job rank 0 with PID 28286 on node juno.sns.ias.edu
exited on signal 15 (Terminated).

-- 
Prentice
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int rank;
MPI_Status status;
int size;
int tag;
typedef struct{
  int index;
  int* coords;
}point;
int block_lengths[2];
MPI_Datatype type_list[2];
MPI_Aint displacements[2];
MPI_Aint start_address;
MPI_Aint address;
MPI_Datatype derived_point;
point a_point, b_point;
int main(int argc, char* argv[])
{
  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  if (rank == 0) {
    a_point.index = 1;
    a_point.coords = malloc(3 * sizeof(int));
    a_point.coords[0] = 3;
    a_point.coords[1] = 6;
    a_point.coords[2] = 9;
  }
  block_lengths[0] = 1;
  block_lengths[1] = 3;
  type_list[0] = MPI_INT;
  type_list[1] = MPI_INT;
  displacements[0] = 0;
  MPI_Address(&a_point.index, &start_address);
  MPI_Address(a_point.coords, &address);
  displacements[1] = address - start_address;
  MPI_Type_create_struct(2, block_lengths, displacements, type_list,
&derived_point);
  MPI_Type_commit(&derived_point);
  if (rank == 0) {
    MPI_Send(&a_point, 1, derived_point, 1, 0, MPI_COMM_WORLD);
  }
  if (rank == 1) {
    b_point.coords = malloc(3 *sizeof(int));
    MPI_Recv(&b_point, 1, derived_point, 0, 0, MPI_COMM_WORLD, &status);
    printf("b_point.index = %i\n", b_point.index);
    printf("b_point.coords:(%i, %i, %i)\n", b_point.coords[0],
b_point.coords[1], b_point.coords[2]);
  }
  MPI_Finalize();
  exit(0);
}