ScaLAPACK 2.1  2.1
ScaLAPACK: Scalable Linear Algebra PACKage
pbchkvect.c
Go to the documentation of this file.
1 /* ---------------------------------------------------------------------
2 *
3 * -- PBLAS routine (version 1.5) --
4 * University of Tennessee, Knoxville, Oak Ridge National Laboratory,
5 * and University of California, Berkeley.
6 * March 17, 1995
7 *
8 * ---------------------------------------------------------------------
9 */
10 /*
11 * Include files
12 */
13 #include "tools.h"
14 
15 void pbchkvect( n, npos0, ix, jx, desc_X, incx, dpos0, iix, jjx, ixrow,
16  ixcol, nprow, npcol, myrow, mycol, info )
17 /*
18 * .. Scalar Arguments ..
19 */
20  int dpos0, * iix, incx, * info, ix, * ixcol, * ixrow, * jjx,
21  jx, myrow, mycol, npcol, nprow, n, npos0;
22 /*
23 * .. Array Arguments ..
24 */
25  int desc_X[];
26 {
27 /*
28 *
29 * Purpose
30 * =======
31 *
32 * pbchkvect checks the validity of a descriptor vector DESCX, the
33 * related global indexes IX, JX and the global increment INCX. It also
34 * computes the starting local indexes (IIX,JJX) corresponding to the
35 * submatrix starting globally at the entry pointed by (IX,JX).
36 * Moreover, this routine returns the coordinates in the grid of the
37 * process owning the global matrix entry of indexes (IX,JX), namely
38 * (IXROW,IXCOL). The routine prevents out-of-bound memory access
39 * by performing the appropriate MIN operation on iix and JJX. Finally,
40 * if an inconsistency is found among its parameters IX, JX, DESCX and
41 * INCX, the routine returns an error code in info.
42 *
43 * Arguments
44 * =========
45 *
46 * N (global input) INTEGER
47 * The length of the vector X being operated on.
48 *
49 * NPOS0 (global input) INTEGER
50 * Where in the calling routine's parameter list N appears.
51 *
52 * IX (global input) INTEGER
53 * X's global row index, which points to the beginning of the
54 * submatrix which is to be operated on.
55 *
56 * JX (global input) INTEGER
57 * X's global column index, which points to the beginning of
58 * the submatrix which is to be operated on.
59 *
60 * DESCX (global and local input) INTEGER array of dimension DLEN_.
61 * The array descriptor for the distributed matrix X.
62 *
63 * INCX (global input) INTEGER
64 * The global increment for the elements of X. Only two values
65 * of INCX are supported in this version, namely 1 and M_X.
66 * INCX must not be zero.
67 *
68 * DPOS0 (global input) INTEGER
69 * Where in the calling routine's parameter list DESCX
70 * appears. Note that we assume IX and JX are respectively 2
71 * and 1 entries behind DESCX, and INCX is 1 entry after DESCX.
72 *
73 * IIX (local output) pointer to INTEGER
74 * The local rows starting index of the submatrix.
75 *
76 * JJX (local output) pointer to INTEGER
77 * The local columns starting index of the submatrix.
78 *
79 * IXROW (global output) pointer to INTEGER
80 * The row coordinate of the process that possesses the first
81 * row and column of the submatrix.
82 *
83 * IXCOL (global output) pointer to INTEGER
84 * The column coordinate of the process that possesses the
85 * first row and column of the submatrix.
86 *
87 * NPROW (global input) INTEGER
88 * The total number of process rows over which the distributed
89 * matrix is distributed.
90 *
91 * NPCOL (global input) INTEGER
92 * The total number of process columns over which the
93 * distributed matrix is distributed.
94 *
95 * MYROW (local input) INTEGER
96 * The row coordinate of the process calling this routine.
97 *
98 * MYCOL (local input) INTEGER
99 * The column coordinate of the process calling this routine.
100 *
101 * INFO (local input/local output) INTEGER
102 * = 0: successful exit
103 * < 0: If the i-th argument is an array and the j-entry had
104 * an illegal value, then INFO = -(i*100+j), if the i-th
105 * argument is a scalar and had an illegal value, then
106 * INFO = -i.
107 *
108 * =====================================================================
109 *
110 * .. Parameters ..
111 */
112 #define DESCMULT 100
113 #define BIGNUM 10000
114 /* ..
115 * .. Local Scalars ..
116 */
117  int descpos, ExtraColBlock, ExtraRowBlock, icpos, ixpos,
118  jxpos, MyColBlock, MyColDist, MyRowBlock, MyRowDist,
119  NColBlock, np, npos, nq, NRowBlock;
120 /* ..
121 * .. External Functions ..
122 */
123  F_INTG_FCT numroc_();
124 /*
125 * .. Executable Statements ..
126 */
127  if( *info >= 0 )
128  *info = BIGNUM;
129  else if( *info < -DESCMULT )
130  *info = -(*info);
131  else
132  *info = -(*info) * DESCMULT;
133 /*
134 * Figure where in parameter list each parameter was, factoring in
135 * descriptor multiplier
136 */
137  npos = npos0 * DESCMULT;
138  ixpos = ( dpos0 - 2 ) * DESCMULT;
139  jxpos = ( dpos0 - 1 ) * DESCMULT;
140  icpos = ( dpos0 + 1 ) * DESCMULT;
141  descpos = dpos0 * DESCMULT + 1;
142 /*
143  * Check that we have a legal descriptor type
144  */
145  if(desc_X[DT_] != BLOCK_CYCLIC_2D) *info = MIN( *info, descpos + DT_ );
146 /*
147 * Check that matrix values make sense from local viewpoint
148 */
149  if( n < 0 )
150  *info = MIN( *info, npos );
151  else if( ix < 1 )
152  *info = MIN( *info, ixpos );
153  else if( jx < 1 )
154  *info = MIN( *info, jxpos );
155  else if( desc_X[MB_] < 1 )
156  *info = MIN( *info, descpos + MB_ );
157  else if( desc_X[NB_] < 1 )
158  *info = MIN( *info, descpos + NB_ );
159  else if( ( desc_X[RSRC_] < 0 ) || ( desc_X[RSRC_] >= nprow ) )
160  *info = MIN( *info, descpos + RSRC_ );
161  else if( ( desc_X[CSRC_] < 0 ) || ( desc_X[CSRC_] >= npcol ) )
162  *info = MIN( *info, descpos + CSRC_ );
163  else if( incx != 1 && incx != desc_X[M_] )
164  *info = MIN( *info, icpos );
165  else if( desc_X[LLD_] < 1 )
166  *info = MIN( *info, descpos + LLD_ );
167 
168  if( n == 0 )
169  {
170 /*
171 * NULL matrix, relax some checks
172 */
173  if( desc_X[M_] < 0 )
174  *info = MIN( *info, descpos + M_ );
175  if( desc_X[N_] < 0 )
176  *info = MIN( *info, descpos + N_ );
177  }
178  else
179  {
180 /*
181 * more rigorous checks for non-degenerate matrices
182 */
183  if( desc_X[M_] < 1 )
184  *info = MIN( *info, descpos + M_ );
185  else if( desc_X[N_] < 1 )
186  *info = MIN( *info, descpos + N_ );
187  else if( ( incx == desc_X[M_] ) && ( jx+n-1 > desc_X[N_] ) )
188  *info = MIN( *info, jxpos );
189  else if( ( incx == 1 ) && ( incx != desc_X[M_] ) &&
190  ( ix+n-1 > desc_X[M_] ) )
191  *info = MIN( *info, ixpos );
192  else
193  {
194  if( ix > desc_X[M_] )
195  *info = MIN( *info, ixpos );
196  else if( jx > desc_X[N_] )
197  *info = MIN( *info, jxpos );
198  }
199  }
200 /*
201 * Retrieve local information for vector X, and prepare output:
202 * set info = 0 if no error, and divide by DESCMULT if error is not
203 * in a descriptor entry.
204 */
205  if( *info == BIGNUM )
206  {
207  MyRowDist = ( myrow + nprow - desc_X[RSRC_] ) % nprow;
208  MyColDist = ( mycol + npcol - desc_X[CSRC_] ) % npcol;
209  NRowBlock = desc_X[M_] / desc_X[MB_];
210  NColBlock = desc_X[N_] / desc_X[NB_];
211  np = ( NRowBlock / nprow ) * desc_X[MB_];
212  nq = ( NColBlock / npcol ) * desc_X[NB_];
213  ExtraRowBlock = NRowBlock % nprow;
214  ExtraColBlock = NColBlock % npcol;
215 
216  ix--;
217  jx--;
218  MyRowBlock = ix / desc_X[MB_];
219  MyColBlock = jx / desc_X[NB_];
220  *ixrow = ( MyRowBlock + desc_X[RSRC_] ) % nprow;
221  *ixcol = ( MyColBlock + desc_X[CSRC_] ) % npcol;
222 
223  *iix = ( MyRowBlock / nprow + 1 ) * desc_X[MB_] + 1;
224  *jjx = ( MyColBlock / npcol + 1 ) * desc_X[NB_] + 1;
225 
226  if( MyRowDist >= ( MyRowBlock % nprow ) )
227  {
228  if( myrow == *ixrow )
229  *iix += ix % desc_X[MB_];
230  *iix -= desc_X[MB_];
231  }
232  if( MyRowDist < ExtraRowBlock )
233  np += desc_X[MB_];
234  else if( MyRowDist == ExtraRowBlock )
235  np += ( desc_X[M_] % desc_X[MB_] );
236  np = MAX( 1, np );
237 
238  if( MyColDist >= ( MyColBlock % npcol ) )
239  {
240  if( mycol == *ixcol )
241  *jjx += jx % desc_X[NB_];
242  *jjx -= desc_X[NB_];
243  }
244  if( MyColDist < ExtraColBlock )
245  nq += desc_X[NB_];
246  else if( MyColDist == ExtraColBlock )
247  nq += ( desc_X[N_] % desc_X[NB_] );
248  nq = MAX( 1, nq );
249 
250  *iix = MIN( *iix, np );
251  *jjx = MIN( *jjx, nq );
252 
253  if( desc_X[LLD_] < np )
254  {
255  if( numroc_(&desc_X[N_], &desc_X[NB_], &mycol, &desc_X[CSRC_], &npcol) )
256  *info = -( descpos + LLD_ );
257  else *info = 0;
258  }
259  else *info = 0;
260  }
261  else if( *info % DESCMULT == 0 )
262  {
263  *info = -(*info) / DESCMULT;
264  }
265  else
266  {
267  *info = -(*info);
268  }
269 }
M_
#define M_
Definition: PBtools.h:39
MB_
#define MB_
Definition: PBtools.h:43
NB_
#define NB_
Definition: PBtools.h:44
CSRC_
#define CSRC_
Definition: PBtools.h:46
DESCMULT
#define DESCMULT
LLD_
#define LLD_
Definition: PBtools.h:47
pbchkvect
void pbchkvect(int n, int npos0, int ix, int jx, desc_X, int incx, int dpos0, int *iix, int *jjx, int *ixrow, int *ixcol, int nprow, int npcol, int myrow, int mycol, int *info)
Definition: pbchkvect.c:15
RSRC_
#define RSRC_
Definition: PBtools.h:45
F_INTG_FCT
#define F_INTG_FCT
Definition: pblas.h:124
DT_
#define DT_
Definition: pblas.h:126
N_
#define N_
Definition: PBtools.h:40
BIGNUM
#define BIGNUM
MIN
#define MIN(a_, b_)
Definition: PBtools.h:76
BLOCK_CYCLIC_2D
#define BLOCK_CYCLIC_2D
Definition: PBtools.h:20
MAX
#define MAX(a_, b_)
Definition: PBtools.h:77
tools.h