ScaLAPACK 2.1  2.1
ScaLAPACK: Scalable Linear Algebra PACKage
PB_Cg2lrem.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_Cg2lrem( int IG, int INB, int NB, int MYPROC, int SRCPROC, int NPROCS )
21 #else
22 int PB_Cg2lrem( IG, INB, NB, MYPROC, SRCPROC, NPROCS )
23 /*
24 * .. Scalar Arguments ..
25 */
26  int IG, INB, NB, NPROCS, MYPROC, SRCPROC;
27 #endif
28 {
29 /*
30 * Purpose
31 * =======
32 *
33 * PB_Cg2lrem computes the local index of a matrix entry pointed to by
34 * the global index IG. Note that when MYPROC is not the process owning
35 * this entry, this routine returns the closest larger local index cor-
36 * responding to IG just like the routine PB_Cinfog2l.
37 *
38 * Arguments
39 * =========
40 *
41 * IG (global input) INTEGER
42 * On entry, IG specifies the global index of the matrix entry.
43 * IG must be at least zero.
44 *
45 * INB (global input) INTEGER
46 * On entry, INB specifies the size of the first block of the
47 * global matrix. INB must be at least one.
48 *
49 * NB (global input) INTEGER
50 * On entry, NB specifies the size of the blocks used to parti-
51 * tion the matrix. NB must be at least one.
52 *
53 * MYPROC (global input) INTEGER
54 * On entry, MYPROC specifies the process number in which the
55 * value of the local index is to be computed. MYPROC must be at
56 * least zero and strictly less than NPROCS.
57 *
58 * SRCPROC (global input) INTEGER
59 * On entry, if SRCPROC = -1, the data is not distributed but
60 * replicated, in which case this routine returns IG in all
61 * processes. Otherwise, the value of SRCPROC is ignored.
62 *
63 * NPROCS (global input) INTEGER
64 * On entry, NPROCS specifies the total number of process rows
65 * or columns over which the matrix is distributed. NPROCS must
66 * be at least one.
67 *
68 * -- Written on April 1, 1998 by
69 * Antoine Petitet, University of Tennessee, Knoxville 37996, USA.
70 *
71 * ---------------------------------------------------------------------
72 */
73 /*
74 * .. Local Scalars ..
75 */
76  int ilocblk, mydist, nblocks, proc;
77 /* ..
78 * .. Executable Statements ..
79 *
80 */
81 /*
82 * The data is not distributed, or there is just one process in this dimension
83 * of the grid.
84 */
85  if( ( SRCPROC == -1 ) || ( NPROCS == 1 ) ) return( IG );
86 /*
87 * IG refers to an entry in the first block
88 */
89  if( IG < INB ) return( ( MYPROC == SRCPROC ? IG : 0 ) );
90 /*
91 * The discussion goes as follows: compute my distance from the source process
92 * so that within this process coordinate system, the source process is the
93 * process such that mydist = 0, or equivalently MYROC == SRCPROC.
94 *
95 * Find out the global coordinate of the block IG belongs to (nblocks), as well
96 * as the minimum local number of blocks that every process has.
97 *
98 * when mydist < nblocks - ilocblk * NPROCS, I own ilocblk + 1 full blocks,
99 * when mydist > nblocks - ilocblk * NPROCS, I own ilocblk full blocks,
100 * when mydist = nblocks - ilocblk * NPROCS, I own ilocblk full blocks
101 * but not IG, or I own ilocblk + 1 blocks and the entry IG refers to.
102 */
103  if( MYPROC == SRCPROC )
104  {
105 /*
106 * If I am the source process and there are less than NPROCS blocks, then
107 * the local index in that process is INB.
108 */
109  nblocks = ( IG - INB ) / NB + 1;
110  if( nblocks < NPROCS ) return( INB );
111 /*
112 * IG refers to an entry that is not in the first block, find out which process
113 * has it.
114 */
115  proc = SRCPROC + nblocks;
116  proc -= ( proc / NPROCS ) * NPROCS;
117 /*
118 * Since mydist = 0 and nblocks - ilocblk * NPROCS >= 0, there are only three
119 * possible cases:
120 *
121 * 1) When 0 = mydist = nblocks - ilocblk * NPROCS = 0 and I don't own IG, in
122 * which case II = INB + ( ilocblk - 1 ) * NB. Note that this case cannot
123 * happen when ilocblk is zero, since nblocks is at least one.
124 *
125 * 2) When 0 = mydist = nblocks - ilocblk * NPROCS = 0 and I own IG, in which
126 * case IG and II can respectively be written as INB + (nblocks-1)*NB + IL,
127 * INB + (ilocblk-1) * NB + IL. That is II = IG + ( ilocblk - nblocks )*NB.
128 * Note that this case cannot happen when ilocblk is zero, since nblocks
129 * is at least one.
130 *
131 * 3) mydist = 0 < nblocks - ilocblk * NPROCS, the source process owns
132 * ilocblk+1 full blocks, and therefore II = INB + ilocblk * NB. Note
133 * that when ilocblk is zero, II is just INB.
134 */
135  ilocblk = nblocks / NPROCS;
136  if( ilocblk * NPROCS >= nblocks )
137  return( ( ( MYPROC == proc ) ? IG + ( ilocblk - nblocks ) * NB :
138  INB + ( ilocblk - 1 ) * NB ) );
139  else
140  return( INB + ilocblk * NB );
141  }
142  else
143  {
144 /*
145 * IG refers to an entry that is not in the first block, find out which process
146 * has it.
147 */
148  nblocks = ( IG -= INB ) / NB + 1;
149  proc = SRCPROC + nblocks;
150  proc -= ( proc / NPROCS ) * NPROCS;
151 /*
152 * Compute my distance from the source process so that within this process
153 * coordinate system, the source process is the process such that mydist=0.
154 */
155  if( ( mydist = MYPROC - SRCPROC ) < 0 ) mydist += NPROCS;
156 /*
157 * When mydist < nblocks - ilocblk * NPROCS, I own ilocblk + 1 full blocks of
158 * size NB since I am not the source process, i.e. II = ( ilocblk + 1 ) * NB.
159 * When mydist >= nblocks - ilocblk * NPROCS and I don't own IG, I own ilocblk
160 * full blocks of size NB, i.e. II = ilocblk * NB, otherwise I own ilocblk
161 * blocks and IG, in which case IG can be written as INB + (nblocks-1)*NB + IL
162 * and II = ilocblk*NB + IL = IG - INB + ( ilocblk - nblocks + 1 )*NB.
163 */
164  if( nblocks < NPROCS )
165  {
166  mydist -= nblocks;
167  return( ( ( mydist < 0 ) ? NB :
168  ( ( MYPROC == proc ) ? IG + ( 1 - nblocks ) * NB : 0 ) ) );
169  }
170  else
171  {
172  ilocblk = nblocks / NPROCS;
173  mydist -= nblocks - ilocblk * NPROCS;
174  return( ( ( mydist < 0 ) ? ( ilocblk + 1 ) * NB :
175  ( ( MYPROC == proc ) ?
176  ( ilocblk - nblocks + 1 ) * NB + IG : ilocblk * NB ) ) );
177  }
178  }
179 /*
180 * End of PB_Cg2lrem
181 */
182 }
PB_Cg2lrem
int PB_Cg2lrem(int IG, int INB, int NB, int MYPROC, int SRCPROC, int NPROCS)
Definition: PB_Cg2lrem.c:22