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/
>
|