ScaLAPACK 2.1  2.1
ScaLAPACK: Scalable Linear Algebra PACKage
PB_CVMupdate.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_CVMupdate( PB_VM_T * VM, int K, int * II, int * JJ )
21 #else
22 void PB_CVMupdate( VM, K, II, JJ )
23 /*
24 * .. Scalar Arguments ..
25 */
26  int * II, * JJ, K;
27  PB_VM_T * VM;
28 #endif
29 {
30 /*
31 * Purpose
32 * =======
33 *
34 * PB_CVMupdate updates the local information of an m by n local array
35 * owned by the process of relative coordinates ( MRROW, MRCOL ). Note
36 * that if m or n is less or equal than zero, there is no data, in which
37 * case this process does not need the local information computed by
38 * this routine to proceed.
39 *
40 * Arguments
41 * =========
42 *
43 * VM (local input) pointer to a PB_VM_T structure
44 * On entry, VM is a pointer to a structure of type PB_VM_T,
45 * that contains the virtual matrix information (see pblas.h).
46 *
47 * K (global input) INTEGER
48 * On entry, K specifies the number of diagonal elements that
49 * have been used so far. K must be at least zero.
50 *
51 * II (local input/local output) INTEGER
52 * On entry, II specifies the local row index to be updated. On
53 * exit, II points to the local row owning the K+1 diagonal of
54 * this local block. On entry and on exit, II is at least zero.
55 *
56 * JJ (local input/local output) INTEGER
57 * On entry, JJ specifies the local column index to be updated.
58 * On exit, JJ points to the local column owning the K+1
59 * diagonal of this local block. On entry and on exit, JJ is at
60 * least zero.
61 *
62 * -- Written on April 1, 1998 by
63 * Antoine Petitet, University of Tennessee, Knoxville 37996, USA.
64 *
65 * ---------------------------------------------------------------------
66 */
67 /*
68 * .. Local Scalars ..
69 */
70  int GoEast, GoSouth, ilow, imbloc, inbloc, ioff, ioffd, iupp,
71  joff, joffd, lcmt, lcmt00, lmbloc, lnbloc, low, mb, mblkd,
72  mblks, mbloc, nb, nblkd, nblks, nbloc, npq=0, pmb, qnb,
73  tmp1, tmp2, upp;
74 /* ..
75 * .. Executable Statements ..
76 *
77 */
78  mblks = VM->mblks; nblks = VM->nblks;
79 /*
80 * Quick return if I don't own any blocks or if no diagonals were found.
81 */
82  if( ( K <= 0 ) || ( mblks == 0 ) || ( nblks == 0 ) ) return;
83 /*
84 * Handle the first block of rows or columns separately
85 */
86  ioff = *II;
87  joff = *JJ;
88 /*
89 * Retrieve the contents of VM structure fields
90 */
91  lcmt00 = VM->lcmt00;
92  imbloc = VM->imbloc; mb = VM->mb; lmbloc = VM->lmbloc;
93  iupp = VM->iupp; upp = VM->upp; pmb = VM->nprow * mb;
94  inbloc = VM->inbloc; nb = VM->nb; lnbloc = VM->lnbloc;
95  ilow = VM->ilow; low = VM->low; qnb = VM->npcol * nb;
96 /*
97 * Handle separately the first row and/or column of the LCM table. Update the
98 * LCM value of the curent block lcmt00, as well as the number of rows and
99 * columns mblks and nblks remaining in the LCM table.
100 */
101  GoSouth = ( lcmt00 > iupp );
102  GoEast = ( lcmt00 < ilow );
103 /*
104 * Go through the table looking for blocks owning diagonal entries.
105 */
106  if( !( GoSouth ) && !( GoEast ) )
107  {
108 /*
109 * The upper left block owns diagonal entries lcmt00 >= ilow && lcmt00 <= iupp
110 */
111  if( lcmt00 >= 0 )
112  {
113  npq = ( ( tmp2 = ( tmp1 = imbloc - lcmt00 ) > 0 ? tmp1 : 0 ) <
114  inbloc ? tmp2 : inbloc );
115  if( K < npq )
116  {
117  tmp1 = lcmt00 + K;
118  *II += tmp1;
119  iupp = ( imbloc -= tmp1 ) - 1;
120  if( mblks == 1 ) lmbloc = imbloc;
121  *JJ += K;
122  ilow = 1 - ( inbloc -= K );
123  if( nblks == 1 ) lnbloc = inbloc;
124  lcmt00 = 0;
125  goto l_end;
126  }
127  }
128  else
129  {
130  npq = ( ( tmp2 = ( tmp1 = inbloc + lcmt00 ) > 0 ? tmp1 : 0 ) >
131  imbloc ? imbloc : tmp2 );
132  if( K < npq )
133  {
134  tmp1 = lcmt00 - K;
135  *JJ -= tmp1;
136  ilow = 1 - ( inbloc += tmp1 );
137  if( nblks == 1 ) lnbloc = inbloc;
138  *II += K;
139  iupp = ( imbloc -= K ) - 1;
140  if( mblks == 1 ) lmbloc = imbloc;
141  lcmt00 = 0;
142  goto l_end;
143  }
144  }
145  K -= npq;
146 /*
147 * Decide whether one should go south or east in the table: Go east if the
148 * block below the current one only owns lower entries. If this block,
149 * however, owns diagonals, then go south.
150 */
151  GoSouth = !( GoEast = ( ( lcmt00 - ( iupp-upp+pmb ) ) < ilow ) );
152 /*
153 * Update the local indexes II and JJ
154 */
155  if( GoSouth ) *II += imbloc;
156  else *JJ += inbloc;
157  }
158 
159  if( GoSouth )
160  {
161 /*
162 * Go one step south in the LCM table. Adjust the current LCM value.
163 */
164  lcmt00 -= iupp - upp + pmb; mblks--; ioff += imbloc;
165 /*
166 * While there are blocks remaining that own upper entries, keep going south.
167 * Adjust the current LCM value accordingly.
168 */
169  while( mblks && ( lcmt00 > upp ) ) { lcmt00 -= pmb; mblks--; ioff += mb; }
170 /*
171 * Return if no more row in the LCM table.
172 */
173  if( mblks <= 0 ) goto l_end;
174 /*
175 * lcmt00 <= upp. The current block owns either diagonals or lower entries.
176 * Save the current position in the LCM table. After this column has been
177 * completely taken care of, re-start from this row and the next column of
178 * the LCM table.
179 */
180  lcmt = lcmt00; mblkd = mblks; mbloc = mb; ioffd = ioff;
181 
182  while( mblkd && ( lcmt >= ilow ) )
183  {
184 /*
185 * A block owning diagonals lcmt00 >= ilow && lcmt00 <= upp has been found.
186 */
187  if( mblkd == 1 ) mbloc = lmbloc;
188 
189  if( lcmt >= 0 )
190  {
191  npq = ( ( tmp2 = ( tmp1 = mbloc - lcmt ) > 0 ? tmp1 : 0 ) < inbloc ?
192  tmp2 : inbloc );
193  if( K < npq )
194  {
195  tmp1 = lcmt + K;
196  *II = ioffd + tmp1;
197  iupp = ( imbloc = mbloc - tmp1 ) - 1;
198  if( mblks == 1 ) lmbloc = imbloc;
199  *JJ = joff + K;
200  ilow = 1 - ( inbloc -= K );
201  if( nblks == 1 ) lnbloc = inbloc;
202  lcmt00 = 0;
203  goto l_end;
204  }
205  }
206  else
207  {
208  npq = ( ( tmp2 = ( tmp1 = inbloc + lcmt ) > 0 ? tmp1 : 0 ) > mbloc ?
209  mbloc : tmp2 );
210  if( K < npq )
211  {
212  tmp1 = lcmt - K;
213  *JJ = joff - tmp1;
214  ilow = 1 - ( inbloc += tmp1 );
215  if( nblks == 1 ) lnbloc = inbloc;
216  *II = ioffd + K;
217  iupp = ( imbloc = mbloc - K ) - 1;
218  if( mblks == 1 ) lmbloc = imbloc;
219  lcmt00 = 0;
220  goto l_end;
221  }
222  }
223 /*
224 * Keep going south until there are no more blocks owning diagonals
225 */
226  K -= npq;
227  lcmt00 = lcmt;
228  lcmt -= pmb;
229  mblks = mblkd--;
230  ioff = ioffd;
231  ioffd += mbloc;
232  }
233 /*
234 * I am done with the first column of the LCM table. Go to the next column.
235 */
236  lcmt00 += low - ilow + qnb; nblks--; joff += inbloc;
237 /*
238 * Update the local indexes II and JJ
239 */
240  *II = ioff;
241  *JJ = joff;
242  }
243  else if( GoEast )
244  {
245 /*
246 * Go one step east in the LCM table. Adjust the current LCM value.
247 */
248  lcmt00 += low - ilow + qnb; nblks--; joff += inbloc;
249 /*
250 * While there are blocks remaining that own lower entries, keep going east
251 * in the LCM table. Adjust the current LCM value.
252 */
253  while( nblks && ( lcmt00 < low ) ) { lcmt00 += qnb; nblks--; joff += nb; }
254 /*
255 * Return if no more column in the LCM table.
256 */
257  if( nblks <= 0 ) goto l_end;
258 /*
259 * lcmt00 >= low. The current block owns either diagonals or upper entries. Save
260 * the current position in the LCM table. After this row has been completely
261 * taken care of, re-start from this column and the next row of the LCM table.
262 */
263  lcmt = lcmt00; nblkd = nblks; nbloc = nb; joffd = joff;
264 
265  while( nblkd && ( lcmt <= iupp ) )
266  {
267 /*
268 * A block owning diagonals lcmt00 >= low && lcmt00 <= iupp has been found.
269 */
270  if( nblkd == 1 ) nbloc = lnbloc;
271 
272  if( lcmt >= 0 )
273  {
274  npq = ( ( tmp2 = ( tmp1 = imbloc - lcmt ) > 0 ? tmp1 : 0 ) < nbloc ?
275  tmp2 : nbloc );
276  if( K < npq )
277  {
278  tmp1 = lcmt + K;
279  *II = ioff + tmp1;
280  iupp = ( imbloc -= tmp1 ) - 1;
281  if( mblks == 1 ) lmbloc = imbloc;
282  *JJ = joffd + K;
283  ilow = 1 - ( inbloc = nbloc - K );
284  if( nblks == 1 ) lnbloc = inbloc;
285  lcmt00 = 0;
286  goto l_end;
287  }
288  }
289  else
290  {
291  npq = ( ( tmp2 = ( tmp1 = nbloc + lcmt ) > 0 ? tmp1 : 0 ) > imbloc ?
292  imbloc : tmp2 );
293  if( K < npq )
294  {
295  tmp1 = lcmt - K;
296  *JJ = joffd - tmp1;
297  ilow = 1 - ( inbloc = nbloc + tmp1 );
298  if( nblks == 1 ) lnbloc = inbloc;
299  *II = ioff + K;
300  iupp = ( imbloc -= K ) - 1;
301  if( mblks == 1 ) lmbloc = imbloc;
302  lcmt00 = 0;
303  goto l_end;
304  }
305  }
306 /*
307 * Keep going east until there are no more blocks owning diagonals.
308 */
309  K -= npq;
310  lcmt00 = lcmt;
311  lcmt += qnb;
312  nblks = nblkd--;
313  joff = joffd;
314  joffd += nbloc;
315  }
316 /*
317 * I am done with the first row of the LCM table. Go to the next row.
318 */
319  lcmt00 -= iupp - upp + pmb; mblks--; ioff += imbloc;
320 /*
321 * Update the local indexes II and JJ
322 */
323  *II = ioff;
324  *JJ = joff;
325  }
326 /*
327 * Loop over the remaining columns of the LCM table.
328 */
329  nbloc = nb;
330 
331  while( nblks )
332  {
333  if( nblks == 1 ) nbloc = lnbloc;
334 /*
335 * While there are blocks remaining that own upper entries, keep going south.
336 * Adjust the current LCM value accordingly.
337 */
338  while( mblks && ( lcmt00 > upp ) ) { lcmt00 -= pmb; mblks--; ioff += mb; }
339 /*
340 * Return if no more row in the LCM table.
341 */
342  if( mblks <= 0 ) goto l_end;
343 /*
344 * lcmt00 <= upp. The current block owns either diagonals or lower entries.
345 * Save the current position in the LCM table. After this column has been
346 * completely taken care of, re-start from this row and the next column of
347 * the LCM table.
348 */
349  lcmt = lcmt00; mblkd = mblks; mbloc = mb; ioffd = ioff;
350 
351  while( mblkd && ( lcmt >= low ) )
352  {
353 /*
354 * A block owning diagonals lcmt00 >= low && lcmt00 <= upp has been found.
355 */
356  if( mblkd == 1 ) mbloc = lmbloc;
357 
358  if( lcmt >= 0 )
359  {
360  npq = ( ( tmp2 = ( tmp1 = mbloc - lcmt ) > 0 ? tmp1 : 0 ) < nbloc ?
361  tmp2 : nbloc );
362  if( K < npq )
363  {
364  tmp1 = lcmt + K;
365  *II = ioffd + tmp1;
366  iupp = ( imbloc = mbloc - tmp1 ) - 1;
367  if( mblks == 1 ) lmbloc = imbloc;
368  *JJ = joff + K;
369  ilow = 1 - ( inbloc = nbloc - K );
370  if( nblks == 1 ) lnbloc = inbloc;
371  lcmt00 = 0;
372  goto l_end;
373  }
374  }
375  else
376  {
377  npq = ( ( tmp2 = ( tmp1 = nbloc + lcmt ) > 0 ? tmp1 : 0 ) > mbloc ?
378  mbloc : tmp2 );
379  if( K < npq )
380  {
381  tmp1 = lcmt - K;
382  *JJ = joff - tmp1;
383  ilow = 1 - ( inbloc = nbloc + tmp1 );
384  if( nblks == 1 ) lnbloc = inbloc;
385  *II = ioffd + K;
386  iupp = ( imbloc = mbloc - K ) - 1;
387  if( mblks == 1 ) lmbloc = imbloc;
388  lcmt00 = 0;
389  goto l_end;
390  }
391  }
392 /*
393 * Keep going south until there are no more blocks owning diagonals
394 */
395  K -= npq;
396  lcmt00 = lcmt;
397  lcmt -= pmb;
398  mblks = mblkd--;
399  ioff = ioffd;
400  ioffd += mbloc;
401  }
402 /*
403 * I am done with this column of the LCM table. Go to the next column until
404 * there are no more column in the table.
405 */
406  lcmt00 += qnb; nblks--; joff += nbloc;
407 /*
408 * Update the local indexes II and JJ
409 */
410  *II = ioff;
411  *JJ = joff;
412  }
413 
414 l_end:
415 /*
416 * Update the fields of the VM structure
417 */
418  VM->lcmt00 = lcmt00;
419  VM->mp = ( mblks >= 2 ? imbloc + ( mblks - 2 ) * mb + lmbloc :
420  ( mblks == 1 ? imbloc : 0 ) );
421  VM->imbloc = imbloc; VM->lmbloc = lmbloc; VM->mblks = mblks; VM->iupp = iupp;
422  VM->nq = ( nblks >= 2 ? inbloc + ( nblks - 2 ) * nb + lnbloc :
423  ( nblks == 1 ? inbloc : 0 ) );
424  VM->inbloc = inbloc; VM->lnbloc = lnbloc; VM->nblks = nblks; VM->ilow = ilow;
425 /*
426 * End of PB_CVMupdate
427 */
428 }
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::mp
int mp
Definition: pblas.h:437
PB_VM_T::imbloc
int imbloc
Definition: pblas.h:439
PB_VM_T::low
int low
Definition: pblas.h:455
PB_VM_T::npcol
int npcol
Definition: pblas.h:457
PB_VM_T::nq
int nq
Definition: pblas.h:448
PB_VM_T::mblks
int mblks
Definition: pblas.h:442
PB_VM_T::lmbloc
int lmbloc
Definition: pblas.h:441
PB_VM_T::upp
int upp
Definition: pblas.h:444
PB_VM_T::nprow
int nprow
Definition: pblas.h:446
PB_VM_T::nblks
int nblks
Definition: pblas.h:453
PB_VM_T
Definition: pblas.h:432
PB_VM_T::lnbloc
int lnbloc
Definition: pblas.h:452
PB_VM_T::ilow
int ilow
Definition: pblas.h:454
PB_CVMupdate
void PB_CVMupdate(PB_VM_T *VM, int K, int *II, int *JJ)
Definition: PB_CVMupdate.c:22
PB_VM_T::mb
int mb
Definition: pblas.h:440
PB_VM_T::nb
int nb
Definition: pblas.h:451