Fixes for samples install

This commit is contained in:
Salvatore Filippone
2021-05-07 13:12:23 +02:00
parent 555d7433b7
commit 6dddaaa77b
63 changed files with 11 additions and 11 deletions
+92
View File
@@ -0,0 +1,92 @@
AMGDIR=../../..
AMGINCDIR=$(AMGDIR)/include
include $(AMGINCDIR)/Make.inc.amg4psblas
AMGMODDIR=$(AMGDIR)/modules
AMGLIBDIR=$(AMGDIR)/lib
AMG_LIBS=-L$(AMGLIBDIR) -lpsb_krylov -lamg_prec -lpsb_prec
FINCLUDES=$(FMFLAG). $(FMFLAG)$(AMGMODDIR) $(FMFLAG)$(AMGINCDIR) $(PSBLAS_INCLUDES) $(FIFLAG).
LINKOPT=
DMOBJS=amg_dexample_ml.o data_input.o
D1OBJS=amg_dexample_1lev.o data_input.o
ZMOBJS=amg_zexample_ml.o data_input.o
Z1OBJS=amg_zexample_1lev.o data_input.o
SMOBJS=amg_sexample_ml.o data_input.o
S1OBJS=amg_sexample_1lev.o data_input.o
CMOBJS=amg_cexample_ml.o data_input.o
C1OBJS=amg_cexample_1lev.o data_input.o
EXEDIR=./runs
all: amg_dexample_ml amg_dexample_1lev amg_zexample_ml amg_zexample_1lev\
amg_sexample_ml amg_sexample_1lev amg_cexample_ml amg_cexample_1lev
amg_dexample_ml: $(DMOBJS)
$(FLINK) $(LINKOPT) $(DMOBJS) -o amg_dexample_ml \
$(AMG_LIBS) $(PSBLAS_LIBS) $(LDLIBS)
/bin/mv amg_dexample_ml $(EXEDIR)
amg_dexample_1lev: $(D1OBJS)
$(FLINK) $(LINKOPT) $(D1OBJS) -o amg_dexample_1lev \
$(AMG_LIBS) $(PSBLAS_LIBS) $(LDLIBS)
/bin/mv amg_dexample_1lev $(EXEDIR)
amg_dexample_ml.o: data_input.o
amg_dexample_1lev.o: data_input.o
amg_zexample_ml: $(ZMOBJS)
$(FLINK) $(LINKOPT) $(ZMOBJS) -o amg_zexample_ml \
$(AMG_LIBS) $(PSBLAS_LIBS) $(LDLIBS)
/bin/mv amg_zexample_ml $(EXEDIR)
amg_zexample_1lev: $(Z1OBJS)
$(FLINK) $(LINKOPT) $(Z1OBJS) -o amg_zexample_1lev \
$(AMG_LIBS) $(PSBLAS_LIBS) $(LDLIBS)
/bin/mv amg_zexample_1lev $(EXEDIR)
amg_zexample_ml.o: data_input.o
amg_zexample_1lev.o: data_input.o
amg_sexample_ml: $(SMOBJS)
$(FLINK) $(LINKOPT) $(SMOBJS) -o amg_sexample_ml \
$(AMG_LIBS) $(PSBLAS_LIBS) $(LDLIBS)
/bin/mv amg_sexample_ml $(EXEDIR)
amg_sexample_1lev: $(S1OBJS)
$(FLINK) $(LINKOPT) $(S1OBJS) -o amg_sexample_1lev \
$(AMG_LIBS) $(PSBLAS_LIBS) $(LDLIBS)
/bin/mv amg_sexample_1lev $(EXEDIR)
amg_sexample_ml.o: data_input.o
amg_sexample_1lev.o: data_input.o
amg_cexample_ml: $(CMOBJS)
$(FLINK) $(LINKOPT) $(CMOBJS) -o amg_cexample_ml \
$(AMG_LIBS) $(PSBLAS_LIBS) $(LDLIBS)
/bin/mv amg_cexample_ml $(EXEDIR)
amg_cexample_1lev: $(C1OBJS)
$(FLINK) $(LINKOPT) $(C1OBJS) -o amg_cexample_1lev \
$(AMG_LIBS) $(PSBLAS_LIBS) $(LDLIBS)
/bin/mv amg_cexample_1lev $(EXEDIR)
amg_cexample_ml.o: data_input.o
amg_cexample_1lev.o: data_input.o
clean:
/bin/rm -f *$(.mod) \
$(DMOBJS) $(D1OBJS) $(ZMOBJS) $(Z1OBJS) \
$(EXEDIR)/amg_dexample_ml $(EXEDIR)/amg_dexample_1lev \
$(EXEDIR)/amg_zexample_ml $(EXEDIR)/amg_zexample_1lev \
$(SMOBJS) $(S1OBJS) $(CMOBJS) $(C1OBJS) \
$(EXEDIR)/amg_sexample_ml $(EXEDIR)/amg_sexample_1lev \
$(EXEDIR)/amg_cexample_ml $(EXEDIR)/amg_cexample_1lev
lib:
(cd ../../; make library)
verycleanlib:
(cd ../../; make veryclean)
@@ -0,0 +1,350 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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.
!
!
! File: amg_cexample_1lev.f90
!
! This sample program solves a linear system by using BiCGStab preconditioned by
! RAS with overlap 2 and ILU(0) on the local blocks, as explained in Section 4.1
! of the AMG4PSBLAS User's and Reference Guide.
!
! The matrix and the rhs are read from files (if an rhs is not available, the
! unit rhs is set).
!
program amg_cexample_1lev
use psb_base_mod
use amg_prec_mod
use psb_krylov_mod
use psb_util_mod
use data_input
implicit none
! input parameters
character(len=40) :: mtrx_file, rhs_file
character(len=2) :: filefmt
! sparse matrices
type(psb_cspmat_type) :: A, aux_A
! descriptor of sparse matrices
type(psb_desc_type):: desc_A
! preconditioner
type(amg_cprec_type) :: P
! right-hand side, solution and residual vectors
type(psb_c_vect_type) :: b, x, r
complex(psb_spk_), allocatable , save :: x_glob(:), r_glob(:)
complex(psb_spk_), allocatable, target :: aux_b(:,:)
complex(psb_spk_), pointer :: b_glob(:)
! solver and preconditioner parameters
real(psb_spk_) :: tol, err
integer :: itmax, iter, istop
integer :: nlev
! parallel environment parameters
type(psb_ctxt_type) :: ctxt
integer :: iam, np
! other variables
integer :: i,info,j,m_problem
integer(psb_epk_) :: amatsize, precsize, descsize
integer :: ierr, ircode
real(psb_spk_) :: resmx, resmxp
real(psb_dpk_) :: t1, t2, tprec
character(len=20) :: name, kmethod
integer, parameter :: iunit=12
! initialize the parallel environment
call psb_init(ctxt)
call psb_info(ctxt,iam,np)
if (iam < 0) then
! This should not happen, but just in case
call psb_exit(ctxt)
stop
endif
name='amg_cexample_ml'
if(psb_get_errstatus() /= 0) goto 9999
info=psb_success_
call psb_set_errverbosity(2)
!
! Hello world
!
if (iam == psb_root_) then
write(*,*) 'Welcome to AMG4PSBLAS version: ',amg_version_string_
write(*,*) 'This is the ',trim(name),' sample program'
end if
! get parameters
call get_parms(ctxt,mtrx_file,rhs_file,filefmt,itmax,tol)
call psb_barrier(ctxt)
t1 = psb_wtime()
! read and assemble the matrix A and the right-hand side b
! using PSBLAS routines for sparse matrix / vector management
if (iam == psb_root_) then
select case(psb_toupper(filefmt))
case('MM')
! For Matrix Market we have an input file for the matrix
! and an (optional) second file for the RHS.
call mm_mat_read(aux_a,info,iunit=iunit,filename=mtrx_file)
if (info == psb_success_) then
if (rhs_file /= 'NONE') then
call mm_array_read(aux_b,info,iunit=iunit,filename=rhs_file)
end if
end if
case ('HB')
! For Harwell-Boeing we have a single file which may or may not
! contain an RHS.
call hb_read(aux_a,info,iunit=iunit,b=aux_b,filename=mtrx_file)
case default
info = -1
write(0,*) 'Wrong choice for fileformat ', filefmt
end select
if (info /= psb_success_) then
write(0,*) 'Error while reading input matrix '
call psb_abort(ctxt)
end if
m_problem = aux_a%get_nrows()
call psb_bcast(ctxt,m_problem)
! At this point aux_b may still be unallocated
if (psb_size(aux_b,1) == m_problem) then
! if any rhs were present, broadcast the first one
write(0,'("Ok, got an rhs ")')
b_glob =>aux_b(:,1)
else
write(*,'("Generating an rhs...")')
write(*,'(" ")')
call psb_realloc(m_problem,1,aux_b,ircode)
if (ircode /= 0) then
call psb_errpush(psb_err_alloc_dealloc_,name)
goto 9999
endif
b_glob => aux_b(:,1)
do i=1, m_problem
b_glob(i) = 1.d0
enddo
endif
else
call psb_bcast(ctxt,m_problem)
end if
call psb_barrier(ctxt)
if (iam == psb_root_) write(*,'("Partition type: block")')
call psb_matdist(aux_A, A, ctxt, desc_A,info,parts=part_block)
call psb_scatter(b_glob,b,desc_a,info,root=psb_root_)
t2 = psb_wtime() - t1
call psb_amx(ctxt, t2)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Time to read and partition matrix : ",es12.5)')t2
write(*,'(" ")')
end if
! START SETTING PARAMETER
! set RAS
call P%init(ctxt,'AS',info)
! set number of overlaps
call P%set('SUB_OVR',2,info)
! build the preconditioner
t1 = psb_wtime()
call P%build(A,desc_A,info)
tprec = psb_wtime()-t1
call psb_amx(ctxt, tprec)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,a_err='amg_precbld')
goto 9999
end if
! set the initial guess
call psb_geall(x,desc_A,info)
call x%zero()
call psb_geasb(x,desc_A,info)
! solve Ax=b with preconditioned Krylov method: BiCGSTAB
kmethod = 'BiCGSTAB'
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_krylov(kmethod,A,P,b,x,tol,desc_A,info,itmax,iter,err,istop=2)
t2 = psb_wtime() - t1
call psb_amx(ctxt,t2)
call psb_geasb(r,desc_A,info,scratch=.true.)
call psb_geaxpby(cone,b,czero,r,desc_A,info)
call psb_spmm(-cone,A,x,cone,r,desc_A,info)
resmx = psb_genrm2(r,desc_A,info)
resmxp = psb_geamax(r,desc_A,info)
amatsize = a%sizeof()
descsize = desc_a%sizeof()
precsize = p%sizeof()
call psb_sum(ctxt,amatsize)
call psb_sum(ctxt,descsize)
call psb_sum(ctxt,precsize)
call P%descr(info)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Matrix: ",A)')mtrx_file
write(*,'("Computed solution on ",i8," processors")')np
write(*,'("Krylov method : ",a)') kmethod
write(*,'("Iterations to convergence : ",i6)')iter
write(*,'("Error estimate on exit : ",es12.5)')err
write(*,'("Time to build prec. : ",es12.5)')tprec
write(*,'("Time to solve system : ",es12.5)')t2
write(*,'("Time per iteration : ",es12.5)')t2/(iter)
write(*,'("Total time : ",es12.5)')t2+tprec
write(*,'("Residual 2-norm : ",es12.5)')resmx
write(*,'("Residual inf-norm : ",es12.5)')resmxp
write(*,'("Total memory occupation for A : ",i12)')amatsize
write(*,'("Total memory occupation for DESC_A : ",i12)')descsize
write(*,'("Total memory occupation for PREC : ",i12)')precsize
end if
call psb_gather(x_glob,x,desc_a,info,root=psb_root_)
if (info == psb_success_) &
& call psb_gather(r_glob,r,desc_a,info,root=psb_root_)
if (info /= psb_success_) goto 9999
if (iam == psb_root_) then
write(0,'(" ")')
write(0,'("Saving x on file")')
write(20,*) 'matrix: ',mtrx_file
write(20,*) 'computed solution on ',np,' processor(s).'
write(20,*) 'iterations to convergence: ',iter
write(20,*) 'error estimate (infinity norm) on exit:', &
& ' ||r||/(||a||||x||+||b||) = ',err
write(20,*) 'max residual = ',resmx, resmxp
write(20,'(a8,4(2x,a20))') 'I','X(I)','R(I)','B(I)'
do i=1,m_problem
write(20,998) i,x_glob(i),r_glob(i),b_glob(i)
enddo
end if
998 format(i8,4(2x,g20.14))
993 format(i6,4(1x,e12.6))
! deallocate the data structures
call psb_gefree(b, desc_A,info)
call psb_gefree(x, desc_A,info)
call psb_spfree(A, desc_A,info)
call P%free(info)
call psb_cdfree(desc_A,info)
call psb_exit(ctxt)
stop
9999 continue
call psb_error(ctxt)
contains
!
! get parameters from standard input
!
subroutine get_parms(ctxt,mtrx,rhs,filefmt,itmax,tol)
implicit none
type(psb_ctxt_type) :: ctxt
integer :: itmax
real(psb_spk_) :: tol
character(len=*) :: mtrx, rhs,filefmt
integer :: iam, np, inp_unit
character(len=1024) :: filename
call psb_info(ctxt,iam,np)
if (iam == psb_root_) then
if (command_argument_count()>0) then
call get_command_argument(1,filename)
inp_unit = 30
open(inp_unit,file=filename,action='read',iostat=info)
if (info /= 0) then
write(psb_err_unit,*) 'Could not open file ',filename,' for input'
call psb_abort(ctxt)
stop
else
write(psb_err_unit,*) 'Opened file ',trim(filename),' for input'
end if
else
inp_unit=psb_inp_unit
end if
! read input parameters
call read_data(mtrx,inp_unit)
call read_data(rhs,inp_unit)
call read_data(filefmt,inp_unit)
call read_data(itmax,inp_unit)
call read_data(tol,inp_unit)
if (inp_unit /= psb_inp_unit) then
close(inp_unit)
end if
end if
call psb_bcast(ctxt,mtrx)
call psb_bcast(ctxt,rhs)
call psb_bcast(ctxt,filefmt)
call psb_bcast(ctxt,itmax)
call psb_bcast(ctxt,tol)
end subroutine get_parms
end program amg_cexample_1lev
+401
View File
@@ -0,0 +1,401 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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.
!
!
! File: amg_cexample_ml.f90
!
! This sample program solves a linear system by using CG coupled with
! one of the following multi-level preconditioner, as explained in Section 4.1
! of the AMG4PSBLAS User's and Reference Guide:
!
! - choice = 1, the default multi-level preconditioner solver, i.e.,
! V-cycle with decoupled smoothed aggregation, 1 hybrid forward/backward
! GS sweep as pre/post-smoother and UMFPACK as coarsest-level
! solver (Sec. 4.1, Listing 1)
!
! - choice = 2, a V-cycle preconditioner with 1 block-Jacobi sweep
! (with ILU(0) on the blocks) as pre- and post-smoother, and 8 block-Jacobi
! sweeps (with ILU(0) on the blocks) as coarsest-level solver (Sec. 4.1, Listing 2)
!
! - choice = 3, W-cycle preconditioner based on the coupled aggregation relying on matching,
! with maximum size of aggregates equal to 8 and smoothed prolongators,
! 2 hybrid forward/backward GS sweeps as pre/post-smoother, a distributed coarsest
! matrix, and preconditioned Flexible Conjugate Gradient as coarsest-level solver
! (Sec. 4.1, Listing 3)
!
! The matrix and the rhs are read from files (if an rhs is not available, the
! unit rhs is set).
!
program amg_cexample_ml
use psb_base_mod
use amg_prec_mod
use psb_krylov_mod
use psb_util_mod
use data_input
implicit none
! input file parameters
character(len=40) :: mtrx_file, rhs_file
character(len=2) :: filefmt
! sparse matrices
type(psb_cspmat_type) :: A, aux_A
! descriptor of sparse matrices
type(psb_desc_type):: desc_A
! preconditioner
type(amg_cprec_type) :: P
! right-hand side, solution and residual vectors
type(psb_c_vect_type) :: b, x, r
complex(psb_spk_), allocatable , save :: x_glob(:), r_glob(:)
complex(psb_spk_), allocatable, target :: aux_b(:,:)
complex(psb_spk_), pointer :: b_glob(:)
! solver and preconditioner parameters
real(psb_spk_) :: tol, err
integer :: itmax, iter, istop
integer :: nlev
! parallel environment parameters
type(psb_ctxt_type) :: ctxt
integer :: iam, np
! other variables
integer :: choice
integer :: i,info,j,m_problem
integer(psb_epk_) :: amatsize, precsize, descsize
integer :: ierr, ircode
real(psb_spk_) :: resmx, resmxp
real(psb_dpk_) :: t1, t2, tprec
character(len=20) :: name, kmethod
integer, parameter :: iunit=12
! initialize the parallel environment
call psb_init(ctxt)
call psb_info(ctxt,iam,np)
if (iam < 0) then
! This should not happen, but just in case
call psb_exit(ctxt)
stop
endif
name='amg_cexample_ml'
if(psb_get_errstatus() /= 0) goto 9999
info=psb_success_
call psb_set_errverbosity(2)
!
! Hello world
!
if (iam == psb_root_) then
write(*,*) 'Welcome to AMG4PSBLAS version: ',amg_version_string_
write(*,*) 'This is the ',trim(name),' sample program'
end if
! get parameters
call get_parms(ctxt,mtrx_file,rhs_file,filefmt,choice,itmax,tol)
call psb_barrier(ctxt)
t1 = psb_wtime()
! read and assemble the matrix A and the right-hand side b
! using PSBLAS routines for sparse matrix / vector management
if (iam == psb_root_) then
select case(psb_toupper(filefmt))
case('MM')
! For Matrix Market we have an input file for the matrix
! and an (optional) second file for the RHS.
call mm_mat_read(aux_a,info,iunit=iunit,filename=mtrx_file)
if (info == psb_success_) then
if (rhs_file /= 'NONE') then
call mm_array_read(aux_b,info,iunit=iunit,filename=rhs_file)
end if
end if
case ('HB')
! For Harwell-Boeing we have a single file which may or may not
! contain an RHS.
call hb_read(aux_a,info,iunit=iunit,b=aux_b,filename=mtrx_file)
case default
info = -1
write(0,*) 'Wrong choice for fileformat ', filefmt
end select
if (info /= psb_success_) then
write(0,*) 'Error while reading input matrix '
call psb_abort(ctxt)
end if
m_problem = aux_a%get_nrows()
call psb_bcast(ctxt,m_problem)
! At this point aux_b may still be unallocated
if (psb_size(aux_b,1) == m_problem) then
! if any rhs were present, broadcast the first one
write(0,'("Ok, got an rhs ")')
b_glob =>aux_b(:,1)
else
write(*,'("Generating an rhs...")')
write(*,'(" ")')
call psb_realloc(m_problem,1,aux_b,ircode)
if (ircode /= 0) then
call psb_errpush(psb_err_alloc_dealloc_,name)
goto 9999
endif
b_glob => aux_b(:,1)
do i=1, m_problem
b_glob(i) = 1.d0
enddo
endif
else
call psb_bcast(ctxt,m_problem)
end if
call psb_barrier(ctxt)
if (iam == psb_root_) write(*,'("Partition type: block")')
call psb_matdist(aux_A, A, ctxt, desc_A,info,parts=part_block)
call psb_scatter(b_glob,b,desc_a,info,root=psb_root_)
t2 = psb_wtime() - t1
call psb_amx(ctxt, t2)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Time to read and partition matrix : ",es12.5)')t2
write(*,'(" ")')
end if
select case(choice)
case(1)
! initialize the default multi-level preconditioner, i.e. V-cycle
! with decoupled smoothed aggregation, 1 hybrid forward/backward
! GS sweep as pre/post-smoother and UMFPACK as coarsest-level
! solver
call P%init(ctxt,'ML',info)
kmethod = 'CG'
case(2)
! initialize a V-cycle preconditioner with 1 block-Jacobi sweep (with
! ILU(0) on the blocks) as pre- and post-smoother, and 8 block-Jacobi
! sweeps (with ILU(0) on the blocks) as coarsest-level solver
call P%init(ctxt,'ML',info)
call P%set('SMOOTHER_TYPE','BJAC',info)
call P%set('COARSE_SOLVE','BJAC',info)
call P%set('COARSE_SWEEPS',8,info)
kmethod = 'CG'
case(3)
! initialize a W-cycle preconditioner based on the coupled aggregation relying on matching,
! with maximum size of aggregates equal to 8 and smoothed prolongators,
! 2 hybrid forward/backward GS sweeps as pre/post-smoother, a distributed coarsest
! matrix, and preconditioned Flexible Conjugate Gradient as coarsest-level solver
call P%init(ctxt,'ML',info)
call P%set('PAR_AGGR_ALG','COUPLED',info)
call P%set('AGGR_TYPE','MATCHBOXP',info)
call P%set('AGGR_SIZE',8,info)
call P%set('ML_CYCLE','WCYCLE',info)
call P%set('SMOOTHER_SWEEPS',2,info)
call P%set('COARSE_SOLVE','KRM',info)
kmethod = 'CG'
end select
! build the preconditioner
call psb_barrier(ctxt)
t1 = psb_wtime()
! build the preconditioner
call P%hierarchy_build(A,desc_A,info)
call P%smoothers_build(A,desc_A,info)
tprec = psb_wtime()-t1
call psb_amx(ctxt, tprec)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,a_err='amg_precbld')
goto 9999
end if
! set the initial guess
call psb_geall(x,desc_A,info)
call x%zero()
call psb_geasb(x,desc_A,info)
! solve Ax=b with preconditioned CG
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_krylov(kmethod,A,P,b,x,tol,desc_A,info,itmax,iter,err,itrace=1,istop=2)
t2 = psb_wtime() - t1
call psb_amx(ctxt,t2)
call psb_geasb(r,desc_A,info,scratch=.true.)
call psb_geaxpby(cone,b,czero,r,desc_A,info)
call psb_spmm(-cone,A,x,cone,r,desc_A,info)
resmx = psb_genrm2(r,desc_A,info)
resmxp = psb_geamax(r,desc_A,info)
amatsize = a%sizeof()
descsize = desc_a%sizeof()
precsize = p%sizeof()
call psb_sum(ctxt,amatsize)
call psb_sum(ctxt,descsize)
call psb_sum(ctxt,precsize)
call P%descr(info)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Matrix: ",A)')mtrx_file
write(*,'("Computed solution on ",i8," processors")')np
write(*,'("Krylov method : ",a)') kmethod
write(*,'("Iterations to convergence : ",i6)')iter
write(*,'("Error estimate on exit : ",es12.5)')err
write(*,'("Time to build prec. : ",es12.5)')tprec
write(*,'("Time to solve system : ",es12.5)')t2
write(*,'("Time per iteration : ",es12.5)')t2/(iter)
write(*,'("Total time : ",es12.5)')t2+tprec
write(*,'("Residual 2-norm : ",es12.5)')resmx
write(*,'("Residual inf-norm : ",es12.5)')resmxp
write(*,'("Total memory occupation for A : ",i12)')amatsize
write(*,'("Total memory occupation for DESC_A : ",i12)')descsize
write(*,'("Total memory occupation for PREC : ",i12)')precsize
end if
call psb_gather(x_glob,x,desc_a,info,root=psb_root_)
if (info == psb_success_) &
& call psb_gather(r_glob,r,desc_a,info,root=psb_root_)
if (info /= psb_success_) goto 9999
if (iam == psb_root_) then
write(0,'(" ")')
write(0,'("Saving x on file")')
write(20,*) 'matrix: ',mtrx_file
write(20,*) 'computed solution on ',np,' processors.'
write(20,*) 'iterations to convergence: ',iter
write(20,*) 'error estimate (infinity norm) on exit:', &
& ' ||r||/(||a||||x||+||b||) = ',err
write(20,*) 'max residual = ',resmx, resmxp
write(20,'(a8,4(2x,a20))') 'I','X(I)','R(I)','B(I)'
do i=1,m_problem
write(20,998) i,x_glob(i),r_glob(i),b_glob(i)
enddo
end if
998 format(i8,4(2x,g20.14))
993 format(i6,4(1x,e12.6))
! deallocate the data structures
call psb_gefree(b, desc_A,info)
call psb_gefree(x, desc_A,info)
call psb_spfree(A, desc_A,info)
call P%free(info)
call psb_cdfree(desc_A,info)
call psb_exit(ctxt)
stop
9999 continue
call psb_error(ctxt)
contains
!
! get parameters from standard input
!
subroutine get_parms(ctxt,mtrx,rhs,filefmt,choice,itmax,tol)
implicit none
type(psb_ctxt_type) :: ctxt
integer :: choice, itmax
real(psb_spk_) :: tol
character(len=*) :: mtrx, rhs,filefmt
integer :: iam, np, inp_unit
character(len=1024) :: filename
call psb_info(ctxt,iam,np)
if (iam == psb_root_) then
if (command_argument_count()>0) then
call get_command_argument(1,filename)
inp_unit = 30
open(inp_unit,file=filename,action='read',iostat=info)
if (info /= 0) then
write(psb_err_unit,*) 'Could not open file ',filename,' for input'
call psb_abort(ctxt)
stop
else
write(psb_err_unit,*) 'Opened file ',trim(filename),' for input'
end if
else
inp_unit=psb_inp_unit
end if
! read input parameters
call read_data(mtrx,inp_unit)
call read_data(rhs,inp_unit)
call read_data(filefmt,inp_unit)
call read_data(choice,inp_unit)
call read_data(itmax,inp_unit)
call read_data(tol,inp_unit)
if (inp_unit /= psb_inp_unit) then
close(inp_unit)
end if
end if
call psb_bcast(ctxt,mtrx)
call psb_bcast(ctxt,rhs)
call psb_bcast(ctxt,filefmt)
call psb_bcast(ctxt,choice)
call psb_bcast(ctxt,itmax)
call psb_bcast(ctxt,tol)
end subroutine get_parms
end program amg_cexample_ml
@@ -0,0 +1,350 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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.
!
!
! File: amg_dexample_1lev.f90
!
! This sample program solves a linear system by using BiCGStab preconditioned by
! RAS with overlap 2 and ILU(0) on the local blocks, as explained in Section 4.1
! of the AMG4PSBLAS User's and Reference Guide.
!
! The matrix and the rhs are read from files (if an rhs is not available, the
! unit rhs is set).
!
program amg_dexample_1lev
use psb_base_mod
use amg_prec_mod
use psb_krylov_mod
use psb_util_mod
use data_input
implicit none
! input parameters
character(len=40) :: mtrx_file, rhs_file
character(len=2) :: filefmt
! sparse matrices
type(psb_dspmat_type) :: A, aux_A
! descriptor of sparse matrices
type(psb_desc_type):: desc_A
! preconditioner
type(amg_dprec_type) :: P
! right-hand side, solution and residual vectors
type(psb_d_vect_type) :: b, x, r
real(psb_dpk_), allocatable , save :: x_glob(:), r_glob(:)
real(psb_dpk_), allocatable, target :: aux_b(:,:)
real(psb_dpk_), pointer :: b_glob(:)
! solver and preconditioner parameters
real(psb_dpk_) :: tol, err
integer :: itmax, iter, istop
integer :: nlev
! parallel environment parameters
type(psb_ctxt_type) :: ctxt
integer :: iam, np
! other variables
integer :: i,info,j,m_problem
integer(psb_epk_) :: amatsize, precsize, descsize
integer :: ierr, ircode
real(psb_dpk_) :: resmx, resmxp
real(psb_dpk_) :: t1, t2, tprec
character(len=20) :: name, kmethod
integer, parameter :: iunit=12
! initialize the parallel environment
call psb_init(ctxt)
call psb_info(ctxt,iam,np)
if (iam < 0) then
! This should not happen, but just in case
call psb_exit(ctxt)
stop
endif
name='amg_dexample_ml'
if(psb_get_errstatus() /= 0) goto 9999
info=psb_success_
call psb_set_errverbosity(2)
!
! Hello world
!
if (iam == psb_root_) then
write(*,*) 'Welcome to AMG4PSBLAS version: ',amg_version_string_
write(*,*) 'This is the ',trim(name),' sample program'
end if
! get parameters
call get_parms(ctxt,mtrx_file,rhs_file,filefmt,itmax,tol)
call psb_barrier(ctxt)
t1 = psb_wtime()
! read and assemble the matrix A and the right-hand side b
! using PSBLAS routines for sparse matrix / vector management
if (iam == psb_root_) then
select case(psb_toupper(filefmt))
case('MM')
! For Matrix Market we have an input file for the matrix
! and an (optional) second file for the RHS.
call mm_mat_read(aux_a,info,iunit=iunit,filename=mtrx_file)
if (info == psb_success_) then
if (rhs_file /= 'NONE') then
call mm_array_read(aux_b,info,iunit=iunit,filename=rhs_file)
end if
end if
case ('HB')
! For Harwell-Boeing we have a single file which may or may not
! contain an RHS.
call hb_read(aux_a,info,iunit=iunit,b=aux_b,filename=mtrx_file)
case default
info = -1
write(0,*) 'Wrong choice for fileformat ', filefmt
end select
if (info /= psb_success_) then
write(0,*) 'Error while reading input matrix '
call psb_abort(ctxt)
end if
m_problem = aux_a%get_nrows()
call psb_bcast(ctxt,m_problem)
! At this point aux_b may still be unallocated
if (psb_size(aux_b,1) == m_problem) then
! if any rhs were present, broadcast the first one
write(0,'("Ok, got an rhs ")')
b_glob =>aux_b(:,1)
else
write(*,'("Generating an rhs...")')
write(*,'(" ")')
call psb_realloc(m_problem,1,aux_b,ircode)
if (ircode /= 0) then
call psb_errpush(psb_err_alloc_dealloc_,name)
goto 9999
endif
b_glob => aux_b(:,1)
do i=1, m_problem
b_glob(i) = 1.d0
enddo
endif
else
call psb_bcast(ctxt,m_problem)
end if
call psb_barrier(ctxt)
if (iam == psb_root_) write(*,'("Partition type: block")')
call psb_matdist(aux_A, A, ctxt, desc_A,info,parts=part_block)
call psb_scatter(b_glob,b,desc_a,info,root=psb_root_)
t2 = psb_wtime() - t1
call psb_amx(ctxt, t2)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Time to read and partition matrix : ",es12.5)')t2
write(*,'(" ")')
end if
! START SETTING PARAMETER
! set RAS
call P%init(ctxt,'AS',info)
! set number of overlaps
call P%set('SUB_OVR',2,info)
! build the preconditioner
t1 = psb_wtime()
call P%build(A,desc_A,info)
tprec = psb_wtime()-t1
call psb_amx(ctxt, tprec)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,a_err='amg_precbld')
goto 9999
end if
! set the initial guess
call psb_geall(x,desc_A,info)
call x%zero()
call psb_geasb(x,desc_A,info)
! solve Ax=b with preconditioned Krylov method: BiCGSTAB
kmethod = 'BiCGSTAB'
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_krylov(kmethod,A,P,b,x,tol,desc_A,info,itmax,iter,err,istop=2)
t2 = psb_wtime() - t1
call psb_amx(ctxt,t2)
call psb_geasb(r,desc_A,info,scratch=.true.)
call psb_geaxpby(done,b,dzero,r,desc_A,info)
call psb_spmm(-done,A,x,done,r,desc_A,info)
resmx = psb_genrm2(r,desc_A,info)
resmxp = psb_geamax(r,desc_A,info)
amatsize = a%sizeof()
descsize = desc_a%sizeof()
precsize = p%sizeof()
call psb_sum(ctxt,amatsize)
call psb_sum(ctxt,descsize)
call psb_sum(ctxt,precsize)
call P%descr(info)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Matrix: ",A)')mtrx_file
write(*,'("Computed solution on ",i8," processors")')np
write(*,'("Krylov method : ",a)') kmethod
write(*,'("Iterations to convergence : ",i6)')iter
write(*,'("Error estimate on exit : ",es12.5)')err
write(*,'("Time to build prec. : ",es12.5)')tprec
write(*,'("Time to solve system : ",es12.5)')t2
write(*,'("Time per iteration : ",es12.5)')t2/(iter)
write(*,'("Total time : ",es12.5)')t2+tprec
write(*,'("Residual 2-norm : ",es12.5)')resmx
write(*,'("Residual inf-norm : ",es12.5)')resmxp
write(*,'("Total memory occupation for A : ",i12)')amatsize
write(*,'("Total memory occupation for DESC_A : ",i12)')descsize
write(*,'("Total memory occupation for PREC : ",i12)')precsize
end if
call psb_gather(x_glob,x,desc_a,info,root=psb_root_)
if (info == psb_success_) &
& call psb_gather(r_glob,r,desc_a,info,root=psb_root_)
if (info /= psb_success_) goto 9999
if (iam == psb_root_) then
write(0,'(" ")')
write(0,'("Saving x on file")')
write(20,*) 'matrix: ',mtrx_file
write(20,*) 'computed solution on ',np,' processor(s).'
write(20,*) 'iterations to convergence: ',iter
write(20,*) 'error estimate (infinity norm) on exit:', &
& ' ||r||/(||a||||x||+||b||) = ',err
write(20,*) 'max residual = ',resmx, resmxp
write(20,'(a8,4(2x,a20))') 'I','X(I)','R(I)','B(I)'
do i=1,m_problem
write(20,998) i,x_glob(i),r_glob(i),b_glob(i)
enddo
end if
998 format(i8,4(2x,g20.14))
993 format(i6,4(1x,e12.6))
! deallocate the data structures
call psb_gefree(b, desc_A,info)
call psb_gefree(x, desc_A,info)
call psb_spfree(A, desc_A,info)
call P%free(info)
call psb_cdfree(desc_A,info)
call psb_exit(ctxt)
stop
9999 continue
call psb_error(ctxt)
contains
!
! get parameters from standard input
!
subroutine get_parms(ctxt,mtrx,rhs,filefmt,itmax,tol)
implicit none
type(psb_ctxt_type) :: ctxt
integer :: itmax
real(psb_dpk_) :: tol
character(len=*) :: mtrx, rhs,filefmt
integer :: iam, np, inp_unit
character(len=1024) :: filename
call psb_info(ctxt,iam,np)
if (iam == psb_root_) then
if (command_argument_count()>0) then
call get_command_argument(1,filename)
inp_unit = 30
open(inp_unit,file=filename,action='read',iostat=info)
if (info /= 0) then
write(psb_err_unit,*) 'Could not open file ',filename,' for input'
call psb_abort(ctxt)
stop
else
write(psb_err_unit,*) 'Opened file ',trim(filename),' for input'
end if
else
inp_unit=psb_inp_unit
end if
! read input parameters
call read_data(mtrx,inp_unit)
call read_data(rhs,inp_unit)
call read_data(filefmt,inp_unit)
call read_data(itmax,inp_unit)
call read_data(tol,inp_unit)
if (inp_unit /= psb_inp_unit) then
close(inp_unit)
end if
end if
call psb_bcast(ctxt,mtrx)
call psb_bcast(ctxt,rhs)
call psb_bcast(ctxt,filefmt)
call psb_bcast(ctxt,itmax)
call psb_bcast(ctxt,tol)
end subroutine get_parms
end program amg_dexample_1lev
+401
View File
@@ -0,0 +1,401 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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.
!
!
! File: amg_dexample_ml.f90
!
! This sample program solves a linear system by using CG coupled with
! one of the following multi-level preconditioner, as explained in Section 4.1
! of the AMG4PSBLAS User's and Reference Guide:
!
! - choice = 1, the default multi-level preconditioner solver, i.e.,
! V-cycle with decoupled smoothed aggregation, 1 hybrid forward/backward
! GS sweep as pre/post-smoother and UMFPACK as coarsest-level
! solver (Sec. 4.1, Listing 1)
!
! - choice = 2, a V-cycle preconditioner with 1 block-Jacobi sweep
! (with ILU(0) on the blocks) as pre- and post-smoother, and 8 block-Jacobi
! sweeps (with ILU(0) on the blocks) as coarsest-level solver (Sec. 4.1, Listing 2)
!
! - choice = 3, W-cycle preconditioner based on the coupled aggregation relying on matching,
! with maximum size of aggregates equal to 8 and smoothed prolongators,
! 2 hybrid forward/backward GS sweeps as pre/post-smoother, a distributed coarsest
! matrix, and preconditioned Flexible Conjugate Gradient as coarsest-level solver
! (Sec. 4.1, Listing 3)
!
! The matrix and the rhs are read from files (if an rhs is not available, the
! unit rhs is set).
!
program amg_dexample_ml
use psb_base_mod
use amg_prec_mod
use psb_krylov_mod
use psb_util_mod
use data_input
implicit none
! input file parameters
character(len=40) :: mtrx_file, rhs_file
character(len=2) :: filefmt
! sparse matrices
type(psb_dspmat_type) :: A, aux_A
! descriptor of sparse matrices
type(psb_desc_type):: desc_A
! preconditioner
type(amg_dprec_type) :: P
! right-hand side, solution and residual vectors
type(psb_d_vect_type) :: b, x, r
real(psb_dpk_), allocatable , save :: x_glob(:), r_glob(:)
real(psb_dpk_), allocatable, target :: aux_b(:,:)
real(psb_dpk_), pointer :: b_glob(:)
! solver and preconditioner parameters
real(psb_dpk_) :: tol, err
integer :: itmax, iter, istop
integer :: nlev
! parallel environment parameters
type(psb_ctxt_type) :: ctxt
integer :: iam, np
! other variables
integer :: choice
integer :: i,info,j,m_problem
integer(psb_epk_) :: amatsize, precsize, descsize
integer :: ierr, ircode
real(psb_dpk_) :: resmx, resmxp
real(psb_dpk_) :: t1, t2, tprec
character(len=20) :: name, kmethod
integer, parameter :: iunit=12
! initialize the parallel environment
call psb_init(ctxt)
call psb_info(ctxt,iam,np)
if (iam < 0) then
! This should not happen, but just in case
call psb_exit(ctxt)
stop
endif
name='amg_dexample_ml'
if(psb_get_errstatus() /= 0) goto 9999
info=psb_success_
call psb_set_errverbosity(2)
!
! Hello world
!
if (iam == psb_root_) then
write(*,*) 'Welcome to AMG4PSBLAS version: ',amg_version_string_
write(*,*) 'This is the ',trim(name),' sample program'
end if
! get parameters
call get_parms(ctxt,mtrx_file,rhs_file,filefmt,choice,itmax,tol)
call psb_barrier(ctxt)
t1 = psb_wtime()
! read and assemble the matrix A and the right-hand side b
! using PSBLAS routines for sparse matrix / vector management
if (iam == psb_root_) then
select case(psb_toupper(filefmt))
case('MM')
! For Matrix Market we have an input file for the matrix
! and an (optional) second file for the RHS.
call mm_mat_read(aux_a,info,iunit=iunit,filename=mtrx_file)
if (info == psb_success_) then
if (rhs_file /= 'NONE') then
call mm_array_read(aux_b,info,iunit=iunit,filename=rhs_file)
end if
end if
case ('HB')
! For Harwell-Boeing we have a single file which may or may not
! contain an RHS.
call hb_read(aux_a,info,iunit=iunit,b=aux_b,filename=mtrx_file)
case default
info = -1
write(0,*) 'Wrong choice for fileformat ', filefmt
end select
if (info /= psb_success_) then
write(0,*) 'Error while reading input matrix '
call psb_abort(ctxt)
end if
m_problem = aux_a%get_nrows()
call psb_bcast(ctxt,m_problem)
! At this point aux_b may still be unallocated
if (psb_size(aux_b,1) == m_problem) then
! if any rhs were present, broadcast the first one
write(0,'("Ok, got an rhs ")')
b_glob =>aux_b(:,1)
else
write(*,'("Generating an rhs...")')
write(*,'(" ")')
call psb_realloc(m_problem,1,aux_b,ircode)
if (ircode /= 0) then
call psb_errpush(psb_err_alloc_dealloc_,name)
goto 9999
endif
b_glob => aux_b(:,1)
do i=1, m_problem
b_glob(i) = 1.d0
enddo
endif
else
call psb_bcast(ctxt,m_problem)
end if
call psb_barrier(ctxt)
if (iam == psb_root_) write(*,'("Partition type: block")')
call psb_matdist(aux_A, A, ctxt, desc_A,info,parts=part_block)
call psb_scatter(b_glob,b,desc_a,info,root=psb_root_)
t2 = psb_wtime() - t1
call psb_amx(ctxt, t2)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Time to read and partition matrix : ",es12.5)')t2
write(*,'(" ")')
end if
select case(choice)
case(1)
! initialize the default multi-level preconditioner, i.e. V-cycle
! with decoupled smoothed aggregation, 1 hybrid forward/backward
! GS sweep as pre/post-smoother and UMFPACK as coarsest-level
! solver
call P%init(ctxt,'ML',info)
kmethod = 'CG'
case(2)
! initialize a V-cycle preconditioner with 1 block-Jacobi sweep (with
! ILU(0) on the blocks) as pre- and post-smoother, and 8 block-Jacobi
! sweeps (with ILU(0) on the blocks) as coarsest-level solver
call P%init(ctxt,'ML',info)
call P%set('SMOOTHER_TYPE','BJAC',info)
call P%set('COARSE_SOLVE','BJAC',info)
call P%set('COARSE_SWEEPS',8,info)
kmethod = 'CG'
case(3)
! initialize a W-cycle preconditioner based on the coupled aggregation relying on matching,
! with maximum size of aggregates equal to 8 and smoothed prolongators,
! 2 hybrid forward/backward GS sweeps as pre/post-smoother, a distributed coarsest
! matrix, and preconditioned Flexible Conjugate Gradient as coarsest-level solver
call P%init(ctxt,'ML',info)
call P%set('PAR_AGGR_ALG','COUPLED',info)
call P%set('AGGR_TYPE','MATCHBOXP',info)
call P%set('AGGR_SIZE',8,info)
call P%set('ML_CYCLE','WCYCLE',info)
call P%set('SMOOTHER_SWEEPS',2,info)
call P%set('COARSE_SOLVE','KRM',info)
kmethod = 'CG'
end select
! build the preconditioner
call psb_barrier(ctxt)
t1 = psb_wtime()
! build the preconditioner
call P%hierarchy_build(A,desc_A,info)
call P%smoothers_build(A,desc_A,info)
tprec = psb_wtime()-t1
call psb_amx(ctxt, tprec)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,a_err='amg_precbld')
goto 9999
end if
! set the initial guess
call psb_geall(x,desc_A,info)
call x%zero()
call psb_geasb(x,desc_A,info)
! solve Ax=b with preconditioned CG
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_krylov(kmethod,A,P,b,x,tol,desc_A,info,itmax,iter,err,itrace=1,istop=2)
t2 = psb_wtime() - t1
call psb_amx(ctxt,t2)
call psb_geasb(r,desc_A,info,scratch=.true.)
call psb_geaxpby(done,b,dzero,r,desc_A,info)
call psb_spmm(-done,A,x,done,r,desc_A,info)
resmx = psb_genrm2(r,desc_A,info)
resmxp = psb_geamax(r,desc_A,info)
amatsize = a%sizeof()
descsize = desc_a%sizeof()
precsize = p%sizeof()
call psb_sum(ctxt,amatsize)
call psb_sum(ctxt,descsize)
call psb_sum(ctxt,precsize)
call P%descr(info)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Matrix: ",A)')mtrx_file
write(*,'("Computed solution on ",i8," processors")')np
write(*,'("Krylov method : ",a)') kmethod
write(*,'("Iterations to convergence : ",i6)')iter
write(*,'("Error estimate on exit : ",es12.5)')err
write(*,'("Time to build prec. : ",es12.5)')tprec
write(*,'("Time to solve system : ",es12.5)')t2
write(*,'("Time per iteration : ",es12.5)')t2/(iter)
write(*,'("Total time : ",es12.5)')t2+tprec
write(*,'("Residual 2-norm : ",es12.5)')resmx
write(*,'("Residual inf-norm : ",es12.5)')resmxp
write(*,'("Total memory occupation for A : ",i12)')amatsize
write(*,'("Total memory occupation for DESC_A : ",i12)')descsize
write(*,'("Total memory occupation for PREC : ",i12)')precsize
end if
call psb_gather(x_glob,x,desc_a,info,root=psb_root_)
if (info == psb_success_) &
& call psb_gather(r_glob,r,desc_a,info,root=psb_root_)
if (info /= psb_success_) goto 9999
if (iam == psb_root_) then
write(0,'(" ")')
write(0,'("Saving x on file")')
write(20,*) 'matrix: ',mtrx_file
write(20,*) 'computed solution on ',np,' processors.'
write(20,*) 'iterations to convergence: ',iter
write(20,*) 'error estimate (infinity norm) on exit:', &
& ' ||r||/(||a||||x||+||b||) = ',err
write(20,*) 'max residual = ',resmx, resmxp
write(20,'(a8,4(2x,a20))') 'I','X(I)','R(I)','B(I)'
do i=1,m_problem
write(20,998) i,x_glob(i),r_glob(i),b_glob(i)
enddo
end if
998 format(i8,4(2x,g20.14))
993 format(i6,4(1x,e12.6))
! deallocate the data structures
call psb_gefree(b, desc_A,info)
call psb_gefree(x, desc_A,info)
call psb_spfree(A, desc_A,info)
call P%free(info)
call psb_cdfree(desc_A,info)
call psb_exit(ctxt)
stop
9999 continue
call psb_error(ctxt)
contains
!
! get parameters from standard input
!
subroutine get_parms(ctxt,mtrx,rhs,filefmt,choice,itmax,tol)
implicit none
type(psb_ctxt_type) :: ctxt
integer :: choice, itmax
real(psb_dpk_) :: tol
character(len=*) :: mtrx, rhs,filefmt
integer :: iam, np, inp_unit
character(len=1024) :: filename
call psb_info(ctxt,iam,np)
if (iam == psb_root_) then
if (command_argument_count()>0) then
call get_command_argument(1,filename)
inp_unit = 30
open(inp_unit,file=filename,action='read',iostat=info)
if (info /= 0) then
write(psb_err_unit,*) 'Could not open file ',filename,' for input'
call psb_abort(ctxt)
stop
else
write(psb_err_unit,*) 'Opened file ',trim(filename),' for input'
end if
else
inp_unit=psb_inp_unit
end if
! read input parameters
call read_data(mtrx,inp_unit)
call read_data(rhs,inp_unit)
call read_data(filefmt,inp_unit)
call read_data(choice,inp_unit)
call read_data(itmax,inp_unit)
call read_data(tol,inp_unit)
if (inp_unit /= psb_inp_unit) then
close(inp_unit)
end if
end if
call psb_bcast(ctxt,mtrx)
call psb_bcast(ctxt,rhs)
call psb_bcast(ctxt,filefmt)
call psb_bcast(ctxt,choice)
call psb_bcast(ctxt,itmax)
call psb_bcast(ctxt,tol)
end subroutine get_parms
end program amg_dexample_ml
@@ -0,0 +1,350 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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.
!
!
! File: amg_sexample_1lev.f90
!
! This sample program solves a linear system by using BiCGStab preconditioned by
! RAS with overlap 2 and ILU(0) on the local blocks, as explained in Section 4.1
! of the AMG4PSBLAS User's and Reference Guide.
!
! The matrix and the rhs are read from files (if an rhs is not available, the
! unit rhs is set).
!
program amg_sexample_1lev
use psb_base_mod
use amg_prec_mod
use psb_krylov_mod
use psb_util_mod
use data_input
implicit none
! input parameters
character(len=40) :: mtrx_file, rhs_file
character(len=2) :: filefmt
! sparse matrices
type(psb_sspmat_type) :: A, aux_A
! descriptor of sparse matrices
type(psb_desc_type):: desc_A
! preconditioner
type(amg_sprec_type) :: P
! right-hand side, solution and residual vectors
type(psb_s_vect_type) :: b, x, r
real(psb_spk_), allocatable , save :: x_glob(:), r_glob(:)
real(psb_spk_), allocatable, target :: aux_b(:,:)
real(psb_spk_), pointer :: b_glob(:)
! solver and preconditioner parameters
real(psb_spk_) :: tol, err
integer :: itmax, iter, istop
integer :: nlev
! parallel environment parameters
type(psb_ctxt_type) :: ctxt
integer :: iam, np
! other variables
integer :: i,info,j,m_problem
integer(psb_epk_) :: amatsize, precsize, descsize
integer :: ierr, ircode
real(psb_spk_) :: resmx, resmxp
real(psb_dpk_) :: t1, t2, tprec
character(len=20) :: name, kmethod
integer, parameter :: iunit=12
! initialize the parallel environment
call psb_init(ctxt)
call psb_info(ctxt,iam,np)
if (iam < 0) then
! This should not happen, but just in case
call psb_exit(ctxt)
stop
endif
name='amg_sexample_ml'
if(psb_get_errstatus() /= 0) goto 9999
info=psb_success_
call psb_set_errverbosity(2)
!
! Hello world
!
if (iam == psb_root_) then
write(*,*) 'Welcome to AMG4PSBLAS version: ',amg_version_string_
write(*,*) 'This is the ',trim(name),' sample program'
end if
! get parameters
call get_parms(ctxt,mtrx_file,rhs_file,filefmt,itmax,tol)
call psb_barrier(ctxt)
t1 = psb_wtime()
! read and assemble the matrix A and the right-hand side b
! using PSBLAS routines for sparse matrix / vector management
if (iam == psb_root_) then
select case(psb_toupper(filefmt))
case('MM')
! For Matrix Market we have an input file for the matrix
! and an (optional) second file for the RHS.
call mm_mat_read(aux_a,info,iunit=iunit,filename=mtrx_file)
if (info == psb_success_) then
if (rhs_file /= 'NONE') then
call mm_array_read(aux_b,info,iunit=iunit,filename=rhs_file)
end if
end if
case ('HB')
! For Harwell-Boeing we have a single file which may or may not
! contain an RHS.
call hb_read(aux_a,info,iunit=iunit,b=aux_b,filename=mtrx_file)
case default
info = -1
write(0,*) 'Wrong choice for fileformat ', filefmt
end select
if (info /= psb_success_) then
write(0,*) 'Error while reading input matrix '
call psb_abort(ctxt)
end if
m_problem = aux_a%get_nrows()
call psb_bcast(ctxt,m_problem)
! At this point aux_b may still be unallocated
if (psb_size(aux_b,1) == m_problem) then
! if any rhs were present, broadcast the first one
write(0,'("Ok, got an rhs ")')
b_glob =>aux_b(:,1)
else
write(*,'("Generating an rhs...")')
write(*,'(" ")')
call psb_realloc(m_problem,1,aux_b,ircode)
if (ircode /= 0) then
call psb_errpush(psb_err_alloc_dealloc_,name)
goto 9999
endif
b_glob => aux_b(:,1)
do i=1, m_problem
b_glob(i) = 1.d0
enddo
endif
else
call psb_bcast(ctxt,m_problem)
end if
call psb_barrier(ctxt)
if (iam == psb_root_) write(*,'("Partition type: block")')
call psb_matdist(aux_A, A, ctxt, desc_A,info,parts=part_block)
call psb_scatter(b_glob,b,desc_a,info,root=psb_root_)
t2 = psb_wtime() - t1
call psb_amx(ctxt, t2)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Time to read and partition matrix : ",es12.5)')t2
write(*,'(" ")')
end if
! START SETTING PARAMETER
! set RAS
call P%init(ctxt,'AS',info)
! set number of overlaps
call P%set('SUB_OVR',2,info)
! build the preconditioner
t1 = psb_wtime()
call P%build(A,desc_A,info)
tprec = psb_wtime()-t1
call psb_amx(ctxt, tprec)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,a_err='amg_precbld')
goto 9999
end if
! set the initial guess
call psb_geall(x,desc_A,info)
call x%zero()
call psb_geasb(x,desc_A,info)
! solve Ax=b with preconditioned Krylov method: BiCGSTAB
kmethod = 'BiCGSTAB'
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_krylov(kmethod,A,P,b,x,tol,desc_A,info,itmax,iter,err,istop=2)
t2 = psb_wtime() - t1
call psb_amx(ctxt,t2)
call psb_geasb(r,desc_A,info,scratch=.true.)
call psb_geaxpby(sone,b,szero,r,desc_A,info)
call psb_spmm(-sone,A,x,sone,r,desc_A,info)
resmx = psb_genrm2(r,desc_A,info)
resmxp = psb_geamax(r,desc_A,info)
amatsize = a%sizeof()
descsize = desc_a%sizeof()
precsize = p%sizeof()
call psb_sum(ctxt,amatsize)
call psb_sum(ctxt,descsize)
call psb_sum(ctxt,precsize)
call P%descr(info)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Matrix: ",A)')mtrx_file
write(*,'("Computed solution on ",i8," processors")')np
write(*,'("Krylov method : ",a)') kmethod
write(*,'("Iterations to convergence : ",i6)')iter
write(*,'("Error estimate on exit : ",es12.5)')err
write(*,'("Time to build prec. : ",es12.5)')tprec
write(*,'("Time to solve system : ",es12.5)')t2
write(*,'("Time per iteration : ",es12.5)')t2/(iter)
write(*,'("Total time : ",es12.5)')t2+tprec
write(*,'("Residual 2-norm : ",es12.5)')resmx
write(*,'("Residual inf-norm : ",es12.5)')resmxp
write(*,'("Total memory occupation for A : ",i12)')amatsize
write(*,'("Total memory occupation for DESC_A : ",i12)')descsize
write(*,'("Total memory occupation for PREC : ",i12)')precsize
end if
call psb_gather(x_glob,x,desc_a,info,root=psb_root_)
if (info == psb_success_) &
& call psb_gather(r_glob,r,desc_a,info,root=psb_root_)
if (info /= psb_success_) goto 9999
if (iam == psb_root_) then
write(0,'(" ")')
write(0,'("Saving x on file")')
write(20,*) 'matrix: ',mtrx_file
write(20,*) 'computed solution on ',np,' processor(s).'
write(20,*) 'iterations to convergence: ',iter
write(20,*) 'error estimate (infinity norm) on exit:', &
& ' ||r||/(||a||||x||+||b||) = ',err
write(20,*) 'max residual = ',resmx, resmxp
write(20,'(a8,4(2x,a20))') 'I','X(I)','R(I)','B(I)'
do i=1,m_problem
write(20,998) i,x_glob(i),r_glob(i),b_glob(i)
enddo
end if
998 format(i8,4(2x,g20.14))
993 format(i6,4(1x,e12.6))
! deallocate the data structures
call psb_gefree(b, desc_A,info)
call psb_gefree(x, desc_A,info)
call psb_spfree(A, desc_A,info)
call P%free(info)
call psb_cdfree(desc_A,info)
call psb_exit(ctxt)
stop
9999 continue
call psb_error(ctxt)
contains
!
! get parameters from standard input
!
subroutine get_parms(ctxt,mtrx,rhs,filefmt,itmax,tol)
implicit none
type(psb_ctxt_type) :: ctxt
integer :: itmax
real(psb_spk_) :: tol
character(len=*) :: mtrx, rhs,filefmt
integer :: iam, np, inp_unit
character(len=1024) :: filename
call psb_info(ctxt,iam,np)
if (iam == psb_root_) then
if (command_argument_count()>0) then
call get_command_argument(1,filename)
inp_unit = 30
open(inp_unit,file=filename,action='read',iostat=info)
if (info /= 0) then
write(psb_err_unit,*) 'Could not open file ',filename,' for input'
call psb_abort(ctxt)
stop
else
write(psb_err_unit,*) 'Opened file ',trim(filename),' for input'
end if
else
inp_unit=psb_inp_unit
end if
! read input parameters
call read_data(mtrx,inp_unit)
call read_data(rhs,inp_unit)
call read_data(filefmt,inp_unit)
call read_data(itmax,inp_unit)
call read_data(tol,inp_unit)
if (inp_unit /= psb_inp_unit) then
close(inp_unit)
end if
end if
call psb_bcast(ctxt,mtrx)
call psb_bcast(ctxt,rhs)
call psb_bcast(ctxt,filefmt)
call psb_bcast(ctxt,itmax)
call psb_bcast(ctxt,tol)
end subroutine get_parms
end program amg_sexample_1lev
+401
View File
@@ -0,0 +1,401 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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.
!
!
! File: amg_sexample_ml.f90
!
! This sample program solves a linear system by using CG coupled with
! one of the following multi-level preconditioner, as explained in Section 4.1
! of the AMG4PSBLAS User's and Reference Guide:
!
! - choice = 1, the default multi-level preconditioner solver, i.e.,
! V-cycle with decoupled smoothed aggregation, 1 hybrid forward/backward
! GS sweep as pre/post-smoother and UMFPACK as coarsest-level
! solver (Sec. 4.1, Listing 1)
!
! - choice = 2, a V-cycle preconditioner with 1 block-Jacobi sweep
! (with ILU(0) on the blocks) as pre- and post-smoother, and 8 block-Jacobi
! sweeps (with ILU(0) on the blocks) as coarsest-level solver (Sec. 4.1, Listing 2)
!
! - choice = 3, W-cycle preconditioner based on the coupled aggregation relying on matching,
! with maximum size of aggregates equal to 8 and smoothed prolongators,
! 2 hybrid forward/backward GS sweeps as pre/post-smoother, a distributed coarsest
! matrix, and preconditioned Flexible Conjugate Gradient as coarsest-level solver
! (Sec. 4.1, Listing 3)
!
! The matrix and the rhs are read from files (if an rhs is not available, the
! unit rhs is set).
!
program amg_sexample_ml
use psb_base_mod
use amg_prec_mod
use psb_krylov_mod
use psb_util_mod
use data_input
implicit none
! input file parameters
character(len=40) :: mtrx_file, rhs_file
character(len=2) :: filefmt
! sparse matrices
type(psb_sspmat_type) :: A, aux_A
! descriptor of sparse matrices
type(psb_desc_type):: desc_A
! preconditioner
type(amg_sprec_type) :: P
! right-hand side, solution and residual vectors
type(psb_s_vect_type) :: b, x, r
real(psb_spk_), allocatable , save :: x_glob(:), r_glob(:)
real(psb_spk_), allocatable, target :: aux_b(:,:)
real(psb_spk_), pointer :: b_glob(:)
! solver and preconditioner parameters
real(psb_spk_) :: tol, err
integer :: itmax, iter, istop
integer :: nlev
! parallel environment parameters
type(psb_ctxt_type) :: ctxt
integer :: iam, np
! other variables
integer :: choice
integer :: i,info,j,m_problem
integer(psb_epk_) :: amatsize, precsize, descsize
integer :: ierr, ircode
real(psb_spk_) :: resmx, resmxp
real(psb_dpk_) :: t1, t2, tprec
character(len=20) :: name, kmethod
integer, parameter :: iunit=12
! initialize the parallel environment
call psb_init(ctxt)
call psb_info(ctxt,iam,np)
if (iam < 0) then
! This should not happen, but just in case
call psb_exit(ctxt)
stop
endif
name='amg_sexample_ml'
if(psb_get_errstatus() /= 0) goto 9999
info=psb_success_
call psb_set_errverbosity(2)
!
! Hello world
!
if (iam == psb_root_) then
write(*,*) 'Welcome to AMG4PSBLAS version: ',amg_version_string_
write(*,*) 'This is the ',trim(name),' sample program'
end if
! get parameters
call get_parms(ctxt,mtrx_file,rhs_file,filefmt,choice,itmax,tol)
call psb_barrier(ctxt)
t1 = psb_wtime()
! read and assemble the matrix A and the right-hand side b
! using PSBLAS routines for sparse matrix / vector management
if (iam == psb_root_) then
select case(psb_toupper(filefmt))
case('MM')
! For Matrix Market we have an input file for the matrix
! and an (optional) second file for the RHS.
call mm_mat_read(aux_a,info,iunit=iunit,filename=mtrx_file)
if (info == psb_success_) then
if (rhs_file /= 'NONE') then
call mm_array_read(aux_b,info,iunit=iunit,filename=rhs_file)
end if
end if
case ('HB')
! For Harwell-Boeing we have a single file which may or may not
! contain an RHS.
call hb_read(aux_a,info,iunit=iunit,b=aux_b,filename=mtrx_file)
case default
info = -1
write(0,*) 'Wrong choice for fileformat ', filefmt
end select
if (info /= psb_success_) then
write(0,*) 'Error while reading input matrix '
call psb_abort(ctxt)
end if
m_problem = aux_a%get_nrows()
call psb_bcast(ctxt,m_problem)
! At this point aux_b may still be unallocated
if (psb_size(aux_b,1) == m_problem) then
! if any rhs were present, broadcast the first one
write(0,'("Ok, got an rhs ")')
b_glob =>aux_b(:,1)
else
write(*,'("Generating an rhs...")')
write(*,'(" ")')
call psb_realloc(m_problem,1,aux_b,ircode)
if (ircode /= 0) then
call psb_errpush(psb_err_alloc_dealloc_,name)
goto 9999
endif
b_glob => aux_b(:,1)
do i=1, m_problem
b_glob(i) = 1.d0
enddo
endif
else
call psb_bcast(ctxt,m_problem)
end if
call psb_barrier(ctxt)
if (iam == psb_root_) write(*,'("Partition type: block")')
call psb_matdist(aux_A, A, ctxt, desc_A,info,parts=part_block)
call psb_scatter(b_glob,b,desc_a,info,root=psb_root_)
t2 = psb_wtime() - t1
call psb_amx(ctxt, t2)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Time to read and partition matrix : ",es12.5)')t2
write(*,'(" ")')
end if
select case(choice)
case(1)
! initialize the default multi-level preconditioner, i.e. V-cycle
! with decoupled smoothed aggregation, 1 hybrid forward/backward
! GS sweep as pre/post-smoother and UMFPACK as coarsest-level
! solver
call P%init(ctxt,'ML',info)
kmethod = 'CG'
case(2)
! initialize a V-cycle preconditioner with 1 block-Jacobi sweep (with
! ILU(0) on the blocks) as pre- and post-smoother, and 8 block-Jacobi
! sweeps (with ILU(0) on the blocks) as coarsest-level solver
call P%init(ctxt,'ML',info)
call P%set('SMOOTHER_TYPE','BJAC',info)
call P%set('COARSE_SOLVE','BJAC',info)
call P%set('COARSE_SWEEPS',8,info)
kmethod = 'CG'
case(3)
! initialize a W-cycle preconditioner based on the coupled aggregation relying on matching,
! with maximum size of aggregates equal to 8 and smoothed prolongators,
! 2 hybrid forward/backward GS sweeps as pre/post-smoother, a distributed coarsest
! matrix, and preconditioned Flexible Conjugate Gradient as coarsest-level solver
call P%init(ctxt,'ML',info)
call P%set('PAR_AGGR_ALG','COUPLED',info)
call P%set('AGGR_TYPE','MATCHBOXP',info)
call P%set('AGGR_SIZE',8,info)
call P%set('ML_CYCLE','WCYCLE',info)
call P%set('SMOOTHER_SWEEPS',2,info)
call P%set('COARSE_SOLVE','KRM',info)
kmethod = 'CG'
end select
! build the preconditioner
call psb_barrier(ctxt)
t1 = psb_wtime()
! build the preconditioner
call P%hierarchy_build(A,desc_A,info)
call P%smoothers_build(A,desc_A,info)
tprec = psb_wtime()-t1
call psb_amx(ctxt, tprec)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,a_err='amg_precbld')
goto 9999
end if
! set the initial guess
call psb_geall(x,desc_A,info)
call x%zero()
call psb_geasb(x,desc_A,info)
! solve Ax=b with preconditioned CG
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_krylov(kmethod,A,P,b,x,tol,desc_A,info,itmax,iter,err,itrace=1,istop=2)
t2 = psb_wtime() - t1
call psb_amx(ctxt,t2)
call psb_geasb(r,desc_A,info,scratch=.true.)
call psb_geaxpby(sone,b,szero,r,desc_A,info)
call psb_spmm(-sone,A,x,sone,r,desc_A,info)
resmx = psb_genrm2(r,desc_A,info)
resmxp = psb_geamax(r,desc_A,info)
amatsize = a%sizeof()
descsize = desc_a%sizeof()
precsize = p%sizeof()
call psb_sum(ctxt,amatsize)
call psb_sum(ctxt,descsize)
call psb_sum(ctxt,precsize)
call P%descr(info)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Matrix: ",A)')mtrx_file
write(*,'("Computed solution on ",i8," processors")')np
write(*,'("Krylov method : ",a)') kmethod
write(*,'("Iterations to convergence : ",i6)')iter
write(*,'("Error estimate on exit : ",es12.5)')err
write(*,'("Time to build prec. : ",es12.5)')tprec
write(*,'("Time to solve system : ",es12.5)')t2
write(*,'("Time per iteration : ",es12.5)')t2/(iter)
write(*,'("Total time : ",es12.5)')t2+tprec
write(*,'("Residual 2-norm : ",es12.5)')resmx
write(*,'("Residual inf-norm : ",es12.5)')resmxp
write(*,'("Total memory occupation for A : ",i12)')amatsize
write(*,'("Total memory occupation for DESC_A : ",i12)')descsize
write(*,'("Total memory occupation for PREC : ",i12)')precsize
end if
call psb_gather(x_glob,x,desc_a,info,root=psb_root_)
if (info == psb_success_) &
& call psb_gather(r_glob,r,desc_a,info,root=psb_root_)
if (info /= psb_success_) goto 9999
if (iam == psb_root_) then
write(0,'(" ")')
write(0,'("Saving x on file")')
write(20,*) 'matrix: ',mtrx_file
write(20,*) 'computed solution on ',np,' processors.'
write(20,*) 'iterations to convergence: ',iter
write(20,*) 'error estimate (infinity norm) on exit:', &
& ' ||r||/(||a||||x||+||b||) = ',err
write(20,*) 'max residual = ',resmx, resmxp
write(20,'(a8,4(2x,a20))') 'I','X(I)','R(I)','B(I)'
do i=1,m_problem
write(20,998) i,x_glob(i),r_glob(i),b_glob(i)
enddo
end if
998 format(i8,4(2x,g20.14))
993 format(i6,4(1x,e12.6))
! deallocate the data structures
call psb_gefree(b, desc_A,info)
call psb_gefree(x, desc_A,info)
call psb_spfree(A, desc_A,info)
call P%free(info)
call psb_cdfree(desc_A,info)
call psb_exit(ctxt)
stop
9999 continue
call psb_error(ctxt)
contains
!
! get parameters from standard input
!
subroutine get_parms(ctxt,mtrx,rhs,filefmt,choice,itmax,tol)
implicit none
type(psb_ctxt_type) :: ctxt
integer :: choice, itmax
real(psb_spk_) :: tol
character(len=*) :: mtrx, rhs,filefmt
integer :: iam, np, inp_unit
character(len=1024) :: filename
call psb_info(ctxt,iam,np)
if (iam == psb_root_) then
if (command_argument_count()>0) then
call get_command_argument(1,filename)
inp_unit = 30
open(inp_unit,file=filename,action='read',iostat=info)
if (info /= 0) then
write(psb_err_unit,*) 'Could not open file ',filename,' for input'
call psb_abort(ctxt)
stop
else
write(psb_err_unit,*) 'Opened file ',trim(filename),' for input'
end if
else
inp_unit=psb_inp_unit
end if
! read input parameters
call read_data(mtrx,inp_unit)
call read_data(rhs,inp_unit)
call read_data(filefmt,inp_unit)
call read_data(choice,inp_unit)
call read_data(itmax,inp_unit)
call read_data(tol,inp_unit)
if (inp_unit /= psb_inp_unit) then
close(inp_unit)
end if
end if
call psb_bcast(ctxt,mtrx)
call psb_bcast(ctxt,rhs)
call psb_bcast(ctxt,filefmt)
call psb_bcast(ctxt,choice)
call psb_bcast(ctxt,itmax)
call psb_bcast(ctxt,tol)
end subroutine get_parms
end program amg_sexample_ml
@@ -0,0 +1,350 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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.
!
!
! File: amg_zexample_1lev.f90
!
! This sample program solves a linear system by using BiCGStab preconditioned by
! RAS with overlap 2 and ILU(0) on the local blocks, as explained in Section 4.1
! of the AMG4PSBLAS User's and Reference Guide.
!
! The matrix and the rhs are read from files (if an rhs is not available, the
! unit rhs is set).
!
program amg_zexample_1lev
use psb_base_mod
use amg_prec_mod
use psb_krylov_mod
use psb_util_mod
use data_input
implicit none
! input parameters
character(len=40) :: mtrx_file, rhs_file
character(len=2) :: filefmt
! sparse matrices
type(psb_zspmat_type) :: A, aux_A
! descriptor of sparse matrices
type(psb_desc_type):: desc_A
! preconditioner
type(amg_zprec_type) :: P
! right-hand side, solution and residual vectors
type(psb_z_vect_type) :: b, x, r
complex(psb_dpk_), allocatable , save :: x_glob(:), r_glob(:)
complex(psb_dpk_), allocatable, target :: aux_b(:,:)
complex(psb_dpk_), pointer :: b_glob(:)
! solver and preconditioner parameters
real(psb_dpk_) :: tol, err
integer :: itmax, iter, istop
integer :: nlev
! parallel environment parameters
type(psb_ctxt_type) :: ctxt
integer :: iam, np
! other variables
integer :: i,info,j,m_problem
integer(psb_epk_) :: amatsize, precsize, descsize
integer :: ierr, ircode
real(psb_dpk_) :: resmx, resmxp
real(psb_dpk_) :: t1, t2, tprec
character(len=20) :: name, kmethod
integer, parameter :: iunit=12
! initialize the parallel environment
call psb_init(ctxt)
call psb_info(ctxt,iam,np)
if (iam < 0) then
! This should not happen, but just in case
call psb_exit(ctxt)
stop
endif
name='amg_zexample_ml'
if(psb_get_errstatus() /= 0) goto 9999
info=psb_success_
call psb_set_errverbosity(2)
!
! Hello world
!
if (iam == psb_root_) then
write(*,*) 'Welcome to AMG4PSBLAS version: ',amg_version_string_
write(*,*) 'This is the ',trim(name),' sample program'
end if
! get parameters
call get_parms(ctxt,mtrx_file,rhs_file,filefmt,itmax,tol)
call psb_barrier(ctxt)
t1 = psb_wtime()
! read and assemble the matrix A and the right-hand side b
! using PSBLAS routines for sparse matrix / vector management
if (iam == psb_root_) then
select case(psb_toupper(filefmt))
case('MM')
! For Matrix Market we have an input file for the matrix
! and an (optional) second file for the RHS.
call mm_mat_read(aux_a,info,iunit=iunit,filename=mtrx_file)
if (info == psb_success_) then
if (rhs_file /= 'NONE') then
call mm_array_read(aux_b,info,iunit=iunit,filename=rhs_file)
end if
end if
case ('HB')
! For Harwell-Boeing we have a single file which may or may not
! contain an RHS.
call hb_read(aux_a,info,iunit=iunit,b=aux_b,filename=mtrx_file)
case default
info = -1
write(0,*) 'Wrong choice for fileformat ', filefmt
end select
if (info /= psb_success_) then
write(0,*) 'Error while reading input matrix '
call psb_abort(ctxt)
end if
m_problem = aux_a%get_nrows()
call psb_bcast(ctxt,m_problem)
! At this point aux_b may still be unallocated
if (psb_size(aux_b,1) == m_problem) then
! if any rhs were present, broadcast the first one
write(0,'("Ok, got an rhs ")')
b_glob =>aux_b(:,1)
else
write(*,'("Generating an rhs...")')
write(*,'(" ")')
call psb_realloc(m_problem,1,aux_b,ircode)
if (ircode /= 0) then
call psb_errpush(psb_err_alloc_dealloc_,name)
goto 9999
endif
b_glob => aux_b(:,1)
do i=1, m_problem
b_glob(i) = 1.d0
enddo
endif
else
call psb_bcast(ctxt,m_problem)
end if
call psb_barrier(ctxt)
if (iam == psb_root_) write(*,'("Partition type: block")')
call psb_matdist(aux_A, A, ctxt, desc_A,info,parts=part_block)
call psb_scatter(b_glob,b,desc_a,info,root=psb_root_)
t2 = psb_wtime() - t1
call psb_amx(ctxt, t2)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Time to read and partition matrix : ",es12.5)')t2
write(*,'(" ")')
end if
! START SETTING PARAMETER
! set RAS
call P%init(ctxt,'AS',info)
! set number of overlaps
call P%set('SUB_OVR',2,info)
! build the preconditioner
t1 = psb_wtime()
call P%build(A,desc_A,info)
tprec = psb_wtime()-t1
call psb_amx(ctxt, tprec)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,a_err='amg_precbld')
goto 9999
end if
! set the initial guess
call psb_geall(x,desc_A,info)
call x%zero()
call psb_geasb(x,desc_A,info)
! solve Ax=b with preconditioned Krylov method: BiCGSTAB
kmethod = 'BiCGSTAB'
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_krylov(kmethod,A,P,b,x,tol,desc_A,info,itmax,iter,err,istop=2)
t2 = psb_wtime() - t1
call psb_amx(ctxt,t2)
call psb_geasb(r,desc_A,info,scratch=.true.)
call psb_geaxpby(zone,b,zzero,r,desc_A,info)
call psb_spmm(-zone,A,x,zone,r,desc_A,info)
resmx = psb_genrm2(r,desc_A,info)
resmxp = psb_geamax(r,desc_A,info)
amatsize = a%sizeof()
descsize = desc_a%sizeof()
precsize = p%sizeof()
call psb_sum(ctxt,amatsize)
call psb_sum(ctxt,descsize)
call psb_sum(ctxt,precsize)
call P%descr(info)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Matrix: ",A)')mtrx_file
write(*,'("Computed solution on ",i8," processors")')np
write(*,'("Krylov method : ",a)') kmethod
write(*,'("Iterations to convergence : ",i6)')iter
write(*,'("Error estimate on exit : ",es12.5)')err
write(*,'("Time to build prec. : ",es12.5)')tprec
write(*,'("Time to solve system : ",es12.5)')t2
write(*,'("Time per iteration : ",es12.5)')t2/(iter)
write(*,'("Total time : ",es12.5)')t2+tprec
write(*,'("Residual 2-norm : ",es12.5)')resmx
write(*,'("Residual inf-norm : ",es12.5)')resmxp
write(*,'("Total memory occupation for A : ",i12)')amatsize
write(*,'("Total memory occupation for DESC_A : ",i12)')descsize
write(*,'("Total memory occupation for PREC : ",i12)')precsize
end if
call psb_gather(x_glob,x,desc_a,info,root=psb_root_)
if (info == psb_success_) &
& call psb_gather(r_glob,r,desc_a,info,root=psb_root_)
if (info /= psb_success_) goto 9999
if (iam == psb_root_) then
write(0,'(" ")')
write(0,'("Saving x on file")')
write(20,*) 'matrix: ',mtrx_file
write(20,*) 'computed solution on ',np,' processor(s).'
write(20,*) 'iterations to convergence: ',iter
write(20,*) 'error estimate (infinity norm) on exit:', &
& ' ||r||/(||a||||x||+||b||) = ',err
write(20,*) 'max residual = ',resmx, resmxp
write(20,'(a8,4(2x,a20))') 'I','X(I)','R(I)','B(I)'
do i=1,m_problem
write(20,998) i,x_glob(i),r_glob(i),b_glob(i)
enddo
end if
998 format(i8,4(2x,g20.14))
993 format(i6,4(1x,e12.6))
! deallocate the data structures
call psb_gefree(b, desc_A,info)
call psb_gefree(x, desc_A,info)
call psb_spfree(A, desc_A,info)
call P%free(info)
call psb_cdfree(desc_A,info)
call psb_exit(ctxt)
stop
9999 continue
call psb_error(ctxt)
contains
!
! get parameters from standard input
!
subroutine get_parms(ctxt,mtrx,rhs,filefmt,itmax,tol)
implicit none
type(psb_ctxt_type) :: ctxt
integer :: itmax
real(psb_dpk_) :: tol
character(len=*) :: mtrx, rhs,filefmt
integer :: iam, np, inp_unit
character(len=1024) :: filename
call psb_info(ctxt,iam,np)
if (iam == psb_root_) then
if (command_argument_count()>0) then
call get_command_argument(1,filename)
inp_unit = 30
open(inp_unit,file=filename,action='read',iostat=info)
if (info /= 0) then
write(psb_err_unit,*) 'Could not open file ',filename,' for input'
call psb_abort(ctxt)
stop
else
write(psb_err_unit,*) 'Opened file ',trim(filename),' for input'
end if
else
inp_unit=psb_inp_unit
end if
! read input parameters
call read_data(mtrx,inp_unit)
call read_data(rhs,inp_unit)
call read_data(filefmt,inp_unit)
call read_data(itmax,inp_unit)
call read_data(tol,inp_unit)
if (inp_unit /= psb_inp_unit) then
close(inp_unit)
end if
end if
call psb_bcast(ctxt,mtrx)
call psb_bcast(ctxt,rhs)
call psb_bcast(ctxt,filefmt)
call psb_bcast(ctxt,itmax)
call psb_bcast(ctxt,tol)
end subroutine get_parms
end program amg_zexample_1lev
+401
View File
@@ -0,0 +1,401 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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.
!
!
! File: amg_zexample_ml.f90
!
! This sample program solves a linear system by using CG coupled with
! one of the following multi-level preconditioner, as explained in Section 4.1
! of the AMG4PSBLAS User's and Reference Guide:
!
! - choice = 1, the default multi-level preconditioner solver, i.e.,
! V-cycle with decoupled smoothed aggregation, 1 hybrid forward/backward
! GS sweep as pre/post-smoother and UMFPACK as coarsest-level
! solver (Sec. 4.1, Listing 1)
!
! - choice = 2, a V-cycle preconditioner with 1 block-Jacobi sweep
! (with ILU(0) on the blocks) as pre- and post-smoother, and 8 block-Jacobi
! sweeps (with ILU(0) on the blocks) as coarsest-level solver (Sec. 4.1, Listing 2)
!
! - choice = 3, W-cycle preconditioner based on the coupled aggregation relying on matching,
! with maximum size of aggregates equal to 8 and smoothed prolongators,
! 2 hybrid forward/backward GS sweeps as pre/post-smoother, a distributed coarsest
! matrix, and preconditioned Flexible Conjugate Gradient as coarsest-level solver
! (Sec. 4.1, Listing 3)
!
! The matrix and the rhs are read from files (if an rhs is not available, the
! unit rhs is set).
!
program amg_zexample_ml
use psb_base_mod
use amg_prec_mod
use psb_krylov_mod
use psb_util_mod
use data_input
implicit none
! input file parameters
character(len=40) :: mtrx_file, rhs_file
character(len=2) :: filefmt
! sparse matrices
type(psb_zspmat_type) :: A, aux_A
! descriptor of sparse matrices
type(psb_desc_type):: desc_A
! preconditioner
type(amg_zprec_type) :: P
! right-hand side, solution and residual vectors
type(psb_z_vect_type) :: b, x, r
complex(psb_dpk_), allocatable , save :: x_glob(:), r_glob(:)
complex(psb_dpk_), allocatable, target :: aux_b(:,:)
complex(psb_dpk_), pointer :: b_glob(:)
! solver and preconditioner parameters
real(psb_dpk_) :: tol, err
integer :: itmax, iter, istop
integer :: nlev
! parallel environment parameters
type(psb_ctxt_type) :: ctxt
integer :: iam, np
! other variables
integer :: choice
integer :: i,info,j,m_problem
integer(psb_epk_) :: amatsize, precsize, descsize
integer :: ierr, ircode
real(psb_dpk_) :: resmx, resmxp
real(psb_dpk_) :: t1, t2, tprec
character(len=20) :: name, kmethod
integer, parameter :: iunit=12
! initialize the parallel environment
call psb_init(ctxt)
call psb_info(ctxt,iam,np)
if (iam < 0) then
! This should not happen, but just in case
call psb_exit(ctxt)
stop
endif
name='amg_zexample_ml'
if(psb_get_errstatus() /= 0) goto 9999
info=psb_success_
call psb_set_errverbosity(2)
!
! Hello world
!
if (iam == psb_root_) then
write(*,*) 'Welcome to AMG4PSBLAS version: ',amg_version_string_
write(*,*) 'This is the ',trim(name),' sample program'
end if
! get parameters
call get_parms(ctxt,mtrx_file,rhs_file,filefmt,choice,itmax,tol)
call psb_barrier(ctxt)
t1 = psb_wtime()
! read and assemble the matrix A and the right-hand side b
! using PSBLAS routines for sparse matrix / vector management
if (iam == psb_root_) then
select case(psb_toupper(filefmt))
case('MM')
! For Matrix Market we have an input file for the matrix
! and an (optional) second file for the RHS.
call mm_mat_read(aux_a,info,iunit=iunit,filename=mtrx_file)
if (info == psb_success_) then
if (rhs_file /= 'NONE') then
call mm_array_read(aux_b,info,iunit=iunit,filename=rhs_file)
end if
end if
case ('HB')
! For Harwell-Boeing we have a single file which may or may not
! contain an RHS.
call hb_read(aux_a,info,iunit=iunit,b=aux_b,filename=mtrx_file)
case default
info = -1
write(0,*) 'Wrong choice for fileformat ', filefmt
end select
if (info /= psb_success_) then
write(0,*) 'Error while reading input matrix '
call psb_abort(ctxt)
end if
m_problem = aux_a%get_nrows()
call psb_bcast(ctxt,m_problem)
! At this point aux_b may still be unallocated
if (psb_size(aux_b,1) == m_problem) then
! if any rhs were present, broadcast the first one
write(0,'("Ok, got an rhs ")')
b_glob =>aux_b(:,1)
else
write(*,'("Generating an rhs...")')
write(*,'(" ")')
call psb_realloc(m_problem,1,aux_b,ircode)
if (ircode /= 0) then
call psb_errpush(psb_err_alloc_dealloc_,name)
goto 9999
endif
b_glob => aux_b(:,1)
do i=1, m_problem
b_glob(i) = 1.d0
enddo
endif
else
call psb_bcast(ctxt,m_problem)
end if
call psb_barrier(ctxt)
if (iam == psb_root_) write(*,'("Partition type: block")')
call psb_matdist(aux_A, A, ctxt, desc_A,info,parts=part_block)
call psb_scatter(b_glob,b,desc_a,info,root=psb_root_)
t2 = psb_wtime() - t1
call psb_amx(ctxt, t2)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Time to read and partition matrix : ",es12.5)')t2
write(*,'(" ")')
end if
select case(choice)
case(1)
! initialize the default multi-level preconditioner, i.e. V-cycle
! with decoupled smoothed aggregation, 1 hybrid forward/backward
! GS sweep as pre/post-smoother and UMFPACK as coarsest-level
! solver
call P%init(ctxt,'ML',info)
kmethod = 'CG'
case(2)
! initialize a V-cycle preconditioner with 1 block-Jacobi sweep (with
! ILU(0) on the blocks) as pre- and post-smoother, and 8 block-Jacobi
! sweeps (with ILU(0) on the blocks) as coarsest-level solver
call P%init(ctxt,'ML',info)
call P%set('SMOOTHER_TYPE','BJAC',info)
call P%set('COARSE_SOLVE','BJAC',info)
call P%set('COARSE_SWEEPS',8,info)
kmethod = 'CG'
case(3)
! initialize a W-cycle preconditioner based on the coupled aggregation relying on matching,
! with maximum size of aggregates equal to 8 and smoothed prolongators,
! 2 hybrid forward/backward GS sweeps as pre/post-smoother, a distributed coarsest
! matrix, and preconditioned Flexible Conjugate Gradient as coarsest-level solver
call P%init(ctxt,'ML',info)
call P%set('PAR_AGGR_ALG','COUPLED',info)
call P%set('AGGR_TYPE','MATCHBOXP',info)
call P%set('AGGR_SIZE',8,info)
call P%set('ML_CYCLE','WCYCLE',info)
call P%set('SMOOTHER_SWEEPS',2,info)
call P%set('COARSE_SOLVE','KRM',info)
kmethod = 'CG'
end select
! build the preconditioner
call psb_barrier(ctxt)
t1 = psb_wtime()
! build the preconditioner
call P%hierarchy_build(A,desc_A,info)
call P%smoothers_build(A,desc_A,info)
tprec = psb_wtime()-t1
call psb_amx(ctxt, tprec)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,a_err='amg_precbld')
goto 9999
end if
! set the initial guess
call psb_geall(x,desc_A,info)
call x%zero()
call psb_geasb(x,desc_A,info)
! solve Ax=b with preconditioned CG
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_krylov(kmethod,A,P,b,x,tol,desc_A,info,itmax,iter,err,itrace=1,istop=2)
t2 = psb_wtime() - t1
call psb_amx(ctxt,t2)
call psb_geasb(r,desc_A,info,scratch=.true.)
call psb_geaxpby(zone,b,zzero,r,desc_A,info)
call psb_spmm(-zone,A,x,zone,r,desc_A,info)
resmx = psb_genrm2(r,desc_A,info)
resmxp = psb_geamax(r,desc_A,info)
amatsize = a%sizeof()
descsize = desc_a%sizeof()
precsize = p%sizeof()
call psb_sum(ctxt,amatsize)
call psb_sum(ctxt,descsize)
call psb_sum(ctxt,precsize)
call P%descr(info)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Matrix: ",A)')mtrx_file
write(*,'("Computed solution on ",i8," processors")')np
write(*,'("Krylov method : ",a)') kmethod
write(*,'("Iterations to convergence : ",i6)')iter
write(*,'("Error estimate on exit : ",es12.5)')err
write(*,'("Time to build prec. : ",es12.5)')tprec
write(*,'("Time to solve system : ",es12.5)')t2
write(*,'("Time per iteration : ",es12.5)')t2/(iter)
write(*,'("Total time : ",es12.5)')t2+tprec
write(*,'("Residual 2-norm : ",es12.5)')resmx
write(*,'("Residual inf-norm : ",es12.5)')resmxp
write(*,'("Total memory occupation for A : ",i12)')amatsize
write(*,'("Total memory occupation for DESC_A : ",i12)')descsize
write(*,'("Total memory occupation for PREC : ",i12)')precsize
end if
call psb_gather(x_glob,x,desc_a,info,root=psb_root_)
if (info == psb_success_) &
& call psb_gather(r_glob,r,desc_a,info,root=psb_root_)
if (info /= psb_success_) goto 9999
if (iam == psb_root_) then
write(0,'(" ")')
write(0,'("Saving x on file")')
write(20,*) 'matrix: ',mtrx_file
write(20,*) 'computed solution on ',np,' processors.'
write(20,*) 'iterations to convergence: ',iter
write(20,*) 'error estimate (infinity norm) on exit:', &
& ' ||r||/(||a||||x||+||b||) = ',err
write(20,*) 'max residual = ',resmx, resmxp
write(20,'(a8,4(2x,a20))') 'I','X(I)','R(I)','B(I)'
do i=1,m_problem
write(20,998) i,x_glob(i),r_glob(i),b_glob(i)
enddo
end if
998 format(i8,4(2x,g20.14))
993 format(i6,4(1x,e12.6))
! deallocate the data structures
call psb_gefree(b, desc_A,info)
call psb_gefree(x, desc_A,info)
call psb_spfree(A, desc_A,info)
call P%free(info)
call psb_cdfree(desc_A,info)
call psb_exit(ctxt)
stop
9999 continue
call psb_error(ctxt)
contains
!
! get parameters from standard input
!
subroutine get_parms(ctxt,mtrx,rhs,filefmt,choice,itmax,tol)
implicit none
type(psb_ctxt_type) :: ctxt
integer :: choice, itmax
real(psb_dpk_) :: tol
character(len=*) :: mtrx, rhs,filefmt
integer :: iam, np, inp_unit
character(len=1024) :: filename
call psb_info(ctxt,iam,np)
if (iam == psb_root_) then
if (command_argument_count()>0) then
call get_command_argument(1,filename)
inp_unit = 30
open(inp_unit,file=filename,action='read',iostat=info)
if (info /= 0) then
write(psb_err_unit,*) 'Could not open file ',filename,' for input'
call psb_abort(ctxt)
stop
else
write(psb_err_unit,*) 'Opened file ',trim(filename),' for input'
end if
else
inp_unit=psb_inp_unit
end if
! read input parameters
call read_data(mtrx,inp_unit)
call read_data(rhs,inp_unit)
call read_data(filefmt,inp_unit)
call read_data(choice,inp_unit)
call read_data(itmax,inp_unit)
call read_data(tol,inp_unit)
if (inp_unit /= psb_inp_unit) then
close(inp_unit)
end if
end if
call psb_bcast(ctxt,mtrx)
call psb_bcast(ctxt,rhs)
call psb_bcast(ctxt,filefmt)
call psb_bcast(ctxt,choice)
call psb_bcast(ctxt,itmax)
call psb_bcast(ctxt,tol)
end subroutine get_parms
end program amg_zexample_ml
+186
View File
@@ -0,0 +1,186 @@
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2020
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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 data_input
interface read_data
module procedure read_char, read_int,&
& read_double, read_single,&
& string_read_char, string_read_int,&
& string_read_double, string_read_single
end interface read_data
interface trim_string
module procedure trim_string
end interface
character(len=4096), private :: charbuf
character, private, parameter :: def_marker="!"
contains
subroutine read_char(val,file,marker)
character(len=*), intent(out) :: val
integer, intent(in) :: file
character(len=1), optional, intent(in) :: marker
read(file,'(a)')charbuf
call read_data(val,charbuf,marker)
end subroutine read_char
subroutine read_int(val,file,marker)
integer, intent(out) :: val
integer, intent(in) :: file
character(len=1), optional, intent(in) :: marker
read(file,'(a)')charbuf
call read_data(val,charbuf,marker)
end subroutine read_int
subroutine read_single(val,file,marker)
use psb_base_mod
real(psb_spk_), intent(out) :: val
integer, intent(in) :: file
character(len=1), optional, intent(in) :: marker
read(file,'(a)')charbuf
call read_data(val,charbuf,marker)
end subroutine read_single
subroutine read_double(val,file,marker)
use psb_base_mod
real(psb_dpk_), intent(out) :: val
integer, intent(in) :: file
character(len=1), optional, intent(in) :: marker
read(file,'(a)')charbuf
call read_data(val,charbuf,marker)
end subroutine read_double
subroutine string_read_char(val,file,marker)
character(len=*), intent(out) :: val
character(len=*), intent(in) :: file
character(len=1), optional, intent(in) :: marker
character(len=1) :: marker_
character(len=1024) :: charbuf
integer :: idx
if (present(marker)) then
marker_ = marker
else
marker_ = def_marker
end if
read(file,'(a)')charbuf
charbuf = adjustl(charbuf)
idx=index(charbuf,marker_)
if (idx == 0) idx = len(charbuf)+1
read(charbuf(1:idx-1),'(a)') val
end subroutine string_read_char
subroutine string_read_int(val,file,marker)
integer, intent(out) :: val
character(len=*), intent(in) :: file
character(len=1), optional, intent(in) :: marker
character(len=1) :: marker_
character(len=1024) :: charbuf
integer :: idx
if (present(marker)) then
marker_ = marker
else
marker_ = def_marker
end if
read(file,'(a)')charbuf
charbuf = adjustl(charbuf)
idx=index(charbuf,marker_)
if (idx == 0) idx = len(charbuf)+1
read(charbuf(1:idx-1),*) val
end subroutine string_read_int
subroutine string_read_single(val,file,marker)
use psb_base_mod
real(psb_spk_), intent(out) :: val
character(len=*), intent(in) :: file
character(len=1), optional, intent(in) :: marker
character(len=1) :: marker_
character(len=1024) :: charbuf
integer :: idx
if (present(marker)) then
marker_ = marker
else
marker_ = def_marker
end if
read(file,'(a)')charbuf
charbuf = adjustl(charbuf)
idx=index(charbuf,marker_)
if (idx == 0) idx = len(charbuf)+1
read(charbuf(1:idx-1),*) val
end subroutine string_read_single
subroutine string_read_double(val,file,marker)
use psb_base_mod
real(psb_dpk_), intent(out) :: val
character(len=*), intent(in) :: file
character(len=1), optional, intent(in) :: marker
character(len=1) :: marker_
character(len=1024) :: charbuf
integer :: idx
if (present(marker)) then
marker_ = marker
else
marker_ = def_marker
end if
read(file,'(a)')charbuf
charbuf = adjustl(charbuf)
idx=index(charbuf,marker_)
if (idx == 0) idx = len(charbuf)+1
read(charbuf(1:idx-1),*) val
end subroutine string_read_double
function trim_string(string,marker)
character(len=*), intent(in) :: string
character(len=1), optional, intent(in) :: marker
character(len=len(string)) :: trim_string
character(len=1) :: marker_
integer :: idx
if (present(marker)) then
marker_ = marker
else
marker_ = def_marker
end if
idx=index(string,marker_)
trim_string = adjustl(string(idx:))
end function trim_string
end module data_input
+5
View File
@@ -0,0 +1,5 @@
mld_mat.mtx ! This matrix (and others) from: http://math.nist.gov/MatrixMarket/ or
mld_rhs.mtx ! rhs | http://www.cise.ufl.edu/research/sparse/matrices/index.html
MM ! File format: MM (Matrix Market) HB (Harwell-Boeing).
01000 ! ITMAX
1.d-6 ! EPS
+6
View File
@@ -0,0 +1,6 @@
mld_mat.mtx ! This matrix (and others) from: http://math.nist.gov/MatrixMarket/ or
mld_rhs.mtx ! rhs | http://www.cise.ufl.edu/research/sparse/matrices/index.html
MM ! File format: MM (Matrix Market) HB (Harwell-Boeing).
1 ! Preconditioner choice
0100 ! ITMAX
1.d-6 ! EPS
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+55
View File
@@ -0,0 +1,55 @@
AMGDIR=../../..
AMGINCDIR=$(AMGDIR)/include
include $(AMGINCDIR)/Make.inc.amg4psblas
AMGMODDIR=$(AMGDIR)/modules
AMGLIBDIR=$(AMGDIR)/lib
AMG_LIBS=-L$(AMGLIBDIR) -lpsb_krylov -lamg_prec -lpsb_prec
FINCLUDES=$(FMFLAG). $(FMFLAG)$(AMGMODDIR) $(FMFLAG)$(AMGINCDIR) $(PSBLAS_INCLUDES) $(FIFLAG).
LINKOPT=
DMOBJS=amg_dexample_ml.o data_input.o amg_dpde_mod.o
D1OBJS=amg_dexample_1lev.o data_input.o amg_dpde_mod.o
SMOBJS=amg_sexample_ml.o data_input.o amg_spde_mod.o
S1OBJS=amg_sexample_1lev.o data_input.o amg_spde_mod.o
EXEDIR=./runs
all: amg_sexample_ml amg_sexample_1lev amg_dexample_ml amg_dexample_1lev
amg_dexample_ml: $(DMOBJS)
$(FLINK) $(LINKOPT) $(DMOBJS) -o amg_dexample_ml \
$(AMG_LIBS) $(PSBLAS_LIBS) $(LDLIBS)
/bin/mv amg_dexample_ml $(EXEDIR)
amg_dexample_1lev: $(D1OBJS)
$(FLINK) $(LINKOPT) $(D1OBJS) -o amg_dexample_1lev \
$(AMG_LIBS) $(PSBLAS_LIBS) $(LDLIBS)
/bin/mv amg_dexample_1lev $(EXEDIR)
amg_dexample_ml.o: data_input.o amg_dpde_mod.o
amg_dexample_1lev.o: data_input.o amg_dpde_mod.o
amg_sexample_ml: $(SMOBJS)
$(FLINK) $(LINKOPT) $(SMOBJS) -o amg_sexample_ml \
$(AMG_LIBS) $(PSBLAS_LIBS) $(LDLIBS)
/bin/mv amg_sexample_ml $(EXEDIR)
amg_sexample_1lev: $(S1OBJS)
$(FLINK) $(LINKOPT) $(S1OBJS) -o amg_sexample_1lev \
$(AMG_LIBS) $(PSBLAS_LIBS) $(LDLIBS)
/bin/mv amg_sexample_1lev $(EXEDIR)
amg_sexample_ml.o: data_input.o amg_spde_mod.o
amg_sexample_1lev.o: data_input.o amg_spde_mod.o
clean:
/bin/rm -f $(DMOBJS) $(D1OBJS) $(SMOBJS) $(S1OBJS) \
*$(.mod) $(EXEDIR)/amg_dexample_ml $(EXEDIR)/amg_dexample_1lev\
$(EXEDIR)/amg_sexample_ml $(EXEDIR)/amg_sexample_1lev
lib:
(cd ../../; make library)
verycleanlib:
(cd ../../; make veryclean)
+276
View File
@@ -0,0 +1,276 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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.
!
!
! File: amg_dexample_1lev.f90
!
! This sample program solves a linear system obtained by discretizing a
! PDE with Dirichlet BCs. The solver is BiCGStab preconditioned by
! RAS with overlap 2 and ILU(0) on the local blocks, as explained in Section 4.1
! of the AMG4PSBLAS User's and Reference Guide.
!
!
! The PDE is a general second order equation in 3d
!
! a1 dd(u) a2 dd(u) a3 dd(u) b1 d(u) b2 d(u) b3 d(u)
! - ------ - ------ - ------ + ----- + ------ + ------ + c u = f
! dxdx dydy dzdz dx dy dz
!
! with Dirichlet boundary conditions
! u = g
!
! on the unit cube 0<=x,y,z<=1.
!
!
! Note that if b1=b2=b3=c=0., the PDE is the Laplace equation.
!
program amg_dexample_1lev
use psb_base_mod
use amg_prec_mod
use psb_krylov_mod
use psb_util_mod
use data_input
use amg_d_pde_mod
implicit none
! sparse matrices
type(psb_dspmat_type) :: A
! descriptor of sparse matrices
type(psb_desc_type):: desc_A
! preconditioner
type(amg_dprec_type) :: P
! right-hand side, solution and residual vectors
type(psb_d_vect_type) :: x, b, r
! solver parameters
real(psb_dpk_) :: tol, err
integer :: itmax, iter, itrace, istop
! parallel environment parameters
type(psb_ctxt_type) :: ctxt
integer :: iam, np
! other variables
integer :: i,info,j
integer(psb_epk_) :: amatsize, precsize, descsize
integer(psb_epk_) :: system_size
integer :: idim, nlev, ierr, ircode
real(psb_dpk_) :: resmx, resmxp
real(psb_dpk_) :: t1, t2, tprec
character(len=5) :: afmt='CSR'
character(len=20) :: name, kmethod
! initialize the parallel environment
call psb_init(ctxt)
call psb_info(ctxt,iam,np)
if (iam < 0) then
! This should not happen, but just in case
call psb_exit(ctxt)
stop
endif
name='amg_dexample_ml'
if(psb_get_errstatus() /= 0) goto 9999
info=psb_success_
call psb_set_errverbosity(2)
!
! Hello world
!
if (iam == psb_root_) then
write(*,*) 'Welcome to AMG4PSBLAS version: ',amg_version_string_
write(*,*) 'This is the ',trim(name),' sample program'
end if
! get parameters
call get_parms(ctxt,idim,itmax,tol)
! allocate and fill in the coefficient matrix, rhs and initial guess
call psb_barrier(ctxt)
t1 = psb_wtime()
call amg_gen_pde3d(ctxt,idim,a,b,x,desc_a,afmt,&
& a1,a2,a3,b1,b2,b3,c,g,info)
call psb_barrier(ctxt)
t2 = psb_wtime() - t1
if(info /= psb_success_) then
info=psb_err_from_subroutine_
call psb_errpush(info,name)
goto 9999
end if
if (iam == psb_root_) write(*,'("Overall matrix creation time : ",es12.5)')t2
if (iam == psb_root_) write(*,'(" ")')
! set RAS
call P%init(ctxt,'AS',info)
! set number of overlaps
call P%set('SUB_OVR',2,info)
! build the preconditioner
t1 = psb_wtime()
call P%build(A,desc_A,info)
tprec = psb_wtime()-t1
call psb_amx(ctxt, tprec)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,a_err='amg_precbld')
goto 9999
end if
! set the initial guess
call psb_geall(x,desc_A,info)
call x%zero()
call psb_geasb(x,desc_A,info)
! solve Ax=b with preconditioned Krylov method: BiCGSTAB
kmethod = 'BiCGSTAB'
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_krylov(kmethod,A,P,b,x,tol,desc_A,info,itmax,iter,err,itrace=1,istop=2)
t2 = psb_wtime() - t1
call psb_amx(ctxt,t2)
call psb_geall(r,desc_A,info)
call r%zero()
call psb_geasb(r,desc_A,info)
call psb_geaxpby(done,b,dzero,r,desc_A,info)
call psb_spmm(-done,A,x,done,r,desc_A,info)
resmx = psb_genrm2(r,desc_A,info)
resmxp = psb_geamax(r,desc_A,info)
amatsize = a%sizeof()
descsize = desc_a%sizeof()
precsize = p%sizeof()
system_size = desc_a%get_global_rows()
call psb_sum(ctxt,amatsize)
call psb_sum(ctxt,descsize)
call psb_sum(ctxt,precsize)
call P%descr(info)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Matrix from PDE example")')
write(*,'("Computed solution on ",i8," processors")')np
write(*,'("Linear system size : ",i12)') system_size
write(*,'("Krylov method : ",a)') kmethod
write(*,'("Iterations to convergence : ",i6)')iter
write(*,'("Error estimate on exit : ",es12.5)')err
write(*,'("Time to build prec. : ",es12.5)')tprec
write(*,'("Time to solve system : ",es12.5)')t2
write(*,'("Time per iteration : ",es12.5)')t2/(iter)
write(*,'("Total time : ",es12.5)')t2+tprec
write(*,'("Residual 2-norm : ",es12.5)')resmx
write(*,'("Residual inf-norm : ",es12.5)')resmxp
write(*,'("Total memory occupation for A : ",i12)')amatsize
write(*,'("Total memory occupation for DESC_A : ",i12)')descsize
write(*,'("Total memory occupation for PREC : ",i12)')precsize
end if
call psb_gefree(b, desc_A,info)
call psb_gefree(x, desc_A,info)
call psb_spfree(A, desc_A,info)
call P%free(info)
call psb_cdfree(desc_A,info)
call psb_exit(ctxt)
stop
9999 continue
call psb_error(ctxt)
contains
!
! get parameters from standard input
!
subroutine get_parms(ctxt,idim,itmax,tol)
implicit none
type(psb_ctxt_type) :: ctxt
integer :: idim, itmax
real(psb_dpk_) :: tol
integer :: iam, np, inp_unit
character(len=1024) :: filename
call psb_info(ctxt,iam,np)
if (iam == psb_root_) then
if (command_argument_count()>0) then
call get_command_argument(1,filename)
inp_unit = 30
open(inp_unit,file=filename,action='read',iostat=info)
if (info /= 0) then
write(psb_err_unit,*) 'Could not open file ',filename,' for input'
call psb_abort(ctxt)
stop
else
write(psb_err_unit,*) 'Opened file ',trim(filename),' for input'
end if
else
inp_unit=psb_inp_unit
end if
! read input parameters
call read_data(idim,inp_unit)
call read_data(itmax,inp_unit)
call read_data(tol,inp_unit)
if (inp_unit /= psb_inp_unit) then
close(inp_unit)
end if
end if
call psb_bcast(ctxt,idim)
call psb_bcast(ctxt,itmax)
call psb_bcast(ctxt,tol)
end subroutine get_parms
end program amg_dexample_1lev
+340
View File
@@ -0,0 +1,340 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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.
!
!
! File: amg_dexample_ml.f90
!
! This sample program solves a linear system obtained by discretizing a
! PDE with Dirichlet BCs. The solver is CG, coupled with one of the
! following multi-level preconditioner, as explained in Section 4.1 of
! the AMG4PSBLAS User's and Reference Guide:
!
! - choice = 1, the default multi-level preconditioner solver, i.e.,
! V-cycle with decoupled smoothed aggregation, 1 hybrid forward/backward
! GS sweep as pre/post-smoother and UMFPACK as coarsest-level
! solver (Sec. 4.1, Listing 1)
!
! - choice = 2, a V-cycle preconditioner with 1 block-Jacobi sweep
! (with ILU(0) on the blocks) as pre- and post-smoother, and 8 block-Jacobi
! sweeps (with ILU(0) on the blocks) as coarsest-level solver (Sec. 4.1, Listing 2)
!
! - choice = 3, W-cycle preconditioner based on the coupled aggregation relying
! on matching, with maximum size of aggregates equal to 8 and smoothed prolongators,
! 2 hybrid forward/backward GS sweeps as pre/post-smoother, a distributed coarsest
! matrix, and preconditioned Flexible Conjugate Gradient as coarsest-level solver
! (Sec. 4.1, Listing 3)
!
! The matrix and the rhs are read from files (if an rhs is not available, the
! unit rhs is set).
!
!
! The PDE is a general second order equation in 3d
!
! a1 dd(u) a2 dd(u) a3 dd(u) b1 d(u) b2 d(u) b3 d(u)
! - ------ - ------ - ------ + ----- + ------ + ------ + c u = f
! dxdx dydy dzdz dx dy dz
!
! with Dirichlet boundary conditions
! u = g
!
! on the unit cube 0<=x,y,z<=1.
!
!
! Note that if b1=b2=b3=c=0., the PDE is the Laplace equation.
!
! In this sample program the index space of the discretized
! computational domain is first numbered sequentially in a standard way,
! then the corresponding vector is distributed according to a BLOCK
! data distribution.
!
program amg_dexample_ml
use psb_base_mod
use amg_prec_mod
use psb_krylov_mod
use psb_util_mod
use data_input
use amg_d_pde_mod
implicit none
! input parameters
! sparse matrices
type(psb_dspmat_type) :: A
! sparse matrices descriptor
type(psb_desc_type):: desc_A
! preconditioner
type(amg_dprec_type) :: P
! right-hand side, solution and residual vectors
type(psb_d_vect_type) :: x, b, r
! solver and preconditioner parameters
real(psb_dpk_) :: tol, err
integer :: itmax, iter, istop
integer :: nlev
! parallel environment parameters
type(psb_ctxt_type) :: ctxt
integer :: iam, np
! other variables
integer :: choice
integer :: i,info,j
integer(psb_epk_) :: amatsize, precsize, descsize
integer(psb_epk_) :: system_size
integer :: idim, ierr, ircode
real(psb_dpk_) :: resmx, resmxp
real(psb_dpk_) :: t1, t2, tprec
character(len=5) :: afmt='CSR'
character(len=20) :: name, kmethod
! initialize the parallel environment
call psb_init(ctxt)
call psb_info(ctxt,iam,np)
if (iam < 0) then
! This should not happen, but just in case
call psb_exit(ctxt)
stop
endif
name='amg_dexample_ml'
if(psb_get_errstatus() /= 0) goto 9999
info=psb_success_
call psb_set_errverbosity(2)
!
! Hello world
!
if (iam == psb_root_) then
write(*,*) 'Welcome to AMG4PSBLAS version: ',amg_version_string_
write(*,*) 'This is the ',trim(name),' sample program'
end if
! get parameters
call get_parms(ctxt,choice,idim,itmax,tol)
! allocate and fill in the coefficient matrix, rhs and initial guess
call psb_barrier(ctxt)
t1 = psb_wtime()
call amg_gen_pde3d(ctxt,idim,a,b,x,desc_a,afmt,&
& a1,a2,a3,b1,b2,b3,c,g,info)
call psb_barrier(ctxt)
t2 = psb_wtime() - t1
if(info /= psb_success_) then
info=psb_err_from_subroutine_
call psb_errpush(info,name)
goto 9999
end if
if (iam == psb_root_) write(*,'("Overall matrix creation time : ",es12.5)')t2
if (iam == psb_root_) write(*,'(" ")')
select case(choice)
case(1)
! initialize the default multi-level preconditioner, i.e. V-cycle
! with basic smoothed aggregation, 1 hybrid forward/backward
! GS sweep as pre/post-smoother and UMFPACK as coarsest-level
! solver
call P%init(ctxt,'ML',info)
kmethod = 'CG'
case(2)
! initialize a V-cycle preconditioner with 1 block-Jacobi sweep (with
! ILU(0) on the blocks) as pre- and post-smoother, and 8 block-Jacobi
! sweeps (with ILU(0) on the blocks) as coarsest-level solver
call P%init(ctxt,'ML',info)
call P%set('SMOOTHER_TYPE','BJAC',info)
call P%set('COARSE_SOLVE','BJAC',info)
call P%set('COARSE_SWEEPS',8,info)
kmethod = 'CG'
case(3)
! initialize a W-cycle preconditioner based on the coupled aggregation relying on matching,
! with maximum size of aggregates equal to 8 and smoothed prolongators,
! 2 hybrid forward/backward GS sweeps as pre/post-smoother, a distributed coarsest
! matrix, and preconditioned Flexible Conjugate Gradient as coarsest-level solver
call P%init(ctxt,'ML',info)
call P%set('PAR_AGGR_ALG','COUPLED',info)
call P%set('AGGR_TYPE','MATCHBOXP',info)
call P%set('AGGR_SIZE',8,info)
call P%set('ML_CYCLE','WCYCLE',info)
call P%set('SMOOTHER_SWEEPS',2,info)
call P%set('COARSE_SOLVE','KRM',info)
call P%set('COARSE_MAT','DIST',info)
kmethod = 'CG'
end select
call psb_barrier(ctxt)
t1 = psb_wtime()
! build the preconditioner
call P%hierarchy_build(A,desc_A,info)
call P%smoothers_build(A,desc_A,info)
tprec = psb_wtime()-t1
call psb_amx(ctxt, tprec)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,a_err='amg_precbld')
goto 9999
end if
! set the solver parameters and the initial guess
call psb_geall(x,desc_A,info)
call x%zero()
call psb_geasb(x,desc_A,info)
! solve Ax=b with preconditioned Krylov method
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_krylov(kmethod,A,P,b,x,tol,desc_A,info,itmax,iter,err,itrace=1,istop=2)
t2 = psb_wtime() - t1
call psb_amx(ctxt,t2)
call psb_geall(r,desc_A,info)
call r%zero()
call psb_geasb(r,desc_A,info)
call psb_geaxpby(done,b,dzero,r,desc_A,info)
call psb_spmm(-done,A,x,done,r,desc_A,info)
resmx = psb_genrm2(r,desc_A,info)
resmxp = psb_geamax(r,desc_A,info)
amatsize = a%sizeof()
descsize = desc_a%sizeof()
precsize = p%sizeof()
system_size = desc_a%get_global_rows()
call psb_sum(ctxt,amatsize)
call psb_sum(ctxt,descsize)
call psb_sum(ctxt,precsize)
call P%descr(info)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Matrix from PDE example")')
write(*,'("Computed solution on ",i8," processors")')np
write(*,'("Linear system size : ",i12)') system_size
write(*,'("Krylov method : ",a)') kmethod
write(*,'("Iterations to convergence : ",i6)')iter
write(*,'("Error estimate on exit : ",es12.5)')err
write(*,'("Time to build prec. : ",es12.5)')tprec
write(*,'("Time to solve system : ",es12.5)')t2
write(*,'("Time per iteration : ",es12.5)')t2/(iter)
write(*,'("Total time : ",es12.5)')t2+tprec
write(*,'("Residual 2-norm : ",es12.5)')resmx
write(*,'("Residual inf-norm : ",es12.5)')resmxp
write(*,'("Total memory occupation for A : ",i12)')amatsize
write(*,'("Total memory occupation for DESC_A : ",i12)')descsize
write(*,'("Total memory occupation for PREC : ",i12)')precsize
end if
call psb_gefree(b, desc_A,info)
call psb_gefree(x, desc_A,info)
call psb_spfree(A, desc_A,info)
call P%free(info)
call psb_cdfree(desc_A,info)
call psb_exit(ctxt)
stop
9999 continue
call psb_error(ctxt)
contains
!
! get parameters from standard input
!
subroutine get_parms(ctxt,choice,idim,itmax,tol)
implicit none
type(psb_ctxt_type) :: ctxt
integer :: choice, idim, itmax
real(psb_dpk_) :: tol
integer :: iam, np, inp_unit
character(len=1024) :: filename
call psb_info(ctxt,iam,np)
if (iam == psb_root_) then
if (command_argument_count()>0) then
call get_command_argument(1,filename)
inp_unit = 30
open(inp_unit,file=filename,action='read',iostat=info)
if (info /= 0) then
write(psb_err_unit,*) 'Could not open file ',filename,' for input'
call psb_abort(ctxt)
stop
else
write(psb_err_unit,*) 'Opened file ',trim(filename),' for input'
end if
else
inp_unit=psb_inp_unit
end if
! read input parameters
call read_data(choice,inp_unit)
call read_data(idim,inp_unit)
call read_data(itmax,inp_unit)
call read_data(tol,inp_unit)
if (inp_unit /= psb_inp_unit) then
close(inp_unit)
end if
end if
call psb_bcast(ctxt,choice)
call psb_bcast(ctxt,idim)
call psb_bcast(ctxt,itmax)
call psb_bcast(ctxt,tol)
end subroutine get_parms
end program amg_dexample_ml
+572
View File
@@ -0,0 +1,572 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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 amg_d_pde_mod
use psb_base_mod, only : psb_dpk_, psb_ipk_, psb_desc_type,&
& psb_dspmat_type, psb_d_vect_type, dzero, done,&
& psb_d_base_sparse_mat, psb_d_base_vect_type, psb_i_base_vect_type
interface
function d_func_3d(x,y,z) result(val)
import :: psb_dpk_
real(psb_dpk_), intent(in) :: x,y,z
real(psb_dpk_) :: val
end function d_func_3d
end interface
interface amg_gen_pde3d
module procedure amg_d_gen_pde3d
end interface amg_gen_pde3d
contains
function d_null_func_3d(x,y,z) result(val)
real(psb_dpk_), intent(in) :: x,y,z
real(psb_dpk_) :: val
val = dzero
end function d_null_func_3d
!
! subroutine to allocate and fill in the coefficient matrix and
! the rhs.
!
subroutine amg_d_gen_pde3d(ctxt,idim,a,bv,xv,desc_a,afmt,&
& a1,a2,a3,b1,b2,b3,c,g,info,f,amold,vmold,imold,partition,nrl,iv)
use psb_base_mod
use psb_util_mod
!
! Discretizes the partial differential equation
!
! a1 dd(u) a2 dd(u) a3 dd(u) b1 d(u) b2 d(u) b3 d(u)
! - ------ - ------ - ------ + ----- + ------ + ------ + c u = f
! dxdx dydy dzdz dx dy dz
!
! with Dirichlet boundary conditions
! u = g
!
! on the unit cube 0<=x,y,z<=1.
!
!
! Note that if b1=b2=b3=c=0., the PDE is the Laplace equation.
!
implicit none
procedure(d_func_3d) :: b1,b2,b3,c,a1,a2,a3,g
integer(psb_ipk_) :: idim
type(psb_dspmat_type) :: a
type(psb_d_vect_type) :: xv,bv
type(psb_desc_type) :: desc_a
integer(psb_ipk_) :: info
type(psb_ctxt_type) :: ctxt
character :: afmt*5
procedure(d_func_3d), optional :: f
class(psb_d_base_sparse_mat), optional :: amold
class(psb_d_base_vect_type), optional :: vmold
class(psb_i_base_vect_type), optional :: imold
integer(psb_ipk_), optional :: partition, nrl,iv(:)
! Local variables.
integer(psb_ipk_), parameter :: nb=20
type(psb_d_csc_sparse_mat) :: acsc
type(psb_d_coo_sparse_mat) :: acoo
type(psb_d_csr_sparse_mat) :: acsr
real(psb_dpk_) :: zt(nb),x,y,z,xph,xmh,yph,ymh,zph,zmh
integer(psb_ipk_) :: nnz,nr,nlr,i,j,ii,ib,k, partition_
integer(psb_lpk_) :: m,n,glob_row,nt
integer(psb_ipk_) :: ix,iy,iz,ia,indx_owner
! For 3D partition
! Note: integer control variables going directly into an MPI call
! must be 4 bytes, i.e. psb_mpk_
integer(psb_mpk_) :: npdims(3), npp, minfo
integer(psb_ipk_) :: npx,npy,npz, iamx,iamy,iamz,mynx,myny,mynz
integer(psb_ipk_), allocatable :: bndx(:),bndy(:),bndz(:)
! Process grid
integer(psb_ipk_) :: np, iam
integer(psb_ipk_) :: icoeff
integer(psb_lpk_), allocatable :: irow(:),icol(:),myidx(:)
real(psb_dpk_), allocatable :: val(:)
! deltah dimension of each grid cell
! deltat discretization time
real(psb_dpk_) :: deltah, sqdeltah, deltah2
real(psb_dpk_), parameter :: rhs=dzero,one=done,zero=dzero
real(psb_dpk_) :: t0, t1, t2, t3, tasb, talc, ttot, tgen, tcdasb
integer(psb_ipk_) :: err_act
procedure(d_func_3d), pointer :: f_
character(len=20) :: name, ch_err,tmpfmt
info = psb_success_
name = 'create_matrix'
call psb_erractionsave(err_act)
call psb_info(ctxt, iam, np)
if (present(f)) then
f_ => f
else
f_ => d_null_func_3d
end if
deltah = 1.d0/(idim+1)
sqdeltah = deltah*deltah
deltah2 = 2.0_psb_dpk_* deltah
if (present(partition)) then
if ((1<= partition).and.(partition <= 3)) then
partition_ = partition
else
write(*,*) 'Invalid partition choice ',partition,' defaulting to 3'
partition_ = 3
end if
else
partition_ = 3
end if
! initialize array descriptor and sparse matrix storage. provide an
! estimate of the number of non zeroes
m = (1_psb_lpk_*idim)*idim*idim
n = m
nnz = 7*((n+np-1)/np)
if(iam == psb_root_) write(psb_out_unit,'("Generating Matrix (size=",i0,")...")')n
select case(partition_)
case(1)
! A BLOCK partition
if (present(nrl)) then
nr = nrl
else
!
! Using a simple BLOCK distribution.
!
nt = (m+np-1)/np
nr = max(0,min(nt,m-(iam*nt)))
end if
nt = nr
call psb_sum(ctxt,nt)
if (nt /= m) then
write(psb_err_unit,*) iam, 'Initialization error ',nr,nt,m
info = -1
call psb_barrier(ctxt)
call psb_abort(ctxt)
return
end if
!
! First example of use of CDALL: specify for each process a number of
! contiguous rows
!
call psb_cdall(ctxt,desc_a,info,nl=nr)
myidx = desc_a%get_global_indices()
nlr = size(myidx)
case(2)
! A partition defined by the user through IV
if (present(iv)) then
if (size(iv) /= m) then
write(psb_err_unit,*) iam, 'Initialization error: wrong IV size',size(iv),m
info = -1
call psb_barrier(ctxt)
call psb_abort(ctxt)
return
end if
else
write(psb_err_unit,*) iam, 'Initialization error: IV not present'
info = -1
call psb_barrier(ctxt)
call psb_abort(ctxt)
return
end if
!
! Second example of use of CDALL: specify for each row the
! process that owns it
!
call psb_cdall(ctxt,desc_a,info,vg=iv)
myidx = desc_a%get_global_indices()
nlr = size(myidx)
case(3)
! A 3-dimensional partition
! A nifty MPI function will split the process list
npdims = 0
call mpi_dims_create(np,3,npdims,info)
npx = npdims(1)
npy = npdims(2)
npz = npdims(3)
allocate(bndx(0:npx),bndy(0:npy),bndz(0:npz))
! We can reuse idx2ijk for process indices as well.
call idx2ijk(iamx,iamy,iamz,iam,npx,npy,npz,base=0)
! Now let's split the 3D cube in hexahedra
call dist1Didx(bndx,idim,npx)
mynx = bndx(iamx+1)-bndx(iamx)
call dist1Didx(bndy,idim,npy)
myny = bndy(iamy+1)-bndy(iamy)
call dist1Didx(bndz,idim,npz)
mynz = bndz(iamz+1)-bndz(iamz)
! How many indices do I own?
nlr = mynx*myny*mynz
allocate(myidx(nlr))
! Now, let's generate the list of indices I own
nr = 0
do i=bndx(iamx),bndx(iamx+1)-1
do j=bndy(iamy),bndy(iamy+1)-1
do k=bndz(iamz),bndz(iamz+1)-1
nr = nr + 1
call ijk2idx(myidx(nr),i,j,k,idim,idim,idim)
end do
end do
end do
if (nr /= nlr) then
write(psb_err_unit,*) iam,iamx,iamy,iamz, 'Initialization error: NR vs NLR ',&
& nr,nlr,mynx,myny,mynz
info = -1
call psb_barrier(ctxt)
call psb_abort(ctxt)
end if
!
! Third example of use of CDALL: specify for each process
! the set of global indices it owns.
!
call psb_cdall(ctxt,desc_a,info,vl=myidx)
!
! Specify process topology
!
block
!
! Use adjcncy methods
!
integer(psb_mpk_), allocatable :: neighbours(:)
integer(psb_mpk_) :: cnt
logical, parameter :: debug_adj=.true.
if (debug_adj.and.(np > 1)) then
cnt = 0
allocate(neighbours(np))
if (iamx < npx-1) then
cnt = cnt + 1
call ijk2idx(neighbours(cnt),iamx+1,iamy,iamz,npx,npy,npz,base=0)
end if
if (iamy < npy-1) then
cnt = cnt + 1
call ijk2idx(neighbours(cnt),iamx,iamy+1,iamz,npx,npy,npz,base=0)
end if
if (iamz < npz-1) then
cnt = cnt + 1
call ijk2idx(neighbours(cnt),iamx,iamy,iamz+1,npx,npy,npz,base=0)
end if
if (iamx >0) then
cnt = cnt + 1
call ijk2idx(neighbours(cnt),iamx-1,iamy,iamz,npx,npy,npz,base=0)
end if
if (iamy >0) then
cnt = cnt + 1
call ijk2idx(neighbours(cnt),iamx,iamy-1,iamz,npx,npy,npz,base=0)
end if
if (iamz >0) then
cnt = cnt + 1
call ijk2idx(neighbours(cnt),iamx,iamy,iamz-1,npx,npy,npz,base=0)
end if
call psb_realloc(cnt, neighbours,info)
call desc_a%set_p_adjcncy(neighbours)
!write(0,*) iam,' Check on neighbours: ',desc_a%get_p_adjcncy()
end if
end block
case default
write(psb_err_unit,*) iam, 'Initialization error: should not get here'
info = -1
call psb_barrier(ctxt)
call psb_abort(ctxt)
return
end select
if (info == psb_success_) call psb_spall(a,desc_a,info,nnz=nnz)
! define rhs from boundary conditions; also build initial guess
if (info == psb_success_) call psb_geall(xv,desc_a,info)
if (info == psb_success_) call psb_geall(bv,desc_a,info)
call psb_barrier(ctxt)
talc = psb_wtime()-t0
if (info /= psb_success_) then
info=psb_err_from_subroutine_
ch_err='allocation rout.'
call psb_errpush(info,name,a_err=ch_err)
goto 9999
end if
! we build an auxiliary matrix consisting of one row at a
! time; just a small matrix. might be extended to generate
! a bunch of rows per call.
!
allocate(val(20*nb),irow(20*nb),&
&icol(20*nb),stat=info)
if (info /= psb_success_ ) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
endif
! loop over rows belonging to current process in a block
! distribution.
call psb_barrier(ctxt)
t1 = psb_wtime()
do ii=1, nlr,nb
ib = min(nb,nlr-ii+1)
icoeff = 1
do k=1,ib
i=ii+k-1
! local matrix pointer
glob_row=myidx(i)
! compute gridpoint coordinates
call idx2ijk(ix,iy,iz,glob_row,idim,idim,idim)
! x, y, z coordinates
x = (ix-1)*deltah
y = (iy-1)*deltah
z = (iz-1)*deltah
zt(k) = f_(x,y,z)
! internal point: build discretization
!
! term depending on (x-1,y,z)
!
val(icoeff) = -a1(x,y,z)/sqdeltah-b1(x,y,z)/deltah2
if (ix == 1) then
zt(k) = g(dzero,y,z)*(-val(icoeff)) + zt(k)
else
call ijk2idx(icol(icoeff),ix-1,iy,iz,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
endif
! term depending on (x,y-1,z)
val(icoeff) = -a2(x,y,z)/sqdeltah-b2(x,y,z)/deltah2
if (iy == 1) then
zt(k) = g(x,dzero,z)*(-val(icoeff)) + zt(k)
else
call ijk2idx(icol(icoeff),ix,iy-1,iz,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
endif
! term depending on (x,y,z-1)
val(icoeff)=-a3(x,y,z)/sqdeltah-b3(x,y,z)/deltah2
if (iz == 1) then
zt(k) = g(x,y,dzero)*(-val(icoeff)) + zt(k)
else
call ijk2idx(icol(icoeff),ix,iy,iz-1,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
endif
! term depending on (x,y,z)
val(icoeff)=(2*done)*(a1(x,y,z)+a2(x,y,z)+a3(x,y,z))/sqdeltah &
& + c(x,y,z)
call ijk2idx(icol(icoeff),ix,iy,iz,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
! term depending on (x,y,z+1)
val(icoeff)=-a3(x,y,z)/sqdeltah+b3(x,y,z)/deltah2
if (iz == idim) then
zt(k) = g(x,y,done)*(-val(icoeff)) + zt(k)
else
call ijk2idx(icol(icoeff),ix,iy,iz+1,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
endif
! term depending on (x,y+1,z)
val(icoeff)=-a2(x,y,z)/sqdeltah+b2(x,y,z)/deltah2
if (iy == idim) then
zt(k) = g(x,done,z)*(-val(icoeff)) + zt(k)
else
call ijk2idx(icol(icoeff),ix,iy+1,iz,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
endif
! term depending on (x+1,y,z)
val(icoeff)=-a1(x,y,z)/sqdeltah+b1(x,y,z)/deltah2
if (ix==idim) then
zt(k) = g(done,y,z)*(-val(icoeff)) + zt(k)
else
call ijk2idx(icol(icoeff),ix+1,iy,iz,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
endif
end do
call psb_spins(icoeff-1,irow,icol,val,a,desc_a,info)
if(info /= psb_success_) exit
call psb_geins(ib,myidx(ii:ii+ib-1),zt(1:ib),bv,desc_a,info)
if(info /= psb_success_) exit
zt(:)=dzero
call psb_geins(ib,myidx(ii:ii+ib-1),zt(1:ib),xv,desc_a,info)
if(info /= psb_success_) exit
end do
tgen = psb_wtime()-t1
if(info /= psb_success_) then
info=psb_err_from_subroutine_
ch_err='insert rout.'
call psb_errpush(info,name,a_err=ch_err)
goto 9999
end if
deallocate(val,irow,icol)
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_cdasb(desc_a,info,mold=imold)
tcdasb = psb_wtime()-t1
call psb_barrier(ctxt)
t1 = psb_wtime()
if (info == psb_success_) then
if (present(amold)) then
call psb_spasb(a,desc_a,info,dupl=psb_dupl_err_,mold=amold)
else
call psb_spasb(a,desc_a,info,dupl=psb_dupl_err_,afmt=afmt)
end if
end if
call psb_barrier(ctxt)
if(info /= psb_success_) then
info=psb_err_from_subroutine_
ch_err='asb rout.'
call psb_errpush(info,name,a_err=ch_err)
goto 9999
end if
if (info == psb_success_) call psb_geasb(xv,desc_a,info,mold=vmold)
if (info == psb_success_) call psb_geasb(bv,desc_a,info,mold=vmold)
if(info /= psb_success_) then
info=psb_err_from_subroutine_
ch_err='asb rout.'
call psb_errpush(info,name,a_err=ch_err)
goto 9999
end if
tasb = psb_wtime()-t1
call psb_barrier(ctxt)
ttot = psb_wtime() - t0
call psb_amx(ctxt,talc)
call psb_amx(ctxt,tgen)
call psb_amx(ctxt,tasb)
call psb_amx(ctxt,ttot)
if(iam == psb_root_) then
tmpfmt = a%get_fmt()
write(psb_out_unit,'("The matrix has been generated and assembled in ",a3," format.")')&
& tmpfmt
write(psb_out_unit,'("-allocation time : ",es12.5)') talc
write(psb_out_unit,'("-coeff. gen. time : ",es12.5)') tgen
write(psb_out_unit,'("-desc asbly time : ",es12.5)') tcdasb
write(psb_out_unit,'("- mat asbly time : ",es12.5)') tasb
write(psb_out_unit,'("-total time : ",es12.5)') ttot
end if
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(ctxt,err_act)
return
end subroutine amg_d_gen_pde3d
!
! functions parametrizing the differential equation
!
function b1(x,y,z)
use psb_base_mod, only : psb_dpk_, done
real(psb_dpk_) :: b1
real(psb_dpk_), intent(in) :: x,y,z
b1=dzero
end function b1
function b2(x,y,z)
use psb_base_mod, only : psb_dpk_, done
real(psb_dpk_) :: b2
real(psb_dpk_), intent(in) :: x,y,z
b2=dzero
end function b2
function b3(x,y,z)
use psb_base_mod, only : psb_dpk_, done
real(psb_dpk_) :: b3
real(psb_dpk_), intent(in) :: x,y,z
b3=dzero
end function b3
function c(x,y,z)
use psb_base_mod, only : psb_dpk_, done
real(psb_dpk_) :: c
real(psb_dpk_), intent(in) :: x,y,z
c=dzero
end function c
function a1(x,y,z)
use psb_base_mod, only : psb_dpk_, done
real(psb_dpk_) :: a1
real(psb_dpk_), intent(in) :: x,y,z
a1=done
end function a1
function a2(x,y,z)
use psb_base_mod, only : psb_dpk_, done
real(psb_dpk_) :: a2
real(psb_dpk_), intent(in) :: x,y,z
a2=done
end function a2
function a3(x,y,z)
use psb_base_mod, only : psb_dpk_, done
real(psb_dpk_) :: a3
real(psb_dpk_), intent(in) :: x,y,z
a3=done
end function a3
function g(x,y,z)
use psb_base_mod, only : psb_dpk_, done, dzero
real(psb_dpk_) :: g
real(psb_dpk_), intent(in) :: x,y,z
g = dzero
if (x == done) then
g = done
else if (x == dzero) then
g = exp(y**2-z**2)
end if
end function g
end module amg_d_pde_mod
+276
View File
@@ -0,0 +1,276 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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.
!
!
! File: amg_sexample_1lev.f90
!
! This sample program solves a linear system obtained by discretizing a
! PDE with Dirichlet BCs. The solver is BiCGStab preconditioned by
! RAS with overlap 2 and ILU(0) on the local blocks, as explained in Section 4.1
! of the AMG4PSBLAS User's and Reference Guide.
!
!
! The PDE is a general second order equation in 3d
!
! a1 dd(u) a2 dd(u) a3 dd(u) b1 d(u) b2 d(u) b3 d(u)
! - ------ - ------ - ------ + ----- + ------ + ------ + c u = f
! dxdx dydy dzdz dx dy dz
!
! with Dirichlet boundary conditions
! u = g
!
! on the unit cube 0<=x,y,z<=1.
!
!
! Note that if b1=b2=b3=c=0., the PDE is the Laplace equation.
!
program amg_sexample_1lev
use psb_base_mod
use amg_prec_mod
use psb_krylov_mod
use psb_util_mod
use data_input
use amg_s_pde_mod
implicit none
! sparse matrices
type(psb_sspmat_type) :: A
! descriptor of sparse matrices
type(psb_desc_type):: desc_A
! preconditioner
type(amg_sprec_type) :: P
! right-hand side, solution and residual vectors
type(psb_s_vect_type) :: x, b, r
! solver parameters
real(psb_spk_) :: tol, err
integer :: itmax, iter, itrace, istop
! parallel environment parameters
type(psb_ctxt_type) :: ctxt
integer :: iam, np
! other variables
integer :: i,info,j
integer(psb_epk_) :: amatsize, precsize, descsize
integer(psb_epk_) :: system_size
integer :: idim, nlev, ierr, ircode
real(psb_spk_) :: resmx, resmxp
real(psb_dpk_) :: t1, t2, tprec
character(len=5) :: afmt='CSR'
character(len=20) :: name, kmethod
! initialize the parallel environment
call psb_init(ctxt)
call psb_info(ctxt,iam,np)
if (iam < 0) then
! This should not happen, but just in case
call psb_exit(ctxt)
stop
endif
name='amg_sexample_ml'
if(psb_get_errstatus() /= 0) goto 9999
info=psb_success_
call psb_set_errverbosity(2)
!
! Hello world
!
if (iam == psb_root_) then
write(*,*) 'Welcome to AMG4PSBLAS version: ',amg_version_string_
write(*,*) 'This is the ',trim(name),' sample program'
end if
! get parameters
call get_parms(ctxt,idim,itmax,tol)
! allocate and fill in the coefficient matrix, rhs and initial guess
call psb_barrier(ctxt)
t1 = psb_wtime()
call amg_gen_pde3d(ctxt,idim,a,b,x,desc_a,afmt,&
& a1,a2,a3,b1,b2,b3,c,g,info)
call psb_barrier(ctxt)
t2 = psb_wtime() - t1
if(info /= psb_success_) then
info=psb_err_from_subroutine_
call psb_errpush(info,name)
goto 9999
end if
if (iam == psb_root_) write(*,'("Overall matrix creation time : ",es12.5)')t2
if (iam == psb_root_) write(*,'(" ")')
! set RAS
call P%init(ctxt,'AS',info)
! set number of overlaps
call P%set('SUB_OVR',2,info)
! build the preconditioner
t1 = psb_wtime()
call P%build(A,desc_A,info)
tprec = psb_wtime()-t1
call psb_amx(ctxt, tprec)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,a_err='amg_precbld')
goto 9999
end if
! set the initial guess
call psb_geall(x,desc_A,info)
call x%zero()
call psb_geasb(x,desc_A,info)
! solve Ax=b with preconditioned Krylov method: BiCGSTAB
kmethod = 'BiCGSTAB'
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_krylov(kmethod,A,P,b,x,tol,desc_A,info,itmax,iter,err,itrace=1,istop=2)
t2 = psb_wtime() - t1
call psb_amx(ctxt,t2)
call psb_geall(r,desc_A,info)
call r%zero()
call psb_geasb(r,desc_A,info)
call psb_geaxpby(sone,b,szero,r,desc_A,info)
call psb_spmm(-sone,A,x,sone,r,desc_A,info)
resmx = psb_genrm2(r,desc_A,info)
resmxp = psb_geamax(r,desc_A,info)
amatsize = a%sizeof()
descsize = desc_a%sizeof()
precsize = p%sizeof()
system_size = desc_a%get_global_rows()
call psb_sum(ctxt,amatsize)
call psb_sum(ctxt,descsize)
call psb_sum(ctxt,precsize)
call P%descr(info)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Matrix from PDE example")')
write(*,'("Computed solution on ",i8," processors")')np
write(*,'("Linear system size : ",i12)') system_size
write(*,'("Krylov method : ",a)') kmethod
write(*,'("Iterations to convergence : ",i6)')iter
write(*,'("Error estimate on exit : ",es12.5)')err
write(*,'("Time to build prec. : ",es12.5)')tprec
write(*,'("Time to solve system : ",es12.5)')t2
write(*,'("Time per iteration : ",es12.5)')t2/(iter)
write(*,'("Total time : ",es12.5)')t2+tprec
write(*,'("Residual 2-norm : ",es12.5)')resmx
write(*,'("Residual inf-norm : ",es12.5)')resmxp
write(*,'("Total memory occupation for A : ",i12)')amatsize
write(*,'("Total memory occupation for DESC_A : ",i12)')descsize
write(*,'("Total memory occupation for PREC : ",i12)')precsize
end if
call psb_gefree(b, desc_A,info)
call psb_gefree(x, desc_A,info)
call psb_spfree(A, desc_A,info)
call P%free(info)
call psb_cdfree(desc_A,info)
call psb_exit(ctxt)
stop
9999 continue
call psb_error(ctxt)
contains
!
! get parameters from standard input
!
subroutine get_parms(ctxt,idim,itmax,tol)
implicit none
type(psb_ctxt_type) :: ctxt
integer :: idim, itmax
real(psb_spk_) :: tol
integer :: iam, np, inp_unit
character(len=1024) :: filename
call psb_info(ctxt,iam,np)
if (iam == psb_root_) then
if (command_argument_count()>0) then
call get_command_argument(1,filename)
inp_unit = 30
open(inp_unit,file=filename,action='read',iostat=info)
if (info /= 0) then
write(psb_err_unit,*) 'Could not open file ',filename,' for input'
call psb_abort(ctxt)
stop
else
write(psb_err_unit,*) 'Opened file ',trim(filename),' for input'
end if
else
inp_unit=psb_inp_unit
end if
! read input parameters
call read_data(idim,inp_unit)
call read_data(itmax,inp_unit)
call read_data(tol,inp_unit)
if (inp_unit /= psb_inp_unit) then
close(inp_unit)
end if
end if
call psb_bcast(ctxt,idim)
call psb_bcast(ctxt,itmax)
call psb_bcast(ctxt,tol)
end subroutine get_parms
end program amg_sexample_1lev
+340
View File
@@ -0,0 +1,340 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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.
!
!
! File: amg_sexample_ml.f90
!
! This sample program solves a linear system obtained by discretizing a
! PDE with Dirichlet BCs. The solver is CG, coupled with one of the
! following multi-level preconditioner, as explained in Section 4.1 of
! the AMG4PSBLAS User's and Reference Guide:
!
! - choice = 1, the default multi-level preconditioner solver, i.e.,
! V-cycle with decoupled smoothed aggregation, 1 hybrid forward/backward
! GS sweep as pre/post-smoother and UMFPACK as coarsest-level
! solver (Sec. 4.1, Listing 1)
!
! - choice = 2, a V-cycle preconditioner with 1 block-Jacobi sweep
! (with ILU(0) on the blocks) as pre- and post-smoother, and 8 block-Jacobi
! sweeps (with ILU(0) on the blocks) as coarsest-level solver (Sec. 4.1, Listing 2)
!
! - choice = 3, W-cycle preconditioner based on the coupled aggregation relying
! on matching, with maximum size of aggregates equal to 8 and smoothed prolongators,
! 2 hybrid forward/backward GS sweeps as pre/post-smoother, a distributed coarsest
! matrix, and preconditioned Flexible Conjugate Gradient as coarsest-level solver
! (Sec. 4.1, Listing 3)
!
! The matrix and the rhs are read from files (if an rhs is not available, the
! unit rhs is set).
!
!
! The PDE is a general second order equation in 3d
!
! a1 dd(u) a2 dd(u) a3 dd(u) b1 d(u) b2 d(u) b3 d(u)
! - ------ - ------ - ------ + ----- + ------ + ------ + c u = f
! dxdx dydy dzdz dx dy dz
!
! with Dirichlet boundary conditions
! u = g
!
! on the unit cube 0<=x,y,z<=1.
!
!
! Note that if b1=b2=b3=c=0., the PDE is the Laplace equation.
!
! In this sample program the index space of the discretized
! computational domain is first numbered sequentially in a standard way,
! then the corresponding vector is distributed according to a BLOCK
! data distribution.
!
program amg_sexample_ml
use psb_base_mod
use amg_prec_mod
use psb_krylov_mod
use psb_util_mod
use data_input
use amg_s_pde_mod
implicit none
! input parameters
! sparse matrices
type(psb_sspmat_type) :: A
! sparse matrices descriptor
type(psb_desc_type):: desc_A
! preconditioner
type(amg_sprec_type) :: P
! right-hand side, solution and residual vectors
type(psb_s_vect_type) :: x, b, r
! solver and preconditioner parameters
real(psb_spk_) :: tol, err
integer :: itmax, iter, istop
integer :: nlev
! parallel environment parameters
type(psb_ctxt_type) :: ctxt
integer :: iam, np
! other variables
integer :: choice
integer :: i,info,j
integer(psb_epk_) :: amatsize, precsize, descsize
integer(psb_epk_) :: system_size
integer :: idim, ierr, ircode
real(psb_spk_) :: resmx, resmxp
real(psb_dpk_) :: t1, t2, tprec
character(len=5) :: afmt='CSR'
character(len=20) :: name, kmethod
! initialize the parallel environment
call psb_init(ctxt)
call psb_info(ctxt,iam,np)
if (iam < 0) then
! This should not happen, but just in case
call psb_exit(ctxt)
stop
endif
name='amg_sexample_ml'
if(psb_get_errstatus() /= 0) goto 9999
info=psb_success_
call psb_set_errverbosity(2)
!
! Hello world
!
if (iam == psb_root_) then
write(*,*) 'Welcome to AMG4PSBLAS version: ',amg_version_string_
write(*,*) 'This is the ',trim(name),' sample program'
end if
! get parameters
call get_parms(ctxt,choice,idim,itmax,tol)
! allocate and fill in the coefficient matrix, rhs and initial guess
call psb_barrier(ctxt)
t1 = psb_wtime()
call amg_gen_pde3d(ctxt,idim,a,b,x,desc_a,afmt,&
& a1,a2,a3,b1,b2,b3,c,g,info)
call psb_barrier(ctxt)
t2 = psb_wtime() - t1
if(info /= psb_success_) then
info=psb_err_from_subroutine_
call psb_errpush(info,name)
goto 9999
end if
if (iam == psb_root_) write(*,'("Overall matrix creation time : ",es12.5)')t2
if (iam == psb_root_) write(*,'(" ")')
select case(choice)
case(1)
! initialize the default multi-level preconditioner, i.e. V-cycle
! with basic smoothed aggregation, 1 hybrid forward/backward
! GS sweep as pre/post-smoother and UMFPACK as coarsest-level
! solver
call P%init(ctxt,'ML',info)
kmethod = 'CG'
case(2)
! initialize a V-cycle preconditioner with 1 block-Jacobi sweep (with
! ILU(0) on the blocks) as pre- and post-smoother, and 8 block-Jacobi
! sweeps (with ILU(0) on the blocks) as coarsest-level solver
call P%init(ctxt,'ML',info)
call P%set('SMOOTHER_TYPE','BJAC',info)
call P%set('COARSE_SOLVE','BJAC',info)
call P%set('COARSE_SWEEPS',8,info)
kmethod = 'CG'
case(3)
! initialize a W-cycle preconditioner based on the coupled aggregation relying on matching,
! with maximum size of aggregates equal to 8 and smoothed prolongators,
! 2 hybrid forward/backward GS sweeps as pre/post-smoother, a distributed coarsest
! matrix, and preconditioned Flexible Conjugate Gradient as coarsest-level solver
call P%init(ctxt,'ML',info)
call P%set('PAR_AGGR_ALG','COUPLED',info)
call P%set('AGGR_TYPE','MATCHBOXP',info)
call P%set('AGGR_SIZE',8,info)
call P%set('ML_CYCLE','WCYCLE',info)
call P%set('SMOOTHER_SWEEPS',2,info)
call P%set('COARSE_SOLVE','KRM',info)
call P%set('COARSE_MAT','DIST',info)
kmethod = 'CG'
end select
call psb_barrier(ctxt)
t1 = psb_wtime()
! build the preconditioner
call P%hierarchy_build(A,desc_A,info)
call P%smoothers_build(A,desc_A,info)
tprec = psb_wtime()-t1
call psb_amx(ctxt, tprec)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,a_err='amg_precbld')
goto 9999
end if
! set the solver parameters and the initial guess
call psb_geall(x,desc_A,info)
call x%zero()
call psb_geasb(x,desc_A,info)
! solve Ax=b with preconditioned Krylov method
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_krylov(kmethod,A,P,b,x,tol,desc_A,info,itmax,iter,err,itrace=1,istop=2)
t2 = psb_wtime() - t1
call psb_amx(ctxt,t2)
call psb_geall(r,desc_A,info)
call r%zero()
call psb_geasb(r,desc_A,info)
call psb_geaxpby(sone,b,szero,r,desc_A,info)
call psb_spmm(-sone,A,x,sone,r,desc_A,info)
resmx = psb_genrm2(r,desc_A,info)
resmxp = psb_geamax(r,desc_A,info)
amatsize = a%sizeof()
descsize = desc_a%sizeof()
precsize = p%sizeof()
system_size = desc_a%get_global_rows()
call psb_sum(ctxt,amatsize)
call psb_sum(ctxt,descsize)
call psb_sum(ctxt,precsize)
call P%descr(info)
if (iam == psb_root_) then
write(*,'(" ")')
write(*,'("Matrix from PDE example")')
write(*,'("Computed solution on ",i8," processors")')np
write(*,'("Linear system size : ",i12)') system_size
write(*,'("Krylov method : ",a)') kmethod
write(*,'("Iterations to convergence : ",i6)')iter
write(*,'("Error estimate on exit : ",es12.5)')err
write(*,'("Time to build prec. : ",es12.5)')tprec
write(*,'("Time to solve system : ",es12.5)')t2
write(*,'("Time per iteration : ",es12.5)')t2/(iter)
write(*,'("Total time : ",es12.5)')t2+tprec
write(*,'("Residual 2-norm : ",es12.5)')resmx
write(*,'("Residual inf-norm : ",es12.5)')resmxp
write(*,'("Total memory occupation for A : ",i12)')amatsize
write(*,'("Total memory occupation for DESC_A : ",i12)')descsize
write(*,'("Total memory occupation for PREC : ",i12)')precsize
end if
call psb_gefree(b, desc_A,info)
call psb_gefree(x, desc_A,info)
call psb_spfree(A, desc_A,info)
call P%free(info)
call psb_cdfree(desc_A,info)
call psb_exit(ctxt)
stop
9999 continue
call psb_error(ctxt)
contains
!
! get parameters from standard input
!
subroutine get_parms(ctxt,choice,idim,itmax,tol)
implicit none
type(psb_ctxt_type) :: ctxt
integer :: choice, idim, itmax
real(psb_spk_) :: tol
integer :: iam, np, inp_unit
character(len=1024) :: filename
call psb_info(ctxt,iam,np)
if (iam == psb_root_) then
if (command_argument_count()>0) then
call get_command_argument(1,filename)
inp_unit = 30
open(inp_unit,file=filename,action='read',iostat=info)
if (info /= 0) then
write(psb_err_unit,*) 'Could not open file ',filename,' for input'
call psb_abort(ctxt)
stop
else
write(psb_err_unit,*) 'Opened file ',trim(filename),' for input'
end if
else
inp_unit=psb_inp_unit
end if
! read input parameters
call read_data(choice,inp_unit)
call read_data(idim,inp_unit)
call read_data(itmax,inp_unit)
call read_data(tol,inp_unit)
if (inp_unit /= psb_inp_unit) then
close(inp_unit)
end if
end if
call psb_bcast(ctxt,choice)
call psb_bcast(ctxt,idim)
call psb_bcast(ctxt,itmax)
call psb_bcast(ctxt,tol)
end subroutine get_parms
end program amg_sexample_ml
+572
View File
@@ -0,0 +1,572 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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 amg_s_pde_mod
use psb_base_mod, only : psb_spk_, psb_ipk_, psb_desc_type,&
& psb_sspmat_type, psb_s_vect_type, szero, sone,&
& psb_s_base_sparse_mat, psb_s_base_vect_type, psb_i_base_vect_type
interface
function s_func_3d(x,y,z) result(val)
import :: psb_spk_
real(psb_spk_), intent(in) :: x,y,z
real(psb_spk_) :: val
end function s_func_3d
end interface
interface amg_gen_pde3d
module procedure amg_s_gen_pde3d
end interface amg_gen_pde3d
contains
function s_null_func_3d(x,y,z) result(val)
real(psb_spk_), intent(in) :: x,y,z
real(psb_spk_) :: val
val = szero
end function s_null_func_3d
!
! subroutine to allocate and fill in the coefficient matrix and
! the rhs.
!
subroutine amg_s_gen_pde3d(ctxt,idim,a,bv,xv,desc_a,afmt,&
& a1,a2,a3,b1,b2,b3,c,g,info,f,amold,vmold,imold,partition,nrl,iv)
use psb_base_mod
use psb_util_mod
!
! Discretizes the partial differential equation
!
! a1 dd(u) a2 dd(u) a3 dd(u) b1 d(u) b2 d(u) b3 d(u)
! - ------ - ------ - ------ + ----- + ------ + ------ + c u = f
! dxdx dydy dzdz dx dy dz
!
! with Dirichlet boundary conditions
! u = g
!
! on the unit cube 0<=x,y,z<=1.
!
!
! Note that if b1=b2=b3=c=0., the PDE is the Laplace equation.
!
implicit none
procedure(s_func_3d) :: b1,b2,b3,c,a1,a2,a3,g
integer(psb_ipk_) :: idim
type(psb_sspmat_type) :: a
type(psb_s_vect_type) :: xv,bv
type(psb_desc_type) :: desc_a
integer(psb_ipk_) :: info
type(psb_ctxt_type) :: ctxt
character :: afmt*5
procedure(s_func_3d), optional :: f
class(psb_s_base_sparse_mat), optional :: amold
class(psb_s_base_vect_type), optional :: vmold
class(psb_i_base_vect_type), optional :: imold
integer(psb_ipk_), optional :: partition, nrl,iv(:)
! Local variables.
integer(psb_ipk_), parameter :: nb=20
type(psb_s_csc_sparse_mat) :: acsc
type(psb_s_coo_sparse_mat) :: acoo
type(psb_s_csr_sparse_mat) :: acsr
real(psb_spk_) :: zt(nb),x,y,z,xph,xmh,yph,ymh,zph,zmh
integer(psb_ipk_) :: nnz,nr,nlr,i,j,ii,ib,k, partition_
integer(psb_lpk_) :: m,n,glob_row,nt
integer(psb_ipk_) :: ix,iy,iz,ia,indx_owner
! For 3D partition
! Note: integer control variables going directly into an MPI call
! must be 4 bytes, i.e. psb_mpk_
integer(psb_mpk_) :: npdims(3), npp, minfo
integer(psb_ipk_) :: npx,npy,npz, iamx,iamy,iamz,mynx,myny,mynz
integer(psb_ipk_), allocatable :: bndx(:),bndy(:),bndz(:)
! Process grid
integer(psb_ipk_) :: np, iam
integer(psb_ipk_) :: icoeff
integer(psb_lpk_), allocatable :: irow(:),icol(:),myidx(:)
real(psb_spk_), allocatable :: val(:)
! deltah dimension of each grid cell
! deltat discretization time
real(psb_spk_) :: deltah, sqdeltah, deltah2
real(psb_spk_), parameter :: rhs=szero,one=sone,zero=szero
real(psb_dpk_) :: t0, t1, t2, t3, tasb, talc, ttot, tgen, tcdasb
integer(psb_ipk_) :: err_act
procedure(s_func_3d), pointer :: f_
character(len=20) :: name, ch_err,tmpfmt
info = psb_success_
name = 'create_matrix'
call psb_erractionsave(err_act)
call psb_info(ctxt, iam, np)
if (present(f)) then
f_ => f
else
f_ => s_null_func_3d
end if
deltah = 1.d0/(idim+1)
sqdeltah = deltah*deltah
deltah2 = 2.0_psb_spk_* deltah
if (present(partition)) then
if ((1<= partition).and.(partition <= 3)) then
partition_ = partition
else
write(*,*) 'Invalid partition choice ',partition,' defaulting to 3'
partition_ = 3
end if
else
partition_ = 3
end if
! initialize array descriptor and sparse matrix storage. provide an
! estimate of the number of non zeroes
m = (1_psb_lpk_*idim)*idim*idim
n = m
nnz = 7*((n+np-1)/np)
if(iam == psb_root_) write(psb_out_unit,'("Generating Matrix (size=",i0,")...")')n
select case(partition_)
case(1)
! A BLOCK partition
if (present(nrl)) then
nr = nrl
else
!
! Using a simple BLOCK distribution.
!
nt = (m+np-1)/np
nr = max(0,min(nt,m-(iam*nt)))
end if
nt = nr
call psb_sum(ctxt,nt)
if (nt /= m) then
write(psb_err_unit,*) iam, 'Initialization error ',nr,nt,m
info = -1
call psb_barrier(ctxt)
call psb_abort(ctxt)
return
end if
!
! First example of use of CDALL: specify for each process a number of
! contiguous rows
!
call psb_cdall(ctxt,desc_a,info,nl=nr)
myidx = desc_a%get_global_indices()
nlr = size(myidx)
case(2)
! A partition defined by the user through IV
if (present(iv)) then
if (size(iv) /= m) then
write(psb_err_unit,*) iam, 'Initialization error: wrong IV size',size(iv),m
info = -1
call psb_barrier(ctxt)
call psb_abort(ctxt)
return
end if
else
write(psb_err_unit,*) iam, 'Initialization error: IV not present'
info = -1
call psb_barrier(ctxt)
call psb_abort(ctxt)
return
end if
!
! Second example of use of CDALL: specify for each row the
! process that owns it
!
call psb_cdall(ctxt,desc_a,info,vg=iv)
myidx = desc_a%get_global_indices()
nlr = size(myidx)
case(3)
! A 3-dimensional partition
! A nifty MPI function will split the process list
npdims = 0
call mpi_dims_create(np,3,npdims,info)
npx = npdims(1)
npy = npdims(2)
npz = npdims(3)
allocate(bndx(0:npx),bndy(0:npy),bndz(0:npz))
! We can reuse idx2ijk for process indices as well.
call idx2ijk(iamx,iamy,iamz,iam,npx,npy,npz,base=0)
! Now let's split the 3D cube in hexahedra
call dist1Didx(bndx,idim,npx)
mynx = bndx(iamx+1)-bndx(iamx)
call dist1Didx(bndy,idim,npy)
myny = bndy(iamy+1)-bndy(iamy)
call dist1Didx(bndz,idim,npz)
mynz = bndz(iamz+1)-bndz(iamz)
! How many indices do I own?
nlr = mynx*myny*mynz
allocate(myidx(nlr))
! Now, let's generate the list of indices I own
nr = 0
do i=bndx(iamx),bndx(iamx+1)-1
do j=bndy(iamy),bndy(iamy+1)-1
do k=bndz(iamz),bndz(iamz+1)-1
nr = nr + 1
call ijk2idx(myidx(nr),i,j,k,idim,idim,idim)
end do
end do
end do
if (nr /= nlr) then
write(psb_err_unit,*) iam,iamx,iamy,iamz, 'Initialization error: NR vs NLR ',&
& nr,nlr,mynx,myny,mynz
info = -1
call psb_barrier(ctxt)
call psb_abort(ctxt)
end if
!
! Third example of use of CDALL: specify for each process
! the set of global indices it owns.
!
call psb_cdall(ctxt,desc_a,info,vl=myidx)
!
! Specify process topology
!
block
!
! Use adjcncy methods
!
integer(psb_mpk_), allocatable :: neighbours(:)
integer(psb_mpk_) :: cnt
logical, parameter :: debug_adj=.true.
if (debug_adj.and.(np > 1)) then
cnt = 0
allocate(neighbours(np))
if (iamx < npx-1) then
cnt = cnt + 1
call ijk2idx(neighbours(cnt),iamx+1,iamy,iamz,npx,npy,npz,base=0)
end if
if (iamy < npy-1) then
cnt = cnt + 1
call ijk2idx(neighbours(cnt),iamx,iamy+1,iamz,npx,npy,npz,base=0)
end if
if (iamz < npz-1) then
cnt = cnt + 1
call ijk2idx(neighbours(cnt),iamx,iamy,iamz+1,npx,npy,npz,base=0)
end if
if (iamx >0) then
cnt = cnt + 1
call ijk2idx(neighbours(cnt),iamx-1,iamy,iamz,npx,npy,npz,base=0)
end if
if (iamy >0) then
cnt = cnt + 1
call ijk2idx(neighbours(cnt),iamx,iamy-1,iamz,npx,npy,npz,base=0)
end if
if (iamz >0) then
cnt = cnt + 1
call ijk2idx(neighbours(cnt),iamx,iamy,iamz-1,npx,npy,npz,base=0)
end if
call psb_realloc(cnt, neighbours,info)
call desc_a%set_p_adjcncy(neighbours)
!write(0,*) iam,' Check on neighbours: ',desc_a%get_p_adjcncy()
end if
end block
case default
write(psb_err_unit,*) iam, 'Initialization error: should not get here'
info = -1
call psb_barrier(ctxt)
call psb_abort(ctxt)
return
end select
if (info == psb_success_) call psb_spall(a,desc_a,info,nnz=nnz)
! define rhs from boundary conditions; also build initial guess
if (info == psb_success_) call psb_geall(xv,desc_a,info)
if (info == psb_success_) call psb_geall(bv,desc_a,info)
call psb_barrier(ctxt)
talc = psb_wtime()-t0
if (info /= psb_success_) then
info=psb_err_from_subroutine_
ch_err='allocation rout.'
call psb_errpush(info,name,a_err=ch_err)
goto 9999
end if
! we build an auxiliary matrix consisting of one row at a
! time; just a small matrix. might be extended to generate
! a bunch of rows per call.
!
allocate(val(20*nb),irow(20*nb),&
&icol(20*nb),stat=info)
if (info /= psb_success_ ) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
endif
! loop over rows belonging to current process in a block
! distribution.
call psb_barrier(ctxt)
t1 = psb_wtime()
do ii=1, nlr,nb
ib = min(nb,nlr-ii+1)
icoeff = 1
do k=1,ib
i=ii+k-1
! local matrix pointer
glob_row=myidx(i)
! compute gridpoint coordinates
call idx2ijk(ix,iy,iz,glob_row,idim,idim,idim)
! x, y, z coordinates
x = (ix-1)*deltah
y = (iy-1)*deltah
z = (iz-1)*deltah
zt(k) = f_(x,y,z)
! internal point: build discretization
!
! term depending on (x-1,y,z)
!
val(icoeff) = -a1(x,y,z)/sqdeltah-b1(x,y,z)/deltah2
if (ix == 1) then
zt(k) = g(szero,y,z)*(-val(icoeff)) + zt(k)
else
call ijk2idx(icol(icoeff),ix-1,iy,iz,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
endif
! term depending on (x,y-1,z)
val(icoeff) = -a2(x,y,z)/sqdeltah-b2(x,y,z)/deltah2
if (iy == 1) then
zt(k) = g(x,szero,z)*(-val(icoeff)) + zt(k)
else
call ijk2idx(icol(icoeff),ix,iy-1,iz,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
endif
! term depending on (x,y,z-1)
val(icoeff)=-a3(x,y,z)/sqdeltah-b3(x,y,z)/deltah2
if (iz == 1) then
zt(k) = g(x,y,szero)*(-val(icoeff)) + zt(k)
else
call ijk2idx(icol(icoeff),ix,iy,iz-1,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
endif
! term depending on (x,y,z)
val(icoeff)=(2*sone)*(a1(x,y,z)+a2(x,y,z)+a3(x,y,z))/sqdeltah &
& + c(x,y,z)
call ijk2idx(icol(icoeff),ix,iy,iz,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
! term depending on (x,y,z+1)
val(icoeff)=-a3(x,y,z)/sqdeltah+b3(x,y,z)/deltah2
if (iz == idim) then
zt(k) = g(x,y,sone)*(-val(icoeff)) + zt(k)
else
call ijk2idx(icol(icoeff),ix,iy,iz+1,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
endif
! term depending on (x,y+1,z)
val(icoeff)=-a2(x,y,z)/sqdeltah+b2(x,y,z)/deltah2
if (iy == idim) then
zt(k) = g(x,sone,z)*(-val(icoeff)) + zt(k)
else
call ijk2idx(icol(icoeff),ix,iy+1,iz,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
endif
! term depending on (x+1,y,z)
val(icoeff)=-a1(x,y,z)/sqdeltah+b1(x,y,z)/deltah2
if (ix==idim) then
zt(k) = g(sone,y,z)*(-val(icoeff)) + zt(k)
else
call ijk2idx(icol(icoeff),ix+1,iy,iz,idim,idim,idim)
irow(icoeff) = glob_row
icoeff = icoeff+1
endif
end do
call psb_spins(icoeff-1,irow,icol,val,a,desc_a,info)
if(info /= psb_success_) exit
call psb_geins(ib,myidx(ii:ii+ib-1),zt(1:ib),bv,desc_a,info)
if(info /= psb_success_) exit
zt(:)=szero
call psb_geins(ib,myidx(ii:ii+ib-1),zt(1:ib),xv,desc_a,info)
if(info /= psb_success_) exit
end do
tgen = psb_wtime()-t1
if(info /= psb_success_) then
info=psb_err_from_subroutine_
ch_err='insert rout.'
call psb_errpush(info,name,a_err=ch_err)
goto 9999
end if
deallocate(val,irow,icol)
call psb_barrier(ctxt)
t1 = psb_wtime()
call psb_cdasb(desc_a,info,mold=imold)
tcdasb = psb_wtime()-t1
call psb_barrier(ctxt)
t1 = psb_wtime()
if (info == psb_success_) then
if (present(amold)) then
call psb_spasb(a,desc_a,info,dupl=psb_dupl_err_,mold=amold)
else
call psb_spasb(a,desc_a,info,dupl=psb_dupl_err_,afmt=afmt)
end if
end if
call psb_barrier(ctxt)
if(info /= psb_success_) then
info=psb_err_from_subroutine_
ch_err='asb rout.'
call psb_errpush(info,name,a_err=ch_err)
goto 9999
end if
if (info == psb_success_) call psb_geasb(xv,desc_a,info,mold=vmold)
if (info == psb_success_) call psb_geasb(bv,desc_a,info,mold=vmold)
if(info /= psb_success_) then
info=psb_err_from_subroutine_
ch_err='asb rout.'
call psb_errpush(info,name,a_err=ch_err)
goto 9999
end if
tasb = psb_wtime()-t1
call psb_barrier(ctxt)
ttot = psb_wtime() - t0
call psb_amx(ctxt,talc)
call psb_amx(ctxt,tgen)
call psb_amx(ctxt,tasb)
call psb_amx(ctxt,ttot)
if(iam == psb_root_) then
tmpfmt = a%get_fmt()
write(psb_out_unit,'("The matrix has been generated and assembled in ",a3," format.")')&
& tmpfmt
write(psb_out_unit,'("-allocation time : ",es12.5)') talc
write(psb_out_unit,'("-coeff. gen. time : ",es12.5)') tgen
write(psb_out_unit,'("-desc asbly time : ",es12.5)') tcdasb
write(psb_out_unit,'("- mat asbly time : ",es12.5)') tasb
write(psb_out_unit,'("-total time : ",es12.5)') ttot
end if
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(ctxt,err_act)
return
end subroutine amg_s_gen_pde3d
!
! functions parametrizing the differential equation
!
function b1(x,y,z)
use psb_base_mod, only : psb_spk_, sone
real(psb_spk_) :: b1
real(psb_spk_), intent(in) :: x,y,z
b1=szero
end function b1
function b2(x,y,z)
use psb_base_mod, only : psb_spk_, sone
real(psb_spk_) :: b2
real(psb_spk_), intent(in) :: x,y,z
b2=szero
end function b2
function b3(x,y,z)
use psb_base_mod, only : psb_spk_, sone
real(psb_spk_) :: b3
real(psb_spk_), intent(in) :: x,y,z
b3=szero
end function b3
function c(x,y,z)
use psb_base_mod, only : psb_spk_, sone
real(psb_spk_) :: c
real(psb_spk_), intent(in) :: x,y,z
c=szero
end function c
function a1(x,y,z)
use psb_base_mod, only : psb_spk_, sone
real(psb_spk_) :: a1
real(psb_spk_), intent(in) :: x,y,z
a1=sone
end function a1
function a2(x,y,z)
use psb_base_mod, only : psb_spk_, sone
real(psb_spk_) :: a2
real(psb_spk_), intent(in) :: x,y,z
a2=sone
end function a2
function a3(x,y,z)
use psb_base_mod, only : psb_spk_, sone
real(psb_spk_) :: a3
real(psb_spk_), intent(in) :: x,y,z
a3=sone
end function a3
function g(x,y,z)
use psb_base_mod, only : psb_spk_, sone, szero
real(psb_spk_) :: g
real(psb_spk_), intent(in) :: x,y,z
g = szero
if (x == sone) then
g = sone
else if (x == szero) then
g = exp(y**2-z**2)
end if
end function g
end module amg_s_pde_mod
+182
View File
@@ -0,0 +1,182 @@
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2020
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! 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 AMG4PSBLAS 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 AMG4PSBLAS 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 data_input
interface read_data
module procedure read_char, read_int,&
& read_double, read_single,&
& string_read_char, string_read_int,&
& string_read_double, string_read_single
end interface read_data
interface trim_string
module procedure trim_string
end interface
character(len=4096), private :: charbuf
character, private, parameter :: def_marker="!"
contains
subroutine read_char(val,file,marker)
character(len=*), intent(out) :: val
integer, intent(in) :: file
character(len=1), optional, intent(in) :: marker
read(file,'(a)')charbuf
call read_data(val,charbuf,marker)
end subroutine read_char
subroutine read_int(val,file,marker)
integer, intent(out) :: val
integer, intent(in) :: file
character(len=1), optional, intent(in) :: marker
read(file,'(a)')charbuf
call read_data(val,charbuf,marker)
end subroutine read_int
subroutine read_single(val,file,marker)
use psb_base_mod
real(psb_spk_), intent(out) :: val
integer, intent(in) :: file
character(len=1), optional, intent(in) :: marker
read(file,'(a)')charbuf
call read_data(val,charbuf,marker)
end subroutine read_single
subroutine read_double(val,file,marker)
use psb_base_mod
real(psb_dpk_), intent(out) :: val
integer, intent(in) :: file
character(len=1), optional, intent(in) :: marker
read(file,'(a)')charbuf
call read_data(val,charbuf,marker)
end subroutine read_double
subroutine string_read_char(val,file,marker)
character(len=*), intent(out) :: val
character(len=*), intent(in) :: file
character(len=1), optional, intent(in) :: marker
character(len=1) :: marker_
character(len=1024) :: charbuf
integer :: idx
if (present(marker)) then
marker_ = marker
else
marker_ = def_marker
end if
read(file,'(a)')charbuf
charbuf = adjustl(charbuf)
idx=index(charbuf,marker_)
if (idx == 0) idx = len(charbuf)+1
read(charbuf(1:idx-1),'(a)') val
end subroutine string_read_char
subroutine string_read_int(val,file,marker)
integer, intent(out) :: val
character(len=*), intent(in) :: file
character(len=1), optional, intent(in) :: marker
character(len=1) :: marker_
character(len=1024) :: charbuf
integer :: idx
if (present(marker)) then
marker_ = marker
else
marker_ = def_marker
end if
read(file,'(a)')charbuf
charbuf = adjustl(charbuf)
idx=index(charbuf,marker_)
if (idx == 0) idx = len(charbuf)+1
read(charbuf(1:idx-1),*) val
end subroutine string_read_int
subroutine string_read_single(val,file,marker)
use psb_base_mod
real(psb_spk_), intent(out) :: val
character(len=*), intent(in) :: file
character(len=1), optional, intent(in) :: marker
character(len=1) :: marker_
character(len=1024) :: charbuf
integer :: idx
if (present(marker)) then
marker_ = marker
else
marker_ = def_marker
end if
read(file,'(a)')charbuf
charbuf = adjustl(charbuf)
idx=index(charbuf,marker_)
if (idx == 0) idx = len(charbuf)+1
read(charbuf(1:idx-1),*) val
end subroutine string_read_single
subroutine string_read_double(val,file,marker)
use psb_base_mod
real(psb_dpk_), intent(out) :: val
character(len=*), intent(in) :: file
character(len=1), optional, intent(in) :: marker
character(len=1) :: marker_
character(len=1024) :: charbuf
integer :: idx
if (present(marker)) then
marker_ = marker
else
marker_ = def_marker
end if
read(file,'(a)')charbuf
charbuf = adjustl(charbuf)
idx=index(charbuf,marker_)
if (idx == 0) idx = len(charbuf)+1
read(charbuf(1:idx-1),*) val
end subroutine string_read_double
function trim_string(string,marker)
character(len=*), intent(in) :: string
character(len=1), optional, intent(in) :: marker
character(len=len(string)) :: trim_string
character(len=1) :: marker_
integer :: idx
if (present(marker)) then
marker_ = marker
else
marker_ = def_marker
end if
idx=index(string,marker_)
trim_string = adjustl(string(idx:))
end function trim_string
end module data_input
+3
View File
@@ -0,0 +1,3 @@
15 ! IDIM; domain size is idim**3
100 ! ITMAX
1.d-6 ! EPS
+4
View File
@@ -0,0 +1,4 @@
1 ! Preconditioner choice
10 ! IDIM; domain size is idim**3
500 ! ITMAX
1.d-6 ! EPS
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
#PBS -l nodes=1:ppn=4,walltime=10:00:00
#PBS -A ambra
#PBS -o pbs2.output
#PBS -e pbs2.error
cd $PBS_O_WORKDIR
mpirun -np 4 ./mld_dexample_ml<ml.inp
@@ -0,0 +1,9 @@
#!/bin/bash
#PBS -l nodes=1:ppn=4,walltime=0:40:00
#PBS -A ambra
#PBS -o pbs.output
#PBS -e pbs.error
cd $PBS_O_WORKDIR
mpirun -np 4 ./mld_dexample_1lev<1lev.inp