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

void printhello(int rank)
{
  MPI_Barrier(MPI_COMM_WORLD);
  if(rank == 0){
    printf("Hello ");
    fflush(stdout);
  }
  MPI_Barrier(MPI_COMM_WORLD);
  if(rank == 1){
    printf("world!\n");
    fflush(stdout);
  }
}

int end()
{
  MPI_Finalize();
  return 0;
}

int main(int argc, char* argv[])
{
  int rank;
  MPI_Comm comm = MPI_COMM_WORLD;

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  int iam, nprocs;

  Cblacs_pinfo(&iam, &nprocs);
  int context;
  context = Csys2blacs_handle(comm);
  
  char order;
  int nprow = 4, npcol = 2;

  Cblacs_gridinit(&context, &order, nprow, npcol);
  fflush(stdout);

  MPI_Group worldgroup, subgroup;
  MPI_Comm subcomm;

  MPI_Comm_group(comm, &worldgroup);

  // It works with this criterion
  //int criterion = (rank < 4);
  //int ranks1[4] = {0, 1, 2, 3};
  //int ranks2[4] = {4, 5, 6, 7};
  

  // It won't work with this criterion
  int criterion = (rank % 2 == 0);
  int ranks1[4] = {0, 2, 4, 6};
  int ranks2[4] = {1, 3, 5, 7};

  if(criterion){
    MPI_Group_incl(worldgroup, 4, ranks1, &subgroup);
  } else {
    MPI_Group_incl(worldgroup, 4, ranks2, &subgroup);
  }

  MPI_Barrier(comm);
  MPI_Comm_create(comm, subgroup, &subcomm);
  fflush(stdout);
  
  int subcontext;
  char order2;
  int nprow2 = 2, npcol2 = 2;
  fflush(stdout);

  if(criterion){
    // cannot create blacsgrid with non-contiguous ranks
    subcontext = Csys2blacs_handle(subcomm);
    printf("rank=%d, subcontext=%d\n", rank, subcontext);
    fflush(stdout);
    Cblacs_gridinit(&subcontext, &order2, nprow2, npcol2);
  }
  MPI_Barrier(comm);




  printhello(rank);

  MPI_Finalize();
  return 0;
}

