SF_SPARSE_ARRAY_COO.f90 Source File


This file depends on

sourcefile~~sf_sparse_array_coo.f90~~EfferentGraph sourcefile~sf_sparse_array_coo.f90 SF_SPARSE_ARRAY_COO.f90 sourcefile~sf_sparse_common.f90 SF_SPARSE_COMMON.f90 sourcefile~sf_sparse_array_coo.f90->sourcefile~sf_sparse_common.f90 sourcefile~sf_linalg.f90 SF_LINALG.f90 sourcefile~sf_sparse_common.f90->sourcefile~sf_linalg.f90 sourcefile~sf_blacs.f90 SF_BLACS.f90 sourcefile~sf_linalg.f90->sourcefile~sf_blacs.f90 sourcefile~sf_mpi.f90 SF_MPI.f90 sourcefile~sf_linalg.f90->sourcefile~sf_mpi.f90

Source Code

MODULE SF_SPARSE_ARRAY_COO
  USE SF_SPARSE_COMMON
#ifdef _MPI
  USE MPI
#endif
  implicit none
  public :: sf_sparse_dmatrix_coo,sf_sparse_cmatrix_coo, sf_init_matrix_coo, sf_delete_matrix_coo, sf_insert_element_coo, sf_dump_matrix_coo

!COO MATRIX
  type sf_sparse_dmatrix_coo
     integer,dimension(:),allocatable :: rows
     integer,dimension(:),allocatable :: cols
     real(8),dimension(:),allocatable :: vals
     integer                                   :: Size
     integer                                   :: Nrow
     integer                                   :: Ncol
     logical                                   :: status=.false.
! #ifdef _MPI
!      type(sf_sparse_drow_coo),dimension(:),pointer :: loc
!      integer                                   :: istart=0 !global start index for MPI storage
!      integer                                   :: iend=0
!      integer                                   :: ishift=0
!      logical                                   :: mpi=.false.
! #endif
  end type sf_sparse_dmatrix_coo
  
  type sf_sparse_cmatrix_coo
     integer,dimension(:),allocatable     :: rows
     integer,dimension(:),allocatable     :: cols
     complex(8),dimension(:),allocatable :: vals
     integer                                   :: Size
     integer                                   :: Nrow
     integer                                   :: Ncol
     logical                                   :: status=.false.
! #ifdef _MPI
!      type(sf_sparse_crow_coo),dimension(:),pointer :: loc
!      integer                                   :: istart=0 !global start index for MPI storage
!      integer                                   :: iend=0
!      integer                                   :: ishift=0
!      logical                                   :: mpi=.false.
! #endif
  end type sf_sparse_cmatrix_coo
  
  !INIT SPARSE MATRICES 
  interface sf_init_matrix_coo
     module procedure :: sf_init_dmatrix_coo
     module procedure :: sf_init_cmatrix_coo
! #ifdef _MPI
!      module procedure :: mpi_sf_init_dmatrix_coo
!      module procedure :: mpi_sf_init_cmatrix_coo
! #endif
  end interface sf_init_matrix_coo
  
  !DELETE SPARSE MATRIX 
  interface sf_delete_matrix_coo
     module procedure :: sf_delete_dmatrix_coo
     module procedure :: sf_delete_cmatrix_coo
! #ifdef _MPI
!      module procedure :: mpi_sf_delete_dmatrix_coo
!      module procedure :: mpi_sf_delete_cmatrix_coo
! #endif
  end interface sf_delete_matrix_coo


  !INSERT ELEMENTS
  interface sf_insert_element_coo
     module procedure :: sf_insert_delement_coo
     module procedure :: sf_insert_celement_coo
! #ifdef _MPI
!      module procedure :: mpi_sf_insert_delement_coo
!      module procedure :: mpi_sf_insert_celement_coo
! #endif
  end interface sf_insert_element_coo

  
  !DUMP SPARSE MATRIX INTO STANDARD MATRIX
  interface sf_dump_matrix_coo
     module procedure :: sf_dump_dmatrix_coo
     module procedure :: sf_dump_cmatrix_coo
! #ifdef _MPI
!      module procedure :: mpi_sf_dump_matrix_coo
!      module procedure :: mpi_sf_dump_matrix_coo
! #endif
  end interface sf_dump_matrix_coo

