#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>


int main(int argc, char *argv[])
{
  int rank; 
  int shared_rank, shared_size ;
  MPI_Comm shared_comm;
  void * mem;
  MPI_Win win;
  MPI_Info info;
  MPI_Aint memsize;
  int disp_unit;
  int k;
  MPI_Init(&argc, &argv);
  MPI_Info_create(&info);
  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
  long unsigned int window_size=2147483648;

  /* creating communicator for shared communication using MPI_COMM_TYPE_SHARED */
  MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, &shared_comm);
  MPI_Comm_rank(shared_comm, &shared_rank);
  MPI_Comm_size(shared_comm, &shared_size);
  MPI_Win_allocate_shared(window_size, sizeof(double), info, shared_comm, &mem, &win);
  /* print setup only once */
  if (rank == 0 )
  {
    printf("Created shared_communicator of size %d\n", shared_size);
    int * model, flag;
    MPI_Win_get_attr( win, MPI_WIN_MODEL, &model, &flag);
    printf("Memory type: (MPI_WIN_SEPARATE %i;MPI_WIN_UNIFIED %i) MPI_WIN_MODEL: %i\n",MPI_WIN_SEPARATE,MPI_WIN_UNIFIED,*model);
  }
  /* print rank in MPI_COMM_WORLD and shared_comm */
  printf("rank %i, shared_rank %i\n",rank, shared_rank);

  /* both work*/ 
    MPI_Win_fence(0,win);

  MPI_Win_free(&win);
  MPI_Comm_free(&shared_comm);
  MPI_Finalize();

  return 0;
}
