ScaLAPACK 2.1  2.1
ScaLAPACK: Scalable Linear Algebra PACKage
PB_CVMswp.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 int PB_CVMswp( PBTYP_T * TYPE, PB_VM_T * VM, char * VROCS, char * ROCS,
21  char * TRANS, int MN, char * X, int INCX, char * Y,
22  int INCY )
23 #else
24 int PB_CVMswp( TYPE, VM, VROCS, ROCS, TRANS, MN, X, INCX, Y, INCY )
25 /*
26 * .. Scalar Arguments ..
27 */
28  int INCX, INCY, MN;
29 /*
30 * .. Array Arguments ..
31 */
32  char * VROCS, * ROCS, * TRANS;
33  PBTYP_T * TYPE;
34  PB_VM_T * VM;
35  char * X, * Y;
36 #endif
37 {
38 /*
39 * Purpose
40 * =======
41 *
42 * PB_CVMswp swaps a one-dimensional distributed vector X with another
43 * one-dimensional distributed vector Y. This operation is triggered by
44 * a virtual distributed array.
45 *
46 * Arguments
47 * =========
48 *
49 * TYPE (local input) pointer to a PBTYP_T structure
50 * On entry, TYPE is a pointer to a structure of type PBTYP_T,
51 * that contains type information (See pblas.h).
52 *
53 * VM (local input) pointer to a PB_VM_T structure
54 * On entry, VM is a pointer to a structure of type PB_VM_T,
55 * that contains the virtual matrix information (see pblas.h).
56 *
57 * VROCS (local input) pointer to CHAR
58 * On entry, VROCS specifies if the rows or columns of the vir-
59 * tual distributed array grid should be used for the swapping
60 * operation as follows:
61 * VROCS = 'R' or 'r', the rows should be used,
62 * VROCS = 'C' or 'c', the columns should be used.
63 *
64 * ROCS (local input) pointer to CHAR
65 * On entry, ROCS specifies if rows or columns should be swap-
66 * ped as follows:
67 * ROCS = 'R' or 'r', rows should be swapped,
68 * ROCS = 'C' or 'c', columns should be swapped.
69 *
70 * TRANS (local input) pointer to CHAR
71 * On entry, TRANS specifies if transposition should occur du-
72 * ring the swapping operation as follows:
73 * TRANS = 'N' or 'n', natural swapping,
74 * otherwise, transposed swapping.
75 *
76 * MN (local input) INTEGER
77 * On entry, MN specifies the number of rows or columns to be
78 * swapped. MN must be at least zero.
79 *
80 * X (local input/local output) pointer to CHAR
81 * On entry, X points to an array of dimension at least
82 * ( 1 + ( n - 1 )*abs( INCX ) ) where n is IMBLOC+(MBLKS-2)*MB+
83 * LMB when VROCS is 'R' or 'r', and INBLOC+(NBLKS-2)*NB+LNB
84 * otherwise. Before entry, the incremented array X must contain
85 * the vector x. On exit, the entries of the incremented array X
86 * are exchanged with the entries of the incremented array Y.
87 *
88 * INCX (local input) INTEGER
89 * On entry, INCX specifies the increment for the elements of X.
90 * INCX must not be zero.
91 *
92 * Y (local input/local output) pointer to CHAR
93 * On entry, Y points to an array of dimension at least
94 * ( 1 + ( n - 1 )*abs( INCY ) ) where n is IMBLOC+(MBLKS-2)*MB+
95 * LMB when VROCS is 'C' or 'c', and INBLOC+(NBLKS-2)*NB+LNB
96 * otherwise. Before entry, the incremented array Y must contain
97 * the vector y. On exit, the entries of the incremented array Y
98 * are exchanged with the entries of the incremented array X.
99 *
100 * INCY (local input) INTEGER
101 * On entry, INCY specifies the increment for the elements of Y.
102 * INCY must not be zero.
103 *
104 * -- Written on April 1, 1998 by
105 * Antoine Petitet, University of Tennessee, Knoxville 37996, USA.
106 *
107 * ---------------------------------------------------------------------
108 */
109 /*
110 * .. Local Scalars ..
111 */
112  int GoEast, GoSouth, Xinc, Yinc, ilow, imbloc, inbloc, iupp, kb,
113  lcmt, lcmt00, lmbloc, lnbloc, low, mb, mblkd, mblks, mbloc,
114  nb, nblkd, nblks, nbloc, notran, npcol, npq=0, nprow, pmb,
115  qnb, rows, size, tmp1, tmp2, upp;
116  char * Xptrd, * Yptrd;
117 /* ..
118 * .. Executable Statements ..
119 *
120 */
121  mblks = VM->mblks; nblks = VM->nblks;
122 /*
123 * Quick return if I don't own any blocks.
124 */
125  if( ( mblks == 0 ) || ( nblks == 0 ) ) return( 0 );
126 /*
127 * Retrieve the contents of VM structure fields
128 */
129  lcmt00 = VM->lcmt00;
130  imbloc = VM->imbloc; mb = VM->mb; lmbloc = VM->lmbloc; upp = VM->upp;
131  iupp = VM->iupp; nprow = VM->nprow;
132  inbloc = VM->inbloc; nb = VM->nb; lnbloc = VM->lnbloc; low = VM->low;
133  ilow = VM->ilow; npcol = VM->npcol;
134 
135  notran = ( Mupcase( TRANS[0] ) == CNOTRAN );
136 
137  size = TYPE->size;
138  rows = ( Mupcase( ROCS[0] ) == CROW );
139 
140  if( Mupcase( VROCS[0] ) == CROW )
141  {
142 /*
143 * (un)packing using rows of virtual matrix
144 */
145  if( rows )
146  {
147 /*
148 * (un)packing rows of mn by k array A.
149 */
150  Xinc = size;
151  Yinc = ( notran ? size : INCY * size );
152  }
153  else
154  {
155 /*
156 * (un)packing columns of k by mn array A
157 */
158  Xinc = INCX * size;
159  Yinc = ( notran ? INCY * size : size );
160  }
161  kb = MN;
162 /*
163 * From the (un)packing point of view the only valuable shortcut is when the
164 * virtual grid and the blocks are square, and the offset is zero or the grid
165 * is 1x1.
166 */
167  if( ( ( lcmt00 == 0 ) && ( VM->imb1 == VM->inb1 ) && ( mb == nb ) &&
168  ( nprow == npcol ) ) || ( ( nprow == 1 ) && ( npcol == 1 ) ) )
169  {
170  if( VM->prow == VM->pcol )
171  {
172  npq = ( ( mblks < 2 ) ? imbloc :
173  imbloc + ( mblks - 2 ) * mb + lmbloc );
174  npq = MIN( npq, kb );
175  if( rows ) TYPE->Fswap( &npq, X, &INCX, Y, &INCY );
176  else TYPE->Fswap( &npq, X, &INCX, Y, &INCY );
177  }
178  return( npq );
179  }
180  pmb = nprow * mb;
181  qnb = npcol * nb;
182 /*
183 * Handle separately the first row and/or column of the LCM table. Update the
184 * LCM value of the curent block lcmt00, as well as the number of rows and
185 * columns mblks and nblks remaining in the LCM table.
186 */
187  GoSouth = ( lcmt00 > iupp );
188  GoEast = ( lcmt00 < ilow );
189 
190  if( !( GoSouth ) && !( GoEast ) )
191  {
192 /*
193 * The upper left block owns diagonal entries lcmt00 >= ilow && lcmt00 <= iupp
194 */
195  if( lcmt00 >= 0 )
196  {
197  tmp1 = imbloc - lcmt00; tmp1 = MAX( 0, tmp1 );
198  tmp2 = MIN( tmp1, inbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
199  TYPE->Fswap( &tmp2, X+lcmt00*Xinc, &INCX, Y, &INCY );
200  }
201  else
202  {
203  tmp1 = inbloc + lcmt00; tmp1 = MAX( 0, tmp1 );
204  tmp2 = MIN( tmp1, imbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
205  TYPE->Fswap( &tmp2, X, &INCX, Y-lcmt00*Yinc, &INCY );
206  }
207  if( ( kb -= tmp2 ) == 0 ) return( npq );
208 /*
209 * Decide whether one should go south or east in the table: Go east if
210 * the block below the current one only owns lower entries. If this block,
211 * however, owns diagonals, then go south.
212 */
213  GoSouth = !( GoEast = ( ( lcmt00 - ( iupp - upp + pmb ) ) < ilow ) );
214  }
215 
216  if( GoSouth )
217  {
218 /*
219 * Go one step south in the LCM table. Adjust the current LCM value as well as
220 * the pointer to X. The pointer to Y remains unchanged.
221 */
222  lcmt00 -= iupp - upp + pmb; mblks--; X += imbloc * Xinc;
223 /*
224 * While there are blocks remaining that own upper entries, keep going south.
225 * Adjust the current LCM value as well as the pointer to X accordingly.
226 */
227  while( mblks && ( lcmt00 > upp ) )
228  { lcmt00 -= pmb; mblks--; X += mb * Xinc; }
229 /*
230 * Return if no more row in the LCM table.
231 */
232  if( mblks <= 0 ) return( npq );
233 /*
234 * lcmt00 <= upp. The current block owns either diagonals or lower entries.
235 * Save the current position in the LCM table. After this column has been
236 * completely taken care of, re-start from this row and the next column of
237 * the LCM table.
238 */
239  lcmt = lcmt00; mblkd = mblks; Xptrd = X;
240 
241  while( mblkd && ( lcmt >= ilow ) )
242  {
243 /*
244 * A block owning diagonals lcmt00 >= ilow && lcmt00 <= upp has been found.
245 */
246  mbloc = ( ( mblkd == 1 ) ? lmbloc : mb );
247  if( lcmt >= 0 )
248  {
249  tmp1 = mbloc - lcmt; tmp1 = MAX( 0, tmp1 );
250  tmp2 = MIN( tmp1, inbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
251  TYPE->Fswap( &tmp2, Xptrd+lcmt*Xinc, &INCX, Y, &INCY );
252  }
253  else
254  {
255  tmp1 = inbloc + lcmt; tmp1 = MAX( 0, tmp1 );
256  tmp2 = MIN( tmp1, mbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
257  TYPE->Fswap( &tmp2, Xptrd, &INCX, Y-lcmt*Yinc, &INCY );
258  }
259  if( ( kb -= tmp2 ) == 0 ) return( npq );
260 /*
261 * Keep going south until there are no more blocks owning diagonals
262 */
263  lcmt -= pmb; mblkd--; Xptrd += mbloc * Xinc;
264  }
265 /*
266 * I am done with the first column of the LCM table. Go to the next column.
267 */
268  lcmt00 += low - ilow + qnb; nblks--; Y += inbloc * Yinc;
269  }
270  else if( GoEast )
271  {
272 /*
273 * Go one step east in the LCM table. Adjust the current LCM value as
274 * well as the pointer to Y. The pointer to X remains unchanged.
275 */
276  lcmt00 += low - ilow + qnb; nblks--; Y += inbloc * Yinc;
277 /*
278 * While there are blocks remaining that own lower entries, keep going east
279 * in the LCM table. Adjust the current LCM value as well as the pointer to
280 * Y accordingly.
281 */
282  while( nblks && ( lcmt00 < low ) )
283  { lcmt00 += qnb; nblks--; Y += nb * Yinc; }
284 /*
285 * Return if no more column in the LCM table.
286 */
287  if( nblks <= 0 ) return( npq );
288 /*
289 * lcmt00 >= low. The current block owns either diagonals or upper entries. Save
290 * the current position in the LCM table. After this row has been completely
291 * taken care of, re-start from this column and the next row of the LCM table.
292 */
293  lcmt = lcmt00; nblkd = nblks; Yptrd = Y;
294 
295  while( nblkd && ( lcmt <= iupp ) )
296  {
297 /*
298 * A block owning diagonals lcmt00 >= low && lcmt00 <= iupp has been found.
299 */
300  nbloc = ( ( nblkd == 1 ) ? lnbloc : nb );
301  if( lcmt >= 0 )
302  {
303  tmp1 = imbloc - lcmt; tmp1 = MAX( 0, tmp1 );
304  tmp2 = MIN( tmp1, nbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
305  TYPE->Fswap( &tmp2, X+lcmt*Xinc, &INCX, Yptrd, &INCY );
306  }
307  else
308  {
309  tmp1 = nbloc + lcmt; tmp1 = MAX( 0, tmp1 );
310  tmp2 = MIN( tmp1, imbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
311  TYPE->Fswap( &tmp2, X, &INCX, Yptrd-lcmt*Yinc, &INCY );
312  }
313  if( ( kb -= tmp2 ) == 0 ) return( npq );
314 /*
315 * Keep going east until there are no more blocks owning diagonals.
316 */
317  lcmt += qnb; nblkd--; Yptrd += nbloc * Yinc;
318  }
319 /*
320 * I am done with the first row of the LCM table. Go to the next row.
321 */
322  lcmt00 -= iupp - upp + pmb; mblks--; X += imbloc * Xinc;
323  }
324 /*
325 * Loop over the remaining columns of the LCM table.
326 */
327  do
328  {
329 /*
330 * If the current block does not have diagonal elements, find the closest one in
331 * the LCM table having some.
332 */
333  if( ( lcmt00 < low ) || ( lcmt00 > upp ) )
334  {
335  while( mblks && nblks )
336  {
337  while( mblks && ( lcmt00 > upp ) )
338  { lcmt00 -= pmb; mblks--; X += mb * Xinc; }
339  if( lcmt00 >= low ) break;
340  while( nblks && ( lcmt00 < low ) )
341  { lcmt00 += qnb; nblks--; Y += nb * Yinc; }
342  if( lcmt00 <= upp ) break;
343  }
344  }
345  if( !mblks || !nblks ) return( npq );
346 /*
347 * The current block owns diagonals. Save the current position in the LCM table.
348 * After this column has been completely taken care of, re-start from this row
349 * and the next column in the LCM table.
350 */
351  nbloc = ( ( nblks == 1 ) ? lnbloc : nb );
352  lcmt = lcmt00; mblkd = mblks; Xptrd = X;
353 
354  while( mblkd && lcmt >= low )
355  {
356 /*
357 * A block owning diagonals lcmt00 >= low && lcmt00 <= upp has been found.
358 */
359  mbloc = ( ( mblkd == 1 ) ? lmbloc : mb );
360  if( lcmt >= 0 )
361  {
362  tmp1 = mbloc - lcmt; tmp1 = MAX( 0, tmp1 );
363  tmp2 = MIN( tmp1, nbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
364  TYPE->Fswap( &tmp2, Xptrd+lcmt*Xinc, &INCX, Y, &INCY );
365  }
366  else
367  {
368  tmp1 = nbloc + lcmt; tmp1 = MAX( 0, tmp1 );
369  tmp2 = MIN( tmp1, mbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
370  TYPE->Fswap( &tmp2, Xptrd, &INCX, Y-lcmt*Yinc, &INCY );
371  }
372  if( ( kb -= tmp2 ) == 0 ) return( npq );
373 /*
374 * Keep going south until there are no more blocks owning diagonals
375 */
376  lcmt -= pmb; mblkd--; Xptrd += mbloc * Xinc;
377  }
378 /*
379 * I am done with this column of the LCM table. Go to the next column ...
380 */
381  lcmt00 += qnb; nblks--; Y += nbloc * Yinc;
382 /*
383 * ... until there are no more columns.
384 */
385  } while( nblks > 0 );
386 /*
387 * Return the number of diagonals found.
388 */
389  return( npq );
390  }
391  else
392  {
393 /*
394 * (un)packing using columns of virtual matrix
395 */
396  if( rows )
397  {
398 /*
399 * (un)packing rows of mn by k array A
400 */
401  Xinc = size;
402  Yinc = ( notran ? size : INCY * size );
403  }
404  else
405  {
406 /*
407 * (un)packing columns of k by mn array A
408 */
409  Xinc = INCX * size;
410  Yinc = ( notran ? INCY * size : size );
411  }
412  kb = MN;
413 /*
414 * From the (un)packing point of view the only valuable shortcut is when the
415 * virtual grid and the blocks are square, and the offset is zero or the grid
416 * is 1x1.
417 */
418  if( ( ( lcmt00 == 0 ) && ( VM->imb1 == VM->inb1 ) && ( mb == nb ) &&
419  ( nprow == npcol ) ) || ( ( nprow == 1 ) && ( npcol == 1 ) ) )
420  {
421  if( VM->prow == VM->pcol )
422  {
423  npq = ( ( nblks < 2 ) ? inbloc :
424  inbloc + ( nblks - 2 ) * nb + lnbloc );
425  npq = MIN( npq, kb );
426  if( rows ) TYPE->Fswap( &npq, X, &INCX, Y, &INCY );
427  else TYPE->Fswap( &npq, X, &INCX, Y, &INCY );
428  }
429  return( npq );
430  }
431  pmb = nprow * mb;
432  qnb = npcol * nb;
433 /*
434 * Handle separately the first row and/or column of the LCM table. Update the
435 * LCM value of the curent block lcmt00, as well as the number of rows and
436 * columns mblks and nblks remaining in the LCM table.
437 */
438  GoSouth = ( lcmt00 > iupp );
439  GoEast = ( lcmt00 < ilow );
440 
441  if( !( GoSouth ) && !( GoEast ) )
442  {
443 /*
444 * The upper left block owns diagonal entries lcmt00 >= ilow && lcmt00 <= iupp
445 */
446  if( lcmt00 >= 0 )
447  {
448  tmp1 = imbloc - lcmt00; tmp1 = MAX( 0, tmp1 );
449  tmp2 = MIN( tmp1, inbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
450  TYPE->Fswap( &tmp2, X, &INCX, Y+lcmt00*Yinc, &INCY );
451  }
452  else
453  {
454  tmp1 = inbloc + lcmt00; tmp1 = MAX( 0, tmp1 );
455  tmp2 = MIN( tmp1, imbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
456  TYPE->Fswap( &tmp2, X-lcmt00*Xinc, &INCX, Y, &INCY );
457  }
458  if( ( kb -= tmp2 ) == 0 ) return( npq );
459 /*
460 * Decide whether one should go south or east in the table: Go east if
461 * the block below the current one only owns lower entries. If this block,
462 * however, owns diagonals, then go south.
463 */
464  GoSouth = !( GoEast = ( ( lcmt00 - ( iupp - upp + pmb ) ) < ilow ) );
465  }
466 
467  if( GoSouth )
468  {
469 /*
470 * Go one step south in the LCM table. Adjust the current LCM value as well as
471 * the pointer to Y. The pointer to X remains unchanged.
472 */
473  lcmt00 -= iupp - upp + pmb; mblks--; Y += imbloc * Yinc;
474 /*
475 * While there are blocks remaining that own upper entries, keep going south.
476 * Adjust the current LCM value as well as the pointer to Y accordingly.
477 */
478  while( mblks && ( lcmt00 > upp ) )
479  { lcmt00 -= pmb; mblks--; Y += mb * Yinc; }
480 /*
481 * Return if no more row in the LCM table.
482 */
483  if( mblks <= 0 ) return( npq );
484 /*
485 * lcmt00 <= upp. The current block owns either diagonals or lower entries.
486 * Save the current position in the LCM table. After this column has been
487 * completely taken care of, re-start from this row and the next column of
488 * the LCM table.
489 */
490  lcmt = lcmt00; mblkd = mblks; Yptrd = Y;
491 
492  while( mblkd && ( lcmt >= ilow ) )
493  {
494 /*
495 * A block owning diagonals lcmt00 >= ilow && lcmt00 <= upp has been found.
496 */
497  mbloc = ( ( mblkd == 1 ) ? lmbloc : mb );
498  if( lcmt >= 0 )
499  {
500  tmp1 = mbloc - lcmt; tmp1 = MAX( 0, tmp1 );
501  tmp2 = MIN( tmp1, inbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
502  TYPE->Fswap( &tmp2, X, &INCX, Yptrd+lcmt*Yinc, &INCY );
503  }
504  else
505  {
506  tmp1 = inbloc + lcmt; tmp1 = MAX( 0, tmp1 );
507  tmp2 = MIN( tmp1, mbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
508  TYPE->Fswap( &tmp2, X-lcmt*Xinc, &INCX, Yptrd, &INCY );
509  }
510  if( ( kb -= tmp2 ) == 0 ) return( npq );
511 /*
512 * Keep going south until there are no more blocks owning diagonals
513 */
514  lcmt -= pmb; mblkd--; Yptrd += mbloc * Yinc;
515  }
516 /*
517 * I am done with the first column of the LCM table. Go to the next column.
518 */
519  lcmt00 += low - ilow + qnb; nblks--; X += inbloc * Xinc;
520  }
521  else if( GoEast )
522  {
523 /*
524 * Go one step east in the LCM table. Adjust the current LCM value as
525 * well as the pointer to X. The pointer to Y remains unchanged.
526 */
527  lcmt00 += low - ilow + qnb; nblks--; X += inbloc * Xinc;
528 /*
529 * While there are blocks remaining that own lower entries, keep going east
530 * in the LCM table. Adjust the current LCM value as well as the pointer to
531 * X accordingly.
532 */
533  while( nblks && ( lcmt00 < low ) )
534  { lcmt00 += qnb; nblks--; X += nb * Xinc; }
535 /*
536 * Return if no more column in the LCM table.
537 */
538  if( nblks <= 0 ) return( npq );
539 /*
540 * lcmt00 >= low. The current block owns either diagonals or upper entries. Save
541 * the current position in the LCM table. After this row has been completely
542 * taken care of, re-start from this column and the next row of the LCM table.
543 */
544  lcmt = lcmt00; nblkd = nblks; Xptrd = X;
545 
546  while( nblkd && ( lcmt <= iupp ) )
547  {
548 /*
549 * A block owning diagonals lcmt00 >= low && lcmt00 <= iupp has been found.
550 */
551  nbloc = ( ( nblkd == 1 ) ? lnbloc : nb );
552  if( lcmt >= 0 )
553  {
554  tmp1 = imbloc - lcmt; tmp1 = MAX( 0, tmp1 );
555  tmp2 = MIN( tmp1, nbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
556  TYPE->Fswap( &tmp2, Xptrd, &INCX, Y+lcmt*Yinc, &INCY );
557  }
558  else
559  {
560  tmp1 = nbloc + lcmt; tmp1 = MAX( 0, tmp1 );
561  tmp2 = MIN( tmp1, imbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
562  TYPE->Fswap( &tmp2, Xptrd-lcmt*Xinc, &INCX, Y, &INCY );
563  }
564  if( ( kb -= tmp2 ) == 0 ) return( npq );
565 /*
566 * Keep going east until there are no more blocks owning diagonals.
567 */
568  lcmt += qnb; nblkd--; Xptrd += nbloc * Xinc;
569  }
570 /*
571 * I am done with the first row of the LCM table. Go to the next row.
572 */
573  lcmt00 -= iupp - upp + pmb; mblks--; Y += imbloc * Yinc;
574  }
575 /*
576 * Loop over the remaining columns of the LCM table.
577 */
578  do
579  {
580 /*
581 * If the current block does not have diagonal elements, find the closest one in
582 * the LCM table having some.
583 */
584  if( ( lcmt00 < low ) || ( lcmt00 > upp ) )
585  {
586  while( mblks && nblks )
587  {
588  while( mblks && ( lcmt00 > upp ) )
589  { lcmt00 -= pmb; mblks--; Y += mb * Yinc; }
590  if( lcmt00 >= low ) break;
591  while( nblks && ( lcmt00 < low ) )
592  { lcmt00 += qnb; nblks--; X += nb * Xinc; }
593  if( lcmt00 <= upp ) break;
594  }
595  }
596  if( !( mblks ) || !( nblks ) ) return( npq );
597 /*
598 * The current block owns diagonals. Save the current position in the LCM table.
599 * After this column has been completely taken care of, re-start from this row
600 * and the next column in the LCM table.
601 */
602  nbloc = ( ( nblks == 1 ) ? lnbloc : nb );
603  lcmt = lcmt00; mblkd = mblks; Yptrd = Y;
604 /*
605 * A block owning diagonals lcmt00 >= low && lcmt00 <= upp has been found.
606 */
607  while( mblkd && lcmt >= low )
608  {
609  mbloc = ( ( mblkd == 1 ) ? lmbloc : mb );
610  if( lcmt >= 0 )
611  {
612  tmp1 = mbloc - lcmt; tmp1 = MAX( 0, tmp1 );
613  tmp2 = MIN( tmp1, nbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
614  TYPE->Fswap( &tmp2, X, &INCX, Yptrd+lcmt*Yinc, &INCY );
615  }
616  else
617  {
618  tmp1 = nbloc + lcmt; tmp1 = MAX( 0, tmp1 );
619  tmp2 = MIN( tmp1, mbloc ); npq += ( tmp2 = MIN( tmp2, kb ) );
620  TYPE->Fswap( &tmp2, X-lcmt*Xinc, &INCX, Yptrd, &INCY );
621  }
622  if( ( kb -= tmp2 ) == 0 ) return( npq );
623 /*
624 * Keep going south until there are no more blocks owning diagonals
625 */
626  lcmt -= pmb; mblkd--; Yptrd += mbloc * Yinc;
627  }
628 /*
629 * I am done with this column of the LCM table. Go to the next column ...
630 */
631  lcmt00 += qnb; nblks--; X += nbloc * Xinc;
632 /*
633 * ... until there are no more columns.
634 */
635  } while( nblks > 0 );
636 /*
637 * Return the number of diagonals found.
638 */
639  return( npq );
640  }
641 /*
642 * End of PB_CVMswp
643 */
644 }
TYPE
#define TYPE
Definition: clamov.c:7
PB_VM_T::imb1
int imb1
Definition: pblas.h:438
PB_VM_T::pcol
int pcol
Definition: pblas.h:456
PB_VM_T::lcmt00
int lcmt00
Definition: pblas.h:435
PB_VM_T::inbloc
int inbloc
Definition: pblas.h:450
PB_VM_T::iupp
int iupp
Definition: pblas.h:443
PB_VM_T::imbloc
int imbloc
Definition: pblas.h:439
PB_VM_T::prow
int prow
Definition: pblas.h:445
PB_VM_T::inb1
int inb1
Definition: pblas.h:449
PB_CVMswp
int PB_CVMswp(PBTYP_T *TYPE, PB_VM_T *VM, char *VROCS, char *ROCS, char *TRANS, int MN, char *X, int INCX, char *Y, int INCY)
Definition: PB_CVMswp.c:24
PB_VM_T::low
int low
Definition: pblas.h:455
PB_VM_T::npcol
int npcol
Definition: pblas.h:457
PB_VM_T::mblks
int mblks
Definition: pblas.h:442
PB_VM_T::lmbloc
int lmbloc
Definition: pblas.h:441
CROW
#define CROW
Definition: PBblacs.h:21
PB_VM_T::upp
int upp
Definition: pblas.h:444
PB_VM_T::nprow
int nprow
Definition: pblas.h:446
CNOTRAN
#define CNOTRAN
Definition: PBblas.h:18
PB_VM_T::nblks
int nblks
Definition: pblas.h:453
PB_VM_T
Definition: pblas.h:432
MIN
#define MIN(a_, b_)
Definition: PBtools.h:76
PB_VM_T::lnbloc
int lnbloc
Definition: pblas.h:452
PB_VM_T::ilow
int ilow
Definition: pblas.h:454
MAX
#define MAX(a_, b_)
Definition: PBtools.h:77
PBTYP_T
Definition: pblas.h:325
Mupcase
#define Mupcase(C)
Definition: PBtools.h:83
PB_VM_T::mb
int mb
Definition: pblas.h:440
PB_VM_T::nb
int nb
Definition: pblas.h:451