#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