File: blacs_gridmap_.c

package info (click to toggle)
blacs-mpi 1.1-28.2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 2,320 kB
  • ctags: 2,031
  • sloc: fortran: 14,968; ansic: 12,353; makefile: 531; sh: 1
file content (200 lines) | stat: -rw-r--r-- 5,870 bytes parent folder | download | duplicates (9)
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);

}