ScaLAPACK 2.1  2.1
ScaLAPACK: Scalable Linear Algebra PACKage
PB_Cnpreroc.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_Cnpreroc( int N, int I, int INB, int NB, int PROC, int SRCPROC,
21  int NPROCS )
22 #else
23 int PB_Cnpreroc( N, I, INB, NB, PROC, SRCPROC, NPROCS )
24 /*
25 * .. Scalar Arguments ..
26 */
27  int I, INB, N, NB, NPROCS, PROC, SRCPROC;
28 #endif
29 {
30 /*
31 * Purpose
32 * =======
33 *
34 * PB_Cnpreroc computes the number of preceeding rows or columns of a
35 * submatrix that are possessed by processes closer to SRCPROC1 than
36 * PROC where SRCPROC1 is the process owning the row or column globally
37 * indexed by I. The submatrix is defined by giving out N rows/columns
38 * starting from global index I. Therefore, if SRCPROC=0 and PROC=4,
39 * then PB_Cnpreroc returns the number of matrix rows or columns owned
40 * by processes 0, 1, 2, and 3.
41 *
42 * Arguments
43 * =========
44 *
45 * N (global input) INTEGER
46 * On entry, N specifies the number of rows/columns being dealt
47 * out. N must be at least zero.
48 *
49 * I (global input) INTEGER
50 * On entry, I specifies the global index of the matrix entry.
51 * I must be at least zero.
52 *
53 * INB (global input) INTEGER
54 * On entry, INB specifies the size of the first block of the
55 * global matrix distribution. INB must be at least one.
56 *
57 * NB (global input) INTEGER
58 * On entry, NB specifies the size of the blocks used to parti-
59 * tion the matrix. NB must be at least one.
60 *
61 * PROC (local input) INTEGER
62 * On entry, PROC specifies the coordinate of the process whose
63 * local portion is determined. PROC must be at least zero and
64 * strictly less than NPROCS.
65 *
66 * SRCPROC (global input) INTEGER
67 * On entry, SRCPROC specifies the coordinate of the process
68 * that possesses the first row or column of the matrix. When
69 * SRCPROC = -1, the data is not distributed but replicated,
70 * otherwise SRCPROC must be at least zero and strictly less
71 * than NPROCS.
72 *
73 * NPROCS (global input) INTEGER
74 * On entry, NPROCS specifies the total number of process rows
75 * or columns over which the matrix is distributed. NPROCS must
76 * be at least one.
77 *
78 * -- Written on April 1, 1998 by
79 * Antoine Petitet, University of Tennessee, Knoxville 37996, USA.
80 *
81 * ---------------------------------------------------------------------
82 */
83 /*
84 * .. Local Scalars ..
85 */
86  int ilocblk, mydist, nblocks;
87 /* ..
88 * .. Executable Statements ..
89 *
90 */
91  if( ( SRCPROC == -1 ) || ( NPROCS == 1 ) )
92 /*
93 * The data is not distributed, or there is just one process in this dimension
94 * of the grid.
95 */
96  return( 0 );
97 /*
98 * Compute coordinate of process owning I and corresponding INB
99 */
100  if( ( INB -= I ) <= 0 )
101  {
102 /*
103 * I is not in first block, find out which process has it and update size of
104 * first block
105 */
106  nblocks = ( -INB ) / NB + 1;
107  SRCPROC += nblocks;
108  SRCPROC -= ( SRCPROC / NPROCS ) * NPROCS;
109  INB += nblocks * NB;
110  }
111 /*
112 * Now everything is just like N, I=0, INB, NB, SRCPROC, NPROCS. If I am the
113 * source process, nothing preceeds me ...
114 */
115  if( PROC == SRCPROC ) return( 0 );
116 /*
117 * If SRCPROC owns the N rows or columns, then return N since I cannot be the
118 * source process anymore.
119 */
120  if( N <= INB ) return( N );
121 /*
122 * Find out how many full blocks are globally (nblocks) and locally (ilocblk)
123 * in those N entries.
124 */
125  nblocks = ( N - INB ) / NB + 1;
126 /*
127 * Compute my distance from the source process so that within this process
128 * coordinate system, the source process is the process such that mydist=0.
129 */
130  if( ( mydist = PROC - SRCPROC ) < 0 ) mydist += NPROCS;
131 /*
132 * When mydist < nblocks - ilocblk * NPROCS, I own ilocblk + 1 full blocks,
133 * when mydist > nblocks - ilocblk * NPROCS, I own ilocblk full blocks,
134 * when mydist = nblocks - ilocblk * NPROCS, either the last block is not full
135 * and I own it, or the last block is full and I am the first process owning
136 * only ilocblk full blocks.
137 *
138 * Therefore, when 0 < mydist <= nblocks - ilocblk * NPROCS, the number of rows
139 * or columns preceeding me is INB + ilocblk*NB + (mydist-1)*(ilocblk+1)*NB,
140 * i.e. INB - NB + ( ilocblk+1 ) * NB * mydist. Otherwise, there are exactly
141 * NB * ilocblk * ( NPROCS - mydist ) rows or columns after me including mine,
142 * i.e N + NB * ilocblk * ( mydist - NPROCS ) rows or columns preceeding me.
143 */
144  if( nblocks < NPROCS )
145  return( ( ( mydist <= nblocks ) ? INB + NB * ( mydist - 1 ) : N ) );
146 
147  ilocblk = nblocks / NPROCS;
148  return( ( ( mydist <= ( nblocks - ilocblk * NPROCS ) ) ?
149  INB - NB + ( ilocblk + 1 ) * NB * mydist :
150  N + NB * ilocblk * ( mydist - NPROCS ) ) );
151 /*
152 * End of PB_Cnpreroc
153 */
154 }
PB_Cnpreroc
int PB_Cnpreroc(int N, int I, int INB, int NB, int PROC, int SRCPROC, int NPROCS)
Definition: PB_Cnpreroc.c:23