LCOV - code coverage report
Current view: top level - src/aobasis - ai_contraction.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4dc10b3) Lines: 69 142 48.6 %
Date: 2024-11-21 06:45:46 Functions: 4 5 80.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Set of routines to:
      10             : !>        Contract integrals over primitive Gaussians
      11             : !>        Decontract (density) matrices
      12             : !>        Trace matrices to get forces
      13             : !>        Block copy and add matrices
      14             : !> \par History
      15             : !>      Replace dgemm by MATMUL: Massive speedups in openMP loops (JGH, 12.2019)
      16             : !> \author JGH (01.07.2014)
      17             : ! **************************************************************************************************
      18             : MODULE ai_contraction
      19             : 
      20             :    USE kinds,                           ONLY: dp
      21             : #include "../base/base_uses.f90"
      22             : 
      23             :    IMPLICIT NONE
      24             : 
      25             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ai_contraction'
      26             : 
      27             :    PRIVATE
      28             : 
      29             :    PUBLIC :: contraction, decontraction, block_add, force_trace
      30             : 
      31             :    INTERFACE contraction
      32             :       MODULE PROCEDURE contraction_ab, contraction_abc
      33             :    END INTERFACE
      34             : 
      35             :    INTERFACE decontraction
      36             :       MODULE PROCEDURE decontraction_ab
      37             :    END INTERFACE
      38             : 
      39             :    INTERFACE force_trace
      40             :       MODULE PROCEDURE force_trace_ab
      41             :    END INTERFACE
      42             : 
      43             :    INTERFACE block_add
      44             :       MODULE PROCEDURE block_add_ab
      45             :    END INTERFACE
      46             : 
      47             : ! **************************************************************************************************
      48             : 
      49             : CONTAINS
      50             : 
      51             : ! **************************************************************************************************
      52             : !> \brief Applying the contraction coefficients to a set of two-center primitive
      53             : !>        integrals
      54             : !>        QAB <- CA(T) * SAB * CB
      55             : !>        QAB is optionally scaled with "fscale"
      56             : !>        Variable "trans" requests the output to be QAB(T)
      57             : !>        If only one of the transformation matrix is given, only a half
      58             : !>        transformation is done
      59             : !>        Active dimensions are: QAB(ma,mb), SAB(na,nb)
      60             : !> \param sab     Input matrix, dimension(:,:)
      61             : !> \param qab     Output matrix, dimension(:,:)
      62             : !> \param ca      Left transformation matrix, optional
      63             : !> \param na      First dimension of ca, optional
      64             : !> \param ma      Second dimension of ca, optional
      65             : !> \param cb      Right transformation matrix, optional
      66             : !> \param nb      First dimension of cb, optional
      67             : !> \param mb      Second dimension of cb, optional
      68             : !> \param fscale  Optional scaling of output
      69             : !> \param trans   Optional transposition of output
      70             : ! **************************************************************************************************
      71    19274566 :    SUBROUTINE contraction_ab(sab, qab, ca, na, ma, cb, nb, mb, fscale, trans)
      72             : 
      73             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: sab
      74             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: qab
      75             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
      76             :          OPTIONAL                                        :: ca
      77             :       INTEGER, INTENT(IN), OPTIONAL                      :: na, ma
      78             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
      79             :          OPTIONAL                                        :: cb
      80             :       INTEGER, INTENT(IN), OPTIONAL                      :: nb, mb
      81             :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: fscale
      82             :       LOGICAL, INTENT(IN), OPTIONAL                      :: trans
      83             : 
      84             :       INTEGER                                            :: lda, ldb, ldq, lds, ldw, mal, mbl, nal, &
      85             :                                                             nbl
      86             :       LOGICAL                                            :: my_trans
      87             :       REAL(KIND=dp)                                      :: fs
      88    19274566 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: work
      89             : 
      90             : ! Should output matrix be transposed?
      91             : 
      92    19274566 :       IF (PRESENT(trans)) THEN
      93    19273842 :          my_trans = trans
      94             :       ELSE
      95             :          my_trans = .FALSE.
      96             :       END IF
      97             : 
      98             :       ! Scaling of output matrix
      99    19274566 :       IF (PRESENT(fscale)) THEN
     100    19272816 :          fs = fscale
     101             :       ELSE
     102             :          fs = 1.0_dp
     103             :       END IF
     104             : 
     105             :       ! Active matrix size
     106    19274566 :       IF (PRESENT(ca)) THEN
     107    19274566 :          IF (PRESENT(na)) THEN
     108    19274566 :             nal = na
     109             :          ELSE
     110           0 :             nal = SIZE(ca, 1)
     111             :          END IF
     112    19274566 :          IF (PRESENT(ma)) THEN
     113    19274566 :             mal = ma
     114             :          ELSE
     115           0 :             mal = SIZE(ca, 2)
     116             :          END IF
     117    19274566 :          lda = SIZE(ca, 1)
     118             :       END IF
     119    19274566 :       IF (PRESENT(cb)) THEN
     120    19274566 :          IF (PRESENT(nb)) THEN
     121    19274566 :             nbl = nb
     122             :          ELSE
     123           0 :             nbl = SIZE(cb, 1)
     124             :          END IF
     125    19274566 :          IF (PRESENT(mb)) THEN
     126    19274566 :             mbl = mb
     127             :          ELSE
     128           0 :             mbl = SIZE(cb, 2)
     129             :          END IF
     130    19274566 :          ldb = SIZE(cb, 1)
     131             :       END IF
     132             : 
     133    19274566 :       lds = SIZE(sab, 1)
     134    19274566 :       ldq = SIZE(qab, 1)
     135             : 
     136    19274566 :       IF (PRESENT(ca) .AND. PRESENT(cb)) THEN
     137             :          ! Full transform
     138    77098264 :          ALLOCATE (work(nal, mbl))
     139    19274566 :          ldw = nal
     140             : !dg      CALL dgemm("N", "N", nal, mbl, nbl, 1.0_dp, sab(1, 1), lds, cb(1, 1), ldb, 0.0_dp, work(1, 1), ldw)
     141 16789299197 :          work(1:nal, 1:mbl) = MATMUL(sab(1:nal, 1:nbl), cb(1:nbl, 1:mbl))
     142    19274566 :          IF (my_trans) THEN
     143             : !dg         CALL dgemm("T", "N", mbl, mal, nal, fs, work(1, 1), ldw, ca(1, 1), lda, 0.0_dp, qab(1, 1), ldq)
     144  2222280802 :             qab(1:mbl, 1:mal) = fs*MATMUL(TRANSPOSE(work(1:nal, 1:mbl)), ca(1:nal, 1:mal))
     145             :          ELSE
     146             : !dg         CALL dgemm("T", "N", mal, mbl, nal, fs, ca(1, 1), lda, work(1, 1), ldw, 0.0_dp, qab(1, 1), ldq)
     147  5053534043 :             qab(1:mal, 1:mbl) = fs*MATMUL(TRANSPOSE(ca(1:nal, 1:mal)), work(1:nal, 1:mbl))
     148             :          END IF
     149    19274566 :          DEALLOCATE (work)
     150           0 :       ELSE IF (PRESENT(ca)) THEN
     151           0 :          IF (PRESENT(nb)) THEN
     152           0 :             nbl = nb
     153             :          ELSE
     154           0 :             nbl = SIZE(sab, 2)
     155             :          END IF
     156           0 :          IF (my_trans) THEN
     157             : !dg         CALL dgemm("T", "N", nbl, mal, nal, fs, sab(1, 1), lds, ca(1, 1), lda, 0.0_dp, qab(1, 1), ldq)
     158           0 :             qab(1:nbl, 1:mal) = fs*MATMUL(TRANSPOSE(sab(1:nal, 1:nbl)), ca(1:nal, 1:mal))
     159             :          ELSE
     160             : !dg         CALL dgemm("T", "N", mal, nbl, nal, fs, ca(1, 1), lda, sab(1, 1), lds, 0.0_dp, qab(1, 1), ldq)
     161           0 :             qab(1:mal, 1:nbl) = fs*MATMUL(TRANSPOSE(ca(1:nal, 1:mal)), sab(1:nal, 1:nbl))
     162             :          END IF
     163           0 :       ELSE IF (PRESENT(cb)) THEN
     164           0 :          IF (PRESENT(na)) THEN
     165           0 :             nal = na
     166             :          ELSE
     167           0 :             nal = SIZE(sab, 1)
     168             :          END IF
     169           0 :          IF (my_trans) THEN
     170             : !dg         CALL dgemm("N", "N", nal, mbl, nbl, fs, sab(1, 1), lds, cb(1, 1), ldb, 0.0_dp, qab, ldq)
     171           0 :             qab(1:nal, 1:mbl) = fs*MATMUL(sab(1:nal, 1:nbl), cb(1:nbl, 1:mbl))
     172             :          ELSE
     173             : !dg         CALL dgemm("T", "T", mbl, nal, nbl, fs, cb(1, 1), ldb, sab(1, 1), lds, 0.0_dp, qab, ldq)
     174           0 :             qab(1:mbl, 1:nal) = fs*MATMUL(TRANSPOSE(cb(1:nbl, 1:mbl)), TRANSPOSE(sab(1:nal, 1:nbl)))
     175             :          END IF
     176             :       ELSE
     177             :          ! Copy of arrays is not covered here
     178           0 :          CPABORT("Copy of arrays is not covered here")
     179             :       END IF
     180             : 
     181    19274566 :    END SUBROUTINE contraction_ab
     182             : 
     183             : ! **************************************************************************************************
     184             : !> \brief Applying the contraction coefficients to a tripple set integrals
     185             : !>        QABC <- CA(T) * SABC * CB * CC
     186             : !>        If only one or two of the transformation matrices are given, only a
     187             : !>        part transformation is done
     188             : !> \param sabc    Input matrix, dimension(:,:)
     189             : !> \param qabc    Output matrix, dimension(:,:)
     190             : !> \param ca      Transformation matrix (index 1), optional
     191             : !> \param na      First dimension of ca, optional
     192             : !> \param ma      Second dimension of ca, optional
     193             : !> \param cb      Transformation matrix (index 2), optional
     194             : !> \param nb      First dimension of cb, optional
     195             : !> \param mb      Second dimension of cb, optional
     196             : !> \param cc      Transformation matrix (index 3), optional
     197             : !> \param nc      First dimension of cc, optional
     198             : !> \param mc      Second dimension of cc, optional
     199             : ! **************************************************************************************************
     200           0 :    SUBROUTINE contraction_abc(sabc, qabc, ca, na, ma, cb, nb, mb, cc, nc, mc)
     201             : 
     202             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN)      :: sabc
     203             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(INOUT)   :: qabc
     204             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
     205             :          OPTIONAL                                        :: ca
     206             :       INTEGER, INTENT(IN), OPTIONAL                      :: na, ma
     207             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
     208             :          OPTIONAL                                        :: cb
     209             :       INTEGER, INTENT(IN), OPTIONAL                      :: nb, mb
     210             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
     211             :          OPTIONAL                                        :: cc
     212             :       INTEGER, INTENT(IN), OPTIONAL                      :: nc, mc
     213             : 
     214             :       INTEGER                                            :: lda, ldb, ldc, mal, mbl, mcl, nal, nbl, &
     215             :                                                             ncl
     216           0 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: work1, work2, work3, work4
     217             : 
     218             : ! Active matrix size
     219             : 
     220           0 :       IF (PRESENT(ca)) THEN
     221           0 :          IF (PRESENT(na)) THEN
     222           0 :             nal = na
     223             :          ELSE
     224           0 :             nal = SIZE(ca, 1)
     225             :          END IF
     226           0 :          IF (PRESENT(ma)) THEN
     227           0 :             mal = ma
     228             :          ELSE
     229           0 :             mal = SIZE(ca, 2)
     230             :          END IF
     231           0 :          lda = SIZE(ca, 1)
     232             :       END IF
     233           0 :       IF (PRESENT(cb)) THEN
     234           0 :          IF (PRESENT(nb)) THEN
     235           0 :             nbl = nb
     236             :          ELSE
     237           0 :             nbl = SIZE(cb, 1)
     238             :          END IF
     239           0 :          IF (PRESENT(mb)) THEN
     240           0 :             mbl = mb
     241             :          ELSE
     242           0 :             mbl = SIZE(cb, 2)
     243             :          END IF
     244           0 :          ldb = SIZE(cb, 1)
     245             :       END IF
     246           0 :       IF (PRESENT(cc)) THEN
     247           0 :          IF (PRESENT(nc)) THEN
     248           0 :             ncl = nc
     249             :          ELSE
     250           0 :             ncl = SIZE(cc, 1)
     251             :          END IF
     252           0 :          IF (PRESENT(mc)) THEN
     253           0 :             mcl = mc
     254             :          ELSE
     255           0 :             mcl = SIZE(cc, 2)
     256             :          END IF
     257           0 :          ldc = SIZE(cc, 1)
     258             :       END IF
     259             : 
     260           0 :       IF (PRESENT(ca) .AND. PRESENT(cb) .AND. PRESENT(cc)) THEN
     261             :          ! Full transform
     262           0 :          ALLOCATE (work1(nal, nbl, ncl))
     263             :          ! make sure that we have contiguous memory, needed for transpose algorithm
     264           0 :          work1(1:nal, 1:nbl, 1:ncl) = sabc(1:nal, 1:nbl, 1:ncl)
     265             :          !
     266           0 :          ALLOCATE (work2(nbl, ncl, mal))
     267             :          CALL dgemm("T", "N", nbl*ncl, mal, nal, 1.0_dp, work1(1, 1, 1), nal, ca(1, 1), lda, &
     268           0 :                     0.0_dp, work2(1, 1, 1), nbl*ncl)
     269             :          !
     270           0 :          ALLOCATE (work3(ncl, mal, mbl))
     271             :          CALL dgemm("T", "N", ncl*mal, mbl, nbl, 1.0_dp, work2(1, 1, 1), nbl, cb(1, 1), ldb, &
     272           0 :                     0.0_dp, work3(1, 1, 1), ncl*mal)
     273             :          !
     274           0 :          ALLOCATE (work4(mal, mbl, mcl))
     275             :          CALL dgemm("T", "N", mal*mbl, mcl, ncl, 1.0_dp, work3(1, 1, 1), ncl, cc(1, 1), ldc, &
     276           0 :                     0.0_dp, work4(1, 1, 1), mal*mbl)
     277             :          !
     278           0 :          qabc(1:mal, 1:mbl, 1:mcl) = work4(1:mal, 1:mbl, 1:mcl)
     279             :          !
     280           0 :          DEALLOCATE (work1, work2, work3, work4)
     281             :          !
     282           0 :       ELSE IF (PRESENT(ca) .AND. PRESENT(cb)) THEN
     283           0 :          CPABORT("Not implemented")
     284           0 :       ELSE IF (PRESENT(ca) .AND. PRESENT(cc)) THEN
     285           0 :          CPABORT("Not implemented")
     286           0 :       ELSE IF (PRESENT(cb) .AND. PRESENT(cc)) THEN
     287           0 :          CPABORT("Not implemented")
     288           0 :       ELSE IF (PRESENT(ca)) THEN
     289           0 :          CPABORT("Not implemented")
     290           0 :       ELSE IF (PRESENT(cb)) THEN
     291           0 :          CPABORT("Not implemented")
     292           0 :       ELSE IF (PRESENT(cc)) THEN
     293           0 :          CPABORT("Not implemented")
     294             :       ELSE
     295             :          ! Copy of arrays is not covered here
     296           0 :          CPABORT("Copy of arrays is not covered here")
     297             :       END IF
     298             : 
     299           0 :    END SUBROUTINE contraction_abc
     300             : 
     301             : ! **************************************************************************************************
     302             : !> \brief Applying the de-contraction coefficients to a matrix
     303             : !>        QAB <- CA * SAB * CB(T)
     304             : !>        Variable "trans" requests the input matrix to be SAB(T)
     305             : !>        Active dimensions are: QAB(na,nb), SAB(ma,mb)
     306             : !> \param sab     Input matrix, dimension(:,:)
     307             : !> \param qab     Output matrix, dimension(:,:)
     308             : !> \param ca      Left transformation matrix
     309             : !> \param na      First dimension of ca
     310             : !> \param ma      Second dimension of ca
     311             : !> \param cb      Right transformation matrix
     312             : !> \param nb      First dimension of cb
     313             : !> \param mb      Second dimension of cb
     314             : !> \param trans   Optional transposition of input matrix
     315             : ! **************************************************************************************************
     316     1664667 :    SUBROUTINE decontraction_ab(sab, qab, ca, na, ma, cb, nb, mb, trans)
     317             : 
     318             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: sab
     319             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: qab
     320             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: ca
     321             :       INTEGER, INTENT(IN)                                :: na, ma
     322             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: cb
     323             :       INTEGER, INTENT(IN)                                :: nb, mb
     324             :       LOGICAL, INTENT(IN), OPTIONAL                      :: trans
     325             : 
     326             :       INTEGER                                            :: lda, ldb, ldq, lds, ldw
     327             :       LOGICAL                                            :: my_trans
     328     1664667 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: work
     329             : 
     330             :       ! Should input matrix be transposed?
     331     1664667 :       IF (PRESENT(trans)) THEN
     332     1664667 :          my_trans = trans
     333             :       ELSE
     334             :          my_trans = .FALSE.
     335             :       END IF
     336             : 
     337     1664667 :       lds = SIZE(sab, 1)
     338     1664667 :       ldq = SIZE(qab, 1)
     339     1664667 :       lda = SIZE(ca, 1)
     340     1664667 :       ldb = SIZE(cb, 1)
     341             : 
     342     6658668 :       ALLOCATE (work(na, mb))
     343     1664667 :       ldw = na
     344             : 
     345     1664667 :       IF (my_trans) THEN
     346             : !dg      CALL dgemm("N", "T", na, mb, ma, 1.0_dp, ca, lda, sab, lds, 0.0_dp, work, ldw)
     347   650765605 :          work(1:na, 1:mb) = MATMUL(ca(1:na, 1:ma), TRANSPOSE(sab(1:mb, 1:ma)))
     348             :       ELSE
     349             : !dg      CALL dgemm("N", "N", na, mb, ma, 1.0_dp, ca, lda, sab, lds, 0.0_dp, work, ldw)
     350   602278495 :          work(1:na, 1:mb) = MATMUL(ca(1:na, 1:ma), sab(1:ma, 1:mb))
     351             :       END IF
     352             : !dg   CALL dgemm("N", "T", na, nb, mb, 1.0_dp, work, ldw, cb, ldb, 0.0_dp, qab, ldq)
     353  3628347731 :       qab(1:na, 1:nb) = MATMUL(work(1:na, 1:mb), TRANSPOSE(cb(1:nb, 1:mb)))
     354             : 
     355     1664667 :       DEALLOCATE (work)
     356             : 
     357     1664667 :    END SUBROUTINE decontraction_ab
     358             : 
     359             : ! **************************************************************************************************
     360             : !> \brief Routine to trace a series of matrices with another matrix
     361             : !>        Calculate forces of type f(:) = Trace(Pab*Sab(:))
     362             : !> \param force   Vector to hold output forces
     363             : !> \param sab     Input vector of matrices, dimension (:,:,:)
     364             : !> \param pab     Input matrix
     365             : !> \param na      Active first dimension
     366             : !> \param nb      Active second dimension
     367             : !> \param m       Number of matrices to be traced
     368             : !> \param trans   Matrices are transposed (Sab and Pab)
     369             : ! **************************************************************************************************
     370     1664667 :    SUBROUTINE force_trace_ab(force, sab, pab, na, nb, m, trans)
     371             : 
     372             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: force
     373             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN)      :: sab
     374             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: pab
     375             :       INTEGER, INTENT(IN)                                :: na, nb, m
     376             :       LOGICAL, INTENT(IN), OPTIONAL                      :: trans
     377             : 
     378             :       INTEGER                                            :: i
     379             :       LOGICAL                                            :: my_trans
     380             : 
     381     1664667 :       CPASSERT(m <= SIZE(SAB, 3))
     382     1664667 :       CPASSERT(m <= SIZE(force, 1))
     383             : 
     384             :       ! are matrices transposed?
     385     1664667 :       IF (PRESENT(trans)) THEN
     386           0 :          my_trans = trans
     387             :       ELSE
     388             :          my_trans = .FALSE.
     389             :       END IF
     390             : 
     391     6658668 :       DO i = 1, m
     392     6658668 :          IF (my_trans) THEN
     393           0 :             force(i) = SUM(sab(1:nb, 1:na, i)*pab(1:nb, 1:na))
     394             :          ELSE
     395  1083790743 :             force(i) = SUM(sab(1:na, 1:nb, i)*pab(1:na, 1:nb))
     396             :          END IF
     397             :       END DO
     398             : 
     399     1664667 :    END SUBROUTINE force_trace_ab
     400             : 
     401             : ! **************************************************************************************************
     402             : !> \brief Copy a block out of a matrix and add it to another matrix
     403             : !>        SAB = SAB + QAB  or  QAB = QAB + SAB
     404             : !>        QAB(ia:,ib:) and SAB(1:,1:)
     405             : !> \param dir    "IN" and "OUT" defines direction of copy
     406             : !> \param sab    Matrix input for "IN", output for "OUT"
     407             : !> \param na     first dimension of matrix to copy
     408             : !> \param nb     second dimension of matrix to copy
     409             : !> \param qab    Matrix output for "IN", input for "OUT"
     410             : !>               Use subblock of this matrix
     411             : !> \param ia     Starting index in qab first dimension
     412             : !> \param ib     Starting index in qab second dimension
     413             : !> \param trans  Matrices (qab and sab) are transposed
     414             : ! **************************************************************************************************
     415    21677378 :    SUBROUTINE block_add_ab(dir, sab, na, nb, qab, ia, ib, trans)
     416             : 
     417             :       CHARACTER(LEN=*), INTENT(IN)                       :: dir
     418             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: sab
     419             :       INTEGER, INTENT(IN)                                :: na, nb
     420             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: qab
     421             :       INTEGER, INTENT(IN)                                :: ia, ib
     422             :       LOGICAL, INTENT(IN), OPTIONAL                      :: trans
     423             : 
     424             :       INTEGER                                            :: ja, jb
     425             :       LOGICAL                                            :: my_trans
     426             : 
     427    21677378 :       IF (PRESENT(trans)) THEN
     428    21676654 :          my_trans = trans
     429             :       ELSE
     430             :          my_trans = .FALSE.
     431             :       END IF
     432             : 
     433    21677378 :       IF (dir == "IN" .OR. dir == "in") THEN
     434             :          !  QAB(block) <= SAB
     435    20012711 :          ja = ia + na - 1
     436    20012711 :          jb = ib + nb - 1
     437    20012711 :          IF (my_trans) THEN
     438   190065871 :             qab(ib:jb, ia:ja) = qab(ib:jb, ia:ja) + sab(1:nb, 1:na)
     439             :          ELSE
     440   380103905 :             qab(ia:ja, ib:jb) = qab(ia:ja, ib:jb) + sab(1:na, 1:nb)
     441             :          END IF
     442     1664667 :       ELSEIF (dir == "OUT" .OR. dir == "out") THEN
     443             :          !  SAB <= QAB(block)
     444     1664667 :          ja = ia + na - 1
     445     1664667 :          jb = ib + nb - 1
     446     1664667 :          IF (my_trans) THEN
     447    31278372 :             sab(1:nb, 1:na) = sab(1:nb, 1:na) + qab(ib:jb, ia:ja)
     448             :          ELSE
     449    26715152 :             sab(1:na, 1:nb) = sab(1:na, 1:nb) + qab(ia:ja, ib:jb)
     450             :          END IF
     451             :       ELSE
     452           0 :          CPABORT("")
     453             :       END IF
     454             : 
     455    21677378 :    END SUBROUTINE block_add_ab
     456             : ! **************************************************************************************************
     457             : 
     458             : END MODULE ai_contraction

Generated by: LCOV version 1.15