PZLARFB(l)
π PZLARFB π
okay so bestie, welcome to PZLARFB, a LAPACK auxiliary routine (that's the manual fam, version 1.5) and she is that girl. let's get into it π«Ά
β¨ NAME β¨
PZLARFB β she applies a complex block reflector Q or its conjugate transpose Q**H to a complex M-by-N distributed matrix sub( C ) (which is shorthand for C(IC:IC+M-1,JC:JC+N-1)), and she does it from the left or from the right. versatile icon behavior π
πΈ SYNOPSIS πΈ
SUBROUTINE PZLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, IV, JV,
DESCV, T, C, IC, JC, DESCC, WORK )
CHARACTER SIDE, TRANS, DIRECT, STOREV
INTEGER IC, IV, JC, JV, K, M, N
INTEGER DESCC( * ), DESCV( * )
COMPLEX*16 C( * ), T( * ), V( * ), WORK( * )
π¦ PURPOSE π¦
PZLARFB applies a complex block reflector Q or its conjugate transpose Q**H to a complex M-by-N distributed matrix sub( C ) β and sub( C ) means C(IC:IC+M-1,JC:JC+N-1) β from the left or the right. that's the whole job and she does it flawlessly, no cap β¨
π Notes π
every global data object out here has an associated description vector. that vector is the receipts: it stores everything you need to establish the mapping between an object element and its corresponding process and memory location. iykyk.
so let A be a generic term for any 2D block cyclicly distributed array. such a global array has an associated description vector DESCA. and in the comments below, read that underscore _ as "of the global array". periodt.
the notation situation, laid out pretty:
DTYPE_A(global) β stored inDESCA( DTYPE_ ): the descriptor type. in this case,DTYPE_A = 1.CTXT_A(global) β stored inDESCA( 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 inDESCA( M_ ): the number of rows in the global array A.N_A(global) β stored inDESCA( N_ ): the number of columns in the global array A.MB_A(global) β stored inDESCA( MB_ ): the blocking factor used to distribute the rows of the array.NB_A(global) β stored inDESCA( NB_ ): the blocking factor used to distribute the columns of the array.RSRC_A(global) β stored inDESCA( RSRC_ ): the process row over which the first row of the array A is distributed.CSRC_A(global) β stored inDESCA( CSRC_ ): the process column over which the first column of the array A is distributed.LLD_A(local) β stored inDESCA( LLD_ ): the leading dimension of the local array.LLD_A >= MAX(1,LOCr(M_A)).
now 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.
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.
and you can get those values by calling 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
π ARGUMENTS π
SIDEβ (global input)CHARACTER. tells you which side we're coming from:= 'L': applyQorQ**Hfrom the Left;= 'R': applyQorQ**Hfrom the Right.
TRANSβ (global input)CHARACTER. the transpose tea:= 'N': No transpose, applyQ;= 'C': Conjugate transpose, applyQ**H.
DIRECTβ (global input)CHARACTER. indicates howQis formed from a product of elementary reflectors:= 'F':Q = H(1) H(2) . . . H(k)(Forward)= 'B':Q = H(k) . . . H(2) H(1)(Backward)
STOREVβ (global input)CHARACTER. indicates how the vectors which define the elementary reflectors are stored:= 'C': Columnwise= 'R': Rowwise
Mβ (global input)INTEGER. the number of rows to be operated on, i.e the number of rows of the distributed submatrixsub( C ).M >= 0. no negativity allowed bestie πNβ (global input)INTEGER. the number of columns to be operated on, i.e the number of columns of the distributed submatrixsub( C ).N >= 0.Kβ (global input)INTEGER. the order of the matrixT(= the number of elementary reflectors whose product defines the block reflector).Vβ (local input)COMPLEX*16pointer into the local memory to an array of dimension( LLD_V, LOCc(JV+K-1) )ifSTOREV = 'C',( LLD_V, LOCc(JV+M-1))ifSTOREV = 'R'andSIDE = 'L',( LLD_V, LOCc(JV+N-1) )ifSTOREV = 'R'andSIDE = 'R'. it contains the local pieces of the distributed vectorsVrepresenting the Householder transformation. see further details. and the leading-dimension rules: ifSTOREV = 'C'andSIDE = 'L',LLD_V >= MAX(1,LOCr(IV+M-1)); ifSTOREV = 'C'andSIDE = 'R',LLD_V >= MAX(1,LOCr(IV+N-1)); ifSTOREV = 'R',LLD_V >= LOCr(IV+K-1). πIVβ (global input)INTEGER. the row index in the global arrayVindicating the first row ofsub( V ).JVβ (global input)INTEGER. the column index in the global arrayVindicating the first column ofsub( V ).DESCVβ (global and local input)INTEGERarray of dimensionDLEN_. the array descriptor for the distributed matrixV.Tβ (local input)COMPLEX*16array, dimensionMB_VbyMB_VifSTOREV = 'R'andNB_VbyNB_VifSTOREV = 'C'. the triangular matrixTin the representation of the block reflector.Cβ (local input/local output)COMPLEX*16pointer into the local memory to an array of dimension(LLD_C,LOCc(JC+N-1)). on entry, the M-by-N distributed matrixsub( C ). on exit,sub( C )is overwritten byQ*sub( C )orQ'*sub( C )orsub( C )*Qorsub( C )*Q'. she overwrites. that's just how she moves πICβ (global input)INTEGER. the row index in the global arrayCindicating the first row ofsub( C ).JCβ (global input)INTEGER. the column index in the global arrayCindicating the first column ofsub( C ).DESCCβ (global and local input)INTEGERarray of dimensionDLEN_. the array descriptor for the distributed matrixC.WORKβ (local workspace)COMPLEX*16array, dimension(LWORK). and now the formula part, buckle up:- if
STOREV = 'C':- if
SIDE = 'L',LWORK >= ( NqC0 + MpC0 ) * K - else if
SIDE = 'R',LWORK >= ( NqC0 + MAX( NpV0 + NUMROC( NUMROC( N+ICOFFC, NB_V, 0, 0, NPCOL ), NB_V, 0, 0, LCMQ ), MpC0 ) ) * K
- if
- else if
STOREV = 'R':- if
SIDE = 'L',LWORK >= ( MpC0 + MAX( MqV0 + NUMROC( NUMROC( M+IROFFC, MB_V, 0, 0, NPROW ), MB_V, 0, 0, LCMP ), NqC0 ) ) * K - else if
SIDE = 'R',LWORK >= ( MpC0 + NqC0 ) * K
- if
- if
where:
LCMQ = LCM / NPCOL with LCM = ICLM( NPROW, NPCOL ),
IROFFV = MOD( IV-1, MB_V ), ICOFFV = MOD( JV-1, NB_V ), IVROW =
INDXG2P( IV, MB_V, MYROW, RSRC_V, NPROW ), IVCOL = INDXG2P( JV,
NB_V, MYCOL, CSRC_V, NPCOL ), MqV0 = NUMROC( M+ICOFFV, NB_V,
MYCOL, IVCOL, NPCOL ), NpV0 = NUMROC( N+IROFFV, MB_V, MYROW,
IVROW, NPROW ),
IROFFC = MOD( IC-1, MB_C ), ICOFFC = MOD( JC-1, NB_C ), ICROW =
INDXG2P( IC, MB_C, MYROW, RSRC_C, NPROW ), ICCOL = INDXG2P( JC,
NB_C, MYCOL, CSRC_C, NPCOL ), MpC0 = NUMROC( M+IROFFC, MB_C,
MYROW, ICROW, NPROW ), NpC0 = NUMROC( N+ICOFFC, MB_C, MYROW,
ICROW, NPROW ), NqC0 = NUMROC( N+ICOFFC, NB_C, MYCOL, ICCOL,
NPCOL ),
and ILCM, INDXG2P and NUMROC are ScaLAPACK tool functions; MYROW, MYCOL, NPROW and NPCOL can be determined by calling the subroutine BLACS_GRIDINFO. π
π§ Alignment requirements π§
the distributed submatrices V(IV:*, JV:*) and C(IC:IC+M-1,JC:JC+N-1) must verify some alignment properties, namely the following expressions should be true:
If STOREV = 'Columnwise'
If SIDE = 'Left', ( MB_V.EQ.MB_C .AND. IROFFV.EQ.IROFFC .AND. IVROW.EQ.ICROW )
If SIDE = 'Right', ( MB_V.EQ.NB_C .AND. IROFFV.EQ.ICOFFC )
else if STOREV = 'Rowwise'
If SIDE = 'Left', ( NB_V.EQ.MB_C .AND. ICOFFV.EQ.IROFFC )
If SIDE = 'Right', ( NB_V.EQ.NB_C .AND. ICOFFV.EQ.ICOFFC .AND. IVCOL.EQ.ICCOL )
end if
bestie this is a must, not a suggestion. check your alignment before you call her or it's giving chaos π
and that's the whole page!! mwah π«Ά this one is from LAPACK, version 1.5, dated 12 May 1997 β yes she's an icon from the archives and she still ate. slay, go call your girl PZLARFB responsibly β¨π
π¦ where this page comes from
- ubuntu jammy: scalapack-doc 1.5-11
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms