ScaLAPACK 2.1  2.1
ScaLAPACK: Scalable Linear Algebra PACKage
PB_CInV.c
Go to the documentation of this file.
1 /* ---------------------------------------------------------------------
2 *
3 * -- PBLAS auxiliary routine (version 2.0) --
4 * University of Tennessee, Knoxville, Oak Ridge National Laboratory,
5 * and University of California, Berkeley.
6 * April 1, 1998
7 *
8 * ---------------------------------------------------------------------
9 */
10 /*
11 * Include files
12 */
13 #include "../pblas.h"
14 #include "../PBpblas.h"
15 #include "../PBtools.h"
16 #include "../PBblacs.h"
17 #include "../PBblas.h"
18 
19 #ifdef __STDC__
20 void PB_CInV( PBTYP_T * TYPE, char * CONJUG, char * ROWCOL, int M,
21  int N, int * DESCA, int K, char * X, int IX, int JX,
22  int * DESCX, char * XROC, char * * XAPTR, int * DXA,
23  int * XAFREE )
24 #else
25 void PB_CInV( TYPE, CONJUG, ROWCOL, M, N, DESCA, K, X, IX, JX, DESCX,
26  XROC, XAPTR, DXA, XAFREE )
27 /*
28 * .. Scalar Arguments ..
29 */
30  char * CONJUG, * ROWCOL, * XROC;
31  int * XAFREE, IX, JX, K, M, N;
32  PBTYP_T * TYPE;
33 /*
34 * .. Array Arguments ..
35 */
36  int * DESCA, * DESCX, * DXA;
37  char * X, * * XAPTR;
38 #endif
39 {
40 /*
41 * Purpose
42 * =======
43 *
44 * PB_CInV returns a pointer to an array that contains a one-dimensional
45 * input only subvector which is replicated over the rows or columns of
46 * a submatrix described by DESCA. A subvector is specified on input to
47 * this routine that is reused whenever possible. On return, the subvec-
48 * tor is specified by a pointer to some data, a descriptor array des-
49 * cribing its layout and a logical value indicating if this local piece
50 * of data has been dynamically allocated by this function. This routine
51 * is specifically designed for traditional Level 2 like PBLAS opera-
52 * tions using an input only vector such as PxGER, PxSYR ...
53 *
54 * Notes
55 * =====
56 *
57 * A description vector is associated with each 2D block-cyclicly dis-
58 * tributed matrix. This vector stores the information required to
59 * establish the mapping between a matrix entry and its corresponding
60 * process and memory location.
61 *
62 * In the following comments, the character _ should be read as
63 * "of the distributed matrix". Let A be a generic term for any 2D
64 * block cyclicly distributed matrix. Its description vector is DESC_A:
65 *
66 * NOTATION STORED IN EXPLANATION
67 * ---------------- --------------- ------------------------------------
68 * DTYPE_A (global) DESCA[ DTYPE_ ] The descriptor type.
69 * CTXT_A (global) DESCA[ CTXT_ ] The BLACS context handle, indicating
70 * the NPROW x NPCOL BLACS process grid
71 * A is distributed over. The context
72 * itself is global, but the handle
73 * (the integer value) may vary.
74 * M_A (global) DESCA[ M_ ] The number of rows in the distribu-
75 * ted matrix A, M_A >= 0.
76 * N_A (global) DESCA[ N_ ] The number of columns in the distri-
77 * buted matrix A, N_A >= 0.
78 * IMB_A (global) DESCA[ IMB_ ] The number of rows of the upper left
79 * block of the matrix A, IMB_A > 0.
80 * INB_A (global) DESCA[ INB_ ] The number of columns of the upper
81 * left block of the matrix A,
82 * INB_A > 0.
83 * MB_A (global) DESCA[ MB_ ] The blocking factor used to distri-
84 * bute the last M_A-IMB_A rows of A,
85 * MB_A > 0.
86 * NB_A (global) DESCA[ NB_ ] The blocking factor used to distri-
87 * bute the last N_A-INB_A columns of
88 * A, NB_A > 0.
89 * RSRC_A (global) DESCA[ RSRC_ ] The process row over which the first
90 * row of the matrix A is distributed,
91 * NPROW > RSRC_A >= 0.
92 * CSRC_A (global) DESCA[ CSRC_ ] The process column over which the
93 * first column of A is distributed.
94 * NPCOL > CSRC_A >= 0.
95 * LLD_A (local) DESCA[ LLD_ ] The leading dimension of the local
96 * array storing the local blocks of
97 * the distributed matrix A,
98 * IF( Lc( 1, N_A ) > 0 )
99 * LLD_A >= MAX( 1, Lr( 1, M_A ) )
100 * ELSE
101 * LLD_A >= 1.
102 *
103 * Let K be the number of rows of a matrix A starting at the global in-
104 * dex IA,i.e, A( IA:IA+K-1, : ). Lr( IA, K ) denotes the number of rows
105 * that the process of row coordinate MYROW ( 0 <= MYROW < NPROW ) would
106 * receive if these K rows were distributed over NPROW processes. If K
107 * is the number of columns of a matrix A starting at the global index
108 * JA, i.e, A( :, JA:JA+K-1, : ), Lc( JA, K ) denotes the number of co-
109 * lumns that the process MYCOL ( 0 <= MYCOL < NPCOL ) would receive if
110 * these K columns were distributed over NPCOL processes.
111 *
112 * The values of Lr() and Lc() may be determined via a call to the func-
113 * tion PB_Cnumroc:
114 * Lr( IA, K ) = PB_Cnumroc( K, IA, IMB_A, MB_A, MYROW, RSRC_A, NPROW )
115 * Lc( JA, K ) = PB_Cnumroc( K, JA, INB_A, NB_A, MYCOL, CSRC_A, NPCOL )
116 *
117 * Arguments
118 * =========
119 *
120 * TYPE (local input) pointer to a PBTYP_T structure
121 * On entry, TYPE is a pointer to a structure of type PBTYP_T,
122 * that contains type information (See pblas.h).
123 *
124 * CONJUG (global input) pointer to CHAR
125 * On entry, CONJUG specifies if this routine should return
126 * the conjugate subvector as follows:
127 * = 'N' or 'n': The initial subvector is returned,
128 * = 'Z' or 'z': The conjugate subvector is returned.
129 *
130 * ROWCOL (global input) pointer to CHAR
131 * On entry, ROWCOL specifies if this routine should return a
132 * row or column subvector replicated over the underlying subma-
133 * trix as follows:
134 * = 'R' or 'r': A row subvector is returned,
135 * = 'C' or 'c': A column subvector is returned.
136 *
137 * M (global input) INTEGER
138 * On entry, M specifies the number of rows of the underlying
139 * submatrix described by DESCA. M must be at least zero.
140 *
141 * N (global input) INTEGER
142 * On entry, N specifies the number of columns of the underlying
143 * submatrix described by DESCA. N must be at least zero.
144 *
145 * DESCA (global and local input) INTEGER array
146 * On entry, DESCA is an integer array of dimension DLEN_. This
147 * is the array descriptor for the matrix A.
148 *
149 * K (global input) INTEGER
150 * On entry, K specifies the length of the non-distributed di-
151 * mension of the subvector sub( X ). K must be at least zero.
152 *
153 * X (local input) pointer to CHAR
154 * On entry, X is an array of dimension (LLD_X, Kx), where LLD_X
155 * is at least MAX( 1, Lr( K, IX ) ) when XROC is 'R' or 'r'
156 * and MAX( 1, Lr( 1, IX+Lx-1 ) ) otherwise, and, Kx is at least
157 * Lc( 1, JX+Lx-1 ) when INCX = M_X and Lc( K, JX ) otherwise.
158 * Lx is N when ROWCOL = 'R' or 'r' and M otherwise. Before en-
159 * try, this array contains the local entries of the matrix X.
160 *
161 * IX (global input) INTEGER
162 * On entry, IX specifies X's global row index, which points to
163 * the beginning of the submatrix sub( X ).
164 *
165 * JX (global input) INTEGER
166 * On entry, JX specifies X's global column index, which points
167 * to the beginning of the submatrix sub( X ).
168 *
169 * DESCX (global and local input) INTEGER array
170 * On entry, DESCX is an integer array of dimension DLEN_. This
171 * is the array descriptor for the matrix X.
172 *
173 * XROC (global input) pointer to CHAR
174 * On entry, XROC specifies the orientation of the subvector
175 * sub( X ). When XROC is 'R' or 'r', sub( X ) is a row vector,
176 * and a column vector otherwise.
177 *
178 * XAPTR (local output) pointer to pointer to CHAR
179 * On exit, * XAPTR is an array containing the same data as the
180 * subvector sub( X ) which is replicated over the rows or co-
181 * lumns of the underlying matrix as specified by ROWCOL and
182 * DESCA.
183 *
184 * DXA (global and local output) INTEGER array
185 * On exit, DXA is a descriptor array of dimension DLEN_ descri-
186 * bing the data layout of the data pointed to by * XAPTR.
187 *
188 * XAFREE (local output) INTEGER
189 * On exit, XAFREE specifies if it has been possible to reuse
190 * the subvector sub( X ), i.e., if some dynamic memory was al-
191 * located for the data pointed to by *XAPTR or not. When XAFREE
192 * is zero, no dynamic memory was allocated. Otherwise, some dy-
193 * namic memory was allocated by this function that one MUST re-
194 * lease as soon as possible.
195 *
196 * -- Written on April 1, 1998 by
197 * Antoine Petitet, University of Tennessee, Knoxville 37996, USA.
198 *
199 * ---------------------------------------------------------------------
200 */
201 /*
202 * .. Local Scalars ..
203 */
204  char * top;
205  int AColSpan, ARowSpan, Acol, Aimb, Ainb, AisD, Amb, Amp, Anb,
206  Anq, Arow, Xcol, Xii, Ximb, Ximb1, Xinb, Xinb1, XisD, XisR,
207  XisRow, Xjj, Xld=1, Xmb, Xmp, Xnb, Xnq, Xrow, ctxt, mycol,
208  myrow, npcol, nprow;
209 /* ..
210 * .. Executable Statements ..
211 *
212 */
213 /*
214 * Initialize the output parameters to a default value
215 */
216  *XAFREE = 0;
217  *XAPTR = NULL;
218 /*
219 * Quick return if possible
220 */
221  if( ( M <= 0 ) || ( N <= 0 ) || ( K <= 0 ) )
222  {
223  if( Mupcase( ROWCOL[0] ) == CROW )
224  {
225  PB_Cdescset( DXA, K, N, 1, DESCA[INB_], 1, DESCA[NB_], DESCA[RSRC_],
226  DESCA[CSRC_], DESCA[CTXT_], 1 );
227  }
228  else
229  {
230  PB_Cdescset( DXA, M, K, DESCA[IMB_], 1, DESCA[MB_], 1, DESCA[RSRC_],
231  DESCA[CSRC_], DESCA[CTXT_], DESCA[LLD_] );
232  }
233  return;
234  }
235 /*
236 * Retrieve process grid information
237 */
238  Cblacs_gridinfo( ( ctxt = DESCX[CTXT_] ), &nprow, &npcol, &myrow, &mycol );
239 /*
240 * Retrieve sub( X )'s local information: Xii, Xjj, Xrow, Ycol
241 */
242  Minfog2l( IX, JX, DESCX, nprow, npcol, myrow, mycol, Xii, Xjj, Xrow, Xcol );
243 /*
244 * Is sub( X ) distributed or not, replicated or not ?
245 */
246  if( ( XisRow = ( Mupcase( XROC[0] ) == CROW ) ) != 0 )
247  {
248  XisD = ( ( Xcol >= 0 ) && ( npcol > 1 ) );
249  XisR = ( ( Xrow == -1 ) || ( nprow == 1 ) );
250  }
251  else
252  {
253  XisD = ( ( Xrow >= 0 ) && ( nprow > 1 ) );
254  XisR = ( ( Xcol == -1 ) || ( npcol == 1 ) );
255  }
256 
257  Arow = DESCA[ RSRC_ ]; Acol = DESCA[ CSRC_ ];
258 
259  if( Mupcase( ROWCOL[0] ) == CROW )
260  {
261 /*
262 * Want a row vector
263 */
264  Ainb = DESCA[ INB_ ]; Anb = DESCA[ NB_ ];
265  Mnumroc( Anq, N, 0, Ainb, Anb, mycol, Acol, npcol );
266 /*
267 * Does A spans multiples process rows ? It does if Arow < 0.
268 */
269  ARowSpan = ( Arow < 0 ) ||
270  Mspan( M, 0, DESCA[IMB_], DESCA[MB_], Arow, nprow );
271 
272  if( XisRow && ( Mupcase( CONJUG[0] ) == CNOCONJG ) )
273  {
274 /*
275 * It is possible to reuse sub( X ) iff sub( X ) is already a row vector and
276 * the data does not need to be conjugated.
277 */
278  AisD = ( ( Acol >= 0 ) && ( npcol > 1 ) );
279 
280  Xinb = DESCX[ INB_ ]; Xnb = DESCX[ NB_ ];
281  Mfirstnb( Xinb1, N, JX, Xinb, Xnb );
282 /*
283 * sub( X ) is aligned with A (reuse condition) iff both operands are not
284 * distributed, or both of them are distributed and start in the same process
285 * column and either N is smaller than the first blocksize of sub( X ) and A,
286 * or their column blocking factors match.
287 */
288  if( ( !AisD && !XisD ) ||
289  ( ( AisD && XisD ) &&
290  ( ( Acol == Xcol ) &&
291  ( ( ( Ainb >= N ) && ( Xinb1 >= N ) ) ||
292  ( ( Ainb == Xinb1 ) && ( Anb == Xnb ) ) ) ) ) )
293  {
294 /*
295 * sub( X ) is aligned with A
296 */
297  Ximb = DESCX[ IMB_ ]; Xmb = DESCX[ MB_ ];
298  Mfirstnb( Ximb1, K, IX, Ximb, Xmb );
299 
300  if( XisR || ( !ARowSpan && ( Arow == Xrow ) ) )
301  {
302 /*
303 * If sub( X ) is replicated, or, A spans only one process row and either
304 * sub( X ) is replicated or resides in the same process row than A, then
305 * sub( X ) is already at the correct place.
306 */
307  if( Anq > 0 )
308  {
309  Xld = DESCX[ LLD_ ];
310  if( ARowSpan || ( myrow == Arow ) )
311  *XAPTR = Mptr( X, Xii, Xjj, Xld, TYPE->size );
312  }
313  else
314  {
315  Xld = 1;
316  }
317  MDescSet( DXA, K, N, K, Xinb1, 1, Xnb, ( ARowSpan ? -1 : Arow ),
318  Xcol, ctxt, Xld );
319  }
320  else if( ARowSpan )
321  {
322 /*
323 * Otherwise, we know that sub( X ) cannot be replicated, let suppose in
324 * addition that A spans all process rows. sub( X ) need simply to be broadcast
325 * over A.
326 */
327  if( myrow == Xrow )
328  {
329  Xld = DESCX[ LLD_ ];
330  if( Anq > 0 )
331  {
332  *XAPTR = Mptr( X, Xii, Xjj, Xld, TYPE->size );
333  top = PB_Ctop( &ctxt, BCAST, COLUMN, TOP_GET );
334  TYPE->Cgebs2d( ctxt, COLUMN, top, K, Anq, *XAPTR, Xld );
335  }
336  }
337  else
338  {
339  Xld = MAX( 1, K );
340  if( Anq > 0 )
341  {
342  *XAPTR = PB_Cmalloc( K * Anq * TYPE->size );
343  *XAFREE = 1;
344  top = PB_Ctop( &ctxt, BCAST, COLUMN, TOP_GET );
345  TYPE->Cgebr2d( ctxt, COLUMN, top, K, Anq, *XAPTR, Xld,
346  Xrow, mycol );
347  }
348  }
349  PB_Cdescset( DXA, K, N, K, Xinb1, 1, Xnb, -1, Xcol, ctxt, Xld );
350  }
351  else
352  {
353 /*
354 * Finally, sub( X ) is not replicated and A spans only one process row. There
355 * is no need to broadcast, a send/recv is sufficient.
356 */
357  if( myrow == Xrow )
358  {
359  Xld = DESCX[ LLD_ ];
360  if( Anq > 0 )
361  {
362  *XAPTR = Mptr( X, Xii, Xjj, Xld, TYPE->size );
363  TYPE->Cgesd2d( ctxt, K, Anq, *XAPTR, Xld, Arow, mycol );
364  }
365  }
366  else if( myrow == Arow )
367  {
368  Xld = MAX( 1, K );
369  if( Anq > 0 )
370  {
371  *XAPTR = PB_Cmalloc( K * Anq * TYPE->size );
372  *XAFREE = 1;
373  TYPE->Cgerv2d( ctxt, K, Anq, *XAPTR, Xld, Xrow, mycol );
374  }
375  }
376  PB_Cdescset( DXA, K, N, K, Xinb1, 1, Xnb, Arow, Xcol, ctxt,
377  Xld );
378  }
379  return;
380  }
381  }
382 /*
383 * sub( X ) cannot be reused, too bad ... redistribute
384 */
385  PB_Cdescset( DXA, K, N, K, Ainb, 1, Anb, ( ARowSpan ? -1 : Arow ), Acol,
386  ctxt, K );
387  Xmp = ( ARowSpan ? K : ( ( myrow == Arow ) ? K : 0 ) );
388  if( Xmp > 0 && Anq > 0 )
389  {
390  *XAPTR = PB_Cmalloc( Anq * Xmp * TYPE->size );
391  *XAFREE = 1;
392  }
393  if( XisRow )
394  {
395  PB_Cpaxpby( TYPE, CONJUG, K, N, TYPE->one, X, IX, JX, DESCX, XROC,
396  TYPE->zero, *XAPTR, 0, 0, DXA, ROW );
397  }
398  else
399  {
400  PB_Cpaxpby( TYPE, CONJUG, N, K, TYPE->one, X, IX, JX, DESCX, XROC,
401  TYPE->zero, *XAPTR, 0, 0, DXA, ROW );
402  }
403  }
404  else
405  {
406 /*
407 * Want a column vector
408 */
409  Aimb = DESCA[IMB_]; Amb = DESCA[MB_];
410  Mnumroc( Amp, M, 0, Aimb, Amb, myrow, Arow, nprow );
411 /*
412 * Does A spans multiples process columns ? It does if Acol < 0.
413 */
414  AColSpan = ( Acol < 0 ) ||
415  Mspan( N, 0, DESCA[INB_], DESCA[NB_], Acol, npcol );
416 
417  if( !( XisRow ) && ( Mupcase( CONJUG[0] ) == CNOCONJG ) )
418  {
419 /*
420 * It is possible to reuse sub( X ) iff sub( X ) is already a column vector and
421 * the data does not need to be conjugated
422 */
423  AisD = ( ( Arow >= 0 ) && ( nprow > 1 ) );
424 
425  Ximb = DESCX[ IMB_ ]; Xmb = DESCX[ MB_ ];
426  Mfirstnb( Ximb1, M, IX, Ximb, Xmb );
427 /*
428 * sub( X ) is aligned with A (reuse condition) iff both operands are not
429 * distributed, or both of them are distributed and start in the same process
430 * row and either M is smaller than the first blocksize of sub( X ) and A, or
431 * their row blocking factors match.
432 */
433  if( ( !AisD && !XisD ) ||
434  ( ( AisD && XisD ) &&
435  ( ( Arow == Xrow ) &&
436  ( ( ( Aimb >= M ) && ( Ximb1 >= M ) ) ||
437  ( ( Aimb == Ximb1 ) && ( Amb == Xmb ) ) ) ) ) )
438  {
439 /*
440 * sub( X ) is aligned with A
441 */
442  Xinb = DESCX[ INB_ ]; Xnb = DESCX[ NB_ ];
443  Mfirstnb( Xinb1, K, JX, Xinb, Xnb );
444 
445  if( XisR || ( !AColSpan && ( Acol == Xcol ) ) )
446  {
447 /*
448 * If sub( X ) is replicated, or, A spans only one process column and either
449 * sub( X ) is replicated or resides in the same process columns than A, then
450 * sub( X ) is already at the correct place.
451 */
452  if( Amp > 0 )
453  {
454  Xld = DESCX[ LLD_ ];
455  if( AColSpan || ( mycol == Acol ) )
456  *XAPTR = Mptr( X, Xii, Xjj, Xld, TYPE->size );
457  }
458  else
459  {
460  Xld = 1;
461  }
462  MDescSet( DXA, M, K, Ximb1, K, Xmb, 1, Xrow,
463  ( AColSpan ? -1 : Acol ), ctxt, Xld );
464  }
465  else if( AColSpan )
466  {
467 /*
468 * Otherwise, we know that sub( X ) is not be replicated, let suppose in
469 * addition that A spans all process columns. sub( X ) need simply to be
470 * broadcast over A.
471 */
472  if( mycol == Xcol )
473  {
474  Xld = DESCX[ LLD_ ];
475  if( Amp > 0 )
476  {
477  *XAPTR = Mptr( X, Xii, Xjj, Xld, TYPE->size );
478  top = PB_Ctop( &ctxt, BCAST, ROW, TOP_GET );
479  TYPE->Cgebs2d( ctxt, ROW, top, Amp, K, *XAPTR, Xld );
480  }
481  }
482  else
483  {
484  Xld = MAX( 1, Amp );
485  if( Amp > 0 )
486  {
487  *XAPTR = PB_Cmalloc( Amp * K * TYPE->size );
488  *XAFREE = 1;
489  top = PB_Ctop( &ctxt, BCAST, ROW, TOP_GET );
490  TYPE->Cgebr2d( ctxt, ROW, top, Amp, K, *XAPTR, Xld, myrow,
491  Xcol );
492  }
493  }
494  PB_Cdescset( DXA, M, K, Ximb1, K, Xmb, 1, Xrow, -1, ctxt, Xld );
495  }
496  else
497  {
498 /*
499 * Finally, sub( X ) is not replicated and A spans only one process column.
500 * There is no need to broadcast, a send/recv is sufficient.
501 */
502  if( mycol == Xcol )
503  {
504  Xld = DESCX[ LLD_ ];
505  if( Amp > 0 )
506  {
507  *XAPTR = Mptr( X, Xii, Xjj, Xld, TYPE->size );
508  TYPE->Cgesd2d( ctxt, Amp, K, *XAPTR, Xld, myrow, Acol );
509  }
510  }
511  else if( mycol == Acol )
512  {
513  Xld = MAX( 1, Amp );
514  if( Amp > 0 )
515  {
516  *XAPTR = PB_Cmalloc( Amp * K * TYPE->size );
517  *XAFREE = 1;
518  TYPE->Cgerv2d( ctxt, Amp, K, *XAPTR, Xld, myrow, Xcol );
519  }
520  }
521  PB_Cdescset( DXA, M, K, Ximb1, K, Xmb, 1, Xrow, Acol, ctxt,
522  Xld );
523  }
524  return;
525  }
526  }
527 /*
528 * sub( X ) cannot be reused, too bad ... redistribute
529 */
530  PB_Cdescset( DXA, M, K, Aimb, K, Amb, 1, Arow, ( AColSpan ? -1 : Acol ),
531  ctxt, MAX( 1, Amp ) );
532  Xnq = ( AColSpan ? K : ( ( mycol == Acol ) ? K : 0 ) );
533  if( Xnq > 0 && Amp > 0 )
534  {
535  *XAPTR = PB_Cmalloc( Amp * Xnq * TYPE->size );
536  *XAFREE = 1;
537  }
538  if( XisRow )
539  {
540  PB_Cpaxpby( TYPE, CONJUG, K, M, TYPE->one, X, IX, JX, DESCX, XROC,
541  TYPE->zero, *XAPTR, 0, 0, DXA, COLUMN );
542  }
543  else
544  {
545  PB_Cpaxpby( TYPE, CONJUG, M, K, TYPE->one, X, IX, JX, DESCX, XROC,
546  TYPE->zero, *XAPTR, 0, 0, DXA, COLUMN );
547  }
548  }
549 /*
550 * End of PB_CInV
551 */
552 }
PB_CInV
void PB_CInV(PBTYP_T *TYPE, char *CONJUG, char *ROWCOL, int M, int N, int *DESCA, int K, char *X, int IX, int JX, int *DESCX, char *XROC, char **XAPTR, int *DXA, int *XAFREE)
Definition: PB_CInV.c:25
TYPE
#define TYPE
Definition: clamov.c:7
ROW
#define ROW
Definition: PBblacs.h:46
MB_
#define MB_
Definition: PBtools.h:43
PB_Cpaxpby
void PB_Cpaxpby()
MDescSet
#define MDescSet(desc, m, n, imb, inb, mb, nb, rsrc, csrc, ictxt, lld)
Definition: PBtools.h:499
NB_
#define NB_
Definition: PBtools.h:44
COLUMN
#define COLUMN
Definition: PBblacs.h:45
CSRC_
#define CSRC_
Definition: PBtools.h:46
Mspan
#define Mspan(n_, i_, inb_, nb_, srcproc_, nprocs_)
Definition: PBtools.h:160
Mnumroc
#define Mnumroc(np_, n_, i_, inb_, nb_, proc_, srcproc_, nprocs_)
Definition: PBtools.h:222
LLD_
#define LLD_
Definition: PBtools.h:47
CNOCONJG
#define CNOCONJG
Definition: PBblas.h:19
CROW
#define CROW
Definition: PBblacs.h:21
IMB_
#define IMB_
Definition: PBtools.h:41
PB_Cdescset
void PB_Cdescset()
Minfog2l
#define Minfog2l(i_, j_, desc_, nr_, nc_, r_, c_, ii_, jj_, pr_, pc_)
Definition: PBtools.h:428
TOP_GET
#define TOP_GET
Definition: PBblacs.h:50
Mfirstnb
#define Mfirstnb(inbt_, n_, i_, inb_, nb_)
Definition: PBtools.h:139
PB_Ctop
char * PB_Ctop()
RSRC_
#define RSRC_
Definition: PBtools.h:45
BCAST
#define BCAST
Definition: PBblacs.h:48
PB_Cmalloc
char * PB_Cmalloc()
INB_
#define INB_
Definition: PBtools.h:42
MAX
#define MAX(a_, b_)
Definition: PBtools.h:77
Cblacs_gridinfo
void Cblacs_gridinfo()
PBTYP_T
Definition: pblas.h:325
Mupcase
#define Mupcase(C)
Definition: PBtools.h:83
Mptr
#define Mptr(a_, i_, j_, lda_, siz_)
Definition: PBtools.h:132
CTXT_
#define CTXT_
Definition: PBtools.h:38