SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches

◆ PB_Cg2lrem()

Int PB_Cg2lrem ( Int  IG,
Int  INB,
Int  NB,
Int  MYPROC,
Int  SRCPROC,
Int  NPROCS 
)

Definition at line 22 of file PB_Cg2lrem.c.

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}
#define Int
Definition Bconfig.h:22