1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
#include "Bdef.h"
#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 *);
MPI_Comm Cblacs2sys_handle(Int BlacsCtxt);
MPI_Comm BI_TransUserComm(Int, Int, Int *);
MpiInt Iam;
Int info, i, j, *iptr;
Int myrow, mycol, nprow, npcol, Ng;
BLACSCONTEXT *ctxt, **tCTxts;
MPI_Comm comm, tcomm;
MPI_Group grp, tgrp;
extern BLACSCONTEXT **BI_MyContxts;
extern BLACBUFF BI_AuxBuff;
extern Int BI_Iam, BI_Np, BI_MaxNCtxt;
extern 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 = (MPI_Request*)malloc(BI_Np*sizeof(*BI_AuxBuff.Aops));
BI_Stats = (MPI_Status *) malloc(BI_Np * sizeof(MPI_Status));
}
nprow = Mpval(nprow0);
npcol = Mpval(npcol0);
Ng = nprow * npcol;
if ( (Ng > BI_Np) || (nprow < 1) || (npcol < 1) )
BI_BlacsErr((Int)-1, (Int)-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)
MpiInt *miptr = (MpiInt *) malloc(Ng*sizeof(MpiInt));
for (j=0; j < Ng; j++) miptr[j] = iptr[j];
tcomm = Cblacs2sys_handle(*ConTxt);
MPI_Comm_group(tcomm, &grp); /* find input comm's group */
MPI_Group_incl(grp, Ng, miptr, &tgrp); /* form new group */
MPI_Comm_create(tcomm, tgrp, &comm); /* create new comm */
MPI_Group_free(&tgrp);
MPI_Group_free(&grp);
free(miptr);
#else /* gridmap called from fortran */
comm = BI_TransUserComm(*ConTxt, Ng, iptr);
#endif
/*
* Weed out callers who are not participating in present grid
*/
if (comm == 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;
ctxt->ascp.comm = comm;
MPI_Comm_dup(comm, &ctxt->pscp.comm); /* copy acomm for pcomm */
MPI_Comm_rank(comm, &Iam); /* find my rank in new comm */
myrow = Iam / npcol;
mycol = Iam % npcol;
/*
* Form MPI communicators for scope = 'row'
*/
MPI_Comm_split(comm, myrow, mycol, &ctxt->rscp.comm);
/*
* Form MPI communicators for scope = 'Column'
*/
MPI_Comm_split(comm, mycol, myrow, &ctxt->cscp.comm);
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);
}
|