Hello,

I am wondering whether or not the MPI_Accumulate subroutine implemented in OpenMPI v1.6.2  is capable to operate on derived datatypes? I wrote a very simple test program for accumulating data from several process on master. The program works properly only with predefined datatypes. In the case of  a derived datatype generated via MPI_Type_contiguous/MPI_Type_
vector subroutine, the results are incorrect:

%mpicc accum.derived.c  -o accum.predifined
%mpicc -D_DERIVED_ accum.derived.c  -o accum.derived

%mpirun -n 2 accum.predifined
tnum_acc[0] =  2.0 (expected: Nprocs =  2.0)
tnum_acc[1] =  2.0 (expected: Nprocs =  2.0)

%mpirun -n 2 accum.derived
tnum_acc[0] =  1.0 (expected: Nprocs =  2.0)
tnum_acc[1] =  1.0 (expected: Nprocs =  2.0)


The point is that within mvapich2-1.8-r5668 and mpich2-1.5 the results are always correct, regardless of datatypes used.

Any comments are highly appreciated!


With best regards,
Victor.

The test program is listed below:

/* Simple test for MPI_Accumulate && derived datatypes */
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <math.h>

#define NEL 10
#define NAC  2

int main(int argc, char **argv) {
    int          i, j, rank, nranks;
    double      *win_buf, *src_buf;
    MPI_Win      buf_win;
    MPI_Aint     nelp;
    MPI_Datatype dtype;
   
    MPI_Init(&argc, &argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &nranks);

    nelp=(rank==0)?(NEL):0;

    win_buf=(double *) calloc(nelp,sizeof(double));
    src_buf=(double *) calloc(NAC,sizeof(double));

    for(i=0;i<NAC;i++)  src_buf[i]=1;

    MPI_Win_create(win_buf, nelp, sizeof(double), MPI_INFO_NULL, MPI_COMM_WORLD, &buf_win);
/* 
    MPI_Type_vector(NAC,1,1,MPI_DOUBLE,&dtype);
*/
#ifdef _DERIVED_
    MPI_Type_contiguous(NAC,MPI_DOUBLE,&dtype);
    MPI_Type_commit(&dtype);
#endif

    MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 0, 0, buf_win);

#ifdef _DERIVED_   
    MPI_Accumulate(src_buf, 1, dtype, 0, 0, 1, dtype, MPI_SUM, buf_win);
#else   
    MPI_Accumulate(src_buf, NAC, MPI_DOUBLE, 0, 0, NAC, MPI_DOUBLE, MPI_SUM, buf_win);
#endif   

    MPI_Win_unlock(0, buf_win);
    MPI_Barrier(MPI_COMM_WORLD);

    if(rank==0) {
      for(j=0;j<NAC;j++) printf("tnum_acc[%d] =%5.1lf (expected: Nprocs =%5.1lf)\n",j,win_buf[j],(double) nranks);
    }


    MPI_Win_free(&buf_win);
    MPI_Finalize();

    exit(0);
}