contains  
  !+------------------------------------------------------------------+
  !PURPOSE:  initialize the sparse matrix list
  !+------------------------------------------------------------------+
  subroutine sf_init_dmatrix_coo(sparse,N,N1)
    type(sf_sparse_dmatrix_coo),intent(inout) :: sparse
    integer                               :: N
    integer,optional                      :: N1
    integer                               :: i
    !
#ifdef _DEBUG
    write(*,"(A)")"DEBUG sf_init_dmatrix_coo: allocate sparse"
#endif
    !put here a delete statement to avoid problems
    if(sparse%status)stop "sf_init_dmatrix_coo: already allocated can not init"
    !
    sparse%Nrow=N
    sparse%Ncol=N
    sparse%Size=0
    if(present(N1))sparse%Ncol=N1
    !
    allocate(sparse%rows(0))
    allocate(sparse%cols(0))
    allocate(sparse%vals(0))
    !
    sparse%status=.true.
    !
  end subroutine sf_init_dmatrix_coo
  
subroutine sf_init_cmatrix_coo(sparse,N,N1)
    type(sf_sparse_cmatrix_coo),intent(inout) :: sparse
    integer                               :: N
    integer,optional                      :: N1
    integer                               :: i
    !
#ifdef _DEBUG
    write(*,"(A)")"DEBUG sf_init_cmatrix_coo: allocate sparse"
#endif
    !put here a delete statement to avoid problems
    if(sparse%status)stop "sf_init_cmatrix_coo: already allocated can not init"
    !
    sparse%Nrow=N
    sparse%Ncol=N
    sparse%Size=0
    if(present(N1))sparse%Ncol=N1
    !
    allocate(sparse%rows(0))
    allocate(sparse%cols(0))
    allocate(sparse%vals(0))
    !
    sparse%status=.true.
    !
  end subroutine sf_init_cmatrix_coo



! #ifdef _MPI
!   subroutine mpi_sf_init_dmatrix_coo(MpiComm,sparse,N,N1)
!     integer                               :: MpiComm
!     type(sf_sparse_dmatrix_coo),intent(inout) :: sparse
!     integer                               :: N
!     integer,optional                      :: N1
!     integer                               :: i,Ncol,Nloc
!     !
! #ifdef _DEBUG
!     write(*,"(A)")"DEBUG MPI_sf_init_dmatrix_coo: allocate sparse"
! #endif
!     if(MpiComm==Mpi_Comm_Null)return
!     !
!     call sf_test_matrix_mpi(MpiComm,sparse,"mpi_sf_init_dmatrix_coo")
!     !
!     Ncol = N
!     if(present(N1))Ncol=N1
!     !
!     Nloc = sparse%iend-sparse%istart+1
!     !
!     call sf_init_matrix_coo(sparse,Nloc,Ncol)
!     !
!     allocate(sparse%loc(Nloc))
!     do i=1,Nloc
!        sparse%loc(i)%size=0
!        allocate(sparse%loc(i)%vals(0)) !empty array
!        allocate(sparse%loc(i)%cols(0)) !empty array
!     end do
!     !
!   end subroutine mpi_sf_init_dmatrix_coo
  
!   subroutine mpi_sf_init_cmatrix_coo(MpiComm,sparse,N,N1)
!     integer                               :: MpiComm
!     type(sf_sparse_cmatrix_coo),intent(inout) :: sparse
!     integer                               :: N
!     integer,optional                      :: N1
!     integer                               :: i,Ncol,Nloc
!     !
! #ifdef _DEBUG
!     write(*,"(A)")"DEBUG MPI_sf_init_cmatrix_coo: allocate sparse"
! #endif
!     if(MpiComm==Mpi_Comm_Null)return
!     !
!     call sf_test_matrix_mpi(MpiComm,sparse,"mpi_sf_init_cmatrix_coo")
!     !
!     Ncol = N
!     if(present(N1))Ncol=N1
!     !
!     Nloc = sparse%iend-sparse%istart+1
!     !
!     call sf_init_matrix_coo(sparse,Nloc,Ncol)
!     !
!     allocate(sparse%loc(Nloc))
!     do i=1,Nloc
!        sparse%loc(i)%size=0
!        allocate(sparse%loc(i)%vals(0)) !empty array
!        allocate(sparse%loc(i)%cols(0)) !empty array
!     end do
!     !
!   end subroutine mpi_sf_init_cmatrix_coo
! #endif

  
  !+------------------------------------------------------------------+
  !PURPOSE: delete an entire sparse matrix
  !+------------------------------------------------------------------+
  subroutine sf_delete_dmatrix_coo(sparse)
    type(sf_sparse_dmatrix_coo),intent(inout) :: sparse
    integer                           :: i
    !
