SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
PB_CVMcontig.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_CVMcontig( PB_VM_T * VM, Int * NRPQ, Int * NCPQ, Int * IOFF,
21 Int * JOFF )
22#else
23void PB_CVMcontig( VM, NRPQ, NCPQ, IOFF, JOFF )
24/*
25* .. Scalar Arguments ..
26*/
27 Int * IOFF, * JOFF, * NCPQ, * NRPQ;
28 PB_VM_T * VM;
29#endif
30{
31/*
32* Purpose
33* =======
34*
35* PB_CVMcontig computes the maximum number of contiguous rows and
36* columns corresponding to the first diagonals of the local virtual
37* matrix VM. This routine also returns the row and column offset of the
38* first diagonal entry.
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* NRPQ (local output) INTEGER
48* On exit, NRPQ specifies the number of contiguous rows corres-
49* ponding to the first diagonals of the local virtual matrix
50* VM. On exit, NRPQ is at least zero.
51*
52* NCPQ (local output) INTEGER
53* On exit, NCPQ specifies the number of contiguous columns cor-
54* responding to the first diagonals of the local virtual matrix
55* VM. On exit, NRPQ is at least zero.
56*
57* IOFF (local output) INTEGER
58* On exit, IOFF is the local row offset of the first row cor-
59* responding to a diagonal entry of the Virtual matrix VM. If
60* no diagonals are found, the value zero is returned. On exit,
61* IOFF is at least zero.
62*
63* JOFF (local output) INTEGER
64* On exit, JOFF is the local column offset of the first column
65* corresponding to a diagonal entry of the Virtual matrix VM.
66* If no diagonals are found, the value zero is returned. On
67* exit, JOFF is at least zero.
68*
69* -- Written on April 1, 1998 by
70* Antoine Petitet, University of Tennessee, Knoxville 37996, USA.
71*
72* ---------------------------------------------------------------------
73*/
74/*
75* .. Local Scalars ..
76*/
77 Int ColCont=1, FirstD=0, GoSouth, GoEast, RowCont=1, ilow, imbloc,
78 inbloc, iupp, lcmt, lcmtnn=0, lcmt00, lmbloc, lnbloc, low, mb,
79 mblks, mbloc, mcur=0, mcurd, md=0, nb, nblks, nbloc, ncur=0,
80 ncurd, nd=0, npq=0, pmb, qnb, tmp1, tmp2, upp;
81/* ..
82* .. Executable Statements ..
83*
84*/
85 *NRPQ = 0; *NCPQ = 0; *IOFF = 0; *JOFF = 0;
86 mblks = VM->mblks; nblks = VM->nblks;
87/*
88* Quick return if I don't own any blocks.
89*/
90 if( ( mblks == 0 ) || ( nblks == 0 ) ) return;
91/*
92* Retrieve the contents of VM structure fields
93*/
94 lcmt00 = VM->lcmt00;
95 imbloc = VM->imbloc; mb = VM->mb; lmbloc = VM->lmbloc;
96 iupp = VM->iupp; upp = VM->upp; pmb = VM->nprow * mb;
97 inbloc = VM->inbloc; nb = VM->nb; lnbloc = VM->lnbloc;
98 ilow = VM->ilow; low = VM->low; qnb = VM->npcol * nb;
99/*
100* Handle separately the first row and/or column of the LCM table. Update the
101* LCM value of the curent block lcmt00, as well as the coordinates of the
102* current entry in the LCM table (mcur,ncur).
103*/
104 GoSouth = ( lcmt00 > iupp );
105 GoEast = ( lcmt00 < ilow );
106/*
107* Go through the table looking for blocks owning diagonal entries.
108*/
109 if( !( GoSouth ) && !( GoEast ) )
110 {
111/*
112* The upper left block owns diagonal entries lcmt00 >= ilow && lcmt00 <= iupp
113* Compute the number of diagonals in this block as well as lcm value (lcntnn)
114* that its neighbor should have to preserve continuity.
115*/
116 if( lcmt00 >= 0 )
117 {
118 tmp2 = ( ( tmp1 = imbloc - lcmt00 ) > 0 ? tmp1 : 0 );
119 if( tmp2 < inbloc ) { npq = tmp2; lcmtnn = -npq; }
120 else if ( tmp2 == inbloc ) { npq = inbloc; lcmtnn = 0; }
121 else { npq = inbloc; lcmtnn = lcmt00 + npq; }
122 *IOFF += lcmt00;
123 }
124 else
125 {
126 tmp2 = ( ( tmp1 = inbloc + lcmt00 ) > 0 ? tmp1 : 0 );
127 if( tmp2 < imbloc ) { npq = tmp2; lcmtnn = npq; }
128 else if ( tmp2 == imbloc ) { npq = tmp2; lcmtnn = 0; }
129 else { npq = imbloc; lcmtnn = lcmt00 - npq; }
130 *JOFF -= lcmt00;
131 }
132/*
133* Save coordinates of last block owning diagonals. Set FirstD to one, since
134* a block owning diagonals has been found.
135*/
136 md = 0; nd = 0; FirstD = 1;
137/*
138* Those rows and columns are obviously contiguous
139*/
140 *NRPQ = *NCPQ = npq;
141/*
142* Decide whether one should go south or east in the table: Go east if the
143* block below the current one only owns lower entries. If this block, however,
144* owns diagonals, then go south.
145*/
146 GoSouth = !( GoEast = ( lcmt00 - iupp + upp - pmb < ilow ) );
147 }
148
149 if( GoSouth )
150 {
151/*
152* Go one step south in the LCM table. Adjust the current LCM value.
153*/
154 lcmt00 -= iupp - upp + pmb; mcur++;
155 if( !FirstD ) *IOFF += imbloc;
156/*
157* While there are blocks remaining that own upper entries, keep going south.
158* Adjust the current LCM value accordingly.
159*/
160 while( ( mcur < mblks ) && ( lcmt00 > upp ) )
161 {
162 lcmt00 -= pmb;
163 mcur++;
164 if( !FirstD ) *IOFF += mb;
165 }
166/*
167* Return if no more row in the LCM table.
168*/
169 if( mcur >= mblks ) goto l_end;
170/*
171* lcmt00 <= upp. The current block owns either diagonals or lower entries.
172* Save the current position in the LCM table. After this column has been
173* completely taken care of, re-start from this row and the next column of
174* the LCM table.
175*/
176 lcmt = lcmt00; mbloc = mb; mcurd = mcur;
177
178 while( ( mcurd < mblks ) && ( lcmt >= ilow ) )
179 {
180 if( mcurd == mblks-1 ) mbloc = lmbloc;
181/*
182* A block owning diagonals lcmt00 >= ilow && lcmt00 <= upp has been found.
183* If this is not the first one, update the booleans telling if the rows
184* and/or columns are contiguous.
185*/
186 if( FirstD )
187 {
188 RowCont = RowCont &&
189 ( ( ( mcurd == md+1 ) && ( lcmtnn <= 0 ) && ( lcmt <= 0 ) ) ||
190 ( ( mcurd == md ) && ( ncur == nd+1 ) && ( lcmtnn == lcmt ) ) );
191 ColCont = ColCont &&
192 ( ( ( ncur == nd+1 ) && ( lcmtnn >= 0 ) && ( lcmt >= 0 ) ) ||
193 ( ( ncur == nd ) && ( mcurd == md+1 ) && ( lcmtnn == lcmt ) ) );
194 }
195/*
196* Compute the number of diagonals in this block as well as lcm value (lcntnn)
197* that its neighbor should have to preserve continuity.
198*/
199 if( lcmt >= 0 )
200 {
201 tmp2 = ( ( tmp1 = mbloc - lcmt ) > 0 ? tmp1 : 0 );
202 if( tmp2 < inbloc ) { npq = tmp2; lcmtnn = -npq; }
203 else if ( tmp2 == inbloc ) { npq = inbloc; lcmtnn = 0; }
204 else { npq = inbloc; lcmtnn = lcmt + npq; }
205 if( !FirstD ) *IOFF += lcmt;
206 }
207 else
208 {
209 tmp2 = ( ( tmp1 = inbloc + lcmt ) > 0 ? tmp1 : 0 );
210 if( tmp2 < mbloc ) { npq = tmp2; lcmtnn = npq; }
211 else if ( tmp2 == mbloc ) { npq = tmp2; lcmtnn = 0; }
212 else { npq = mbloc; lcmtnn = lcmt - npq; }
213 if( !FirstD ) *JOFF -= lcmt;
214 }
215/*
216* Save coordinates of last block owning diagonals. Set FirstD to one, since
217* a block owning diagonals has been found.
218*/
219 md = mcurd; nd = ncur; FirstD = 1;
220/*
221* If rows (resp columns) are still contiguous, add those npq rows (resp.
222* columns).
223*/
224 if( RowCont ) *NRPQ += npq;
225 if( ColCont ) *NCPQ += npq;
226/*
227* Keep going south until there are no more blocks owning diagonals
228*/
229 lcmt00 = lcmt;
230 lcmt -= pmb;
231 mcur = mcurd++;
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; ncur++;
237 if( !FirstD ) *JOFF += inbloc;
238 }
239 else if( GoEast )
240 {
241/*
242* Go one step east in the LCM table. Adjust the current LCM value.
243*/
244 lcmt00 += low - ilow + qnb; ncur++;
245 if( !FirstD ) *JOFF += inbloc;
246/*
247* While there are blocks remaining that own lower entries, keep going east
248* in the LCM table. Adjust the current LCM value.
249*/
250 while( ( ncur < nblks ) && ( lcmt00 < low ) )
251 {
252 lcmt00 += qnb;
253 ncur++;
254 if( !FirstD ) *JOFF += nb;
255 }
256/*
257* Return if no more column in the LCM table.
258*/
259 if( ncur >= nblks ) goto l_end;
260/*
261* lcmt00 >= low. The current block owns either diagonals or upper entries. Save
262* the current position in the LCM table. After this row has been completely
263* taken care of, re-start from this column and the next row of the LCM table.
264*/
265 lcmt = lcmt00; nbloc = nb; ncurd = ncur;
266
267 while( ( ncurd < nblks ) && ( lcmt <= iupp ) )
268 {
269 if( ncurd == nblks-1 ) nbloc = lnbloc;
270/*
271* A block owning diagonals lcmt00 >= low && lcmt00 <= iupp has been found.
272* If this is not the first one, update the booleans telling if the rows
273* and/or columns are contiguous.
274*/
275 if( FirstD )
276 {
277 RowCont = RowCont &&
278 ( ( ( mcur == md+1 ) && ( lcmtnn <= 0 ) && ( lcmt <= 0 ) ) ||
279 ( ( mcur == md ) && ( ncurd == nd+1 ) && ( lcmtnn == lcmt ) ) );
280 ColCont = ColCont &&
281 ( ( ( ncurd == nd+1 ) && ( lcmtnn >= 0 ) && ( lcmt >= 0 ) ) ||
282 ( ( ncurd == nd ) && ( mcur == md+1 ) && ( lcmtnn == lcmt ) ) );
283 }
284/*
285* Compute the number of diagonals in this block as well as lcm value (lcntnn)
286* that its neighbor should have to preserve continuity.
287*/
288 if( lcmt >= 0 )
289 {
290 tmp2 = ( ( tmp1 = imbloc - lcmt ) > 0 ? tmp1 : 0 );
291 if( tmp2 < nbloc ) { npq = tmp2; lcmtnn = -npq; }
292 else if ( tmp2 == nbloc ) { npq = nbloc; lcmtnn = 0; }
293 else { npq = nbloc; lcmtnn = lcmt + npq; }
294 if( !FirstD ) *IOFF += lcmt;
295 }
296 else
297 {
298 tmp2 = ( ( tmp1 = nbloc + lcmt ) > 0 ? tmp1 : 0 );
299 if( tmp2 < imbloc ) { npq = tmp2; lcmtnn = npq; }
300 else if ( tmp2 == imbloc ) { npq = tmp2; lcmtnn = 0; }
301 else { npq = imbloc; lcmtnn = lcmt - npq; }
302 if( !FirstD ) *JOFF -= lcmt;
303 }
304/*
305* Save coordinates of last block owning diagonals. Set FirstD to one, since
306* a block owning diagonals has been found.
307*/
308 md = mcur; nd = ncurd; FirstD = 1;
309/*
310* If rows (resp columns) are still contiguous, add those npq rows (resp.
311* columns).
312*/
313 if( RowCont ) *NRPQ += npq;
314 if( ColCont ) *NCPQ += npq;
315/*
316* Keep going east until there are no more blocks owning diagonals.
317*/
318 lcmt00 = lcmt; lcmt += qnb; ncur = ncurd++;
319 }
320/*
321* I am done with the first row of the LCM table. Go to the next row.
322*/
323 lcmt00 -= iupp - upp + pmb; mcur++;
324 if( !FirstD ) *IOFF += imbloc;
325 }
326/*
327* Loop over the remaining columns of the LCM table.
328*/
329 nbloc = nb;
330
331 while( ( RowCont || ColCont ) && ( ncur < nblks ) )
332 {
333 if( ncur == 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( ( mcur < mblks ) && ( lcmt00 > upp ) )
339 {
340 lcmt00 -= pmb;
341 mcur++;
342 if( !FirstD ) *IOFF += mb;
343 }
344/*
345* Return if no more row in the LCM table.
346*/
347 if( mcur >= mblks ) goto l_end;
348/*
349* lcmt00 <= upp. The current block owns either diagonals or lower entries.
350* Save the current position in the LCM table. After this column has been
351* completely taken care of, re-start from this row and the next column of
352* the LCM table.
353*/
354 lcmt = lcmt00; mbloc = mb; mcurd = mcur;
355
356 while( ( mcurd < mblks ) && ( lcmt >= low ) )
357 {
358 if( mcurd == mblks-1 ) mbloc = lmbloc;
359/*
360* A block owning diagonals lcmt00 >= low && lcmt00 <= upp has been found.
361* If this is not the first one, update the booleans telling if the rows
362* and/or columns are contiguous.
363*/
364 if( FirstD )
365 {
366 RowCont = RowCont &&
367 ( ( ( mcurd == md+1 ) && ( lcmtnn <= 0 ) && ( lcmt <= 0 ) ) ||
368 ( ( mcurd == md ) && ( ncur == nd+1 ) && ( lcmtnn == lcmt ) ) );
369 ColCont = ColCont &&
370 ( ( ( ncur == nd+1 ) && ( lcmtnn >= 0 ) && ( lcmt >= 0 ) ) ||
371 ( ( ncur == nd ) && ( mcurd == md+1 ) && ( lcmtnn == lcmt ) ) );
372 }
373/*
374* Compute the number of diagonals in this block as well as lcm value (lcntnn)
375* that its neighbor should have to preserve continuity.
376*/
377 if( lcmt >= 0 )
378 {
379 tmp2 = ( ( tmp1 = mbloc - lcmt ) > 0 ? tmp1 : 0 );
380 if( tmp2 < nbloc ) { npq = tmp2; lcmtnn = -npq; }
381 else if ( tmp2 == nbloc ) { npq = nbloc; lcmtnn = 0; }
382 else { npq = nbloc; lcmtnn = lcmt + npq; }
383 if( !FirstD ) *IOFF += lcmt;
384 }
385 else
386 {
387 tmp2 = ( ( tmp1 = nbloc + lcmt ) > 0 ? tmp1 : 0 );
388 if( tmp2 < mbloc ) { npq = tmp2; lcmtnn = npq; }
389 else if ( tmp2 == mbloc ) { npq = tmp2; lcmtnn = 0; }
390 else { npq = mbloc; lcmtnn = lcmt - npq; }
391 if( !FirstD ) *JOFF -= lcmt;
392 }
393/*
394* Save coordinates of last block owning diagonals. Set FirstD to one, since
395* a block owning diagonals has been found.
396*/
397 md = mcurd; nd = ncur; FirstD = 1;
398/*
399* If rows (resp columns) are still contiguous, add those npq rows (resp.
400* columns).
401*/
402 if( RowCont ) *NRPQ += npq;
403 if( ColCont ) *NCPQ += npq;
404/*
405* Keep going south until there are no more blocks owning diagonals
406*/
407 lcmt00 = lcmt;
408 lcmt -= pmb;
409 mcur = mcurd++;
410 }
411/*
412* I am done with this column of the LCM table. Go to the next column until
413* there are no more column in the table.
414*/
415 lcmt00 += qnb; ncur++;
416 if( !FirstD ) *JOFF += nb;
417 }
418
419l_end:
420/*
421* If no diagonals were found, reset IOFF and JOFF to zero.
422*/
423 if( !FirstD ) { *IOFF = 0; *JOFF = 0; }
424/*
425* End of PB_CVMcontig
426*/
427}
#define Int
Definition Bconfig.h:22
void PB_CVMcontig()
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 imbloc
Definition pblas.h:443
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