List Info

Thread: LAM: MPI_Alltoallv and a strided data type




LAM: MPI_Alltoallv and a strided data type
user name
2006-08-31 23:49:42
Hi Brain,

Thanks for your reply. I agree that I was very brief in my
question. I
will elaborate it more now.  Please see the code at the end
of the
e-mail. The code is written in C.

This program is a very simple program. It runs only for 2
processors.
I tries to send an integer  array of size 4 to every other
processors
(ie. to itself and to the other processor) using
MPI_AlltoAllv. The
program takes as its input a "stride". If stride
= 1, the processors
send and receive the entire array. If stride = 2, the
processors send
and receive only 2 elements (in strides of 2 of the original
array).
I build the a new data type using MPI_Type_vector with the
given
stride and number of elements. I also calculate the send and
recv
offset.

The program works fine for stride =1, but for stride=2 I get
a wrong
answer.  I am not sure what mistake I make.

The problem I found is that MPI_Type_extent for the datatype
I build
is 12. But, the send and receive buffers for each processor
are in the
offset of 16 (4 * sizeof(int)).

  What  should I to do to make the program correctly? Is
there a way
for me to change the extent of the datatype to 16?

#include <iostream>
#include "mpi.h"

using namespace std;

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

  int rank;
  int nprocs;
  MPI_Comm_rank (MPI_COMM_WORLD, &rank);
  MPI_Comm_size (MPI_COMM_WORLD, &nprocs);
  assert (nprocs == 2);

  assert (argc == 2);
  int stride = atoi (argv[1]);
  assert (stride == 1 || stride == 2);


  int size = 4; //size of the array

  int *dummy = new int[size*nprocs]; //allocate the buffer
contiguously
  int* sbuf0 = &(dummy[0]); //to processor 0
  int* sbuf1 = &(dummy[1*size]); //to processor 1

  int *dummy1 = new int[size*nprocs]; //allocate the buffer
contiguously
  int* rbuf0 =  &(dummy1[0]); //from processor 0
  int* rbuf1 =  &(dummy1[1*size]); //from processor 1

  int sdispls[2];
  int rdispls[2];
  int count[2];

  for (int i = 0; i < size; i++)
    {
      sbuf0[i] = i * (rank+1);
      sbuf1[i] = i * (rank+1);

      rbuf0[i] = 0;
      rbuf1[i] = 0;
    }

  MPI_Datatype type;
  MPI_Type_vector ((size / stride), 1, stride, MPI_INT,
&type);	
  MPI_Type_commit (&type);

  for (int i = 0; i < nprocs; i++)
    {
      sdispls[i] = i;
      rdispls[i] = i;
    }

  for (int i = 0; i < nprocs; i++)
    count[i] = 1;

  MPI_Alltoallv (sbuf0, count, sdispls, type,
		 rbuf0, count, rdispls, type,
		 MPI_COMM_WORLD);

  cout << rank << ": " ;
  for (int i = 0; i < size; i++)
    {
      cout << rbuf0[i] << " " ;
    }

  cout << endl;
  cout << rank << ": " ;
  for (int i = 0; i < size; i++)
    cout  << rbuf1[i] << " ";
  cout << endl;

  MPI_Finalize ();
  return 0;
}


On 8/31/06, Brian Barrett <brbarretlam-mpi.org> wrote:
> On Wed, 2006-08-30 at 15:09 -0500, Ganesh Bikshandi
wrote:
> > Hi All,
> >
> > I have a problem with MPI_Alltoallv and strided
user defined type. I
> > get segmentation fault. I guess that I have to
adjust my offset
> > calculation. But don't know what and how. I tried
different things,
> > but still get the seg fault. Somebody please help.
>
> You really don't provide enough information for us to
help you.  The
> only thing worth clarifying about Alltoallv is that the
displacements
> are the number of elements of type sendtype (or receive
type, depending
> on the displacements you are talking about), not the
number of bytes.
> This is the cause of most of the confusion with
Alltoallv.
>
> Brian
>
>
> _______________________________________________
> This list is archived at http://www.l
am-mpi.org/MailArchives/lam/
>
_______________________________________________
This list is archived at http://www.l
am-mpi.org/MailArchives/lam/
[1]

about | contact  Other archives ( Real Estate discussion Medical topics )