PZLAEVSWP(l)

๐Ÿ“ฆ version 1.5, in ubuntu jammy

๐ŸŒธ NAME ๐ŸŒธ

PZLAEVSWP โ€” bestie, this is the LAPACK routine (we're on LAPACK version 1.5, mwah ๐Ÿ’‹) that moves your eigenvectors (which may be potentially unsorted, no judgement) from wherever they got computed, over to a ScaLAPACK standard block cyclic array, and it sorts them on the way so that the corresponding eigenvalues come out sorted too. It's giving โœจorganizedโœจ. It's giving ๐ŸŽ€glow-up๐ŸŽ€.


๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

SUBROUTINE PZLAEVSWP( N, ZIN, LDZI, Z, IZ, JZ, DESCZ, NVS, KEY, RWORK,
                      LRWORK )

    INTEGER           IZ, JZ, LDZI, LRWORK, N

    INTEGER           DESCZ( * ), KEY( * ), NVS( * )

    DOUBLE            PRECISION RWORK( * ), ZIN( LDZI, * )

    COMPLEX*16        Z( * )

๐Ÿ’– PURPOSE ๐Ÿ’–

PZLAEVSWP moves the eigenvectors (potentially unsorted) from where they are computed, to a ScaLAPACK standard block cyclic array, sorted so that the corresponding eigenvalues are sorted. That's the whole vibe. Eigenvectors in, sorted distributed eigenvectors out, slay ๐Ÿ’….

๐ŸŒˆ Notes ๐ŸŒˆ

Every global data object gets its own little description vector, okay? That vector is holding all the info you need to figure out the mapping between an element of the object and the exact process + memory location where it lives. It's basically the object's Find My Friends ๐Ÿซถ.

So let A be a generic term for any 2D block cyclicly distributed array. Such a global array has an associated description vector DESCA. In the following comments, the character _ should be read as "of the global array" โ€” like, M_A is "M of A", iykyk ๐Ÿงš.

NOTATION        STORED IN      EXPLANATION
--------------- -------------- --------------------------------------
DTYPE_A(global) DESCA( DTYPE_ )The descriptor type.  In this case,
                               DTYPE_A = 1.
CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating
                               the BLACS process grid A is distribu-
                               ted over. The context itself is glo-
                               bal, but the handle (the integer
                               value) may vary.
M_A    (global) DESCA( M_ )    The number of rows in the global
                               array A.
N_A    (global) DESCA( N_ )    The number of columns in the global
                               array A.
MB_A   (global) DESCA( MB_ )   The blocking factor used to distribute
                               the rows of the array.
NB_A   (global) DESCA( NB_ )   The blocking factor used to distribute
                               the columns of the array.
RSRC_A (global) DESCA( RSRC_ ) The process row over which the first
                               row of the array A is distributed.
CSRC_A (global) DESCA( CSRC_ ) The process column over which the
                               first column of the array A is
                               distributed.
LLD_A  (local)  DESCA( LLD_ )  The leading dimension of the local
                               array.  LLD_A >= MAX(1,LOCr(M_A)).

Now โœจmath timeโœจ. Let K be the number of rows or columns of a distributed matrix, and assume its process grid has dimension p x q.

  • LOCr( K ) = the number of elements of K that a process would receive if K were distributed over the p processes of its process column.
  • Similarly, LOCc( K ) = the number of elements of K that a process would receive if K were distributed over the q processes of its process row.

The values of LOCr() and LOCc() may be determined via a call to the ScaLAPACK tool function, NUMROC:

        LOCr( M ) = NUMROC( M, MB_A, MYROW, RSRC_A, NPROW ),
        LOCc( N ) = NUMROC( N, NB_A, MYCOL, CSRC_A, NPCOL ).  An upper
bound for these quantities may be computed by:
        LOCr( M ) <= ceil( ceil(M/MB_A)/NPROW )*MB_A
        LOCc( N ) <= ceil( ceil(N/NB_A)/NPCOL )*NB_A

no cap, those bounds are the blueprint ๐Ÿ“


๐Ÿ‘‘ ARGUMENTS ๐Ÿ‘‘

First up, the two little cuties the whole section is framed around:

  • NP = the number of rows local to a given process.
  • NQ = the number of columns local to a given process.

Now the actual cast ๐Ÿ’œ:

  • N (global input) INTEGER โ€” The order of the matrix A. Constraint check bestie: N >= 0. Periodt.
  • ZIN (local input) DOUBLE PRECISION array, dimension ( LDZI, NVS(iam) ) โ€” The eigenvectors on input. Each eigenvector resides entirely in one process (she does not share, she commits ๐Ÿ’…). Each process holds a contiguous set of NVS(iam) eigenvectors. The first eigenvector which the process holds is: sum for i=[0,iam-1) of NVS(i).
  • LDZI (locl input) INTEGER โ€” leading dimension of the ZIN array.
  • Z (local output) COMPLEX*16 array โ€” global dimension (N, N), local dimension (DESCZ(DLEN_), NQ). The eigenvectors on output. The eigenvectors are distributed in a block cyclic manner in both dimensions, with a block size of NB. the glow up is real ๐Ÿ˜ญโœจ
  • IZ (global input) INTEGER โ€” Z's global row index, which points to the beginning of the submatrix which is to be operated on.
  • JZ (global input) INTEGER โ€” Z's global column index, which points to the beginning of the submatrix which is to be operated on.
  • DESCZ (global and local input) INTEGER array of dimension DLEN_. โ€” The array descriptor for the distributed matrix Z.
  • NVS (global input) INTEGER array, dimension( nprocs+1 ) โ€” okay so: nvs(i) = number of eigenvectors held by processes [0,i-1). Also nvs(1) = number of eigen vectors held by [0,1-1) == 0, and nvs(nprocs+1) = number of eigen vectors held by [0,nprocs) == the total number of eigenvectors. She's a running tally ๐Ÿงฎ.
  • RWORK (local workspace) DOUBLE PRECISION array, dimension (LRWORK).
  • LRWORK (local input) INTEGER โ€” dimension of RWORK.

reminder bestie: ZIN is DOUBLE PRECISION, Z is COMPLEX*16, and the array descriptor is DESCZ โ€” do NOT mix them up, I am begging ๐Ÿ™ˆ

and that's the whole page, my love ๐Ÿ’œ shoutout to LAPACK version 1.5, dated 12 May 1997 โ€” she's vintage, she's iconic, she's still serving ๐Ÿ’–๐ŸŒˆโญ bye bestie ๐Ÿซถ

๐Ÿ“ฆ where this page comes from