/* ---------------------------------------------------------------------
*
* -- PBLAS auxiliary routine (version 2.0) --
* University of Tennessee, Knoxville, Oak Ridge National Laboratory,
* and University of California, Berkeley.
* April 1, 1998
*
* ---------------------------------------------------------------------
*/
/*
* Include files
*/
#include "../pblas.h"
#include "../PBpblas.h"
#include "../PBtools.h"
#include "../PBblacs.h"
#include "../PBblas.h"
#ifdef __STDC__
void PB_Cbinfo( int OFFD, int M, int N, int IMB1, int INB1, int MB,
int NB, int MRROW, int MRCOL, int * LCMT00, int * MBLKS,
int * NBLKS, int * IMBLOC, int * INBLOC, int * LMBLOC,
int * LNBLOC, int * ILOW, int * LOW, int * IUPP, int * UPP )
#else
void PB_Cbinfo( OFFD, M, N, IMB1, INB1, MB, NB, MRROW, MRCOL, LCMT00,
MBLKS, NBLKS, IMBLOC, INBLOC, LMBLOC, LNBLOC, ILOW, LOW,
IUPP, UPP )
/*
* .. Scalar Arguments ..
*/
int * ILOW, IMB1, * IMBLOC, INB1, * INBLOC, * IUPP,
* LCMT00, * LMBLOC, * LNBLOC, * LOW, M, MB, * MBLKS,
MRCOL, MRROW, N, NB, * NBLKS, OFFD, * UPP;
#endif
{
/*
* Purpose
* =======
*
* PB_Cbinfo initializes the local information of an m by n local array
* owned by the process of relative coordinates ( MRROW, MRCOL ). Note
* that if m or n is less or equal than zero, there is no data, in which
* case this process does not need the local information computed by
* this routine to proceed.
*
* Arguments
* =========
*
* OFFD (global input) INTEGER
* On entry, OFFD specifies the off-diagonal of the underlying
* matrix of interest as follows:
* OFFD = 0 specifies the main diagonal,
* OFFD > 0 specifies lower subdiagonals, and
* OFFD < 0 specifies upper superdiagonals.
*
* M (local input) INTEGER
* On entry, M specifies the local number of rows of the under-
* lying matrix owned by the process of relative coordinates
* ( MRROW, MRCOL ). M must be at least zero.
*
* N (local input) INTEGER
* On entry, N specifies the local number of columns of the un-
* derlying matrix owned by the process of relative coordinates
* ( MRROW, MRCOL ). N must be at least zero.
*
* IMB1 (global input) INTEGER
* On input, IMB1 specifies the global true size of the first
* block of rows of the underlying global submatrix. IMB1 must
* be at least MIN( 1, M ).
*
* INB1 (global input) INTEGER
* On input, INB1 specifies the global true size of the first
* block of columns of the underlying global submatrix. INB1
* must be at least MIN( 1, N ).
*
* MB (global input) INTEGER
* On entry, MB specifies the blocking factor used to partition
* the rows of the matrix. MB must be at least one.
*
* NB (global input) INTEGER
* On entry, NB specifies the blocking factor used to partition
* the the columns of the matrix. NB must be at least one.
*
* MRROW (local input) INTEGER
* On entry, MRROW specifies the relative row coordinate of the
* process that possesses these M rows. MRROW must be least zero
* and strictly less than NPROW.
*
* MRCOL (local input) INTEGER
* On entry, MRCOL specifies the relative column coordinate of
* the process that possesses these N columns. MRCOL must be
* least zero and strictly less than NPCOL.
*
* LCMT00 (local output) INTEGER
* On exit, LCMT00 is the LCM value of the left upper block of
* this m by n local block owned by the process of relative co-
* ordinates ( MRROW, MRCOL ).
*
* MBLKS (local output) INTEGER
* On exit, MBLKS specifies the local number of blocks of rows
* corresponding to M. MBLKS must be at least zero.
*
* NBLKS (local output) INTEGER
* On exit, NBLKS specifies the local number of blocks of co-
* lumns corresponding to N. NBLKS must be at least zero.
*
* IMBLOC (local output) INTEGER
* On exit, IMBLOC specifies the number of rows (size) of the
* uppest blocks of this m by n local array owned by the process
* of relative coordinates ( MRROW, MRCOL ). IMBLOC is at least
* MIN( 1, M ).
*
* INBLOC (local output) INTEGER
* On exit, INBLOC specifies the number of columns (size) of
* the leftmost blocks of this m by n local array owned by the
* process of relative coordinates ( MRROW, MRCOL ). INBLOC is
* at least MIN( 1, N ).
*
* LMBLOC (local output) INTEGER
* On exit, LMBLOC specifies the number of rows (size) of the
* lowest blocks of this m by n local array owned by the process
* of relative coordinates ( MRROW, MRCOL ). LMBLOC is at least
* MIN( 1, M ).
*
* LNBLOC (local output) INTEGER
* On exit, LNBLOC specifies the number of columns (size) of the
* rightmost blocks of this m by n local array owned by the
* process of relative coordinates ( MRROW, MRCOL ). LNBLOC is
* at least MIN( 1, N ).
*
* ILOW (local output) INTEGER
* On exit, ILOW is the lower bound characterizing the first co-
* lumn block owning offdiagonals of this m by n array. ILOW
* must be less or equal than zero.
*
* LOW (global output) INTEGER
* On exit, LOW is the lower bound characterizing the column
* blocks with te exception of the first one (see ILOW) owning
* offdiagonals of this m by n array. LOW must be less or equal
* than zero.
*
* IUPP (local output) INTEGER
* On exit, IUPP is the upper bound characterizing the first row
* block owning offdiagonals of this m by n array. IUPP must be
* greater or equal than zero.
*
* UPP (global output) INTEGER
* On exit, UPP is the upper bound characterizing the row
* blocks with te exception of the first one (see IUPP) owning
* offdiagonals of this m by n array. UPP must be greater or
* equal than zero.
*
* -- Written on April 1, 1998 by
* Antoine Petitet, University of Tennessee, Knoxville 37996, USA.
*
* ---------------------------------------------------------------------
*/
/*
* .. Local Scalars ..
*/
int tmp1;
/* ..
* .. Executable Statements ..
*
*/
/*
* Initialize LOW, ILOW, UPP, IUPP, LMBLOC, LNBLOC, IMBLOC, INBLOC, MBLKS,
* NBLKS and LCMT00.
*/
*LOW = 1 - NB;
*UPP = MB - 1;
*LCMT00 = OFFD;
if( ( M <= 0 ) || ( N <= 0 ) )
{
/*
* If the local virtual array is empty, then simplify the remaining of the
* initialization.
*/
*IUPP = ( MRROW ? MB - 1 : ( IMB1 > 0 ? IMB1 - 1 : 0 ) );
*IMBLOC = 0;
*MBLKS = 0;
*LMBLOC = 0;
*ILOW = ( MRCOL ? 1 - NB : ( INB1 > 0 ? 1 - INB1 : 0 ) );
*INBLOC = 0;
*NBLKS = 0;
*LNBLOC = 0;
*LCMT00 += ( *LOW - *ILOW + MRCOL * NB ) - ( *IUPP - *UPP + MRROW * MB );
return;
}
if( MRROW )
{
/*
* I am not in the first relative process row. Use the first local row block
* size MB to initialize the VM structure.
*/
*IMBLOC = MIN( M, MB );
*IUPP = MB - 1;
*LCMT00 -= IMB1 - MB + MRROW * MB;
*MBLKS = ( M - 1 ) / MB + 1;
*LMBLOC = M - ( M / MB ) * MB;
if( !( *LMBLOC ) ) *LMBLOC = MB;
if( MRCOL )
{
/*
* I am not in the first relative process column. Use the first local column
* block size NB to initialize the VM structure.
*/
*INBLOC = MIN( N, NB );
*ILOW = 1 - NB;
*LCMT00 += INB1 - NB + MRCOL * NB;
*NBLKS = ( N - 1 ) / NB + 1;
*LNBLOC = N - ( N / NB ) * NB;
if( !( *LNBLOC ) ) *LNBLOC = NB;
}
else
{
/*
* I am in the first relative process column. Use the first column block size
* INB1 to initialize the VM structure.
*/
*INBLOC = INB1;
*ILOW = 1 - INB1;
tmp1 = N - INB1;
if( tmp1 )
{
/*
* There is more than one column block. Compute the number of local column
* blocks and the size of the last one.
*/
*NBLKS = ( tmp1 - 1 ) / NB + 2;
*LNBLOC = tmp1 - ( tmp1 / NB ) * NB;
if( !( *LNBLOC ) ) *LNBLOC = NB;
}
else
{
/*
* There is only one column block.
*/
*NBLKS = 1;
*LNBLOC = INB1;
}
}
}
else
{
/*
* I am in the first relative process row. Use the first row block size IMB1 to
* initialize the VM structure.
*/
*IMBLOC = IMB1;
*IUPP = IMB1 - 1;
tmp1 = M - IMB1;
if( tmp1 )
{
/*
* There is more than one row block. Compute the number of local row blocks and
* the size of the last one.
*/
*MBLKS = ( tmp1 - 1 ) / MB + 2;
*LMBLOC = tmp1 - ( tmp1 / MB ) * MB;
if( !( *LMBLOC ) ) *LMBLOC = MB;
}
else
{
/*
* There is only one row block.
*/
*MBLKS = 1;
*LMBLOC = IMB1;
}
if( MRCOL )
{
/*
* I am not in the first relative process column. Use the first local column
* block size NB to initialize the VM structure.
*/
*INBLOC = MIN( N, NB );
*ILOW = 1 - NB;
*LCMT00 += INB1 - NB + MRCOL * NB;
*NBLKS = ( N - 1 ) / NB + 1;
*LNBLOC = N - ( N / NB ) * NB;
if( !( *LNBLOC ) ) *LNBLOC = NB;
}
else
{
/*
* I am in the first relative process column. Use the first column block size
* INB1 to initialize the VM structure.
*/
*INBLOC = INB1;
*ILOW = 1 - INB1;
tmp1 = N - INB1;
if( tmp1 )
{
/*
* There is more than one column block. Compute the number of local column
* blocks and the size of the last one.
*/
*NBLKS = ( tmp1 - 1 ) / NB + 2;
*LNBLOC = tmp1 - ( tmp1 / NB ) * NB;
if( !( *LNBLOC ) ) *LNBLOC = NB;
}
else
{
/*
* There is only one column block.
*/
*NBLKS = 1;
*LNBLOC = INB1;
}
}
}
/*
* End of PB_Cbinfo
*/
}