#ifdef _DEBUG
    write(*,"(A)")"DEBUG sf_delete_dmatrix_coo: delete sparse"
#endif
    if(.not.sparse%status)return !stop "Error SPARSE/sf_delete_matrix: sparse is not allocated."
    !
    deallocate(sparse%rows)
    deallocate(sparse%cols)
    deallocate(sparse%vals)
    !
    sparse%Nrow=0
    sparse%Ncol=0
    sparse%Size=0
    sparse%status=.false.
  end subroutine sf_delete_dmatrix_coo

    subroutine sf_delete_cmatrix_coo(sparse)
    type(sf_sparse_cmatrix_coo),intent(inout) :: sparse
    integer                           :: i
    !
#ifdef _DEBUG
    write(*,"(A)")"DEBUG sf_delete_cmatrix_coo: delete sparse"
#endif
    if(.not.sparse%status)return !stop "Error SPARSE/sf_delete_matrix: sparse is not allocated."
    !
    deallocate(sparse%rows)
    deallocate(sparse%cols)
    deallocate(sparse%vals)
    !
    sparse%Nrow=0
    sparse%Ncol=0
    sparse%Size=0
    sparse%status=.false.
  end subroutine sf_delete_cmatrix_coo



! #ifdef _MPI
!   subroutine mpi_sf_delete_dmatrix_coo(MpiComm,sparse)
!     integer                              :: MpiComm
!     type(sf_sparse_dmatrix_coo),intent(inout) :: sparse
!     integer                              :: i
!     type(sf_sparse_drow_coo),pointer          :: row
!     !
! #ifdef _DEBUG
!     write(*,"(A)")"DEBUG MPI_sf_delete_dmatrix_coo: delete sparse"
! #endif
!     if(.not.sparse%status)return !stop "Error SPARSE/mpi_sp_delete_matrix: sparse is not allocated."
!     !
!     do i=1,sparse%Nrow
!        deallocate(sparse%row(i)%vals)
!        deallocate(sparse%row(i)%cols)
!        sparse%row(i)%Size  = 0
!        !
!        deallocate(sparse%loc(i)%vals)
!        deallocate(sparse%loc(i)%cols)
!        sparse%loc(i)%Size  = 0
!     enddo
!     deallocate(sparse%row)
!     deallocate(sparse%loc)
!     !
!     sparse%Nrow=0
!     sparse%Ncol=0
!     sparse%status=.false.
!     !
!     sparse%istart=0
!     sparse%iend=0
!     sparse%ishift=0
!     sparse%mpi=.false.
!     !
!   end subroutine mpi_sf_delete_dmatrix_coo
  
!   subroutine mpi_sf_delete_cmatrix_coo(MpiComm,sparse)
!     integer                              :: MpiComm
!     type(sf_sparse_cmatrix_coo),intent(inout) :: sparse
!     integer                              :: i
!     type(sf_sparse_crow_coo),pointer          :: row
!     !
! #ifdef _DEBUG
!     write(*,"(A)")"DEBUG MPI_sf_delete_cmatrix_coo: delete sparse"
! #endif
!     if(.not.sparse%status)return !stop "Error SPARSE/mpi_sp_delete_matrix: sparse is not allocated."
!     !
!     do i=1,sparse%Nrow
!        deallocate(sparse%row(i)%vals)
!        deallocate(sparse%row(i)%cols)
!        sparse%row(i)%Size  = 0
!        !
!        deallocate(sparse%loc(i)%vals)
!        deallocate(sparse%loc(i)%cols)
!        sparse%loc(i)%Size  = 0
!     enddo
!     deallocate(sparse%row)
!     deallocate(sparse%loc)
!     !
!     sparse%Nrow=0
!     sparse%Ncol=0
!     sparse%status=.false.
!     !
!     sparse%istart=0
!     sparse%iend=0
!     sparse%ishift=0
!     sparse%mpi=.false.
!     !
!   end subroutine mpi_sf_delete_cmatrix_coo
! #endif    


  !+------------------------------------------------------------------+
  !PURPOSE: insert an element value at position (i,j) in the sparse matrix
  !+------------------------------------------------------------------+
  subroutine sf_insert_delement_coo(sparse,value,i,j)
    type(sf_sparse_dmatrix_coo),intent(inout) :: sparse
    real(8),intent(in)                    :: value
    integer,intent(in)                    :: i,j
    integer                               :: k
    logical                               :: present
    !
#ifdef _DEBUG
    write(*,"(A,2I8)")"DEBUG sf_insert_delement_coo: insert element in sparse @",i,j
#endif
    !
    present=.false.
    do k=1,sparse%Size !Find position if present
       if( (i==sparse%rows(k)).and.(j==sparse%cols(k)))then
          present=.true.
          exit
       end if
    end do
    !
    if(present)then                            ! Add if present
       sparse%vals(k) = sparse%vals(k) + value !
    else
       call add_to(sparse%rows,i)
       call add_to(sparse%cols,j)
       call add_to(sparse%vals,value)
       sparse%Size = sparse%Size +1
    endif
    !
    if(sparse%Size > sparse%Ncol*sparse%Nrow)stop "sf_insert_delement_coo ERROR: sparse%Size > sparse%Ncol*sparse%Nrow"
    !
  end subroutine sf_insert_delement_coo

  subroutine sf_insert_celement_coo(sparse,value,i,j)
    type(sf_sparse_cmatrix_coo),intent(inout) :: sparse
    complex(8),intent(in)                 :: value
    integer,intent(in)                    :: i,j
    integer                               :: k
    logical                               :: present
    !
#ifdef _DEBUG
    write(*,"(A,2I8)")"DEBUG sf_insert_celement_coo: insert element in sparse @",i,j
#endif
    !
    present=.false.
    do k=1,sparse%Size !Find position if present
       if( (i==sparse%rows(k)).and.(j==sparse%cols(k)))then
          present=.true.
          exit
       end if
    end do
    !
    if(present)then                            ! Add if present
       sparse%vals(k) = sparse%vals(k) + value !
    else
       call add_to(sparse%rows,i)
       call add_to(sparse%cols,j)
       call add_to(sparse%vals,value)
       sparse%Size = sparse%Size +1
    endif
    !
    if(sparse%Size > sparse%Ncol*sparse%Nrow)stop "sf_insert_celement_coo ERROR: sparse%Size > sparse%Ncol*sparse%Nrow"
    !
  end subroutine sf_insert_celement_coo

! #ifdef _MPI
!   subroutine mpi_sf_insert_delement_coo(MpiComm,sparse,value,i,j)
!     integer                               :: MpiComm
!     type(sf_sparse_dmatrix_coo),intent(inout) :: sparse
!     real(8),intent(in)                    :: value
!     integer,intent(in)                    :: i,j
!     type(sf_sparse_drow_coo),pointer          :: row
!     integer                               :: column,pos
!     logical                               :: iadd
!     !
! #ifdef _DEBUG
!     write(*,"(A,2I8)")"DEBUG MPI_sf_insert_delement_coo: insert element in sparse @",i,j
! #endif
!     !
!     if(MpiComm==Mpi_Comm_Null)return
!     !
!     call sp_test_matrix_mpi(MpiComm,sparse," mpi_sf_insert_delement_coo")
!     !
!     column = j
!     !
!     row => sparse%row(i-sparse%Ishift)
!     !
!     iadd = .false.                          !check if column already exist
!     if(any(row%cols == column))then         !
!        pos = binary_search(row%cols,column) !find the position  column in %cols        
!        iadd=.true.                          !set Iadd to true
!     endif
!     !
!     if(iadd)then                            !this column exists so just sum it up       
!        row%vals(pos)=row%vals(pos) + value  !add up value to the current one in %vals
!     else                                    !this column is new. increase counter and store it 
!        call add_to(row%vals,value)
!        call add_to(row%cols,column)
!        row%Size = row%Size + 1
!     endif
!     !
!     if(row%Size > sparse%Ncol)stop "mpi_sp_insert_element_coo ERROR: row%Size > sparse%Ncol"
!     !
!   end subroutine mpi_sf_insert_delement_coo

!   subroutine mpi_sf_insert_celement_coo(MpiComm,sparse,value,i,j)
!     integer                               :: MpiComm
!     type(sf_sparse_cmatrix_coo),intent(inout) :: sparse
!     complex(8),intent(in)                 :: value
!     integer,intent(in)                    :: i,j
!     type(sf_sparse_crow_coo),pointer          :: row
!     integer                               :: column,pos
!     logical                               :: iadd
!     !
! #ifdef _DEBUG
!     write(*,"(A,2I8)")"DEBUG MPI_sf_insert_celement_coo: insert element in sparse @",i,j
! #endif
!     !
!     call sp_test_matrix_mpi(MpiComm,sparse," mpi_sf_insert_celement_coo")
!     !
!     column = j
!     !
!     if(column>=sparse%Istart.AND.column<=sparse%Iend)then
!        row => sparse%loc(i-sparse%Ishift)
!     else
!        row => sparse%row(i-sparse%Ishift)
!     endif
!     !
!     iadd = .false.                          !check if column already exist
!     if(any(row%cols == column))then         !
!        pos = binary_search(row%cols,column) !find the position  column in %cols        
!        iadd=.true.                          !set Iadd to true
!     endif
!     !
!     if(iadd)then                            !this column exists so just sum it up       
!        row%vals(pos)=row%vals(pos) + value  !add up value to the current one in %vals
!     else                                    !this column is new. increase counter and store it 
!        call add_to(row%vals,value)
!        call add_to(row%cols,column)
!        row%Size = row%Size + 1
!     endif
!     !
!     if(row%Size > sparse%Ncol)stop "mpi_sp_insert_element_coo ERROR: row%Size > sparse%Ncol"
!     !
!   end subroutine mpi_sf_insert_celement_coo
! #endif
  
  !+------------------------------------------------------------------+
  !PURPOSE: dump a sparse matrix into a regular 2dim array
  !+------------------------------------------------------------------+
  subroutine sf_dump_dmatrix_coo(sparse,matrix)
    type(sf_sparse_dmatrix_coo),intent(in)   :: sparse
    real(8),dimension(:,:),intent(inout) :: matrix
    real(8)                              :: val
    integer                              :: i,col,row,Ndim1,Ndim2
    !
#ifdef _DEBUG
    write(*,"(A)")"DEBUG sf_dump_dmatrix_coo: dump sparse"
#endif
    !
    Ndim1=size(matrix,1)
    Ndim2=size(matrix,2)
    !
    if(sparse%Nrow/=Ndim1 .OR. sparse%Ncol/=Ndim2)stop "Warning SPARSE/dump_matrix: dimensions error"
    !
    do i=1,sparse%Size
       row=sparse%rows(i);  col=sparse%cols(i)
       matrix(row,col) = matrix(row,col) + sparse%vals(i)
    enddo
  end subroutine sf_dump_dmatrix_coo

  subroutine sf_dump_cmatrix_coo(sparse,matrix)
    type(sf_sparse_cmatrix_coo),intent(in)      :: sparse
    complex(8),dimension(:,:),intent(inout) :: matrix
    complex(8)                              :: vals
    integer                                 :: i,col,row,Ndim1,Ndim2
    !
#ifdef _DEBUG
    write(*,"(A)")"DEBUG sf_dump_cmatrix_coo: dump sparse"
#endif
    !
    Ndim1=size(matrix,1)
    Ndim2=size(matrix,2)
    !
    if(sparse%Nrow/=Ndim1 .OR. sparse%Ncol/=Ndim2)stop "Warning SPARSE/dump_matrix: dimensions error"
    !
    do i=1,sparse%Size
       row=sparse%rows(i);  col=sparse%cols(i)
       matrix(row,col) = matrix(row,col) + sparse%vals(i)
    enddo
  end subroutine sf_dump_cmatrix_coo

