SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
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__
20void PB_CVMupdate( PB_VM_T * VM, Int K, Int * II, Int * JJ )
21#else
22void 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
414l_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}
#define Int
Definition Bconfig.h:22
void PB_CVMupdate()
Int lnbloc
Definition pblas.h:456
Int low
Definition pblas.h:459
Int iupp
Definition pblas.h:447
Int npcol
Definition pblas.h:461
Int nprow
Definition pblas.h:450
Int lcmt00
Definition pblas.h:439
Int inbloc
Definition pblas.h:454
Int ilow
Definition pblas.h:458
Int nblks
Definition pblas.h:457
Int mp
Definition pblas.h:441
Int imbloc
Definition pblas.h:443
Int nq
Definition pblas.h:452
Int lmbloc
Definition pblas.h:445
Int nb
Definition pblas.h:455
Int mblks
Definition pblas.h:446
Int mb
Definition pblas.h:444
Int upp
Definition pblas.h:448