1 SUBROUTINE psorm2l( SIDE, TRANS, M, N, K, A, IA, JA, DESCA, TAU,
2 $ C, IC, JC, DESCC, WORK, LWORK, INFO )
11 INTEGER IA, IC, INFO, JA, JC, K, LWORK, M, N
14 INTEGER DESCA( * ), DESCC( * )
15 REAL A( * ), C( * ), TAU( * ), WORK( * )
209 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
210 $ lld_, mb_, m_, nb_, n_, rsrc_
211 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
212 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
213 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
215 parameter( one = 1.0e+0 )
218 LOGICAL LEFT, LQUERY, NOTRAN
219 CHARACTER COLBTOP, ROWBTOP
220 INTEGER IACOL, IAROW, ICCOL, ICOFFC, ICROW, ICTXT, ICC,
221 $ ii, iroffa, iroffc, j, j1, j2, j3, jcc, jj,
222 $ lcm, lcmq, lwmin, mi, mp, mpc0, mycol, myrow,
223 $ ni, npcol, nprow, nq, nqc0
229 $ pb_topset,
pxerbla, sgebr2d, sgebs2d,
230 $ sgerv2d, sgesd2d, sscal
234 INTEGER ILCM, INDXG2P, NUMROC
235 EXTERNAL ilcm, indxg2p, lsame, numroc
238 INTRINSIC max, mod, real
244 ictxt = desca( ctxt_ )
245 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
250 IF( nprow.EQ.-1 )
THEN
253 left = lsame( side,
'L' )
254 notran = lsame( trans,
'N' )
260 CALL chk1mat( m, 3, k, 5, ia, ja, desca, 9, info )
263 CALL chk1mat( n, 4, k, 5, ia, ja, desca, 9, info )
265 CALL chk1mat( m, 3, n, 4, ic, jc, descc, 14, info )
267 iroffa = mod( ia-1, desca( mb_ ) )
268 iroffc = mod( ic-1, descc( mb_ ) )
269 icoffc = mod( jc-1, descc( nb_ ) )
270 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
272 icrow = indxg2p( ic, descc( mb_ ), myrow, descc( rsrc_ ),
274 iccol = indxg2p( jc, descc( nb_ ), mycol, descc( csrc_ ),
276 mpc0 = numroc( m+iroffc, descc( mb_ ), myrow, icrow, nprow )
277 nqc0 = numroc( n+icoffc, descc( nb_ ), mycol, iccol, npcol )
280 lwmin = mpc0 +
max( 1, nqc0 )
282 lcm = ilcm( nprow, npcol )
284 lwmin = nqc0 +
max(
max( 1, mpc0 ), numroc( numroc(
285 $ n+icoffc, desca( nb_ ), 0, 0, npcol ),
286 $ desca( nb_ ), 0, 0, lcmq ) )
289 work( 1 ) = real( lwmin )
290 lquery = ( lwork.EQ.-1 )
291 IF( .NOT.left .AND. .NOT.lsame( side,
'R' ) )
THEN
293 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans,
'T' ) )
THEN
295 ELSE IF( k.LT.0 .OR. k.GT.nq )
THEN
297 ELSE IF( .NOT.left .AND. desca( mb_ ).NE.descc( nb_ ) )
THEN
299 ELSE IF( left .AND. iroffa.NE.iroffc )
THEN
301 ELSE IF( left .AND. iarow.NE.icrow )
THEN
303 ELSE IF( .NOT.left .AND. iroffa.NE.icoffc )
THEN
305 ELSE IF( left .AND. desca( mb_ ).NE.descc( mb_ ) )
THEN
307 ELSE IF( ictxt.NE.descc( ctxt_ ) )
THEN
309 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
315 CALL pxerbla( ictxt,
'PSORM2L', -info )
316 CALL blacs_abort( ictxt, 1 )
318 ELSE IF( lquery )
THEN
324 IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
327 IF( desca( m_ ).EQ.1 )
THEN
328 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, ii,
330 CALL infog2l( ic, jc, descc, nprow, npcol, myrow, mycol, icc,
331 $ jcc, icrow, iccol )
333 IF( myrow.EQ.iarow )
THEN
334 nq = numroc( jc+n-1, descc( nb_ ), mycol, descc( csrc_ ),
336 IF( mycol.EQ.iacol )
THEN
337 ajj = one - tau( jj )
338 CALL sgebs2d( ictxt,
'Rowwise',
' ', 1, 1, ajj, 1 )
339 CALL sscal( nq-jcc+1, ajj,
340 $ c( icc+(jcc-1)*descc( lld_ ) ),
343 CALL sgebr2d( ictxt,
'Rowwise',
' ', 1, 1, ajj, 1,
345 CALL sscal( nq-jcc+1, ajj,
346 $ c( icc+(jcc-1)*descc( lld_ ) ),
351 IF( mycol.EQ.iacol )
THEN
352 ajj = one - tau( jj )
355 IF( iacol.NE.iccol )
THEN
357 $
CALL sgesd2d( ictxt, 1, 1, ajj, 1, myrow, iccol )
359 $
CALL sgerv2d( ictxt, 1, 1, ajj, 1, myrow, iacol )
362 IF( mycol.EQ.iccol )
THEN
363 mp = numroc( ic+m-1, descc( mb_ ), myrow, descc( rsrc_ ),
365 CALL sscal( mp-icc+1, ajj, c( icc+(jcc-1)*
366 $ descc( lld_ ) ), 1 )
373 CALL pb_topget( ictxt,
'Broadcast',
'Rowwise', rowbtop )
374 CALL pb_topget( ictxt,
'Broadcast',
'Columnwise', colbtop )
376 IF( left .AND. notran .OR. .NOT.left .AND. .NOT.notran )
THEN
389 CALL pb_topset( ictxt,
'Broadcast',
'Rowwise',
'I-ring' )
391 CALL pb_topset( ictxt,
'Broadcast',
'Rowwise',
'D-ring' )
393 CALL pb_topset( ictxt,
'Broadcast',
'Columnwise',
' ' )
404 mi = m - k + j - ja + 1
409 ni = n - k + j - ja + 1
414 CALL pselset2( ajj, a, ia+nq-k+j-ja, j, desca, one )
415 CALL pslarf( side, mi, ni, a, ia, j, desca, 1, tau, c, ic,
417 CALL pselset( a, ia+nq-k+j-ja, j, desca, ajj )
421 CALL pb_topset( ictxt,
'Broadcast',
'Rowwise', rowbtop )
422 CALL pb_topset( ictxt,
'Broadcast',
'Columnwise', colbtop )
426 work( 1 ) = real( lwmin )