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 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
#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);
}
|