Open MPI logo

Open MPI User's Mailing List Archives

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

Subject: [OMPI users] Is MPI_Accumulate compatible with an user-defined derived datatype?
From: Victor Vysotskiy (Victor.Vysotskiy_at_[hidden])
Date: 2012-10-10 04:25:18


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);
}