! #ifdef _MPI
!   subroutine mpi_sf_dump_dmatrix_coo(MpiComm,sparse,matrix)
!     integer                              :: MpiComm
!     type(sf_sparse_dmatrix_coo),intent(in)   :: sparse
!     real(8),dimension(:,:),intent(inout) :: matrix
!     real(8),dimension(:,:),allocatable   :: matrix_tmp
!     integer                              :: i,impi,j,N1_,N2_,Ndim1,Ndim2,Nrow,Ncol
!     !
! #ifdef _DEBUG
!     write(*,"(A)")"DEBUG MPI_sf_dump_dmatrix_coo: dump sparse"
! #endif
!     !
!     call sp_test_matrix_mpi(MpiComm,sparse," mpi_sf_dump_dmatrix_coo")
!     !
!     Ndim1=size(matrix,1)
!     Ndim2=size(matrix,2)
!     !
!     N1_  = sparse%Nrow
!     N2_  = sparse%Ncol
!     Nrow = 0
!     Ncol = 0
!     call MPI_AllReduce(N1_,Nrow,1,MPI_Integer,MPI_SUM,MpiComm,MpiIerr)
!     call MPI_AllReduce(N2_,Ncol,1,MPI_Integer,MPI_MAX,MpiComm,MpiIerr)
!     !
!     if(Nrow>Ndim1 .OR. Ncol>Ndim2)stop "Warning SPARSE/mpi_dump_matrix: dimensions error"
!     !
!     allocate(matrix_tmp(Ndim1,Ndim2)) ; matrix_tmp=0d0
!     do i=sparse%Istart,sparse%Iend
!        impi = i - sparse%Ishift
!        do j=1,sparse%row(impi)%Size
!           matrix_tmp(i,sparse%row(impi)%cols(j))=matrix_tmp(i,sparse%row(impi)%cols(j))+sparse%row(impi)%vals(j)
!        enddo
!     enddo
!     !
!     call AllReduce_MPI(MpiCOmm,Matrix_tmp,Matrix)
!     !
!   end subroutine mpi_sf_dump_dmatrix_coo

!   subroutine mpi_sf_dump_cmatrix_coo(MpiComm,sparse,matrix)
!     integer                                 :: MpiComm
!     type(sf_sparse_cmatrix_coo),intent(in)      :: sparse
!     complex(8),dimension(:,:),intent(inout) :: matrix
!     complex(8),dimension(:,:),allocatable   :: matrix_tmp
!     integer                                 :: i,impi,j,N1_,N2_,Ndim1,Ndim2,Nrow,Ncol
!     !
! #ifdef _DEBUG
!     write(*,"(A)")"DEBUG MPI_sf_dump_cmatrix_coo: dump sparse"
! #endif
!     !
!     call sp_test_matrix_mpi(MpiComm,sparse," mpi_sf_dump_cmatrix_coo")
!     !
!     Ndim1=size(matrix,1)
!     Ndim2=size(matrix,2)
!     !
!     N1_  = sparse%Nrow
!     N2_  = sparse%Ncol
!     Nrow = 0
!     Ncol = 0
!     call MPI_AllReduce(N1_,Nrow,1,MPI_Integer,MPI_SUM,MpiComm,MpiIerr)
!     call MPI_AllReduce(N2_,Ncol,1,MPI_Integer,MPI_MAX,MpiComm,MpiIerr)
!     !
!     if(Nrow>Ndim1 .OR. Ncol>Ndim2)stop "Warning SPARSE/mpi_dump_matrix: dimensions error"
!     !
!     allocate(matrix_tmp(Ndim1,Ndim2)) ; matrix_tmp=zero
!     do i=sparse%Istart,sparse%Iend
!        impi = i - sparse%Ishift
!        !Local part:
!        do j=1,sparse%loc(impi)%Size
!           matrix_tmp(i,sparse%loc(impi)%cols(j))=matrix_tmp(i,sparse%loc(impi)%cols(j))+sparse%loc(impi)%vals(j)
!        enddo
!        !
!        !Non-local part:
!        do j=1,sparse%row(impi)%Size
!           matrix_tmp(i,sparse%row(impi)%cols(j))=matrix_tmp(i,sparse%row(impi)%cols(j))+sparse%row(impi)%cvals(j)
!        enddo
!     enddo
!     !
!     call AllReduce_MPI(MpiCOmm,Matrix_tmp,Matrix)
!     !
!   end subroutine mpi_sf_dump_cmatrix_coo
! #endif 

END MODULE SF_SPARSE_ARRAY_COO