|
|
|
@ -3550,6 +3550,269 @@ contains
|
|
|
|
|
|
|
|
|
|
end subroutine psb_ccsrspspmm
|
|
|
|
|
|
|
|
|
|
subroutine psb_c_ecsr_mold(a,b,info)
|
|
|
|
|
use psb_c_csr_mat_mod, psb_protect_name => psb_c_ecsr_mold
|
|
|
|
|
use psb_error_mod
|
|
|
|
|
implicit none
|
|
|
|
|
class(psb_c_ecsr_sparse_mat), intent(in) :: a
|
|
|
|
|
class(psb_c_base_sparse_mat), intent(inout), allocatable :: b
|
|
|
|
|
integer(psb_ipk_), intent(out) :: info
|
|
|
|
|
integer(psb_ipk_) :: err_act
|
|
|
|
|
character(len=20) :: name='ecsr_mold'
|
|
|
|
|
logical, parameter :: debug=.false.
|
|
|
|
|
|
|
|
|
|
call psb_get_erraction(err_act)
|
|
|
|
|
|
|
|
|
|
info = 0
|
|
|
|
|
if (allocated(b)) then
|
|
|
|
|
call b%free()
|
|
|
|
|
deallocate(b,stat=info)
|
|
|
|
|
end if
|
|
|
|
|
if (info == 0) allocate(psb_c_ecsr_sparse_mat :: b, stat=info)
|
|
|
|
|
|
|
|
|
|
if (info /= 0) then
|
|
|
|
|
info = psb_err_alloc_dealloc_
|
|
|
|
|
call psb_errpush(info, name)
|
|
|
|
|
goto 9999
|
|
|
|
|
end if
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
9999 call psb_error_handler(err_act)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
end subroutine psb_c_ecsr_mold
|
|
|
|
|
|
|
|
|
|
subroutine psb_c_ecsr_csmv(alpha,a,x,beta,y,info,trans)
|
|
|
|
|
use psb_error_mod
|
|
|
|
|
use psb_string_mod
|
|
|
|
|
use psb_c_csr_mat_mod, psb_protect_name => psb_c_ecsr_csmv
|
|
|
|
|
implicit none
|
|
|
|
|
class(psb_c_ecsr_sparse_mat), intent(in) :: a
|
|
|
|
|
complex(psb_spk_), intent(in) :: alpha, beta, x(:)
|
|
|
|
|
complex(psb_spk_), intent(inout) :: y(:)
|
|
|
|
|
integer(psb_ipk_), intent(out) :: info
|
|
|
|
|
character, optional, intent(in) :: trans
|
|
|
|
|
|
|
|
|
|
character :: trans_
|
|
|
|
|
integer(psb_ipk_) :: m, n
|
|
|
|
|
logical :: tra, ctra
|
|
|
|
|
integer(psb_ipk_) :: err_act
|
|
|
|
|
integer(psb_ipk_) :: ierr(5)
|
|
|
|
|
character(len=20) :: name='c_csr_csmv'
|
|
|
|
|
logical, parameter :: debug=.false.
|
|
|
|
|
|
|
|
|
|
call psb_erractionsave(err_act)
|
|
|
|
|
info = psb_success_
|
|
|
|
|
if (a%is_dev()) call a%sync()
|
|
|
|
|
|
|
|
|
|
if (present(trans)) then
|
|
|
|
|
trans_ = trans
|
|
|
|
|
else
|
|
|
|
|
trans_ = 'N'
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
if (.not.a%is_asb()) then
|
|
|
|
|
info = psb_err_invalid_mat_state_
|
|
|
|
|
call psb_errpush(info,name)
|
|
|
|
|
goto 9999
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tra = (psb_toupper(trans_) == 'T')
|
|
|
|
|
ctra = (psb_toupper(trans_) == 'C')
|
|
|
|
|
|
|
|
|
|
if (tra.or.ctra) then
|
|
|
|
|
m = a%get_ncols()
|
|
|
|
|
n = a%get_nrows()
|
|
|
|
|
else
|
|
|
|
|
n = a%get_ncols()
|
|
|
|
|
m = a%get_nrows()
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
if (size(x,1)<n) then
|
|
|
|
|
info = psb_err_input_asize_small_i_
|
|
|
|
|
ierr(1) = 3; ierr(2) = size(x); ierr(3) = n;
|
|
|
|
|
call psb_errpush(info,name,i_err=ierr)
|
|
|
|
|
goto 9999
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
if (size(y,1)<m) then
|
|
|
|
|
info = psb_err_input_asize_small_i_
|
|
|
|
|
ierr(1) = 5; ierr(2) = size(y); ierr(3) =m;
|
|
|
|
|
call psb_errpush(info,name,i_err=ierr)
|
|
|
|
|
goto 9999
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
if (((beta == cone).and..not.(tra.or.ctra))&
|
|
|
|
|
& .or.(a%is_triangle()).or.(a%is_unit())) then
|
|
|
|
|
|
|
|
|
|
call psb_c_ecsr_csmv_inner(m,n,alpha,a%irp,a%ja,a%val,&
|
|
|
|
|
& a%nnerws,a%nerwp,x,y)
|
|
|
|
|
else
|
|
|
|
|
call a%psb_c_csr_sparse_mat%csmv(alpha,x,beta,y,info,trans)
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
call psb_erractionrestore(err_act)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
9999 call psb_error_handler(err_act)
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
contains
|
|
|
|
|
subroutine psb_c_ecsr_csmv_inner(m,n,alpha,irp,ja,val,&
|
|
|
|
|
& nnerws,nerwp,x,y)
|
|
|
|
|
integer(psb_ipk_), intent(in) :: m,n,nnerws,irp(*),ja(*),nerwp(*)
|
|
|
|
|
complex(psb_spk_), intent(in) :: alpha, x(*),val(*)
|
|
|
|
|
complex(psb_spk_), intent(inout) :: y(*)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
integer(psb_ipk_) :: i,j,ir
|
|
|
|
|
complex(psb_spk_) :: acc
|
|
|
|
|
|
|
|
|
|
if (alpha == czero) return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (alpha == cone) then
|
|
|
|
|
!$omp parallel do private(ir,i,j,acc)
|
|
|
|
|
do ir=1,nnerws
|
|
|
|
|
i = nerwp(ir)
|
|
|
|
|
acc = czero
|
|
|
|
|
do j=irp(i), irp(i+1)-1
|
|
|
|
|
acc = acc + val(j) * x(ja(j))
|
|
|
|
|
enddo
|
|
|
|
|
y(i) = y(i) + acc
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
else if (alpha == -cone) then
|
|
|
|
|
|
|
|
|
|
!$omp parallel do private(ir,i,j,acc)
|
|
|
|
|
do ir=1,nnerws
|
|
|
|
|
i = nerwp(ir)
|
|
|
|
|
acc = czero
|
|
|
|
|
do j=irp(i), irp(i+1)-1
|
|
|
|
|
acc = acc + val(j) * x(ja(j))
|
|
|
|
|
enddo
|
|
|
|
|
y(i) = y(i) -acc
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
|
|
!$omp parallel do private(ir,i,j,acc)
|
|
|
|
|
do ir=1,nnerws
|
|
|
|
|
i = nerwp(ir)
|
|
|
|
|
acc = czero
|
|
|
|
|
do j=irp(i), irp(i+1)-1
|
|
|
|
|
acc = acc + val(j) * x(ja(j))
|
|
|
|
|
enddo
|
|
|
|
|
y(i) = y(i) + alpha*acc
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
end subroutine psb_c_ecsr_csmv_inner
|
|
|
|
|
|
|
|
|
|
end subroutine psb_c_ecsr_csmv
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
subroutine psb_c_ecsr_cmp_nerwp(a,info)
|
|
|
|
|
use psb_const_mod
|
|
|
|
|
use psb_realloc_mod
|
|
|
|
|
use psb_c_base_mat_mod
|
|
|
|
|
use psb_c_csr_mat_mod, psb_protect_name => psb_c_ecsr_cmp_nerwp
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
class(psb_c_ecsr_sparse_mat), intent(inout) :: a
|
|
|
|
|
integer(psb_ipk_), intent(out) :: info
|
|
|
|
|
|
|
|
|
|
integer(psb_ipk_) :: nnerws, i, nr, nzr
|
|
|
|
|
info = psb_success_
|
|
|
|
|
nr = a%get_nrows()
|
|
|
|
|
call psb_realloc(nr,a%nerwp,info)
|
|
|
|
|
nnerws = 0
|
|
|
|
|
do i=1, nr
|
|
|
|
|
nzr = a%irp(i+1)-a%irp(i)
|
|
|
|
|
if (nzr>0) then
|
|
|
|
|
nnerws = nnerws + 1
|
|
|
|
|
a%nerwp(nnerws) = i
|
|
|
|
|
end if
|
|
|
|
|
end do
|
|
|
|
|
call psb_realloc(nnerws,a%nerwp,info)
|
|
|
|
|
end subroutine psb_c_ecsr_cmp_nerwp
|
|
|
|
|
|
|
|
|
|
subroutine psb_c_cp_ecsr_from_coo(a,b,info)
|
|
|
|
|
use psb_const_mod
|
|
|
|
|
use psb_realloc_mod
|
|
|
|
|
use psb_c_base_mat_mod
|
|
|
|
|
use psb_c_csr_mat_mod, psb_protect_name => psb_c_cp_ecsr_from_coo
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
class(psb_c_ecsr_sparse_mat), intent(inout) :: a
|
|
|
|
|
class(psb_c_coo_sparse_mat), intent(in) :: b
|
|
|
|
|
integer(psb_ipk_), intent(out) :: info
|
|
|
|
|
|
|
|
|
|
info = psb_success_
|
|
|
|
|
call a%psb_c_csr_sparse_mat%cp_from_coo(b,info)
|
|
|
|
|
if (info == psb_success_) call a%cmp_nerwp(info)
|
|
|
|
|
|
|
|
|
|
end subroutine psb_c_cp_ecsr_from_coo
|
|
|
|
|
|
|
|
|
|
subroutine psb_c_mv_ecsr_from_coo(a,b,info)
|
|
|
|
|
use psb_const_mod
|
|
|
|
|
use psb_realloc_mod
|
|
|
|
|
use psb_error_mod
|
|
|
|
|
use psb_c_base_mat_mod
|
|
|
|
|
use psb_c_csr_mat_mod, psb_protect_name => psb_c_mv_ecsr_from_coo
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
class(psb_c_ecsr_sparse_mat), intent(inout) :: a
|
|
|
|
|
class(psb_c_coo_sparse_mat), intent(inout) :: b
|
|
|
|
|
integer(psb_ipk_), intent(out) :: info
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
info = psb_success_
|
|
|
|
|
call a%psb_c_csr_sparse_mat%mv_from_coo(b,info)
|
|
|
|
|
if (info == psb_success_) call a%cmp_nerwp(info)
|
|
|
|
|
|
|
|
|
|
end subroutine psb_c_mv_ecsr_from_coo
|
|
|
|
|
|
|
|
|
|
subroutine psb_c_mv_ecsr_from_fmt(a,b,info)
|
|
|
|
|
use psb_const_mod
|
|
|
|
|
use psb_c_base_mat_mod
|
|
|
|
|
use psb_c_csr_mat_mod, psb_protect_name => psb_c_mv_ecsr_from_fmt
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
class(psb_c_ecsr_sparse_mat), intent(inout) :: a
|
|
|
|
|
class(psb_c_base_sparse_mat), intent(inout) :: b
|
|
|
|
|
integer(psb_ipk_), intent(out) :: info
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
info = psb_success_
|
|
|
|
|
call a%psb_c_csr_sparse_mat%mv_from_fmt(b,info)
|
|
|
|
|
if (info == psb_success_) call a%cmp_nerwp(info)
|
|
|
|
|
|
|
|
|
|
end subroutine psb_c_mv_ecsr_from_fmt
|
|
|
|
|
|
|
|
|
|
subroutine psb_c_cp_ecsr_from_fmt(a,b,info)
|
|
|
|
|
use psb_const_mod
|
|
|
|
|
use psb_c_base_mat_mod
|
|
|
|
|
use psb_realloc_mod
|
|
|
|
|
use psb_c_csr_mat_mod, psb_protect_name => psb_c_cp_ecsr_from_fmt
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
class(psb_c_ecsr_sparse_mat), intent(inout) :: a
|
|
|
|
|
class(psb_c_base_sparse_mat), intent(in) :: b
|
|
|
|
|
integer(psb_ipk_), intent(out) :: info
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
info = psb_success_
|
|
|
|
|
call a%psb_c_csr_sparse_mat%cp_from_fmt(b,info)
|
|
|
|
|
if (info == psb_success_) call a%cmp_nerwp(info)
|
|
|
|
|
|
|
|
|
|
end subroutine psb_c_cp_ecsr_from_fmt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
|
|
|
|
|
!
|
|
|
|
|