SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
PB_Cpdot11.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__
20void PB_Cpdot11( PBTYP_T * TYPE, Int N, char * DOT,
21 char * X, Int IX, Int JX, Int * DESCX, Int INCX,
22 char * Y, Int IY, Int JY, Int * DESCY, Int INCY,
23 VVDOT_T FDOT )
24#else
25void PB_Cpdot11( TYPE, N, DOT, X, IX, JX, DESCX, INCX, Y, IY, JY, DESCY,
26 INCY, FDOT )
27/*
28* .. Scalar Arguments ..
29*/
30 Int INCX, INCY, IX, IY, JX, JY, N;
31 char * DOT;
32 PBTYP_T * TYPE;
33 VVDOT_T FDOT;
34/*
35* .. Array Arguments ..
36*/
37 Int * DESCX, * DESCY;
38 char * X, * Y;
39#endif
40{
41/*
42* Purpose
43* =======
44*
45* PB_Cpdot11 forms the dot product of two subvectors,
46*
47* DOT := sub( X )**T * sub( Y ) or DOT := sub( X )**H * sub( Y ),
48*
49* where
50*
51* sub( X ) denotes X(IX,JX:JX+N-1) if INCX = M_X,
52* X(IX:IX+N-1,JX) if INCX = 1 and INCX <> M_X, and,
53*
54* sub( Y ) denotes Y(IY,JY:JY+N-1) if INCY = M_Y,
55* Y(IY:IY+N-1,JY) if INCY = 1 and INCY <> M_Y.
56*
57* One subvector at least is assumed to be degenerated.
58*
59* Notes
60* =====
61*
62* A description vector is associated with each 2D block-cyclicly dis-
63* tributed matrix. This vector stores the information required to
64* establish the mapping between a matrix entry and its corresponding
65* process and memory location.
66*
67* In the following comments, the character _ should be read as
68* "of the distributed matrix". Let A be a generic term for any 2D
69* block cyclicly distributed matrix. Its description vector is DESC_A:
70*
71* NOTATION STORED IN EXPLANATION
72* ---------------- --------------- ------------------------------------
73* DTYPE_A (global) DESCA[ DTYPE_ ] The descriptor type.
74* CTXT_A (global) DESCA[ CTXT_ ] The BLACS context handle, indicating
75* the NPROW x NPCOL BLACS process grid
76* A is distributed over. The context
77* itself is global, but the handle
78* (the integer value) may vary.
79* M_A (global) DESCA[ M_ ] The number of rows in the distribu-
80* ted matrix A, M_A >= 0.
81* N_A (global) DESCA[ N_ ] The number of columns in the distri-
82* buted matrix A, N_A >= 0.
83* IMB_A (global) DESCA[ IMB_ ] The number of rows of the upper left
84* block of the matrix A, IMB_A > 0.
85* INB_A (global) DESCA[ INB_ ] The number of columns of the upper
86* left block of the matrix A,
87* INB_A > 0.
88* MB_A (global) DESCA[ MB_ ] The blocking factor used to distri-
89* bute the last M_A-IMB_A rows of A,
90* MB_A > 0.
91* NB_A (global) DESCA[ NB_ ] The blocking factor used to distri-
92* bute the last N_A-INB_A columns of
93* A, NB_A > 0.
94* RSRC_A (global) DESCA[ RSRC_ ] The process row over which the first
95* row of the matrix A is distributed,
96* NPROW > RSRC_A >= 0.
97* CSRC_A (global) DESCA[ CSRC_ ] The process column over which the
98* first column of A is distributed.
99* NPCOL > CSRC_A >= 0.
100* LLD_A (local) DESCA[ LLD_ ] The leading dimension of the local
101* array storing the local blocks of
102* the distributed matrix A,
103* IF( Lc( 1, N_A ) > 0 )
104* LLD_A >= MAX( 1, Lr( 1, M_A ) )
105* ELSE
106* LLD_A >= 1.
107*
108* Let K be the number of rows of a matrix A starting at the global in-
109* dex IA,i.e, A( IA:IA+K-1, : ). Lr( IA, K ) denotes the number of rows
110* that the process of row coordinate MYROW ( 0 <= MYROW < NPROW ) would
111* receive if these K rows were distributed over NPROW processes. If K
112* is the number of columns of a matrix A starting at the global index
113* JA, i.e, A( :, JA:JA+K-1, : ), Lc( JA, K ) denotes the number of co-
114* lumns that the process MYCOL ( 0 <= MYCOL < NPCOL ) would receive if
115* these K columns were distributed over NPCOL processes.
116*
117* The values of Lr() and Lc() may be determined via a call to the func-
118* tion PB_Cnumroc:
119* Lr( IA, K ) = PB_Cnumroc( K, IA, IMB_A, MB_A, MYROW, RSRC_A, NPROW )
120* Lc( JA, K ) = PB_Cnumroc( K, JA, INB_A, NB_A, MYCOL, CSRC_A, NPCOL )
121*
122* Arguments
123* =========
124*
125* TYPE (local input) pointer to a PBTYP_T structure
126* On entry, TYPE is a pointer to a structure of type PBTYP_T,
127* that contains type information (See pblas.h).
128*
129* N (global input) INTEGER
130* On entry, N specifies the length of the subvectors to be
131* multiplied. N must be at least zero.
132*
133* DOT (local output) pointer to CHAR
134* On exit, DOT specifies the dot product of the two subvectors
135* sub( X ) and sub( Y ) only in their scope (See below for fur-
136* ther details).
137*
138* X (local input) pointer to CHAR
139* On entry, X is an array of dimension (LLD_X, Kx), where LLD_X
140* is at least MAX( 1, Lr( 1, IX ) ) when INCX = M_X and
141* MAX( 1, Lr( 1, IX+N-1 ) ) otherwise, and, Kx is at least
142* Lc( 1, JX+N-1 ) when INCX = M_X and Lc( 1, JX ) otherwise.
143* Before entry, this array contains the local entries of the
144* matrix X.
145*
146* IX (global input) INTEGER
147* On entry, IX specifies X's global row index, which points to
148* the beginning of the submatrix sub( X ).
149*
150* JX (global input) INTEGER
151* On entry, JX specifies X's global column index, which points
152* to the beginning of the submatrix sub( X ).
153*
154* DESCX (global and local input) INTEGER array
155* On entry, DESCX is an integer array of dimension DLEN_. This
156* is the array descriptor for the matrix X.
157*
158* INCX (global input) INTEGER
159* On entry, INCX specifies the global increment for the
160* elements of X. Only two values of INCX are supported in
161* this version, namely 1 and M_X. INCX must not be zero.
162*
163* Y (local input) pointer to CHAR
164* On entry, Y is an array of dimension (LLD_Y, Ky), where LLD_Y
165* is at least MAX( 1, Lr( 1, IY ) ) when INCY = M_Y and
166* MAX( 1, Lr( 1, IY+N-1 ) ) otherwise, and, Ky is at least
167* Lc( 1, JY+N-1 ) when INCY = M_Y and Lc( 1, JY ) otherwise.
168* Before entry, this array contains the local entries of the
169* matrix Y.
170*
171* IY (global input) INTEGER
172* On entry, IY specifies Y's global row index, which points to
173* the beginning of the submatrix sub( Y ).
174*
175* JY (global input) INTEGER
176* On entry, JY specifies Y's global column index, which points
177* to the beginning of the submatrix sub( Y ).
178*
179* DESCY (global and local input) INTEGER array
180* On entry, DESCY is an integer array of dimension DLEN_. This
181* is the array descriptor for the matrix Y.
182*
183* INCY (global input) INTEGER
184* On entry, INCY specifies the global increment for the
185* elements of Y. Only two values of INCY are supported in
186* this version, namely 1 and M_Y. INCY must not be zero.
187*
188* FDOT (local input) pointer to a function of type VVDOT
189* On entry, FDOT points to a subroutine that computes the local
190* dot product of two vectors.
191*
192* Further Details
193* ===============
194*
195* When the result of a vector-oriented PBLAS call is a scalar, this
196* scalar is set only within the process scope which owns the vector(s)
197* being operated on. Let sub( X ) be a generic term for the input vec-
198* tor(s). Then, the processes owning the correct the answer is determi-
199* ned as follows: if an operation involves more than one vector, the
200* processes receiving the result will be the union of the following set
201* of processes for each vector:
202*
203* If N = 1, M_X = 1 and INCX = 1, then one cannot determine if a pro-
204* cess row or process column owns the vector operand, therefore only
205* the process owning sub( X ) receives the correct result;
206*
207* If INCX = M_X, then sub( X ) is a vector distributed over a process
208* row. Each process in this row receives the result;
209*
210* If INCX = 1, then sub( X ) is a vector distributed over a process
211* column. Each process in this column receives the result;
212*
213* -- Written on April 1, 1998 by
214* Antoine Petitet, University of Tennessee, Knoxville 37996, USA.
215*
216* ---------------------------------------------------------------------
217*/
218/*
219* .. Local Scalars ..
220*/
221 char Xscope, Yscope, * top;
222 Int RRorCC, Xcol, Xii, XisD, XisOne, XisR, XisRow, Xjj, Xld,
223 Xlinc, XmyprocD, XmyprocR, XprocD, XprocR, Xrow, Ycol, Yii,
224 YisD, YisOne, YisR, YisRow, Yjj, YmyprocD, YmyprocR, YprocD,
225 YprocR, Yrow, cdst, ctxt, ione=1, mycol, myrow, npcol, nprow,
226 rdst;
227/*
228* .. Local Arrays ..
229*/
230 Int dbuf[DLEN_];
231 char * buf = NULL;
232/* ..
233* .. Executable Statements ..
234*
235*/
236/*
237* Retrieve process grid information
238*/
239 Cblacs_gridinfo( ( ctxt = DESCX[ CTXT_ ] ), &nprow, &npcol, &myrow, &mycol );
240/*
241* Retrieve sub( X )'s local information: Xii, Xjj, Xrow, Xcol ...
242*/
243 PB_Cinfog2l( IX, JX, DESCX, nprow, npcol, myrow, mycol, &Xii, &Xjj,
244 &Xrow, &Xcol );
245 if( ( XisRow = ( INCX == DESCX[ M_ ] ) ) != 0 )
246 {
247 Xld = DESCX[ LLD_ ]; Xlinc = Xld;
248 XprocD = Xcol; XmyprocD = mycol; XprocR = Xrow; XmyprocR = myrow;
249 XisR = ( ( Xrow == -1 ) || ( nprow == 1 ) );
250 XisD = ( ( Xcol >= 0 ) && ( npcol > 1 ) );
251 }
252 else
253 {
254 Xld = DESCX[ LLD_ ]; Xlinc = 1;
255 XprocD = Xrow; XmyprocD = myrow; XprocR = Xcol; XmyprocR = mycol;
256 XisR = ( ( Xcol == -1 ) || ( npcol == 1 ) );
257 XisD = ( ( Xrow >= 0 ) && ( nprow > 1 ) );
258 }
259 XisOne = ( ( N == 1 ) && ( DESCX[ M_ ] == 1 ) );
260/*
261* Retrieve sub( Y )'s local information: Yii, Yjj, Yrow, Ycol ...
262*/
263 PB_Cinfog2l( IY, JY, DESCY, nprow, npcol, myrow, mycol, &Yii, &Yjj,
264 &Yrow, &Ycol );
265 if( ( YisRow = ( INCY == DESCY[ M_ ] ) ) != 0 )
266 {
267 YprocD = Ycol; YmyprocD = mycol; YprocR = Yrow; YmyprocR = myrow;
268 YisR = ( ( Yrow == -1 ) || ( nprow == 1 ) );
269 YisD = ( ( Ycol >= 0 ) && ( npcol > 1 ) );
270 }
271 else
272 {
273 YprocD = Yrow; YmyprocD = myrow; YprocR = Ycol; YmyprocR = mycol;
274 YisR = ( ( Ycol == -1 ) || ( npcol == 1 ) );
275 YisD = ( ( Yrow >= 0 ) && ( nprow > 1 ) );
276 }
277 YisOne = ( ( N == 1 ) && ( DESCY[ M_ ] == 1 ) );
278/*
279* Are sub( X ) and sub( Y ) both row or column vectors ?
280*/
281 RRorCC = ( ( XisRow && YisRow ) || ( !( XisRow ) && !( YisRow ) ) );
282/*
283* Copy sub( Y ) in sub( X )'s scope
284*/
285 PB_Cdescset( dbuf, 1, 1, 1, 1, 1, 1, Xrow, Xcol, ctxt, 1 );
286 buf = PB_Cmalloc( TYPE->size );
287 PB_Cpaxpby( TYPE, NOCONJG, 1, 1, TYPE->one, Y, IY, JY, DESCY, ( YisRow ?
288 ROW : COLUMN ), TYPE->zero, buf, 0, 0, dbuf, ( XisRow ? ROW :
289 COLUMN ) );
290/*
291* Compute the dot product in sub( X )'s scope
292*/
293 if( XisR || ( XmyprocR == XprocR ) )
294 {
295 if( ( XisD && ( XmyprocD == XprocD ) ) || ( !XisD ) )
296 FDOT( &ione, DOT, Mptr( X, Xii, Xjj, Xld, TYPE->size ), &Xlinc, buf,
297 &ione );
298 if( XisD && !XisOne )
299 {
300 Xscope = ( XisRow ? CROW : CCOLUMN );
301 top = PB_Ctop( &ctxt, COMBINE, &Xscope, TOP_GET );
302 TYPE->Cgsum2d( ctxt, &Xscope, top, 1, 1, DOT, 1, -1, 0 );
303 }
304 }
305 if( buf ) free( buf );
306/*
307* sub( X ) or sub( Y ) is a degenerated vector
308*/
309 if( XisD && XisOne )
310 {
311/*
312* Since XisOne, sub( X ) must be a row vector
313*/
314 if( XisR )
315 {
316/*
317* sub( X ) resides in one process column ( *, XprocD )
318*/
319 if( RRorCC )
320 {
321/*
322* sub( Y ) is a row vector as well
323*/
324 if( YisR || YmyprocR == YprocR )
325 {
326/*
327* I am a process row owning sub( Y )
328*/
329 if( YisD && YisOne )
330 {
331/*
332* sub( Y ) resides in a process column ( *, YprocD )
333*/
334 if( XprocD != YprocD )
335 {
336 if( XmyprocD == XprocD )
337 TYPE->Cgesd2d( ctxt, 1, 1, DOT, 1, XmyprocR, YprocD );
338 else if( YmyprocD == YprocD )
339 TYPE->Cgerv2d( ctxt, 1, 1, DOT, 1, XmyprocR, XprocD );
340 }
341 }
342 else
343 {
344/*
345* Every process in those rows needs the answer
346*/
347 top = PB_Ctop( &ctxt, BCAST, ROW, TOP_GET );
348 if( XmyprocD == XprocD )
349 TYPE->Cgebs2d( ctxt, ROW, top, 1, 1, DOT, 1 );
350 else
351 TYPE->Cgebr2d( ctxt, ROW, top, 1, 1, DOT, 1, XmyprocR,
352 XprocD );
353 }
354 }
355 }
356 else
357 {
358/*
359* sub( Y ) is a column vector
360*/
361 if( YisR )
362 {
363/*
364* sub( Y ) resides in every process column
365*/
366 top = PB_Ctop( &ctxt, BCAST, ROW, TOP_GET );
367 if( XmyprocD == XprocD )
368 TYPE->Cgebs2d( ctxt, ROW, top, 1, 1, DOT, 1 );
369 else
370 TYPE->Cgebr2d( ctxt, ROW, top, 1, 1, DOT, 1, XmyprocR,
371 XprocD );
372 }
373 else if( XprocD != YprocR )
374 {
375/*
376* sub( Y ) resides in process column YprocR
377*/
378 if( XmyprocD == XprocD )
379 TYPE->Cgesd2d( ctxt, 1, 1, DOT, 1, XmyprocR, YprocR );
380 if( YmyprocR == YprocR )
381 TYPE->Cgerv2d( ctxt, 1, 1, DOT, 1, XmyprocR, XprocD );
382 }
383 }
384 }
385 else
386 {
387/*
388* sub( X ) resides in one process ( XprocR, XprocD )
389*/
390 if( YisD && YisOne )
391 {
392/*
393* sub( Y ) resides in one process ( YprocR, YprocD ) if it is not replicated,
394* and in one process column ( *, YprocD ) otherwise
395*/
396 if( ( XprocD != YprocD ) || ( !YisR && ( XprocR != YprocR ) ) )
397 {
398/*
399* ( XprocR, XprocD ) sends DOT to ( YprocR, YprocD ) if sub( Y ) is not repli-
400* cated, and to ( XprocR, YprocD ) otherwise
401*/
402 rdst = ( YisR ? XprocR : YprocR );
403 if( ( XmyprocR == XprocR ) && ( XmyprocD == XprocD ) )
404 TYPE->Cgesd2d( ctxt, 1, 1, DOT, 1, rdst, YprocD );
405 if( ( YmyprocR == rdst ) && ( YmyprocD == YprocD ) )
406 TYPE->Cgerv2d( ctxt, 1, 1, DOT, 1, XprocR, XprocD );
407 }
408
409 if( YisR && ( YmyprocD == YprocD ) )
410 {
411/*
412* Broadcast DOT within process column owning sub( Y )
413*/
414 top = PB_Ctop( &ctxt, BCAST, COLUMN, TOP_GET );
415 if( XmyprocR == XprocR )
416 TYPE->Cgebs2d( ctxt, COLUMN, top, 1, 1, DOT, 1 );
417 else
418 TYPE->Cgebr2d( ctxt, COLUMN, top, 1, 1, DOT, 1, XprocR,
419 YprocD );
420 }
421 }
422 else if( !YisR )
423 {
424/*
425* sub( Y ) resides in one process row or column
426*/
427 if( YisRow ) { Yscope = CROW; rdst = YprocR; cdst = XprocD; }
428 else { Yscope = CCOLUMN; rdst = XprocR; cdst = YprocR; }
429/*
430* ( XprocR, XprocD ) sends DOT to ( YprocR, XprocD ) if sub( Y ) is a row
431* vector and to ( XprocR, YprocR ) otherwise. If RRorCC, then YisRow and the
432* send occurs iff XprocR != YprocR; Otherwise !YisRow, and the send occurs
433* iff XprocD is not YprocR.
434*/
435 if( ( RRorCC && ( XprocR != YprocR ) ) ||
436 ( !( RRorCC ) && ( XprocD != YprocR ) ) )
437 {
438 if( ( XmyprocR == XprocR ) && ( XmyprocD == XprocD ) )
439 TYPE->Cgesd2d( ctxt, 1, 1, DOT, 1, rdst, cdst );
440 if( ( myrow == rdst ) && ( mycol == cdst ) )
441 TYPE->Cgerv2d( ctxt, 1, 1, DOT, 1, XprocR, XprocD );
442 }
443/*
444* Broadcast the result in sub( Y )'s scope
445*/
446 if( ( myrow == rdst ) && ( mycol == cdst ) )
447 {
448 top = PB_Ctop( &ctxt, BCAST, &Yscope, TOP_GET );
449 TYPE->Cgebs2d( ctxt, &Yscope, top, 1, 1, DOT, 1 );
450 }
451 else if( ( YisRow && ( myrow == rdst ) ) ||
452 ( !( YisRow ) && ( mycol == cdst ) ) )
453 {
454 top = PB_Ctop( &ctxt, BCAST, &Yscope, TOP_GET );
455 TYPE->Cgebr2d( ctxt, &Yscope, top, 1, 1, DOT, 1, rdst, cdst );
456 }
457 }
458 else
459 {
460/*
461* Every process in the grid needs the answer
462*/
463 top = PB_Ctop( &ctxt, BCAST, ALL, TOP_GET );
464 if( ( XmyprocR == XprocR ) && ( XmyprocD == XprocD ) )
465 {
466 TYPE->Cgebs2d( ctxt, ALL, top, 1, 1, DOT, 1 );
467 }
468 else
469 {
470 TYPE->Cgebr2d( ctxt, ALL, top, 1, 1, DOT, 1, XprocR, XprocD );
471 }
472 }
473 }
474 }
475 else
476 {
477/*
478* If XisR, then the result has already been sent in every process of the grid
479*/
480 if( XisR ) return;
481
482 if( RRorCC )
483 {
484/*
485* If YisD && YisOne => YisRow => XisRow, communication orthogonal to sub( X )'s
486* direction: only process column YprocD is involved.
487*/
488 if( YisD && YisOne && ( YmyprocD != YprocD ) ) return;
489
490 if( YisR )
491 {
492/*
493* YisR and sub( Y ) is // to sub( X ) => bcast orthogonal to sub( X ) direction
494*/
495 if( XisRow )
496 {
497 top = PB_Ctop( &ctxt, BCAST, COLUMN, TOP_GET );
498 if( XmyprocR == XprocR )
499 TYPE->Cgebs2d( ctxt, COLUMN, top, 1, 1, DOT, 1 );
500 else
501 TYPE->Cgebr2d( ctxt, COLUMN, top, 1, 1, DOT, 1, XprocR,
502 XmyprocD );
503 }
504 else
505 {
506 top = PB_Ctop( &ctxt, BCAST, ROW, TOP_GET );
507 if( XmyprocR == XprocR )
508 TYPE->Cgebs2d( ctxt, ROW, top, 1, 1, DOT, 1 );
509 else
510 TYPE->Cgebr2d( ctxt, ROW, top, 1, 1, DOT, 1, XmyprocD,
511 XprocR );
512 }
513 }
514 else if( XprocR != YprocR )
515 {
516/*
517* Send from one column/row to another if they differ
518*/
519 if( XisRow )
520 {
521 if( XmyprocR == XprocR )
522 TYPE->Cgesd2d( ctxt, 1, 1, DOT, 1, YprocR, YmyprocD );
523 if( YmyprocR == YprocR )
524 TYPE->Cgerv2d( ctxt, 1, 1, DOT, 1, XprocR, XmyprocD );
525 }
526 else
527 {
528 if( XmyprocR == XprocR )
529 TYPE->Cgesd2d( ctxt, 1, 1, DOT, 1, YmyprocD, YprocR );
530 if( YmyprocR == YprocR )
531 TYPE->Cgerv2d( ctxt, 1, 1, DOT, 1, XmyprocD, XprocR );
532 }
533 }
534 }
535 else
536 {
537/*
538* If XisRow then !YisRow and thus bcast result in all rows if YisR or in
539* process row YprocR otherwise. If !YisD || ( YisD && !YisOne ), then result
540* should be sent in the same processes because they span a row or a column of
541* the grid.
542*/
543 if( XisRow || !( YisD ) || ( YisD && !( YisOne ) ) )
544 {
545 if( YisR || YmyprocR == YprocR )
546 {
547 if( XisRow )
548 {
549 top = PB_Ctop( &ctxt, BCAST, COLUMN, TOP_GET );
550 if( XmyprocR == XprocR )
551 TYPE->Cgebs2d( ctxt, COLUMN, top, 1, 1, DOT, 1 );
552 else
553 TYPE->Cgebr2d( ctxt, COLUMN, top, 1, 1, DOT, 1, XprocR,
554 XmyprocD );
555 }
556 else
557 {
558 top = PB_Ctop( &ctxt, BCAST, ROW, TOP_GET );
559 if( XmyprocR == XprocR )
560 TYPE->Cgebs2d( ctxt, ROW, top, 1, 1, DOT, 1 );
561 else
562 TYPE->Cgebr2d( ctxt, ROW, top, 1, 1, DOT, 1, XmyprocD,
563 XprocR );
564 }
565 }
566 }
567 else if( XprocR != YprocD )
568 {
569/*
570* YisD && YisOne => YisRow => !XisRow, so the column of processes owning
571* sub( X ) send the result to the column YprocD. The process rows involved
572* in the operation depend on YisR.
573*/
574 if( YisR || YmyprocR == YprocR )
575 {
576 if( XmyprocR == XprocR )
577 {
578 TYPE->Cgesd2d( ctxt, 1, 1, DOT, 1, YmyprocR, YprocD );
579 }
580 if( YmyprocD == YprocD )
581 {
582 TYPE->Cgerv2d( ctxt, 1, 1, DOT, 1, YmyprocR, XprocR );
583 }
584 }
585 }
586 }
587 }
588/*
589* End of PB_Cpdot11
590*/
591}
#define Int
Definition Bconfig.h:22
F_VOID_FCT(* VVDOT_T)()
Definition pblas.h:290
#define CCOLUMN
Definition PBblacs.h:20
#define TOP_GET
Definition PBblacs.h:50
#define COLUMN
Definition PBblacs.h:45
#define COMBINE
Definition PBblacs.h:49
#define CROW
Definition PBblacs.h:21
#define ROW
Definition PBblacs.h:46
void Cblacs_gridinfo()
#define BCAST
Definition PBblacs.h:48
#define ALL
Definition PBblas.h:50
#define NOCONJG
Definition PBblas.h:45
#define CTXT_
Definition PBtools.h:38
char * PB_Cmalloc()
void PB_Cinfog2l()
void PB_Cpdot11()
#define Mptr(a_, i_, j_, lda_, siz_)
Definition PBtools.h:132
#define LLD_
Definition PBtools.h:47
char * PB_Ctop()
void PB_Cdescset()
#define M_
Definition PBtools.h:39
#define DLEN_
Definition PBtools.h:48
void PB_Cpaxpby()
#define TYPE
Definition clamov.c:7