LCOV - code coverage report
Current view: top level - src/aobasis - ai_contraction_sphi.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:85b8a9b) Lines: 93.8 % 113 106
Test Date: 2026-06-14 06:48:14 Functions: 100.0 % 4 4

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Contraction of integrals over primitive Cartesian Gaussians based on the contraction
      10              : !>        matrix sphi which is part of the gto_basis_set_type
      11              : !> \par History
      12              : !>      -added abc_contract_xsmm routine, A. Bussy (04.2020)
      13              : !> \author Dorothea Golze (05.2016)
      14              : ! **************************************************************************************************
      15              : MODULE ai_contraction_sphi
      16              : 
      17              :    USE kinds, ONLY: dp, int_8
      18              : #if defined(__LIBXS)
      19              :    USE LIBXS_JIT, ONLY: libxs_gemm_config_t, libxs_gemm_dispatch, &
      20              :                         libxs_gemm_call, LIBXS_DATATYPE_F64, C_LOC
      21              : #endif
      22              : 
      23              : #include "../base/base_uses.f90"
      24              : 
      25              :    IMPLICIT NONE
      26              : 
      27              :    PRIVATE
      28              : 
      29              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ai_contraction_sphi'
      30              : 
      31              :    PUBLIC :: ab_contract, abc_contract, abcd_contract, abc_contract_xsmm
      32              : 
      33              : CONTAINS
      34              : 
      35              : ! **************************************************************************************************
      36              : !> \brief contract overlap integrals (a,b) and transfer to spherical Gaussians
      37              : !> \param abint contracted, normalized integrals of spherical Gaussians
      38              : !> \param sab uncontracted, unnormalized integrals of primitive Cartesian Gaussians
      39              : !> \param sphi_a contraction matrix for center a
      40              : !> \param sphi_b contraction matrix for center b
      41              : !> \param ncoa number of cartesian orbitals on a
      42              : !> \param ncob number of cartesian orbitals on b
      43              : !> \param nsgfa number of spherical Gaussian functions on a
      44              : !> \param nsgfb number of spherical Gaussian functions on b
      45              : ! **************************************************************************************************
      46      1169586 :    SUBROUTINE ab_contract(abint, sab, sphi_a, sphi_b, ncoa, ncob, nsgfa, nsgfb)
      47              : 
      48              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: abint
      49              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: sab, sphi_a, sphi_b
      50              :       INTEGER, INTENT(IN)                                :: ncoa, ncob, nsgfa, nsgfb
      51              : 
      52              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'ab_contract'
      53              : 
      54              :       INTEGER                                            :: handle
      55      1169586 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: cpp
      56              : 
      57      1169586 :       CALL timeset(routineN, handle)
      58              : 
      59      1169586 :       CPASSERT(ncob <= SIZE(sab, 2))
      60              : 
      61      1169586 :       IF ((nsgfa*ncob*(ncoa + nsgfb)) <= (nsgfb*ncoa*(ncob + nsgfa))) THEN ! (sphi_a x sab) x sphi_b
      62      3186868 :          ALLOCATE (cpp(nsgfa, ncob))
      63              :          ! [nsgfa,ncoa] x [ncoa,ncob] -> [nsgfa,ncob]
      64     24630064 :          CALL dgemm("T", "N", nsgfa, ncob, ncoa, 1._dp, sphi_a, SIZE(sphi_a, 1), sab, SIZE(sab, 1), 0.0_dp, cpp, nsgfa)
      65              :          ! [nsgfa,ncob] x [ncob,nsgfb] -> [nsgfa,nsgfb]
      66              :          CALL dgemm("N", "N", nsgfa, nsgfb, ncob, 1._dp, cpp, nsgfa, sphi_b, SIZE(sphi_b, 1), 0.0_dp, &
      67     54550439 :                     abint, SIZE(abint, 1))
      68              :       ELSE ! sphi_a x (sab x sphi_b)
      69      1491476 :          ALLOCATE (cpp(ncoa, nsgfb))
      70              :          ! [ncoa,ncob] x [ncob,nsgfb] -> [ncoa,nsgfb]
      71      8303829 :          CALL dgemm("N", "N", ncoa, nsgfb, ncob, 1._dp, sab, SIZE(sab, 1), sphi_b, SIZE(sphi_b, 1), 0.0_dp, cpp, ncoa)
      72              :          ! [nsgfa,ncoa] x [ncoa,nsgfb] -> [nsgfa,nsgfb]
      73              :          CALL dgemm("T", "N", nsgfa, nsgfb, ncoa, 1._dp, sphi_a, SIZE(sphi_a, 1), cpp, ncoa, 0.0_dp, &
      74     13928925 :                     abint, SIZE(abint, 1))
      75              :       END IF
      76              : 
      77      1169586 :       DEALLOCATE (cpp)
      78              : 
      79      1169586 :       CALL timestop(handle)
      80              : 
      81      1169586 :    END SUBROUTINE ab_contract
      82              : 
      83              : ! **************************************************************************************************
      84              : !> \brief contract three-center overlap integrals (a,b,c) and transfer
      85              : !>        to spherical Gaussians
      86              : !> \param abcint contracted, normalized integrals of spherical Gaussians
      87              : !> \param sabc uncontracted, unnormalized integrals of primitive Cartesian Gaussians
      88              : !> \param sphi_a contraction matrix for center a
      89              : !> \param sphi_b contraction matrix for center b
      90              : !> \param sphi_c contraction matrix for center c
      91              : !> \param ncoa number of cartesian orbitals on a
      92              : !> \param ncob number of cartesian orbitals on b
      93              : !> \param ncoc number of cartesian orbitals on c
      94              : !> \param nsgfa number of spherical Gaussian functions on a
      95              : !> \param nsgfb number of spherical Gaussian functions on b
      96              : !> \param nsgfc number of spherical Gaussian functions on c
      97              : ! **************************************************************************************************
      98       126004 :    SUBROUTINE abc_contract(abcint, sabc, sphi_a, sphi_b, sphi_c, ncoa, ncob, ncoc, &
      99              :                            nsgfa, nsgfb, nsgfc)
     100              : 
     101              :       REAL(KIND=dp), DIMENSION(:, :, :)                  :: abcint, sabc
     102              :       REAL(KIND=dp), DIMENSION(:, :)                     :: sphi_a, sphi_b, sphi_c
     103              :       INTEGER, INTENT(IN)                                :: ncoa, ncob, ncoc, nsgfa, nsgfb, nsgfc
     104              : 
     105              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'abc_contract'
     106              : 
     107              :       INTEGER                                            :: handle, i, m1, m2, m3, msphia, msphib, &
     108              :                                                             msphic, mx
     109       126004 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: tmp
     110              : 
     111       126004 :       CALL timeset(routineN, handle)
     112              : 
     113       126004 :       CPASSERT(SIZE(abcint, 1) == nsgfa)
     114       126004 :       CPASSERT(SIZE(abcint, 2) == nsgfb)
     115              : 
     116       126004 :       msphia = SIZE(sphi_a, 1)
     117       126004 :       msphib = SIZE(sphi_b, 1)
     118       126004 :       msphic = SIZE(sphi_c, 1)
     119              : 
     120       126004 :       m1 = SIZE(sabc, 1)
     121       126004 :       m2 = SIZE(sabc, 2)
     122       126004 :       m3 = SIZE(sabc, 3)
     123       126004 :       mx = MAX(m2, nsgfb)
     124              : 
     125              :       ! ALLOCATE (cpp(nsgfa, m2, m3), cpc(nsgfa, nsgfb, m3))
     126       630020 :       ALLOCATE (tmp(nsgfa, mx, m3 + 1))
     127              : 
     128       126004 :       CALL dgemm("T", "N", nsgfa, m2*m3, ncoa, 1._dp, sphi_a, msphia, sabc, m1, 0.0_dp, tmp(:, :, 2), nsgfa)
     129      1271092 :       DO i = 1, m3
     130              :          CALL dgemm("N", "N", nsgfa, nsgfb, ncob, 1._dp, tmp(:, :, i + 1), nsgfa, sphi_b, msphib, &
     131      1271092 :                     0.0_dp, tmp(:, :, i), nsgfa)
     132              :       END DO
     133              :       CALL dgemm("N", "N", nsgfa*nsgfb, nsgfc, ncoc, 1._dp, tmp, nsgfa*mx, sphi_c, msphic, 0.0_dp, &
     134      1155536 :                  abcint, nsgfa*nsgfb)
     135              : 
     136       126004 :       DEALLOCATE (tmp)
     137              : 
     138       126004 :       CALL timestop(handle)
     139              : 
     140       126004 :    END SUBROUTINE abc_contract
     141              : 
     142              : ! **************************************************************************************************
     143              : !> \brief contract four-center overlap integrals (a,b,c,d) and transfer
     144              : !>        to spherical Gaussians
     145              : !> \param abcdint contracted, normalized integrals of spherical Gaussians
     146              : !> \param sabcd uncontracted, unnormalized integrals of primitive Cartesian Gaussians
     147              : !> \param sphi_a contraction matrix for center a
     148              : !> \param sphi_b contraction matrix for center b
     149              : !> \param sphi_c contraction matrix for center c
     150              : !> \param sphi_d contraction matrix for center d
     151              : !> \param ncoa number of cartesian orbitals on a
     152              : !> \param ncob number of cartesian orbitals on b
     153              : !> \param ncoc number of cartesian orbitals on c
     154              : !> \param ncod number of cartesian orbitals on d
     155              : !> \param nsgfa number of spherical Gaussian functions on a
     156              : !> \param nsgfb number of spherical Gaussian functions on b
     157              : !> \param nsgfc number of spherical Gaussian functions on c
     158              : !> \param nsgfd number of spherical Gaussian functions on d
     159              : ! **************************************************************************************************
     160            9 :    SUBROUTINE abcd_contract(abcdint, sabcd, sphi_a, sphi_b, sphi_c, sphi_d, ncoa, ncob, &
     161              :                             ncoc, ncod, nsgfa, nsgfb, nsgfc, nsgfd)
     162              : 
     163              :       REAL(KIND=dp), DIMENSION(:, :, :, :), &
     164              :          INTENT(INOUT)                                   :: abcdint
     165              :       REAL(KIND=dp), DIMENSION(:, :, :, :), INTENT(IN)   :: sabcd
     166              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: sphi_a, sphi_b, sphi_c, sphi_d
     167              :       INTEGER, INTENT(IN)                                :: ncoa, ncob, ncoc, ncod, nsgfa, nsgfb, &
     168              :                                                             nsgfc, nsgfd
     169              : 
     170              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'abcd_contract'
     171              : 
     172              :       INTEGER                                            :: handle, isgfc, isgfd, m1, m2, m3, m4, &
     173              :                                                             msphia, msphib, msphic, msphid
     174            9 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: temp_cccc, work_cpcc
     175            9 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: temp_cpcc, work_cppc
     176            9 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :, :)  :: cpcc, cppc, cppp
     177              : 
     178            9 :       CALL timeset(routineN, handle)
     179              : 
     180            9 :       msphia = SIZE(sphi_a, 1)
     181            9 :       msphib = SIZE(sphi_b, 1)
     182            9 :       msphic = SIZE(sphi_c, 1)
     183            9 :       msphid = SIZE(sphi_d, 1)
     184              : 
     185            9 :       m1 = SIZE(sabcd, 1)
     186            9 :       m2 = SIZE(sabcd, 2)
     187            9 :       m3 = SIZE(sabcd, 3)
     188            9 :       m4 = SIZE(sabcd, 4)
     189              : 
     190              :       ALLOCATE (cppp(nsgfa, m2, m3, m4), cppc(nsgfa, m2, m3, nsgfd), &
     191          144 :                 cpcc(nsgfa, m2, nsgfc, nsgfd))
     192              : 
     193           81 :       ALLOCATE (work_cppc(nsgfa, m2, m3), temp_cpcc(nsgfa, m2, nsgfc))
     194            9 :       work_cppc = 0._dp
     195            9 :       temp_cpcc = 0._dp
     196              : 
     197           63 :       ALLOCATE (work_cpcc(nsgfa, m2), temp_cccc(nsgfa, nsgfb))
     198            9 :       work_cpcc = 0._dp
     199            9 :       temp_cccc = 0._dp
     200              : 
     201              :       CALL dgemm("T", "N", nsgfa, m2*m3*m4, ncoa, 1._dp, sphi_a, msphia, sabcd, m1, &
     202            9 :                  0.0_dp, cppp, nsgfa)
     203              :       CALL dgemm("N", "N", nsgfa*m2*m3, nsgfd, ncod, 1._dp, cppp, nsgfa*m2*m3, &
     204            9 :                  sphi_d, msphid, 0.0_dp, cppc, nsgfa*m2*m3)
     205              : 
     206           45 :       DO isgfd = 1, nsgfd
     207       142164 :          work_cppc(:, :, :) = cppc(:, :, :, isgfd)
     208              :          CALL dgemm("N", "N", nsgfa*m2, nsgfc, ncoc, 1._dp, work_cppc, nsgfa*m2, &
     209           36 :                     sphi_c, msphic, 0.0_dp, temp_cpcc, nsgfa*m2)
     210        20340 :          cpcc(:, :, :, isgfd) = temp_cpcc(:, :, :)
     211          189 :          DO isgfc = 1, nsgfc
     212        20304 :             work_cpcc(:, :) = cpcc(:, :, isgfc, isgfd)
     213              :             CALL dgemm("N", "N", nsgfa, nsgfb, ncob, 1._dp, work_cpcc, nsgfa, sphi_b, &
     214          144 :                        msphib, 0.0_dp, temp_cccc, nsgfa)
     215         3060 :             abcdint(:, :, isgfc, isgfd) = temp_cccc(:, :)
     216              :          END DO
     217              :       END DO
     218              : 
     219            9 :       DEALLOCATE (cpcc, cppc, cppp)
     220            9 :       DEALLOCATE (work_cpcc, work_cppc, temp_cpcc, temp_cccc)
     221              : 
     222            9 :       CALL timestop(handle)
     223              : 
     224            9 :    END SUBROUTINE abcd_contract
     225              : 
     226              : ! **************************************************************************************************
     227              : !> \brief 3-center contraction routine from primitive cartesian Gaussians to spherical Gaussian
     228              : !>        functions using BLAS dgemm.
     229              : !>        Requires pre-transposition of the sphi_a array. The call-side shall DEALLOCATE buffers
     230              : !>        end of scope or after last use. This function ALLOCATEs or grows the work buffers
     231              : !>        as necessary.
     232              : !> \param abcint contracted integrals
     233              : !> \param sabc uncontracted integrals
     234              : !> \param sphi_a assumed to have dimensions nsgfa x ncoa
     235              : !> \param sphi_b assumed to have dimensions ncob x nsgfb
     236              : !> \param sphi_c assumed to have dimensions ncoc x nsgfc
     237              : !> \param ncoa ...
     238              : !> \param ncob ...
     239              : !> \param ncoc ...
     240              : !> \param nsgfa ...
     241              : !> \param nsgfb ...
     242              : !> \param nsgfc ...
     243              : !> \param cpp_buffer Buffer used for intermediate results (automatically allocated).
     244              : !> \param ccp_buffer Buffer used for intermediate results (automatically allocated).
     245              : !> \param prefac Prefactor which is finally multiplied into abcint (default: 1.0).
     246              : !> \param pstfac Factor used to consider initial abcint (default: 0.0).
     247              : ! **************************************************************************************************
     248      2202416 :    SUBROUTINE abc_contract_xsmm(abcint, sabc, sphi_a, sphi_b, sphi_c, ncoa, ncob, ncoc, &
     249              :                                 nsgfa, nsgfb, nsgfc, cpp_buffer, ccp_buffer, prefac, pstfac)
     250              : 
     251              :       REAL(KIND=dp), DIMENSION(:, :, :)           :: abcint
     252              :       REAL(KIND=dp), DIMENSION(*), INTENT(IN), TARGET :: sabc
     253              :       REAL(KIND=dp), DIMENSION(:, :), CONTIGUOUS, INTENT(IN), TARGET :: sphi_a, sphi_b, sphi_c
     254              :       INTEGER, INTENT(IN)                         :: ncoa, ncob, ncoc, nsgfa, nsgfb, nsgfc
     255              :       REAL(KIND=dp), DIMENSION(:), ALLOCATABLE, TARGET :: cpp_buffer, ccp_buffer
     256              :       REAL(KIND=dp), INTENT(IN), OPTIONAL         :: prefac, pstfac
     257              : 
     258              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'abc_contract_xsmm'
     259              : 
     260              :       REAL(KIND=dp)                                           :: alpha, beta
     261              :       INTEGER(KIND=int_8)                                     :: cpp_size, ccp_size
     262              :       INTEGER                                                 :: handle, i
     263              :       LOGICAL                                                 :: ab_first
     264              : #if defined(__LIBXS)
     265              :       TYPE(libxs_gemm_config_t) :: cfg1, cfg2
     266              :       INTEGER :: rc1, rc2
     267              : #endif
     268              : 
     269      2202416 :       CALL timeset(routineN, handle)
     270              : 
     271      2202416 :       alpha = 1.0_dp
     272      2202416 :       IF (PRESENT(prefac)) alpha = prefac
     273              : 
     274      2202416 :       beta = 0.0_dp
     275      2202416 :       IF (PRESENT(pstfac)) beta = pstfac
     276              : 
     277              :       ! M*N*K FLOPS are used to decide if contracting (AB)C vs A(BC)
     278      2202416 :       IF ((nsgfa*ncob*(ncoa + nsgfb)) <= (ncoa*nsgfb*(ncob + nsgfa))) THEN
     279      2202416 :          cpp_size = nsgfa*ncob
     280      2202416 :          ab_first = .TRUE.
     281              :       ELSE
     282       655098 :          cpp_size = ncoa*nsgfb
     283       655098 :          ab_first = .FALSE.
     284              :       END IF
     285              : 
     286      2202416 :       ccp_size = nsgfa*nsgfb*ncoc
     287      2202416 :       IF (.NOT. ALLOCATED(ccp_buffer)) THEN
     288         7524 :          ALLOCATE (ccp_buffer(ccp_size))
     289      2199908 :       ELSE IF (SIZE(ccp_buffer) < ccp_size) THEN
     290         6542 :          DEALLOCATE (ccp_buffer)
     291        19626 :          ALLOCATE (ccp_buffer(ccp_size))
     292              :       END IF
     293              : 
     294      2202416 :       IF (.NOT. ALLOCATED(cpp_buffer)) THEN
     295         7524 :          ALLOCATE (cpp_buffer(cpp_size))
     296      2199908 :       ELSE IF (SIZE(cpp_buffer) < cpp_size) THEN
     297         3327 :          DEALLOCATE (cpp_buffer)
     298         9981 :          ALLOCATE (cpp_buffer(cpp_size))
     299              :       END IF
     300              : 
     301              : #if defined(__LIBXS)
     302      2202416 :       IF (ab_first) THEN
     303              :          rc1 = libxs_gemm_dispatch(cfg1, LIBXS_DATATYPE_F64, 'N', 'N', &
     304      1547318 :                                    nsgfa, ncob, ncoa, nsgfa, ncoa, nsgfa, 1.0D0, 0.0D0)
     305              :          rc2 = libxs_gemm_dispatch(cfg2, LIBXS_DATATYPE_F64, 'N', 'N', &
     306      1547318 :                                    nsgfa, nsgfb, ncob, nsgfa, ncob, nsgfa, 1.0D0, 0.0D0)
     307              :       ELSE
     308              :          rc1 = libxs_gemm_dispatch(cfg1, LIBXS_DATATYPE_F64, 'N', 'N', &
     309       655098 :                                    ncoa, nsgfb, ncob, ncoa, ncob, ncoa, 1.0D0, 0.0D0)
     310              :          rc2 = libxs_gemm_dispatch(cfg2, LIBXS_DATATYPE_F64, 'N', 'N', &
     311       655098 :                                    nsgfa, nsgfb, ncoa, nsgfa, ncoa, nsgfa, 1.0D0, 0.0D0)
     312              :       END IF
     313      2202416 :       IF (0 /= rc1 .AND. 0 /= rc2) THEN
     314      2202416 :          IF (ab_first) THEN
     315     28105058 :             DO i = 0, ncoc - 1
     316              :                CALL libxs_gemm_call(cfg1, C_LOC(sphi_a(1, 1)), &
     317     26557740 :                                     C_LOC(sabc(i*ncoa*ncob + 1)), C_LOC(cpp_buffer(1)))
     318              :                CALL libxs_gemm_call(cfg2, C_LOC(cpp_buffer(1)), &
     319     28105058 :                                     C_LOC(sphi_b(1, 1)), C_LOC(ccp_buffer(i*nsgfa*nsgfb + 1)))
     320              :             END DO
     321              :          ELSE
     322     11375938 :             DO i = 0, ncoc - 1
     323              :                CALL libxs_gemm_call(cfg1, C_LOC(sabc(i*ncoa*ncob + 1)), &
     324     10720840 :                                     C_LOC(sphi_b(1, 1)), C_LOC(cpp_buffer(1)))
     325              :                CALL libxs_gemm_call(cfg2, C_LOC(sphi_a(1, 1)), &
     326     11375938 :                                     C_LOC(cpp_buffer(1)), C_LOC(ccp_buffer(i*nsgfa*nsgfb + 1)))
     327              :             END DO
     328              :          END IF
     329              :       ELSE
     330              : #endif
     331            0 :          IF (ab_first) THEN ! (AB)C
     332            0 :             DO i = 0, ncoc - 1
     333              :                CALL dgemm("N", "N", nsgfa, ncob, ncoa, 1.0_dp, sphi_a, nsgfa, sabc(i*ncoa*ncob + 1), &
     334            0 :                           ncoa, 0.0_dp, cpp_buffer, nsgfa)
     335              :                CALL dgemm("N", "N", nsgfa, nsgfb, ncob, 1.0_dp, cpp_buffer, nsgfa, sphi_b, ncob, 0.0_dp, &
     336            0 :                           ccp_buffer(i*nsgfa*nsgfb + 1), nsgfa)
     337              :             END DO
     338              :          ELSE ! A(BC)
     339            0 :             DO i = 0, ncoc - 1
     340              :                CALL dgemm("N", "N", ncoa, nsgfb, ncob, 1.0_dp, sabc(i*ncoa*ncob + 1), ncoa, sphi_b, &
     341            0 :                           ncob, 0.0_dp, cpp_buffer, ncoa)
     342              :                CALL dgemm("N", "N", nsgfa, nsgfb, ncoa, 1.0_dp, sphi_a, nsgfa, cpp_buffer, ncoa, 0.0_dp, &
     343            0 :                           ccp_buffer(i*nsgfa*nsgfb + 1), nsgfa)
     344              :             END DO
     345              :          END IF
     346              : #if defined(__LIBXS)
     347              :       END IF
     348              : #endif
     349              :       ! contractions over c: [nsgfa*nsgfb,ncoc] x [ncoc,nsgfc] -> [sgfa*nsgfb,nsgfc]
     350              :       CALL dgemm("N", "N", nsgfa*nsgfb, nsgfc, ncoc, alpha, ccp_buffer, nsgfa*nsgfb, &
     351      2202416 :                  sphi_c, ncoc, beta, abcint, nsgfa*nsgfb)
     352              : 
     353      2202416 :       CALL timestop(handle)
     354              : 
     355      2202416 :    END SUBROUTINE abc_contract_xsmm
     356              : 
     357              : END MODULE ai_contraction_sphi
        

Generated by: LCOV version 2.0-1