SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
igamn2d_.c
Go to the documentation of this file.
1#include "Bdef.h"
2
3#if (INTFACE == C_CALL)
4void Cigamn2d(Int ConTxt, char *scope, char *top, Int m, Int n, Int *A,
5 Int lda, Int *rA, Int *cA, Int ldia, Int rdest, Int cdest)
6#else
7F_VOID_FUNC igamn2d_(Int *ConTxt, F_CHAR scope, F_CHAR top, Int *m, Int *n,
8 Int *A, Int *lda, Int *rA, Int *cA, Int *ldia,
9 Int *rdest, Int *cdest)
10#endif
11/*
12 * -- V1.1 BLACS routine --
13 * University of Tennessee, May 1, 1996
14 * Written by Clint Whaley.
15 *
16 * Purpose
17 * =======
18 * Combine amn operation for integer rectangular matrices.
19 *
20 * Arguments
21 * =========
22 *
23 * ConTxt (input) Ptr to Int
24 * Index into MyConTxts00 (my contexts array).
25 *
26 * SCOPE (input) Ptr to char
27 * Limit the scope of the operation.
28 * = 'R' : Operation is performed by a process row.
29 * = 'C' : Operation is performed by a process column.
30 * = 'A' : Operation is performed by all processes in grid.
31 *
32 * TOP (input) Ptr to char
33 * Controls fashion in which messages flow within the operation.
34 *
35 * M (input) Ptr to Int
36 * The number of rows of the matrix A. M >= 0.
37 *
38 * N (input) Ptr to Int
39 * The number of columns of the matrix A. N >= 0.
40 *
41 * A (output) Ptr to integer two dimensional array
42 * The m by n matrix A. Fortran77 (column-major) storage
43 * assumed.
44 *
45 * LDA (input) Ptr to Int
46 * The leading dimension of the array A. LDA >= M.
47 *
48 * RA (output) Integer Array, dimension (LDIA, N)
49 * Contains process row that the amn of each element
50 * of A was found on: i.e., rA(1,2) contains the process
51 * row that the amn of A(1,2) was found on.
52 * Values are left on process {rdest, cdest} only, others
53 * may be modified, but not left with interesting data.
54 * If rdest == -1, then result is left on all processes in scope.
55 * If LDIA == -1, this array is not accessed, and need not exist.
56 *
57 * CA (output) Integer Array, dimension (LDIA, N)
58 * Contains process column that the amn of each element
59 * of A was found on: i.e., cA(1,2) contains the process
60 * column that the max/min of A(1,2) was found on.
61 * Values are left on process {rdest, cdest} only, others
62 * may be modified, but not left with interesting data.
63 * If rdest == -1, then result is left on all processes in scope.
64 * If LDIA == -1, this array is not accessed, and need not exist.
65 *
66 * LDIA (input) Ptr to Int
67 * If (LDIA == -1), then the arrays RA and CA are not accessed.
68 * ELSE leading dimension of the arrays RA and CA. LDIA >= M.
69 *
70 * RDEST (input) Ptr to Int
71 * The process row of the destination of the amn.
72 * If rdest == -1, then result is left on all processes in scope.
73 *
74 * CDEST (input) Ptr to Int
75 * The process column of the destination of the amn.
76 * If rdest == -1, then CDEST ignored.
77 *
78 * ------------------------------------------------------------------------
79 */
80{
81 void BI_ArgCheck(Int, Int, char *, char, char, char, Int, Int, Int, Int,
82 Int *, Int *);
86 MPI_Datatype BI_GetMpiGeType(BLACSCONTEXT *, Int, Int, Int,
87 MPI_Datatype, Int *);
88 BLACBUFF *BI_Pack(BLACSCONTEXT *, BVOID *, BLACBUFF *, MPI_Datatype);
89 MPI_Datatype BI_GetMpiGeType(BLACSCONTEXT *, Int, Int, Int,
90 MPI_Datatype, Int *);
91 void BI_Unpack(BLACSCONTEXT *, BVOID *, BLACBUFF *, MPI_Datatype);
93 Int, Int);
95 Int, Int);
97 void BI_ivvamn(Int, char *, char *);
98 void BI_ivvamn2(Int, char *, char *);
99 void BI_iMPI_amn(void *, void *, MpiInt *, MPI_Datatype *);
100 void BI_iMPI_amn2(void *, void *, MpiInt *, MPI_Datatype *);
101/*
102 * Variable Declarations
103 */
104 VVFUNPTR vvop;
105 BLACBUFF *bp, *bp2;
106 BLACSCONTEXT *ctxt;
107 char ttop, tscope;
108 Int i, j, N, dest, idist, length, tlda, tldia, trdest, ierr;
109 MpiInt len[2];
110 MPI_Aint disp[2];
111 MPI_Datatype dtypes[2];
112 MPI_Op BlacComb;
113 MPI_Datatype IntTyp, MyType;
114 BI_DistType *dist, mydist;
115 extern BLACBUFF *BI_ActiveQ;
116 extern BLACBUFF BI_AuxBuff;
117
118 MPI_Type_match_size(MPI_TYPECLASS_INTEGER, sizeof(Int), &IntTyp);
119
120 MGetConTxt(Mpval(ConTxt), ctxt);
121 ttop = F2C_CharTrans(top);
122 ttop = Mlowcase(ttop);
123 tscope = F2C_CharTrans(scope);
124 tscope = Mlowcase(tscope);
125/*
126 * If the user has set the default combine topology, use it instead of
127 * BLACS default
128 */
129#ifdef DefCombTop
130 if (ttop == ' ') ttop = DefCombTop;
131#endif
132 if (Mpval(cdest) == -1) trdest = -1;
133 else trdest = Mpval(rdest);
134#if (BlacsDebugLvl > 0)
135 BI_ArgCheck(Mpval(ConTxt), RT_COMB, __FILE__, tscope, 'u', 'u', Mpval(m),
136 Mpval(n), Mpval(lda), 1, &trdest, Mpaddress(cdest));
137 if (Mpval(ldia) < Mpval(m))
138 {
139 if (Mpval(ldia) != -1)
140 BI_BlacsWarn(Mpval(ConTxt), __LINE__, __FILE__,
141 "LDIA too small (LDIA=%d, but M=%d)", Mpval(ldia),
142 Mpval(m));
143 }
144#endif
145 if (Mpval(lda) >= Mpval(m)) tlda = Mpval(lda);
146 else tlda = Mpval(m);
147 if (Mpval(ldia) < Mpval(m)) tldia = Mpval(m);
148 else tldia = Mpval(ldia);
149 switch(tscope)
150 {
151 case 'r':
152 ctxt->scp = &ctxt->rscp;
153 if (trdest == -1) dest = -1;
154 else dest = Mpval(cdest);
155 break;
156 case 'c':
157 ctxt->scp = &ctxt->cscp;
158 dest = trdest;
159 break;
160 case 'a':
161 ctxt->scp = &ctxt->ascp;
162 if (trdest == -1) dest = -1;
163 else dest = Mvkpnum(ctxt, trdest, Mpval(cdest));
164 break;
165 default:
166 BI_BlacsErr(Mpval(ConTxt), __LINE__, __FILE__, "Unknown scope '%c'",
167 tscope);
168 }
169
170
171/*
172 * It's not defined how MPI reacts to 0 element reductions, so use BLACS 1-tree
173 * topology if we've got one
174 */
175 if (ttop == ' ') if ( (Mpval(m) < 1) || (Mpval(n) < 1) ) ttop = '1';
176 N = Mpval(m) * Mpval(n);
177/*
178 * If process who has amn is to be communicated, must set up distance
179 * vector after value vector
180 */
181 if (Mpval(ldia) != -1)
182 {
183 vvop = BI_ivvamn;
184 length = N * sizeof(Int);
185 i = length % sizeof(BI_DistType); /* ensure dist vec aligned correctly */
186 if (i) length += sizeof(BI_DistType) - i;
187 idist = length;
188 length += N * sizeof(BI_DistType);
189/*
190 * For performance, insist second buffer is at least 8-byte aligned
191 */
192 j = 8;
193 if (sizeof(Int) > j) j = sizeof(Int);
194 i = length % j;
195 if (i) length += j - i;
196 i = 2 * length;
197
198 bp = BI_GetBuff(i);
199 bp2 = &BI_AuxBuff;
200 bp2->Buff = &bp->Buff[length];
201 BI_imvcopy(Mpval(m), Mpval(n), A, tlda, bp->Buff);
202/*
203 * Fill in distance vector
204 */
205 if (dest == -1) mydist = ctxt->scp->Iam;
206 else mydist = (ctxt->scp->Np + ctxt->scp->Iam - dest) % ctxt->scp->Np;
207 dist = (BI_DistType *) &bp->Buff[idist];
208 for (i=0; i < N; i++) dist[i] = mydist;
209
210/*
211 * Create the MPI datatype holding both user's buffer and distance vector
212 */
213 len[0] = len[1] = N;
214 disp[0] = 0;
215 disp[1] = idist;
216 dtypes[0] = IntTyp;
217 dtypes[1] = BI_MpiDistType;
218#ifdef ZeroByteTypeBug
219 if (N > 0)
220 {
221#endif
222 i = 2;
223 ierr=MPI_Type_create_struct(i, len, disp, dtypes, &MyType);
224 ierr=MPI_Type_commit(&MyType);
225 bp->N = bp2->N = 1;
226 bp->dtype = bp2->dtype = MyType;
227#ifdef ZeroByteTypeBug
228 }
229 else
230 {
231 bp->N = bp2->N = 0;
232 bp->dtype = bp2->dtype = IntTyp;
233 }
234#endif
235 }
236 else
237 {
238 vvop = BI_ivvamn2;
239 length = N * sizeof(Int);
240/*
241 * If A is contiguous, we can use it as one of our buffers
242 */
243 if ( (Mpval(m) == tlda) || (Mpval(n) == 1) )
244 {
245 bp = &BI_AuxBuff;
246 bp->Buff = (char *) A;
247 bp2 = BI_GetBuff(length);
248 }
249 else
250 {
251 bp = BI_GetBuff(length*2);
252 bp2 = &BI_AuxBuff;
253 bp2->Buff = &bp->Buff[length];
254 BI_imvcopy(Mpval(m), Mpval(n), A, tlda, bp->Buff);
255 }
256 bp->N = bp2->N = N;
257 bp->dtype = bp2->dtype = IntTyp;
258 }
259
260 switch(ttop)
261 {
262 case ' ': /* use MPI's reduction by default */
263 i = 1;
264 if (Mpval(ldia) == -1)
265 {
266 ierr=MPI_Op_create(BI_iMPI_amn2, i, &BlacComb);
267 }
268 else
269 {
270 ierr=MPI_Op_create(BI_iMPI_amn, i, &BlacComb);
271 BI_AuxBuff.Len = N; /* set this up for the MPI OP wrappers */
272 }
273
274 if (trdest != -1)
275 {
276 ierr=MPI_Reduce(bp->Buff, bp2->Buff, bp->N, bp->dtype, BlacComb, dest,
277 ctxt->scp->comm);
278 if (ctxt->scp->Iam == dest)
279 {
280 BI_ivmcopy(Mpval(m), Mpval(n), A, tlda, bp2->Buff);
281 if (Mpval(ldia) != -1)
282 BI_TransDist(ctxt, tscope, Mpval(m), Mpval(n), rA, cA, tldia,
283 (BI_DistType *) &bp2->Buff[idist],
284 trdest, Mpval(cdest));
285 }
286 }
287 else
288 {
289 ierr=MPI_Allreduce(bp->Buff, bp2->Buff, bp->N, bp->dtype, BlacComb,
290 ctxt->scp->comm);
291 BI_ivmcopy(Mpval(m), Mpval(n), A, tlda, bp2->Buff);
292 if (Mpval(ldia) != -1)
293 BI_TransDist(ctxt, tscope, Mpval(m), Mpval(n), rA, cA, tldia,
294 (BI_DistType *) &bp2->Buff[idist],
295 trdest, Mpval(cdest));
296 }
297 ierr=MPI_Op_free(&BlacComb);
298 if (Mpval(ldia) != -1)
299#ifdef ZeroByteTypeBug
300 if (N > 0)
301#endif
302 ierr=BI_MPI_TYPE_FREE(&MyType);
303 if (BI_ActiveQ) BI_UpdateBuffs(NULL);
304 return;
305 break;
306 case 'i':
307 BI_MringComb(ctxt, bp, bp2, N, vvop, dest, 1);
308 break;
309 case 'd':
310 BI_MringComb(ctxt, bp, bp2, N, vvop, dest, -1);
311 break;
312 case 's':
313 BI_MringComb(ctxt, bp, bp2, N, vvop, dest, 2);
314 break;
315 case 'm':
316 BI_MringComb(ctxt, bp, bp2, N, vvop, dest, ctxt->Nr_co);
317 break;
318 case '1':
319 case '2':
320 case '3':
321 case '4':
322 case '5':
323 case '6':
324 case '7':
325 case '8':
326 case '9':
327 BI_TreeComb(ctxt, bp, bp2, N, vvop, dest, ttop-47);
328 break;
329 case 'f':
330 BI_TreeComb(ctxt, bp, bp2, N, vvop, dest, FULLCON);
331 break;
332 case 't':
333 BI_TreeComb(ctxt, bp, bp2, N, vvop, dest, ctxt->Nb_co);
334 break;
335 case 'h':
336/*
337 * Use bidirectional exchange if everyone wants answer
338 */
339 if ( (trdest == -1) && !(ctxt->TopsCohrnt) )
340 BI_BeComb(ctxt, bp, bp2, N, vvop);
341 else
342 BI_TreeComb(ctxt, bp, bp2, N, vvop, dest, 2);
343 break;
344 default :
345 BI_BlacsErr(Mpval(ConTxt), __LINE__, __FILE__, "Unknown topology '%c'",
346 ttop);
347 }
348
349 if (Mpval(ldia) != -1)
350#ifdef ZeroByteTypeBug
351 if (N > 0)
352#endif
353 ierr=BI_MPI_TYPE_FREE(&MyType);
354/*
355 * If I am selected to receive answer
356 */
357 if ( (ctxt->scp->Iam == dest) || (dest == -1) )
358 {
359/*
360 * Translate the distances stored in the latter part of bp->Buff into
361 * process grid coordinates, and output these coordinates in the
362 * arrays rA and cA.
363 */
364 if (Mpval(ldia) != -1)
365 BI_TransDist(ctxt, tscope, Mpval(m), Mpval(n), rA, cA, tldia,
366 dist, trdest, Mpval(cdest));
367/*
368 * Unpack the amn array
369 */
370 if (bp != &BI_AuxBuff) BI_ivmcopy(Mpval(m), Mpval(n), A, tlda, bp->Buff);
371 }
372}
void BI_ArgCheck(Int ConTxt, Int RoutType, char *routine, char scope, char uplo, char diag, Int m, Int n, Int lda, Int nprocs, Int *prows, Int *pcols)
Definition BI_ArgCheck.c:4
void BI_BeComb(BLACSCONTEXT *ctxt, BLACBUFF *bp, BLACBUFF *bp2, Int N, VVFUNPTR Xvvop)
Definition BI_BeComb.c:10
Int BI_BuffIsFree(BLACBUFF *bp, Int Wait)
BLACBUFF * BI_GetBuff(Int length)
Definition BI_GetBuff.c:37
MPI_Datatype BI_GetMpiGeType(BLACSCONTEXT *ctxt, Int m, Int n, Int lda, MPI_Datatype Dtype, Int *N)
BLACBUFF * BI_ActiveQ
BLACBUFF BI_AuxBuff
void BI_MringComb(BLACSCONTEXT *ctxt, BLACBUFF *bp, BLACBUFF *bp2, Int N, VVFUNPTR Xvvop, Int dest, Int nrings)
Definition BI_MringComb.c:2
BLACBUFF * BI_Pack(BLACSCONTEXT *ctxt, BVOID *A, BLACBUFF *bp, MPI_Datatype Dtype)
Definition BI_Pack.c:2
void BI_TransDist(BLACSCONTEXT *ctxt, char scope, Int m, Int n, Int *rA, Int *cA, Int ldrc, BI_DistType *dist, Int rdest, Int cdest)
Definition BI_TransDist.c:3
void BI_TreeComb(BLACSCONTEXT *ctxt, BLACBUFF *bp, BLACBUFF *bp2, Int N, VVFUNPTR Xvvop, Int dest, Int nbranches)
Definition BI_TreeComb.c:19
void BI_Unpack(BLACSCONTEXT *ctxt, BVOID *A, BLACBUFF *bp, MPI_Datatype Dtype)
Definition BI_Unpack.c:3
void BI_UpdateBuffs(BLACBUFF *Newbp)
void BI_iMPI_amn2(void *in, void *inout, MpiInt *N, MPI_Datatype *dtype)
Definition BI_iMPI_amn2.c:2
void BI_iMPI_amn(void *in, void *inout, MpiInt *N, MPI_Datatype *dtype)
Definition BI_iMPI_amn.c:3
void BI_imvcopy(Int m, Int n, Int *A, Int lda, Int *buff)
Definition BI_imvcopy.c:2
void BI_ivmcopy(Int m, Int n, Int *A, Int lda, Int *buff)
Definition BI_ivmcopy.c:3
void BI_ivvamn2(Int N, char *vec1, char *vec2)
Definition BI_ivvamn2.c:3
void BI_ivvamn(Int N, char *vec1, char *vec2)
Definition BI_ivvamn.c:2
#define Int
Definition Bconfig.h:22
#define MpiInt
Definition Bconfig.h:25
void BI_BlacsErr(Int ConTxt, Int line, char *file, char *form,...)
Definition BI_BlacsErr.c:3
#define BI_MpiDistType
Definition Bdef.h:73
#define BI_MPI_TYPE_FREE(t)
Definition Bdef.h:305
#define F2C_CharTrans(c)
Definition Bdef.h:246
#define Mvkpnum(ctxt, prow, pcol)
Definition Bdef.h:174
#define MGetConTxt(Context, ctxtptr)
Definition Bdef.h:200
#define F_VOID_FUNC
Definition Bdef.h:232
void(* VVFUNPTR)(Int, char *, char *)
Definition Bdef.h:68
#define Mpaddress(para)
Definition Bdef.h:262
#define Mpval(para)
Definition Bdef.h:261
#define FULLCON
Definition Bdef.h:100
#define Mlowcase(C)
Definition Bdef.h:145
void BI_BlacsWarn(Int ConTxt, Int line, char *file, char *form,...)
Definition BI_BlacsWarn.c:3
#define BI_DistType
Definition Bdef.h:72
#define RT_COMB
Definition Bdef.h:109
#define BVOID
Definition Bdef.h:136
void Cigamn2d()
char * F_CHAR
Definition pblas.h:113
F_VOID_FUNC igamn2d_(Int *ConTxt, F_CHAR scope, F_CHAR top, Int *m, Int *n, Int *A, Int *lda, Int *rA, Int *cA, Int *ldia, Int *rdest, Int *cdest)
Definition igamn2d_.c:7
Int Len
Definition Bdef.h:57
Int N
Definition Bdef.h:61
MPI_Datatype dtype
Definition Bdef.h:60
char * Buff
Definition Bdef.h:56
Int TopsCohrnt
Definition Bdef.h:28
BLACSSCOPE * scp
Definition Bdef.h:26
Int Nb_co
Definition Bdef.h:30
BLACSSCOPE ascp
Definition Bdef.h:25
BLACSSCOPE rscp
Definition Bdef.h:25
BLACSSCOPE cscp
Definition Bdef.h:25
Int Nr_co
Definition Bdef.h:30
Int Np
Definition Bdef.h:17
MPI_Comm comm
Definition Bdef.h:15
Int Iam
Definition Bdef.h:17