kusano 2b45e8
      SUBROUTINE CGEMMF(TRANA,TRANB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
kusano 2b45e8
*     .. Scalar Arguments ..
kusano 2b45e8
      COMPLEX ALPHA,BETA
kusano 2b45e8
      INTEGER K,LDA,LDB,LDC,M,N
kusano 2b45e8
      CHARACTER TRANA,TRANB
kusano 2b45e8
*     ..
kusano 2b45e8
*     .. Array Arguments ..
kusano 2b45e8
      COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
kusano 2b45e8
*     ..
kusano 2b45e8
*
kusano 2b45e8
*  Purpose
kusano 2b45e8
*  =======
kusano 2b45e8
*
kusano 2b45e8
*  CGEMM  performs one of the matrix-matrix operations
kusano 2b45e8
*
kusano 2b45e8
*     C := alpha*op( A )*op( B ) + beta*C,
kusano 2b45e8
*
kusano 2b45e8
*  where  op( X ) is one of
kusano 2b45e8
*
kusano 2b45e8
*     op( X ) = X   or   op( X ) = X'   or   op( X ) = conjg( X' ),
kusano 2b45e8
*
kusano 2b45e8
*  alpha and beta are scalars, and A, B and C are matrices, with op( A )
kusano 2b45e8
*  an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix.
kusano 2b45e8
*
kusano 2b45e8
*  Arguments
kusano 2b45e8
*  ==========
kusano 2b45e8
*
kusano 2b45e8
*  TRANA - CHARACTER*1.
kusano 2b45e8
*           On entry, TRANA specifies the form of op( A ) to be used in
kusano 2b45e8
*           the matrix multiplication as follows:
kusano 2b45e8
*
kusano 2b45e8
*              TRANA = 'N' or 'n',  op( A ) = A.
kusano 2b45e8
*
kusano 2b45e8
*              TRANA = 'T' or 't',  op( A ) = A'.
kusano 2b45e8
*
kusano 2b45e8
*              TRANA = 'C' or 'c',  op( A ) = conjg( A' ).
kusano 2b45e8
*
kusano 2b45e8
*           Unchanged on exit.
kusano 2b45e8
*
kusano 2b45e8
*  TRANB - CHARACTER*1.
kusano 2b45e8
*           On entry, TRANB specifies the form of op( B ) to be used in
kusano 2b45e8
*           the matrix multiplication as follows:
kusano 2b45e8
*
kusano 2b45e8
*              TRANB = 'N' or 'n',  op( B ) = B.
kusano 2b45e8
*
kusano 2b45e8
*              TRANB = 'T' or 't',  op( B ) = B'.
kusano 2b45e8
*
kusano 2b45e8
*              TRANB = 'C' or 'c',  op( B ) = conjg( B' ).
kusano 2b45e8
*
kusano 2b45e8
*           Unchanged on exit.
kusano 2b45e8
*
kusano 2b45e8
*  M      - INTEGER.
kusano 2b45e8
*           On entry,  M  specifies  the number  of rows  of the  matrix
kusano 2b45e8
*           op( A )  and of the  matrix  C.  M  must  be at least  zero.
kusano 2b45e8
*           Unchanged on exit.
kusano 2b45e8
*
kusano 2b45e8
*  N      - INTEGER.
kusano 2b45e8
*           On entry,  N  specifies the number  of columns of the matrix
kusano 2b45e8
*           op( B ) and the number of columns of the matrix C. N must be
kusano 2b45e8
*           at least zero.
kusano 2b45e8
*           Unchanged on exit.
kusano 2b45e8
*
kusano 2b45e8
*  K      - INTEGER.
kusano 2b45e8
*           On entry,  K  specifies  the number of columns of the matrix
kusano 2b45e8
*           op( A ) and the number of rows of the matrix op( B ). K must
kusano 2b45e8
*           be at least  zero.
kusano 2b45e8
*           Unchanged on exit.
kusano 2b45e8
*
kusano 2b45e8
*  ALPHA  - COMPLEX         .
kusano 2b45e8
*           On entry, ALPHA specifies the scalar alpha.
kusano 2b45e8
*           Unchanged on exit.
kusano 2b45e8
*
kusano 2b45e8
*  A      - COMPLEX          array of DIMENSION ( LDA, ka ), where ka is
kusano 2b45e8
*           k  when  TRANA = 'N' or 'n',  and is  m  otherwise.
kusano 2b45e8
*           Before entry with  TRANA = 'N' or 'n',  the leading  m by k
kusano 2b45e8
*           part of the array  A  must contain the matrix  A,  otherwise
kusano 2b45e8
*           the leading  k by m  part of the array  A  must contain  the
kusano 2b45e8
*           matrix A.
kusano 2b45e8
*           Unchanged on exit.
kusano 2b45e8
*
kusano 2b45e8
*  LDA    - INTEGER.
kusano 2b45e8
*           On entry, LDA specifies the first dimension of A as declared
kusano 2b45e8
*           in the calling (sub) program. When  TRANA = 'N' or 'n' then
kusano 2b45e8
*           LDA must be at least  max( 1, m ), otherwise  LDA must be at
kusano 2b45e8
*           least  max( 1, k ).
kusano 2b45e8
*           Unchanged on exit.
kusano 2b45e8
*
kusano 2b45e8
*  B      - COMPLEX          array of DIMENSION ( LDB, kb ), where kb is
kusano 2b45e8
*           n  when  TRANB = 'N' or 'n',  and is  k  otherwise.
kusano 2b45e8
*           Before entry with  TRANB = 'N' or 'n',  the leading  k by n
kusano 2b45e8
*           part of the array  B  must contain the matrix  B,  otherwise
kusano 2b45e8
*           the leading  n by k  part of the array  B  must contain  the
kusano 2b45e8
*           matrix B.
kusano 2b45e8
*           Unchanged on exit.
kusano 2b45e8
*
kusano 2b45e8
*  LDB    - INTEGER.
kusano 2b45e8
*           On entry, LDB specifies the first dimension of B as declared
kusano 2b45e8
*           in the calling (sub) program. When  TRANB = 'N' or 'n' then
kusano 2b45e8
*           LDB must be at least  max( 1, k ), otherwise  LDB must be at
kusano 2b45e8
*           least  max( 1, n ).
kusano 2b45e8
*           Unchanged on exit.
kusano 2b45e8
*
kusano 2b45e8
*  BETA   - COMPLEX         .
kusano 2b45e8
*           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
kusano 2b45e8
*           supplied as zero then C need not be set on input.
kusano 2b45e8
*           Unchanged on exit.
kusano 2b45e8
*
kusano 2b45e8
*  C      - COMPLEX          array of DIMENSION ( LDC, n ).
kusano 2b45e8
*           Before entry, the leading  m by n  part of the array  C must
kusano 2b45e8
*           contain the matrix  C,  except when  beta  is zero, in which
kusano 2b45e8
*           case C need not be set on entry.
kusano 2b45e8
*           On exit, the array  C  is overwritten by the  m by n  matrix
kusano 2b45e8
*           ( alpha*op( A )*op( B ) + beta*C ).
kusano 2b45e8
*
kusano 2b45e8
*  LDC    - INTEGER.
kusano 2b45e8
*           On entry, LDC specifies the first dimension of C as declared
kusano 2b45e8
*           in  the  calling  (sub)  program.   LDC  must  be  at  least
kusano 2b45e8
*           max( 1, m ).
kusano 2b45e8
*           Unchanged on exit.
kusano 2b45e8
*
kusano 2b45e8
*
kusano 2b45e8
*  Level 3 Blas routine.
kusano 2b45e8
*
kusano 2b45e8
*  -- Written on 8-February-1989.
kusano 2b45e8
*     Jack Dongarra, Argonne National Laboratory.
kusano 2b45e8
*     Iain Duff, AERE Harwell.
kusano 2b45e8
*     Jeremy Du Croz, Numerical Algorithms Group Ltd.
kusano 2b45e8
*     Sven Hammarling, Numerical Algorithms Group Ltd.
kusano 2b45e8
*
kusano 2b45e8
*
kusano 2b45e8
*     .. External Functions ..
kusano 2b45e8
      LOGICAL LSAME
kusano 2b45e8
      EXTERNAL LSAME
kusano 2b45e8
*     ..
kusano 2b45e8
*     .. External Subroutines ..
kusano 2b45e8
      EXTERNAL XERBLA
kusano 2b45e8
*     ..
kusano 2b45e8
*     .. Intrinsic Functions ..
kusano 2b45e8
      INTRINSIC CONJG,MAX
kusano 2b45e8
*     ..
kusano 2b45e8
*     .. Local Scalars ..
kusano 2b45e8
      COMPLEX TEMP
kusano 2b45e8
      INTEGER I,INFO,J,L,NCOLA,NROWA,NROWB
kusano 2b45e8
      LOGICAL CONJA,CONJB,NOTA,NOTB
kusano 2b45e8
*     ..
kusano 2b45e8
*     .. Parameters ..
kusano 2b45e8
      COMPLEX ONE
kusano 2b45e8
      PARAMETER (ONE= (1.0E+0,0.0E+0))
kusano 2b45e8
      COMPLEX ZERO
kusano 2b45e8
      PARAMETER (ZERO= (0.0E+0,0.0E+0))
kusano 2b45e8
*     ..
kusano 2b45e8
*
kusano 2b45e8
*     Set  NOTA  and  NOTB  as  true if  A  and  B  respectively are not
kusano 2b45e8
*     conjugated or transposed, set  CONJA and CONJB  as true if  A  and
kusano 2b45e8
*     B  respectively are to be  transposed but  not conjugated  and set
kusano 2b45e8
*     NROWA, NCOLA and  NROWB  as the number of rows and  columns  of  A
kusano 2b45e8
*     and the number of rows of  B  respectively.
kusano 2b45e8
*
kusano 2b45e8
      NOTA = LSAME(TRANA,'N')
kusano 2b45e8
      NOTB = LSAME(TRANB,'N')
kusano 2b45e8
      CONJA = LSAME(TRANA,'C')
kusano 2b45e8
      CONJB = LSAME(TRANB,'C')
kusano 2b45e8
      IF (NOTA) THEN
kusano 2b45e8
          NROWA = M
kusano 2b45e8
          NCOLA = K
kusano 2b45e8
      ELSE
kusano 2b45e8
          NROWA = K
kusano 2b45e8
          NCOLA = M
kusano 2b45e8
      END IF
kusano 2b45e8
      IF (NOTB) THEN
kusano 2b45e8
          NROWB = K
kusano 2b45e8
      ELSE
kusano 2b45e8
          NROWB = N
kusano 2b45e8
      END IF
kusano 2b45e8
*
kusano 2b45e8
*     Test the input parameters.
kusano 2b45e8
*
kusano 2b45e8
      INFO = 0
kusano 2b45e8
      IF ((.NOT.NOTA) .AND. (.NOT.CONJA) .AND.
kusano 2b45e8
     +    (.NOT.LSAME(TRANA,'T'))) THEN
kusano 2b45e8
          INFO = 1
kusano 2b45e8
      ELSE IF ((.NOT.NOTB) .AND. (.NOT.CONJB) .AND.
kusano 2b45e8
     +         (.NOT.LSAME(TRANB,'T'))) THEN
kusano 2b45e8
          INFO = 2
kusano 2b45e8
      ELSE IF (M.LT.0) THEN
kusano 2b45e8
          INFO = 3
kusano 2b45e8
      ELSE IF (N.LT.0) THEN
kusano 2b45e8
          INFO = 4
kusano 2b45e8
      ELSE IF (K.LT.0) THEN
kusano 2b45e8
          INFO = 5
kusano 2b45e8
      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
kusano 2b45e8
          INFO = 8
kusano 2b45e8
      ELSE IF (LDB.LT.MAX(1,NROWB)) THEN
kusano 2b45e8
          INFO = 10
kusano 2b45e8
      ELSE IF (LDC.LT.MAX(1,M)) THEN
kusano 2b45e8
          INFO = 13
kusano 2b45e8
      END IF
kusano 2b45e8
      IF (INFO.NE.0) THEN
kusano 2b45e8
          CALL XERBLA('CGEMM ',INFO)
kusano 2b45e8
          RETURN
kusano 2b45e8
      END IF
kusano 2b45e8
*
kusano 2b45e8
*     Quick return if possible.
kusano 2b45e8
*
kusano 2b45e8
      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
kusano 2b45e8
     +    (((ALPHA.EQ.ZERO).OR. (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
kusano 2b45e8
*
kusano 2b45e8
*     And when  alpha.eq.zero.
kusano 2b45e8
*
kusano 2b45e8
      IF (ALPHA.EQ.ZERO) THEN
kusano 2b45e8
          IF (BETA.EQ.ZERO) THEN
kusano 2b45e8
              DO 20 J = 1,N
kusano 2b45e8
                  DO 10 I = 1,M
kusano 2b45e8
                      C(I,J) = ZERO
kusano 2b45e8
   10             CONTINUE
kusano 2b45e8
   20         CONTINUE
kusano 2b45e8
          ELSE
kusano 2b45e8
              DO 40 J = 1,N
kusano 2b45e8
                  DO 30 I = 1,M
kusano 2b45e8
                      C(I,J) = BETA*C(I,J)
kusano 2b45e8
   30             CONTINUE
kusano 2b45e8
   40         CONTINUE
kusano 2b45e8
          END IF
kusano 2b45e8
          RETURN
kusano 2b45e8
      END IF
kusano 2b45e8
*
kusano 2b45e8
*     Start the operations.
kusano 2b45e8
*
kusano 2b45e8
      IF (NOTB) THEN
kusano 2b45e8
          IF (NOTA) THEN
kusano 2b45e8
*
kusano 2b45e8
*           Form  C := alpha*A*B + beta*C.
kusano 2b45e8
*
kusano 2b45e8
              DO 90 J = 1,N
kusano 2b45e8
                  IF (BETA.EQ.ZERO) THEN
kusano 2b45e8
                      DO 50 I = 1,M
kusano 2b45e8
                          C(I,J) = ZERO
kusano 2b45e8
   50                 CONTINUE
kusano 2b45e8
                  ELSE IF (BETA.NE.ONE) THEN
kusano 2b45e8
                      DO 60 I = 1,M
kusano 2b45e8
                          C(I,J) = BETA*C(I,J)
kusano 2b45e8
   60                 CONTINUE
kusano 2b45e8
                  END IF
kusano 2b45e8
                  DO 80 L = 1,K
kusano 2b45e8
                      IF (B(L,J).NE.ZERO) THEN
kusano 2b45e8
                          TEMP = ALPHA*B(L,J)
kusano 2b45e8
                          DO 70 I = 1,M
kusano 2b45e8
                              C(I,J) = C(I,J) + TEMP*A(I,L)
kusano 2b45e8
   70                     CONTINUE
kusano 2b45e8
                      END IF
kusano 2b45e8
   80             CONTINUE
kusano 2b45e8
   90         CONTINUE
kusano 2b45e8
          ELSE IF (CONJA) THEN
kusano 2b45e8
*
kusano 2b45e8
*           Form  C := alpha*conjg( A' )*B + beta*C.
kusano 2b45e8
*
kusano 2b45e8
              DO 120 J = 1,N
kusano 2b45e8
                  DO 110 I = 1,M
kusano 2b45e8
                      TEMP = ZERO
kusano 2b45e8
                      DO 100 L = 1,K
kusano 2b45e8
                          TEMP = TEMP + CONJG(A(L,I))*B(L,J)
kusano 2b45e8
  100                 CONTINUE
kusano 2b45e8
                      IF (BETA.EQ.ZERO) THEN
kusano 2b45e8
                          C(I,J) = ALPHA*TEMP
kusano 2b45e8
                      ELSE
kusano 2b45e8
                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
kusano 2b45e8
                      END IF
kusano 2b45e8
  110             CONTINUE
kusano 2b45e8
  120         CONTINUE
kusano 2b45e8
          ELSE
kusano 2b45e8
*
kusano 2b45e8
*           Form  C := alpha*A'*B + beta*C
kusano 2b45e8
*
kusano 2b45e8
              DO 150 J = 1,N
kusano 2b45e8
                  DO 140 I = 1,M
kusano 2b45e8
                      TEMP = ZERO
kusano 2b45e8
                      DO 130 L = 1,K
kusano 2b45e8
                          TEMP = TEMP + A(L,I)*B(L,J)
kusano 2b45e8
  130                 CONTINUE
kusano 2b45e8
                      IF (BETA.EQ.ZERO) THEN
kusano 2b45e8
                          C(I,J) = ALPHA*TEMP
kusano 2b45e8
                      ELSE
kusano 2b45e8
                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
kusano 2b45e8
                      END IF
kusano 2b45e8
  140             CONTINUE
kusano 2b45e8
  150         CONTINUE
kusano 2b45e8
          END IF
kusano 2b45e8
      ELSE IF (NOTA) THEN
kusano 2b45e8
          IF (CONJB) THEN
kusano 2b45e8
*
kusano 2b45e8
*           Form  C := alpha*A*conjg( B' ) + beta*C.
kusano 2b45e8
*
kusano 2b45e8
              DO 200 J = 1,N
kusano 2b45e8
                  IF (BETA.EQ.ZERO) THEN
kusano 2b45e8
                      DO 160 I = 1,M
kusano 2b45e8
                          C(I,J) = ZERO
kusano 2b45e8
  160                 CONTINUE
kusano 2b45e8
                  ELSE IF (BETA.NE.ONE) THEN
kusano 2b45e8
                      DO 170 I = 1,M
kusano 2b45e8
                          C(I,J) = BETA*C(I,J)
kusano 2b45e8
  170                 CONTINUE
kusano 2b45e8
                  END IF
kusano 2b45e8
                  DO 190 L = 1,K
kusano 2b45e8
                      IF (B(J,L).NE.ZERO) THEN
kusano 2b45e8
                          TEMP = ALPHA*CONJG(B(J,L))
kusano 2b45e8
                          DO 180 I = 1,M
kusano 2b45e8
                              C(I,J) = C(I,J) + TEMP*A(I,L)
kusano 2b45e8
  180                     CONTINUE
kusano 2b45e8
                      END IF
kusano 2b45e8
  190             CONTINUE
kusano 2b45e8
  200         CONTINUE
kusano 2b45e8
          ELSE
kusano 2b45e8
*
kusano 2b45e8
*           Form  C := alpha*A*B'          + beta*C
kusano 2b45e8
*
kusano 2b45e8
              DO 250 J = 1,N
kusano 2b45e8
                  IF (BETA.EQ.ZERO) THEN
kusano 2b45e8
                      DO 210 I = 1,M
kusano 2b45e8
                          C(I,J) = ZERO
kusano 2b45e8
  210                 CONTINUE
kusano 2b45e8
                  ELSE IF (BETA.NE.ONE) THEN
kusano 2b45e8
                      DO 220 I = 1,M
kusano 2b45e8
                          C(I,J) = BETA*C(I,J)
kusano 2b45e8
  220                 CONTINUE
kusano 2b45e8
                  END IF
kusano 2b45e8
                  DO 240 L = 1,K
kusano 2b45e8
                      IF (B(J,L).NE.ZERO) THEN
kusano 2b45e8
                          TEMP = ALPHA*B(J,L)
kusano 2b45e8
                          DO 230 I = 1,M
kusano 2b45e8
                              C(I,J) = C(I,J) + TEMP*A(I,L)
kusano 2b45e8
  230                     CONTINUE
kusano 2b45e8
                      END IF
kusano 2b45e8
  240             CONTINUE
kusano 2b45e8
  250         CONTINUE
kusano 2b45e8
          END IF
kusano 2b45e8
      ELSE IF (CONJA) THEN
kusano 2b45e8
          IF (CONJB) THEN
kusano 2b45e8
*
kusano 2b45e8
*           Form  C := alpha*conjg( A' )*conjg( B' ) + beta*C.
kusano 2b45e8
*
kusano 2b45e8
              DO 280 J = 1,N
kusano 2b45e8
                  DO 270 I = 1,M
kusano 2b45e8
                      TEMP = ZERO
kusano 2b45e8
                      DO 260 L = 1,K
kusano 2b45e8
                          TEMP = TEMP + CONJG(A(L,I))*CONJG(B(J,L))
kusano 2b45e8
  260                 CONTINUE
kusano 2b45e8
                      IF (BETA.EQ.ZERO) THEN
kusano 2b45e8
                          C(I,J) = ALPHA*TEMP
kusano 2b45e8
                      ELSE
kusano 2b45e8
                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
kusano 2b45e8
                      END IF
kusano 2b45e8
  270             CONTINUE
kusano 2b45e8
  280         CONTINUE
kusano 2b45e8
          ELSE
kusano 2b45e8
*
kusano 2b45e8
*           Form  C := alpha*conjg( A' )*B' + beta*C
kusano 2b45e8
*
kusano 2b45e8
              DO 310 J = 1,N
kusano 2b45e8
                  DO 300 I = 1,M
kusano 2b45e8
                      TEMP = ZERO
kusano 2b45e8
                      DO 290 L = 1,K
kusano 2b45e8
                          TEMP = TEMP + CONJG(A(L,I))*B(J,L)
kusano 2b45e8
  290                 CONTINUE
kusano 2b45e8
                      IF (BETA.EQ.ZERO) THEN
kusano 2b45e8
                          C(I,J) = ALPHA*TEMP
kusano 2b45e8
                      ELSE
kusano 2b45e8
                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
kusano 2b45e8
                      END IF
kusano 2b45e8
  300             CONTINUE
kusano 2b45e8
  310         CONTINUE
kusano 2b45e8
          END IF
kusano 2b45e8
      ELSE
kusano 2b45e8
          IF (CONJB) THEN
kusano 2b45e8
*
kusano 2b45e8
*           Form  C := alpha*A'*conjg( B' ) + beta*C
kusano 2b45e8
*
kusano 2b45e8
              DO 340 J = 1,N
kusano 2b45e8
                  DO 330 I = 1,M
kusano 2b45e8
                      TEMP = ZERO
kusano 2b45e8
                      DO 320 L = 1,K
kusano 2b45e8
                          TEMP = TEMP + A(L,I)*CONJG(B(J,L))
kusano 2b45e8
  320                 CONTINUE
kusano 2b45e8
                      IF (BETA.EQ.ZERO) THEN
kusano 2b45e8
                          C(I,J) = ALPHA*TEMP
kusano 2b45e8
                      ELSE
kusano 2b45e8
                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
kusano 2b45e8
                      END IF
kusano 2b45e8
  330             CONTINUE
kusano 2b45e8
  340         CONTINUE
kusano 2b45e8
          ELSE
kusano 2b45e8
*
kusano 2b45e8
*           Form  C := alpha*A'*B' + beta*C
kusano 2b45e8
*
kusano 2b45e8
              DO 370 J = 1,N
kusano 2b45e8
                  DO 360 I = 1,M
kusano 2b45e8
                      TEMP = ZERO
kusano 2b45e8
                      DO 350 L = 1,K
kusano 2b45e8
                          TEMP = TEMP + A(L,I)*B(J,L)
kusano 2b45e8
  350                 CONTINUE
kusano 2b45e8
                      IF (BETA.EQ.ZERO) THEN
kusano 2b45e8
                          C(I,J) = ALPHA*TEMP
kusano 2b45e8
                      ELSE
kusano 2b45e8
                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
kusano 2b45e8
                      END IF
kusano 2b45e8
  360             CONTINUE
kusano 2b45e8
  370         CONTINUE
kusano 2b45e8
          END IF
kusano 2b45e8
      END IF
kusano 2b45e8
*
kusano 2b45e8
      RETURN
kusano 2b45e8
*
kusano 2b45e8
*     End of CGEMM .
kusano 2b45e8
*
kusano 2b45e8
      END