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