#include <mpi.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
  struct {int u,k;} local,global;
  MPI_Datatype MY_2INT;
  MPI_Win win;
  int rank;

  MPI_Init(&argc,&argv);
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
  MPI_Type_contiguous(2,MPI_INT,&MY_2INT);
  MPI_Type_commit(&MY_2INT);

  local.u = 10+rank;
  local.k = 100+rank;

  /* Works with MPI_2INT. No error with MY_2INT, but incorrect results.
   */
  global.u = 0;
  global.k = 0;
  MPI_Win_create(&global,1,sizeof(global),MPI_INFO_NULL,MPI_COMM_WORLD,&win);
  MPI_Win_fence(0,win);
  MPI_Accumulate(&local,1,MY_2INT,0,0,1,MY_2INT,MPI_MAXLOC,win);
  MPI_Win_fence(0,win);
  MPI_Win_free(&win);
  if (!rank) printf("MPI_Accumulate: u=%d k=%d\n",global.u,global.k); /* u=0 k=0 */

  /* Works with MPI_2INT. (Desirable) error with MY_2INT.
   *
   * Fatal error in PMPI_Reduce: Invalid MPI_Op, error stack:
   * PMPI_Reduce(1217)...........: MPI_Reduce(sbuf=0x7fff3e39fa50, rbuf=0x7fff3e39fa40, count=1, dtype=USER<contig>, MPI_MAXLOC, root=0, MPI_COMM_WORLD) failed
   * MPIR_MAXLOC_check_dtype(151): MPI_Op MPI_MAXLOC operation not defined for this datatype
   */
  global.u = 0;
  global.k = 0;
  MPI_Reduce(&local,&global,1,MY_2INT,MPI_MAXLOC,0,MPI_COMM_WORLD);
  if (!rank) printf("MPI_Accumulate: u=%d k=%d\n",global.u,global.k); /* u=11 k=101 */

  MPI_Type_free(&MY_2INT);
  MPI_Finalize();
  return 0;
}
