#include "Bdef.h"
/* This file from mpiblacs_patch01 */

#if (INTFACE == C_CALL)
void Cblacs_gridmap(int *ConTxt, int *usermap, int ldup, int nprow0, int npcol0)
#else
F_VOID_FUNC blacs_gridmap_(int *ConTxt, int *usermap, int *ldup, int *nprow0,
                           int *npcol0)
#endif
{
   void Cblacs_pinfo(int *, int *);
   void Cblacs_get(int, int, int *);
#ifdef UseF77Mpi
   int BI_TransUserComm(MPI_Comm, int, int *);
#else
   MPI_Comm BI_TransUserComm(int, int, int *);
#endif
   MPI_Comm Cblacs2sys_handle(int);

   int info, i, j, Iam, *iptr;
   int myrow, mycol, nprow, npcol, Ng;
   BLACSCONTEXT *ctxt, **tCTxts;
   BI_MPI_Comm comm, tcomm;
   BI_MPI_Group grp, tgrp;
#if (BI_TransComm == BONEHEAD)
#ifdef UseF77Mpi
   MPI_Comm Ucomm, Ccomm=MPI_COMM_NULL;
   MPI_Group Cgrp, Cgrp2;
#else
   int Fgrp, Fgrp2, *Fcomm=NULL;
#endif
#endif
   extern BLACSCONTEXT **BI_MyContxts;
   extern BLACBUFF BI_AuxBuff;
   extern int BI_Iam, BI_Np, BI_MaxNCtxt;
   extern BI_MPI_Status *BI_Stats;

/*
 * If first call to blacs_gridmap
 */
   if (BI_MaxNCtxt == 0)
   {
      Cblacs_pinfo(&BI_Iam, &BI_Np);
      BI_AuxBuff.nAops = 0;
      BI_AuxBuff.Aops = (BI_MPI_Request*)malloc(BI_Np*sizeof(*BI_AuxBuff.Aops));
      BI_Stats = (BI_MPI_Status *) malloc(BI_Np * BI_MPI_STATUS_SIZE *
                                          sizeof(BI_MPI_Status));
#ifndef UseF77Mpi
      BI_MPI_Type_contiguous(2, BI_MPI_FLOAT, &BI_MPI_COMPLEX, info);
      BI_MPI_Type_commit(&BI_MPI_COMPLEX, info);
      BI_MPI_Type_contiguous(2, BI_MPI_DOUBLE, &BI_MPI_DOUBLE_COMPLEX, info);
      BI_MPI_Type_commit(&BI_MPI_DOUBLE_COMPLEX, info);
#endif
   }

   nprow = Mpval(nprow0);
   npcol = Mpval(npcol0);
   Ng = nprow * npcol;
   if ( (Ng > BI_Np) || (nprow < 1) || (npcol < 1) )
      BI_BlacsErr(-1, -1, "BLACS_GRIDINIT/BLACS_GRIDMAP",
                  "Illegal grid (%d x %d), #procs=%d", nprow, npcol, BI_Np);
/*
 * Form MPI communicator for scope = 'all'
 */
   if (Ng > 2) i = Ng;
   else i = 2;
   iptr = (int *) malloc(i*sizeof(int));
   for (j=0; j < npcol; j++)
   {
      for (i=0; i < nprow; i++) iptr[i*npcol+j] = usermap[j*Mpval(ldup)+i];
   }
#if (INTFACE == C_CALL)

#ifdef UseF77Mpi
   comm = BI_TransUserComm(Cblacs2sys_handle(*ConTxt), Ng, iptr);
/*
 * If we globally blocked to translate the User's communicator from C to F77,
 * go ahead and translate the new context back to F77 in case he calls blacs_get
 */
#if (BI_TransComm == BONEHEAD)
   Ucomm = Cblacs2sys_handle(*ConTxt);
   MPI_Comm_group(Ucomm, &Cgrp);            /* find input comm's group */
   MPI_Group_incl(Cgrp, Ng, iptr, &Cgrp2);  /* form new group */
   MPI_Comm_create(Ucomm, Cgrp2, &Ccomm);   /* create new comm */
   MPI_Group_free(&Cgrp);
   MPI_Group_free(&Cgrp2);
#endif
#else
#define BI_FormComm
   tcomm = Cblacs2sys_handle(*ConTxt);
#endif

#else  /* gridmap called from f77 */

#ifdef UseF77Mpi
#define BI_FormComm
   tcomm = *ConTxt;
#else
   comm = BI_TransUserComm(*ConTxt, Ng, iptr);
#if (BI_TransComm == BONEHEAD)
   Fcomm = (int *) malloc(sizeof(int));
   mpi_comm_group_(ConTxt, &Fgrp, &info);
   mpi_group_incl_(&Fgrp, &Ng, iptr, &Fgrp2, &info);
   mpi_comm_create_(ConTxt, &Fgrp2, Fcomm, &info);
   mpi_group_free_(&Fgrp2, &info);
   mpi_group_free_(&Fgrp, &info);
#endif
#endif

#endif

#ifdef BI_FormComm
   BI_MPI_Comm_group(tcomm, &grp, info);           /* find input comm's group */
   BI_MPI_Group_incl(grp, Ng, iptr, &tgrp, info);  /* form new group */
   BI_MPI_Comm_create(tcomm, tgrp, &comm, info);   /* create new comm */
   BI_MPI_Group_free(&tgrp, info);
   BI_MPI_Group_free(&grp, info);
#endif
/*
 * Weed out callers who are not participating in present grid
 */
   if (comm == BI_MPI_COMM_NULL)
   {
      *ConTxt = NOTINCONTEXT;
      free(iptr);
      return;
   }

/*
 * ==================================================
 * Get new context and add it to my array of contexts
 * ==================================================
 */
   ctxt = (BLACSCONTEXT *) malloc(sizeof(BLACSCONTEXT));
/*
 * Find free slot in my context array
 */
   for (i=0; i < BI_MaxNCtxt; i++) if (BI_MyContxts[i] == NULL) break;
/*
 * Get bigger context pointer array, if needed
 */
   if (i == BI_MaxNCtxt)
   {
      j = BI_MaxNCtxt + MAXNCTXT;
      tCTxts = (BLACSCONTEXT **) malloc(j * sizeof(*tCTxts));
      for (i=0; i < BI_MaxNCtxt; i++) tCTxts[i] = BI_MyContxts[i];
      BI_MaxNCtxt = j;
      for(j=i; j < BI_MaxNCtxt; j++) tCTxts[j] = NULL;
      if (BI_MyContxts) free(BI_MyContxts);
      BI_MyContxts = tCTxts;
   }
   BI_MyContxts[i] = ctxt;
   *ConTxt = i;

#if (BI_TransComm == BONEHEAD)
#ifdef UseF77Mpi
   ctxt->C_comm = Ccomm;
#else
   ctxt->F77_comm = Fcomm;
#endif
#endif
   ctxt->ascp.comm = comm;
   BI_MPI_Comm_dup(comm, &ctxt->pscp.comm, info); /* copy acomm for pcomm */
   BI_MPI_Comm_rank(comm, &Iam, info);            /* find my rank in new comm */
   myrow = Iam / npcol;
   mycol = Iam % npcol;

/*
 * Form MPI communicators for scope = 'row'
 */
   BI_MPI_Comm_split(comm, myrow, mycol, &ctxt->rscp.comm, info);
/*
 * Form MPI communicators for scope = 'Column'
 */
   BI_MPI_Comm_split(comm, mycol, myrow, &ctxt->cscp.comm, info);

   ctxt->rscp.Np = npcol;
   ctxt->rscp.Iam = mycol;
   ctxt->cscp.Np = nprow;
   ctxt->cscp.Iam = myrow;
   ctxt->pscp.Np = ctxt->ascp.Np = Ng;
   ctxt->pscp.Iam = ctxt->ascp.Iam = Iam;
   ctxt->Nr_bs = ctxt->Nr_co = 1;
   ctxt->Nb_bs = ctxt->Nb_co = 2;
   ctxt->TopsRepeat = ctxt->TopsCohrnt = 0;

/*
 * ===========================
 * Set up the message id stuff
 * ===========================
 */
   Cblacs_get(-1, 1, iptr);
   ctxt->pscp.MinId = ctxt->rscp.MinId = ctxt->cscp.MinId =
   ctxt->ascp.MinId = ctxt->pscp.ScpId = ctxt->rscp.ScpId =
   ctxt->cscp.ScpId = ctxt->ascp.ScpId = iptr[0];
   ctxt->pscp.MaxId = ctxt->rscp.MaxId = ctxt->cscp.MaxId =
   ctxt->ascp.MaxId = iptr[1];
   free(iptr);

}


syntax highlighted by Code2HTML, v. 0.9.1