mirror of
https://github.com/sfilippone/psblas3.git
synced 2026-10-16 02:49:03 +00:00
Put renum under template. New interface/implementation.
This commit is contained in:
+3
-1
@@ -10,7 +10,8 @@ HERE=.
|
||||
BASEOBJS= psb_blockpart_mod.o psb_metispart_mod.o psb_partidx_mod.o \
|
||||
psb_hbio_mod.o psb_mmio_mod.o psb_mat_dist_mod.o \
|
||||
psb_s_mat_dist_mod.o psb_d_mat_dist_mod.o psb_c_mat_dist_mod.o psb_z_mat_dist_mod.o \
|
||||
psb_renum_mod.o psb_gps_mod.o
|
||||
psb_renum_mod.o psb_gps_mod.o \
|
||||
psb_s_renum_mod.o psb_d_renum_mod.o psb_c_renum_mod.o psb_z_renum_mod.o
|
||||
IMPLOBJS= psb_s_hbio_impl.o psb_d_hbio_impl.o \
|
||||
psb_c_hbio_impl.o psb_z_hbio_impl.o \
|
||||
psb_s_mmio_impl.o psb_d_mmio_impl.o \
|
||||
@@ -40,6 +41,7 @@ $(OBJS): $(MODDIR)/$(BASEMODNAME)$(.mod)
|
||||
psb_util_mod.o: $(BASEOBJS)
|
||||
psb_metispart_mod.o: psb_metis_int.o
|
||||
psb_mat_dist_mod.o: psb_s_mat_dist_mod.o psb_d_mat_dist_mod.o psb_c_mat_dist_mod.o psb_z_mat_dist_mod.o
|
||||
psb_renum_mod.o: psb_s_renum_mod.o psb_d_renum_mod.o psb_c_renum_mod.o psb_z_renum_mod.o
|
||||
|
||||
$(IMPLOBJS): $(BASEOBJS)
|
||||
|
||||
|
||||
+273
-55
@@ -29,55 +29,11 @@
|
||||
! POSSIBILITY OF SUCH DAMAGE.
|
||||
!
|
||||
!
|
||||
subroutine psb_c_mat_renums(alg,mat,info,perm)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_c_mat_renums
|
||||
implicit none
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_cspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
|
||||
integer(psb_ipk_) :: err_act, nr, nc, ialg
|
||||
character(len=20) :: name
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
select case (psb_toupper(alg))
|
||||
case ('GPS')
|
||||
ialg = psb_mat_renum_gps_
|
||||
case ('AMD')
|
||||
ialg = psb_mat_renum_amd_
|
||||
case ('NONE', 'ID')
|
||||
ialg = psb_mat_renum_identity_
|
||||
case default
|
||||
write(0,*) 'Unknown algorithm "',psb_toupper(alg),'"'
|
||||
ialg = -1
|
||||
end select
|
||||
|
||||
call psb_mat_renum(ialg,mat,info,perm)
|
||||
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_from_subroutine_non_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
end subroutine psb_c_mat_renums
|
||||
|
||||
subroutine psb_c_mat_renum(alg,mat,info,perm)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_c_mat_renum
|
||||
implicit none
|
||||
integer(psb_ipk_), intent(in) :: alg
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_cspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
@@ -89,8 +45,6 @@ subroutine psb_c_mat_renum(alg,mat,info,perm)
|
||||
name = 'mat_renum'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
|
||||
nr = mat%get_nrows()
|
||||
nc = mat%get_ncols()
|
||||
if (nr /= nc) then
|
||||
@@ -100,16 +54,17 @@ subroutine psb_c_mat_renum(alg,mat,info,perm)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
select case (alg)
|
||||
case(psb_mat_renum_gps_)
|
||||
info = psb_success_
|
||||
select case (psb_toupper(alg))
|
||||
case ('GPS')
|
||||
|
||||
call psb_mat_renum_gps(mat,info,perm)
|
||||
|
||||
case(psb_mat_renum_amd_)
|
||||
case('AMD')
|
||||
|
||||
call psb_mat_renum_amd(mat,info,perm)
|
||||
|
||||
case(psb_mat_renum_identity_)
|
||||
case ('NONE', 'ID')
|
||||
nr = mat%get_nrows()
|
||||
allocate(perm(nr),stat=info)
|
||||
if (info == 0) then
|
||||
@@ -122,8 +77,9 @@ subroutine psb_c_mat_renum(alg,mat,info,perm)
|
||||
goto 9999
|
||||
endif
|
||||
case default
|
||||
write(0,*) 'Unknown algorithm "',psb_toupper(alg),'"'
|
||||
info = psb_err_input_value_invalid_i_
|
||||
ierr(1) = 1; ierr(2) = alg;
|
||||
ierr(1) = 1;
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end select
|
||||
@@ -161,7 +117,7 @@ contains
|
||||
integer(psb_ipk_) :: i, j, k, ideg, nr, ibw, ipf, idpth
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum'
|
||||
name = 'mat_renum_gps'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
@@ -267,7 +223,7 @@ contains
|
||||
name = 'mat_renum_amd'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
#if defined(HAVE_AMD) && defined(IPK4)
|
||||
#if defined(HAVE_AMD) && defined(IPK4)
|
||||
|
||||
info = psb_success_
|
||||
nr = a%get_nrows()
|
||||
@@ -331,11 +287,273 @@ contains
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
end subroutine psb_mat_renum_amd
|
||||
|
||||
end subroutine psb_c_mat_renum
|
||||
|
||||
subroutine psb_lc_mat_renum(alg,mat,info,perm)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_lc_mat_renum
|
||||
implicit none
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_lcspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: perm(:)
|
||||
|
||||
integer(psb_lpk_) :: nr, nc, i
|
||||
integer(psb_ipk_) :: err_act, ierr(5)
|
||||
character(len=20) :: name
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
nr = mat%get_nrows()
|
||||
nc = mat%get_ncols()
|
||||
if (nr /= nc) then
|
||||
info = psb_err_rectangular_mat_unsupported_
|
||||
ierr(1) = nr; ierr(2) = nc;
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
info = psb_success_
|
||||
select case (psb_toupper(alg))
|
||||
case ('GPS')
|
||||
|
||||
call psb_lmat_renum_gps(mat,info,perm)
|
||||
|
||||
case('AMD')
|
||||
|
||||
call psb_lmat_renum_amd(mat,info,perm)
|
||||
|
||||
case ('NONE', 'ID')
|
||||
nr = mat%get_nrows()
|
||||
allocate(perm(nr),stat=info)
|
||||
if (info == 0) then
|
||||
do i=1,nr
|
||||
perm(i) = i
|
||||
end do
|
||||
else
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
case default
|
||||
write(0,*) 'Unknown algorithm "',psb_toupper(alg),'"'
|
||||
info = psb_err_input_value_invalid_i_
|
||||
ierr(1) = 1;
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end select
|
||||
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_from_subroutine_non_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
contains
|
||||
|
||||
subroutine psb_lmat_renum_gps(a,info,operm)
|
||||
use psb_base_mod
|
||||
use psb_lgps_mod
|
||||
implicit none
|
||||
type(psb_lcspmat_type), intent(inout) :: a
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: operm(:)
|
||||
|
||||
!
|
||||
class(psb_lc_base_sparse_mat), allocatable :: aa
|
||||
type(psb_lc_csr_sparse_mat) :: acsr
|
||||
type(psb_lc_coo_sparse_mat) :: acoo
|
||||
|
||||
integer(psb_ipk_) :: err_act
|
||||
character(len=20) :: name
|
||||
integer(psb_lpk_), allocatable :: ndstk(:,:), iold(:), ndeg(:), perm(:)
|
||||
integer(psb_lpk_) :: i, j, k, ideg, nr, ibw, ipf, idpth
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum_gps'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
|
||||
call a%mold(aa)
|
||||
call a%mv_to(aa)
|
||||
call aa%mv_to_fmt(acsr,info)
|
||||
! Insert call to gps_reduce
|
||||
nr = acsr%get_nrows()
|
||||
ideg = 0
|
||||
do i=1, nr
|
||||
ideg = max(ideg,acsr%irp(i+1)-acsr%irp(i))
|
||||
end do
|
||||
allocate(ndstk(nr,ideg), iold(nr), perm(nr+1), ndeg(nr),stat=info)
|
||||
if (info /= 0) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info, name)
|
||||
goto 9999
|
||||
end if
|
||||
do i=1, nr
|
||||
iold(i) = i
|
||||
ndstk(i,:) = 0
|
||||
k = 0
|
||||
do j=acsr%irp(i),acsr%irp(i+1)-1
|
||||
k = k + 1
|
||||
ndstk(i,k) = acsr%ja(j)
|
||||
end do
|
||||
end do
|
||||
perm = 0
|
||||
|
||||
call psb_lgps_reduce(ndstk,nr,ideg,iold,perm,ndeg,ibw,ipf,idpth)
|
||||
|
||||
if (.not.psb_isaperm(nr,perm)) then
|
||||
write(0,*) 'Something wrong: bad perm from gps_reduce'
|
||||
info = psb_err_from_subroutine_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
! Move to coordinate to apply renumbering
|
||||
call acsr%mv_to_coo(acoo,info)
|
||||
do i=1, acoo%get_nzeros()
|
||||
acoo%ia(i) = perm(acoo%ia(i))
|
||||
acoo%ja(i) = perm(acoo%ja(i))
|
||||
end do
|
||||
call acoo%fix(info)
|
||||
|
||||
! Get back to where we started from
|
||||
call aa%mv_from_coo(acoo,info)
|
||||
call a%mv_from(aa)
|
||||
if (present(operm)) then
|
||||
call psb_realloc(nr,operm,info)
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
operm(1:nr) = perm(1:nr)
|
||||
end if
|
||||
|
||||
deallocate(aa)
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
end subroutine psb_lmat_renum_gps
|
||||
|
||||
|
||||
subroutine psb_lmat_renum_amd(a,info,operm)
|
||||
#if defined(HAVE_AMD)
|
||||
use iso_c_binding
|
||||
#endif
|
||||
use psb_base_mod
|
||||
implicit none
|
||||
type(psb_lcspmat_type), intent(inout) :: a
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: operm(:)
|
||||
|
||||
!
|
||||
#if defined(HAVE_AMD)
|
||||
interface
|
||||
function psb_amd_order(n,ap,ai,p)&
|
||||
& result(res) bind(c,name='psb_amd_order')
|
||||
use iso_c_binding
|
||||
integer(c_int) :: res
|
||||
integer(c_int), value :: n
|
||||
integer(c_int) :: ap(*), ai(*), p(*)
|
||||
end function psb_amd_order
|
||||
end interface
|
||||
#endif
|
||||
|
||||
type(psb_lc_csc_sparse_mat) :: acsc
|
||||
class(psb_lc_base_sparse_mat), allocatable :: aa
|
||||
type(psb_lc_coo_sparse_mat) :: acoo
|
||||
|
||||
integer(psb_ipk_), allocatable :: perm(:)
|
||||
integer(psb_ipk_) :: err_act
|
||||
character(len=20) :: name
|
||||
integer(psb_lpk_) :: i, j, k, ideg, nr, ibw, ipf, idpth, nz
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum_amd'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
#if defined(HAVE_AMD) && defined(LPK4)
|
||||
|
||||
info = psb_success_
|
||||
nr = a%get_nrows()
|
||||
nz = a%get_nzeros()
|
||||
allocate(perm(nr),stat=info)
|
||||
if (info /= 0) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
|
||||
allocate(aa, mold=a%a)
|
||||
call a%mv_to(acsc)
|
||||
|
||||
acsc%ia(:) = acsc%ia(:) - 1
|
||||
acsc%icp(:) = acsc%icp(:) - 1
|
||||
|
||||
info = psb_amd_order(nr,acsc%icp,acsc%ia,perm)
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_from_subroutine_
|
||||
call psb_errpush(info,name,a_err='psb_amd_order')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
perm(:) = perm(:) + 1
|
||||
acsc%ia(:) = acsc%ia(:) + 1
|
||||
acsc%icp(:) = acsc%icp(:) + 1
|
||||
|
||||
call acsc%mv_to_coo(acoo,info)
|
||||
do i=1, acoo%get_nzeros()
|
||||
acoo%ia(i) = perm(acoo%ia(i))
|
||||
acoo%ja(i) = perm(acoo%ja(i))
|
||||
end do
|
||||
call acoo%fix(info)
|
||||
|
||||
! Get back to where we started from
|
||||
call aa%mv_from_coo(acoo,info)
|
||||
call a%mv_from(aa)
|
||||
if (present(operm)) then
|
||||
call psb_realloc(nr,operm,info)
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
operm(1:nr) = perm(1:nr)
|
||||
end if
|
||||
|
||||
deallocate(aa,perm)
|
||||
|
||||
#else
|
||||
|
||||
info = psb_err_missing_aux_lib_
|
||||
call psb_errpush(info, name)
|
||||
goto 9999
|
||||
#endif
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
end subroutine psb_lmat_renum_amd
|
||||
|
||||
end subroutine psb_lc_mat_renum
|
||||
|
||||
subroutine psb_c_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_c_cmp_bwpf
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
!
|
||||
! Parallel Sparse BLAS version 3.5
|
||||
! (C) Copyright 2006-2018
|
||||
! Salvatore Filippone
|
||||
! Alfredo Buttari
|
||||
!
|
||||
! Redistribution and use in source and binary forms, with or without
|
||||
! modification, are permitted provided that the following conditions
|
||||
! are met:
|
||||
! 1. Redistributions of source code must retain the above copyright
|
||||
! notice, this list of conditions and the following disclaimer.
|
||||
! 2. Redistributions in binary form must reproduce the above copyright
|
||||
! notice, this list of conditions, and the following disclaimer in the
|
||||
! documentation and/or other materials provided with the distribution.
|
||||
! 3. The name of the PSBLAS group or the names of its contributors may
|
||||
! not be used to endorse or promote products derived from this
|
||||
! software without specific written permission.
|
||||
!
|
||||
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
||||
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
! POSSIBILITY OF SUCH DAMAGE.
|
||||
!
|
||||
!
|
||||
module psb_c_renum_mod
|
||||
use psb_base_mod
|
||||
|
||||
interface psb_mat_renum
|
||||
subroutine psb_c_mat_renum(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_cspmat_type
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_cspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_c_mat_renum
|
||||
subroutine psb_lc_mat_renum(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_lpk_, psb_lcspmat_type
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_lcspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_lc_mat_renum
|
||||
end interface psb_mat_renum
|
||||
|
||||
interface psb_cmp_bwpf
|
||||
subroutine psb_c_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_cspmat_type
|
||||
type(psb_cspmat_type), intent(in) :: mat
|
||||
integer(psb_ipk_), intent(out) :: bwl, bwu
|
||||
integer(psb_ipk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_c_cmp_bwpf
|
||||
subroutine psb_lc_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_lpk_, psb_lcspmat_type
|
||||
type(psb_lcspmat_type), intent(in) :: mat
|
||||
integer(psb_lpk_), intent(out) :: bwl, bwu
|
||||
integer(psb_lpk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_lc_cmp_bwpf
|
||||
end interface psb_cmp_bwpf
|
||||
|
||||
end module psb_c_renum_mod
|
||||
+271
-52
@@ -29,55 +29,11 @@
|
||||
! POSSIBILITY OF SUCH DAMAGE.
|
||||
!
|
||||
!
|
||||
subroutine psb_d_mat_renums(alg,mat,info,perm)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_d_mat_renums
|
||||
implicit none
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_dspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
|
||||
integer(psb_ipk_) :: err_act, nr, nc, ialg
|
||||
character(len=20) :: name
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
select case (psb_toupper(alg))
|
||||
case ('GPS')
|
||||
ialg = psb_mat_renum_gps_
|
||||
case ('AMD')
|
||||
ialg = psb_mat_renum_amd_
|
||||
case ('NONE', 'ID')
|
||||
ialg = psb_mat_renum_identity_
|
||||
case default
|
||||
write(0,*) 'Unknown algorithm "',psb_toupper(alg),'"'
|
||||
ialg = -1
|
||||
end select
|
||||
|
||||
call psb_mat_renum(ialg,mat,info,perm)
|
||||
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_from_subroutine_non_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
end subroutine psb_d_mat_renums
|
||||
|
||||
subroutine psb_d_mat_renum(alg,mat,info,perm)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_d_mat_renum
|
||||
implicit none
|
||||
integer(psb_ipk_), intent(in) :: alg
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_dspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
@@ -89,8 +45,6 @@ subroutine psb_d_mat_renum(alg,mat,info,perm)
|
||||
name = 'mat_renum'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
|
||||
nr = mat%get_nrows()
|
||||
nc = mat%get_ncols()
|
||||
if (nr /= nc) then
|
||||
@@ -100,16 +54,17 @@ subroutine psb_d_mat_renum(alg,mat,info,perm)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
select case (alg)
|
||||
case(psb_mat_renum_gps_)
|
||||
info = psb_success_
|
||||
select case (psb_toupper(alg))
|
||||
case ('GPS')
|
||||
|
||||
call psb_mat_renum_gps(mat,info,perm)
|
||||
|
||||
case(psb_mat_renum_amd_)
|
||||
case('AMD')
|
||||
|
||||
call psb_mat_renum_amd(mat,info,perm)
|
||||
|
||||
case(psb_mat_renum_identity_)
|
||||
case ('NONE', 'ID')
|
||||
nr = mat%get_nrows()
|
||||
allocate(perm(nr),stat=info)
|
||||
if (info == 0) then
|
||||
@@ -122,8 +77,9 @@ subroutine psb_d_mat_renum(alg,mat,info,perm)
|
||||
goto 9999
|
||||
endif
|
||||
case default
|
||||
write(0,*) 'Unknown algorithm "',psb_toupper(alg),'"'
|
||||
info = psb_err_input_value_invalid_i_
|
||||
ierr(1) = 1; ierr(2) = alg;
|
||||
ierr(1) = 1;
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end select
|
||||
@@ -335,6 +291,269 @@ contains
|
||||
|
||||
end subroutine psb_d_mat_renum
|
||||
|
||||
subroutine psb_ld_mat_renum(alg,mat,info,perm)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_ld_mat_renum
|
||||
implicit none
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_ldspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: perm(:)
|
||||
|
||||
integer(psb_lpk_) :: nr, nc, i
|
||||
integer(psb_ipk_) :: err_act, ierr(5)
|
||||
character(len=20) :: name
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
nr = mat%get_nrows()
|
||||
nc = mat%get_ncols()
|
||||
if (nr /= nc) then
|
||||
info = psb_err_rectangular_mat_unsupported_
|
||||
ierr(1) = nr; ierr(2) = nc;
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
info = psb_success_
|
||||
select case (psb_toupper(alg))
|
||||
case ('GPS')
|
||||
|
||||
call psb_lmat_renum_gps(mat,info,perm)
|
||||
|
||||
case('AMD')
|
||||
|
||||
call psb_lmat_renum_amd(mat,info,perm)
|
||||
|
||||
case ('NONE', 'ID')
|
||||
nr = mat%get_nrows()
|
||||
allocate(perm(nr),stat=info)
|
||||
if (info == 0) then
|
||||
do i=1,nr
|
||||
perm(i) = i
|
||||
end do
|
||||
else
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
case default
|
||||
write(0,*) 'Unknown algorithm "',psb_toupper(alg),'"'
|
||||
info = psb_err_input_value_invalid_i_
|
||||
ierr(1) = 1;
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end select
|
||||
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_from_subroutine_non_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
contains
|
||||
|
||||
subroutine psb_lmat_renum_gps(a,info,operm)
|
||||
use psb_base_mod
|
||||
use psb_lgps_mod
|
||||
implicit none
|
||||
type(psb_ldspmat_type), intent(inout) :: a
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: operm(:)
|
||||
|
||||
!
|
||||
class(psb_ld_base_sparse_mat), allocatable :: aa
|
||||
type(psb_ld_csr_sparse_mat) :: acsr
|
||||
type(psb_ld_coo_sparse_mat) :: acoo
|
||||
|
||||
integer(psb_ipk_) :: err_act
|
||||
character(len=20) :: name
|
||||
integer(psb_lpk_), allocatable :: ndstk(:,:), iold(:), ndeg(:), perm(:)
|
||||
integer(psb_lpk_) :: i, j, k, ideg, nr, ibw, ipf, idpth
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum_gps'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
|
||||
call a%mold(aa)
|
||||
call a%mv_to(aa)
|
||||
call aa%mv_to_fmt(acsr,info)
|
||||
! Insert call to gps_reduce
|
||||
nr = acsr%get_nrows()
|
||||
ideg = 0
|
||||
do i=1, nr
|
||||
ideg = max(ideg,acsr%irp(i+1)-acsr%irp(i))
|
||||
end do
|
||||
allocate(ndstk(nr,ideg), iold(nr), perm(nr+1), ndeg(nr),stat=info)
|
||||
if (info /= 0) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info, name)
|
||||
goto 9999
|
||||
end if
|
||||
do i=1, nr
|
||||
iold(i) = i
|
||||
ndstk(i,:) = 0
|
||||
k = 0
|
||||
do j=acsr%irp(i),acsr%irp(i+1)-1
|
||||
k = k + 1
|
||||
ndstk(i,k) = acsr%ja(j)
|
||||
end do
|
||||
end do
|
||||
perm = 0
|
||||
|
||||
call psb_lgps_reduce(ndstk,nr,ideg,iold,perm,ndeg,ibw,ipf,idpth)
|
||||
|
||||
if (.not.psb_isaperm(nr,perm)) then
|
||||
write(0,*) 'Something wrong: bad perm from gps_reduce'
|
||||
info = psb_err_from_subroutine_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
! Move to coordinate to apply renumbering
|
||||
call acsr%mv_to_coo(acoo,info)
|
||||
do i=1, acoo%get_nzeros()
|
||||
acoo%ia(i) = perm(acoo%ia(i))
|
||||
acoo%ja(i) = perm(acoo%ja(i))
|
||||
end do
|
||||
call acoo%fix(info)
|
||||
|
||||
! Get back to where we started from
|
||||
call aa%mv_from_coo(acoo,info)
|
||||
call a%mv_from(aa)
|
||||
if (present(operm)) then
|
||||
call psb_realloc(nr,operm,info)
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
operm(1:nr) = perm(1:nr)
|
||||
end if
|
||||
|
||||
deallocate(aa)
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
end subroutine psb_lmat_renum_gps
|
||||
|
||||
|
||||
subroutine psb_lmat_renum_amd(a,info,operm)
|
||||
#if defined(HAVE_AMD)
|
||||
use iso_c_binding
|
||||
#endif
|
||||
use psb_base_mod
|
||||
implicit none
|
||||
type(psb_ldspmat_type), intent(inout) :: a
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: operm(:)
|
||||
|
||||
!
|
||||
#if defined(HAVE_AMD)
|
||||
interface
|
||||
function psb_amd_order(n,ap,ai,p)&
|
||||
& result(res) bind(c,name='psb_amd_order')
|
||||
use iso_c_binding
|
||||
integer(c_int) :: res
|
||||
integer(c_int), value :: n
|
||||
integer(c_int) :: ap(*), ai(*), p(*)
|
||||
end function psb_amd_order
|
||||
end interface
|
||||
#endif
|
||||
|
||||
type(psb_ld_csc_sparse_mat) :: acsc
|
||||
class(psb_ld_base_sparse_mat), allocatable :: aa
|
||||
type(psb_ld_coo_sparse_mat) :: acoo
|
||||
|
||||
integer(psb_ipk_), allocatable :: perm(:)
|
||||
integer(psb_ipk_) :: err_act
|
||||
character(len=20) :: name
|
||||
integer(psb_lpk_) :: i, j, k, ideg, nr, ibw, ipf, idpth, nz
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum_amd'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
#if defined(HAVE_AMD) && defined(LPK4)
|
||||
|
||||
info = psb_success_
|
||||
nr = a%get_nrows()
|
||||
nz = a%get_nzeros()
|
||||
allocate(perm(nr),stat=info)
|
||||
if (info /= 0) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
|
||||
allocate(aa, mold=a%a)
|
||||
call a%mv_to(acsc)
|
||||
|
||||
acsc%ia(:) = acsc%ia(:) - 1
|
||||
acsc%icp(:) = acsc%icp(:) - 1
|
||||
|
||||
info = psb_amd_order(nr,acsc%icp,acsc%ia,perm)
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_from_subroutine_
|
||||
call psb_errpush(info,name,a_err='psb_amd_order')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
perm(:) = perm(:) + 1
|
||||
acsc%ia(:) = acsc%ia(:) + 1
|
||||
acsc%icp(:) = acsc%icp(:) + 1
|
||||
|
||||
call acsc%mv_to_coo(acoo,info)
|
||||
do i=1, acoo%get_nzeros()
|
||||
acoo%ia(i) = perm(acoo%ia(i))
|
||||
acoo%ja(i) = perm(acoo%ja(i))
|
||||
end do
|
||||
call acoo%fix(info)
|
||||
|
||||
! Get back to where we started from
|
||||
call aa%mv_from_coo(acoo,info)
|
||||
call a%mv_from(aa)
|
||||
if (present(operm)) then
|
||||
call psb_realloc(nr,operm,info)
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
operm(1:nr) = perm(1:nr)
|
||||
end if
|
||||
|
||||
deallocate(aa,perm)
|
||||
|
||||
#else
|
||||
|
||||
info = psb_err_missing_aux_lib_
|
||||
call psb_errpush(info, name)
|
||||
goto 9999
|
||||
#endif
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
end subroutine psb_lmat_renum_amd
|
||||
|
||||
end subroutine psb_ld_mat_renum
|
||||
|
||||
subroutine psb_d_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_d_cmp_bwpf
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
!
|
||||
! Parallel Sparse BLAS version 3.5
|
||||
! (C) Copyright 2006-2018
|
||||
! Salvatore Filippone
|
||||
! Alfredo Buttari
|
||||
!
|
||||
! Redistribution and use in source and binary forms, with or without
|
||||
! modification, are permitted provided that the following conditions
|
||||
! are met:
|
||||
! 1. Redistributions of source code must retain the above copyright
|
||||
! notice, this list of conditions and the following disclaimer.
|
||||
! 2. Redistributions in binary form must reproduce the above copyright
|
||||
! notice, this list of conditions, and the following disclaimer in the
|
||||
! documentation and/or other materials provided with the distribution.
|
||||
! 3. The name of the PSBLAS group or the names of its contributors may
|
||||
! not be used to endorse or promote products derived from this
|
||||
! software without specific written permission.
|
||||
!
|
||||
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
||||
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
! POSSIBILITY OF SUCH DAMAGE.
|
||||
!
|
||||
!
|
||||
module psb_d_renum_mod
|
||||
use psb_base_mod
|
||||
|
||||
interface psb_mat_renum
|
||||
subroutine psb_d_mat_renum(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_dspmat_type
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_dspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_d_mat_renum
|
||||
subroutine psb_ld_mat_renum(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_lpk_, psb_ldspmat_type
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_ldspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_ld_mat_renum
|
||||
end interface psb_mat_renum
|
||||
|
||||
interface psb_cmp_bwpf
|
||||
subroutine psb_d_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_dspmat_type
|
||||
type(psb_dspmat_type), intent(in) :: mat
|
||||
integer(psb_ipk_), intent(out) :: bwl, bwu
|
||||
integer(psb_ipk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_d_cmp_bwpf
|
||||
subroutine psb_ld_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_lpk_, psb_ldspmat_type
|
||||
type(psb_ldspmat_type), intent(in) :: mat
|
||||
integer(psb_lpk_), intent(out) :: bwl, bwu
|
||||
integer(psb_lpk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_ld_cmp_bwpf
|
||||
end interface psb_cmp_bwpf
|
||||
|
||||
end module psb_d_renum_mod
|
||||
+741
-1
@@ -774,4 +774,744 @@ CONTAINS
|
||||
RETURN
|
||||
END SUBROUTINE REALLOC
|
||||
!
|
||||
END MODULE psb_gps_mod
|
||||
end module psb_gps_mod
|
||||
|
||||
module psb_lgps_mod
|
||||
!
|
||||
use psb_base_mod, only : psb_lpk_
|
||||
public psb_lgps_reduce
|
||||
!
|
||||
! COMMON /GRA/ N, IDPTH, IDEG
|
||||
!
|
||||
private
|
||||
! common /CC/ XCC,SIZEG,STPT
|
||||
integer(psb_lpk_), save :: xcc,n,idpth,ideg
|
||||
integer(psb_lpk_),allocatable,SAVE :: SIZEG(:),STPT(:)
|
||||
!
|
||||
! COMMON /LVLW/ NHIGH,NLOW,NACUM
|
||||
integer(psb_lpk_),allocatable,target,save :: NHIGH(:),NLOW(:),NACUM(:),AUX(:)
|
||||
integer(psb_lpk_),PARAMETER :: INIT=500
|
||||
!
|
||||
CONTAINS
|
||||
!
|
||||
!!$ SUBROUTINE psb_gps_reduce(NDSTK, NR, IOLD, RENUM, NDEG, LVL, LVLS1, LVLS2,&
|
||||
!!$ & CCSTOR, IBW2, IPF2,NE,IDPTHE,IDEGE)
|
||||
SUBROUTINE psb_lgps_reduce(NDSTK, NR, IDEGE, IOLD, RENUM, NDEG,ibw2,ipf2,IDPTHE)
|
||||
! SUBROUTINE REDUCE DETERMINES A ROW AND COLUMN PERMUTATION WHICH,
|
||||
! WHEN APPLIED TO A GIVEN SPARSE MATRIX, PRODUCES A PERMUTED
|
||||
! MATRIX WITH A SMALLER BANDWIDTH AND PROFILE.
|
||||
! THE INPUT ARRAY IS A CONNECTION TABLE WHICH REPRESENTS THE
|
||||
! INDICES OF THE NONZERO ELEMENTS OF THE MATRIX, A. THE ALGO-
|
||||
! RITHM IS DESCRIBED IN TERMS OF THE ADJACENCY GRAPH WHICH
|
||||
! HAS THE CHARACTERISTIC THAT THERE IS AN EDGE (CONNECTION)
|
||||
! BETWEEN NODES I AND J IF A(I,J) /= 0 AND I /= J.
|
||||
! DIMENSIONING INFORMATION--THE FOLLOWING INTEGER ARRAYS MUST BE
|
||||
! DIMENSIONED IN THE CALLING ROUTINE.
|
||||
! NDSTK(NR,D1) D1 IS >= MAXIMUM DEGREE OF ALL NODES.
|
||||
! IOLD(D2) D2 AND NR ARE >= THE TOTAL NUMBER OF
|
||||
! RENUM(D2+1) NODES IN THE GRAPH.
|
||||
! NDEG(D2) STORAGE REQUIREMENTS CAN BE SIGNIFICANTLY
|
||||
! LVL(D2) DECREASED FOR IBM 360 AND 370 COMPUTERS
|
||||
! LVLS1(D2) BY REPLACING INTEGER NDSTK BY
|
||||
! LVLS2(D2) INTEGER*2 NDSTK IN SUBROUTINES REDUCE,
|
||||
! CCSTOR(D2) DGREE, FNDIAM, TREE AND NUMBER.
|
||||
! COMMON INFORMATION--THE FOLLOWING COMMON BLOCK MUST BE IN THE
|
||||
! CALLING ROUTINE.
|
||||
! COMMON/GRA/N,IDPTH,IDEG
|
||||
! EXPLANATION OF INPUT VARIABLES--
|
||||
! NDSTK- CONNECTION TABLE REPRESENTING GRAPH.
|
||||
! NDSTK(I,J)=NODE NUMBER OF JTH CONNECTION TO NODE
|
||||
! NUMBER I. A CONNECTION OF A NODE TO ITSELF IS NOT
|
||||
! LISTED. EXTRA POSITIONS MUST HAVE ZERO FILL.
|
||||
! NR- ROW DIMENSION ASSIGNED NDSTK IN CALLING PROGRAM.
|
||||
! IOLD(I)- NUMBERING OF ITH NODE UPON INPUT.
|
||||
! IF NO NUMBERING EXISTS THEN IOLD(I)=I.
|
||||
! N- NUMBER OF NODES IN GRAPH (EQUAL TO ORDER OF MATRIX).
|
||||
! IDEG- MAXIMUM DEGREE OF ANY NODE IN THE GRAPH.
|
||||
! EXPLANATION OF OUTPUT VARIABLES--
|
||||
! RENUM(I)- THE NEW NUMBER FOR THE ITH NODE.
|
||||
! NDEG(I)- THE DEGREE OF THE ITH NODE.
|
||||
! IBW2- THE BANDWIDTH AFTER RENUMBERING.
|
||||
! IPF2- THE PROFILE AFTER RENUMBERING.
|
||||
! IDPTH- NUMBER OF LEVELS IN REDUCE LEVEL STRUCTURE.
|
||||
! THE FOLLOWING ONLY HAVE MEANING IF THE GRAPH WAS CONNECTED--
|
||||
! LVL(I)- INDEX INTO LVLS1 TO THE FIRST NODE IN LEVEL I.
|
||||
! LVL(I+1)-LVL(I)= NUMBER OF NODES IN ITH LEVEL
|
||||
! LVLS1- NODE NUMBERS LISTED BY LEVEL.
|
||||
! LVLS2(I)- THE LEVEL ASSIGNED TO NODE I BY REDUCE.
|
||||
! WORKING STORAGE VARIABLE--
|
||||
! CCSTOR
|
||||
! LOCAL STORAGE--
|
||||
! COMMON/CC/-SUBROUTINES REDUCE, SORT2 AND PIKLVL ASSUME THAT
|
||||
! THE GRAPH HAS AT MOST 50 CONNECTED COMPONENTS.
|
||||
! SUBROUTINE FNDIAM ASSUMES THAT THERE ARE AT MOST
|
||||
! 100 NODES IN THE LAST LEVEL.
|
||||
! COMMON/LVLW/-SUBROUTINES SETUP AND PIKLVL ASSUME THAT THERE
|
||||
! ARE AT MOST 100 LEVELS.
|
||||
! USE INTEGER*2 NDSTK WITH AN IBM 360 OR 370.
|
||||
use psb_base_mod
|
||||
implicit none
|
||||
INTEGER(psb_lpk_) :: NR, IDEGE, IBW2, IPF2, IDPTHE
|
||||
! COMMON /GRA/ N, IDPTH, IDEG
|
||||
! IT IS ASSUMED THAT THE GRAPH HAS AT MOST 50 CONNECTED COMPONENTS.
|
||||
! COMMON /CC/ XCC, SIZEG(50), STPT(50)
|
||||
! COMMON /LVLW/ NHIGH(100), NLOW(100), NACUM(100)
|
||||
integer(psb_lpk_) :: stnode, rvnode, stnum, sbnum
|
||||
integer(psb_lpk_) :: ndstk(nr,idege), iold(nr), renum(nr+1), ndeg(nr)
|
||||
integer(psb_lpk_) :: lvl(nr), lvls1(nr), lvls2(nr), ccstor(nr)
|
||||
integer(psb_lpk_) :: nflg, info, i, ibw1, ipf1, idflt, isdir, lroot, lowdg
|
||||
integer(psb_lpk_) :: lvlbot, lvln, lvlwth, maxlw, num
|
||||
n = nr
|
||||
ideg = idege
|
||||
idpth = 0
|
||||
|
||||
ALLOCATE(SIZEG(NR),STPT(NR), STAT=INFO)
|
||||
IF(INFO /= psb_success_) THEN
|
||||
write(psb_out_unit,*) 'ERROR! MEMORY ALLOCATION # 1 FAILED IN GPS'
|
||||
STOP
|
||||
END IF
|
||||
!
|
||||
ALLOCATE(NHIGH(INIT), NLOW(INIT), NACUM(INIT), AUX(INIT), STAT=INFO)
|
||||
IF(INFO /= psb_success_) THEN
|
||||
write(psb_out_unit,*) 'ERROR! MEMORY ALLOCATION # 2 FAILED IN GPS'
|
||||
STOP
|
||||
END IF
|
||||
!
|
||||
IBW2 = 0
|
||||
IPF2 = 0
|
||||
! SET RENUM(I)=0 FOR ALL I TO INDICATE NODE I IS UNNUMBERED
|
||||
DO I=1,N
|
||||
RENUM(I) = 0
|
||||
END DO
|
||||
! COMPUTE DEGREE OF EACH NODE AND ORIGINAL BANDWIDTH AND PROFILE
|
||||
CALL DGREE(NDSTK, NR, NDEG, IOLD, IBW1, IPF1)
|
||||
! SBNUM= LOW END OF AVAILABLE NUMBERS FOR RENUMBERING
|
||||
! STNUM= HIGH END OF AVAILABLE NUMBERS FOR RENUMBERING
|
||||
SBNUM = 1
|
||||
STNUM = N
|
||||
! NUMBER THE NODES OF DEGREE ZERO
|
||||
DO I=1,N
|
||||
IF (NDEG(I) > 0) CYCLE
|
||||
RENUM(I) = STNUM
|
||||
STNUM = STNUM - 1
|
||||
END DO
|
||||
! FIND AN UNNUMBERED NODE OF MIN DEGREE TO START ON
|
||||
do
|
||||
LOWDG = IDEG + 1
|
||||
NFLG = 1
|
||||
ISDIR = 1
|
||||
DO I=1,N
|
||||
IF (NDEG(I) >= LOWDG) CYCLE
|
||||
IF (RENUM(I) > 0) CYCLE
|
||||
LOWDG = NDEG(I)
|
||||
STNODE = I
|
||||
END DO
|
||||
! FIND PSEUDO-DIAMETER AND ASSOCIATED LEVEL STRUCTURES.
|
||||
! STNODE AND RVNODE ARE THE ENDS OF THE DIAM AND LVLS1 AND LVLS2
|
||||
! ARE THE RESPECTIVE LEVEL STRUCTURES.
|
||||
CALL FNDIAM(STNODE, RVNODE, NDSTK, NR, NDEG, LVL, LVLS1,LVLS2, CCSTOR, IDFLT)
|
||||
IF (.not.(ndeg(stnode) <= ndeg(rvnode))) then
|
||||
! NFLG INDICATES THE END TO BEGIN NUMBERING ON
|
||||
NFLG = -1
|
||||
STNODE = RVNODE
|
||||
endif
|
||||
CALL SETUP(LVL, LVLS1, LVLS2)
|
||||
! FIND ALL THE CONNECTED COMPONENTS (XCC COUNTS THEM)
|
||||
XCC = 0
|
||||
LROOT = 1
|
||||
LVLN = 1
|
||||
DO I=1,N
|
||||
IF (LVL(I) /= 0) CYCLE
|
||||
XCC = XCC + 1
|
||||
STPT(XCC) = LROOT
|
||||
CALL TREE(I, NDSTK, NR, LVL, CCSTOR, NDEG, LVLWTH, LVLBOT,LVLN, MAXLW, N)
|
||||
SIZEG(XCC) = LVLBOT + LVLWTH - LROOT
|
||||
LROOT = LVLBOT + LVLWTH
|
||||
LVLN = LROOT
|
||||
END DO
|
||||
if (sort2() /= 0) then
|
||||
CALL PIKLVL(LVLS1, LVLS2, CCSTOR, IDFLT, ISDIR)
|
||||
endif
|
||||
! ON RETURN FROM PIKLVL, ISDIR INDICATES THE DIRECTION THE LARGEST
|
||||
! COMPONENT FELL. ISDIR IS MODIFIED NOW TO INDICATE THE NUMBERING
|
||||
! DIRECTION. NUM IS SET TO THE PROPER VALUE FOR THIS DIRECTION.
|
||||
ISDIR = ISDIR*NFLG
|
||||
NUM = SBNUM
|
||||
IF (ISDIR < 0) NUM = STNUM
|
||||
CALL NUMBER(STNODE, NUM, NDSTK, LVLS2, NDEG, RENUM, LVLS1,LVL,&
|
||||
& NR, NFLG, IBW2, IPF2, CCSTOR, ISDIR)
|
||||
! UPDATE STNUM OR SBNUM AFTER NUMBERING
|
||||
IF (ISDIR < 0) STNUM = NUM
|
||||
IF (ISDIR > 0) SBNUM = NUM
|
||||
IF (.not.(sbnum <= stnum)) exit
|
||||
end do
|
||||
IF (IBW2 > IBW1) then
|
||||
! IF ORIGINAL NUMBERING IS BETTER THAN NEW ONE, SET UP TO RETURN IT
|
||||
DO I=1,N
|
||||
RENUM(I) = IOLD(I)
|
||||
END DO
|
||||
IBW2 = IBW1
|
||||
IPF2 = IPF1
|
||||
!
|
||||
endif
|
||||
DEALLOCATE(SIZEG,STPT,NHIGH,NLOW,AUX,NACUM)
|
||||
idpthe = idpth
|
||||
RETURN
|
||||
end subroutine psb_lgps_reduce
|
||||
!
|
||||
SUBROUTINE DGREE(NDSTK, NR, NDEG, IOLD, IBW1, IPF1)
|
||||
! DGREE COMPUTES THE DEGREE OF EACH NODE IN NDSTK AND STORES
|
||||
! IT IN THE ARRAY NDEG. THE BANDWIDTH AND PROFILE FOR THE ORIGINAL
|
||||
! OR INPUT RENUMBERING OF THE GRAPH IS COMPUTED ALSO.
|
||||
! USE INTEGER*2 NDSTK WITH AN IBM 360 OR 370.
|
||||
implicit none
|
||||
INTEGER(psb_lpk_) :: NR, IBW1, IPF1, NDSTK(NR,IDEG), NDEG(N), IOLD(N)
|
||||
! COMMON /GRA/ N, IDPTH, IDEG
|
||||
integer(psb_lpk_) :: i, itst, j, idif, irw
|
||||
|
||||
IBW1 = 0
|
||||
IPF1 = 0
|
||||
DO I=1,N
|
||||
NDEG(I) = 0
|
||||
IRW = 0
|
||||
DO J=1,IDEG
|
||||
ITST = NDSTK(I,J)
|
||||
IF(ITST <= 0) EXIT
|
||||
NDEG(I) = NDEG(I) + 1
|
||||
IDIF = IOLD(I) - IOLD(ITST)
|
||||
IF (IRW < IDIF) IRW = IDIF
|
||||
END DO
|
||||
IPF1 = IPF1 + IRW
|
||||
IF (IRW > IBW1) IBW1 = IRW
|
||||
END DO
|
||||
RETURN
|
||||
END SUBROUTINE DGREE
|
||||
!
|
||||
SUBROUTINE FNDIAM(SND1, SND2, NDSTK, NR, NDEG, LVL, LVLS1,LVLS2, IWK, IDFLT)
|
||||
! FNDIAM IS THE CONTROL PROCEDURE FOR FINDING THE PSEUDO-DIAMETER OF
|
||||
! NDSTK AS WELL AS THE LEVEL STRUCTURE FROM EACH END
|
||||
! SND1- ON INPUT THIS IS THE NODE NUMBER OF THE FIRST
|
||||
! ATTEMPT AT FINDING A DIAMETER. ON OUTPUT IT
|
||||
! CONTAINS THE ACTUAL NUMBER USED.
|
||||
! SND2- ON OUTPUT CONTAINS OTHER END OF DIAMETER
|
||||
! LVLS1- ARRAY CONTAINING LEVEL STRUCTURE WITH SND1 AS ROOT
|
||||
! LVLS2- ARRAY CONTAINING LEVEL STRUCTURE WITH SND2 AS ROOT
|
||||
! IDFLT- FLAG USED IN PICKING FINAL LEVEL STRUCTURE, SET
|
||||
! =1 IF WIDTH OF LVLS1 <= WIDTH OF LVLS2, OTHERWISE =2
|
||||
! LVL,IWK- WORKING STORAGE
|
||||
! USE INTEGER*2 NDSTK WITH AN IBM 360 OR 370.
|
||||
implicit none
|
||||
INTEGER(psb_lpk_) :: FLAG, SND, SND1, SND2, NR, idflt
|
||||
! COMMON /GRA/ N, IDPTH, IDEG
|
||||
! IT IS ASSUMED THAT THE LAST LEVEL HAS AT MOST 100 NODES.
|
||||
! COMMON /CC/ NDLST(100)
|
||||
integer(psb_lpk_),POINTER :: NDLST(:)
|
||||
integer(psb_lpk_) :: NDSTK(NR,IDEG), NDEG(1), LVL(N), LVLS1(N), LVLS2(N),IWK(N)
|
||||
integer(psb_lpk_) :: i, j, mtw2, ndxn, ndxl, inow, lvlbot,lvln,lvlwth
|
||||
integer(psb_lpk_) :: k,mtw1, maxlw
|
||||
!
|
||||
NDLST => AUX
|
||||
!
|
||||
FLAG = 0
|
||||
MTW2 = N
|
||||
SND = SND1
|
||||
! ZERO LVL TO INDICATE ALL NODES ARE AVAILABLE TO TREE
|
||||
10 DO 20 I=1,N
|
||||
LVL(I) = 0
|
||||
20 END DO
|
||||
LVLN = 1
|
||||
! DROP A TREE FROM SND
|
||||
CALL TREE(SND, NDSTK, NR, LVL, IWK, NDEG, LVLWTH, LVLBOT,LVLN, MAXLW, MTW2)
|
||||
IF (FLAG >= 1) GO TO 50
|
||||
FLAG = 1
|
||||
30 IDPTH = LVLN - 1
|
||||
MTW1 = MAXLW
|
||||
! COPY LEVEL STRUCTURE INTO LVLS1
|
||||
DO 40 I=1,N
|
||||
LVLS1(I) = LVL(I)
|
||||
40 END DO
|
||||
NDXN = 1
|
||||
NDXL = 0
|
||||
MTW2 = N
|
||||
! SORT LAST LEVEL BY DEGREE AND STORE IN NDLST
|
||||
CALL SORTDG(NDLST, IWK(LVLBOT), NDXL, LVLWTH, NDEG)
|
||||
SND = NDLST(1)
|
||||
GO TO 10
|
||||
50 IF (IDPTH >= LVLN-1) GO TO 60
|
||||
! START AGAIN WITH NEW STARTING NODE
|
||||
SND1 = SND
|
||||
GO TO 30
|
||||
60 IF (MAXLW >= MTW2) GO TO 80
|
||||
MTW2 = MAXLW
|
||||
SND2 = SND
|
||||
! STORE NARROWEST REVERSE LEVEL STRUCTURE IN LVLS2
|
||||
DO 70 I=1,N
|
||||
LVLS2(I) = LVL(I)
|
||||
70 END DO
|
||||
80 IF (NDXN == NDXL) GO TO 90
|
||||
! TRY NEXT NODE IN NDLST
|
||||
NDXN = NDXN + 1
|
||||
SND = NDLST(NDXN)
|
||||
GO TO 10
|
||||
90 IDFLT = 1
|
||||
IF (MTW2 <= MTW1) IDFLT = 2
|
||||
NULLIFY(NDLST)
|
||||
RETURN
|
||||
END SUBROUTINE FNDIAM
|
||||
!
|
||||
SUBROUTINE TREE(IROOT, NDSTK, NR, LVL, IWK, NDEG, LVLWTH, LVLBOT, LVLN, MAXLW, IBORT)
|
||||
! TREE DROPS A TREE IN NDSTK FROM IROOT
|
||||
! LVL- ARRAY INDICATING AVAILABLE NODES IN NDSTK WITH ZERO
|
||||
! ENTRIES. TREE ENTERS LEVEL NUMBERS ASSIGNED
|
||||
! DURING EXECUTION OF THIS PROCEDURE
|
||||
! IWK- ON OUTPUT CONTAINS NODE NUMBERS USED IN TREE
|
||||
! ARRANGED BY LEVELS (IWK(LVLN) CONTAINS IROOT
|
||||
! AND IWK(LVLBOT+LVLWTH-1) CONTAINS LAST NODE ENTERED)
|
||||
! LVLWTH- ON OUTPUT CONTAINS WIDTH OF LAST LEVEL
|
||||
! LVLBOT- ON OUTPUT CONTAINS INDEX INTO IWK OF FIRST
|
||||
! NODE IN LAST LEVEL
|
||||
! MAXLW- ON OUTPUT CONTAINS THE MAXIMUM LEVEL WIDTH
|
||||
! LVLN- ON INPUT THE FIRST AVAILABLE LOCATION IN IWK
|
||||
! USUALLY ONE BUT IF IWK IS USED TO STORE PREVIOUS
|
||||
! CONNECTED COMPONENTS, LVLN IS NEXT AVAILABLE LOCATION.
|
||||
! ON OUTPUT THE TOTAL NUMBER OF LEVELS + 1
|
||||
! IBORT- INPUT PARAM WHICH TRIGGERS EARLY RETURN IF
|
||||
! MAXLW BECOMES >= IBORT
|
||||
! USE INTEGER*2 NDSTK WITH AN IBM 360 OR 370.
|
||||
implicit none
|
||||
integer(psb_lpk_) :: IROOT, NR, NDSTK(NR,*), LVL(*), IWK(*), NDEG(*)
|
||||
integer(psb_lpk_) :: LVLWTH, LVLBOT, LVLN, MAXLW, IBORT
|
||||
integer(psb_lpk_) :: itest, iwknow, itop, lvltop,j , inow, ndrow
|
||||
MAXLW = 0
|
||||
ITOP = LVLN
|
||||
INOW = LVLN
|
||||
LVLBOT = LVLN
|
||||
LVLTOP = LVLN + 1
|
||||
LVLN = 1
|
||||
LVL(IROOT) = 1
|
||||
IWK(ITOP) = IROOT
|
||||
10 LVLN = LVLN + 1
|
||||
20 IWKNOW = IWK(INOW)
|
||||
NDROW = NDEG(IWKNOW)
|
||||
DO 30 J=1,NDROW
|
||||
ITEST = NDSTK(IWKNOW,J)
|
||||
IF (LVL(ITEST) /= 0) CYCLE
|
||||
LVL(ITEST) = LVLN
|
||||
ITOP = ITOP + 1
|
||||
IWK(ITOP) = ITEST
|
||||
30 END DO
|
||||
INOW = INOW + 1
|
||||
IF (INOW < LVLTOP) GO TO 20
|
||||
LVLWTH = LVLTOP - LVLBOT
|
||||
IF (MAXLW < LVLWTH) MAXLW = LVLWTH
|
||||
IF (MAXLW >= IBORT) RETURN
|
||||
IF (ITOP < LVLTOP) RETURN
|
||||
LVLBOT = INOW
|
||||
LVLTOP = ITOP + 1
|
||||
GO TO 10
|
||||
END SUBROUTINE TREE
|
||||
!
|
||||
SUBROUTINE SORTDG(STK1, STK2, X1, X2, NDEG)
|
||||
! SORTDG SORTS STK2 BY DEGREE OF THE NODE AND ADDS IT TO THE END
|
||||
! OF STK1 IN ORDER OF LOWEST TO HIGHEST DEGREE. X1 AND X2 ARE THE
|
||||
! NUMBER OF NODES IN STK1 AND STK2 RESPECTIVELY.
|
||||
implicit none
|
||||
INTEGER(psb_lpk_) :: X1, X2, STK1, STK2, TEMP,NDEG
|
||||
! COMMON /GRA/ N, IDPTH, IDEG
|
||||
DIMENSION NDEG(N), STK1(X1+X2), STK2(X2)
|
||||
integer(psb_lpk_) :: ind,itest,i,j,istk2,jstk2
|
||||
IND = X2
|
||||
10 ITEST = 0
|
||||
IND = IND - 1
|
||||
IF (IND < 1) GO TO 30
|
||||
DO 20 I=1,IND
|
||||
J = I + 1
|
||||
ISTK2 = STK2(I)
|
||||
JSTK2 = STK2(J)
|
||||
IF (NDEG(ISTK2) <= NDEG(JSTK2)) CYCLE
|
||||
ITEST = 1
|
||||
TEMP = STK2(I)
|
||||
STK2(I) = STK2(J)
|
||||
STK2(J) = TEMP
|
||||
20 END DO
|
||||
IF (ITEST == 1) GO TO 10
|
||||
30 DO 40 I=1,X2
|
||||
X1 = X1 + 1
|
||||
STK1(X1) = STK2(I)
|
||||
40 END DO
|
||||
RETURN
|
||||
END SUBROUTINE SORTDG
|
||||
!
|
||||
SUBROUTINE SETUP(LVL, LVLS1, LVLS2)
|
||||
! SETUP COMPUTES THE REVERSE LEVELING INFO FROM LVLS2 AND STORES
|
||||
! IT INTO LVLS2. NACUM(I) IS INITIALIZED TO NODES/ITH LEVEL FOR NODES
|
||||
! ON THE PSEUDO-DIAMETER OF THE GRAPH. LVL IS INITIALIZED TO NON-
|
||||
! ZERO FOR NODES ON THE PSEUDO-DIAM AND NODES IN A DIFFERENT
|
||||
! COMPONENT OF THE GRAPH.
|
||||
! COMMON /GRA/ N, IDPTH, IDEG
|
||||
! IT IS ASSUMED THAT THERE ARE AT MOST 100 LEVELS.
|
||||
! COMMON /LVLW/ NHIGH(100), NLOW(100), NACUM(100)
|
||||
use psb_base_mod
|
||||
implicit none
|
||||
integer(psb_lpk_) :: LVL(N), LVLS1(N), LVLS2(N)
|
||||
integer(psb_lpk_) :: SZ,i,itemp
|
||||
!-----------------------------------------------------
|
||||
SZ=SIZE(NACUM)
|
||||
IF(SZ < IDPTH) THEN
|
||||
write(psb_out_unit,*) 'GPS_SETUP: on fly reallocation of NACUM'
|
||||
CALL REALLOC(NACUM,SZ,IDPTH)
|
||||
END IF
|
||||
!-----------------------------------------------------
|
||||
DO 10 I=1,IDPTH
|
||||
NACUM(I) = 0
|
||||
10 END DO
|
||||
DO 30 I=1,N
|
||||
LVL(I) = 1
|
||||
LVLS2(I) = IDPTH + 1 - LVLS2(I)
|
||||
ITEMP = LVLS2(I)
|
||||
IF (ITEMP > IDPTH) CYCLE
|
||||
IF (ITEMP /= LVLS1(I)) GO TO 20
|
||||
NACUM(ITEMP) = NACUM(ITEMP) + 1
|
||||
CYCLE
|
||||
20 LVL(I) = 0
|
||||
30 END DO
|
||||
RETURN
|
||||
END SUBROUTINE SETUP
|
||||
!
|
||||
FUNCTION SORT2() result(val)
|
||||
implicit none
|
||||
INTEGER(psb_lpk_) :: val
|
||||
! SORT2 SORTS SIZEG AND STPT INTO DESCENDING ORDER ACCORDING TO
|
||||
! VALUES OF SIZEG. XCC=NUMBER OF ENTRIES IN EACH ARRAY
|
||||
INTEGER(psb_lpk_) :: TEMP,ind,itest,i,j
|
||||
! IT IS ASSUMED THAT THE GRAPH HAS AT MOST 50 CONNECTED COMPONENTS.
|
||||
!COMMON /CC/ XCC, SIZEG(50), STPT(50)
|
||||
|
||||
VAL = 0
|
||||
IF (XCC == 0) RETURN
|
||||
VAL = 1
|
||||
IND = XCC
|
||||
10 ITEST = 0
|
||||
IND = IND - 1
|
||||
IF (IND < 1) RETURN
|
||||
DO 20 I=1,IND
|
||||
J = I + 1
|
||||
IF (SIZEG(I) >= SIZEG(J)) CYCLE
|
||||
ITEST = 1
|
||||
TEMP = SIZEG(I)
|
||||
SIZEG(I) = SIZEG(J)
|
||||
SIZEG(J) = TEMP
|
||||
TEMP = STPT(I)
|
||||
STPT(I) = STPT(J)
|
||||
STPT(J) = TEMP
|
||||
20 END DO
|
||||
IF (ITEST == 1) GO TO 10
|
||||
RETURN
|
||||
END FUNCTION SORT2
|
||||
!
|
||||
SUBROUTINE PIKLVL(LVLS1, LVLS2, CCSTOR, IDFLT, ISDIR)
|
||||
use psb_base_mod
|
||||
implicit none
|
||||
! PIKLVL CHOOSES THE LEVEL STRUCTURE USED IN NUMBERING GRAPH
|
||||
! LVLS1- ON INPUT CONTAINS FORWARD LEVELING INFO
|
||||
! LVLS2- ON INPUT CONTAINS REVERSE LEVELING INFO
|
||||
! ON OUTPUT THE FINAL LEVEL STRUCTURE CHOSEN
|
||||
! CCSTOR- ON INPUT CONTAINS CONNECTED COMPONENT INFO
|
||||
! IDFLT- ON INPUT =1 IF WDTH LVLS1 <= WDTH LVLS2, =2 OTHERWISE
|
||||
! NHIGH KEEPS TRACK OF LEVEL WIDTHS FOR HIGH NUMBERING
|
||||
! NLOW- KEEPS TRACK OF LEVEL WIDTHS FOR LOW NUMBERING
|
||||
! NACUM- KEEPS TRACK OF LEVEL WIDTHS FOR CHOSEN LEVEL STRUCTURE
|
||||
! XCC- NUMBER OF CONNECTED COMPONENTS
|
||||
! SIZEG(I)- SIZE OF ITH CONNECTED COMPONENT
|
||||
! STPT(I)- INDEX INTO CCSTORE OF 1ST NODE IN ITH CON COMPT
|
||||
! ISDIR- FLAG WHICH INDICATES WHICH WAY THE LARGEST CONNECTED
|
||||
! COMPONENT FELL. =+1 IF LOW AND -1 IF HIGH
|
||||
! COMMON /GRA/ N, IDPTH, IDEG
|
||||
! IT IS ASSUMED THAT THE GRAPH HAS AT MOST 50 COMPONENTS AND
|
||||
! THAT THERE ARE AT MOST 100 LEVELS.
|
||||
! COMMON /LVLW/ NHIGH(100), NLOW(100), NACUM(100)
|
||||
! COMMON /CC/ XCC, SIZEG(50), STPT(50)
|
||||
INTEGER(psb_lpk_) :: LVLS1(N), LVLS2(N), CCSTOR(N)
|
||||
integer(psb_lpk_) :: SZ, ENDC,i,j,max1,max2,inode
|
||||
integer(psb_lpk_) :: lvlnh, it, k, lvlnl,idflt,isdir
|
||||
! FOR EACH CONNECTED COMPONENT DO
|
||||
DO 80 I=1,XCC
|
||||
J = STPT(I)
|
||||
ENDC= SIZEG(I) + J - 1
|
||||
! SET NHIGH AND NLOW EQUAL TO NACUM
|
||||
!-----------------------------------------------------
|
||||
SZ=SIZE(NHIGH)
|
||||
IF(SZ < IDPTH) THEN
|
||||
write(psb_out_unit,*) 'GPS_PIKLVL: on fly reallocation of NHIGH'
|
||||
CALL REALLOC(NHIGH,SZ,IDPTH)
|
||||
END IF
|
||||
SZ=SIZE(NLOW)
|
||||
IF(SZ < IDPTH) THEN
|
||||
write(psb_out_unit,*) 'GPS_PIKLVL: on fly reallocation of NLOW'
|
||||
CALL REALLOC(NLOW,SZ,IDPTH)
|
||||
END IF
|
||||
!-----------------------------------------------------
|
||||
DO 10 K=1,IDPTH
|
||||
NHIGH(K) = NACUM(K)
|
||||
NLOW(K) = NACUM(K)
|
||||
10 END DO
|
||||
! UPDATE NHIGH AND NLOW FOR EACH NODE IN CONNECTED COMPONENT
|
||||
DO 20 K=J,ENDC
|
||||
INODE = CCSTOR(K)
|
||||
LVLNH = LVLS1(INODE)
|
||||
NHIGH(LVLNH) = NHIGH(LVLNH) + 1
|
||||
LVLNL = LVLS2(INODE)
|
||||
NLOW(LVLNL) = NLOW(LVLNL) + 1
|
||||
20 END DO
|
||||
MAX1 = 0
|
||||
MAX2 = 0
|
||||
! SET MAX1=LARGEST NEW NUMBER IN NHIGH
|
||||
! SET MAX2=LARGEST NEW NUMBER IN NLOW
|
||||
DO 30 K=1,IDPTH
|
||||
IF (2*NACUM(K) == NLOW(K)+NHIGH(K)) CYCLE
|
||||
IF (NHIGH(K) > MAX1) MAX1 = NHIGH(K)
|
||||
IF (NLOW(K) > MAX2) MAX2 = NLOW(K)
|
||||
30 END DO
|
||||
! SET IT= NUMBER OF LEVEL STRUCTURE TO BE USED
|
||||
IT = 1
|
||||
IF (MAX1 > MAX2) IT = 2
|
||||
IF (MAX1 == MAX2) IT = IDFLT
|
||||
IF (IT == 2) GO TO 60
|
||||
IF (I == 1) ISDIR = -1
|
||||
! COPY LVLS1 INTO LVLS2 FOR EACH NODE IN CONNECTED COMPONENT
|
||||
DO 40 K=J,ENDC
|
||||
INODE = CCSTOR(K)
|
||||
LVLS2(INODE) = LVLS1(INODE)
|
||||
40 END DO
|
||||
! UPDATE NACUM TO BE THE SAME AS NHIGH
|
||||
DO 50 K=1,IDPTH
|
||||
NACUM(K) = NHIGH(K)
|
||||
50 END DO
|
||||
CYCLE
|
||||
! UPDATE NACUM TO BE THE SAME AS NLOW
|
||||
60 DO 70 K=1,IDPTH
|
||||
NACUM(K) = NLOW(K)
|
||||
70 END DO
|
||||
80 END DO
|
||||
RETURN
|
||||
END SUBROUTINE PIKLVL
|
||||
!
|
||||
SUBROUTINE NUMBER(SND, NUM, NDSTK, LVLS2, NDEG, RENUM, LVLST,LSTPT,&
|
||||
& NR, NFLG, IBW2, IPF2, IPFA, ISDIR)
|
||||
use psb_base_mod
|
||||
implicit none
|
||||
! NUMBER PRODUCES THE NUMBERING OF THE GRAPH FOR MIN BANDWIDTH
|
||||
! SND- ON INPUT THE NODE TO BEGIN NUMBERING ON
|
||||
! NUM- ON INPUT AND OUTPUT, THE NEXT AVAILABLE NUMBER
|
||||
! LVLS2- THE LEVEL STRUCTURE TO BE USED IN NUMBERING
|
||||
! RENUM- THE ARRAY USED TO STORE THE NEW NUMBERING
|
||||
! LVLST- ON OUTPUT CONTAINS LEVEL STRUCTURE
|
||||
! LSTPT(I)- ON OUTPUT, INDEX INTO LVLST TO FIRST NODE IN ITH LVL
|
||||
! LSTPT(I+1) - LSTPT(I) = NUMBER OF NODES IN ITH LVL
|
||||
! NFLG- =+1 IF SND IS FORWARD END OF PSEUDO-DIAM
|
||||
! =-1 IF SND IS REVERSE END OF PSEUDO-DIAM
|
||||
! IBW2- BANDWIDTH OF NEW NUMBERING COMPUTED BY NUMBER
|
||||
! IPF2- PROFILE OF NEW NUMBERING COMPUTED BY NUMBER
|
||||
! IPFA- WORKING STORAGE USED TO COMPUTE PROFILE AND BANDWIDTH
|
||||
! ISDIR- INDICATES STEP DIRECTION USED IN NUMBERING(+1 OR -1)
|
||||
! USE INTEGER*2 NDSTK WITH AN IBM 360 OR 370.
|
||||
INTEGER(psb_lpk_) :: SND, NUM, XA, XB, XC, XD, CX, ENDC, TEST, NR, ISDIR
|
||||
! COMMON /GRA/ N, IDPTH, IDEG
|
||||
! THE STORAGE IN COMMON BLOCKS CC AND LVLW IS NOW FREE AND CAN
|
||||
! BE USED FOR STACKS.
|
||||
!COMMON /LVLW/ STKA(100), STKB(100), STKC(100)
|
||||
!COMMON /CC/ STKD(100)
|
||||
INTEGER(psb_lpk_) :: IPFA(N), NDSTK(NR,IDEG), LVLS2(N),&
|
||||
& NDEG(N), RENUM(N+1), LVLST(N),LSTPT(N),ipf2,ibw2,nflg, nbw
|
||||
integer(psb_lpk_),POINTER :: STKA(:),STKB(:),STKC(:),STKD(:)
|
||||
integer(psb_lpk_) :: SZ1,SZ2,i,j,nstpt,lvln, lst, lnd, inx, max, ipro,&
|
||||
& lvlnl, k, it
|
||||
!
|
||||
STKA => NHIGH
|
||||
STKB => NLOW
|
||||
STKC => NACUM
|
||||
STKD => AUX
|
||||
!
|
||||
! SET UP LVLST AND LSTPT FROM LVLS2
|
||||
DO 10 I=1,N
|
||||
IPFA(I) = 0
|
||||
10 END DO
|
||||
NSTPT = 1
|
||||
DO 30 I=1,IDPTH
|
||||
LSTPT(I) = NSTPT
|
||||
DO 20 J=1,N
|
||||
IF (LVLS2(J) /= I) CYCLE
|
||||
LVLST(NSTPT) = J
|
||||
NSTPT = NSTPT + 1
|
||||
20 END DO
|
||||
30 END DO
|
||||
LSTPT(IDPTH+1) = NSTPT
|
||||
! STKA, STKB, STKC AND STKD ARE STACKS WITH POINTERS
|
||||
! XA,XB,XC, AND XD. CX IS A SPECIAL POINTER INTO STKC WHICH
|
||||
! INDICATES THE PARTICULAR NODE BEING PROCESSED.
|
||||
! LVLN KEEPS TRACK OF THE LEVEL WE ARE WORKING AT.
|
||||
! INITIALLY STKC CONTAINS ONLY THE INITIAL NODE, SND.
|
||||
LVLN = 0
|
||||
IF (NFLG < 0) LVLN = IDPTH + 1
|
||||
XC = 1
|
||||
STKC(XC) = SND
|
||||
40 CX = 1
|
||||
XD = 0
|
||||
LVLN = LVLN + NFLG
|
||||
LST = LSTPT(LVLN)
|
||||
LND = LSTPT(LVLN+1) - 1
|
||||
! BEGIN PROCESSING NODE STKC(CX)
|
||||
50 IPRO = STKC(CX)
|
||||
RENUM(IPRO) = NUM
|
||||
NUM = NUM + ISDIR
|
||||
ENDC = NDEG(IPRO)
|
||||
XA = 0
|
||||
XB = 0
|
||||
! CHECK ALL ADJACENT NODES
|
||||
DO 80 I=1,ENDC
|
||||
TEST = NDSTK(IPRO,I)
|
||||
INX = RENUM(TEST)
|
||||
! ONLY NODES NOT NUMBERED OR ALREADY ON A STACK ARE ADDED
|
||||
IF (INX == 0) GO TO 60
|
||||
IF (INX < 0) CYCLE
|
||||
! DO PRELIMINARY BANDWIDTH AND PROFILE CALCULATIONS
|
||||
NBW = (RENUM(IPRO)-INX)*ISDIR
|
||||
IF (ISDIR > 0) INX = RENUM(IPRO)
|
||||
IF (IPFA(INX) < NBW) IPFA(INX) = NBW
|
||||
CYCLE
|
||||
60 RENUM(TEST) = -1
|
||||
! PUT NODES ON SAME LEVEL ON STKA, ALL OTHERS ON STKB
|
||||
IF (LVLS2(TEST) == LVLS2(IPRO)) GO TO 70
|
||||
XB = XB + 1
|
||||
STKB(XB) = TEST
|
||||
CYCLE
|
||||
70 XA = XA + 1
|
||||
STKA(XA) = TEST
|
||||
80 END DO
|
||||
! SORT STKA AND STKB INTO INCREASING DEGREE AND ADD STKA TO STKC
|
||||
! AND STKB TO STKD
|
||||
IF (XA == 0) GO TO 100
|
||||
IF (XA == 1) GO TO 90
|
||||
!-----------------------------------------------------------------
|
||||
SZ1=SIZE(STKC)
|
||||
SZ2=XC+XA
|
||||
IF(SZ1 < SZ2) THEN
|
||||
write(psb_out_unit,*) 'GPS_NUMBER - Check #1: on fly reallocation of STKC'
|
||||
CALL REALLOC(NACUM,SZ1,SZ2)
|
||||
STKC => NACUM
|
||||
END IF
|
||||
!-----------------------------------------------------------------
|
||||
CALL SORTDG(STKC, STKA, XC, XA, NDEG)
|
||||
GO TO 100
|
||||
90 XC = XC + 1
|
||||
!-----------------------------------------------------------------
|
||||
SZ1=SIZE(STKC)
|
||||
SZ2=XC
|
||||
IF(SZ1 < SZ2) THEN
|
||||
write(psb_out_unit,*) 'GPS_NUMBER - Check #2: on fly reallocation of STKC'
|
||||
SZ2=SZ2+INIT
|
||||
CALL REALLOC(NACUM,SZ1,SZ2)
|
||||
STKC => NACUM
|
||||
END IF
|
||||
!-----------------------------------------------------------------
|
||||
STKC(XC) = STKA(XA)
|
||||
100 IF (XB == 0) GO TO 120
|
||||
IF (XB == 1) GO TO 110
|
||||
!-----------------------------------------------------------------
|
||||
SZ1=SIZE(STKD)
|
||||
SZ2=XD+XB
|
||||
IF(SZ1 < SZ2) THEN
|
||||
write(psb_out_unit,*) 'GPS_NUMBER - Check #3: on fly reallocation of STKD'
|
||||
CALL REALLOC(AUX,SZ1,SZ2)
|
||||
STKD => AUX
|
||||
END IF
|
||||
!-----------------------------------------------------------------
|
||||
CALL SORTDG(STKD, STKB, XD, XB, NDEG)
|
||||
GO TO 120
|
||||
110 XD = XD + 1
|
||||
!-----------------------------------------------------------------
|
||||
SZ1=SIZE(STKD)
|
||||
SZ2=XD
|
||||
IF(SZ1 < SZ2) THEN
|
||||
write(psb_out_unit,*) 'GPS_NUMBER - Check #4: on fly reallocation of STKD'
|
||||
SZ2=SZ2+INIT
|
||||
CALL REALLOC(AUX,SZ1,SZ2)
|
||||
STKD => AUX
|
||||
END IF
|
||||
!-----------------------------------------------------------------
|
||||
STKD(XD) = STKB(XB)
|
||||
! BE SURE TO PROCESS ALL NODES IN STKC
|
||||
120 CX = CX + 1
|
||||
IF (XC >= CX) GO TO 50
|
||||
! WHEN STKC IS EXHAUSTED LOOK FOR MIN DEGREE NODE IN SAME LEVEL
|
||||
! WHICH HAS NOT BEEN PROCESSED
|
||||
MAX = IDEG + 1
|
||||
SND = N + 1
|
||||
DO 130 I=LST,LND
|
||||
TEST = LVLST(I)
|
||||
IF (RENUM(TEST) /= 0) CYCLE
|
||||
IF (NDEG(TEST) >= MAX) CYCLE
|
||||
RENUM(SND) = 0
|
||||
RENUM(TEST) = -1
|
||||
MAX = NDEG(TEST)
|
||||
SND = TEST
|
||||
130 END DO
|
||||
IF (SND == N+1) GO TO 140
|
||||
XC = XC + 1
|
||||
!-----------------------------------------------------------------
|
||||
SZ1=SIZE(STKC)
|
||||
SZ2=XC
|
||||
IF(SZ1 < SZ2) THEN
|
||||
write(psb_out_unit,*) 'GPS_NUMBER - Check #5: on fly reallocation of STKC'
|
||||
SZ2=SZ2+INIT
|
||||
CALL REALLOC(NACUM,SZ1,SZ2)
|
||||
STKC => NACUM
|
||||
END IF
|
||||
!-----------------------------------------------------------------
|
||||
STKC(XC) = SND
|
||||
GO TO 50
|
||||
! IF STKD IS EMPTY WE ARE DONE, OTHERWISE COPY STKD ONTO STKC
|
||||
! AND BEGIN PROCESSING NEW STKC
|
||||
140 IF (XD == 0) GO TO 160
|
||||
!-----------------------------------------------------------------
|
||||
SZ1=SIZE(STKC)
|
||||
SZ2=XD
|
||||
IF(SZ1 < SZ2) THEN
|
||||
write(psb_out_unit,*) 'GPS_NUMBER - Check #6: on fly reallocation of STKC'
|
||||
SZ2=SZ2+INIT
|
||||
CALL REALLOC(NACUM,SZ1,SZ2)
|
||||
STKC => NACUM
|
||||
END IF
|
||||
!-----------------------------------------------------------------
|
||||
DO 150 I=1,XD
|
||||
STKC(I) = STKD(I)
|
||||
150 END DO
|
||||
XC = XD
|
||||
GO TO 40
|
||||
! DO FINAL BANDWIDTH AND PROFILE CALCULATIONS
|
||||
160 DO 170 I=1,N
|
||||
IF (IPFA(I) > IBW2) IBW2 = IPFA(I)
|
||||
IPF2 = IPF2 + IPFA(I)
|
||||
170 END DO
|
||||
!
|
||||
RETURN
|
||||
END SUBROUTINE NUMBER
|
||||
!
|
||||
! ---------------------------------------------------------
|
||||
SUBROUTINE REALLOC(VET,SZ1,SZ2)
|
||||
use psb_base_mod
|
||||
! PERFORM ON FLY REALLOCATION OF POINTER VET INCREASING
|
||||
! ITS SIZE FROM SZ1 TO SZ2
|
||||
IMPLICIT NONE
|
||||
integer(psb_lpk_),allocatable :: VET(:)
|
||||
integer(psb_lpk_) :: SZ1,SZ2
|
||||
integer(psb_ipk_) :: info
|
||||
call psb_realloc(sz2,vet,info)
|
||||
IF(INFO /= psb_success_) THEN
|
||||
write(psb_out_unit,*) 'Error! Memory allocation failure in REALLOC'
|
||||
STOP
|
||||
END IF
|
||||
RETURN
|
||||
END SUBROUTINE REALLOC
|
||||
!
|
||||
end module psb_lgps_mod
|
||||
|
||||
+4
-125
@@ -32,129 +32,8 @@
|
||||
module psb_renum_mod
|
||||
use psb_base_mod
|
||||
|
||||
integer(psb_ipk_), parameter :: psb_mat_renum_identity_ = 0
|
||||
integer(psb_ipk_), parameter :: psb_mat_renum_gps_ = 456
|
||||
integer(psb_ipk_), parameter :: psb_mat_renum_amd_ = psb_mat_renum_gps_ + 1
|
||||
|
||||
|
||||
interface psb_mat_renum
|
||||
subroutine psb_d_mat_renums(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_dspmat_type
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_dspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_d_mat_renums
|
||||
subroutine psb_d_mat_renum(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_dspmat_type
|
||||
integer(psb_ipk_), intent(in) :: alg
|
||||
type(psb_dspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_d_mat_renum
|
||||
subroutine psb_s_mat_renums(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_sspmat_type
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_sspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_s_mat_renums
|
||||
subroutine psb_s_mat_renum(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_sspmat_type
|
||||
integer(psb_ipk_), intent(in) :: alg
|
||||
type(psb_sspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_s_mat_renum
|
||||
subroutine psb_z_mat_renums(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_zspmat_type
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_zspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_z_mat_renums
|
||||
subroutine psb_z_mat_renum(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_zspmat_type
|
||||
integer(psb_ipk_), intent(in) :: alg
|
||||
type(psb_zspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_z_mat_renum
|
||||
subroutine psb_c_mat_renums(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_cspmat_type
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_cspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_c_mat_renums
|
||||
subroutine psb_c_mat_renum(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_cspmat_type
|
||||
integer(psb_ipk_), intent(in) :: alg
|
||||
type(psb_cspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_c_mat_renum
|
||||
end interface psb_mat_renum
|
||||
|
||||
|
||||
interface psb_cmp_bwpf
|
||||
subroutine psb_s_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_sspmat_type
|
||||
type(psb_sspmat_type), intent(in) :: mat
|
||||
integer(psb_ipk_), intent(out) :: bwl, bwu
|
||||
integer(psb_ipk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_s_cmp_bwpf
|
||||
subroutine psb_d_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_dspmat_type
|
||||
type(psb_dspmat_type), intent(in) :: mat
|
||||
integer(psb_ipk_), intent(out) :: bwl, bwu
|
||||
integer(psb_ipk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_d_cmp_bwpf
|
||||
subroutine psb_c_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_cspmat_type
|
||||
type(psb_cspmat_type), intent(in) :: mat
|
||||
integer(psb_ipk_), intent(out) :: bwl, bwu
|
||||
integer(psb_ipk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_c_cmp_bwpf
|
||||
subroutine psb_z_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_zspmat_type
|
||||
type(psb_zspmat_type), intent(in) :: mat
|
||||
integer(psb_ipk_), intent(out) :: bwl, bwu
|
||||
integer(psb_ipk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_z_cmp_bwpf
|
||||
subroutine psb_ls_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_lpk_, psb_lsspmat_type
|
||||
type(psb_lsspmat_type), intent(in) :: mat
|
||||
integer(psb_lpk_), intent(out) :: bwl, bwu
|
||||
integer(psb_lpk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_ls_cmp_bwpf
|
||||
subroutine psb_ld_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_lpk_, psb_ldspmat_type
|
||||
type(psb_ldspmat_type), intent(in) :: mat
|
||||
integer(psb_lpk_), intent(out) :: bwl, bwu
|
||||
integer(psb_lpk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_ld_cmp_bwpf
|
||||
subroutine psb_lc_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_lpk_, psb_lcspmat_type
|
||||
type(psb_lcspmat_type), intent(in) :: mat
|
||||
integer(psb_lpk_), intent(out) :: bwl, bwu
|
||||
integer(psb_lpk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_lc_cmp_bwpf
|
||||
subroutine psb_lz_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_lpk_, psb_lzspmat_type
|
||||
type(psb_lzspmat_type), intent(in) :: mat
|
||||
integer(psb_lpk_), intent(out) :: bwl, bwu
|
||||
integer(psb_lpk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_lz_cmp_bwpf
|
||||
end interface psb_cmp_bwpf
|
||||
|
||||
|
||||
use psb_s_renum_mod
|
||||
use psb_c_renum_mod
|
||||
use psb_d_renum_mod
|
||||
use psb_z_renum_mod
|
||||
end module psb_renum_mod
|
||||
|
||||
+272
-55
@@ -29,56 +29,11 @@
|
||||
! POSSIBILITY OF SUCH DAMAGE.
|
||||
!
|
||||
!
|
||||
subroutine psb_s_mat_renums(alg,mat,info,perm)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_s_mat_renums
|
||||
implicit none
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_sspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
|
||||
integer(psb_ipk_) :: err_act, nr, nc, ialg
|
||||
character(len=20) :: name
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
select case (psb_toupper(alg))
|
||||
case ('GPS')
|
||||
ialg = psb_mat_renum_gps_
|
||||
case ('AMD')
|
||||
ialg = psb_mat_renum_amd_
|
||||
case ('NONE', 'ID')
|
||||
ialg = psb_mat_renum_identity_
|
||||
case default
|
||||
write(0,*) 'Unknown algorithm "',psb_toupper(alg),'"'
|
||||
ialg = -1
|
||||
end select
|
||||
|
||||
call psb_mat_renum(ialg,mat,info,perm)
|
||||
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_from_subroutine_non_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
end subroutine psb_s_mat_renums
|
||||
|
||||
subroutine psb_s_mat_renum(alg,mat,info,perm)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_s_mat_renum
|
||||
implicit none
|
||||
integer(psb_ipk_), intent(in) :: alg
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_sspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
@@ -90,8 +45,6 @@ subroutine psb_s_mat_renum(alg,mat,info,perm)
|
||||
name = 'mat_renum'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
|
||||
nr = mat%get_nrows()
|
||||
nc = mat%get_ncols()
|
||||
if (nr /= nc) then
|
||||
@@ -101,16 +54,17 @@ subroutine psb_s_mat_renum(alg,mat,info,perm)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
select case (alg)
|
||||
case(psb_mat_renum_gps_)
|
||||
info = psb_success_
|
||||
select case (psb_toupper(alg))
|
||||
case ('GPS')
|
||||
|
||||
call psb_mat_renum_gps(mat,info,perm)
|
||||
|
||||
case(psb_mat_renum_amd_)
|
||||
case('AMD')
|
||||
|
||||
call psb_mat_renum_amd(mat,info,perm)
|
||||
|
||||
case(psb_mat_renum_identity_)
|
||||
case ('NONE', 'ID')
|
||||
nr = mat%get_nrows()
|
||||
allocate(perm(nr),stat=info)
|
||||
if (info == 0) then
|
||||
@@ -123,8 +77,9 @@ subroutine psb_s_mat_renum(alg,mat,info,perm)
|
||||
goto 9999
|
||||
endif
|
||||
case default
|
||||
write(0,*) 'Unknown algorithm "',psb_toupper(alg),'"'
|
||||
info = psb_err_input_value_invalid_i_
|
||||
ierr(1) = 1; ierr(2) = alg;
|
||||
ierr(1) = 1;
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end select
|
||||
@@ -162,7 +117,7 @@ contains
|
||||
integer(psb_ipk_) :: i, j, k, ideg, nr, ibw, ipf, idpth
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum'
|
||||
name = 'mat_renum_gps'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
@@ -332,11 +287,273 @@ contains
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
end subroutine psb_mat_renum_amd
|
||||
|
||||
end subroutine psb_s_mat_renum
|
||||
|
||||
subroutine psb_ls_mat_renum(alg,mat,info,perm)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_ls_mat_renum
|
||||
implicit none
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_lsspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: perm(:)
|
||||
|
||||
integer(psb_lpk_) :: nr, nc, i
|
||||
integer(psb_ipk_) :: err_act, ierr(5)
|
||||
character(len=20) :: name
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
nr = mat%get_nrows()
|
||||
nc = mat%get_ncols()
|
||||
if (nr /= nc) then
|
||||
info = psb_err_rectangular_mat_unsupported_
|
||||
ierr(1) = nr; ierr(2) = nc;
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
info = psb_success_
|
||||
select case (psb_toupper(alg))
|
||||
case ('GPS')
|
||||
|
||||
call psb_lmat_renum_gps(mat,info,perm)
|
||||
|
||||
case('AMD')
|
||||
|
||||
call psb_lmat_renum_amd(mat,info,perm)
|
||||
|
||||
case ('NONE', 'ID')
|
||||
nr = mat%get_nrows()
|
||||
allocate(perm(nr),stat=info)
|
||||
if (info == 0) then
|
||||
do i=1,nr
|
||||
perm(i) = i
|
||||
end do
|
||||
else
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
case default
|
||||
write(0,*) 'Unknown algorithm "',psb_toupper(alg),'"'
|
||||
info = psb_err_input_value_invalid_i_
|
||||
ierr(1) = 1;
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end select
|
||||
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_from_subroutine_non_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
contains
|
||||
|
||||
subroutine psb_lmat_renum_gps(a,info,operm)
|
||||
use psb_base_mod
|
||||
use psb_lgps_mod
|
||||
implicit none
|
||||
type(psb_lsspmat_type), intent(inout) :: a
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: operm(:)
|
||||
|
||||
!
|
||||
class(psb_ls_base_sparse_mat), allocatable :: aa
|
||||
type(psb_ls_csr_sparse_mat) :: acsr
|
||||
type(psb_ls_coo_sparse_mat) :: acoo
|
||||
|
||||
integer(psb_ipk_) :: err_act
|
||||
character(len=20) :: name
|
||||
integer(psb_lpk_), allocatable :: ndstk(:,:), iold(:), ndeg(:), perm(:)
|
||||
integer(psb_lpk_) :: i, j, k, ideg, nr, ibw, ipf, idpth
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum_gps'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
|
||||
call a%mold(aa)
|
||||
call a%mv_to(aa)
|
||||
call aa%mv_to_fmt(acsr,info)
|
||||
! Insert call to gps_reduce
|
||||
nr = acsr%get_nrows()
|
||||
ideg = 0
|
||||
do i=1, nr
|
||||
ideg = max(ideg,acsr%irp(i+1)-acsr%irp(i))
|
||||
end do
|
||||
allocate(ndstk(nr,ideg), iold(nr), perm(nr+1), ndeg(nr),stat=info)
|
||||
if (info /= 0) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info, name)
|
||||
goto 9999
|
||||
end if
|
||||
do i=1, nr
|
||||
iold(i) = i
|
||||
ndstk(i,:) = 0
|
||||
k = 0
|
||||
do j=acsr%irp(i),acsr%irp(i+1)-1
|
||||
k = k + 1
|
||||
ndstk(i,k) = acsr%ja(j)
|
||||
end do
|
||||
end do
|
||||
perm = 0
|
||||
|
||||
call psb_lgps_reduce(ndstk,nr,ideg,iold,perm,ndeg,ibw,ipf,idpth)
|
||||
|
||||
if (.not.psb_isaperm(nr,perm)) then
|
||||
write(0,*) 'Something wrong: bad perm from gps_reduce'
|
||||
info = psb_err_from_subroutine_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
! Move to coordinate to apply renumbering
|
||||
call acsr%mv_to_coo(acoo,info)
|
||||
do i=1, acoo%get_nzeros()
|
||||
acoo%ia(i) = perm(acoo%ia(i))
|
||||
acoo%ja(i) = perm(acoo%ja(i))
|
||||
end do
|
||||
call acoo%fix(info)
|
||||
|
||||
! Get back to where we started from
|
||||
call aa%mv_from_coo(acoo,info)
|
||||
call a%mv_from(aa)
|
||||
if (present(operm)) then
|
||||
call psb_realloc(nr,operm,info)
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
operm(1:nr) = perm(1:nr)
|
||||
end if
|
||||
|
||||
deallocate(aa)
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
end subroutine psb_lmat_renum_gps
|
||||
|
||||
|
||||
subroutine psb_lmat_renum_amd(a,info,operm)
|
||||
#if defined(HAVE_AMD)
|
||||
use iso_c_binding
|
||||
#endif
|
||||
use psb_base_mod
|
||||
implicit none
|
||||
type(psb_lsspmat_type), intent(inout) :: a
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: operm(:)
|
||||
|
||||
!
|
||||
#if defined(HAVE_AMD)
|
||||
interface
|
||||
function psb_amd_order(n,ap,ai,p)&
|
||||
& result(res) bind(c,name='psb_amd_order')
|
||||
use iso_c_binding
|
||||
integer(c_int) :: res
|
||||
integer(c_int), value :: n
|
||||
integer(c_int) :: ap(*), ai(*), p(*)
|
||||
end function psb_amd_order
|
||||
end interface
|
||||
#endif
|
||||
|
||||
type(psb_ls_csc_sparse_mat) :: acsc
|
||||
class(psb_ls_base_sparse_mat), allocatable :: aa
|
||||
type(psb_ls_coo_sparse_mat) :: acoo
|
||||
|
||||
integer(psb_ipk_), allocatable :: perm(:)
|
||||
integer(psb_ipk_) :: err_act
|
||||
character(len=20) :: name
|
||||
integer(psb_lpk_) :: i, j, k, ideg, nr, ibw, ipf, idpth, nz
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum_amd'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
#if defined(HAVE_AMD) && defined(LPK4)
|
||||
|
||||
info = psb_success_
|
||||
nr = a%get_nrows()
|
||||
nz = a%get_nzeros()
|
||||
allocate(perm(nr),stat=info)
|
||||
if (info /= 0) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
|
||||
allocate(aa, mold=a%a)
|
||||
call a%mv_to(acsc)
|
||||
|
||||
acsc%ia(:) = acsc%ia(:) - 1
|
||||
acsc%icp(:) = acsc%icp(:) - 1
|
||||
|
||||
info = psb_amd_order(nr,acsc%icp,acsc%ia,perm)
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_from_subroutine_
|
||||
call psb_errpush(info,name,a_err='psb_amd_order')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
perm(:) = perm(:) + 1
|
||||
acsc%ia(:) = acsc%ia(:) + 1
|
||||
acsc%icp(:) = acsc%icp(:) + 1
|
||||
|
||||
call acsc%mv_to_coo(acoo,info)
|
||||
do i=1, acoo%get_nzeros()
|
||||
acoo%ia(i) = perm(acoo%ia(i))
|
||||
acoo%ja(i) = perm(acoo%ja(i))
|
||||
end do
|
||||
call acoo%fix(info)
|
||||
|
||||
! Get back to where we started from
|
||||
call aa%mv_from_coo(acoo,info)
|
||||
call a%mv_from(aa)
|
||||
if (present(operm)) then
|
||||
call psb_realloc(nr,operm,info)
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
operm(1:nr) = perm(1:nr)
|
||||
end if
|
||||
|
||||
deallocate(aa,perm)
|
||||
|
||||
#else
|
||||
|
||||
info = psb_err_missing_aux_lib_
|
||||
call psb_errpush(info, name)
|
||||
goto 9999
|
||||
#endif
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
end subroutine psb_lmat_renum_amd
|
||||
|
||||
end subroutine psb_ls_mat_renum
|
||||
|
||||
subroutine psb_s_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_s_cmp_bwpf
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
!
|
||||
! Parallel Sparse BLAS version 3.5
|
||||
! (C) Copyright 2006-2018
|
||||
! Salvatore Filippone
|
||||
! Alfredo Buttari
|
||||
!
|
||||
! Redistribution and use in source and binary forms, with or without
|
||||
! modification, are permitted provided that the following conditions
|
||||
! are met:
|
||||
! 1. Redistributions of source code must retain the above copyright
|
||||
! notice, this list of conditions and the following disclaimer.
|
||||
! 2. Redistributions in binary form must reproduce the above copyright
|
||||
! notice, this list of conditions, and the following disclaimer in the
|
||||
! documentation and/or other materials provided with the distribution.
|
||||
! 3. The name of the PSBLAS group or the names of its contributors may
|
||||
! not be used to endorse or promote products derived from this
|
||||
! software without specific written permission.
|
||||
!
|
||||
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
||||
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
! POSSIBILITY OF SUCH DAMAGE.
|
||||
!
|
||||
!
|
||||
module psb_s_renum_mod
|
||||
use psb_base_mod
|
||||
|
||||
interface psb_mat_renum
|
||||
subroutine psb_s_mat_renum(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_sspmat_type
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_sspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_s_mat_renum
|
||||
subroutine psb_ls_mat_renum(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_lpk_, psb_lsspmat_type
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_lsspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_ls_mat_renum
|
||||
end interface psb_mat_renum
|
||||
|
||||
interface psb_cmp_bwpf
|
||||
subroutine psb_s_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_sspmat_type
|
||||
type(psb_sspmat_type), intent(in) :: mat
|
||||
integer(psb_ipk_), intent(out) :: bwl, bwu
|
||||
integer(psb_ipk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_s_cmp_bwpf
|
||||
subroutine psb_ls_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_lpk_, psb_lsspmat_type
|
||||
type(psb_lsspmat_type), intent(in) :: mat
|
||||
integer(psb_lpk_), intent(out) :: bwl, bwu
|
||||
integer(psb_lpk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_ls_cmp_bwpf
|
||||
end interface psb_cmp_bwpf
|
||||
|
||||
end module psb_s_renum_mod
|
||||
+273
-54
@@ -29,56 +29,11 @@
|
||||
! POSSIBILITY OF SUCH DAMAGE.
|
||||
!
|
||||
!
|
||||
subroutine psb_z_mat_renums(alg,mat,info,perm)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_z_mat_renums
|
||||
implicit none
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_zspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
|
||||
integer(psb_ipk_) :: err_act, nr, nc, ialg
|
||||
character(len=20) :: name
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
select case (psb_toupper(alg))
|
||||
case ('GPS')
|
||||
ialg = psb_mat_renum_gps_
|
||||
case ('AMD')
|
||||
ialg = psb_mat_renum_amd_
|
||||
case ('NONE', 'ID')
|
||||
ialg = psb_mat_renum_identity_
|
||||
case default
|
||||
write(0,*) 'Unknown algorithm "',psb_toupper(alg),'"'
|
||||
ialg = -1
|
||||
end select
|
||||
|
||||
call psb_mat_renum(ialg,mat,info,perm)
|
||||
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_from_subroutine_non_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
end subroutine psb_z_mat_renums
|
||||
|
||||
subroutine psb_z_mat_renum(alg,mat,info,perm)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_z_mat_renum
|
||||
implicit none
|
||||
integer(psb_ipk_), intent(in) :: alg
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_zspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
@@ -90,8 +45,6 @@ subroutine psb_z_mat_renum(alg,mat,info,perm)
|
||||
name = 'mat_renum'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
|
||||
nr = mat%get_nrows()
|
||||
nc = mat%get_ncols()
|
||||
if (nr /= nc) then
|
||||
@@ -101,16 +54,17 @@ subroutine psb_z_mat_renum(alg,mat,info,perm)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
select case (alg)
|
||||
case(psb_mat_renum_gps_)
|
||||
info = psb_success_
|
||||
select case (psb_toupper(alg))
|
||||
case ('GPS')
|
||||
|
||||
call psb_mat_renum_gps(mat,info,perm)
|
||||
|
||||
case(psb_mat_renum_amd_)
|
||||
case('AMD')
|
||||
|
||||
call psb_mat_renum_amd(mat,info,perm)
|
||||
|
||||
case(psb_mat_renum_identity_)
|
||||
case ('NONE', 'ID')
|
||||
nr = mat%get_nrows()
|
||||
allocate(perm(nr),stat=info)
|
||||
if (info == 0) then
|
||||
@@ -123,8 +77,9 @@ subroutine psb_z_mat_renum(alg,mat,info,perm)
|
||||
goto 9999
|
||||
endif
|
||||
case default
|
||||
write(0,*) 'Unknown algorithm "',psb_toupper(alg),'"'
|
||||
info = psb_err_input_value_invalid_i_
|
||||
ierr(1) = 1; ierr(2) = alg;
|
||||
ierr(1) = 1;
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end select
|
||||
@@ -162,7 +117,7 @@ contains
|
||||
integer(psb_ipk_) :: i, j, k, ideg, nr, ibw, ipf, idpth
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum'
|
||||
name = 'mat_renum_gps'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
@@ -228,6 +183,7 @@ contains
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
end subroutine psb_mat_renum_gps
|
||||
|
||||
|
||||
@@ -335,6 +291,269 @@ contains
|
||||
|
||||
end subroutine psb_z_mat_renum
|
||||
|
||||
subroutine psb_lz_mat_renum(alg,mat,info,perm)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_lz_mat_renum
|
||||
implicit none
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_lzspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: perm(:)
|
||||
|
||||
integer(psb_lpk_) :: nr, nc, i
|
||||
integer(psb_ipk_) :: err_act, ierr(5)
|
||||
character(len=20) :: name
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
nr = mat%get_nrows()
|
||||
nc = mat%get_ncols()
|
||||
if (nr /= nc) then
|
||||
info = psb_err_rectangular_mat_unsupported_
|
||||
ierr(1) = nr; ierr(2) = nc;
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
info = psb_success_
|
||||
select case (psb_toupper(alg))
|
||||
case ('GPS')
|
||||
|
||||
call psb_lmat_renum_gps(mat,info,perm)
|
||||
|
||||
case('AMD')
|
||||
|
||||
call psb_lmat_renum_amd(mat,info,perm)
|
||||
|
||||
case ('NONE', 'ID')
|
||||
nr = mat%get_nrows()
|
||||
allocate(perm(nr),stat=info)
|
||||
if (info == 0) then
|
||||
do i=1,nr
|
||||
perm(i) = i
|
||||
end do
|
||||
else
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
case default
|
||||
write(0,*) 'Unknown algorithm "',psb_toupper(alg),'"'
|
||||
info = psb_err_input_value_invalid_i_
|
||||
ierr(1) = 1;
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end select
|
||||
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_from_subroutine_non_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
contains
|
||||
|
||||
subroutine psb_lmat_renum_gps(a,info,operm)
|
||||
use psb_base_mod
|
||||
use psb_lgps_mod
|
||||
implicit none
|
||||
type(psb_lzspmat_type), intent(inout) :: a
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: operm(:)
|
||||
|
||||
!
|
||||
class(psb_lz_base_sparse_mat), allocatable :: aa
|
||||
type(psb_lz_csr_sparse_mat) :: acsr
|
||||
type(psb_lz_coo_sparse_mat) :: acoo
|
||||
|
||||
integer(psb_ipk_) :: err_act
|
||||
character(len=20) :: name
|
||||
integer(psb_lpk_), allocatable :: ndstk(:,:), iold(:), ndeg(:), perm(:)
|
||||
integer(psb_lpk_) :: i, j, k, ideg, nr, ibw, ipf, idpth
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum_gps'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
info = psb_success_
|
||||
|
||||
call a%mold(aa)
|
||||
call a%mv_to(aa)
|
||||
call aa%mv_to_fmt(acsr,info)
|
||||
! Insert call to gps_reduce
|
||||
nr = acsr%get_nrows()
|
||||
ideg = 0
|
||||
do i=1, nr
|
||||
ideg = max(ideg,acsr%irp(i+1)-acsr%irp(i))
|
||||
end do
|
||||
allocate(ndstk(nr,ideg), iold(nr), perm(nr+1), ndeg(nr),stat=info)
|
||||
if (info /= 0) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info, name)
|
||||
goto 9999
|
||||
end if
|
||||
do i=1, nr
|
||||
iold(i) = i
|
||||
ndstk(i,:) = 0
|
||||
k = 0
|
||||
do j=acsr%irp(i),acsr%irp(i+1)-1
|
||||
k = k + 1
|
||||
ndstk(i,k) = acsr%ja(j)
|
||||
end do
|
||||
end do
|
||||
perm = 0
|
||||
|
||||
call psb_lgps_reduce(ndstk,nr,ideg,iold,perm,ndeg,ibw,ipf,idpth)
|
||||
|
||||
if (.not.psb_isaperm(nr,perm)) then
|
||||
write(0,*) 'Something wrong: bad perm from gps_reduce'
|
||||
info = psb_err_from_subroutine_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
! Move to coordinate to apply renumbering
|
||||
call acsr%mv_to_coo(acoo,info)
|
||||
do i=1, acoo%get_nzeros()
|
||||
acoo%ia(i) = perm(acoo%ia(i))
|
||||
acoo%ja(i) = perm(acoo%ja(i))
|
||||
end do
|
||||
call acoo%fix(info)
|
||||
|
||||
! Get back to where we started from
|
||||
call aa%mv_from_coo(acoo,info)
|
||||
call a%mv_from(aa)
|
||||
if (present(operm)) then
|
||||
call psb_realloc(nr,operm,info)
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
operm(1:nr) = perm(1:nr)
|
||||
end if
|
||||
|
||||
deallocate(aa)
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
|
||||
end subroutine psb_lmat_renum_gps
|
||||
|
||||
|
||||
subroutine psb_lmat_renum_amd(a,info,operm)
|
||||
#if defined(HAVE_AMD)
|
||||
use iso_c_binding
|
||||
#endif
|
||||
use psb_base_mod
|
||||
implicit none
|
||||
type(psb_lzspmat_type), intent(inout) :: a
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: operm(:)
|
||||
|
||||
!
|
||||
#if defined(HAVE_AMD)
|
||||
interface
|
||||
function psb_amd_order(n,ap,ai,p)&
|
||||
& result(res) bind(c,name='psb_amd_order')
|
||||
use iso_c_binding
|
||||
integer(c_int) :: res
|
||||
integer(c_int), value :: n
|
||||
integer(c_int) :: ap(*), ai(*), p(*)
|
||||
end function psb_amd_order
|
||||
end interface
|
||||
#endif
|
||||
|
||||
type(psb_lz_csc_sparse_mat) :: acsc
|
||||
class(psb_lz_base_sparse_mat), allocatable :: aa
|
||||
type(psb_lz_coo_sparse_mat) :: acoo
|
||||
|
||||
integer(psb_ipk_), allocatable :: perm(:)
|
||||
integer(psb_ipk_) :: err_act
|
||||
character(len=20) :: name
|
||||
integer(psb_lpk_) :: i, j, k, ideg, nr, ibw, ipf, idpth, nz
|
||||
|
||||
info = psb_success_
|
||||
name = 'mat_renum_amd'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
#if defined(HAVE_AMD) && defined(LPK4)
|
||||
|
||||
info = psb_success_
|
||||
nr = a%get_nrows()
|
||||
nz = a%get_nzeros()
|
||||
allocate(perm(nr),stat=info)
|
||||
if (info /= 0) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
|
||||
allocate(aa, mold=a%a)
|
||||
call a%mv_to(acsc)
|
||||
|
||||
acsc%ia(:) = acsc%ia(:) - 1
|
||||
acsc%icp(:) = acsc%icp(:) - 1
|
||||
|
||||
info = psb_amd_order(nr,acsc%icp,acsc%ia,perm)
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_from_subroutine_
|
||||
call psb_errpush(info,name,a_err='psb_amd_order')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
perm(:) = perm(:) + 1
|
||||
acsc%ia(:) = acsc%ia(:) + 1
|
||||
acsc%icp(:) = acsc%icp(:) + 1
|
||||
|
||||
call acsc%mv_to_coo(acoo,info)
|
||||
do i=1, acoo%get_nzeros()
|
||||
acoo%ia(i) = perm(acoo%ia(i))
|
||||
acoo%ja(i) = perm(acoo%ja(i))
|
||||
end do
|
||||
call acoo%fix(info)
|
||||
|
||||
! Get back to where we started from
|
||||
call aa%mv_from_coo(acoo,info)
|
||||
call a%mv_from(aa)
|
||||
if (present(operm)) then
|
||||
call psb_realloc(nr,operm,info)
|
||||
if (info /= psb_success_) then
|
||||
info = psb_err_alloc_dealloc_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
operm(1:nr) = perm(1:nr)
|
||||
end if
|
||||
|
||||
deallocate(aa,perm)
|
||||
|
||||
#else
|
||||
|
||||
info = psb_err_missing_aux_lib_
|
||||
call psb_errpush(info, name)
|
||||
goto 9999
|
||||
#endif
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(err_act)
|
||||
return
|
||||
end subroutine psb_lmat_renum_amd
|
||||
|
||||
end subroutine psb_lz_mat_renum
|
||||
|
||||
subroutine psb_z_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
use psb_base_mod
|
||||
use psb_renum_mod, psb_protect_name => psb_z_cmp_bwpf
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
!
|
||||
! Parallel Sparse BLAS version 3.5
|
||||
! (C) Copyright 2006-2018
|
||||
! Salvatore Filippone
|
||||
! Alfredo Buttari
|
||||
!
|
||||
! Redistribution and use in source and binary forms, with or without
|
||||
! modification, are permitted provided that the following conditions
|
||||
! are met:
|
||||
! 1. Redistributions of source code must retain the above copyright
|
||||
! notice, this list of conditions and the following disclaimer.
|
||||
! 2. Redistributions in binary form must reproduce the above copyright
|
||||
! notice, this list of conditions, and the following disclaimer in the
|
||||
! documentation and/or other materials provided with the distribution.
|
||||
! 3. The name of the PSBLAS group or the names of its contributors may
|
||||
! not be used to endorse or promote products derived from this
|
||||
! software without specific written permission.
|
||||
!
|
||||
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
||||
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
! POSSIBILITY OF SUCH DAMAGE.
|
||||
!
|
||||
!
|
||||
module psb_z_renum_mod
|
||||
use psb_base_mod
|
||||
|
||||
interface psb_mat_renum
|
||||
subroutine psb_z_mat_renum(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_zspmat_type
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_zspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_ipk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_z_mat_renum
|
||||
subroutine psb_lz_mat_renum(alg,mat,info,perm)
|
||||
import :: psb_ipk_, psb_lpk_, psb_lzspmat_type
|
||||
character(len=*), intent(in) :: alg
|
||||
type(psb_lzspmat_type), intent(inout) :: mat
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
integer(psb_lpk_), allocatable, optional, intent(out) :: perm(:)
|
||||
end subroutine psb_lz_mat_renum
|
||||
end interface psb_mat_renum
|
||||
|
||||
interface psb_cmp_bwpf
|
||||
subroutine psb_z_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_zspmat_type
|
||||
type(psb_zspmat_type), intent(in) :: mat
|
||||
integer(psb_ipk_), intent(out) :: bwl, bwu
|
||||
integer(psb_ipk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_z_cmp_bwpf
|
||||
subroutine psb_lz_cmp_bwpf(mat,bwl,bwu,prf,info)
|
||||
import :: psb_ipk_, psb_lpk_, psb_lzspmat_type
|
||||
type(psb_lzspmat_type), intent(in) :: mat
|
||||
integer(psb_lpk_), intent(out) :: bwl, bwu
|
||||
integer(psb_lpk_), intent(out) :: prf
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
end subroutine psb_lz_cmp_bwpf
|
||||
end interface psb_cmp_bwpf
|
||||
|
||||
end module psb_z_renum_mod
|
||||
Reference in New Issue
Block a user