LCOV - code coverage report
Current view: top level - src/78_effpot - m_spmat_convert.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 30.4 % 115 35
Test Date: 2026-11-10 13:31:01 Functions: 22.2 % 9 2
Branches: 14.5 % 152 22

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_spmat_convert
       2                 :             : !! NAME
       3                 :             : !! m_spmat_convert
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !! This module contains the functions to convert between sparse matrix formats
       7                 :             : !!
       8                 :             : !!
       9                 :             : !! Subroutines:
      10                 :             : !! - dense_to_LIL
      11                 :             : !! - LIL_to_dense
      12                 :             : !! - LIL_to_COO
      13                 :             : !! - LIL_to_CSR
      14                 :             : !! - Dense_to_CSR
      15                 :             : !!
      16                 :             : !!
      17                 :             : !! COPYRIGHT
      18                 :             : !! Copyright (C) 2001-2026 ABINIT group (hexu)
      19                 :             : !! This file is distributed under the terms of the
      20                 :             : !! GNU General Public License, see ~abinit/COPYING
      21                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      22                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      23                 :             : !!
      24                 :             : !! SOURCE
      25                 :             : 
      26                 :             : #if defined HAVE_CONFIG_H
      27                 :             : #include "config.h"
      28                 :             : #endif
      29                 :             : #include "abi_common.h"
      30                 :             : 
      31                 :             : 
      32                 :             : module m_spmat_convert
      33                 :             :   use defs_basis
      34                 :             :   use m_xmpi
      35                 :             :   use m_abicore
      36                 :             :   use m_errors
      37                 :             :   use m_spmat_dense
      38                 :             :   use m_linked_list
      39                 :             :   use m_spmat_lil
      40                 :             :   use m_spmat_csr
      41                 :             :   use m_spmat_coo
      42                 :             :   use m_spmat_lco
      43                 :             :   implicit none
      44                 :             : !!****m*
      45                 :             :   public
      46                 :             :   !-----------------------------------------------------------------------
      47                 :             :   !> @brief convert one type of matrix Amat to the other Bmat
      48                 :             :   !> Note that the dense matrix is not the dense_mat_t because a
      49                 :             :   !> simple 2d array is more generally used.
      50                 :             :   !> @param [in] Amat
      51                 :             :   !> @param [out] Bmat
      52                 :             :   !-----------------------------------------------------------------------
      53                 :             :   interface spmat_convert
      54                 :             :      !procedure  dense_to_LIL
      55                 :             :      procedure  LIL_to_dense
      56                 :             :      procedure  LIL_to_COO
      57                 :             :      procedure  LIL_to_CSR
      58                 :             :      procedure dense_to_CSR
      59                 :             :      procedure dense_to_COO
      60                 :             :      procedure  COO_to_CSR
      61                 :             :      !procedure LCO_to_CSR
      62                 :             :   end interface spmat_convert
      63                 :             : 
      64                 :             :   public :: COO_to_dense
      65                 :             : contains
      66                 :             : 
      67                 :             :   !-----------------------------------------------------------------------
      68                 :             :   !> @brief dense matrix to LIL matrix
      69                 :             :   !> @param [in] mat: 2D array
      70                 :             :   !> @param [out] ll : LIL matrix
      71                 :             :   !-----------------------------------------------------------------------
      72         [ #  # ]:           0 :   subroutine dense_to_LIL(mat, ll)
      73                 :             :     ! check shape
      74                 :             :     real(dp), intent(in):: mat(:, :)
      75                 :             :     type(LIL_mat_t), intent(inout) :: ll
      76                 :             :     integer :: s(2), irow, icol
      77         [ #  # ]:           0 :     s=shape(mat)
      78                 :           0 :     call ll%initialize(s)
      79         [ #  # ]:           0 :     do icol=1, ll%ncol, 1
      80         [ #  # ]:           0 :        do irow=1, ll%nrow, 1
      81                 :           0 :           call ll%insert(irow,icol,mat(irow, icol),0)
      82                 :             :        enddo
      83                 :             :     enddo
      84                 :           0 :   end subroutine dense_to_LIL
      85                 :             : 
      86                 :             :   !-----------------------------------------------------------------------
      87                 :             :   !> @brief LIL matrix to dense matrix
      88                 :             :   !> @param [in] ll : LIL matrix
      89                 :             :   !> @param [out] mat: 2D array
      90                 :             :   !-----------------------------------------------------------------------
      91                 :           0 :   subroutine LIL_to_dense(ll, mat)
      92                 :             :     class(LIL_mat_t) , intent(inout):: ll
      93                 :             :     real(dp), intent(out):: mat(ll%nrow,ll%ncol)
      94                 :             :     integer:: irow
      95   [ #  #  #  # ]:           0 :     mat(:,:)=0.0d0
      96         [ #  # ]:           0 :     do irow=1, ll%nrow
      97                 :           0 :        call llist_iter_restart(ll%rows(irow))
      98         [ #  # ]:           0 :        do while(associated(ll%rows(irow)%iter))
      99                 :           0 :           mat(irow, ll%rows(irow)%iter%i)=ll%rows(irow)%iter%val
     100                 :           0 :           ll%rows(irow)%iter=>ll%rows(irow)%iter%next
     101                 :             :        enddo
     102                 :             :     enddo
     103                 :           0 :   end subroutine LIL_to_dense
     104                 :             : 
     105                 :             :   !-----------------------------------------------------------------------
     106                 :             :   !> @brief LIL matrix to COO matrix
     107                 :             :   !> @param [in] ll : LIL matrix
     108                 :             :   !> @param [out] csrmat: COO matrix
     109                 :             :   !-----------------------------------------------------------------------
     110         [ #  # ]:           0 :   subroutine LIL_to_COO(ll, COO)
     111                 :             :     class(LIL_mat_t) , intent(inout):: ll
     112                 :             :     class(COO_mat_t), intent(out):: COO
     113                 :             :     integer ::  irow
     114                 :           0 :     call  COO%initialize(mshape=ll%mshape)
     115         [ #  # ]:           0 :     do irow=1, ll%nrow
     116                 :           0 :        call llist_iter_restart(ll%rows(irow))
     117         [ #  # ]:           0 :        do while(associated(ll%rows(irow)%iter))
     118         [ #  # ]:           0 :           call coo%add_entry([irow, ll%rows(irow)%iter%i], ll%rows(irow)%iter%val)
     119                 :           0 :           ll%rows(irow)%iter=>ll%rows(irow)%iter%next
     120                 :             :        enddo
     121                 :             :     end do
     122                 :             : 
     123                 :           0 :   end subroutine LIL_to_COO
     124                 :             : 
     125                 :             :   !-----------------------------------------------------------------------
     126                 :             :   !> @brief LIL matrix to CSR matrix
     127                 :             :   !> @param [in] ll : LIL matrix
     128                 :             :   !> @param [out] csrmat: CSR matrix
     129                 :             :   !-----------------------------------------------------------------------
     130                 :           2 :   subroutine LIL_to_CSR(ll, csrmat)
     131                 :             :     type(LIL_mat_t) , intent(inout):: ll
     132                 :             :     type(CSR_mat_t), intent(inout):: csrmat
     133                 :             :     integer:: irow,  i, nzrow
     134         [ +  + ]:           6 :     call  csrmat%initialize([ll%nrow, ll%ncol])
     135                 :           2 :     call csrmat%set(nnz=ll%get_nnz())
     136                 :           2 :     i=0
     137                 :           2 :     csrmat%row_shift(1)=1
     138         [ +  + ]:        1298 :     do irow=1, ll%nrow
     139                 :        1296 :        nzrow=0
     140                 :        1296 :        call llist_iter_restart(ll%rows(irow))
     141         [ +  + ]:       34992 :        do while(associated(ll%rows(irow)%iter))
     142                 :       33696 :           nzrow=nzrow+1
     143                 :       33696 :           i=i+1
     144                 :       33696 :           csrmat%icol(i)=ll%rows(irow)%iter%i
     145                 :       33696 :           csrmat%val(i)=ll%rows(irow)%iter%val
     146                 :       33696 :           ll%rows(irow)%iter=>ll%rows(irow)%iter%next
     147                 :             :        enddo
     148                 :        1298 :        csrmat%row_shift(irow+1)=csrmat%row_shift(irow)+nzrow
     149                 :             :     enddo
     150                 :           2 :   end subroutine LIL_to_CSR
     151                 :             : 
     152                 :             :   !-----------------------------------------------------------------------
     153                 :             :   !> @brief dense matrix to CSR matrix
     154                 :             :   !> @param [in] mat: dense matrix
     155                 :             :   !> @param [out] csrmat: CSR matrix
     156                 :             :   !-----------------------------------------------------------------------
     157   [ #  #  #  #  :           0 :   subroutine dense_to_CSR(mat, csrmat)
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     158                 :             :     real(dp), intent(in):: mat(:, :)
     159                 :             :     type(csr_mat_t), intent(out) :: csrmat
     160                 :             :     !type(lil_mat_t):: lilmat
     161                 :             :     integer :: i, j, nnz, nrow, ncol, inz, nzrow
     162                 :             :     !call dense_to_lil(mat, lilmat)
     163                 :             :     !call lil_to_csr(lilmat, csrmat)
     164                 :             :     !call lilmat%finalize()
     165   [ #  #  #  #  :           0 :     nnz=count(mat /= 0.0_dp)
                   #  # ]
     166                 :           0 :     nrow=size(mat, 1)
     167                 :           0 :     ncol=size(mat, 2)
     168         [ #  # ]:           0 :     call  csrmat%initialize([nrow, ncol])
     169                 :           0 :     call csrmat%set(nnz=nnz)
     170                 :           0 :     csrmat%row_shift(1)=1
     171                 :           0 :     inz=0
     172         [ #  # ]:           0 :     do i=1, nrow
     173                 :             :        nzrow=0
     174         [ #  # ]:           0 :        do j=1, ncol
     175         [ #  # ]:           0 :           if (mat(i, j)/=0.0_dp) then
     176                 :           0 :              inz=inz+1
     177                 :           0 :              nzrow=nzrow+1
     178                 :           0 :              csrmat%icol(inz)=j
     179                 :           0 :              csrmat%val(inz)=mat(i,j)
     180                 :             :           end if
     181                 :             :        end do
     182                 :           0 :        csrmat%row_shift(i+1)=csrmat%row_shift(i)+nzrow
     183                 :             :     end do
     184                 :           0 :   end subroutine dense_to_CSR
     185                 :             : 
     186                 :             :   !-------------------------------------------------------------------!
     187                 :             :   ! dense_to_coo
     188                 :             :   ! Dense to COO matrix convertion
     189                 :             :   !-------------------------------------------------------------------!
     190         [ #  # ]:           0 :   subroutine dense_to_coo(mat, coo)
     191                 :             :     real(dp), intent(in) :: mat(:,:)
     192                 :             :     type(coo_mat_t), intent(inout) :: coo
     193                 :             :     integer:: i, j
     194         [ #  # ]:           0 :     call coo%initialize(shape(mat))
     195         [ #  # ]:           0 :     do j=1, size(mat, dim=2)
     196         [ #  # ]:           0 :        do i=1, size(mat, dim=1)
     197         [ #  # ]:           0 :           if (abs(mat(i, j)) >tiny(1.0d0) ) then
     198         [ #  # ]:           0 :              call coo%add_entry(ind=[i,j], val=mat(i,j))
     199                 :             :           end if
     200                 :             :        end do
     201                 :             :     end do
     202                 :           0 :   end subroutine dense_to_coo
     203                 :             : 
     204                 :             :   !-------------------------------------------------------------------!
     205                 :             :   ! COO_to_CSR:
     206                 :             :   !  translate COO matrix to CSR matrix
     207                 :             :   !  NOTE: This can be quite slow when it is large due to the sort algorithm
     208                 :             :   ! Input:
     209                 :             :   !  COO matrix
     210                 :             :   ! Output:
     211                 :             :   !   CSR matrix
     212                 :             :   !-------------------------------------------------------------------!
     213                 :           1 :   subroutine COO_to_CSR(coo, csr)
     214                 :             :     type(COO_mat_t), intent(inout) :: coo
     215                 :             :     type(CSR_mat_t), intent(inout) :: csr
     216                 :             :     integer :: ngroup
     217                 :           1 :     integer, allocatable :: i1_list(:), istartend(:)
     218                 :           2 :     integer :: row_nz(coo%mshape(1))
     219                 :             :     integer :: i, irow
     220                 :           1 :     call coo%group_by_1dim(ngroup, i1_list, istartend)
     221                 :           1 :     call csr%initialize(coo%mshape)
     222                 :           1 :     call csr%set(nnz=coo%nnz)
     223         [ +  + ]:       67585 :     csr%icol(:)=coo%ind%data(2,1:coo%nnz)
     224         [ +  + ]:       67585 :     csr%val(:) = coo%val%data(1:coo%nnz)
     225         [ +  + ]:        1026 :     csr%row_shift(:)=0
     226         [ +  + ]:        1025 :     row_nz(:)=0
     227         [ +  + ]:        1025 :     do i=1, ngroup
     228                 :        1024 :        irow=i1_list(i)
     229                 :        1025 :        row_nz(irow) = istartend(i+1)-istartend(i)
     230                 :             :     end do
     231                 :             : 
     232                 :           1 :     csr%row_shift(1)=1
     233         [ +  + ]:        1025 :     do i=2, csr%nrow+1
     234                 :        1025 :        csr%row_shift(i)= csr%row_shift(i-1)+row_nz(i-1)
     235                 :             :     end do
     236         [ +  - ]:           1 :     ABI_SFREE(i1_list)
     237         [ +  - ]:           1 :     ABI_SFREE(istartend)
     238   [ -  +  -  + ]:           1 :   end subroutine COO_to_CSR
     239                 :             : 
     240                 :             : 
     241                 :             :   !-------------------------------------------------------------------!
     242                 :             :   ! COO_to_dense
     243                 :             :   !   COO matrix to dense matrix
     244                 :             :   ! Input:
     245                 :             :   !   COO: coo matrix
     246                 :             :   ! Output:
     247                 :             :   !   dense: dense matrix
     248                 :             :   !-------------------------------------------------------------------!
     249         [ #  # ]:           0 :   subroutine COO_to_dense(coo, dense)
     250                 :             :     type(COO_mat_t), intent(inout) :: coo
     251                 :             :     real(dp), intent(inout) :: dense(:,:)
     252                 :             :     integer :: i, j, inz
     253                 :             :     real(dp) :: val
     254   [ #  #  #  # ]:           0 :     dense(:,:) =0.0
     255         [ #  # ]:           0 :     do inz =1, coo%nnz
     256                 :           0 :        i=coo%ind%data(1, inz)
     257                 :           0 :        j=coo%ind%data(2, inz)
     258                 :           0 :        val= coo%val%data(inz)
     259                 :           0 :        dense(i,j) = dense(i,j) + val
     260                 :             :     end do
     261                 :           0 :   end subroutine COO_to_dense
     262                 :             : 
     263                 :             : 
     264                 :             : !  subroutine LCO_to_CSR(lco, csr)
     265                 :             : !    type(LCO_mat_t), intent(inout) :: lco
     266                 :             : !    type(CSR_mat_t), intent(inout) :: csr
     267                 :             : !    integer, allocatable :: i1_list(:), istartend(:)
     268                 :             : !    integer :: row_nz(lco%mshape(1))
     269                 :             : !    integer :: i, irow
     270                 :             : !
     271                 :             : !  end subroutine LCO_to_CSR
     272                 :             : 
     273                 :             : 
     274                 :             : 
     275                 :           0 :   subroutine spmat_convert_unittest()
     276                 :             :     real(dp) ::mat(4,4), x(4), b(4)
     277                 :           0 :     type(coo_mat_t) :: coo
     278                 :           0 :     type(csr_mat_t) :: csr, csr2
     279                 :             :     integer :: ngroup
     280                 :           0 :     integer, allocatable :: i1list(:), ise(:)
     281                 :           0 :     mat=reshape([1,2,0,0, 8, 3, 0,0, 0,2,0,0, 0,0,0,9], [4,4])*1.0d0
     282                 :           0 :     call dense_to_coo(mat, coo)
     283                 :           0 :     call coo%sum_duplicates()
     284                 :           0 :     call dense_to_csr(mat, csr)
     285                 :           0 :     call coo%group_by_1dim(ngroup, i1list, ise)
     286                 :           0 :     call coo%sum_duplicates()
     287         [ #  # ]:           0 :     ABI_SFREE(i1list)
     288         [ #  # ]:           0 :     ABI_SFREE(ise)
     289                 :           0 :     call coo_to_csr(coo, csr2)
     290                 :             : 
     291                 :           0 :     x=[1,2,3,4]
     292   [ #  #  #  # ]:           0 :     b=matmul(mat, x)
     293                 :           0 :     b=0
     294                 :           0 :     call csr%mv(x, b)
     295                 :           0 :     b=0
     296                 :           0 :     call csr2%mv(x, b)
     297                 :             : 
     298                 :           0 :     b=0
     299                 :           0 :     call csr2%mv(x, b)
     300                 :             : 
     301                 :             : 
     302                 :             : 
     303                 :           0 :     call coo%finalize()
     304                 :           0 :     call csr%finalize()
     305                 :           0 :     call csr2%finalize()
     306   [ #  #  #  #  :           0 :   end subroutine spmat_convert_unittest
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     307                 :             : 
     308                 :             : 
     309                 :             : end module m_spmat_convert
        

Generated by: LCOV version 2.3-1