SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
pcgemm_.c
Go to the documentation of this file.
1/* ---------------------------------------------------------------------
2*
3* -- PBLAS 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__
20void pcgemm_( F_CHAR_T TRANSA, F_CHAR_T TRANSB,
21 Int * M, Int * N, Int * K,
22 float * ALPHA,
23 float * A, Int * IA, Int * JA, Int * DESCA,
24 float * B, Int * IB, Int * JB, Int * DESCB,
25 float * BETA,
26 float * C, Int * IC, Int * JC, Int * DESCC )
27#else
28void pcgemm_( TRANSA, TRANSB, M, N, K, ALPHA, A, IA, JA, DESCA,
29 B, IB, JB, DESCB, BETA, C, IC, JC, DESCC )
30/*
31* .. Scalar Arguments ..
32*/
33 F_CHAR_T TRANSA, TRANSB;
34 Int * IA, * IB, * IC, * JA, * JB, * JC, * K, * M, * N;
35 float * ALPHA, * BETA;
36/*
37* .. Array Arguments ..
38*/
39 Int * DESCA, * DESCB, * DESCC;
40 float * A, * B, * C;
41#endif
42{
43/*
44* Purpose
45* =======
46*
47* PCGEMM performs one of the matrix-matrix operations
48*
49* sub( C ) := alpha*op( sub( A ) )*op( sub( B ) ) + beta*sub( C ),
50*
51* where
52*
53* sub( C ) denotes C(IC:IC+M-1,JC:JC+N-1), and, op( X ) is one of
54* op( X ) = X or op( X ) = X' or op( X ) = conjg( X' ).
55*
56* Thus, op( sub( A ) ) denotes A(IA:IA+M-1,JA:JA+K-1) if TRANSA = 'N',
57* A(IA:IA+K-1,JA:JA+M-1)' if TRANSA = 'T',
58* conjg(A(IA:IA+K-1,JA:JA+M-1)') if TRANSA = 'C',
59*
60* and, op( sub( B ) ) denotes B(IB:IB+K-1,JB:JB+N-1) if TRANSB = 'N',
61* B(IB:IB+N-1,JB:JB+K-1)' if TRANSB = 'T',
62* conjg(B(IB:IB+N-1,JB:JB+K-1)') if TRANSB = 'C'.
63*
64* Alpha and beta are scalars. A, B and C are matrices; op( sub( A ) )
65* is an m by k submatrix, op( sub( B ) ) is an k by n submatrix and
66* sub( C ) is an m by n submatrix.
67*
68* Notes
69* =====
70*
71* A description vector is associated with each 2D block-cyclicly dis-
72* tributed matrix. This vector stores the information required to
73* establish the mapping between a matrix entry and its corresponding
74* process and memory location.
75*
76* In the following comments, the character _ should be read as
77* "of the distributed matrix". Let A be a generic term for any 2D
78* block cyclicly distributed matrix. Its description vector is DESC_A:
79*
80* NOTATION STORED IN EXPLANATION
81* ---------------- --------------- ------------------------------------
82* DTYPE_A (global) DESCA[ DTYPE_ ] The descriptor type.
83* CTXT_A (global) DESCA[ CTXT_ ] The BLACS context handle, indicating
84* the NPROW x NPCOL BLACS process grid
85* A is distributed over. The context
86* itself is global, but the handle
87* (the integer value) may vary.
88* M_A (global) DESCA[ M_ ] The number of rows in the distribu-
89* ted matrix A, M_A >= 0.
90* N_A (global) DESCA[ N_ ] The number of columns in the distri-
91* buted matrix A, N_A >= 0.
92* IMB_A (global) DESCA[ IMB_ ] The number of rows of the upper left
93* block of the matrix A, IMB_A > 0.
94* INB_A (global) DESCA[ INB_ ] The number of columns of the upper
95* left block of the matrix A,
96* INB_A > 0.
97* MB_A (global) DESCA[ MB_ ] The blocking factor used to distri-
98* bute the last M_A-IMB_A rows of A,
99* MB_A > 0.
100* NB_A (global) DESCA[ NB_ ] The blocking factor used to distri-
101* bute the last N_A-INB_A columns of
102* A, NB_A > 0.
103* RSRC_A (global) DESCA[ RSRC_ ] The process row over which the first
104* row of the matrix A is distributed,
105* NPROW > RSRC_A >= 0.
106* CSRC_A (global) DESCA[ CSRC_ ] The process column over which the
107* first column of A is distributed.
108* NPCOL > CSRC_A >= 0.
109* LLD_A (local) DESCA[ LLD_ ] The leading dimension of the local
110* array storing the local blocks of
111* the distributed matrix A,
112* IF( Lc( 1, N_A ) > 0 )
113* LLD_A >= MAX( 1, Lr( 1, M_A ) )
114* ELSE
115* LLD_A >= 1.
116*
117* Let K be the number of rows of a matrix A starting at the global in-
118* dex IA,i.e, A( IA:IA+K-1, : ). Lr( IA, K ) denotes the number of rows
119* that the process of row coordinate MYROW ( 0 <= MYROW < NPROW ) would
120* receive if these K rows were distributed over NPROW processes. If K
121* is the number of columns of a matrix A starting at the global index
122* JA, i.e, A( :, JA:JA+K-1, : ), Lc( JA, K ) denotes the number of co-
123* lumns that the process MYCOL ( 0 <= MYCOL < NPCOL ) would receive if
124* these K columns were distributed over NPCOL processes.
125*
126* The values of Lr() and Lc() may be determined via a call to the func-
127* tion PB_Cnumroc:
128* Lr( IA, K ) = PB_Cnumroc( K, IA, IMB_A, MB_A, MYROW, RSRC_A, NPROW )
129* Lc( JA, K ) = PB_Cnumroc( K, JA, INB_A, NB_A, MYCOL, CSRC_A, NPCOL )
130*
131* Arguments
132* =========
133*
134* TRANSA (global input) CHARACTER*1
135* On entry, TRANSA specifies the form of op( sub( A ) ) to be
136* used in the matrix multiplication as follows:
137*
138* TRANSA = 'N' or 'n' op( sub( A ) ) = sub( A ),
139*
140* TRANSA = 'T' or 't' op( sub( A ) ) = sub( A )',
141*
142* TRANSA = 'C' or 'c' op( sub( A ) ) = conjg( sub( A )' ).
143*
144* TRANSB (global input) CHARACTER*1
145* On entry, TRANSB specifies the form of op( sub( B ) ) to be
146* used in the matrix multiplication as follows:
147*
148* TRANSB = 'N' or 'n' op( sub( B ) ) = sub( B ),
149*
150* TRANSB = 'T' or 't' op( sub( B ) ) = sub( B )',
151*
152* TRANSB = 'C' or 'c' op( sub( B ) ) = conjg( sub( B )' ).
153*
154* M (global input) INTEGER
155* On entry, M specifies the number of rows of the submatrix
156* op( sub( A ) ) and of the submatrix sub( C ). M must be at
157* least zero.
158*
159* N (global input) INTEGER
160* On entry, N specifies the number of columns of the submatrix
161* op( sub( B ) ) and the number of columns of the submatrix
162* sub( C ). N must be at least zero.
163*
164* K (global input) INTEGER
165* On entry, K specifies the number of columns of the submatrix
166* op( sub( A ) ) and the number of rows of the submatrix
167* op( sub( B ) ). K must be at least zero.
168*
169* ALPHA (global input) COMPLEX
170* On entry, ALPHA specifies the scalar alpha. When ALPHA is
171* supplied as zero then the local entries of the arrays A and
172* B corresponding to the entries of the submatrices sub( A )
173* and sub( B ) respectively need not be set on input.
174*
175* A (local input) COMPLEX array
176* On entry, A is an array of dimension (LLD_A, Ka), where Ka is
177* at least Lc( 1, JA+K-1 ) when TRANSA = 'N' or 'n', and is at
178* least Lc( 1, JA+M-1 ) otherwise. Before entry, this array
179* contains the local entries of the matrix A.
180*
181* IA (global input) INTEGER
182* On entry, IA specifies A's global row index, which points to
183* the beginning of the submatrix sub( A ).
184*
185* JA (global input) INTEGER
186* On entry, JA specifies A's global column index, which points
187* to the beginning of the submatrix sub( A ).
188*
189* DESCA (global and local input) INTEGER array
190* On entry, DESCA is an integer array of dimension DLEN_. This
191* is the array descriptor for the matrix A.
192*
193* B (local input) COMPLEX array
194* On entry, B is an array of dimension (LLD_B, Kb), where Kb is
195* at least Lc( 1, JB+N-1 ) when TRANSB = 'N' or 'n', and is at
196* least Lc( 1, JB+K-1 ) otherwise. Before entry, this array
197* contains the local entries of the matrix B.
198*
199* IB (global input) INTEGER
200* On entry, IB specifies B's global row index, which points to
201* the beginning of the submatrix sub( B ).
202*
203* JB (global input) INTEGER
204* On entry, JB specifies B's global column index, which points
205* to the beginning of the submatrix sub( B ).
206*
207* DESCB (global and local input) INTEGER array
208* On entry, DESCB is an integer array of dimension DLEN_. This
209* is the array descriptor for the matrix B.
210*
211* BETA (global input) COMPLEX
212* On entry, BETA specifies the scalar beta. When BETA is
213* supplied as zero then the local entries of the array C
214* corresponding to the entries of the submatrix sub( C ) need
215* not be set on input.
216*
217* C (local input/local output) COMPLEX array
218* On entry, C is an array of dimension (LLD_C, Kc), where Kc is
219* at least Lc( 1, JC+N-1 ). Before entry, this array contains
220* the local entries of the matrix C.
221* On exit, the entries of this array corresponding to the local
222* entries of the submatrix sub( C ) are overwritten by the
223* local entries of the m by n updated submatrix.
224*
225* IC (global input) INTEGER
226* On entry, IC specifies C's global row index, which points to
227* the beginning of the submatrix sub( C ).
228*
229* JC (global input) INTEGER
230* On entry, JC specifies C's global column index, which points
231* to the beginning of the submatrix sub( C ).
232*
233* DESCC (global and local input) INTEGER array
234* On entry, DESCC is an integer array of dimension DLEN_. This
235* is the array descriptor for the matrix C.
236*
237* -- Written on April 1, 1998 by
238* Antoine Petitet, University of Tennessee, Knoxville 37996, USA.
239*
240* ---------------------------------------------------------------------
241*/
242/*
243* .. Local Scalars ..
244*/
245 char DirAB, DirBC, OpC, OpR, TrA, TrB, ctop, ctopsave, rtop,
246 rtopsave;
247 Int Ai, Aj, Bi, Bj, ChooseAB, ChooseBC, Ci, Cj, ForceTop, ctxt,
248 info, mycol, myrow, nb, nota, notb, npcol, nprow;
249 double ABest, ACest, BCest, tmp1, tmp2, tmp3, tmp4;
250 PBTYP_T * type;
251/*
252* .. Local Arrays ..
253*/
254 Int Ad[DLEN_], Bd[DLEN_], Cd[DLEN_];
255/* ..
256* .. Executable Statements ..
257*
258*/
259 nota = ( ( TrA = Mupcase( F2C_CHAR( TRANSA )[0] ) ) == CNOTRAN );
260 notb = ( ( TrB = Mupcase( F2C_CHAR( TRANSB )[0] ) ) == CNOTRAN );
261 PB_CargFtoC( *IA, *JA, DESCA, &Ai, &Aj, Ad );
262 PB_CargFtoC( *IB, *JB, DESCB, &Bi, &Bj, Bd );
263 PB_CargFtoC( *IC, *JC, DESCC, &Ci, &Cj, Cd );
264#ifndef NO_ARGCHK
265/*
266* Test the input parameters
267*/
268 Cblacs_gridinfo( ( ctxt = Ad[CTXT_] ), &nprow, &npcol, &myrow,
269 &mycol );
270 if( !( info = ( ( nprow == -1 ) ? -( 1001 + CTXT_ ) : 0 ) ) )
271 {
272 if( ( !nota ) && ( TrA != CTRAN ) && ( TrA != CCOTRAN ) )
273 {
274 PB_Cwarn( ctxt, __LINE__, "PCGEMM", "Illegal TRANSA = %c\n", TrA );
275 info = -1;
276 }
277 else if( ( !notb ) && ( TrB != CTRAN ) && ( TrB != CCOTRAN ) )
278 {
279 PB_Cwarn( ctxt, __LINE__, "PCGEMM", "Illegal TRANSB = %c\n", TrB );
280 info = -2;
281 }
282 if( nota )
283 PB_Cchkmat( ctxt, "PCGEMM", "A", *M, 3, *K, 5, Ai, Aj, Ad, 10,
284 &info );
285 else
286 PB_Cchkmat( ctxt, "PCGEMM", "A", *K, 5, *M, 3, Ai, Aj, Ad, 10,
287 &info );
288 if( notb )
289 PB_Cchkmat( ctxt, "PCGEMM", "B", *K, 5, *N, 4, Bi, Bj, Bd, 14,
290 &info );
291 else
292 PB_Cchkmat( ctxt, "PCGEMM", "B", *N, 4, *K, 5, Bi, Bj, Bd, 14,
293 &info );
294 PB_Cchkmat( ctxt, "PCGEMM", "C", *M, 3, *N, 4, Ci, Cj, Cd, 19,
295 &info );
296 }
297 if( info ) { PB_Cabort( ctxt, "PCGEMM", info ); return; }
298#endif
299/*
300* Quick return if possible
301*/
302 if( ( *M == 0 ) || ( *N == 0 ) ||
303 ( ( ( ALPHA[REAL_PART] == ZERO && ALPHA[IMAG_PART] == ZERO ) ||
304 ( *K == 0 ) ) &&
305 ( BETA [REAL_PART] == ONE && BETA [IMAG_PART] == ZERO ) ) )
306 return;
307/*
308* Get type structure
309*/
310 type = PB_Cctypeset();
311/*
312* If alpha or K is zero, sub( C ) := beta * sub( C ).
313*/
314 if( ( ( ALPHA[REAL_PART] == ZERO ) &&
315 ( ALPHA[IMAG_PART] == ZERO ) ) || ( *K == 0 ) )
316 {
317 if( ( BETA[REAL_PART] == ZERO ) && ( BETA[IMAG_PART] == ZERO ) )
318 {
319 PB_Cplapad( type, ALL, NOCONJG, *M, *N, type->zero, type->zero,
320 ((char * ) C), Ci, Cj, Cd );
321 }
322 else if( !( ( BETA[REAL_PART] == ONE ) &&
323 ( BETA[IMAG_PART] == ZERO ) ) )
324 {
325 PB_Cplascal( type, ALL, NOCONJG, *M, *N, ((char *) BETA),
326 ((char * ) C), Ci, Cj, Cd );
327 }
328 return;
329 }
330/*
331* Start the operations
332*/
333#ifdef NO_ARGCHK
334 Cblacs_gridinfo( ( ctxt = Ad[CTXT_] ), &nprow, &npcol, &myrow, &mycol );
335#endif
336/*
337* Algorithm selection is based on approximation of the communication volume
338* for distributed and aligned operands.
339*
340* ABest: both operands sub( A ) and sub( B ) are communicated (M, N >> K)
341* ACest: both operands sub( A ) and sub( C ) are communicated (K, N >> M)
342* BCest: both operands sub( B ) and sub( C ) are communicated (M, K >> N)
343*/
344 ABest = (double)(*K);
345 ACest = (double)(*M);
346 BCest = (double)(*N);
347
348 if( notb )
349 {
350 if( nota )
351 {
352 tmp1 = DNROC( *M, Cd[MB_], nprow ); tmp2 = DNROC( *N, Cd[NB_], npcol );
353 ABest *= ( ( ( Ad[CSRC_] == -1 ) || ( npcol == 1 ) ) ? ZERO : tmp1 ) +
354 ( ( ( Bd[RSRC_] == -1 ) || ( nprow == 1 ) ) ? ZERO : tmp2 );
355
356 tmp1 = DNROC( *K, Bd[MB_], nprow ); tmp2 = DNROC( *N, Bd[NB_], npcol );
357 tmp3 = DNROC( *K, Ad[NB_], npcol );
358 ACest *= ( npcol == 1 ? ZERO : tmp1 ) + MAX( tmp1, tmp3 ) +
359 CBRATIO * ( nprow == 1 ? ZERO : tmp2 );
360
361 tmp1 = DNROC( *M, Ad[MB_], nprow ); tmp2 = DNROC( *K, Ad[NB_], npcol );
362 tmp4 = DNROC( *K, Bd[MB_], nprow );
363 BCest *= CBRATIO * ( npcol == 1 ? ZERO : tmp1 ) +
364 ( nprow == 1 ? ZERO : tmp2 ) + MAX( tmp2, tmp4 );
365 }
366 else
367 {
368 tmp1 = DNROC( *M, Cd[MB_], nprow ); tmp2 = DNROC( *N, Cd[NB_], npcol );
369 tmp3 = DNROC( *M, Ad[NB_], npcol );
370 ABest *= ( npcol == 1 ? ZERO : tmp1 ) + MAX( tmp1, tmp3 ) +
371 ( nprow == 1 ? ZERO : tmp2 );
372
373 tmp1 = DNROC( *K, Bd[MB_], nprow ); tmp2 = DNROC( *N, Bd[NB_], npcol );
374 ACest *= ( ( ( Ad[CSRC_] == -1 ) || ( npcol == 1 ) ) ? ZERO : tmp1 ) +
375 CBRATIO *
376 ( ( ( Bd[RSRC_] == -1 ) || ( nprow == 1 ) ) ? ZERO : tmp2 );
377
378 tmp1 = DNROC( *K, Ad[MB_], nprow ); tmp2 = DNROC( *M, Bd[NB_], npcol );
379 tmp4 = DNROC( *M, Cd[MB_], nprow );
380 BCest *= ( ( ( Bd[CSRC_] == -1 ) || ( npcol == 1 ) ) ? ZERO : tmp1 ) +
381 CBRATIO * ( nprow == 1 ? ZERO : tmp2 ) + MAX( tmp2, tmp4 );
382 }
383 }
384 else
385 {
386 if( nota )
387 {
388 tmp1 = DNROC( *M, Cd[MB_], nprow ); tmp2 = DNROC( *N, Cd[NB_], npcol );
389 tmp4 = DNROC( *N, Bd[MB_], nprow );
390 ABest *= ( npcol == 1 ? ZERO : tmp1 ) +
391 ( nprow == 1 ? ZERO : tmp2 ) + MAX( tmp2, tmp4 );
392
393 tmp1 = DNROC( *N, Bd[MB_], nprow ); tmp2 = DNROC( *K, Bd[NB_], npcol );
394 tmp3 = DNROC( *N, Cd[NB_], npcol );
395 ACest *= CBRATIO * ( npcol == 1 ? ZERO : tmp1 ) + MAX( tmp1, tmp3 ) +
396 ( ( ( Ad[RSRC_] == -1 ) || ( nprow == 1 ) ) ? ZERO : tmp2 );
397
398 tmp1 = DNROC( *M, Ad[MB_], nprow ); tmp2 = DNROC( *K, Ad[NB_], npcol );
399 BCest *= CBRATIO *
400 ( ( ( Ad[CSRC_] == -1 ) || ( npcol == 1 ) ) ? ZERO : tmp1 ) +
401 ( ( ( Bd[RSRC_] == -1 ) || ( nprow == 1 ) ) ? ZERO : tmp2 );
402 }
403 else
404 {
405 tmp1 = DNROC( *M, Cd[MB_], nprow ); tmp2 = DNROC( *N, Cd[NB_], npcol );
406 tmp3 = DNROC( *M, Ad[NB_], npcol ); tmp4 = DNROC( *N, Bd[MB_], nprow );
407 ABest *= ( npcol == 1 ? ZERO : tmp1 ) + MAX( tmp1, tmp3 ) +
408 ( nprow == 1 ? ZERO : tmp2 ) + MAX( tmp2, tmp4 );
409
410 tmp1 = DNROC( *N, Bd[MB_], nprow ); tmp2 = DNROC( *K, Bd[NB_], npcol );
411 tmp3 = DNROC( *N, Cd[NB_], npcol ); tmp4 = DNROC( *K, Ad[MB_], nprow );
412 ACest *= CBRATIO * ( npcol == 1 ? ZERO : tmp1 ) + MAX( tmp1, tmp3 ) +
413 ( nprow == 1 ? ZERO : tmp2 ) + MAX( tmp2, tmp4 );
414
415 tmp1 = DNROC( *K, Ad[MB_], nprow ); tmp2 = DNROC( *M, Ad[NB_], npcol );
416 tmp3 = DNROC( *K, Bd[NB_], npcol ); tmp4 = DNROC( *M, Cd[MB_], nprow );
417 BCest *= ( npcol == 1 ? ZERO : tmp1 ) + MAX( tmp1, tmp3 ) +
418 CBRATIO * ( nprow == 1 ? ZERO : tmp2 ) + MAX( tmp2, tmp4 );
419 }
420 }
421 ChooseAB = ( ( ABest <= ( 1.3 * BCest ) ) && ( ABest <= ( 1.3 * ACest ) ) );
422 ChooseBC = ( ( BCest <= ACest ) && ( ( 1.3 * BCest ) <= ABest ) );
423/*
424* BLACS topologies are enforced iff M, N and K are strictly greater than the
425* logical block size returned by pilaenv_. Otherwise, it is assumed that the
426* routine calling this routine has already selected an adequate topology.
427*/
428 nb = pilaenv_( &ctxt, C2F_CHAR( &type->type ) );
429 ForceTop = ( ( *M > nb ) && ( *N > nb ) && ( *K > nb ) );
430
431 if( ChooseAB )
432 {
433 OpR = CBCAST;
434 OpC = CBCAST;
435 }
436 else if( ChooseBC )
437 {
438 if( nota ) { OpR = CCOMBINE; OpC = CBCAST; }
439 else { OpR = CBCAST; OpC = CCOMBINE; }
440 }
441 else
442 {
443 if( notb ) { OpR = CBCAST; OpC = CCOMBINE; }
444 else { OpR = CCOMBINE; OpC = CBCAST; }
445 }
446
447 rtop = *PB_Ctop( &ctxt, &OpR, ROW, TOP_GET );
448 ctop = *PB_Ctop( &ctxt, &OpC, COLUMN, TOP_GET );
449
450 if( ForceTop )
451 {
452 rtopsave = rtop;
453 ctopsave = ctop;
454/*
455* No clear winner for the ring topologies, so that if a ring topology is
456* already selected, keep it.
457*/
458 if( ( rtop != CTOP_DRING ) && ( rtop != CTOP_IRING ) &&
459 ( rtop != CTOP_SRING ) )
460 rtop = *PB_Ctop( &ctxt, &OpR, ROW, TOP_IRING );
461 if( ( ctop != CTOP_DRING ) && ( ctop != CTOP_IRING ) &&
462 ( ctop != CTOP_SRING ) )
463 ctop = *PB_Ctop( &ctxt, &OpC, COLUMN, TOP_IRING );
464/*
465* Remove the next 4 lines when the BLACS combine operations support ring
466* topologies
467*/
468 if( OpR == CCOMBINE )
469 rtop = *PB_Ctop( &ctxt, &OpR, ROW, TOP_DEFAULT );
470 if( OpC == CCOMBINE )
471 ctop = *PB_Ctop( &ctxt, &OpC, COLUMN, TOP_DEFAULT );
472 }
473
474 DirAB = ( rtop == CTOP_DRING ? CBACKWARD : CFORWARD );
475 DirBC = ( ctop == CTOP_DRING ? CBACKWARD : CFORWARD );
476
477 if( ChooseAB )
478 {
479 PB_CpgemmAB( type, &DirAB, &DirBC, ( nota ? NOTRAN :
480 ( ( TrA == CCOTRAN ) ? COTRAN : TRAN ) ), ( notb ? NOTRAN :
481 ( ( TrB == CCOTRAN ) ? COTRAN : TRAN ) ), *M, *N, *K,
482 ((char *)ALPHA), ((char *)A), Ai, Aj, Ad, ((char *)B), Bi,
483 Bj, Bd, ((char *)BETA), ((char *)C), Ci, Cj, Cd );
484 }
485 else if( ChooseBC )
486 {
487 PB_CpgemmBC( type, &DirAB, &DirBC, ( nota ? NOTRAN :
488 ( ( TrA == CCOTRAN ) ? COTRAN : TRAN ) ), ( notb ? NOTRAN :
489 ( ( TrB == CCOTRAN ) ? COTRAN : TRAN ) ), *M, *N, *K,
490 ((char *)ALPHA), ((char *)A), Ai, Aj, Ad, ((char *)B), Bi,
491 Bj, Bd, ((char *)BETA), ((char *)C), Ci, Cj, Cd );
492 }
493 else
494 {
495 PB_CpgemmAC( type, &DirAB, &DirBC, ( nota ? NOTRAN :
496 ( ( TrA == CCOTRAN ) ? COTRAN : TRAN ) ), ( notb ? NOTRAN :
497 ( ( TrB == CCOTRAN ) ? COTRAN : TRAN ) ), *M, *N, *K,
498 ((char *)ALPHA), ((char *)A), Ai, Aj, Ad, ((char *)B), Bi,
499 Bj, Bd, ((char *)BETA), ((char *)C), Ci, Cj, Cd );
500 }
501/*
502* Restore the BLACS topologies when necessary.
503*/
504 if( ForceTop )
505 {
506 rtopsave = *PB_Ctop( &ctxt, &OpR, ROW, &rtopsave );
507 ctopsave = *PB_Ctop( &ctxt, &OpC, COLUMN, &ctopsave );
508 }
509/*
510* End of PCGEMM
511*/
512}
#define Int
Definition Bconfig.h:22
#define REAL_PART
Definition pblas.h:139
#define F2C_CHAR(a)
Definition pblas.h:124
#define CBRATIO
Definition pblas.h:37
#define C2F_CHAR(a)
Definition pblas.h:125
#define IMAG_PART
Definition pblas.h:140
char * F_CHAR_T
Definition pblas.h:122
#define TOP_GET
Definition PBblacs.h:50
#define COLUMN
Definition PBblacs.h:45
#define TOP_IRING
Definition PBblacs.h:52
#define CTOP_SRING
Definition PBblacs.h:29
#define TOP_DEFAULT
Definition PBblacs.h:51
#define CCOMBINE
Definition PBblacs.h:24
#define ROW
Definition PBblacs.h:46
#define CBCAST
Definition PBblacs.h:23
void Cblacs_gridinfo()
#define CTOP_IRING
Definition PBblacs.h:27
#define CTOP_DRING
Definition PBblacs.h:28
#define NOTRAN
Definition PBblas.h:44
#define ALL
Definition PBblas.h:50
#define TRAN
Definition PBblas.h:46
#define CBACKWARD
Definition PBblas.h:39
#define NOCONJG
Definition PBblas.h:45
#define CNOTRAN
Definition PBblas.h:18
#define COTRAN
Definition PBblas.h:48
#define CTRAN
Definition PBblas.h:20
#define CCOTRAN
Definition PBblas.h:22
#define CFORWARD
Definition PBblas.h:38
#define pcgemm_
Definition PBpblas.h:148
#define pilaenv_
Definition PBpblas.h:44
#define CTXT_
Definition PBtools.h:38
#define MAX(a_, b_)
Definition PBtools.h:77
#define MB_
Definition PBtools.h:43
void PB_Cabort()
#define ONE
Definition PBtools.h:64
void PB_Cchkmat()
void PB_Cwarn()
char * PB_Ctop()
void PB_Cplapad()
void PB_Cplascal()
#define RSRC_
Definition PBtools.h:45
void PB_CargFtoC()
#define CSRC_
Definition PBtools.h:46
PBTYP_T * PB_Cctypeset()
void PB_CpgemmAB()
#define ZERO
Definition PBtools.h:66
void PB_CpgemmAC()
void PB_CpgemmBC()
#define Mupcase(C)
Definition PBtools.h:83
#define DLEN_
Definition PBtools.h:48
#define NB_
Definition PBtools.h:44
#define DNROC(n_, nb_, p_)
Definition PBtools.h:111
char type
Definition pblas.h:331
char * zero
Definition pblas.h:335