LAM/MPI logo

LAM/MPI General User's Mailing List Archives

  |   Home   |   Download   |   Documentation   |   FAQ   |   all just in this list

From: Ganesh Bikshandi (ganeshb_at_[hidden])
Date: 2006-08-31 19: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 <brbarret_at_[hidden]> 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.lam-mpi.org/MailArchives/lam/
>