PZTRTRI(l)

πŸ“¦ version 1.5, in ubuntu jammy

πŸ’– PZTRTRI πŸ’– β€” aka the LAPACK routine that inverts your triangular distributed matrix, bestie

okay so picture this: it's PZTRTRI(l), it's a LAPACK routine, version 1.5, and it's here to compute the inverse of an upper or lower triangular distributed matrix. sub( A ) = A(IA:IA+N-1,JA:JA+N-1) β€” say it with me now. πŸ’…


✨ SYNOPSIS ✨

SUBROUTINE PZTRTRI( UPLO, DIAG, N, A, IA, JA, DESCA, INFO )

    CHARACTER       DIAG, UPLO

    INTEGER         IA, INFO, JA, N

    INTEGER         DESCA( * )

    COMPLEX*16      A( * )

like. look at her. so clean. πŸŽ€


🌸 PURPOSE 🌸

PZTRTRI computes the inverse of a upper or lower triangular distributed matrix sub( A ) = A(IA:IA+N-1,JA:JA+N-1). that's it, that's the whole job, and she does it flawlessly. no cap. 🫢

Notes πŸ’­

so here's the lore you need, bestie. every global data object has a little bestie of its own called a description vector, and that vector holds all the info needed to map an element of the object to its process and memory location. it's giving personal assistant energy. ✨

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". (iykyk 🧚)

here's the whole notation situation, one bullet at a time because we don't do tables in this house:

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

okay and now for the fun math part, don't scroll away 😭

let K be the number of rows or columns of a distributed matrix, and assume that its process grid has dimension p x q.

LOCr( K ) denotes 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 ) denotes 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

slay. math ate. πŸ”₯


πŸ‘‘ ARGUMENTS πŸ‘‘

  • UPLO β€” (global input) CHARACTER. specifies whether the distributed matrix sub( A ) is upper or lower triangular:
    • = 'U': upper triangular,
    • = 'L': lower triangular.
  • DIAG β€” (global input) CHARACTER. specifies whether or not the distributed matrix sub( A ) is unit triangular:
    • = 'N': non-unit triangular,
    • = 'U': unit triangular.
  • N β€” (global input) INTEGER. the number of rows and columns to be operated on, i.e. the order of the distributed submatrix sub( A ). N >= 0.
  • A β€” (local input/local output) COMPLEX*16 pointer into the local memory to an array of dimension (LLD_A,LOCc(JA+N-1)). on entry, this array contains the local pieces of the triangular matrix sub( A ). if UPLO = 'U', the leading N-by-N upper triangular part of the matrix sub( A ) contains the upper triangular matrix to be inverted, and the strictly lower triangular part of sub( A ) is not referenced. if UPLO = 'L', the leading N-by-N lower triangular part of the matrix sub( A ) contains the lower triangular matrix, and the strictly upper triangular part of sub( A ) is not referenced. on exit, the (triangular) inverse of the original matrix. πŸ’–
  • IA β€” (global input) INTEGER. the row index in the global array A indicating the first row of sub( A ).
  • JA β€” (global input) INTEGER. the column index in the global array A indicating the first column of sub( A ).
  • DESCA β€” (global and local input) INTEGER array of dimension DLEN_. the array descriptor for the distributed matrix A.
  • INFO β€” (global output) INTEGER:
    • = 0: successful exit πŸŽ‰
    • < 0: if the i-th argument is an array and the j-entry had an illegal value, then INFO = -(i*100+j); if the i-th argument is a scalar and had an illegal value, then INFO = -i.
    • > 0: if INFO = K, A(IA+K-1,JA+K-1) is exactly zero. the triangular matrix sub( A ) is singular and its inverse can not be computed.
🚨 bestie listen. that last one is NOT a drill. if you get INFO = K back, A(IA+K-1,JA+K-1) is exactly zero, the triangular matrix sub( A ) is singular, and its inverse can not be computed. she said what she said. periodt. πŸ’€

and that's the whole page, my love. she's giving main character energy and she deserves it. πŸ’œ

signing off with the receipts: this was LAPACK version 1.5, dated 12 May 1997, and it's PZTRTRI(l) forever and always. πŸ¦‹βœ¨πŸ’…

πŸ“¦ where this page comes from