From f66d19e54b658a74e5deae85c9415fe90dd12cb8 Mon Sep 17 00:00:00 2001 From: cirdans-home Date: Wed, 20 Nov 2019 10:20:48 +0100 Subject: [PATCH 01/61] added entrywise vector product psb_gemlt --- base/modules/psblas/psb_c_psblas_mod.F90 | 55 ++++--- base/modules/psblas/psb_d_psblas_mod.F90 | 55 ++++--- base/modules/psblas/psb_s_psblas_mod.F90 | 55 ++++--- base/modules/psblas/psb_z_psblas_mod.F90 | 55 ++++--- base/psblas/Makefile | 3 +- base/psblas/psb_cmlt_vect.f90 | 105 ++++++++++++++ base/psblas/psb_cvmlt.f90 | 111 ++++++++++++++ base/psblas/psb_dmlt_vect.f90 | 105 ++++++++++++++ base/psblas/psb_dvmlt.f90 | 111 ++++++++++++++ base/psblas/psb_smlt_vect.f90 | 105 ++++++++++++++ base/psblas/psb_svmlt.f90 | 111 ++++++++++++++ base/psblas/psb_zmlt_vect.f90 | 105 ++++++++++++++ base/psblas/psb_zvmlt.f90 | 111 ++++++++++++++ test/kernel/Makefile | 28 ++-- test/kernel/vecoperation.f90 | 176 +++++++++++++++++++++++ 15 files changed, 1189 insertions(+), 102 deletions(-) create mode 100644 base/psblas/psb_cmlt_vect.f90 create mode 100644 base/psblas/psb_cvmlt.f90 create mode 100644 base/psblas/psb_dmlt_vect.f90 create mode 100644 base/psblas/psb_dvmlt.f90 create mode 100644 base/psblas/psb_smlt_vect.f90 create mode 100644 base/psblas/psb_svmlt.f90 create mode 100644 base/psblas/psb_zmlt_vect.f90 create mode 100644 base/psblas/psb_zvmlt.f90 create mode 100644 test/kernel/vecoperation.f90 diff --git a/base/modules/psblas/psb_c_psblas_mod.F90 b/base/modules/psblas/psb_c_psblas_mod.F90 index 53271ea90..f4d771e09 100644 --- a/base/modules/psblas/psb_c_psblas_mod.F90 +++ b/base/modules/psblas/psb_c_psblas_mod.F90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,8 +27,8 @@ ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ! POSSIBILITY OF SUCH DAMAGE. -! -! +! +! module psb_c_psblas_mod use psb_desc_mod, only : psb_desc_type, psb_spk_, psb_ipk_ use psb_c_vect_mod, only : psb_c_vect_type @@ -44,7 +44,7 @@ module psb_c_psblas_mod integer(psb_ipk_), intent(out) :: info logical, intent(in), optional :: global end function psb_cdot_vect - function psb_cdotv(x, y, desc_a,info,global) + function psb_cdotv(x, y, desc_a,info,global) import :: psb_desc_type, psb_spk_, psb_ipk_, & & psb_c_vect_type, psb_cspmat_type complex(psb_spk_) :: psb_cdotv @@ -53,7 +53,7 @@ module psb_c_psblas_mod integer(psb_ipk_), intent(out) :: info logical, intent(in), optional :: global end function psb_cdotv - function psb_cdot(x, y, desc_a, info, jx, jy,global) + function psb_cdot(x, y, desc_a, info, jx, jy,global) import :: psb_desc_type, psb_spk_, psb_ipk_, & & psb_c_vect_type, psb_cspmat_type complex(psb_spk_) :: psb_cdot @@ -69,7 +69,7 @@ module psb_c_psblas_mod interface psb_gedots subroutine psb_cdotvs(res,x, y, desc_a, info,global) import :: psb_desc_type, psb_spk_, psb_ipk_, & - & psb_c_vect_type, psb_cspmat_type + & psb_c_vect_type, psb_cspmat_type complex(psb_spk_), intent(out) :: res complex(psb_spk_), intent(in) :: x(:), y(:) type(psb_desc_type), intent(in) :: desc_a @@ -78,7 +78,7 @@ module psb_c_psblas_mod end subroutine psb_cdotvs subroutine psb_cmdots(res,x, y, desc_a,info,global) import :: psb_desc_type, psb_spk_, psb_ipk_, & - & psb_c_vect_type, psb_cspmat_type + & psb_c_vect_type, psb_cspmat_type complex(psb_spk_), intent(out) :: res(:) complex(psb_spk_), intent(in) :: x(:,:), y(:,:) type(psb_desc_type), intent(in) :: desc_a @@ -155,10 +155,10 @@ module psb_c_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_genrmi procedure psb_camax, psb_camaxv, psb_camax_vect - end interface + end interface interface psb_normi procedure psb_camax, psb_camaxv, psb_camax_vect - end interface + end interface #endif interface psb_geamaxs @@ -238,10 +238,10 @@ module psb_c_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_genrm1 procedure psb_casum, psb_casumv, psb_casum_vect - end interface + end interface interface psb_norm1 procedure psb_casum, psb_casumv, psb_casum_vect - end interface + end interface #endif interface psb_genrm2 @@ -278,7 +278,7 @@ module psb_c_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_norm2 procedure psb_cnrm2, psb_cnrm2v, psb_cnrm2_vect - end interface + end interface #endif interface psb_genrm2s @@ -309,7 +309,7 @@ module psb_c_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_normi procedure psb_cnrmi - end interface + end interface #endif interface psb_spnrm1 @@ -323,11 +323,11 @@ module psb_c_psblas_mod logical, intent(in), optional :: global end function psb_cspnrm1 end interface - + #if ! defined(HAVE_BUGGY_GENERICS) interface psb_norm1 procedure psb_cspnrm1 - end interface + end interface #endif interface psb_spmm @@ -378,7 +378,7 @@ module psb_c_psblas_mod interface psb_spsm subroutine psb_cspsm(alpha, t, x, beta, y,& - & desc_a, info, trans, scale, choice,& + & desc_a, info, trans, scale, choice,& & diag, n, jx, jy, work) import :: psb_desc_type, psb_spk_, psb_ipk_, & & psb_c_vect_type, psb_cspmat_type @@ -395,7 +395,7 @@ module psb_c_psblas_mod integer(psb_ipk_), intent(out) :: info end subroutine psb_cspsm subroutine psb_cspsv(alpha, t, x, beta, y,& - & desc_a, info, trans, scale, choice,& + & desc_a, info, trans, scale, choice,& & diag, work) import :: psb_desc_type, psb_spk_, psb_ipk_, & & psb_c_vect_type, psb_cspmat_type @@ -411,7 +411,7 @@ module psb_c_psblas_mod integer(psb_ipk_), intent(out) :: info end subroutine psb_cspsv subroutine psb_cspsv_vect(alpha, t, x, beta, y,& - & desc_a, info, trans, scale, choice,& + & desc_a, info, trans, scale, choice,& & diag, work) import :: psb_desc_type, psb_spk_, psb_ipk_, & & psb_c_vect_type, psb_cspmat_type @@ -428,4 +428,15 @@ module psb_c_psblas_mod end subroutine psb_cspsv_vect end interface + interface psb_gemlt + subroutine psb_cmlt_vect(x,y,desc_a,info) + import :: psb_desc_type, psb_ipk_, & + & psb_c_vect_type + type(psb_c_vect_type), intent (inout) :: x + type(psb_c_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + end subroutine psb_cmlt_vect + end interface + end module psb_c_psblas_mod diff --git a/base/modules/psblas/psb_d_psblas_mod.F90 b/base/modules/psblas/psb_d_psblas_mod.F90 index 56386f92d..825fe41e0 100644 --- a/base/modules/psblas/psb_d_psblas_mod.F90 +++ b/base/modules/psblas/psb_d_psblas_mod.F90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,8 +27,8 @@ ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ! POSSIBILITY OF SUCH DAMAGE. -! -! +! +! module psb_d_psblas_mod use psb_desc_mod, only : psb_desc_type, psb_dpk_, psb_ipk_ use psb_d_vect_mod, only : psb_d_vect_type @@ -44,7 +44,7 @@ module psb_d_psblas_mod integer(psb_ipk_), intent(out) :: info logical, intent(in), optional :: global end function psb_ddot_vect - function psb_ddotv(x, y, desc_a,info,global) + function psb_ddotv(x, y, desc_a,info,global) import :: psb_desc_type, psb_dpk_, psb_ipk_, & & psb_d_vect_type, psb_dspmat_type real(psb_dpk_) :: psb_ddotv @@ -53,7 +53,7 @@ module psb_d_psblas_mod integer(psb_ipk_), intent(out) :: info logical, intent(in), optional :: global end function psb_ddotv - function psb_ddot(x, y, desc_a, info, jx, jy,global) + function psb_ddot(x, y, desc_a, info, jx, jy,global) import :: psb_desc_type, psb_dpk_, psb_ipk_, & & psb_d_vect_type, psb_dspmat_type real(psb_dpk_) :: psb_ddot @@ -69,7 +69,7 @@ module psb_d_psblas_mod interface psb_gedots subroutine psb_ddotvs(res,x, y, desc_a, info,global) import :: psb_desc_type, psb_dpk_, psb_ipk_, & - & psb_d_vect_type, psb_dspmat_type + & psb_d_vect_type, psb_dspmat_type real(psb_dpk_), intent(out) :: res real(psb_dpk_), intent(in) :: x(:), y(:) type(psb_desc_type), intent(in) :: desc_a @@ -78,7 +78,7 @@ module psb_d_psblas_mod end subroutine psb_ddotvs subroutine psb_dmdots(res,x, y, desc_a,info,global) import :: psb_desc_type, psb_dpk_, psb_ipk_, & - & psb_d_vect_type, psb_dspmat_type + & psb_d_vect_type, psb_dspmat_type real(psb_dpk_), intent(out) :: res(:) real(psb_dpk_), intent(in) :: x(:,:), y(:,:) type(psb_desc_type), intent(in) :: desc_a @@ -155,10 +155,10 @@ module psb_d_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_genrmi procedure psb_damax, psb_damaxv, psb_damax_vect - end interface + end interface interface psb_normi procedure psb_damax, psb_damaxv, psb_damax_vect - end interface + end interface #endif interface psb_geamaxs @@ -238,10 +238,10 @@ module psb_d_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_genrm1 procedure psb_dasum, psb_dasumv, psb_dasum_vect - end interface + end interface interface psb_norm1 procedure psb_dasum, psb_dasumv, psb_dasum_vect - end interface + end interface #endif interface psb_genrm2 @@ -278,7 +278,7 @@ module psb_d_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_norm2 procedure psb_dnrm2, psb_dnrm2v, psb_dnrm2_vect - end interface + end interface #endif interface psb_genrm2s @@ -309,7 +309,7 @@ module psb_d_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_normi procedure psb_dnrmi - end interface + end interface #endif interface psb_spnrm1 @@ -323,11 +323,11 @@ module psb_d_psblas_mod logical, intent(in), optional :: global end function psb_dspnrm1 end interface - + #if ! defined(HAVE_BUGGY_GENERICS) interface psb_norm1 procedure psb_dspnrm1 - end interface + end interface #endif interface psb_spmm @@ -378,7 +378,7 @@ module psb_d_psblas_mod interface psb_spsm subroutine psb_dspsm(alpha, t, x, beta, y,& - & desc_a, info, trans, scale, choice,& + & desc_a, info, trans, scale, choice,& & diag, n, jx, jy, work) import :: psb_desc_type, psb_dpk_, psb_ipk_, & & psb_d_vect_type, psb_dspmat_type @@ -395,7 +395,7 @@ module psb_d_psblas_mod integer(psb_ipk_), intent(out) :: info end subroutine psb_dspsm subroutine psb_dspsv(alpha, t, x, beta, y,& - & desc_a, info, trans, scale, choice,& + & desc_a, info, trans, scale, choice,& & diag, work) import :: psb_desc_type, psb_dpk_, psb_ipk_, & & psb_d_vect_type, psb_dspmat_type @@ -411,7 +411,7 @@ module psb_d_psblas_mod integer(psb_ipk_), intent(out) :: info end subroutine psb_dspsv subroutine psb_dspsv_vect(alpha, t, x, beta, y,& - & desc_a, info, trans, scale, choice,& + & desc_a, info, trans, scale, choice,& & diag, work) import :: psb_desc_type, psb_dpk_, psb_ipk_, & & psb_d_vect_type, psb_dspmat_type @@ -428,4 +428,15 @@ module psb_d_psblas_mod end subroutine psb_dspsv_vect end interface + interface psb_gemlt + subroutine psb_dmlt_vect(x,y,desc_a,info) + import :: psb_desc_type, psb_ipk_, & + & psb_d_vect_type + type(psb_d_vect_type), intent (inout) :: x + type(psb_d_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + end subroutine psb_dmlt_vect + end interface + end module psb_d_psblas_mod diff --git a/base/modules/psblas/psb_s_psblas_mod.F90 b/base/modules/psblas/psb_s_psblas_mod.F90 index a764bb402..b91fad791 100644 --- a/base/modules/psblas/psb_s_psblas_mod.F90 +++ b/base/modules/psblas/psb_s_psblas_mod.F90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,8 +27,8 @@ ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ! POSSIBILITY OF SUCH DAMAGE. -! -! +! +! module psb_s_psblas_mod use psb_desc_mod, only : psb_desc_type, psb_spk_, psb_ipk_ use psb_s_vect_mod, only : psb_s_vect_type @@ -44,7 +44,7 @@ module psb_s_psblas_mod integer(psb_ipk_), intent(out) :: info logical, intent(in), optional :: global end function psb_sdot_vect - function psb_sdotv(x, y, desc_a,info,global) + function psb_sdotv(x, y, desc_a,info,global) import :: psb_desc_type, psb_spk_, psb_ipk_, & & psb_s_vect_type, psb_sspmat_type real(psb_spk_) :: psb_sdotv @@ -53,7 +53,7 @@ module psb_s_psblas_mod integer(psb_ipk_), intent(out) :: info logical, intent(in), optional :: global end function psb_sdotv - function psb_sdot(x, y, desc_a, info, jx, jy,global) + function psb_sdot(x, y, desc_a, info, jx, jy,global) import :: psb_desc_type, psb_spk_, psb_ipk_, & & psb_s_vect_type, psb_sspmat_type real(psb_spk_) :: psb_sdot @@ -69,7 +69,7 @@ module psb_s_psblas_mod interface psb_gedots subroutine psb_sdotvs(res,x, y, desc_a, info,global) import :: psb_desc_type, psb_spk_, psb_ipk_, & - & psb_s_vect_type, psb_sspmat_type + & psb_s_vect_type, psb_sspmat_type real(psb_spk_), intent(out) :: res real(psb_spk_), intent(in) :: x(:), y(:) type(psb_desc_type), intent(in) :: desc_a @@ -78,7 +78,7 @@ module psb_s_psblas_mod end subroutine psb_sdotvs subroutine psb_smdots(res,x, y, desc_a,info,global) import :: psb_desc_type, psb_spk_, psb_ipk_, & - & psb_s_vect_type, psb_sspmat_type + & psb_s_vect_type, psb_sspmat_type real(psb_spk_), intent(out) :: res(:) real(psb_spk_), intent(in) :: x(:,:), y(:,:) type(psb_desc_type), intent(in) :: desc_a @@ -155,10 +155,10 @@ module psb_s_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_genrmi procedure psb_samax, psb_samaxv, psb_samax_vect - end interface + end interface interface psb_normi procedure psb_samax, psb_samaxv, psb_samax_vect - end interface + end interface #endif interface psb_geamaxs @@ -238,10 +238,10 @@ module psb_s_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_genrm1 procedure psb_sasum, psb_sasumv, psb_sasum_vect - end interface + end interface interface psb_norm1 procedure psb_sasum, psb_sasumv, psb_sasum_vect - end interface + end interface #endif interface psb_genrm2 @@ -278,7 +278,7 @@ module psb_s_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_norm2 procedure psb_snrm2, psb_snrm2v, psb_snrm2_vect - end interface + end interface #endif interface psb_genrm2s @@ -309,7 +309,7 @@ module psb_s_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_normi procedure psb_snrmi - end interface + end interface #endif interface psb_spnrm1 @@ -323,11 +323,11 @@ module psb_s_psblas_mod logical, intent(in), optional :: global end function psb_sspnrm1 end interface - + #if ! defined(HAVE_BUGGY_GENERICS) interface psb_norm1 procedure psb_sspnrm1 - end interface + end interface #endif interface psb_spmm @@ -378,7 +378,7 @@ module psb_s_psblas_mod interface psb_spsm subroutine psb_sspsm(alpha, t, x, beta, y,& - & desc_a, info, trans, scale, choice,& + & desc_a, info, trans, scale, choice,& & diag, n, jx, jy, work) import :: psb_desc_type, psb_spk_, psb_ipk_, & & psb_s_vect_type, psb_sspmat_type @@ -395,7 +395,7 @@ module psb_s_psblas_mod integer(psb_ipk_), intent(out) :: info end subroutine psb_sspsm subroutine psb_sspsv(alpha, t, x, beta, y,& - & desc_a, info, trans, scale, choice,& + & desc_a, info, trans, scale, choice,& & diag, work) import :: psb_desc_type, psb_spk_, psb_ipk_, & & psb_s_vect_type, psb_sspmat_type @@ -411,7 +411,7 @@ module psb_s_psblas_mod integer(psb_ipk_), intent(out) :: info end subroutine psb_sspsv subroutine psb_sspsv_vect(alpha, t, x, beta, y,& - & desc_a, info, trans, scale, choice,& + & desc_a, info, trans, scale, choice,& & diag, work) import :: psb_desc_type, psb_spk_, psb_ipk_, & & psb_s_vect_type, psb_sspmat_type @@ -428,4 +428,15 @@ module psb_s_psblas_mod end subroutine psb_sspsv_vect end interface + interface psb_gemlt + subroutine psb_smlt_vect(x,y,desc_a,info) + import :: psb_desc_type, psb_ipk_, & + & psb_s_vect_type + type(psb_s_vect_type), intent (inout) :: x + type(psb_s_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + end subroutine psb_smlt_vect + end interface + end module psb_s_psblas_mod diff --git a/base/modules/psblas/psb_z_psblas_mod.F90 b/base/modules/psblas/psb_z_psblas_mod.F90 index 08ee92a72..afd0a9b75 100644 --- a/base/modules/psblas/psb_z_psblas_mod.F90 +++ b/base/modules/psblas/psb_z_psblas_mod.F90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,8 +27,8 @@ ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ! POSSIBILITY OF SUCH DAMAGE. -! -! +! +! module psb_z_psblas_mod use psb_desc_mod, only : psb_desc_type, psb_dpk_, psb_ipk_ use psb_z_vect_mod, only : psb_z_vect_type @@ -44,7 +44,7 @@ module psb_z_psblas_mod integer(psb_ipk_), intent(out) :: info logical, intent(in), optional :: global end function psb_zdot_vect - function psb_zdotv(x, y, desc_a,info,global) + function psb_zdotv(x, y, desc_a,info,global) import :: psb_desc_type, psb_dpk_, psb_ipk_, & & psb_z_vect_type, psb_zspmat_type complex(psb_dpk_) :: psb_zdotv @@ -53,7 +53,7 @@ module psb_z_psblas_mod integer(psb_ipk_), intent(out) :: info logical, intent(in), optional :: global end function psb_zdotv - function psb_zdot(x, y, desc_a, info, jx, jy,global) + function psb_zdot(x, y, desc_a, info, jx, jy,global) import :: psb_desc_type, psb_dpk_, psb_ipk_, & & psb_z_vect_type, psb_zspmat_type complex(psb_dpk_) :: psb_zdot @@ -69,7 +69,7 @@ module psb_z_psblas_mod interface psb_gedots subroutine psb_zdotvs(res,x, y, desc_a, info,global) import :: psb_desc_type, psb_dpk_, psb_ipk_, & - & psb_z_vect_type, psb_zspmat_type + & psb_z_vect_type, psb_zspmat_type complex(psb_dpk_), intent(out) :: res complex(psb_dpk_), intent(in) :: x(:), y(:) type(psb_desc_type), intent(in) :: desc_a @@ -78,7 +78,7 @@ module psb_z_psblas_mod end subroutine psb_zdotvs subroutine psb_zmdots(res,x, y, desc_a,info,global) import :: psb_desc_type, psb_dpk_, psb_ipk_, & - & psb_z_vect_type, psb_zspmat_type + & psb_z_vect_type, psb_zspmat_type complex(psb_dpk_), intent(out) :: res(:) complex(psb_dpk_), intent(in) :: x(:,:), y(:,:) type(psb_desc_type), intent(in) :: desc_a @@ -155,10 +155,10 @@ module psb_z_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_genrmi procedure psb_zamax, psb_zamaxv, psb_zamax_vect - end interface + end interface interface psb_normi procedure psb_zamax, psb_zamaxv, psb_zamax_vect - end interface + end interface #endif interface psb_geamaxs @@ -238,10 +238,10 @@ module psb_z_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_genrm1 procedure psb_zasum, psb_zasumv, psb_zasum_vect - end interface + end interface interface psb_norm1 procedure psb_zasum, psb_zasumv, psb_zasum_vect - end interface + end interface #endif interface psb_genrm2 @@ -278,7 +278,7 @@ module psb_z_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_norm2 procedure psb_znrm2, psb_znrm2v, psb_znrm2_vect - end interface + end interface #endif interface psb_genrm2s @@ -309,7 +309,7 @@ module psb_z_psblas_mod #if ! defined(HAVE_BUGGY_GENERICS) interface psb_normi procedure psb_znrmi - end interface + end interface #endif interface psb_spnrm1 @@ -323,11 +323,11 @@ module psb_z_psblas_mod logical, intent(in), optional :: global end function psb_zspnrm1 end interface - + #if ! defined(HAVE_BUGGY_GENERICS) interface psb_norm1 procedure psb_zspnrm1 - end interface + end interface #endif interface psb_spmm @@ -378,7 +378,7 @@ module psb_z_psblas_mod interface psb_spsm subroutine psb_zspsm(alpha, t, x, beta, y,& - & desc_a, info, trans, scale, choice,& + & desc_a, info, trans, scale, choice,& & diag, n, jx, jy, work) import :: psb_desc_type, psb_dpk_, psb_ipk_, & & psb_z_vect_type, psb_zspmat_type @@ -395,7 +395,7 @@ module psb_z_psblas_mod integer(psb_ipk_), intent(out) :: info end subroutine psb_zspsm subroutine psb_zspsv(alpha, t, x, beta, y,& - & desc_a, info, trans, scale, choice,& + & desc_a, info, trans, scale, choice,& & diag, work) import :: psb_desc_type, psb_dpk_, psb_ipk_, & & psb_z_vect_type, psb_zspmat_type @@ -411,7 +411,7 @@ module psb_z_psblas_mod integer(psb_ipk_), intent(out) :: info end subroutine psb_zspsv subroutine psb_zspsv_vect(alpha, t, x, beta, y,& - & desc_a, info, trans, scale, choice,& + & desc_a, info, trans, scale, choice,& & diag, work) import :: psb_desc_type, psb_dpk_, psb_ipk_, & & psb_z_vect_type, psb_zspmat_type @@ -428,4 +428,15 @@ module psb_z_psblas_mod end subroutine psb_zspsv_vect end interface + interface psb_gemlt + subroutine psb_zmlt_vect(x,y,desc_a,info) + import :: psb_desc_type, psb_ipk_, & + & psb_z_vect_type + type(psb_z_vect_type), intent (inout) :: x + type(psb_z_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + end subroutine psb_zmlt_vect + end interface + end module psb_z_psblas_mod diff --git a/base/psblas/Makefile b/base/psblas/Makefile index 44eb67ee9..bc583f17f 100644 --- a/base/psblas/Makefile +++ b/base/psblas/Makefile @@ -9,7 +9,8 @@ OBJS= psb_ddot.o psb_damax.o psb_dasum.o psb_daxpby.o\ psb_saxpby.o psb_sdot.o psb_sasum.o psb_samax.o\ psb_snrm2.o psb_snrmi.o psb_sspmm.o psb_sspsm.o\ psb_camax.o psb_casum.o psb_caxpby.o psb_cdot.o \ - psb_cnrm2.o psb_cnrmi.o psb_cspmm.o psb_cspsm.o + psb_cnrm2.o psb_cnrmi.o psb_cspmm.o psb_cspsm.o \ + psb_cmlt_vect.o psb_dmlt_vect.o psb_zmlt_vect.o psb_smlt_vect.o LIBDIR=.. diff --git a/base/psblas/psb_cmlt_vect.f90 b/base/psblas/psb_cmlt_vect.f90 new file mode 100644 index 000000000..89679c0ff --- /dev/null +++ b/base/psblas/psb_cmlt_vect.f90 @@ -0,0 +1,105 @@ +! +! Parallel Sparse BLAS version 3.5 +! (C) Copyright 2006-2018 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: psb_cmlt_vect + +subroutine psb_cmlt_vect(x,y,desc_a,info) + use psb_base_mod, psb_protect_name => psb_cmlt_vect + implicit none + type(psb_c_vect_type), intent (inout) :: x + type(psb_c_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_c_mlt_vect' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if(desc_a%get_local_rows() > 0) then + call y%mlt(x,info) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_cmlt_vect diff --git a/base/psblas/psb_cvmlt.f90 b/base/psblas/psb_cvmlt.f90 new file mode 100644 index 000000000..829ce9873 --- /dev/null +++ b/base/psblas/psb_cvmlt.f90 @@ -0,0 +1,111 @@ +! +! Parallel Sparse BLAS version 3.5 +! (C) Copyright 2006-2018 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: psb_cvmlt.f90 + +subroutine psb_cvmlt(x,y,desc_a,info) + use psb_base_mod, psb_protect_name => psb_cvmlt + implicit none + type(psb_c_vect_type), intent (inout) :: x + type(psb_c_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_cgevmlt' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if ((iix /= ione).or.(iiy /= ione)) then + info=psb_err_ix_n1_iy_n1_unsupported_ + call psb_errpush(info,name) + end if + + if(desc_a%get_local_rows() > 0) then + call y%base_mlt_v(desc_a%get_local_rows(),& + & alpha,x,beta,info) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_cvmlt diff --git a/base/psblas/psb_dmlt_vect.f90 b/base/psblas/psb_dmlt_vect.f90 new file mode 100644 index 000000000..2f282824a --- /dev/null +++ b/base/psblas/psb_dmlt_vect.f90 @@ -0,0 +1,105 @@ +! +! Parallel Sparse BLAS version 3.5 +! (C) Copyright 2006-2018 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: psb_dmlt_vect + +subroutine psb_dmlt_vect(x,y,desc_a,info) + use psb_base_mod, psb_protect_name => psb_dmlt_vect + implicit none + type(psb_d_vect_type), intent (inout) :: x + type(psb_d_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_d_mlt_vect' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if(desc_a%get_local_rows() > 0) then + call y%mlt(x,info) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_dmlt_vect diff --git a/base/psblas/psb_dvmlt.f90 b/base/psblas/psb_dvmlt.f90 new file mode 100644 index 000000000..ec5325fc9 --- /dev/null +++ b/base/psblas/psb_dvmlt.f90 @@ -0,0 +1,111 @@ +! +! Parallel Sparse BLAS version 3.5 +! (C) Copyright 2006-2018 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: psb_dvmlt.f90 + +subroutine psb_dvmlt(x,y,desc_a,info) + use psb_base_mod, psb_protect_name => psb_dvmlt + implicit none + type(psb_d_vect_type), intent (inout) :: x + type(psb_d_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_dgevmlt' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if ((iix /= ione).or.(iiy /= ione)) then + info=psb_err_ix_n1_iy_n1_unsupported_ + call psb_errpush(info,name) + end if + + if(desc_a%get_local_rows() > 0) then + call y%base_mlt_v(desc_a%get_local_rows(),& + & alpha,x,beta,info) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_dvmlt diff --git a/base/psblas/psb_smlt_vect.f90 b/base/psblas/psb_smlt_vect.f90 new file mode 100644 index 000000000..f135e97d0 --- /dev/null +++ b/base/psblas/psb_smlt_vect.f90 @@ -0,0 +1,105 @@ +! +! Parallel Sparse BLAS version 3.5 +! (C) Copyright 2006-2018 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: psb_smlt_vect + +subroutine psb_smlt_vect(x,y,desc_a,info) + use psb_base_mod, psb_protect_name => psb_smlt_vect + implicit none + type(psb_s_vect_type), intent (inout) :: x + type(psb_s_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_s_mlt_vect' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if(desc_a%get_local_rows() > 0) then + call y%mlt(x,info) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_smlt_vect diff --git a/base/psblas/psb_svmlt.f90 b/base/psblas/psb_svmlt.f90 new file mode 100644 index 000000000..cfe09de1b --- /dev/null +++ b/base/psblas/psb_svmlt.f90 @@ -0,0 +1,111 @@ +! +! Parallel Sparse BLAS version 3.5 +! (C) Copyright 2006-2018 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: psb_svmlt.f90 + +subroutine psb_svmlt(x,y,desc_a,info) + use psb_base_mod, psb_protect_name => psb_svmlt + implicit none + type(psb_s_vect_type), intent (inout) :: x + type(psb_s_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_sgevmlt' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if ((iix /= ione).or.(iiy /= ione)) then + info=psb_err_ix_n1_iy_n1_unsupported_ + call psb_errpush(info,name) + end if + + if(desc_a%get_local_rows() > 0) then + call y%base_mlt_v(desc_a%get_local_rows(),& + & alpha,x,beta,info) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_svmlt diff --git a/base/psblas/psb_zmlt_vect.f90 b/base/psblas/psb_zmlt_vect.f90 new file mode 100644 index 000000000..5d3153b55 --- /dev/null +++ b/base/psblas/psb_zmlt_vect.f90 @@ -0,0 +1,105 @@ +! +! Parallel Sparse BLAS version 3.5 +! (C) Copyright 2006-2018 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: psb_zmlt_vect + +subroutine psb_zmlt_vect(x,y,desc_a,info) + use psb_base_mod, psb_protect_name => psb_zmlt_vect + implicit none + type(psb_z_vect_type), intent (inout) :: x + type(psb_z_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_z_mlt_vect' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if(desc_a%get_local_rows() > 0) then + call y%mlt(x,info) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_zmlt_vect diff --git a/base/psblas/psb_zvmlt.f90 b/base/psblas/psb_zvmlt.f90 new file mode 100644 index 000000000..01a6fc68e --- /dev/null +++ b/base/psblas/psb_zvmlt.f90 @@ -0,0 +1,111 @@ +! +! Parallel Sparse BLAS version 3.5 +! (C) Copyright 2006-2018 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: psb_zvmlt.f90 + +subroutine psb_zvmlt(x,y,desc_a,info) + use psb_base_mod, psb_protect_name => psb_zvmlt + implicit none + type(psb_z_vect_type), intent (inout) :: x + type(psb_z_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_zgevmlt' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if ((iix /= ione).or.(iiy /= ione)) then + info=psb_err_ix_n1_iy_n1_unsupported_ + call psb_errpush(info,name) + end if + + if(desc_a%get_local_rows() > 0) then + call y%base_mlt_v(desc_a%get_local_rows(),& + & alpha,x,beta,info) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_zvmlt diff --git a/test/kernel/Makefile b/test/kernel/Makefile index 8eb076a49..9dc88e59a 100644 --- a/test/kernel/Makefile +++ b/test/kernel/Makefile @@ -12,36 +12,38 @@ LDLIBS=$(PSBLDLIBS) FINCLUDES=$(FMFLAG)$(MODDIR) $(FMFLAG). -DTOBJS=d_file_spmv.o -STOBJS=s_file_spmv.o +DTOBJS=d_file_spmv.o +STOBJS=s_file_spmv.o DPGOBJS=pdgenspmv.o +DVECOBJS=vecoperation.o EXEDIR=./runs -all: runsd d_file_spmv s_file_spmv pdgenspmv +all: runsd d_file_spmv s_file_spmv pdgenspmv vecoperation runsd: (if test ! -d runs ; then mkdir runs; fi) d_file_spmv: $(DTOBJS) - $(FLINK) $(LOPT) $(DTOBJS) -o d_file_spmv $(PSBLAS_LIB) $(LDLIBS) - /bin/mv d_file_spmv $(EXEDIR) + $(FLINK) $(LOPT) $(DTOBJS) -o d_file_spmv $(PSBLAS_LIB) $(LDLIBS) + /bin/mv d_file_spmv $(EXEDIR) pdgenspmv: $(DPGOBJS) - $(FLINK) $(LOPT) $(DPGOBJS) -o pdgenspmv $(PSBLAS_LIB) $(LDLIBS) - /bin/mv pdgenspmv $(EXEDIR) + $(FLINK) $(LOPT) $(DPGOBJS) -o pdgenspmv $(PSBLAS_LIB) $(LDLIBS) + /bin/mv pdgenspmv $(EXEDIR) s_file_spmv: $(STOBJS) - $(FLINK) $(LOPT) $(STOBJS) -o s_file_spmv $(PSBLAS_LIB) $(LDLIBS) - /bin/mv s_file_spmv $(EXEDIR) + $(FLINK) $(LOPT) $(STOBJS) -o s_file_spmv $(PSBLAS_LIB) $(LDLIBS) + /bin/mv s_file_spmv $(EXEDIR) +vecoperation: $(DVECOBJS) + $(FLINK) $(LOPT) $(DVECOBJS) -o vecoperation $(PSBLAS_LIB) $(LDLIBS) + /bin/mv vecoperation $(EXEDIR) - -clean: - /bin/rm -f $(DBOBJSS) $(DBOBJS) $(DTOBJS) $(STOBJS) +clean: + /bin/rm -f $(DBOBJSS) $(DBOBJS) $(DTOBJS) $(STOBJS) $(DVECOBJS) lib: (cd ../../; make library) verycleanlib: (cd ../../; make veryclean) - diff --git a/test/kernel/vecoperation.f90 b/test/kernel/vecoperation.f90 new file mode 100644 index 000000000..732a47087 --- /dev/null +++ b/test/kernel/vecoperation.f90 @@ -0,0 +1,176 @@ +! +! Parallel Sparse BLAS version 3.5.1 +! (C) Copyright 2015 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: vecoperation.f90 +! +program vecoperation + use psb_base_mod + use psb_util_mod + implicit none + + ! input parameters + integer(psb_ipk_) :: idim = 100 + + ! miscellaneous + real(psb_dpk_), parameter :: one = 1.d0 + real(psb_dpk_) :: t1, t2 + + ! descriptor + type(psb_desc_type) :: desc_a + ! vector + type(psb_d_vect_type) :: x,y + ! blacs parameters + integer(psb_ipk_) :: ictxt, iam, np + ! other variables + integer(psb_ipk_) :: nr, nlr, info, i, ii, ib=1 + integer(psb_lpk_) :: nt + integer(psb_lpk_), allocatable :: myidx(:) + real(psb_dpk_) :: zt(1), dotresult, norm2, norm1, norminf + character(len=20) :: name,ch_err,readinput + + info=psb_success_ + + + call psb_init(ictxt) + call psb_info(ictxt,iam,np) + + if (iam < 0) then + call psb_exit(ictxt) ! This should not happen, but just in case + stop + endif + if(psb_get_errstatus() /= 0) goto 9999 + name='vecoperation' + call psb_set_errverbosity(itwo) + ! + ! Hello world + ! + if (iam == psb_root_) then + write(*,*) 'Welcome to PSBLAS version: ',psb_version_string_ + write(*,*) 'This is the ',trim(name),' sample program' + end if + + call get_command_argument(1,readinput) + if (len_trim(readinput) /= 0) read(readinput,*)idim + + if (iam == psb_root_) write(psb_out_unit,'(" ")') + if (iam == psb_root_) write(psb_out_unit,'("Vector size",I10)')idim + + ! + ! Data distribution + ! We assume a simple contiguous block distribution + ! + nt = (idim+np-1)/np + nr = max(0,min(nt,idim-(iam*nt))) + nt = nr + + call psb_sum(ictxt,nt) + if (nt /= idim) then + write(psb_err_unit,*) iam, 'Initialization error ',nr,nt,idim + info = -1 + call psb_barrier(ictxt) + call psb_abort(ictxt) + return + end if + + call psb_cdall(ictxt,desc_a,info,nl=nr) + myidx = desc_a%get_global_indices() + nlr = size(myidx) + + ! + ! allocate and fill in the vectors + ! + call psb_barrier(ictxt) + t1 = psb_wtime() + ! Allocate memory + call psb_geall(x,desc_a,info) + call psb_geall(y,desc_a,info) + ! Put entries into the vectors + do ii=1,nlr + zt(1) = 1.0 + call psb_geins(ib,myidx(ii:),zt(1:),x,desc_a,info) + zt(1) = 2.0 + call psb_geins(ib,myidx(ii:),zt(1:),y,desc_a,info) + end do + ! Assemble + call psb_cdasb(desc_a,info) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='comm asb rout.' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + if (info == psb_success_) call psb_geasb(x,desc_a,info) + if (info == psb_success_) call psb_geasb(y,desc_a,info) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='vec asb rout.' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_barrier(ictxt) + t2 = psb_wtime() - t1 + + if (iam == psb_root_) write(psb_out_unit,'("Overall vector creation time : ",es12.5)')t2 + + ! + ! Vector operations + ! + dotresult = psb_gedot(x,y,desc_a,info) ! Dot-product + if (iam == psb_root_) write(psb_out_unit,'("Dot product result : ",es12.5)')dotresult + norm1 = psb_norm1(x,desc_a,info) + norm2 = psb_norm2(x,desc_a,info) + norminf = psb_normi(x,desc_a,info) + if (iam == psb_root_) write(psb_out_unit,'("\|x\|_inf : ",es12.5," \|x\|_1 :",es12.5," \|x\|_2",es12.5)')norminf,norm1,norm2 + call psb_geaxpby(1.0_psb_dpk_, x, 1.0_psb_dpk_, y, desc_a, info) ! \alpha x + \beta y + call psb_gemlt(x,y,desc_a,info) + + + + ! + ! cleanup storage and exit + ! + call psb_gefree(x,desc_a,info) + call psb_gefree(y,desc_a,info) + call psb_cdfree(desc_a,info) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='free routine' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + call psb_exit(ictxt) + stop + +9999 call psb_error(ictxt) + + stop +end program vecoperation From ce6383b7ff01c24bb4770b64bbaeb85dba8749d4 Mon Sep 17 00:00:00 2001 From: cirdans-home Date: Wed, 20 Nov 2019 15:45:35 +0100 Subject: [PATCH 02/61] Added Element-by-Element divison --- base/modules/psblas/psb_c_psblas_mod.F90 | 11 + base/modules/psblas/psb_d_psblas_mod.F90 | 11 + base/modules/psblas/psb_s_psblas_mod.F90 | 11 + base/modules/psblas/psb_z_psblas_mod.F90 | 11 + base/modules/serial/psb_c_base_vect_mod.f90 | 800 +++++++++++--------- base/modules/serial/psb_c_vect_mod.F90 | 308 ++++---- base/modules/serial/psb_d_base_vect_mod.f90 | 800 +++++++++++--------- base/modules/serial/psb_d_vect_mod.F90 | 308 ++++---- base/modules/serial/psb_i_base_vect_mod.f90 | 509 +++++++------ base/modules/serial/psb_i_vect_mod.F90 | 152 ++-- base/modules/serial/psb_l_base_vect_mod.f90 | 509 +++++++------ base/modules/serial/psb_l_vect_mod.F90 | 152 ++-- base/modules/serial/psb_s_base_vect_mod.f90 | 800 +++++++++++--------- base/modules/serial/psb_s_vect_mod.F90 | 308 ++++---- base/modules/serial/psb_z_base_vect_mod.f90 | 800 +++++++++++--------- base/modules/serial/psb_z_vect_mod.F90 | 308 ++++---- base/psblas/Makefile | 11 +- base/psblas/psb_cdiv_vect.f90 | 105 +++ base/psblas/psb_ddiv_vect.f90 | 105 +++ base/psblas/psb_sdiv_vect.f90 | 105 +++ base/psblas/psb_zdiv_vect.f90 | 105 +++ test/kernel/vecoperation.f90 | 32 + 22 files changed, 3546 insertions(+), 2715 deletions(-) create mode 100644 base/psblas/psb_cdiv_vect.f90 create mode 100644 base/psblas/psb_ddiv_vect.f90 create mode 100644 base/psblas/psb_sdiv_vect.f90 create mode 100644 base/psblas/psb_zdiv_vect.f90 diff --git a/base/modules/psblas/psb_c_psblas_mod.F90 b/base/modules/psblas/psb_c_psblas_mod.F90 index f4d771e09..1e16312d4 100644 --- a/base/modules/psblas/psb_c_psblas_mod.F90 +++ b/base/modules/psblas/psb_c_psblas_mod.F90 @@ -439,4 +439,15 @@ module psb_c_psblas_mod end subroutine psb_cmlt_vect end interface + interface psb_gediv + subroutine psb_cdiv_vect(x,y,desc_a,info) + import :: psb_desc_type, psb_ipk_, & + & psb_c_vect_type + type(psb_c_vect_type), intent (inout) :: x + type(psb_c_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + end subroutine psb_cdiv_vect + end interface + end module psb_c_psblas_mod diff --git a/base/modules/psblas/psb_d_psblas_mod.F90 b/base/modules/psblas/psb_d_psblas_mod.F90 index 825fe41e0..f7bdfa8f1 100644 --- a/base/modules/psblas/psb_d_psblas_mod.F90 +++ b/base/modules/psblas/psb_d_psblas_mod.F90 @@ -439,4 +439,15 @@ module psb_d_psblas_mod end subroutine psb_dmlt_vect end interface + interface psb_gediv + subroutine psb_ddiv_vect(x,y,desc_a,info) + import :: psb_desc_type, psb_ipk_, & + & psb_d_vect_type + type(psb_d_vect_type), intent (inout) :: x + type(psb_d_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + end subroutine psb_ddiv_vect + end interface + end module psb_d_psblas_mod diff --git a/base/modules/psblas/psb_s_psblas_mod.F90 b/base/modules/psblas/psb_s_psblas_mod.F90 index b91fad791..af2c17f6d 100644 --- a/base/modules/psblas/psb_s_psblas_mod.F90 +++ b/base/modules/psblas/psb_s_psblas_mod.F90 @@ -439,4 +439,15 @@ module psb_s_psblas_mod end subroutine psb_smlt_vect end interface + interface psb_gediv + subroutine psb_sdiv_vect(x,y,desc_a,info) + import :: psb_desc_type, psb_ipk_, & + & psb_s_vect_type + type(psb_s_vect_type), intent (inout) :: x + type(psb_s_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + end subroutine psb_sdiv_vect + end interface + end module psb_s_psblas_mod diff --git a/base/modules/psblas/psb_z_psblas_mod.F90 b/base/modules/psblas/psb_z_psblas_mod.F90 index afd0a9b75..807ec7cd8 100644 --- a/base/modules/psblas/psb_z_psblas_mod.F90 +++ b/base/modules/psblas/psb_z_psblas_mod.F90 @@ -439,4 +439,15 @@ module psb_z_psblas_mod end subroutine psb_zmlt_vect end interface + interface psb_gediv + subroutine psb_zdiv_vect(x,y,desc_a,info) + import :: psb_desc_type, psb_ipk_, & + & psb_z_vect_type + type(psb_z_vect_type), intent (inout) :: x + type(psb_z_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + end subroutine psb_zdiv_vect + end interface + end module psb_z_psblas_mod diff --git a/base/modules/serial/psb_c_base_vect_mod.f90 b/base/modules/serial/psb_c_base_vect_mod.f90 index 59f9816d3..d95314747 100644 --- a/base/modules/serial/psb_c_base_vect_mod.f90 +++ b/base/modules/serial/psb_c_base_vect_mod.f90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,14 +27,14 @@ ! 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. -! -! +! +! ! ! package: psb_c_base_vect_mod ! ! This module contains the definition of the psb_c_base_vect type which ! is a container for dense vectors. -! This is encapsulated instead of being just a simple array to allow for +! This is encapsulated instead of being just a simple array to allow for ! more complicated situations, such as GPU programming, where the memory ! area we are interested in is not easily accessible from the host/Fortran ! side. It is also meant to be encapsulated in an outer type, to allow @@ -43,7 +43,7 @@ ! ! module psb_c_base_vect_mod - + use psb_const_mod use psb_error_mod use psb_realloc_mod @@ -51,9 +51,9 @@ module psb_c_base_vect_mod use psb_l_base_vect_mod !> \namespace psb_base_mod \class psb_c_base_vect_type - !! The psb_c_base_vect_type + !! The psb_c_base_vect_type !! defines a middle level complex(psb_spk_) encapsulated dense vector. - !! The encapsulation is needed, in place of a simple array, to allow + !! The encapsulation is needed, in place of a simple array, to allow !! for complicated situations, such as GPU programming, where the memory !! area we are interested in is not easily accessible from the host/Fortran !! side. It is also meant to be encapsulated in an outer type, to allow @@ -61,9 +61,9 @@ module psb_c_base_vect_mod !! sparse matrix types. !! type psb_c_base_vect_type - !> Values. + !> Values. complex(psb_spk_), allocatable :: v(:) - complex(psb_spk_), allocatable :: combuf(:) + complex(psb_spk_), allocatable :: combuf(:) integer(psb_mpk_), allocatable :: comid(:,:) contains ! @@ -78,7 +78,7 @@ module psb_c_base_vect_mod ! ! Insert/set. Assembly and free. ! Assembly does almost nothing here, but is important - ! in derived classes. + ! in derived classes. ! procedure, pass(x) :: ins_a => c_base_ins_a procedure, pass(x) :: ins_v => c_base_ins_v @@ -93,7 +93,7 @@ module psb_c_base_vect_mod ! Any derived class having extra storage upon sync ! will guarantee that both fortran/host side and ! external side contain the same data. The base - ! version is only a placeholder. + ! version is only a placeholder. ! procedure, pass(x) :: sync => c_base_sync procedure, pass(x) :: is_host => c_base_is_host @@ -130,7 +130,7 @@ module psb_c_base_vect_mod generic, public :: set => set_vect, set_scal ! ! Gather/scatter. These are needed for MPI interfacing. - ! May have to be reworked. + ! May have to be reworked. ! procedure, pass(x) :: gthab => c_base_gthab procedure, pass(x) :: gthzv => c_base_gthzv @@ -164,6 +164,12 @@ module psb_c_base_vect_mod procedure, pass(z) :: mlt_av => c_base_mlt_av generic, public :: mlt => mlt_v, mlt_a, mlt_a_2, mlt_v_2, mlt_av, mlt_va ! + ! Vector-Vector operations + ! + procedure, pass(x) :: div_v => c_base_div_v + procedure, pass(z) :: div_a2 => c_base_div_a2 + generic, public :: div => div_v, div_a2 + ! ! Scaling and norms ! procedure, pass(x) :: scal => c_base_scal @@ -183,11 +189,11 @@ module psb_c_base_vect_mod end interface psb_c_base_vect contains - + ! - ! Constructors. + ! Constructors. ! - + !> Function constructor: !! \brief Constructor from an array !! \param x(:) input array to be copied @@ -200,11 +206,11 @@ contains this%v = x call this%asb(size(x,kind=psb_ipk_),info) end function constructor - - + + !> Function constructor: !! \brief Constructor from size - !! \param n Size of vector to be built. + !! \param n Size of vector to be built. !! function size_const(n) result(this) integer(psb_ipk_), intent(in) :: n @@ -214,7 +220,7 @@ contains call this%asb(n,info) end function size_const - + ! ! Build from a sample ! @@ -226,20 +232,20 @@ contains !! subroutine c_base_bld_x(x,this) use psb_realloc_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: this(:) class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info call psb_realloc(size(this),x%v,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_vect_bld') return end if x%v(:) = this(:) end subroutine c_base_bld_x - + ! ! Create with size, but no initialization ! @@ -247,11 +253,11 @@ contains !> Function bld_mn: !! \memberof psb_c_base_vect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine c_base_bld_mn(x,n) use psb_realloc_mod - implicit none + implicit none integer(psb_mpk_), intent(in) :: n class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info @@ -260,15 +266,15 @@ contains call x%asb(n,info) end subroutine c_base_bld_mn - + !> Function bld_en: !! \memberof psb_c_base_vect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine c_base_bld_en(x,n) use psb_realloc_mod - implicit none + implicit none integer(psb_epk_), intent(in) :: n class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info @@ -277,24 +283,24 @@ contains call x%asb(n,info) end subroutine c_base_bld_en - + !> Function base_all: !! \memberof psb_c_base_vect_type !! \brief Build method with size (uninitialized data) and !! allocation return code. - !! \param n size to be allocated. + !! \param n size to be allocated. !! \param info return code !! subroutine c_base_all(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_c_base_vect_type), intent(out) :: x integer(psb_ipk_), intent(out) :: info - + call psb_realloc(n,x%v,info) - + end subroutine c_base_all !> Function base_mold: @@ -306,11 +312,11 @@ contains subroutine c_base_mold(x, y, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(in) :: x class(psb_c_base_vect_type), intent(out), allocatable :: y integer(psb_ipk_), intent(out) :: info - + allocate(psb_c_base_vect_type :: y, stat=info) end subroutine c_base_mold @@ -320,21 +326,21 @@ contains ! !> Function base_ins: !! \memberof psb_c_base_vect_type - !! \brief Insert coefficients. + !! \brief Insert coefficients. !! !! !! Given a list of N pairs !! (IRL(i),VAL(i)) !! record a new coefficient in X such that !! X(IRL(1:N)) = VAL(1:N). - !! + !! !! - the update operation will perform either !! X(IRL(1:n)) = VAL(1:N) !! or !! X(IRL(1:n)) = X(IRL(1:n))+VAL(1:N) !! according to the value of DUPLICATE. - !! - !! + !! + !! !! \param n number of pairs in input !! \param irl(:) the input row indices !! \param val(:) the input coefficients @@ -344,7 +350,7 @@ contains ! subroutine c_base_ins_a(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -354,21 +360,21 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ - else if (n > min(size(irl),size(val))) then + else if (n > min(size(irl),size(val))) then info = psb_err_invalid_input_ - else + else isz = size(x%v) - select case(dupl) - case(psb_dupl_ovwrt_) + select case(dupl) + case(psb_dupl_ovwrt_) do i = 1, n !loop over all val's rows - ! row actual block row + ! row actual block row if ((1 <= irl(i)).and.(irl(i) <= isz)) then ! this row belongs to me ! copy i-th row of block val in x @@ -376,7 +382,7 @@ contains end if enddo - case(psb_dupl_add_) + case(psb_dupl_add_) do i = 1, n !loop over all val's rows @@ -394,7 +400,7 @@ contains end select end if call x%set_host() - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_vect_ins') return end if @@ -403,7 +409,7 @@ contains subroutine c_base_ins_v(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl class(psb_i_base_vect_type), intent(inout) :: irl @@ -413,14 +419,14 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return if (irl%is_dev()) call irl%sync() if (val%is_dev()) call val%sync() if (x%is_dev()) call x%sync() call x%ins(n,irl%v,val%v,dupl,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_vect_ins') return end if @@ -436,14 +442,14 @@ contains ! subroutine c_base_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x - + if (allocated(x%v)) x%v=czero call x%set_host() end subroutine c_base_zero - + ! ! Assembly. ! For derived classes: after this the vector @@ -452,20 +458,20 @@ contains !> Function base_asb: !! \memberof psb_c_base_vect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! ! - + subroutine c_base_asb_m(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_mpk_), intent(in) :: n class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (x%get_nrows() < n) & & call psb_realloc(n,x%v,info) @@ -482,20 +488,20 @@ contains !> Function base_asb: !! \memberof psb_c_base_vect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! ! - + subroutine c_base_asb_e(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_epk_), intent(in) :: n class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (x%get_nrows() < n) & & call psb_realloc(n,x%v,info) @@ -508,39 +514,39 @@ contains !> Function base_free: !! \memberof psb_c_base_vect_type !! \brief Free vector - !! + !! !! \param info return code !! ! subroutine c_base_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (allocated(x%v)) deallocate(x%v, stat=info) if (info == 0) call x%free_buffer(info) if (info == 0) call x%free_comid(info) - if (info /= 0) call & + if (info /= 0) call & & psb_errpush(psb_err_alloc_dealloc_,'vect_free') - + end subroutine c_base_free - + ! !> Function base_free_buffer: !! \memberof psb_c_base_vect_type !! \brief Free aux buffer - !! + !! !! \param info return code !! ! subroutine c_base_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -555,17 +561,17 @@ contains !! In some derived classes, e.g. GPU, !! does not really frees to avoid runtime !! costs - !! + !! !! \param info return code !! ! subroutine c_base_maybe_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (psb_get_maybe_free_buffer())& & call x%free_buffer(info) @@ -575,13 +581,13 @@ contains !> Function base_free_comid: !! \memberof psb_c_base_vect_type !! \brief Free aux MPI communication id buffer - !! + !! !! \param info return code !! ! subroutine c_base_free_comid(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -593,77 +599,77 @@ contains ! ! The base version of SYNC & friends does nothing, it's just ! a placeholder. - ! + ! ! !> Function base_sync: !! \memberof psb_c_base_vect_type !! \brief Sync: base version is a no-op. - !! + !! ! subroutine c_base_sync(x) - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x - + end subroutine c_base_sync ! !> Function base_set_host: !! \memberof psb_c_base_vect_type !! \brief Set_host: base version is a no-op. - !! + !! ! subroutine c_base_set_host(x) - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x - + end subroutine c_base_set_host ! !> Function base_set_dev: !! \memberof psb_c_base_vect_type !! \brief Set_dev: base version is a no-op. - !! + !! ! subroutine c_base_set_dev(x) - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x - + end subroutine c_base_set_dev ! !> Function base_set_sync: !! \memberof psb_c_base_vect_type !! \brief Set_sync: base version is a no-op. - !! + !! ! subroutine c_base_set_sync(x) - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x - + end subroutine c_base_set_sync ! !> Function base_is_dev: !! \memberof psb_c_base_vect_type !! \brief Is vector on external device . - !! + !! ! function c_base_is_dev(x) result(res) - implicit none + implicit none class(psb_c_base_vect_type), intent(in) :: x logical :: res - + res = .false. end function c_base_is_dev - + ! !> Function base_is_host !! \memberof psb_c_base_vect_type !! \brief Is vector on standard memory . - !! + !! ! function c_base_is_host(x) result(res) - implicit none + implicit none class(psb_c_base_vect_type), intent(in) :: x logical :: res @@ -674,10 +680,10 @@ contains !> Function base_is_sync !! \memberof psb_c_base_vect_type !! \brief Is vector on sync . - !! + !! ! function c_base_is_sync(x) result(res) - implicit none + implicit none class(psb_c_base_vect_type), intent(in) :: x logical :: res @@ -686,16 +692,16 @@ contains ! - ! Size info. + ! Size info. ! ! !> Function base_get_nrows !! \memberof psb_c_base_vect_type !! \brief Number of entries - !! + !! ! function c_base_get_nrows(x) result(res) - implicit none + implicit none class(psb_c_base_vect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -708,13 +714,13 @@ contains !> Function base_get_sizeof !! \memberof psb_c_base_vect_type !! \brief Size in bytes - !! + !! ! function c_base_sizeof(x) result(res) - implicit none + implicit none class(psb_c_base_vect_type), intent(in) :: x integer(psb_epk_) :: res - + ! Force 8-byte integers. res = (1_psb_epk_ * (2*psb_sizeof_sp)) * x%get_nrows() @@ -724,14 +730,14 @@ contains !> Function base_get_fmt !! \memberof psb_c_base_vect_type !! \brief Format - !! + !! ! function c_base_get_fmt() result(res) - implicit none + implicit none character(len=5) :: res res = 'BASE' end function c_base_get_fmt - + ! ! @@ -740,7 +746,7 @@ contains !! \memberof psb_c_base_vect_type !! \brief Extract a copy of the contents !! - ! + ! function c_base_get_vect(x,n) result(res) class(psb_c_base_vect_type), intent(inout) :: x complex(psb_spk_), allocatable :: res(:) @@ -748,21 +754,21 @@ contains integer(psb_ipk_), optional :: n ! Local variables integer(psb_ipk_) :: isz - - if (.not.allocated(x%v)) return + + if (.not.allocated(x%v)) return if (.not.x%is_host()) call x%sync() isz = x%get_nrows() if (present(n)) isz = max(0,min(isz,n)) - allocate(res(isz),stat=info) - if (info /= 0) then + allocate(res(isz),stat=info) + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_get_vect') return end if res(1:isz) = x%v(1:isz) end function c_base_get_vect - + ! - ! Reset all values + ! Reset all values ! ! !> Function base_set_scal @@ -771,18 +777,18 @@ contains !! \param val The value to set !! subroutine c_base_set_scal(x,val,first,last) - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x complex(psb_spk_), intent(in) :: val integer(psb_ipk_), optional :: first, last - + integer(psb_ipk_) :: info, first_, last_ first_=1 last_=size(x%v) if (present(first)) first_ = max(1,first) if (present(last)) last_ = min(last,last_) - + if (x%is_dev()) call x%sync() x%v(first_:last_) = val call x%set_host() @@ -794,14 +800,14 @@ contains !> Function base_set_vect !! \memberof psb_c_base_vect_type !! \brief Set all entries - !! \param val(:) The vector to be copied in + !! \param val(:) The vector to be copied in !! subroutine c_base_set_vect(x,val,first,last) - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x complex(psb_spk_), intent(in) :: val(:) integer(psb_ipk_), optional :: first, last - + integer(psb_ipk_) :: info, first_, last_, nr first_ = 1 @@ -809,7 +815,7 @@ contains last_ = min(psb_size(x%v),first_+size(val)-1) if (present(last)) last_ = min(last,last_) - if (allocated(x%v)) then + if (allocated(x%v)) then if (x%is_dev()) call x%sync() x%v(first_:last_) = val(1:last_-first_+1) else @@ -829,7 +835,7 @@ contains !! \brief Set all entries to their respective absolute values. !! subroutine c_base_absval1(x) - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x if (allocated(x%v)) then @@ -841,21 +847,21 @@ contains end subroutine c_base_absval1 subroutine c_base_absval2(x,y) - implicit none - class(psb_c_base_vect_type), intent(inout) :: x + implicit none + class(psb_c_base_vect_type), intent(inout) :: x class(psb_c_base_vect_type), intent(inout) :: y integer(psb_ipk_) :: info if (.not.x%is_host()) call x%sync() - if (allocated(x%v)) then + if (allocated(x%v)) then call y%axpby(ione*min(x%get_nrows(),y%get_nrows()),cone,x,czero,info) call y%absval() end if - + end subroutine c_base_absval2 ! - ! Dot products - ! + ! Dot products + ! ! !> Function base_dot_v !! \memberof psb_c_base_vect_type @@ -864,12 +870,12 @@ contains !! \param y The other (base_vect) to be multiplied by !! function c_base_dot_v(n,x,y) result(res) - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x, y integer(psb_ipk_), intent(in) :: n complex(psb_spk_) :: res complex(psb_spk_), external :: cdotc - + res = czero ! ! Note: this is the base implementation. @@ -898,19 +904,19 @@ contains !! \param y(:) The array to be multiplied by !! function c_base_dot_a(n,x,y) result(res) - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x complex(psb_spk_), intent(in) :: y(:) integer(psb_ipk_), intent(in) :: n complex(psb_spk_) :: res complex(psb_spk_), external :: cdotc - + res = cdotc(n,y,1,x%v,1) end function c_base_dot_a - + ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! ! @@ -925,13 +931,13 @@ contains !! subroutine c_base_axpby_v(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m class(psb_c_base_vect_type), intent(inout) :: x class(psb_c_base_vect_type), intent(inout) :: y complex(psb_spk_), intent (in) :: alpha, beta integer(psb_ipk_), intent(out) :: info - + if (x%is_dev()) call x%sync() call y%axpby(m,alpha,x%v,beta,info) @@ -939,7 +945,7 @@ contains end subroutine c_base_axpby_v ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! !> Function base_axpby_a @@ -953,20 +959,20 @@ contains !! subroutine c_base_axpby_a(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m complex(psb_spk_), intent(in) :: x(:) class(psb_c_base_vect_type), intent(inout) :: y complex(psb_spk_), intent (in) :: alpha, beta integer(psb_ipk_), intent(out) :: info - + if (y%is_dev()) call y%sync() call psb_geaxpby(m,alpha,x,beta,y%v,info) call y%set_host() - + end subroutine c_base_axpby_a - + ! ! Multiple variants of two operations: ! Simple multiplication Y(:) = X(:)*Y(:) @@ -984,10 +990,10 @@ contains !! subroutine c_base_mlt_v(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x class(psb_c_base_vect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -1005,7 +1011,7 @@ contains !! subroutine c_base_mlt_a(x, y, info) use psi_serial_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: x(:) class(psb_c_base_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -1014,7 +1020,7 @@ contains info = 0 if (y%is_dev()) call y%sync() n = min(size(y%v), size(x)) - do i=1, n + do i=1, n y%v(i) = y%v(i)*x(i) end do call y%set_host() @@ -1035,7 +1041,7 @@ contains !! subroutine c_base_mlt_a_2(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: alpha,beta complex(psb_spk_), intent(in) :: y(:) complex(psb_spk_), intent(in) :: x(:) @@ -1043,58 +1049,58 @@ contains integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n - info = 0 + info = 0 if (z%is_dev()) call z%sync() n = min(size(z%v), size(x), size(y)) - if (alpha == czero) then - if (beta == cone) then - return + if (alpha == czero) then + if (beta == cone) then + return else do i=1, n z%v(i) = beta*z%v(i) end do end if else - if (alpha == cone) then - if (beta == czero) then - do i=1, n + if (alpha == cone) then + if (beta == czero) then + do i=1, n z%v(i) = y(i)*x(i) end do - else if (beta == cone) then - do i=1, n + else if (beta == cone) then + do i=1, n z%v(i) = z%v(i) + y(i)*x(i) end do - else - do i=1, n + else + do i=1, n z%v(i) = beta*z%v(i) + y(i)*x(i) end do end if - else if (alpha == -cone) then - if (beta == czero) then - do i=1, n + else if (alpha == -cone) then + if (beta == czero) then + do i=1, n z%v(i) = -y(i)*x(i) end do - else if (beta == cone) then - do i=1, n + else if (beta == cone) then + do i=1, n z%v(i) = z%v(i) - y(i)*x(i) end do - else - do i=1, n + else + do i=1, n z%v(i) = beta*z%v(i) - y(i)*x(i) end do end if else - if (beta == czero) then - do i=1, n + if (beta == czero) then + do i=1, n z%v(i) = alpha*y(i)*x(i) end do - else if (beta == cone) then - do i=1, n + else if (beta == cone) then + do i=1, n z%v(i) = z%v(i) + alpha*y(i)*x(i) end do - else - do i=1, n + else + do i=1, n z%v(i) = beta*z%v(i) + alpha*y(i)*x(i) end do end if @@ -1118,12 +1124,12 @@ contains subroutine c_base_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) use psi_serial_mod use psb_string_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: alpha,beta class(psb_c_base_vect_type), intent(inout) :: x class(psb_c_base_vect_type), intent(inout) :: y class(psb_c_base_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info character(len=1), intent(in), optional :: conjgx, conjgy integer(psb_ipk_) :: i, n logical :: conjgx_, conjgy_ @@ -1133,7 +1139,7 @@ contains if (x%is_dev()) call x%sync() if (.not.psb_c_is_complex_) then call z%mlt(alpha,x%v,y%v,beta,info) - else + else conjgx_=.false. if (present(conjgx)) conjgx_ = (psb_toupper(conjgx)=='C') conjgy_=.false. @@ -1148,12 +1154,12 @@ contains subroutine c_base_mlt_av(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: alpha,beta complex(psb_spk_), intent(in) :: x(:) class(psb_c_base_vect_type), intent(inout) :: y class(psb_c_base_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -1164,12 +1170,12 @@ contains subroutine c_base_mlt_va(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: alpha,beta complex(psb_spk_), intent(in) :: y(:) class(psb_c_base_vect_type), intent(inout) :: x class(psb_c_base_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -1177,10 +1183,57 @@ contains call z%mlt(alpha,y,x,beta,info) end subroutine c_base_mlt_va + ! + !> Function base_div_v + !! \memberof psb_c_base_vect_type + !! \brief Vector entry-by-entry divide by a vector x=x/y + !! \param y The array to be divided by + !! \param info return code + !! + subroutine c_base_div_v(x, y, info) + use psi_serial_mod + implicit none + class(psb_c_base_vect_type), intent(inout) :: x + class(psb_c_base_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (x%is_dev()) call x%sync() + call x%div(x%v,y%v,info) + + + end subroutine c_base_div_v + ! + !> Function base_div_a2 + !! \memberof psb_c_base_vect_type + !! \brief Entry-by-entry divide between normal array x=x/y + !! \param x(:) The array to be multiplied by + !! \param info return code + !! + subroutine c_base_div_a2(x, y, z, info) + use psi_serial_mod + implicit none + class(psb_c_base_vect_type), intent(inout) :: z + complex(psb_spk_), intent(in) :: x(:) + complex(psb_spk_), intent(in) :: y(:) + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (z%is_dev()) call z%sync() + + n = min(size(y), size(x)) + do i=1, n + z%v(i) = x(i)/y(i) + end do + + end subroutine c_base_div_a2 + ! - ! Simple scaling + ! Simple scaling ! !> Function base_scal !! \memberof psb_c_base_vect_type @@ -1189,17 +1242,17 @@ contains !! subroutine c_base_scal(alpha, x) use psi_serial_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x complex(psb_spk_), intent (in) :: alpha - - if (allocated(x%v)) then + + if (allocated(x%v)) then x%v = alpha*x%v call x%set_host() end if end subroutine c_base_scal - + ! ! Norms 1, 2 and infinity ! @@ -1208,28 +1261,28 @@ contains !! \brief 2-norm |x(1:n)|_2 !! \param n how many entries to consider function c_base_nrm2(n,x) result(res) - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res real(psb_spk_), external :: scnrm2 - + if (x%is_dev()) call x%sync() res = scnrm2(n,x%v,1) end function c_base_nrm2 - + ! !> Function base_amax !! \memberof psb_c_base_vect_type !! \brief infinity-norm |x(1:n)|_\infty !! \param n how many entries to consider function c_base_amax(n,x) result(res) - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res - + if (x%is_dev()) call x%sync() res = maxval(abs(x%v(1:n))) @@ -1241,17 +1294,17 @@ contains !! \brief 1-norm |x(1:n)|_1 !! \param n how many entries to consider function c_base_asum(n,x) result(res) - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res - + if (x%is_dev()) call x%sync() res = sum(abs(x%v(1:n))) end function c_base_asum - - + + ! ! Gather: Y = beta * Y + alpha * X(IDX(:)) ! @@ -1266,18 +1319,18 @@ contains !! \param beta subroutine c_base_gthab(n,idx,alpha,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_spk_) :: alpha, beta, y(:) class(psb_c_base_vect_type) :: x - + if (x%is_dev()) call x%sync() call psi_gth(n,idx,alpha,x%v,beta,y) end subroutine c_base_gthab ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_gthzv !! \memberof psb_c_base_vect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1286,28 +1339,28 @@ contains !! \param idx(:) indices subroutine c_base_gthzv_x(i,n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx complex(psb_spk_) :: y(:) class(psb_c_base_vect_type) :: x - + if (idx%is_dev()) call idx%sync() call x%gth(n,idx%v(i:),y) end subroutine c_base_gthzv_x ! - ! New comm internals impl. + ! New comm internals impl. ! subroutine c_base_gthzbuf(i,n,idx,x) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx class(psb_c_base_vect_type) :: x - - if (.not.allocated(x%combuf)) then + + if (.not.allocated(x%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf') return end if @@ -1320,22 +1373,22 @@ contains !> Function base_device_wait: !! \memberof psb_c_base_vect_type !! \brief device_wait: base version is a no-op. - !! + !! ! subroutine c_base_device_wait() - implicit none - + implicit none + end subroutine c_base_device_wait function c_base_use_buffer() result(res) logical :: res - + res = .true. end function c_base_use_buffer subroutine c_base_new_buffer(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -1345,7 +1398,7 @@ contains subroutine c_base_new_comid(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -1356,7 +1409,7 @@ contains ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_gthzv !! \memberof psb_c_base_vect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1365,20 +1418,20 @@ contains !! \param idx(:) indices subroutine c_base_gthzv(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_spk_) :: y(:) class(psb_c_base_vect_type) :: x - + if (x%is_dev()) call x%sync() call psi_gth(n,idx,x%v,y) end subroutine c_base_gthzv ! - ! Scatter: + ! Scatter: ! Y(IDX(:)) = beta*Y(IDX(:)) + X(:) - ! + ! ! !> Function base_sctb !! \memberof psb_c_base_vect_type @@ -1387,14 +1440,14 @@ contains !! \param n how many entries to consider !! \param idx(:) indices !! \param beta - !! \param x(:) + !! \param x(:) subroutine c_base_sctb(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_spk_) :: beta, x(:) class(psb_c_base_vect_type) :: y - + if (y%is_dev()) call y%sync() call psi_sct(n,idx,x,beta,y%v) call y%set_host() @@ -1403,12 +1456,12 @@ contains subroutine c_base_sctb_x(i,n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx complex(psb_spk_) :: beta, x(:) class(psb_c_base_vect_type) :: y - + if (idx%is_dev()) call idx%sync() call y%sct(n,idx%v(i:),x,beta) call y%set_host() @@ -1417,14 +1470,14 @@ contains subroutine c_base_sctb_buf(i,n,idx,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx complex(psb_spk_) :: beta class(psb_c_base_vect_type) :: y - - - if (.not.allocated(y%combuf)) then + + + if (.not.allocated(y%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf') return end if @@ -1449,22 +1502,22 @@ module psb_c_base_multivect_mod use psb_c_base_vect_mod !> \namespace psb_base_mod \class psb_c_base_vect_type - !! The psb_c_base_vect_type + !! The psb_c_base_vect_type !! defines a middle level integer(psb_ipk_) encapsulated dense vector. - !! The encapsulation is needed, in place of a simple array, to allow + !! The encapsulation is needed, in place of a simple array, to allow !! for complicated situations, such as GPU programming, where the memory !! area we are interested in is not easily accessible from the host/Fortran !! side. It is also meant to be encapsulated in an outer type, to allow !! runtime switching as per the STATE design pattern, similar to the !! sparse matrix types. !! - private + private public :: psb_c_base_multivect, psb_c_base_multivect_type type psb_c_base_multivect_type - !> Values. + !> Values. complex(psb_spk_), allocatable :: v(:,:) - complex(psb_spk_), allocatable :: combuf(:) + complex(psb_spk_), allocatable :: combuf(:) integer(psb_mpk_), allocatable :: comid(:,:) contains ! @@ -1478,7 +1531,7 @@ module psb_c_base_multivect_mod ! ! Insert/set. Assembly and free. ! Assembly does almost nothing here, but is important - ! in derived classes. + ! in derived classes. ! procedure, pass(x) :: ins => c_base_mlv_ins procedure, pass(x) :: zero => c_base_mlv_zero @@ -1489,7 +1542,7 @@ module psb_c_base_multivect_mod ! Any derived class having extra storage upon sync ! will guarantee that both fortran/host side and ! external side contain the same data. The base - ! version is only a placeholder. + ! version is only a placeholder. ! procedure, pass(x) :: sync => c_base_mlv_sync procedure, pass(x) :: is_host => c_base_mlv_is_host @@ -1562,7 +1615,7 @@ module psb_c_base_multivect_mod ! ! Gather/scatter. These are needed for MPI interfacing. - ! May have to be reworked. + ! May have to be reworked. ! procedure, pass(x) :: gthab => c_base_mlv_gthab procedure, pass(x) :: gthzv => c_base_mlv_gthzv @@ -1584,7 +1637,7 @@ module psb_c_base_multivect_mod contains ! - ! Constructors. + ! Constructors. ! !> Function constructor: @@ -1603,7 +1656,7 @@ contains !> Function constructor: !! \brief Constructor from size - !! \param n Size of vector to be built. + !! \param n Size of vector to be built. !! function size_const(m,n) result(this) integer(psb_ipk_), intent(in) :: m,n @@ -1630,7 +1683,7 @@ contains integer(psb_ipk_) :: info call psb_realloc(size(this,1),size(this,2),x%v,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_mlv_vect_bld') return end if @@ -1645,7 +1698,7 @@ contains !> Function bld_n: !! \memberof psb_c_base_multivect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine c_base_mlv_bld_n(x,m,n) use psb_realloc_mod @@ -1662,13 +1715,13 @@ contains !! \memberof psb_c_base_multivect_type !! \brief Build method with size (uninitialized data) and !! allocation return code. - !! \param n size to be allocated. + !! \param n size to be allocated. !! \param info return code !! subroutine c_base_mlv_all(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_c_base_multivect_type), intent(out) :: x integer(psb_ipk_), intent(out) :: info @@ -1686,7 +1739,7 @@ contains subroutine c_base_mlv_mold(x, y, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_c_base_multivect_type), intent(in) :: x class(psb_c_base_multivect_type), intent(out), allocatable :: y integer(psb_ipk_), intent(out) :: info @@ -1700,21 +1753,21 @@ contains ! !> Function base_mlv_ins: !! \memberof psb_c_base_multivect_type - !! \brief Insert coefficients. + !! \brief Insert coefficients. !! !! !! Given a list of N pairs !! (IRL(i),VAL(i)) !! record a new coefficient in X such that !! X(IRL(1:N)) = VAL(1:N). - !! + !! !! - the update operation will perform either !! X(IRL(1:n)) = VAL(1:N) !! or !! X(IRL(1:n)) = X(IRL(1:n))+VAL(1:N) !! according to the value of DUPLICATE. - !! - !! + !! + !! !! \param n number of pairs in input !! \param irl(:) the input row indices !! \param val(:) the input coefficients @@ -1724,7 +1777,7 @@ contains ! subroutine c_base_mlv_ins(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -1734,21 +1787,21 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ - else if (n > min(size(irl),size(val))) then + else if (n > min(size(irl),size(val))) then info = psb_err_invalid_input_ - else + else isz = size(x%v,1) - select case(dupl) - case(psb_dupl_ovwrt_) + select case(dupl) + case(psb_dupl_ovwrt_) do i = 1, n !loop over all val's rows - ! row actual block row + ! row actual block row if ((1 <= irl(i)).and.(irl(i) <= isz)) then ! this row belongs to me ! copy i-th row of block val in x @@ -1756,7 +1809,7 @@ contains end if enddo - case(psb_dupl_add_) + case(psb_dupl_add_) do i = 1, n !loop over all val's rows @@ -1773,7 +1826,7 @@ contains ! !$ goto 9999 end select end if - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_mlv_vect_ins') return end if @@ -1788,7 +1841,7 @@ contains ! subroutine c_base_mlv_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x if (allocated(x%v)) x%v=czero @@ -1804,7 +1857,7 @@ contains !> Function base_mlv_asb: !! \memberof psb_c_base_multivect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! @@ -1813,7 +1866,7 @@ contains subroutine c_base_mlv_asb(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_c_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1830,20 +1883,20 @@ contains !> Function base_mlv_free: !! \memberof psb_c_base_multivect_type !! \brief Free vector - !! + !! !! \param info return code !! ! subroutine c_base_mlv_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 if (allocated(x%v)) deallocate(x%v, stat=info) - if (info /= 0) call & + if (info /= 0) call & & psb_errpush(psb_err_alloc_dealloc_,'vect_free') end subroutine c_base_mlv_free @@ -1853,15 +1906,15 @@ contains ! ! The base version of SYNC & friends does nothing, it's just ! a placeholder. - ! + ! ! !> Function base_mlv_sync: !! \memberof psb_c_base_multivect_type !! \brief Sync: base version is a no-op. - !! + !! ! subroutine c_base_mlv_sync(x) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x end subroutine c_base_mlv_sync @@ -1870,10 +1923,10 @@ contains !> Function base_mlv_set_host: !! \memberof psb_c_base_multivect_type !! \brief Set_host: base version is a no-op. - !! + !! ! subroutine c_base_mlv_set_host(x) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x end subroutine c_base_mlv_set_host @@ -1882,10 +1935,10 @@ contains !> Function base_mlv_set_dev: !! \memberof psb_c_base_multivect_type !! \brief Set_dev: base version is a no-op. - !! + !! ! subroutine c_base_mlv_set_dev(x) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x end subroutine c_base_mlv_set_dev @@ -1894,10 +1947,10 @@ contains !> Function base_mlv_set_sync: !! \memberof psb_c_base_multivect_type !! \brief Set_sync: base version is a no-op. - !! + !! ! subroutine c_base_mlv_set_sync(x) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x end subroutine c_base_mlv_set_sync @@ -1906,10 +1959,10 @@ contains !> Function base_mlv_is_dev: !! \memberof psb_c_base_multivect_type !! \brief Is vector on external device . - !! + !! ! function c_base_mlv_is_dev(x) result(res) - implicit none + implicit none class(psb_c_base_multivect_type), intent(in) :: x logical :: res @@ -1920,10 +1973,10 @@ contains !> Function base_mlv_is_host !! \memberof psb_c_base_multivect_type !! \brief Is vector on standard memory . - !! + !! ! function c_base_mlv_is_host(x) result(res) - implicit none + implicit none class(psb_c_base_multivect_type), intent(in) :: x logical :: res @@ -1934,10 +1987,10 @@ contains !> Function base_mlv_is_sync !! \memberof psb_c_base_multivect_type !! \brief Is vector on sync . - !! + !! ! function c_base_mlv_is_sync(x) result(res) - implicit none + implicit none class(psb_c_base_multivect_type), intent(in) :: x logical :: res @@ -1946,16 +1999,16 @@ contains ! - ! Size info. + ! Size info. ! ! !> Function base_mlv_get_nrows !! \memberof psb_c_base_multivect_type !! \brief Number of entries - !! + !! ! function c_base_mlv_get_nrows(x) result(res) - implicit none + implicit none class(psb_c_base_multivect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -1965,7 +2018,7 @@ contains end function c_base_mlv_get_nrows function c_base_mlv_get_ncols(x) result(res) - implicit none + implicit none class(psb_c_base_multivect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -1978,10 +2031,10 @@ contains !> Function base_mlv_get_sizeof !! \memberof psb_c_base_multivect_type !! \brief Size in bytesa - !! + !! ! function c_base_mlv_sizeof(x) result(res) - implicit none + implicit none class(psb_c_base_multivect_type), intent(in) :: x integer(psb_epk_) :: res @@ -1994,10 +2047,10 @@ contains !> Function base_mlv_get_fmt !! \memberof psb_c_base_multivect_type !! \brief Format - !! + !! ! function c_base_mlv_get_fmt() result(res) - implicit none + implicit none character(len=5) :: res res = 'BASE' end function c_base_mlv_get_fmt @@ -2010,18 +2063,18 @@ contains !! \memberof psb_c_base_multivect_type !! \brief Extract a copy of the contents !! - ! + ! function c_base_mlv_get_vect(x) result(res) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x complex(psb_spk_), allocatable :: res(:,:) integer(psb_ipk_) :: info,m,n m = x%get_nrows() n = x%get_ncols() - if (.not.allocated(x%v)) return + if (.not.allocated(x%v)) return call x%sync() - allocate(res(m,n),stat=info) - if (info /= 0) then + allocate(res(m,n),stat=info) + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_mlv_get_vect') return end if @@ -2029,7 +2082,7 @@ contains end function c_base_mlv_get_vect ! - ! Reset all values + ! Reset all values ! ! !> Function base_mlv_set_scal @@ -2038,7 +2091,7 @@ contains !! \param val The value to set !! subroutine c_base_mlv_set_scal(x,val) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x complex(psb_spk_), intent(in) :: val @@ -2051,16 +2104,16 @@ contains !> Function base_mlv_set_vect !! \memberof psb_c_base_multivect_type !! \brief Set all entries - !! \param val(:) The vector to be copied in + !! \param val(:) The vector to be copied in !! subroutine c_base_mlv_set_vect(x,val) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x complex(psb_spk_), intent(in) :: val(:,:) integer(psb_ipk_) :: nr, nc integer(psb_ipk_) :: info - if (allocated(x%v)) then + if (allocated(x%v)) then nr = min(size(x%v,1),size(val,1)) nc = min(size(x%v,2),size(val,2)) @@ -2072,8 +2125,8 @@ contains end subroutine c_base_mlv_set_vect ! - ! Dot products - ! + ! Dot products + ! ! !> Function base_mlv_dot_v !! \memberof psb_c_base_multivect_type @@ -2082,7 +2135,7 @@ contains !! \param y The other (base_mlv_vect) to be multiplied by !! function c_base_mlv_dot_v(n,x,y) result(res) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x, y integer(psb_ipk_), intent(in) :: n complex(psb_spk_), allocatable :: res(:) @@ -2094,7 +2147,7 @@ contains ! ! Note: this is the base implementation. ! When we get here, we are sure that X is of - ! TYPE psb_c_base_mlv_vect (or its class does not care). + ! TYPE psb_c_base_mlv_vect (or its class does not care). ! If Y is not, throw the burden on it, implicitly ! calling dot_a ! @@ -2123,7 +2176,7 @@ contains !! \param y(:) The array to be multiplied by !! function c_base_mlv_dot_a(n,x,y) result(res) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x complex(psb_spk_), intent(in) :: y(:,:) integer(psb_ipk_), intent(in) :: n @@ -2141,7 +2194,7 @@ contains end function c_base_mlv_dot_a ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! ! @@ -2156,7 +2209,7 @@ contains !! subroutine c_base_mlv_axpby_v(m,alpha, x, beta, y, info, n) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m class(psb_c_base_multivect_type), intent(inout) :: x class(psb_c_base_multivect_type), intent(inout) :: y @@ -2180,7 +2233,7 @@ contains end subroutine c_base_mlv_axpby_v ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! !> Function base_mlv_axpby_a @@ -2194,7 +2247,7 @@ contains !! subroutine c_base_mlv_axpby_a(m,alpha, x, beta, y, info,n) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m complex(psb_spk_), intent(in) :: x(:,:) class(psb_c_base_multivect_type), intent(inout) :: y @@ -2230,10 +2283,10 @@ contains !! subroutine c_base_mlv_mlt_mv(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x class(psb_c_base_multivect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info info = 0 if (x%is_dev()) call x%sync() @@ -2243,10 +2296,10 @@ contains subroutine c_base_mlv_mlt_mv_v(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_c_base_vect_type), intent(inout) :: x class(psb_c_base_multivect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info info = 0 if (x%is_dev()) call x%sync() @@ -2263,7 +2316,7 @@ contains !! subroutine c_base_mlv_mlt_ar1(x, y, info) use psi_serial_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: x(:) class(psb_c_base_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -2271,7 +2324,7 @@ contains info = 0 n = min(psb_size(y%v,1_psb_ipk_), size(x)) - do i=1, n + do i=1, n y%v(i,:) = y%v(i,:)*x(i) end do @@ -2286,7 +2339,7 @@ contains !! subroutine c_base_mlv_mlt_ar2(x, y, info) use psi_serial_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: x(:,:) class(psb_c_base_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -2313,7 +2366,7 @@ contains !! subroutine c_base_mlv_mlt_a_2(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: alpha,beta complex(psb_spk_), intent(in) :: y(:,:) complex(psb_spk_), intent(in) :: x(:,:) @@ -2321,38 +2374,38 @@ contains integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, nr, nc - info = 0 + info = 0 nr = min(psb_size(z%v,1_psb_ipk_), size(x,1), size(y,1)) - nc = min(psb_size(z%v,2_psb_ipk_), size(x,2), size(y,2)) - if (alpha == czero) then - if (beta == cone) then - return + nc = min(psb_size(z%v,2_psb_ipk_), size(x,2), size(y,2)) + if (alpha == czero) then + if (beta == cone) then + return else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) end if else - if (alpha == cone) then - if (beta == czero) then + if (alpha == cone) then + if (beta == czero) then z%v(1:nr,1:nc) = y(1:nr,1:nc)*x(1:nr,1:nc) - else if (beta == cone) then + else if (beta == cone) then z%v(1:nr,1:nc) = z%v(1:nr,1:nc) + y(1:nr,1:nc)*x(1:nr,1:nc) - else + else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) + y(1:nr,1:nc)*x(1:nr,1:nc) end if - else if (alpha == -cone) then - if (beta == czero) then + else if (alpha == -cone) then + if (beta == czero) then z%v(1:nr,1:nc) = -y(1:nr,1:nc)*x(1:nr,1:nc) - else if (beta == cone) then + else if (beta == cone) then z%v(1:nr,1:nc) = z%v(1:nr,1:nc) - y(1:nr,1:nc)*x(1:nr,1:nc) - else + else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) - y(1:nr,1:nc)*x(1:nr,1:nc) end if else - if (beta == czero) then + if (beta == czero) then z%v(1:nr,1:nc) = alpha*y(1:nr,1:nc)*x(1:nr,1:nc) - else if (beta == cone) then + else if (beta == cone) then z%v(1:nr,1:nc) = z%v(1:nr,1:nc) + alpha*y(1:nr,1:nc)*x(1:nr,1:nc) - else + else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) + alpha*y(1:nr,1:nc)*x(1:nr,1:nc) end if end if @@ -2373,12 +2426,12 @@ contains subroutine c_base_mlv_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) use psi_serial_mod use psb_string_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: alpha,beta class(psb_c_base_multivect_type), intent(inout) :: x class(psb_c_base_multivect_type), intent(inout) :: y class(psb_c_base_multivect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info character(len=1), intent(in), optional :: conjgx, conjgy integer(psb_ipk_) :: i, n logical :: conjgx_, conjgy_ @@ -2389,7 +2442,7 @@ contains if (z%is_dev()) call z%sync() if (.not.psb_c_is_complex_) then call z%mlt(alpha,x%v,y%v,beta,info) - else + else conjgx_=.false. if (present(conjgx)) conjgx_ = (psb_toupper(conjgx)=='C') conjgy_=.false. @@ -2404,39 +2457,39 @@ contains !!$ !!$ subroutine c_base_mlv_mlt_av(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_spk_), intent(in) :: alpha,beta !!$ complex(psb_spk_), intent(in) :: x(:) !!$ class(psb_c_base_multivect_type), intent(inout) :: y !!$ class(psb_c_base_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 -!!$ +!!$ !!$ call z%mlt(alpha,x,y%v,beta,info) !!$ !!$ end subroutine c_base_mlv_mlt_av !!$ !!$ subroutine c_base_mlv_mlt_va(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_spk_), intent(in) :: alpha,beta !!$ complex(psb_spk_), intent(in) :: y(:) !!$ class(psb_c_base_multivect_type), intent(inout) :: x !!$ class(psb_c_base_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 -!!$ +!!$ !!$ call z%mlt(alpha,y,x,beta,info) !!$ !!$ end subroutine c_base_mlv_mlt_va !!$ !!$ ! - ! Simple scaling + ! Simple scaling ! !> Function base_mlv_scal !! \memberof psb_c_base_multivect_type @@ -2445,7 +2498,7 @@ contains !! subroutine c_base_mlv_scal(alpha, x) use psi_serial_mod - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x complex(psb_spk_), intent (in) :: alpha @@ -2462,7 +2515,7 @@ contains !! \brief 2-norm |x(1:n)|_2 !! \param n how many entries to consider function c_base_mlv_nrm2(n,x) result(res) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_), allocatable :: res(:) @@ -2484,7 +2537,7 @@ contains !! \brief infinity-norm |x(1:n)|_\infty !! \param n how many entries to consider function c_base_mlv_amax(n,x) result(res) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_), allocatable :: res(:) @@ -2505,7 +2558,7 @@ contains !! \brief 1-norm |x(1:n)|_1 !! \param n how many entries to consider function c_base_mlv_asum(n,x) result(res) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_), allocatable :: res(:) @@ -2528,7 +2581,7 @@ contains !! \brief Set all entries to their respective absolute values. !! subroutine c_base_mlv_absval1(x) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x if (allocated(x%v)) then @@ -2540,13 +2593,13 @@ contains end subroutine c_base_mlv_absval1 subroutine c_base_mlv_absval2(x,y) - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x class(psb_c_base_multivect_type), intent(inout) :: y integer(psb_ipk_) :: info - + if (x%is_dev()) call x%sync() - if (allocated(x%v)) then + if (allocated(x%v)) then call y%axpby(min(x%get_nrows(),y%get_nrows()),cone,x,czero,info) call y%absval() end if @@ -2555,15 +2608,15 @@ contains function c_base_mlv_use_buffer() result(res) - implicit none + implicit none logical :: res - + res = .true. end function c_base_mlv_use_buffer subroutine c_base_mlv_new_buffer(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -2575,7 +2628,7 @@ contains subroutine c_base_mlv_new_comid(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -2586,12 +2639,12 @@ contains subroutine c_base_mlv_maybe_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (psb_get_maybe_free_buffer())& & call x%free_buffer(info) @@ -2599,7 +2652,7 @@ contains subroutine c_base_mlv_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -2609,7 +2662,7 @@ contains subroutine c_base_mlv_free_comid(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_c_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -2632,7 +2685,7 @@ contains !! \param beta subroutine c_base_mlv_gthab(n,idx,alpha,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_spk_) :: alpha, beta, y(:) class(psb_c_base_multivect_type) :: x @@ -2648,7 +2701,7 @@ contains end subroutine c_base_mlv_gthab ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_c_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -2657,7 +2710,7 @@ contains !! \param idx(:) indices subroutine c_base_mlv_gthzv_x(i,n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx complex(psb_spk_) :: y(:) @@ -2670,7 +2723,7 @@ contains ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_c_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -2679,7 +2732,7 @@ contains !! \param idx(:) indices subroutine c_base_mlv_gthzv(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_spk_) :: y(:) class(psb_c_base_multivect_type) :: x @@ -2696,7 +2749,7 @@ contains end subroutine c_base_mlv_gthzv ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_c_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -2705,7 +2758,7 @@ contains !! \param idx(:) indices subroutine c_base_mlv_gthzm(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_spk_) :: y(:,:) class(psb_c_base_multivect_type) :: x @@ -2722,17 +2775,17 @@ contains end subroutine c_base_mlv_gthzm ! - ! New comm internals impl. + ! New comm internals impl. ! subroutine c_base_mlv_gthzbuf(i,ixb,n,idx,x) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, ixb, n class(psb_i_base_vect_type) :: idx class(psb_c_base_multivect_type) :: x integer(psb_ipk_) :: nc - - if (.not.allocated(x%combuf)) then + + if (.not.allocated(x%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf') return end if @@ -2744,9 +2797,9 @@ contains end subroutine c_base_mlv_gthzbuf ! - ! Scatter: + ! Scatter: ! Y(IDX(:),:) = beta*Y(IDX(:),:) + X(:) - ! + ! ! !> Function base_mlv_sctb !! \memberof psb_c_base_multivect_type @@ -2755,10 +2808,10 @@ contains !! \param n how many entries to consider !! \param idx(:) indices !! \param beta - !! \param x(:) + !! \param x(:) subroutine c_base_mlv_sctb(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_spk_) :: beta, x(:) class(psb_c_base_multivect_type) :: y @@ -2773,7 +2826,7 @@ contains subroutine c_base_mlv_sctbr2(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_spk_) :: beta, x(:,:) class(psb_c_base_multivect_type) :: y @@ -2788,7 +2841,7 @@ contains subroutine c_base_mlv_sctb_x(i,n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx complex( psb_spk_) :: beta, x(:) @@ -2800,14 +2853,14 @@ contains subroutine c_base_mlv_sctb_buf(i,iyb,n,idx,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, iyb, n class(psb_i_base_vect_type) :: idx complex(psb_spk_) :: beta class(psb_c_base_multivect_type) :: y integer(psb_ipk_) :: nc - - if (.not.allocated(y%combuf)) then + + if (.not.allocated(y%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf') return end if @@ -2816,19 +2869,18 @@ contains nc = y%get_ncols() call y%sct(n,idx%v(i:),y%combuf(iyb:),beta) call y%set_host() - + end subroutine c_base_mlv_sctb_buf ! !> Function base_device_wait: !! \memberof psb_c_base_vect_type !! \brief device_wait: base version is a no-op. - !! + !! ! subroutine c_base_mlv_device_wait() - implicit none - + implicit none + end subroutine c_base_mlv_device_wait end module psb_c_base_multivect_mod - diff --git a/base/modules/serial/psb_c_vect_mod.F90 b/base/modules/serial/psb_c_vect_mod.F90 index c7a9a0742..02965a3c3 100644 --- a/base/modules/serial/psb_c_vect_mod.F90 +++ b/base/modules/serial/psb_c_vect_mod.F90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,15 +27,15 @@ ! 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. -! -! +! +! ! ! package: psb_c_vect_mod ! ! This module contains the definition of the psb_c_vect type which ! is the outer container for dense vectors. ! Therefore all methods simply invoke the corresponding methods of the -! inner component. +! inner component. ! module psb_c_vect_mod @@ -43,7 +43,7 @@ module psb_c_vect_mod use psb_i_vect_mod type psb_c_vect_type - class(psb_c_base_vect_type), allocatable :: v + class(psb_c_base_vect_type), allocatable :: v contains procedure, pass(x) :: get_nrows => c_vect_get_nrows procedure, pass(x) :: sizeof => c_vect_sizeof @@ -94,13 +94,16 @@ module psb_c_vect_mod procedure, pass(z) :: mlt_av => c_vect_mlt_av generic, public :: mlt => mlt_v, mlt_a, mlt_a_2,& & mlt_v_2, mlt_av, mlt_va + procedure, pass(x) :: div_v => c_vect_div_v + procedure, pass(z) :: div_a2 => c_vect_div_a2 + generic, public :: div => div_v, div_a2 procedure, pass(x) :: scal => c_vect_scal procedure, pass(x) :: absval1 => c_vect_absval1 procedure, pass(x) :: absval2 => c_vect_absval2 generic, public :: absval => absval1, absval2 procedure, pass(x) :: nrm2 => c_vect_nrm2 procedure, pass(x) :: amax => c_vect_amax - procedure, pass(x) :: asum => c_vect_asum + procedure, pass(x) :: asum => c_vect_asum end type psb_c_vect_type public :: psb_c_vect @@ -122,7 +125,7 @@ module psb_c_vect_mod private :: c_vect_dot_v, c_vect_dot_a, c_vect_axpby_v, c_vect_axpby_a, & & c_vect_mlt_v, c_vect_mlt_a, c_vect_mlt_a_2, c_vect_mlt_v_2, & & c_vect_mlt_va, c_vect_mlt_av, c_vect_scal, c_vect_absval1, & - & c_vect_absval2, c_vect_nrm2, c_vect_amax, c_vect_asum + & c_vect_absval2, c_vect_nrm2, c_vect_amax, c_vect_asum @@ -141,11 +144,11 @@ module psb_c_vect_mod contains - subroutine psb_c_set_vect_default(v) - implicit none + subroutine psb_c_set_vect_default(v) + implicit none class(psb_c_base_vect_type), intent(in) :: v - if (allocated(psb_c_base_vect_default)) then + if (allocated(psb_c_base_vect_default)) then deallocate(psb_c_base_vect_default) end if allocate(psb_c_base_vect_default, mold=v) @@ -153,7 +156,7 @@ contains end subroutine psb_c_set_vect_default function psb_c_get_vect_default(v) result(res) - implicit none + implicit none class(psb_c_vect_type), intent(in) :: v class(psb_c_base_vect_type), pointer :: res @@ -163,10 +166,10 @@ contains function psb_c_get_base_vect_default() result(res) - implicit none + implicit none class(psb_c_base_vect_type), pointer :: res - if (.not.allocated(psb_c_base_vect_default)) then + if (.not.allocated(psb_c_base_vect_default)) then allocate(psb_c_base_vect_type :: psb_c_base_vect_default) end if @@ -176,14 +179,14 @@ contains subroutine c_vect_clone(x,y,info) - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x class(psb_c_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info info = psb_success_ call y%free(info) - if ((info==0).and.allocated(x%v)) then + if ((info==0).and.allocated(x%v)) then call y%bld(x%get_vect(),mold=x%v) end if end subroutine c_vect_clone @@ -198,7 +201,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_c_get_base_vect_default()) @@ -220,7 +223,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_c_get_base_vect_default()) @@ -241,7 +244,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_c_get_base_vect_default()) @@ -304,7 +307,7 @@ contains end function size_const function c_vect_get_nrows(x) result(res) - implicit none + implicit none class(psb_c_vect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -312,7 +315,7 @@ contains end function c_vect_get_nrows function c_vect_sizeof(x) result(res) - implicit none + implicit none class(psb_c_vect_type), intent(in) :: x integer(psb_epk_) :: res res = 0 @@ -320,7 +323,7 @@ contains end function c_vect_sizeof function c_vect_get_fmt(x) result(res) - implicit none + implicit none class(psb_c_vect_type), intent(in) :: x character(len=5) :: res res = 'NULL' @@ -329,7 +332,7 @@ contains subroutine c_vect_all(n, x, info, mold) - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_c_vect_type), intent(inout) :: x class(psb_c_base_vect_type), intent(in), optional :: mold @@ -338,12 +341,12 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(psb_c_base_vect_type :: x%v,stat=info) endif - if (info == 0) then + if (info == 0) then call x%v%all(n,info) else info = psb_err_alloc_dealloc_ @@ -353,12 +356,12 @@ contains subroutine c_vect_reall(n, x, info) - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_c_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (.not.allocated(x%v)) & & call x%all(n,info) if (info == 0) & @@ -368,7 +371,7 @@ contains subroutine c_vect_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x if (allocated(x%v)) call x%v%zero() @@ -378,7 +381,7 @@ contains subroutine c_vect_asb(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_c_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -424,12 +427,12 @@ contains subroutine c_vect_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%free(info) if (info == 0) deallocate(x%v,stat=info) end if @@ -438,7 +441,7 @@ contains subroutine c_vect_ins_a(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -448,7 +451,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ return end if @@ -459,7 +462,7 @@ contains subroutine c_vect_ins_v(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl class(psb_i_vect_type), intent(inout) :: irl @@ -469,7 +472,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then + if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then info = psb_err_invalid_vect_state_ return end if @@ -487,12 +490,12 @@ contains integer(psb_ipk_) :: info info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(tmp,stat=info,mold=mold) else allocate(tmp,stat=info,mold=psb_c_get_base_vect_default()) end if - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%sync() if (info == psb_success_) call tmp%bld(x%v%v) call x%v%free(info) @@ -503,7 +506,7 @@ contains subroutine c_vect_sync(x) - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -512,7 +515,7 @@ contains end subroutine c_vect_sync subroutine c_vect_set_sync(x) - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -521,7 +524,7 @@ contains end subroutine c_vect_set_sync subroutine c_vect_set_host(x) - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -530,7 +533,7 @@ contains end subroutine c_vect_set_host subroutine c_vect_set_dev(x) - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -539,7 +542,7 @@ contains end subroutine c_vect_set_dev function c_vect_is_sync(x) result(res) - implicit none + implicit none logical :: res class(psb_c_vect_type), intent(inout) :: x @@ -550,7 +553,7 @@ contains end function c_vect_is_sync function c_vect_is_host(x) result(res) - implicit none + implicit none logical :: res class(psb_c_vect_type), intent(inout) :: x @@ -561,11 +564,11 @@ contains end function c_vect_is_host function c_vect_is_dev(x) result(res) - implicit none + implicit none logical :: res class(psb_c_vect_type), intent(inout) :: x - res = .false. + res = .false. if (allocated(x%v)) & & res = x%v%is_dev() @@ -573,7 +576,7 @@ contains function c_vect_dot_v(n,x,y) result(res) - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x, y integer(psb_ipk_), intent(in) :: n complex(psb_spk_) :: res @@ -585,7 +588,7 @@ contains end function c_vect_dot_v function c_vect_dot_a(n,x,y) result(res) - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x complex(psb_spk_), intent(in) :: y(:) integer(psb_ipk_), intent(in) :: n @@ -599,14 +602,14 @@ contains subroutine c_vect_axpby_v(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m class(psb_c_vect_type), intent(inout) :: x class(psb_c_vect_type), intent(inout) :: y complex(psb_spk_), intent (in) :: alpha, beta integer(psb_ipk_), intent(out) :: info - if (allocated(x%v).and.allocated(y%v)) then + if (allocated(x%v).and.allocated(y%v)) then call y%v%axpby(m,alpha,x%v,beta,info) else info = psb_err_invalid_vect_state_ @@ -616,7 +619,7 @@ contains subroutine c_vect_axpby_a(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m complex(psb_spk_), intent(in) :: x(:) class(psb_c_vect_type), intent(inout) :: y @@ -631,10 +634,10 @@ contains subroutine c_vect_mlt_v(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x class(psb_c_vect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -645,7 +648,7 @@ contains subroutine c_vect_mlt_a(x, y, info) use psi_serial_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: x(:) class(psb_c_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -661,7 +664,7 @@ contains subroutine c_vect_mlt_a_2(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: alpha,beta complex(psb_spk_), intent(in) :: y(:) complex(psb_spk_), intent(in) :: x(:) @@ -669,7 +672,7 @@ contains integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n - info = 0 + info = 0 if (allocated(z%v)) & & call z%v%mlt(alpha,x,y,beta,info) @@ -677,12 +680,12 @@ contains subroutine c_vect_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) use psi_serial_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: alpha,beta class(psb_c_vect_type), intent(inout) :: x class(psb_c_vect_type), intent(inout) :: y class(psb_c_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info character(len=1), intent(in), optional :: conjgx, conjgy integer(psb_ipk_) :: i, n @@ -696,12 +699,12 @@ contains subroutine c_vect_mlt_av(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: alpha,beta complex(psb_spk_), intent(in) :: x(:) class(psb_c_vect_type), intent(inout) :: y class(psb_c_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -712,12 +715,12 @@ contains subroutine c_vect_mlt_va(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_spk_), intent(in) :: alpha,beta complex(psb_spk_), intent(in) :: y(:) class(psb_c_vect_type), intent(inout) :: x class(psb_c_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -727,9 +730,38 @@ contains end subroutine c_vect_mlt_va + subroutine c_vect_div_v(x, y, info) + use psi_serial_mod + implicit none + class(psb_c_vect_type), intent(inout) :: x + class(psb_c_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (allocated(x%v).and.allocated(y%v)) & + & call x%v%div(y%v,info) + + end subroutine c_vect_div_v + + subroutine c_vect_div_a2(x, y, z, info) + use psi_serial_mod + implicit none + complex(psb_spk_), intent(in) :: x(:) + complex(psb_spk_), intent(in) :: y(:) + class(psb_c_vect_type), intent(inout) :: z + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (allocated(z%v)) & + & call z%v%div(x,y,info) + + end subroutine c_vect_div_a2 + subroutine c_vect_scal(alpha, x) use psi_serial_mod - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x complex(psb_spk_), intent (in) :: alpha @@ -749,19 +781,19 @@ contains class(psb_c_vect_type), intent(inout) :: x class(psb_c_vect_type), intent(inout) :: y - if (allocated(x%v)) then + if (allocated(x%v)) then if (.not.allocated(y%v)) call y%bld(psb_size(x%v%v)) call x%v%absval(y%v) end if end subroutine c_vect_absval2 function c_vect_nrm2(n,x) result(res) - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res - if (allocated(x%v)) then + if (allocated(x%v)) then res = x%v%nrm2(n) else res = szero @@ -770,12 +802,12 @@ contains end function c_vect_nrm2 function c_vect_amax(n,x) result(res) - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res - if (allocated(x%v)) then + if (allocated(x%v)) then res = x%v%amax(n) else res = szero @@ -784,12 +816,12 @@ contains end function c_vect_amax function c_vect_asum(n,x) result(res) - implicit none + implicit none class(psb_c_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res - if (allocated(x%v)) then + if (allocated(x%v)) then res = x%v%asum(n) else res = szero @@ -812,7 +844,7 @@ module psb_c_multivect_mod !private type psb_c_multivect_type - class(psb_c_base_multivect_type), allocatable :: v + class(psb_c_base_multivect_type), allocatable :: v contains procedure, pass(x) :: get_nrows => c_vect_get_nrows procedure, pass(x) :: get_ncols => c_vect_get_ncols @@ -886,11 +918,11 @@ module psb_c_multivect_mod contains - subroutine psb_c_set_multivect_default(v) - implicit none + subroutine psb_c_set_multivect_default(v) + implicit none class(psb_c_base_multivect_type), intent(in) :: v - if (allocated(psb_c_base_multivect_default)) then + if (allocated(psb_c_base_multivect_default)) then deallocate(psb_c_base_multivect_default) end if allocate(psb_c_base_multivect_default, mold=v) @@ -898,7 +930,7 @@ contains end subroutine psb_c_set_multivect_default function psb_c_get_multivect_default(v) result(res) - implicit none + implicit none class(psb_c_multivect_type), intent(in) :: v class(psb_c_base_multivect_type), pointer :: res @@ -908,10 +940,10 @@ contains function psb_c_get_base_multivect_default() result(res) - implicit none + implicit none class(psb_c_base_multivect_type), pointer :: res - if (.not.allocated(psb_c_base_multivect_default)) then + if (.not.allocated(psb_c_base_multivect_default)) then allocate(psb_c_base_multivect_type :: psb_c_base_multivect_default) end if @@ -921,14 +953,14 @@ contains subroutine c_vect_clone(x,y,info) - implicit none + implicit none class(psb_c_multivect_type), intent(inout) :: x class(psb_c_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info info = psb_success_ call y%free(info) - if ((info==0).and.allocated(x%v)) then + if ((info==0).and.allocated(x%v)) then call y%bld(x%get_vect(),mold=x%v) end if end subroutine c_vect_clone @@ -941,7 +973,7 @@ contains class(psb_c_base_multivect_type), pointer :: mld info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_c_get_base_multivect_default()) @@ -959,7 +991,7 @@ contains integer(psb_ipk_) :: info info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_c_get_base_multivect_default()) @@ -1019,7 +1051,7 @@ contains end function size_const function c_vect_get_nrows(x) result(res) - implicit none + implicit none class(psb_c_multivect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -1027,7 +1059,7 @@ contains end function c_vect_get_nrows function c_vect_get_ncols(x) result(res) - implicit none + implicit none class(psb_c_multivect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -1035,7 +1067,7 @@ contains end function c_vect_get_ncols function c_vect_sizeof(x) result(res) - implicit none + implicit none class(psb_c_multivect_type), intent(in) :: x integer(psb_epk_) :: res res = 0 @@ -1043,7 +1075,7 @@ contains end function c_vect_sizeof function c_vect_get_fmt(x) result(res) - implicit none + implicit none class(psb_c_multivect_type), intent(in) :: x character(len=5) :: res res = 'NULL' @@ -1052,18 +1084,18 @@ contains subroutine c_vect_all(m,n, x, info, mold) - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_c_multivect_type), intent(out) :: x class(psb_c_base_multivect_type), intent(in), optional :: mold integer(psb_ipk_), intent(out) :: info - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(psb_c_base_multivect_type :: x%v,stat=info) endif - if (info == 0) then + if (info == 0) then call x%v%all(m,n,info) else info = psb_err_alloc_dealloc_ @@ -1073,12 +1105,12 @@ contains subroutine c_vect_reall(m,n, x, info) - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_c_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (.not.allocated(x%v)) & & call x%all(m,n,info) if (info == 0) & @@ -1088,7 +1120,7 @@ contains subroutine c_vect_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_c_multivect_type), intent(inout) :: x if (allocated(x%v)) call x%v%zero() @@ -1098,7 +1130,7 @@ contains subroutine c_vect_asb(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_c_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1109,7 +1141,7 @@ contains end subroutine c_vect_asb subroutine c_vect_sync(x) - implicit none + implicit none class(psb_c_multivect_type), intent(inout) :: x if (allocated(x%v)) & @@ -1177,12 +1209,12 @@ contains subroutine c_vect_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_c_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%free(info) if (info == 0) deallocate(x%v,stat=info) end if @@ -1191,7 +1223,7 @@ contains subroutine c_vect_ins(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_c_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -1201,7 +1233,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ return end if @@ -1217,12 +1249,12 @@ contains class(psb_c_base_multivect_type), allocatable :: tmp integer(psb_ipk_) :: info - if (present(mold)) then + if (present(mold)) then allocate(tmp,stat=info,mold=mold) else allocate(tmp,stat=info, mold=psb_c_get_base_multivect_default()) - endif - if (allocated(x%v)) then + endif + if (allocated(x%v)) then call x%v%sync() if (info == psb_success_) call tmp%bld(x%v%v) call x%v%free(info) @@ -1232,7 +1264,7 @@ contains !!$ function c_vect_dot_v(n,x,y) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_c_multivect_type), intent(inout) :: x, y !!$ integer(psb_ipk_), intent(in) :: n !!$ complex(psb_spk_) :: res @@ -1244,28 +1276,28 @@ contains !!$ end function c_vect_dot_v !!$ !!$ function c_vect_dot_a(n,x,y) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_c_multivect_type), intent(inout) :: x !!$ complex(psb_spk_), intent(in) :: y(:) !!$ integer(psb_ipk_), intent(in) :: n !!$ complex(psb_spk_) :: res -!!$ +!!$ !!$ res = czero !!$ if (allocated(x%v)) & !!$ & res = x%v%dot(n,y) -!!$ +!!$ !!$ end function c_vect_dot_a -!!$ +!!$ !!$ subroutine c_vect_axpby_v(m,alpha, x, beta, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ integer(psb_ipk_), intent(in) :: m !!$ class(psb_c_multivect_type), intent(inout) :: x !!$ class(psb_c_multivect_type), intent(inout) :: y !!$ complex(psb_spk_), intent (in) :: alpha, beta !!$ integer(psb_ipk_), intent(out) :: info -!!$ -!!$ if (allocated(x%v).and.allocated(y%v)) then +!!$ +!!$ if (allocated(x%v).and.allocated(y%v)) then !!$ call y%v%axpby(m,alpha,x%v,beta,info) !!$ else !!$ info = psb_err_invalid_vect_state_ @@ -1275,25 +1307,25 @@ contains !!$ !!$ subroutine c_vect_axpby_a(m,alpha, x, beta, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ integer(psb_ipk_), intent(in) :: m !!$ complex(psb_spk_), intent(in) :: x(:) !!$ class(psb_c_multivect_type), intent(inout) :: y !!$ complex(psb_spk_), intent (in) :: alpha, beta !!$ integer(psb_ipk_), intent(out) :: info -!!$ +!!$ !!$ if (allocated(y%v)) & !!$ & call y%v%axpby(m,alpha,x,beta,info) -!!$ +!!$ !!$ end subroutine c_vect_axpby_a !!$ -!!$ +!!$ !!$ subroutine c_vect_mlt_v(x, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ class(psb_c_multivect_type), intent(inout) :: x !!$ class(psb_c_multivect_type), intent(inout) :: y -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 @@ -1304,7 +1336,7 @@ contains !!$ !!$ subroutine c_vect_mlt_a(x, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_spk_), intent(in) :: x(:) !!$ class(psb_c_multivect_type), intent(inout) :: y !!$ integer(psb_ipk_), intent(out) :: info @@ -1314,13 +1346,13 @@ contains !!$ info = 0 !!$ if (allocated(y%v)) & !!$ & call y%v%mlt(x,info) -!!$ +!!$ !!$ end subroutine c_vect_mlt_a !!$ !!$ !!$ subroutine c_vect_mlt_a_2(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_spk_), intent(in) :: alpha,beta !!$ complex(psb_spk_), intent(in) :: y(:) !!$ complex(psb_spk_), intent(in) :: x(:) @@ -1328,20 +1360,20 @@ contains !!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ -!!$ info = 0 +!!$ info = 0 !!$ if (allocated(z%v)) & !!$ & call z%v%mlt(alpha,x,y,beta,info) -!!$ +!!$ !!$ end subroutine c_vect_mlt_a_2 !!$ !!$ subroutine c_vect_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_spk_), intent(in) :: alpha,beta !!$ class(psb_c_multivect_type), intent(inout) :: x !!$ class(psb_c_multivect_type), intent(inout) :: y !!$ class(psb_c_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ character(len=1), intent(in), optional :: conjgx, conjgy !!$ !!$ integer(psb_ipk_) :: i, n @@ -1355,12 +1387,12 @@ contains !!$ !!$ subroutine c_vect_mlt_av(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_spk_), intent(in) :: alpha,beta !!$ complex(psb_spk_), intent(in) :: x(:) !!$ class(psb_c_multivect_type), intent(inout) :: y !!$ class(psb_c_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 @@ -1371,16 +1403,16 @@ contains !!$ !!$ subroutine c_vect_mlt_va(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_spk_), intent(in) :: alpha,beta !!$ complex(psb_spk_), intent(in) :: y(:) !!$ class(psb_c_multivect_type), intent(inout) :: x !!$ class(psb_c_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 -!!$ +!!$ !!$ if (allocated(z%v).and.allocated(x%v)) & !!$ & call z%v%mlt(alpha,x%v,y,beta,info) !!$ @@ -1388,36 +1420,36 @@ contains !!$ !!$ subroutine c_vect_scal(alpha, x) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ class(psb_c_multivect_type), intent(inout) :: x !!$ complex(psb_spk_), intent (in) :: alpha -!!$ +!!$ !!$ if (allocated(x%v)) call x%v%scal(alpha) !!$ !!$ end subroutine c_vect_scal !!$ !!$ !!$ function c_vect_nrm2(n,x) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_c_multivect_type), intent(inout) :: x !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_spk_) :: res -!!$ -!!$ if (allocated(x%v)) then +!!$ +!!$ if (allocated(x%v)) then !!$ res = x%v%nrm2(n) !!$ else !!$ res = szero !!$ end if !!$ !!$ end function c_vect_nrm2 -!!$ +!!$ !!$ function c_vect_amax(n,x) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_c_multivect_type), intent(inout) :: x !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_spk_) :: res !!$ -!!$ if (allocated(x%v)) then +!!$ if (allocated(x%v)) then !!$ res = x%v%amax(n) !!$ else !!$ res = szero @@ -1426,12 +1458,12 @@ contains !!$ end function c_vect_amax !!$ !!$ function c_vect_asum(n,x) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_c_multivect_type), intent(inout) :: x !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_spk_) :: res !!$ -!!$ if (allocated(x%v)) then +!!$ if (allocated(x%v)) then !!$ res = x%v%asum(n) !!$ else !!$ res = szero diff --git a/base/modules/serial/psb_d_base_vect_mod.f90 b/base/modules/serial/psb_d_base_vect_mod.f90 index 8a59b5134..4d3bb1617 100644 --- a/base/modules/serial/psb_d_base_vect_mod.f90 +++ b/base/modules/serial/psb_d_base_vect_mod.f90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,14 +27,14 @@ ! 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. -! -! +! +! ! ! package: psb_d_base_vect_mod ! ! This module contains the definition of the psb_d_base_vect type which ! is a container for dense vectors. -! This is encapsulated instead of being just a simple array to allow for +! This is encapsulated instead of being just a simple array to allow for ! more complicated situations, such as GPU programming, where the memory ! area we are interested in is not easily accessible from the host/Fortran ! side. It is also meant to be encapsulated in an outer type, to allow @@ -43,7 +43,7 @@ ! ! module psb_d_base_vect_mod - + use psb_const_mod use psb_error_mod use psb_realloc_mod @@ -51,9 +51,9 @@ module psb_d_base_vect_mod use psb_l_base_vect_mod !> \namespace psb_base_mod \class psb_d_base_vect_type - !! The psb_d_base_vect_type + !! The psb_d_base_vect_type !! defines a middle level real(psb_dpk_) encapsulated dense vector. - !! The encapsulation is needed, in place of a simple array, to allow + !! The encapsulation is needed, in place of a simple array, to allow !! for complicated situations, such as GPU programming, where the memory !! area we are interested in is not easily accessible from the host/Fortran !! side. It is also meant to be encapsulated in an outer type, to allow @@ -61,9 +61,9 @@ module psb_d_base_vect_mod !! sparse matrix types. !! type psb_d_base_vect_type - !> Values. + !> Values. real(psb_dpk_), allocatable :: v(:) - real(psb_dpk_), allocatable :: combuf(:) + real(psb_dpk_), allocatable :: combuf(:) integer(psb_mpk_), allocatable :: comid(:,:) contains ! @@ -78,7 +78,7 @@ module psb_d_base_vect_mod ! ! Insert/set. Assembly and free. ! Assembly does almost nothing here, but is important - ! in derived classes. + ! in derived classes. ! procedure, pass(x) :: ins_a => d_base_ins_a procedure, pass(x) :: ins_v => d_base_ins_v @@ -93,7 +93,7 @@ module psb_d_base_vect_mod ! Any derived class having extra storage upon sync ! will guarantee that both fortran/host side and ! external side contain the same data. The base - ! version is only a placeholder. + ! version is only a placeholder. ! procedure, pass(x) :: sync => d_base_sync procedure, pass(x) :: is_host => d_base_is_host @@ -130,7 +130,7 @@ module psb_d_base_vect_mod generic, public :: set => set_vect, set_scal ! ! Gather/scatter. These are needed for MPI interfacing. - ! May have to be reworked. + ! May have to be reworked. ! procedure, pass(x) :: gthab => d_base_gthab procedure, pass(x) :: gthzv => d_base_gthzv @@ -164,6 +164,12 @@ module psb_d_base_vect_mod procedure, pass(z) :: mlt_av => d_base_mlt_av generic, public :: mlt => mlt_v, mlt_a, mlt_a_2, mlt_v_2, mlt_av, mlt_va ! + ! Vector-Vector operations + ! + procedure, pass(x) :: div_v => d_base_div_v + procedure, pass(z) :: div_a2 => d_base_div_a2 + generic, public :: div => div_v, div_a2 + ! ! Scaling and norms ! procedure, pass(x) :: scal => d_base_scal @@ -183,11 +189,11 @@ module psb_d_base_vect_mod end interface psb_d_base_vect contains - + ! - ! Constructors. + ! Constructors. ! - + !> Function constructor: !! \brief Constructor from an array !! \param x(:) input array to be copied @@ -200,11 +206,11 @@ contains this%v = x call this%asb(size(x,kind=psb_ipk_),info) end function constructor - - + + !> Function constructor: !! \brief Constructor from size - !! \param n Size of vector to be built. + !! \param n Size of vector to be built. !! function size_const(n) result(this) integer(psb_ipk_), intent(in) :: n @@ -214,7 +220,7 @@ contains call this%asb(n,info) end function size_const - + ! ! Build from a sample ! @@ -226,20 +232,20 @@ contains !! subroutine d_base_bld_x(x,this) use psb_realloc_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: this(:) class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info call psb_realloc(size(this),x%v,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_vect_bld') return end if x%v(:) = this(:) end subroutine d_base_bld_x - + ! ! Create with size, but no initialization ! @@ -247,11 +253,11 @@ contains !> Function bld_mn: !! \memberof psb_d_base_vect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine d_base_bld_mn(x,n) use psb_realloc_mod - implicit none + implicit none integer(psb_mpk_), intent(in) :: n class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info @@ -260,15 +266,15 @@ contains call x%asb(n,info) end subroutine d_base_bld_mn - + !> Function bld_en: !! \memberof psb_d_base_vect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine d_base_bld_en(x,n) use psb_realloc_mod - implicit none + implicit none integer(psb_epk_), intent(in) :: n class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info @@ -277,24 +283,24 @@ contains call x%asb(n,info) end subroutine d_base_bld_en - + !> Function base_all: !! \memberof psb_d_base_vect_type !! \brief Build method with size (uninitialized data) and !! allocation return code. - !! \param n size to be allocated. + !! \param n size to be allocated. !! \param info return code !! subroutine d_base_all(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_d_base_vect_type), intent(out) :: x integer(psb_ipk_), intent(out) :: info - + call psb_realloc(n,x%v,info) - + end subroutine d_base_all !> Function base_mold: @@ -306,11 +312,11 @@ contains subroutine d_base_mold(x, y, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(in) :: x class(psb_d_base_vect_type), intent(out), allocatable :: y integer(psb_ipk_), intent(out) :: info - + allocate(psb_d_base_vect_type :: y, stat=info) end subroutine d_base_mold @@ -320,21 +326,21 @@ contains ! !> Function base_ins: !! \memberof psb_d_base_vect_type - !! \brief Insert coefficients. + !! \brief Insert coefficients. !! !! !! Given a list of N pairs !! (IRL(i),VAL(i)) !! record a new coefficient in X such that !! X(IRL(1:N)) = VAL(1:N). - !! + !! !! - the update operation will perform either !! X(IRL(1:n)) = VAL(1:N) !! or !! X(IRL(1:n)) = X(IRL(1:n))+VAL(1:N) !! according to the value of DUPLICATE. - !! - !! + !! + !! !! \param n number of pairs in input !! \param irl(:) the input row indices !! \param val(:) the input coefficients @@ -344,7 +350,7 @@ contains ! subroutine d_base_ins_a(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -354,21 +360,21 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ - else if (n > min(size(irl),size(val))) then + else if (n > min(size(irl),size(val))) then info = psb_err_invalid_input_ - else + else isz = size(x%v) - select case(dupl) - case(psb_dupl_ovwrt_) + select case(dupl) + case(psb_dupl_ovwrt_) do i = 1, n !loop over all val's rows - ! row actual block row + ! row actual block row if ((1 <= irl(i)).and.(irl(i) <= isz)) then ! this row belongs to me ! copy i-th row of block val in x @@ -376,7 +382,7 @@ contains end if enddo - case(psb_dupl_add_) + case(psb_dupl_add_) do i = 1, n !loop over all val's rows @@ -394,7 +400,7 @@ contains end select end if call x%set_host() - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_vect_ins') return end if @@ -403,7 +409,7 @@ contains subroutine d_base_ins_v(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl class(psb_i_base_vect_type), intent(inout) :: irl @@ -413,14 +419,14 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return if (irl%is_dev()) call irl%sync() if (val%is_dev()) call val%sync() if (x%is_dev()) call x%sync() call x%ins(n,irl%v,val%v,dupl,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_vect_ins') return end if @@ -436,14 +442,14 @@ contains ! subroutine d_base_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x - + if (allocated(x%v)) x%v=dzero call x%set_host() end subroutine d_base_zero - + ! ! Assembly. ! For derived classes: after this the vector @@ -452,20 +458,20 @@ contains !> Function base_asb: !! \memberof psb_d_base_vect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! ! - + subroutine d_base_asb_m(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_mpk_), intent(in) :: n class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (x%get_nrows() < n) & & call psb_realloc(n,x%v,info) @@ -482,20 +488,20 @@ contains !> Function base_asb: !! \memberof psb_d_base_vect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! ! - + subroutine d_base_asb_e(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_epk_), intent(in) :: n class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (x%get_nrows() < n) & & call psb_realloc(n,x%v,info) @@ -508,39 +514,39 @@ contains !> Function base_free: !! \memberof psb_d_base_vect_type !! \brief Free vector - !! + !! !! \param info return code !! ! subroutine d_base_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (allocated(x%v)) deallocate(x%v, stat=info) if (info == 0) call x%free_buffer(info) if (info == 0) call x%free_comid(info) - if (info /= 0) call & + if (info /= 0) call & & psb_errpush(psb_err_alloc_dealloc_,'vect_free') - + end subroutine d_base_free - + ! !> Function base_free_buffer: !! \memberof psb_d_base_vect_type !! \brief Free aux buffer - !! + !! !! \param info return code !! ! subroutine d_base_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -555,17 +561,17 @@ contains !! In some derived classes, e.g. GPU, !! does not really frees to avoid runtime !! costs - !! + !! !! \param info return code !! ! subroutine d_base_maybe_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (psb_get_maybe_free_buffer())& & call x%free_buffer(info) @@ -575,13 +581,13 @@ contains !> Function base_free_comid: !! \memberof psb_d_base_vect_type !! \brief Free aux MPI communication id buffer - !! + !! !! \param info return code !! ! subroutine d_base_free_comid(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -593,77 +599,77 @@ contains ! ! The base version of SYNC & friends does nothing, it's just ! a placeholder. - ! + ! ! !> Function base_sync: !! \memberof psb_d_base_vect_type !! \brief Sync: base version is a no-op. - !! + !! ! subroutine d_base_sync(x) - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x - + end subroutine d_base_sync ! !> Function base_set_host: !! \memberof psb_d_base_vect_type !! \brief Set_host: base version is a no-op. - !! + !! ! subroutine d_base_set_host(x) - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x - + end subroutine d_base_set_host ! !> Function base_set_dev: !! \memberof psb_d_base_vect_type !! \brief Set_dev: base version is a no-op. - !! + !! ! subroutine d_base_set_dev(x) - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x - + end subroutine d_base_set_dev ! !> Function base_set_sync: !! \memberof psb_d_base_vect_type !! \brief Set_sync: base version is a no-op. - !! + !! ! subroutine d_base_set_sync(x) - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x - + end subroutine d_base_set_sync ! !> Function base_is_dev: !! \memberof psb_d_base_vect_type !! \brief Is vector on external device . - !! + !! ! function d_base_is_dev(x) result(res) - implicit none + implicit none class(psb_d_base_vect_type), intent(in) :: x logical :: res - + res = .false. end function d_base_is_dev - + ! !> Function base_is_host !! \memberof psb_d_base_vect_type !! \brief Is vector on standard memory . - !! + !! ! function d_base_is_host(x) result(res) - implicit none + implicit none class(psb_d_base_vect_type), intent(in) :: x logical :: res @@ -674,10 +680,10 @@ contains !> Function base_is_sync !! \memberof psb_d_base_vect_type !! \brief Is vector on sync . - !! + !! ! function d_base_is_sync(x) result(res) - implicit none + implicit none class(psb_d_base_vect_type), intent(in) :: x logical :: res @@ -686,16 +692,16 @@ contains ! - ! Size info. + ! Size info. ! ! !> Function base_get_nrows !! \memberof psb_d_base_vect_type !! \brief Number of entries - !! + !! ! function d_base_get_nrows(x) result(res) - implicit none + implicit none class(psb_d_base_vect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -708,13 +714,13 @@ contains !> Function base_get_sizeof !! \memberof psb_d_base_vect_type !! \brief Size in bytes - !! + !! ! function d_base_sizeof(x) result(res) - implicit none + implicit none class(psb_d_base_vect_type), intent(in) :: x integer(psb_epk_) :: res - + ! Force 8-byte integers. res = (1_psb_epk_ * psb_sizeof_dp) * x%get_nrows() @@ -724,14 +730,14 @@ contains !> Function base_get_fmt !! \memberof psb_d_base_vect_type !! \brief Format - !! + !! ! function d_base_get_fmt() result(res) - implicit none + implicit none character(len=5) :: res res = 'BASE' end function d_base_get_fmt - + ! ! @@ -740,7 +746,7 @@ contains !! \memberof psb_d_base_vect_type !! \brief Extract a copy of the contents !! - ! + ! function d_base_get_vect(x,n) result(res) class(psb_d_base_vect_type), intent(inout) :: x real(psb_dpk_), allocatable :: res(:) @@ -748,21 +754,21 @@ contains integer(psb_ipk_), optional :: n ! Local variables integer(psb_ipk_) :: isz - - if (.not.allocated(x%v)) return + + if (.not.allocated(x%v)) return if (.not.x%is_host()) call x%sync() isz = x%get_nrows() if (present(n)) isz = max(0,min(isz,n)) - allocate(res(isz),stat=info) - if (info /= 0) then + allocate(res(isz),stat=info) + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_get_vect') return end if res(1:isz) = x%v(1:isz) end function d_base_get_vect - + ! - ! Reset all values + ! Reset all values ! ! !> Function base_set_scal @@ -771,18 +777,18 @@ contains !! \param val The value to set !! subroutine d_base_set_scal(x,val,first,last) - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x real(psb_dpk_), intent(in) :: val integer(psb_ipk_), optional :: first, last - + integer(psb_ipk_) :: info, first_, last_ first_=1 last_=size(x%v) if (present(first)) first_ = max(1,first) if (present(last)) last_ = min(last,last_) - + if (x%is_dev()) call x%sync() x%v(first_:last_) = val call x%set_host() @@ -794,14 +800,14 @@ contains !> Function base_set_vect !! \memberof psb_d_base_vect_type !! \brief Set all entries - !! \param val(:) The vector to be copied in + !! \param val(:) The vector to be copied in !! subroutine d_base_set_vect(x,val,first,last) - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x real(psb_dpk_), intent(in) :: val(:) integer(psb_ipk_), optional :: first, last - + integer(psb_ipk_) :: info, first_, last_, nr first_ = 1 @@ -809,7 +815,7 @@ contains last_ = min(psb_size(x%v),first_+size(val)-1) if (present(last)) last_ = min(last,last_) - if (allocated(x%v)) then + if (allocated(x%v)) then if (x%is_dev()) call x%sync() x%v(first_:last_) = val(1:last_-first_+1) else @@ -829,7 +835,7 @@ contains !! \brief Set all entries to their respective absolute values. !! subroutine d_base_absval1(x) - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x if (allocated(x%v)) then @@ -841,21 +847,21 @@ contains end subroutine d_base_absval1 subroutine d_base_absval2(x,y) - implicit none - class(psb_d_base_vect_type), intent(inout) :: x + implicit none + class(psb_d_base_vect_type), intent(inout) :: x class(psb_d_base_vect_type), intent(inout) :: y integer(psb_ipk_) :: info if (.not.x%is_host()) call x%sync() - if (allocated(x%v)) then + if (allocated(x%v)) then call y%axpby(ione*min(x%get_nrows(),y%get_nrows()),done,x,dzero,info) call y%absval() end if - + end subroutine d_base_absval2 ! - ! Dot products - ! + ! Dot products + ! ! !> Function base_dot_v !! \memberof psb_d_base_vect_type @@ -864,12 +870,12 @@ contains !! \param y The other (base_vect) to be multiplied by !! function d_base_dot_v(n,x,y) result(res) - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x, y integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res real(psb_dpk_), external :: ddot - + res = dzero ! ! Note: this is the base implementation. @@ -898,19 +904,19 @@ contains !! \param y(:) The array to be multiplied by !! function d_base_dot_a(n,x,y) result(res) - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x real(psb_dpk_), intent(in) :: y(:) integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res real(psb_dpk_), external :: ddot - + res = ddot(n,y,1,x%v,1) end function d_base_dot_a - + ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! ! @@ -925,13 +931,13 @@ contains !! subroutine d_base_axpby_v(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m class(psb_d_base_vect_type), intent(inout) :: x class(psb_d_base_vect_type), intent(inout) :: y real(psb_dpk_), intent (in) :: alpha, beta integer(psb_ipk_), intent(out) :: info - + if (x%is_dev()) call x%sync() call y%axpby(m,alpha,x%v,beta,info) @@ -939,7 +945,7 @@ contains end subroutine d_base_axpby_v ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! !> Function base_axpby_a @@ -953,20 +959,20 @@ contains !! subroutine d_base_axpby_a(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m real(psb_dpk_), intent(in) :: x(:) class(psb_d_base_vect_type), intent(inout) :: y real(psb_dpk_), intent (in) :: alpha, beta integer(psb_ipk_), intent(out) :: info - + if (y%is_dev()) call y%sync() call psb_geaxpby(m,alpha,x,beta,y%v,info) call y%set_host() - + end subroutine d_base_axpby_a - + ! ! Multiple variants of two operations: ! Simple multiplication Y(:) = X(:)*Y(:) @@ -984,10 +990,10 @@ contains !! subroutine d_base_mlt_v(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x class(psb_d_base_vect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -1005,7 +1011,7 @@ contains !! subroutine d_base_mlt_a(x, y, info) use psi_serial_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: x(:) class(psb_d_base_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -1014,7 +1020,7 @@ contains info = 0 if (y%is_dev()) call y%sync() n = min(size(y%v), size(x)) - do i=1, n + do i=1, n y%v(i) = y%v(i)*x(i) end do call y%set_host() @@ -1035,7 +1041,7 @@ contains !! subroutine d_base_mlt_a_2(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: alpha,beta real(psb_dpk_), intent(in) :: y(:) real(psb_dpk_), intent(in) :: x(:) @@ -1043,58 +1049,58 @@ contains integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n - info = 0 + info = 0 if (z%is_dev()) call z%sync() n = min(size(z%v), size(x), size(y)) - if (alpha == dzero) then - if (beta == done) then - return + if (alpha == dzero) then + if (beta == done) then + return else do i=1, n z%v(i) = beta*z%v(i) end do end if else - if (alpha == done) then - if (beta == dzero) then - do i=1, n + if (alpha == done) then + if (beta == dzero) then + do i=1, n z%v(i) = y(i)*x(i) end do - else if (beta == done) then - do i=1, n + else if (beta == done) then + do i=1, n z%v(i) = z%v(i) + y(i)*x(i) end do - else - do i=1, n + else + do i=1, n z%v(i) = beta*z%v(i) + y(i)*x(i) end do end if - else if (alpha == -done) then - if (beta == dzero) then - do i=1, n + else if (alpha == -done) then + if (beta == dzero) then + do i=1, n z%v(i) = -y(i)*x(i) end do - else if (beta == done) then - do i=1, n + else if (beta == done) then + do i=1, n z%v(i) = z%v(i) - y(i)*x(i) end do - else - do i=1, n + else + do i=1, n z%v(i) = beta*z%v(i) - y(i)*x(i) end do end if else - if (beta == dzero) then - do i=1, n + if (beta == dzero) then + do i=1, n z%v(i) = alpha*y(i)*x(i) end do - else if (beta == done) then - do i=1, n + else if (beta == done) then + do i=1, n z%v(i) = z%v(i) + alpha*y(i)*x(i) end do - else - do i=1, n + else + do i=1, n z%v(i) = beta*z%v(i) + alpha*y(i)*x(i) end do end if @@ -1118,12 +1124,12 @@ contains subroutine d_base_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) use psi_serial_mod use psb_string_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: alpha,beta class(psb_d_base_vect_type), intent(inout) :: x class(psb_d_base_vect_type), intent(inout) :: y class(psb_d_base_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info character(len=1), intent(in), optional :: conjgx, conjgy integer(psb_ipk_) :: i, n logical :: conjgx_, conjgy_ @@ -1133,7 +1139,7 @@ contains if (x%is_dev()) call x%sync() if (.not.psb_d_is_complex_) then call z%mlt(alpha,x%v,y%v,beta,info) - else + else conjgx_=.false. if (present(conjgx)) conjgx_ = (psb_toupper(conjgx)=='C') conjgy_=.false. @@ -1148,12 +1154,12 @@ contains subroutine d_base_mlt_av(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: alpha,beta real(psb_dpk_), intent(in) :: x(:) class(psb_d_base_vect_type), intent(inout) :: y class(psb_d_base_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -1164,12 +1170,12 @@ contains subroutine d_base_mlt_va(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: alpha,beta real(psb_dpk_), intent(in) :: y(:) class(psb_d_base_vect_type), intent(inout) :: x class(psb_d_base_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -1177,10 +1183,57 @@ contains call z%mlt(alpha,y,x,beta,info) end subroutine d_base_mlt_va + ! + !> Function base_div_v + !! \memberof psb_d_base_vect_type + !! \brief Vector entry-by-entry divide by a vector x=x/y + !! \param y The array to be divided by + !! \param info return code + !! + subroutine d_base_div_v(x, y, info) + use psi_serial_mod + implicit none + class(psb_d_base_vect_type), intent(inout) :: x + class(psb_d_base_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (x%is_dev()) call x%sync() + call x%div(x%v,y%v,info) + + + end subroutine d_base_div_v + ! + !> Function base_div_a2 + !! \memberof psb_d_base_vect_type + !! \brief Entry-by-entry divide between normal array x=x/y + !! \param x(:) The array to be multiplied by + !! \param info return code + !! + subroutine d_base_div_a2(x, y, z, info) + use psi_serial_mod + implicit none + class(psb_d_base_vect_type), intent(inout) :: z + real(psb_dpk_), intent(in) :: x(:) + real(psb_dpk_), intent(in) :: y(:) + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (z%is_dev()) call z%sync() + + n = min(size(y), size(x)) + do i=1, n + z%v(i) = x(i)/y(i) + end do + + end subroutine d_base_div_a2 + ! - ! Simple scaling + ! Simple scaling ! !> Function base_scal !! \memberof psb_d_base_vect_type @@ -1189,17 +1242,17 @@ contains !! subroutine d_base_scal(alpha, x) use psi_serial_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x real(psb_dpk_), intent (in) :: alpha - - if (allocated(x%v)) then + + if (allocated(x%v)) then x%v = alpha*x%v call x%set_host() end if end subroutine d_base_scal - + ! ! Norms 1, 2 and infinity ! @@ -1208,28 +1261,28 @@ contains !! \brief 2-norm |x(1:n)|_2 !! \param n how many entries to consider function d_base_nrm2(n,x) result(res) - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res real(psb_dpk_), external :: dnrm2 - + if (x%is_dev()) call x%sync() res = dnrm2(n,x%v,1) end function d_base_nrm2 - + ! !> Function base_amax !! \memberof psb_d_base_vect_type !! \brief infinity-norm |x(1:n)|_\infty !! \param n how many entries to consider function d_base_amax(n,x) result(res) - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res - + if (x%is_dev()) call x%sync() res = maxval(abs(x%v(1:n))) @@ -1241,17 +1294,17 @@ contains !! \brief 1-norm |x(1:n)|_1 !! \param n how many entries to consider function d_base_asum(n,x) result(res) - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res - + if (x%is_dev()) call x%sync() res = sum(abs(x%v(1:n))) end function d_base_asum - - + + ! ! Gather: Y = beta * Y + alpha * X(IDX(:)) ! @@ -1266,18 +1319,18 @@ contains !! \param beta subroutine d_base_gthab(n,idx,alpha,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_dpk_) :: alpha, beta, y(:) class(psb_d_base_vect_type) :: x - + if (x%is_dev()) call x%sync() call psi_gth(n,idx,alpha,x%v,beta,y) end subroutine d_base_gthab ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_gthzv !! \memberof psb_d_base_vect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1286,28 +1339,28 @@ contains !! \param idx(:) indices subroutine d_base_gthzv_x(i,n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx real(psb_dpk_) :: y(:) class(psb_d_base_vect_type) :: x - + if (idx%is_dev()) call idx%sync() call x%gth(n,idx%v(i:),y) end subroutine d_base_gthzv_x ! - ! New comm internals impl. + ! New comm internals impl. ! subroutine d_base_gthzbuf(i,n,idx,x) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx class(psb_d_base_vect_type) :: x - - if (.not.allocated(x%combuf)) then + + if (.not.allocated(x%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf') return end if @@ -1320,22 +1373,22 @@ contains !> Function base_device_wait: !! \memberof psb_d_base_vect_type !! \brief device_wait: base version is a no-op. - !! + !! ! subroutine d_base_device_wait() - implicit none - + implicit none + end subroutine d_base_device_wait function d_base_use_buffer() result(res) logical :: res - + res = .true. end function d_base_use_buffer subroutine d_base_new_buffer(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -1345,7 +1398,7 @@ contains subroutine d_base_new_comid(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -1356,7 +1409,7 @@ contains ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_gthzv !! \memberof psb_d_base_vect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1365,20 +1418,20 @@ contains !! \param idx(:) indices subroutine d_base_gthzv(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_dpk_) :: y(:) class(psb_d_base_vect_type) :: x - + if (x%is_dev()) call x%sync() call psi_gth(n,idx,x%v,y) end subroutine d_base_gthzv ! - ! Scatter: + ! Scatter: ! Y(IDX(:)) = beta*Y(IDX(:)) + X(:) - ! + ! ! !> Function base_sctb !! \memberof psb_d_base_vect_type @@ -1387,14 +1440,14 @@ contains !! \param n how many entries to consider !! \param idx(:) indices !! \param beta - !! \param x(:) + !! \param x(:) subroutine d_base_sctb(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_dpk_) :: beta, x(:) class(psb_d_base_vect_type) :: y - + if (y%is_dev()) call y%sync() call psi_sct(n,idx,x,beta,y%v) call y%set_host() @@ -1403,12 +1456,12 @@ contains subroutine d_base_sctb_x(i,n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx real(psb_dpk_) :: beta, x(:) class(psb_d_base_vect_type) :: y - + if (idx%is_dev()) call idx%sync() call y%sct(n,idx%v(i:),x,beta) call y%set_host() @@ -1417,14 +1470,14 @@ contains subroutine d_base_sctb_buf(i,n,idx,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx real(psb_dpk_) :: beta class(psb_d_base_vect_type) :: y - - - if (.not.allocated(y%combuf)) then + + + if (.not.allocated(y%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf') return end if @@ -1449,22 +1502,22 @@ module psb_d_base_multivect_mod use psb_d_base_vect_mod !> \namespace psb_base_mod \class psb_d_base_vect_type - !! The psb_d_base_vect_type + !! The psb_d_base_vect_type !! defines a middle level integer(psb_ipk_) encapsulated dense vector. - !! The encapsulation is needed, in place of a simple array, to allow + !! The encapsulation is needed, in place of a simple array, to allow !! for complicated situations, such as GPU programming, where the memory !! area we are interested in is not easily accessible from the host/Fortran !! side. It is also meant to be encapsulated in an outer type, to allow !! runtime switching as per the STATE design pattern, similar to the !! sparse matrix types. !! - private + private public :: psb_d_base_multivect, psb_d_base_multivect_type type psb_d_base_multivect_type - !> Values. + !> Values. real(psb_dpk_), allocatable :: v(:,:) - real(psb_dpk_), allocatable :: combuf(:) + real(psb_dpk_), allocatable :: combuf(:) integer(psb_mpk_), allocatable :: comid(:,:) contains ! @@ -1478,7 +1531,7 @@ module psb_d_base_multivect_mod ! ! Insert/set. Assembly and free. ! Assembly does almost nothing here, but is important - ! in derived classes. + ! in derived classes. ! procedure, pass(x) :: ins => d_base_mlv_ins procedure, pass(x) :: zero => d_base_mlv_zero @@ -1489,7 +1542,7 @@ module psb_d_base_multivect_mod ! Any derived class having extra storage upon sync ! will guarantee that both fortran/host side and ! external side contain the same data. The base - ! version is only a placeholder. + ! version is only a placeholder. ! procedure, pass(x) :: sync => d_base_mlv_sync procedure, pass(x) :: is_host => d_base_mlv_is_host @@ -1562,7 +1615,7 @@ module psb_d_base_multivect_mod ! ! Gather/scatter. These are needed for MPI interfacing. - ! May have to be reworked. + ! May have to be reworked. ! procedure, pass(x) :: gthab => d_base_mlv_gthab procedure, pass(x) :: gthzv => d_base_mlv_gthzv @@ -1584,7 +1637,7 @@ module psb_d_base_multivect_mod contains ! - ! Constructors. + ! Constructors. ! !> Function constructor: @@ -1603,7 +1656,7 @@ contains !> Function constructor: !! \brief Constructor from size - !! \param n Size of vector to be built. + !! \param n Size of vector to be built. !! function size_const(m,n) result(this) integer(psb_ipk_), intent(in) :: m,n @@ -1630,7 +1683,7 @@ contains integer(psb_ipk_) :: info call psb_realloc(size(this,1),size(this,2),x%v,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_mlv_vect_bld') return end if @@ -1645,7 +1698,7 @@ contains !> Function bld_n: !! \memberof psb_d_base_multivect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine d_base_mlv_bld_n(x,m,n) use psb_realloc_mod @@ -1662,13 +1715,13 @@ contains !! \memberof psb_d_base_multivect_type !! \brief Build method with size (uninitialized data) and !! allocation return code. - !! \param n size to be allocated. + !! \param n size to be allocated. !! \param info return code !! subroutine d_base_mlv_all(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_d_base_multivect_type), intent(out) :: x integer(psb_ipk_), intent(out) :: info @@ -1686,7 +1739,7 @@ contains subroutine d_base_mlv_mold(x, y, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_d_base_multivect_type), intent(in) :: x class(psb_d_base_multivect_type), intent(out), allocatable :: y integer(psb_ipk_), intent(out) :: info @@ -1700,21 +1753,21 @@ contains ! !> Function base_mlv_ins: !! \memberof psb_d_base_multivect_type - !! \brief Insert coefficients. + !! \brief Insert coefficients. !! !! !! Given a list of N pairs !! (IRL(i),VAL(i)) !! record a new coefficient in X such that !! X(IRL(1:N)) = VAL(1:N). - !! + !! !! - the update operation will perform either !! X(IRL(1:n)) = VAL(1:N) !! or !! X(IRL(1:n)) = X(IRL(1:n))+VAL(1:N) !! according to the value of DUPLICATE. - !! - !! + !! + !! !! \param n number of pairs in input !! \param irl(:) the input row indices !! \param val(:) the input coefficients @@ -1724,7 +1777,7 @@ contains ! subroutine d_base_mlv_ins(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -1734,21 +1787,21 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ - else if (n > min(size(irl),size(val))) then + else if (n > min(size(irl),size(val))) then info = psb_err_invalid_input_ - else + else isz = size(x%v,1) - select case(dupl) - case(psb_dupl_ovwrt_) + select case(dupl) + case(psb_dupl_ovwrt_) do i = 1, n !loop over all val's rows - ! row actual block row + ! row actual block row if ((1 <= irl(i)).and.(irl(i) <= isz)) then ! this row belongs to me ! copy i-th row of block val in x @@ -1756,7 +1809,7 @@ contains end if enddo - case(psb_dupl_add_) + case(psb_dupl_add_) do i = 1, n !loop over all val's rows @@ -1773,7 +1826,7 @@ contains ! !$ goto 9999 end select end if - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_mlv_vect_ins') return end if @@ -1788,7 +1841,7 @@ contains ! subroutine d_base_mlv_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x if (allocated(x%v)) x%v=dzero @@ -1804,7 +1857,7 @@ contains !> Function base_mlv_asb: !! \memberof psb_d_base_multivect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! @@ -1813,7 +1866,7 @@ contains subroutine d_base_mlv_asb(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_d_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1830,20 +1883,20 @@ contains !> Function base_mlv_free: !! \memberof psb_d_base_multivect_type !! \brief Free vector - !! + !! !! \param info return code !! ! subroutine d_base_mlv_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 if (allocated(x%v)) deallocate(x%v, stat=info) - if (info /= 0) call & + if (info /= 0) call & & psb_errpush(psb_err_alloc_dealloc_,'vect_free') end subroutine d_base_mlv_free @@ -1853,15 +1906,15 @@ contains ! ! The base version of SYNC & friends does nothing, it's just ! a placeholder. - ! + ! ! !> Function base_mlv_sync: !! \memberof psb_d_base_multivect_type !! \brief Sync: base version is a no-op. - !! + !! ! subroutine d_base_mlv_sync(x) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x end subroutine d_base_mlv_sync @@ -1870,10 +1923,10 @@ contains !> Function base_mlv_set_host: !! \memberof psb_d_base_multivect_type !! \brief Set_host: base version is a no-op. - !! + !! ! subroutine d_base_mlv_set_host(x) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x end subroutine d_base_mlv_set_host @@ -1882,10 +1935,10 @@ contains !> Function base_mlv_set_dev: !! \memberof psb_d_base_multivect_type !! \brief Set_dev: base version is a no-op. - !! + !! ! subroutine d_base_mlv_set_dev(x) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x end subroutine d_base_mlv_set_dev @@ -1894,10 +1947,10 @@ contains !> Function base_mlv_set_sync: !! \memberof psb_d_base_multivect_type !! \brief Set_sync: base version is a no-op. - !! + !! ! subroutine d_base_mlv_set_sync(x) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x end subroutine d_base_mlv_set_sync @@ -1906,10 +1959,10 @@ contains !> Function base_mlv_is_dev: !! \memberof psb_d_base_multivect_type !! \brief Is vector on external device . - !! + !! ! function d_base_mlv_is_dev(x) result(res) - implicit none + implicit none class(psb_d_base_multivect_type), intent(in) :: x logical :: res @@ -1920,10 +1973,10 @@ contains !> Function base_mlv_is_host !! \memberof psb_d_base_multivect_type !! \brief Is vector on standard memory . - !! + !! ! function d_base_mlv_is_host(x) result(res) - implicit none + implicit none class(psb_d_base_multivect_type), intent(in) :: x logical :: res @@ -1934,10 +1987,10 @@ contains !> Function base_mlv_is_sync !! \memberof psb_d_base_multivect_type !! \brief Is vector on sync . - !! + !! ! function d_base_mlv_is_sync(x) result(res) - implicit none + implicit none class(psb_d_base_multivect_type), intent(in) :: x logical :: res @@ -1946,16 +1999,16 @@ contains ! - ! Size info. + ! Size info. ! ! !> Function base_mlv_get_nrows !! \memberof psb_d_base_multivect_type !! \brief Number of entries - !! + !! ! function d_base_mlv_get_nrows(x) result(res) - implicit none + implicit none class(psb_d_base_multivect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -1965,7 +2018,7 @@ contains end function d_base_mlv_get_nrows function d_base_mlv_get_ncols(x) result(res) - implicit none + implicit none class(psb_d_base_multivect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -1978,10 +2031,10 @@ contains !> Function base_mlv_get_sizeof !! \memberof psb_d_base_multivect_type !! \brief Size in bytesa - !! + !! ! function d_base_mlv_sizeof(x) result(res) - implicit none + implicit none class(psb_d_base_multivect_type), intent(in) :: x integer(psb_epk_) :: res @@ -1994,10 +2047,10 @@ contains !> Function base_mlv_get_fmt !! \memberof psb_d_base_multivect_type !! \brief Format - !! + !! ! function d_base_mlv_get_fmt() result(res) - implicit none + implicit none character(len=5) :: res res = 'BASE' end function d_base_mlv_get_fmt @@ -2010,18 +2063,18 @@ contains !! \memberof psb_d_base_multivect_type !! \brief Extract a copy of the contents !! - ! + ! function d_base_mlv_get_vect(x) result(res) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x real(psb_dpk_), allocatable :: res(:,:) integer(psb_ipk_) :: info,m,n m = x%get_nrows() n = x%get_ncols() - if (.not.allocated(x%v)) return + if (.not.allocated(x%v)) return call x%sync() - allocate(res(m,n),stat=info) - if (info /= 0) then + allocate(res(m,n),stat=info) + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_mlv_get_vect') return end if @@ -2029,7 +2082,7 @@ contains end function d_base_mlv_get_vect ! - ! Reset all values + ! Reset all values ! ! !> Function base_mlv_set_scal @@ -2038,7 +2091,7 @@ contains !! \param val The value to set !! subroutine d_base_mlv_set_scal(x,val) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x real(psb_dpk_), intent(in) :: val @@ -2051,16 +2104,16 @@ contains !> Function base_mlv_set_vect !! \memberof psb_d_base_multivect_type !! \brief Set all entries - !! \param val(:) The vector to be copied in + !! \param val(:) The vector to be copied in !! subroutine d_base_mlv_set_vect(x,val) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x real(psb_dpk_), intent(in) :: val(:,:) integer(psb_ipk_) :: nr, nc integer(psb_ipk_) :: info - if (allocated(x%v)) then + if (allocated(x%v)) then nr = min(size(x%v,1),size(val,1)) nc = min(size(x%v,2),size(val,2)) @@ -2072,8 +2125,8 @@ contains end subroutine d_base_mlv_set_vect ! - ! Dot products - ! + ! Dot products + ! ! !> Function base_mlv_dot_v !! \memberof psb_d_base_multivect_type @@ -2082,7 +2135,7 @@ contains !! \param y The other (base_mlv_vect) to be multiplied by !! function d_base_mlv_dot_v(n,x,y) result(res) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x, y integer(psb_ipk_), intent(in) :: n real(psb_dpk_), allocatable :: res(:) @@ -2094,7 +2147,7 @@ contains ! ! Note: this is the base implementation. ! When we get here, we are sure that X is of - ! TYPE psb_d_base_mlv_vect (or its class does not care). + ! TYPE psb_d_base_mlv_vect (or its class does not care). ! If Y is not, throw the burden on it, implicitly ! calling dot_a ! @@ -2123,7 +2176,7 @@ contains !! \param y(:) The array to be multiplied by !! function d_base_mlv_dot_a(n,x,y) result(res) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x real(psb_dpk_), intent(in) :: y(:,:) integer(psb_ipk_), intent(in) :: n @@ -2141,7 +2194,7 @@ contains end function d_base_mlv_dot_a ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! ! @@ -2156,7 +2209,7 @@ contains !! subroutine d_base_mlv_axpby_v(m,alpha, x, beta, y, info, n) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m class(psb_d_base_multivect_type), intent(inout) :: x class(psb_d_base_multivect_type), intent(inout) :: y @@ -2180,7 +2233,7 @@ contains end subroutine d_base_mlv_axpby_v ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! !> Function base_mlv_axpby_a @@ -2194,7 +2247,7 @@ contains !! subroutine d_base_mlv_axpby_a(m,alpha, x, beta, y, info,n) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m real(psb_dpk_), intent(in) :: x(:,:) class(psb_d_base_multivect_type), intent(inout) :: y @@ -2230,10 +2283,10 @@ contains !! subroutine d_base_mlv_mlt_mv(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x class(psb_d_base_multivect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info info = 0 if (x%is_dev()) call x%sync() @@ -2243,10 +2296,10 @@ contains subroutine d_base_mlv_mlt_mv_v(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_d_base_vect_type), intent(inout) :: x class(psb_d_base_multivect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info info = 0 if (x%is_dev()) call x%sync() @@ -2263,7 +2316,7 @@ contains !! subroutine d_base_mlv_mlt_ar1(x, y, info) use psi_serial_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: x(:) class(psb_d_base_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -2271,7 +2324,7 @@ contains info = 0 n = min(psb_size(y%v,1_psb_ipk_), size(x)) - do i=1, n + do i=1, n y%v(i,:) = y%v(i,:)*x(i) end do @@ -2286,7 +2339,7 @@ contains !! subroutine d_base_mlv_mlt_ar2(x, y, info) use psi_serial_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: x(:,:) class(psb_d_base_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -2313,7 +2366,7 @@ contains !! subroutine d_base_mlv_mlt_a_2(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: alpha,beta real(psb_dpk_), intent(in) :: y(:,:) real(psb_dpk_), intent(in) :: x(:,:) @@ -2321,38 +2374,38 @@ contains integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, nr, nc - info = 0 + info = 0 nr = min(psb_size(z%v,1_psb_ipk_), size(x,1), size(y,1)) - nc = min(psb_size(z%v,2_psb_ipk_), size(x,2), size(y,2)) - if (alpha == dzero) then - if (beta == done) then - return + nc = min(psb_size(z%v,2_psb_ipk_), size(x,2), size(y,2)) + if (alpha == dzero) then + if (beta == done) then + return else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) end if else - if (alpha == done) then - if (beta == dzero) then + if (alpha == done) then + if (beta == dzero) then z%v(1:nr,1:nc) = y(1:nr,1:nc)*x(1:nr,1:nc) - else if (beta == done) then + else if (beta == done) then z%v(1:nr,1:nc) = z%v(1:nr,1:nc) + y(1:nr,1:nc)*x(1:nr,1:nc) - else + else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) + y(1:nr,1:nc)*x(1:nr,1:nc) end if - else if (alpha == -done) then - if (beta == dzero) then + else if (alpha == -done) then + if (beta == dzero) then z%v(1:nr,1:nc) = -y(1:nr,1:nc)*x(1:nr,1:nc) - else if (beta == done) then + else if (beta == done) then z%v(1:nr,1:nc) = z%v(1:nr,1:nc) - y(1:nr,1:nc)*x(1:nr,1:nc) - else + else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) - y(1:nr,1:nc)*x(1:nr,1:nc) end if else - if (beta == dzero) then + if (beta == dzero) then z%v(1:nr,1:nc) = alpha*y(1:nr,1:nc)*x(1:nr,1:nc) - else if (beta == done) then + else if (beta == done) then z%v(1:nr,1:nc) = z%v(1:nr,1:nc) + alpha*y(1:nr,1:nc)*x(1:nr,1:nc) - else + else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) + alpha*y(1:nr,1:nc)*x(1:nr,1:nc) end if end if @@ -2373,12 +2426,12 @@ contains subroutine d_base_mlv_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) use psi_serial_mod use psb_string_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: alpha,beta class(psb_d_base_multivect_type), intent(inout) :: x class(psb_d_base_multivect_type), intent(inout) :: y class(psb_d_base_multivect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info character(len=1), intent(in), optional :: conjgx, conjgy integer(psb_ipk_) :: i, n logical :: conjgx_, conjgy_ @@ -2389,7 +2442,7 @@ contains if (z%is_dev()) call z%sync() if (.not.psb_d_is_complex_) then call z%mlt(alpha,x%v,y%v,beta,info) - else + else conjgx_=.false. if (present(conjgx)) conjgx_ = (psb_toupper(conjgx)=='C') conjgy_=.false. @@ -2404,39 +2457,39 @@ contains !!$ !!$ subroutine d_base_mlv_mlt_av(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_dpk_), intent(in) :: alpha,beta !!$ real(psb_dpk_), intent(in) :: x(:) !!$ class(psb_d_base_multivect_type), intent(inout) :: y !!$ class(psb_d_base_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 -!!$ +!!$ !!$ call z%mlt(alpha,x,y%v,beta,info) !!$ !!$ end subroutine d_base_mlv_mlt_av !!$ !!$ subroutine d_base_mlv_mlt_va(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_dpk_), intent(in) :: alpha,beta !!$ real(psb_dpk_), intent(in) :: y(:) !!$ class(psb_d_base_multivect_type), intent(inout) :: x !!$ class(psb_d_base_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 -!!$ +!!$ !!$ call z%mlt(alpha,y,x,beta,info) !!$ !!$ end subroutine d_base_mlv_mlt_va !!$ !!$ ! - ! Simple scaling + ! Simple scaling ! !> Function base_mlv_scal !! \memberof psb_d_base_multivect_type @@ -2445,7 +2498,7 @@ contains !! subroutine d_base_mlv_scal(alpha, x) use psi_serial_mod - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x real(psb_dpk_), intent (in) :: alpha @@ -2462,7 +2515,7 @@ contains !! \brief 2-norm |x(1:n)|_2 !! \param n how many entries to consider function d_base_mlv_nrm2(n,x) result(res) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_), allocatable :: res(:) @@ -2484,7 +2537,7 @@ contains !! \brief infinity-norm |x(1:n)|_\infty !! \param n how many entries to consider function d_base_mlv_amax(n,x) result(res) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_), allocatable :: res(:) @@ -2505,7 +2558,7 @@ contains !! \brief 1-norm |x(1:n)|_1 !! \param n how many entries to consider function d_base_mlv_asum(n,x) result(res) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_), allocatable :: res(:) @@ -2528,7 +2581,7 @@ contains !! \brief Set all entries to their respective absolute values. !! subroutine d_base_mlv_absval1(x) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x if (allocated(x%v)) then @@ -2540,13 +2593,13 @@ contains end subroutine d_base_mlv_absval1 subroutine d_base_mlv_absval2(x,y) - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x class(psb_d_base_multivect_type), intent(inout) :: y integer(psb_ipk_) :: info - + if (x%is_dev()) call x%sync() - if (allocated(x%v)) then + if (allocated(x%v)) then call y%axpby(min(x%get_nrows(),y%get_nrows()),done,x,dzero,info) call y%absval() end if @@ -2555,15 +2608,15 @@ contains function d_base_mlv_use_buffer() result(res) - implicit none + implicit none logical :: res - + res = .true. end function d_base_mlv_use_buffer subroutine d_base_mlv_new_buffer(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -2575,7 +2628,7 @@ contains subroutine d_base_mlv_new_comid(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -2586,12 +2639,12 @@ contains subroutine d_base_mlv_maybe_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (psb_get_maybe_free_buffer())& & call x%free_buffer(info) @@ -2599,7 +2652,7 @@ contains subroutine d_base_mlv_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -2609,7 +2662,7 @@ contains subroutine d_base_mlv_free_comid(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_d_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -2632,7 +2685,7 @@ contains !! \param beta subroutine d_base_mlv_gthab(n,idx,alpha,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_dpk_) :: alpha, beta, y(:) class(psb_d_base_multivect_type) :: x @@ -2648,7 +2701,7 @@ contains end subroutine d_base_mlv_gthab ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_d_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -2657,7 +2710,7 @@ contains !! \param idx(:) indices subroutine d_base_mlv_gthzv_x(i,n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx real(psb_dpk_) :: y(:) @@ -2670,7 +2723,7 @@ contains ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_d_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -2679,7 +2732,7 @@ contains !! \param idx(:) indices subroutine d_base_mlv_gthzv(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_dpk_) :: y(:) class(psb_d_base_multivect_type) :: x @@ -2696,7 +2749,7 @@ contains end subroutine d_base_mlv_gthzv ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_d_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -2705,7 +2758,7 @@ contains !! \param idx(:) indices subroutine d_base_mlv_gthzm(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_dpk_) :: y(:,:) class(psb_d_base_multivect_type) :: x @@ -2722,17 +2775,17 @@ contains end subroutine d_base_mlv_gthzm ! - ! New comm internals impl. + ! New comm internals impl. ! subroutine d_base_mlv_gthzbuf(i,ixb,n,idx,x) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, ixb, n class(psb_i_base_vect_type) :: idx class(psb_d_base_multivect_type) :: x integer(psb_ipk_) :: nc - - if (.not.allocated(x%combuf)) then + + if (.not.allocated(x%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf') return end if @@ -2744,9 +2797,9 @@ contains end subroutine d_base_mlv_gthzbuf ! - ! Scatter: + ! Scatter: ! Y(IDX(:),:) = beta*Y(IDX(:),:) + X(:) - ! + ! ! !> Function base_mlv_sctb !! \memberof psb_d_base_multivect_type @@ -2755,10 +2808,10 @@ contains !! \param n how many entries to consider !! \param idx(:) indices !! \param beta - !! \param x(:) + !! \param x(:) subroutine d_base_mlv_sctb(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_dpk_) :: beta, x(:) class(psb_d_base_multivect_type) :: y @@ -2773,7 +2826,7 @@ contains subroutine d_base_mlv_sctbr2(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_dpk_) :: beta, x(:,:) class(psb_d_base_multivect_type) :: y @@ -2788,7 +2841,7 @@ contains subroutine d_base_mlv_sctb_x(i,n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx real( psb_dpk_) :: beta, x(:) @@ -2800,14 +2853,14 @@ contains subroutine d_base_mlv_sctb_buf(i,iyb,n,idx,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, iyb, n class(psb_i_base_vect_type) :: idx real(psb_dpk_) :: beta class(psb_d_base_multivect_type) :: y integer(psb_ipk_) :: nc - - if (.not.allocated(y%combuf)) then + + if (.not.allocated(y%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf') return end if @@ -2816,19 +2869,18 @@ contains nc = y%get_ncols() call y%sct(n,idx%v(i:),y%combuf(iyb:),beta) call y%set_host() - + end subroutine d_base_mlv_sctb_buf ! !> Function base_device_wait: !! \memberof psb_d_base_vect_type !! \brief device_wait: base version is a no-op. - !! + !! ! subroutine d_base_mlv_device_wait() - implicit none - + implicit none + end subroutine d_base_mlv_device_wait end module psb_d_base_multivect_mod - diff --git a/base/modules/serial/psb_d_vect_mod.F90 b/base/modules/serial/psb_d_vect_mod.F90 index f6244e3ef..469cb56df 100644 --- a/base/modules/serial/psb_d_vect_mod.F90 +++ b/base/modules/serial/psb_d_vect_mod.F90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,15 +27,15 @@ ! 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. -! -! +! +! ! ! package: psb_d_vect_mod ! ! This module contains the definition of the psb_d_vect type which ! is the outer container for dense vectors. ! Therefore all methods simply invoke the corresponding methods of the -! inner component. +! inner component. ! module psb_d_vect_mod @@ -43,7 +43,7 @@ module psb_d_vect_mod use psb_i_vect_mod type psb_d_vect_type - class(psb_d_base_vect_type), allocatable :: v + class(psb_d_base_vect_type), allocatable :: v contains procedure, pass(x) :: get_nrows => d_vect_get_nrows procedure, pass(x) :: sizeof => d_vect_sizeof @@ -94,13 +94,16 @@ module psb_d_vect_mod procedure, pass(z) :: mlt_av => d_vect_mlt_av generic, public :: mlt => mlt_v, mlt_a, mlt_a_2,& & mlt_v_2, mlt_av, mlt_va + procedure, pass(x) :: div_v => d_vect_div_v + procedure, pass(z) :: div_a2 => d_vect_div_a2 + generic, public :: div => div_v, div_a2 procedure, pass(x) :: scal => d_vect_scal procedure, pass(x) :: absval1 => d_vect_absval1 procedure, pass(x) :: absval2 => d_vect_absval2 generic, public :: absval => absval1, absval2 procedure, pass(x) :: nrm2 => d_vect_nrm2 procedure, pass(x) :: amax => d_vect_amax - procedure, pass(x) :: asum => d_vect_asum + procedure, pass(x) :: asum => d_vect_asum end type psb_d_vect_type public :: psb_d_vect @@ -122,7 +125,7 @@ module psb_d_vect_mod private :: d_vect_dot_v, d_vect_dot_a, d_vect_axpby_v, d_vect_axpby_a, & & d_vect_mlt_v, d_vect_mlt_a, d_vect_mlt_a_2, d_vect_mlt_v_2, & & d_vect_mlt_va, d_vect_mlt_av, d_vect_scal, d_vect_absval1, & - & d_vect_absval2, d_vect_nrm2, d_vect_amax, d_vect_asum + & d_vect_absval2, d_vect_nrm2, d_vect_amax, d_vect_asum @@ -141,11 +144,11 @@ module psb_d_vect_mod contains - subroutine psb_d_set_vect_default(v) - implicit none + subroutine psb_d_set_vect_default(v) + implicit none class(psb_d_base_vect_type), intent(in) :: v - if (allocated(psb_d_base_vect_default)) then + if (allocated(psb_d_base_vect_default)) then deallocate(psb_d_base_vect_default) end if allocate(psb_d_base_vect_default, mold=v) @@ -153,7 +156,7 @@ contains end subroutine psb_d_set_vect_default function psb_d_get_vect_default(v) result(res) - implicit none + implicit none class(psb_d_vect_type), intent(in) :: v class(psb_d_base_vect_type), pointer :: res @@ -163,10 +166,10 @@ contains function psb_d_get_base_vect_default() result(res) - implicit none + implicit none class(psb_d_base_vect_type), pointer :: res - if (.not.allocated(psb_d_base_vect_default)) then + if (.not.allocated(psb_d_base_vect_default)) then allocate(psb_d_base_vect_type :: psb_d_base_vect_default) end if @@ -176,14 +179,14 @@ contains subroutine d_vect_clone(x,y,info) - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x class(psb_d_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info info = psb_success_ call y%free(info) - if ((info==0).and.allocated(x%v)) then + if ((info==0).and.allocated(x%v)) then call y%bld(x%get_vect(),mold=x%v) end if end subroutine d_vect_clone @@ -198,7 +201,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_d_get_base_vect_default()) @@ -220,7 +223,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_d_get_base_vect_default()) @@ -241,7 +244,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_d_get_base_vect_default()) @@ -304,7 +307,7 @@ contains end function size_const function d_vect_get_nrows(x) result(res) - implicit none + implicit none class(psb_d_vect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -312,7 +315,7 @@ contains end function d_vect_get_nrows function d_vect_sizeof(x) result(res) - implicit none + implicit none class(psb_d_vect_type), intent(in) :: x integer(psb_epk_) :: res res = 0 @@ -320,7 +323,7 @@ contains end function d_vect_sizeof function d_vect_get_fmt(x) result(res) - implicit none + implicit none class(psb_d_vect_type), intent(in) :: x character(len=5) :: res res = 'NULL' @@ -329,7 +332,7 @@ contains subroutine d_vect_all(n, x, info, mold) - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_d_vect_type), intent(inout) :: x class(psb_d_base_vect_type), intent(in), optional :: mold @@ -338,12 +341,12 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(psb_d_base_vect_type :: x%v,stat=info) endif - if (info == 0) then + if (info == 0) then call x%v%all(n,info) else info = psb_err_alloc_dealloc_ @@ -353,12 +356,12 @@ contains subroutine d_vect_reall(n, x, info) - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_d_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (.not.allocated(x%v)) & & call x%all(n,info) if (info == 0) & @@ -368,7 +371,7 @@ contains subroutine d_vect_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x if (allocated(x%v)) call x%v%zero() @@ -378,7 +381,7 @@ contains subroutine d_vect_asb(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_d_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -424,12 +427,12 @@ contains subroutine d_vect_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%free(info) if (info == 0) deallocate(x%v,stat=info) end if @@ -438,7 +441,7 @@ contains subroutine d_vect_ins_a(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -448,7 +451,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ return end if @@ -459,7 +462,7 @@ contains subroutine d_vect_ins_v(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl class(psb_i_vect_type), intent(inout) :: irl @@ -469,7 +472,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then + if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then info = psb_err_invalid_vect_state_ return end if @@ -487,12 +490,12 @@ contains integer(psb_ipk_) :: info info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(tmp,stat=info,mold=mold) else allocate(tmp,stat=info,mold=psb_d_get_base_vect_default()) end if - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%sync() if (info == psb_success_) call tmp%bld(x%v%v) call x%v%free(info) @@ -503,7 +506,7 @@ contains subroutine d_vect_sync(x) - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -512,7 +515,7 @@ contains end subroutine d_vect_sync subroutine d_vect_set_sync(x) - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -521,7 +524,7 @@ contains end subroutine d_vect_set_sync subroutine d_vect_set_host(x) - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -530,7 +533,7 @@ contains end subroutine d_vect_set_host subroutine d_vect_set_dev(x) - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -539,7 +542,7 @@ contains end subroutine d_vect_set_dev function d_vect_is_sync(x) result(res) - implicit none + implicit none logical :: res class(psb_d_vect_type), intent(inout) :: x @@ -550,7 +553,7 @@ contains end function d_vect_is_sync function d_vect_is_host(x) result(res) - implicit none + implicit none logical :: res class(psb_d_vect_type), intent(inout) :: x @@ -561,11 +564,11 @@ contains end function d_vect_is_host function d_vect_is_dev(x) result(res) - implicit none + implicit none logical :: res class(psb_d_vect_type), intent(inout) :: x - res = .false. + res = .false. if (allocated(x%v)) & & res = x%v%is_dev() @@ -573,7 +576,7 @@ contains function d_vect_dot_v(n,x,y) result(res) - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x, y integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res @@ -585,7 +588,7 @@ contains end function d_vect_dot_v function d_vect_dot_a(n,x,y) result(res) - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x real(psb_dpk_), intent(in) :: y(:) integer(psb_ipk_), intent(in) :: n @@ -599,14 +602,14 @@ contains subroutine d_vect_axpby_v(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m class(psb_d_vect_type), intent(inout) :: x class(psb_d_vect_type), intent(inout) :: y real(psb_dpk_), intent (in) :: alpha, beta integer(psb_ipk_), intent(out) :: info - if (allocated(x%v).and.allocated(y%v)) then + if (allocated(x%v).and.allocated(y%v)) then call y%v%axpby(m,alpha,x%v,beta,info) else info = psb_err_invalid_vect_state_ @@ -616,7 +619,7 @@ contains subroutine d_vect_axpby_a(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m real(psb_dpk_), intent(in) :: x(:) class(psb_d_vect_type), intent(inout) :: y @@ -631,10 +634,10 @@ contains subroutine d_vect_mlt_v(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x class(psb_d_vect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -645,7 +648,7 @@ contains subroutine d_vect_mlt_a(x, y, info) use psi_serial_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: x(:) class(psb_d_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -661,7 +664,7 @@ contains subroutine d_vect_mlt_a_2(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: alpha,beta real(psb_dpk_), intent(in) :: y(:) real(psb_dpk_), intent(in) :: x(:) @@ -669,7 +672,7 @@ contains integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n - info = 0 + info = 0 if (allocated(z%v)) & & call z%v%mlt(alpha,x,y,beta,info) @@ -677,12 +680,12 @@ contains subroutine d_vect_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) use psi_serial_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: alpha,beta class(psb_d_vect_type), intent(inout) :: x class(psb_d_vect_type), intent(inout) :: y class(psb_d_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info character(len=1), intent(in), optional :: conjgx, conjgy integer(psb_ipk_) :: i, n @@ -696,12 +699,12 @@ contains subroutine d_vect_mlt_av(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: alpha,beta real(psb_dpk_), intent(in) :: x(:) class(psb_d_vect_type), intent(inout) :: y class(psb_d_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -712,12 +715,12 @@ contains subroutine d_vect_mlt_va(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_dpk_), intent(in) :: alpha,beta real(psb_dpk_), intent(in) :: y(:) class(psb_d_vect_type), intent(inout) :: x class(psb_d_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -727,9 +730,38 @@ contains end subroutine d_vect_mlt_va + subroutine d_vect_div_v(x, y, info) + use psi_serial_mod + implicit none + class(psb_d_vect_type), intent(inout) :: x + class(psb_d_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (allocated(x%v).and.allocated(y%v)) & + & call x%v%div(y%v,info) + + end subroutine d_vect_div_v + + subroutine d_vect_div_a2(x, y, z, info) + use psi_serial_mod + implicit none + real(psb_dpk_), intent(in) :: x(:) + real(psb_dpk_), intent(in) :: y(:) + class(psb_d_vect_type), intent(inout) :: z + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (allocated(z%v)) & + & call z%v%div(x,y,info) + + end subroutine d_vect_div_a2 + subroutine d_vect_scal(alpha, x) use psi_serial_mod - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x real(psb_dpk_), intent (in) :: alpha @@ -749,19 +781,19 @@ contains class(psb_d_vect_type), intent(inout) :: x class(psb_d_vect_type), intent(inout) :: y - if (allocated(x%v)) then + if (allocated(x%v)) then if (.not.allocated(y%v)) call y%bld(psb_size(x%v%v)) call x%v%absval(y%v) end if end subroutine d_vect_absval2 function d_vect_nrm2(n,x) result(res) - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res - if (allocated(x%v)) then + if (allocated(x%v)) then res = x%v%nrm2(n) else res = dzero @@ -770,12 +802,12 @@ contains end function d_vect_nrm2 function d_vect_amax(n,x) result(res) - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res - if (allocated(x%v)) then + if (allocated(x%v)) then res = x%v%amax(n) else res = dzero @@ -784,12 +816,12 @@ contains end function d_vect_amax function d_vect_asum(n,x) result(res) - implicit none + implicit none class(psb_d_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res - if (allocated(x%v)) then + if (allocated(x%v)) then res = x%v%asum(n) else res = dzero @@ -812,7 +844,7 @@ module psb_d_multivect_mod !private type psb_d_multivect_type - class(psb_d_base_multivect_type), allocatable :: v + class(psb_d_base_multivect_type), allocatable :: v contains procedure, pass(x) :: get_nrows => d_vect_get_nrows procedure, pass(x) :: get_ncols => d_vect_get_ncols @@ -886,11 +918,11 @@ module psb_d_multivect_mod contains - subroutine psb_d_set_multivect_default(v) - implicit none + subroutine psb_d_set_multivect_default(v) + implicit none class(psb_d_base_multivect_type), intent(in) :: v - if (allocated(psb_d_base_multivect_default)) then + if (allocated(psb_d_base_multivect_default)) then deallocate(psb_d_base_multivect_default) end if allocate(psb_d_base_multivect_default, mold=v) @@ -898,7 +930,7 @@ contains end subroutine psb_d_set_multivect_default function psb_d_get_multivect_default(v) result(res) - implicit none + implicit none class(psb_d_multivect_type), intent(in) :: v class(psb_d_base_multivect_type), pointer :: res @@ -908,10 +940,10 @@ contains function psb_d_get_base_multivect_default() result(res) - implicit none + implicit none class(psb_d_base_multivect_type), pointer :: res - if (.not.allocated(psb_d_base_multivect_default)) then + if (.not.allocated(psb_d_base_multivect_default)) then allocate(psb_d_base_multivect_type :: psb_d_base_multivect_default) end if @@ -921,14 +953,14 @@ contains subroutine d_vect_clone(x,y,info) - implicit none + implicit none class(psb_d_multivect_type), intent(inout) :: x class(psb_d_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info info = psb_success_ call y%free(info) - if ((info==0).and.allocated(x%v)) then + if ((info==0).and.allocated(x%v)) then call y%bld(x%get_vect(),mold=x%v) end if end subroutine d_vect_clone @@ -941,7 +973,7 @@ contains class(psb_d_base_multivect_type), pointer :: mld info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_d_get_base_multivect_default()) @@ -959,7 +991,7 @@ contains integer(psb_ipk_) :: info info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_d_get_base_multivect_default()) @@ -1019,7 +1051,7 @@ contains end function size_const function d_vect_get_nrows(x) result(res) - implicit none + implicit none class(psb_d_multivect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -1027,7 +1059,7 @@ contains end function d_vect_get_nrows function d_vect_get_ncols(x) result(res) - implicit none + implicit none class(psb_d_multivect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -1035,7 +1067,7 @@ contains end function d_vect_get_ncols function d_vect_sizeof(x) result(res) - implicit none + implicit none class(psb_d_multivect_type), intent(in) :: x integer(psb_epk_) :: res res = 0 @@ -1043,7 +1075,7 @@ contains end function d_vect_sizeof function d_vect_get_fmt(x) result(res) - implicit none + implicit none class(psb_d_multivect_type), intent(in) :: x character(len=5) :: res res = 'NULL' @@ -1052,18 +1084,18 @@ contains subroutine d_vect_all(m,n, x, info, mold) - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_d_multivect_type), intent(out) :: x class(psb_d_base_multivect_type), intent(in), optional :: mold integer(psb_ipk_), intent(out) :: info - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(psb_d_base_multivect_type :: x%v,stat=info) endif - if (info == 0) then + if (info == 0) then call x%v%all(m,n,info) else info = psb_err_alloc_dealloc_ @@ -1073,12 +1105,12 @@ contains subroutine d_vect_reall(m,n, x, info) - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_d_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (.not.allocated(x%v)) & & call x%all(m,n,info) if (info == 0) & @@ -1088,7 +1120,7 @@ contains subroutine d_vect_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_d_multivect_type), intent(inout) :: x if (allocated(x%v)) call x%v%zero() @@ -1098,7 +1130,7 @@ contains subroutine d_vect_asb(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_d_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1109,7 +1141,7 @@ contains end subroutine d_vect_asb subroutine d_vect_sync(x) - implicit none + implicit none class(psb_d_multivect_type), intent(inout) :: x if (allocated(x%v)) & @@ -1177,12 +1209,12 @@ contains subroutine d_vect_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_d_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%free(info) if (info == 0) deallocate(x%v,stat=info) end if @@ -1191,7 +1223,7 @@ contains subroutine d_vect_ins(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_d_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -1201,7 +1233,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ return end if @@ -1217,12 +1249,12 @@ contains class(psb_d_base_multivect_type), allocatable :: tmp integer(psb_ipk_) :: info - if (present(mold)) then + if (present(mold)) then allocate(tmp,stat=info,mold=mold) else allocate(tmp,stat=info, mold=psb_d_get_base_multivect_default()) - endif - if (allocated(x%v)) then + endif + if (allocated(x%v)) then call x%v%sync() if (info == psb_success_) call tmp%bld(x%v%v) call x%v%free(info) @@ -1232,7 +1264,7 @@ contains !!$ function d_vect_dot_v(n,x,y) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_d_multivect_type), intent(inout) :: x, y !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_dpk_) :: res @@ -1244,28 +1276,28 @@ contains !!$ end function d_vect_dot_v !!$ !!$ function d_vect_dot_a(n,x,y) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_d_multivect_type), intent(inout) :: x !!$ real(psb_dpk_), intent(in) :: y(:) !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_dpk_) :: res -!!$ +!!$ !!$ res = dzero !!$ if (allocated(x%v)) & !!$ & res = x%v%dot(n,y) -!!$ +!!$ !!$ end function d_vect_dot_a -!!$ +!!$ !!$ subroutine d_vect_axpby_v(m,alpha, x, beta, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ integer(psb_ipk_), intent(in) :: m !!$ class(psb_d_multivect_type), intent(inout) :: x !!$ class(psb_d_multivect_type), intent(inout) :: y !!$ real(psb_dpk_), intent (in) :: alpha, beta !!$ integer(psb_ipk_), intent(out) :: info -!!$ -!!$ if (allocated(x%v).and.allocated(y%v)) then +!!$ +!!$ if (allocated(x%v).and.allocated(y%v)) then !!$ call y%v%axpby(m,alpha,x%v,beta,info) !!$ else !!$ info = psb_err_invalid_vect_state_ @@ -1275,25 +1307,25 @@ contains !!$ !!$ subroutine d_vect_axpby_a(m,alpha, x, beta, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ integer(psb_ipk_), intent(in) :: m !!$ real(psb_dpk_), intent(in) :: x(:) !!$ class(psb_d_multivect_type), intent(inout) :: y !!$ real(psb_dpk_), intent (in) :: alpha, beta !!$ integer(psb_ipk_), intent(out) :: info -!!$ +!!$ !!$ if (allocated(y%v)) & !!$ & call y%v%axpby(m,alpha,x,beta,info) -!!$ +!!$ !!$ end subroutine d_vect_axpby_a !!$ -!!$ +!!$ !!$ subroutine d_vect_mlt_v(x, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ class(psb_d_multivect_type), intent(inout) :: x !!$ class(psb_d_multivect_type), intent(inout) :: y -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 @@ -1304,7 +1336,7 @@ contains !!$ !!$ subroutine d_vect_mlt_a(x, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_dpk_), intent(in) :: x(:) !!$ class(psb_d_multivect_type), intent(inout) :: y !!$ integer(psb_ipk_), intent(out) :: info @@ -1314,13 +1346,13 @@ contains !!$ info = 0 !!$ if (allocated(y%v)) & !!$ & call y%v%mlt(x,info) -!!$ +!!$ !!$ end subroutine d_vect_mlt_a !!$ !!$ !!$ subroutine d_vect_mlt_a_2(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_dpk_), intent(in) :: alpha,beta !!$ real(psb_dpk_), intent(in) :: y(:) !!$ real(psb_dpk_), intent(in) :: x(:) @@ -1328,20 +1360,20 @@ contains !!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ -!!$ info = 0 +!!$ info = 0 !!$ if (allocated(z%v)) & !!$ & call z%v%mlt(alpha,x,y,beta,info) -!!$ +!!$ !!$ end subroutine d_vect_mlt_a_2 !!$ !!$ subroutine d_vect_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_dpk_), intent(in) :: alpha,beta !!$ class(psb_d_multivect_type), intent(inout) :: x !!$ class(psb_d_multivect_type), intent(inout) :: y !!$ class(psb_d_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ character(len=1), intent(in), optional :: conjgx, conjgy !!$ !!$ integer(psb_ipk_) :: i, n @@ -1355,12 +1387,12 @@ contains !!$ !!$ subroutine d_vect_mlt_av(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_dpk_), intent(in) :: alpha,beta !!$ real(psb_dpk_), intent(in) :: x(:) !!$ class(psb_d_multivect_type), intent(inout) :: y !!$ class(psb_d_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 @@ -1371,16 +1403,16 @@ contains !!$ !!$ subroutine d_vect_mlt_va(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_dpk_), intent(in) :: alpha,beta !!$ real(psb_dpk_), intent(in) :: y(:) !!$ class(psb_d_multivect_type), intent(inout) :: x !!$ class(psb_d_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 -!!$ +!!$ !!$ if (allocated(z%v).and.allocated(x%v)) & !!$ & call z%v%mlt(alpha,x%v,y,beta,info) !!$ @@ -1388,36 +1420,36 @@ contains !!$ !!$ subroutine d_vect_scal(alpha, x) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ class(psb_d_multivect_type), intent(inout) :: x !!$ real(psb_dpk_), intent (in) :: alpha -!!$ +!!$ !!$ if (allocated(x%v)) call x%v%scal(alpha) !!$ !!$ end subroutine d_vect_scal !!$ !!$ !!$ function d_vect_nrm2(n,x) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_d_multivect_type), intent(inout) :: x !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_dpk_) :: res -!!$ -!!$ if (allocated(x%v)) then +!!$ +!!$ if (allocated(x%v)) then !!$ res = x%v%nrm2(n) !!$ else !!$ res = dzero !!$ end if !!$ !!$ end function d_vect_nrm2 -!!$ +!!$ !!$ function d_vect_amax(n,x) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_d_multivect_type), intent(inout) :: x !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_dpk_) :: res !!$ -!!$ if (allocated(x%v)) then +!!$ if (allocated(x%v)) then !!$ res = x%v%amax(n) !!$ else !!$ res = dzero @@ -1426,12 +1458,12 @@ contains !!$ end function d_vect_amax !!$ !!$ function d_vect_asum(n,x) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_d_multivect_type), intent(inout) :: x !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_dpk_) :: res !!$ -!!$ if (allocated(x%v)) then +!!$ if (allocated(x%v)) then !!$ res = x%v%asum(n) !!$ else !!$ res = dzero diff --git a/base/modules/serial/psb_i_base_vect_mod.f90 b/base/modules/serial/psb_i_base_vect_mod.f90 index c18909312..06871cb49 100644 --- a/base/modules/serial/psb_i_base_vect_mod.f90 +++ b/base/modules/serial/psb_i_base_vect_mod.f90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,14 +27,14 @@ ! 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. -! -! +! +! ! ! package: psb_i_base_vect_mod ! ! This module contains the definition of the psb_i_base_vect type which ! is a container for dense vectors. -! This is encapsulated instead of being just a simple array to allow for +! This is encapsulated instead of being just a simple array to allow for ! more complicated situations, such as GPU programming, where the memory ! area we are interested in is not easily accessible from the host/Fortran ! side. It is also meant to be encapsulated in an outer type, to allow @@ -43,15 +43,15 @@ ! ! module psb_i_base_vect_mod - + use psb_const_mod use psb_error_mod use psb_realloc_mod !> \namespace psb_base_mod \class psb_i_base_vect_type - !! The psb_i_base_vect_type + !! The psb_i_base_vect_type !! defines a middle level integer(psb_ipk_) encapsulated dense vector. - !! The encapsulation is needed, in place of a simple array, to allow + !! The encapsulation is needed, in place of a simple array, to allow !! for complicated situations, such as GPU programming, where the memory !! area we are interested in is not easily accessible from the host/Fortran !! side. It is also meant to be encapsulated in an outer type, to allow @@ -59,9 +59,9 @@ module psb_i_base_vect_mod !! sparse matrix types. !! type psb_i_base_vect_type - !> Values. + !> Values. integer(psb_ipk_), allocatable :: v(:) - integer(psb_ipk_), allocatable :: combuf(:) + integer(psb_ipk_), allocatable :: combuf(:) integer(psb_mpk_), allocatable :: comid(:,:) contains ! @@ -76,7 +76,7 @@ module psb_i_base_vect_mod ! ! Insert/set. Assembly and free. ! Assembly does almost nothing here, but is important - ! in derived classes. + ! in derived classes. ! procedure, pass(x) :: ins_a => i_base_ins_a procedure, pass(x) :: ins_v => i_base_ins_v @@ -91,7 +91,7 @@ module psb_i_base_vect_mod ! Any derived class having extra storage upon sync ! will guarantee that both fortran/host side and ! external side contain the same data. The base - ! version is only a placeholder. + ! version is only a placeholder. ! procedure, pass(x) :: sync => i_base_sync procedure, pass(x) :: is_host => i_base_is_host @@ -128,7 +128,7 @@ module psb_i_base_vect_mod generic, public :: set => set_vect, set_scal ! ! Gather/scatter. These are needed for MPI interfacing. - ! May have to be reworked. + ! May have to be reworked. ! procedure, pass(x) :: gthab => i_base_gthab procedure, pass(x) :: gthzv => i_base_gthzv @@ -151,11 +151,11 @@ module psb_i_base_vect_mod end interface psb_i_base_vect contains - + ! - ! Constructors. + ! Constructors. ! - + !> Function constructor: !! \brief Constructor from an array !! \param x(:) input array to be copied @@ -168,11 +168,11 @@ contains this%v = x call this%asb(size(x,kind=psb_ipk_),info) end function constructor - - + + !> Function constructor: !! \brief Constructor from size - !! \param n Size of vector to be built. + !! \param n Size of vector to be built. !! function size_const(n) result(this) integer(psb_ipk_), intent(in) :: n @@ -182,7 +182,7 @@ contains call this%asb(n,info) end function size_const - + ! ! Build from a sample ! @@ -194,20 +194,20 @@ contains !! subroutine i_base_bld_x(x,this) use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: this(:) class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info call psb_realloc(size(this),x%v,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_vect_bld') return end if x%v(:) = this(:) end subroutine i_base_bld_x - + ! ! Create with size, but no initialization ! @@ -215,11 +215,11 @@ contains !> Function bld_mn: !! \memberof psb_i_base_vect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine i_base_bld_mn(x,n) use psb_realloc_mod - implicit none + implicit none integer(psb_mpk_), intent(in) :: n class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info @@ -228,15 +228,15 @@ contains call x%asb(n,info) end subroutine i_base_bld_mn - + !> Function bld_en: !! \memberof psb_i_base_vect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine i_base_bld_en(x,n) use psb_realloc_mod - implicit none + implicit none integer(psb_epk_), intent(in) :: n class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info @@ -245,24 +245,24 @@ contains call x%asb(n,info) end subroutine i_base_bld_en - + !> Function base_all: !! \memberof psb_i_base_vect_type !! \brief Build method with size (uninitialized data) and !! allocation return code. - !! \param n size to be allocated. + !! \param n size to be allocated. !! \param info return code !! subroutine i_base_all(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_i_base_vect_type), intent(out) :: x integer(psb_ipk_), intent(out) :: info - + call psb_realloc(n,x%v,info) - + end subroutine i_base_all !> Function base_mold: @@ -274,11 +274,11 @@ contains subroutine i_base_mold(x, y, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_i_base_vect_type), intent(in) :: x class(psb_i_base_vect_type), intent(out), allocatable :: y integer(psb_ipk_), intent(out) :: info - + allocate(psb_i_base_vect_type :: y, stat=info) end subroutine i_base_mold @@ -288,21 +288,21 @@ contains ! !> Function base_ins: !! \memberof psb_i_base_vect_type - !! \brief Insert coefficients. + !! \brief Insert coefficients. !! !! !! Given a list of N pairs !! (IRL(i),VAL(i)) !! record a new coefficient in X such that !! X(IRL(1:N)) = VAL(1:N). - !! + !! !! - the update operation will perform either !! X(IRL(1:n)) = VAL(1:N) !! or !! X(IRL(1:n)) = X(IRL(1:n))+VAL(1:N) !! according to the value of DUPLICATE. - !! - !! + !! + !! !! \param n number of pairs in input !! \param irl(:) the input row indices !! \param val(:) the input coefficients @@ -312,7 +312,7 @@ contains ! subroutine i_base_ins_a(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -322,21 +322,21 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ - else if (n > min(size(irl),size(val))) then + else if (n > min(size(irl),size(val))) then info = psb_err_invalid_input_ - else + else isz = size(x%v) - select case(dupl) - case(psb_dupl_ovwrt_) + select case(dupl) + case(psb_dupl_ovwrt_) do i = 1, n !loop over all val's rows - ! row actual block row + ! row actual block row if ((1 <= irl(i)).and.(irl(i) <= isz)) then ! this row belongs to me ! copy i-th row of block val in x @@ -344,7 +344,7 @@ contains end if enddo - case(psb_dupl_add_) + case(psb_dupl_add_) do i = 1, n !loop over all val's rows @@ -362,7 +362,7 @@ contains end select end if call x%set_host() - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_vect_ins') return end if @@ -371,7 +371,7 @@ contains subroutine i_base_ins_v(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl class(psb_i_base_vect_type), intent(inout) :: irl @@ -381,14 +381,14 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return if (irl%is_dev()) call irl%sync() if (val%is_dev()) call val%sync() if (x%is_dev()) call x%sync() call x%ins(n,irl%v,val%v,dupl,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_vect_ins') return end if @@ -404,14 +404,14 @@ contains ! subroutine i_base_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x - + if (allocated(x%v)) x%v=izero call x%set_host() end subroutine i_base_zero - + ! ! Assembly. ! For derived classes: after this the vector @@ -420,20 +420,20 @@ contains !> Function base_asb: !! \memberof psb_i_base_vect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! ! - + subroutine i_base_asb_m(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_mpk_), intent(in) :: n class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (x%get_nrows() < n) & & call psb_realloc(n,x%v,info) @@ -450,20 +450,20 @@ contains !> Function base_asb: !! \memberof psb_i_base_vect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! ! - + subroutine i_base_asb_e(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_epk_), intent(in) :: n class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (x%get_nrows() < n) & & call psb_realloc(n,x%v,info) @@ -476,39 +476,39 @@ contains !> Function base_free: !! \memberof psb_i_base_vect_type !! \brief Free vector - !! + !! !! \param info return code !! ! subroutine i_base_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (allocated(x%v)) deallocate(x%v, stat=info) if (info == 0) call x%free_buffer(info) if (info == 0) call x%free_comid(info) - if (info /= 0) call & + if (info /= 0) call & & psb_errpush(psb_err_alloc_dealloc_,'vect_free') - + end subroutine i_base_free - + ! !> Function base_free_buffer: !! \memberof psb_i_base_vect_type !! \brief Free aux buffer - !! + !! !! \param info return code !! ! subroutine i_base_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -523,17 +523,17 @@ contains !! In some derived classes, e.g. GPU, !! does not really frees to avoid runtime !! costs - !! + !! !! \param info return code !! ! subroutine i_base_maybe_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (psb_get_maybe_free_buffer())& & call x%free_buffer(info) @@ -543,13 +543,13 @@ contains !> Function base_free_comid: !! \memberof psb_i_base_vect_type !! \brief Free aux MPI communication id buffer - !! + !! !! \param info return code !! ! subroutine i_base_free_comid(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -561,77 +561,77 @@ contains ! ! The base version of SYNC & friends does nothing, it's just ! a placeholder. - ! + ! ! !> Function base_sync: !! \memberof psb_i_base_vect_type !! \brief Sync: base version is a no-op. - !! + !! ! subroutine i_base_sync(x) - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x - + end subroutine i_base_sync ! !> Function base_set_host: !! \memberof psb_i_base_vect_type !! \brief Set_host: base version is a no-op. - !! + !! ! subroutine i_base_set_host(x) - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x - + end subroutine i_base_set_host ! !> Function base_set_dev: !! \memberof psb_i_base_vect_type !! \brief Set_dev: base version is a no-op. - !! + !! ! subroutine i_base_set_dev(x) - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x - + end subroutine i_base_set_dev ! !> Function base_set_sync: !! \memberof psb_i_base_vect_type !! \brief Set_sync: base version is a no-op. - !! + !! ! subroutine i_base_set_sync(x) - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x - + end subroutine i_base_set_sync ! !> Function base_is_dev: !! \memberof psb_i_base_vect_type !! \brief Is vector on external device . - !! + !! ! function i_base_is_dev(x) result(res) - implicit none + implicit none class(psb_i_base_vect_type), intent(in) :: x logical :: res - + res = .false. end function i_base_is_dev - + ! !> Function base_is_host !! \memberof psb_i_base_vect_type !! \brief Is vector on standard memory . - !! + !! ! function i_base_is_host(x) result(res) - implicit none + implicit none class(psb_i_base_vect_type), intent(in) :: x logical :: res @@ -642,10 +642,10 @@ contains !> Function base_is_sync !! \memberof psb_i_base_vect_type !! \brief Is vector on sync . - !! + !! ! function i_base_is_sync(x) result(res) - implicit none + implicit none class(psb_i_base_vect_type), intent(in) :: x logical :: res @@ -654,16 +654,16 @@ contains ! - ! Size info. + ! Size info. ! ! !> Function base_get_nrows !! \memberof psb_i_base_vect_type !! \brief Number of entries - !! + !! ! function i_base_get_nrows(x) result(res) - implicit none + implicit none class(psb_i_base_vect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -676,13 +676,13 @@ contains !> Function base_get_sizeof !! \memberof psb_i_base_vect_type !! \brief Size in bytes - !! + !! ! function i_base_sizeof(x) result(res) - implicit none + implicit none class(psb_i_base_vect_type), intent(in) :: x integer(psb_epk_) :: res - + ! Force 8-byte integers. res = (1_psb_epk_ * psb_sizeof_ip) * x%get_nrows() @@ -692,14 +692,14 @@ contains !> Function base_get_fmt !! \memberof psb_i_base_vect_type !! \brief Format - !! + !! ! function i_base_get_fmt() result(res) - implicit none + implicit none character(len=5) :: res res = 'BASE' end function i_base_get_fmt - + ! ! @@ -708,7 +708,7 @@ contains !! \memberof psb_i_base_vect_type !! \brief Extract a copy of the contents !! - ! + ! function i_base_get_vect(x,n) result(res) class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), allocatable :: res(:) @@ -716,21 +716,21 @@ contains integer(psb_ipk_), optional :: n ! Local variables integer(psb_ipk_) :: isz - - if (.not.allocated(x%v)) return + + if (.not.allocated(x%v)) return if (.not.x%is_host()) call x%sync() isz = x%get_nrows() if (present(n)) isz = max(0,min(isz,n)) - allocate(res(isz),stat=info) - if (info /= 0) then + allocate(res(isz),stat=info) + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_get_vect') return end if res(1:isz) = x%v(1:isz) end function i_base_get_vect - + ! - ! Reset all values + ! Reset all values ! ! !> Function base_set_scal @@ -739,18 +739,18 @@ contains !! \param val The value to set !! subroutine i_base_set_scal(x,val,first,last) - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: val integer(psb_ipk_), optional :: first, last - + integer(psb_ipk_) :: info, first_, last_ first_=1 last_=size(x%v) if (present(first)) first_ = max(1,first) if (present(last)) last_ = min(last,last_) - + if (x%is_dev()) call x%sync() x%v(first_:last_) = val call x%set_host() @@ -762,14 +762,14 @@ contains !> Function base_set_vect !! \memberof psb_i_base_vect_type !! \brief Set all entries - !! \param val(:) The vector to be copied in + !! \param val(:) The vector to be copied in !! subroutine i_base_set_vect(x,val,first,last) - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: val(:) integer(psb_ipk_), optional :: first, last - + integer(psb_ipk_) :: info, first_, last_, nr first_ = 1 @@ -777,7 +777,7 @@ contains last_ = min(psb_size(x%v),first_+size(val)-1) if (present(last)) last_ = min(last,last_) - if (allocated(x%v)) then + if (allocated(x%v)) then if (x%is_dev()) call x%sync() x%v(first_:last_) = val(1:last_-first_+1) else @@ -788,8 +788,8 @@ contains end subroutine i_base_set_vect - - + + ! ! Gather: Y = beta * Y + alpha * X(IDX(:)) ! @@ -804,18 +804,18 @@ contains !! \param beta subroutine i_base_gthab(n,idx,alpha,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_ipk_) :: alpha, beta, y(:) class(psb_i_base_vect_type) :: x - + if (x%is_dev()) call x%sync() call psi_gth(n,idx,alpha,x%v,beta,y) end subroutine i_base_gthab ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_gthzv !! \memberof psb_i_base_vect_type !! \brief gather into an array special alpha=1 beta=0 @@ -824,28 +824,28 @@ contains !! \param idx(:) indices subroutine i_base_gthzv_x(i,n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx integer(psb_ipk_) :: y(:) class(psb_i_base_vect_type) :: x - + if (idx%is_dev()) call idx%sync() call x%gth(n,idx%v(i:),y) end subroutine i_base_gthzv_x ! - ! New comm internals impl. + ! New comm internals impl. ! subroutine i_base_gthzbuf(i,n,idx,x) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx class(psb_i_base_vect_type) :: x - - if (.not.allocated(x%combuf)) then + + if (.not.allocated(x%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf') return end if @@ -858,22 +858,22 @@ contains !> Function base_device_wait: !! \memberof psb_i_base_vect_type !! \brief device_wait: base version is a no-op. - !! + !! ! subroutine i_base_device_wait() - implicit none - + implicit none + end subroutine i_base_device_wait function i_base_use_buffer() result(res) logical :: res - + res = .true. end function i_base_use_buffer subroutine i_base_new_buffer(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -883,7 +883,7 @@ contains subroutine i_base_new_comid(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_i_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -894,7 +894,7 @@ contains ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_gthzv !! \memberof psb_i_base_vect_type !! \brief gather into an array special alpha=1 beta=0 @@ -903,20 +903,20 @@ contains !! \param idx(:) indices subroutine i_base_gthzv(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_ipk_) :: y(:) class(psb_i_base_vect_type) :: x - + if (x%is_dev()) call x%sync() call psi_gth(n,idx,x%v,y) end subroutine i_base_gthzv ! - ! Scatter: + ! Scatter: ! Y(IDX(:)) = beta*Y(IDX(:)) + X(:) - ! + ! ! !> Function base_sctb !! \memberof psb_i_base_vect_type @@ -925,14 +925,14 @@ contains !! \param n how many entries to consider !! \param idx(:) indices !! \param beta - !! \param x(:) + !! \param x(:) subroutine i_base_sctb(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_ipk_) :: beta, x(:) class(psb_i_base_vect_type) :: y - + if (y%is_dev()) call y%sync() call psi_sct(n,idx,x,beta,y%v) call y%set_host() @@ -941,12 +941,12 @@ contains subroutine i_base_sctb_x(i,n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx integer(psb_ipk_) :: beta, x(:) class(psb_i_base_vect_type) :: y - + if (idx%is_dev()) call idx%sync() call y%sct(n,idx%v(i:),x,beta) call y%set_host() @@ -955,14 +955,14 @@ contains subroutine i_base_sctb_buf(i,n,idx,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx integer(psb_ipk_) :: beta class(psb_i_base_vect_type) :: y - - - if (.not.allocated(y%combuf)) then + + + if (.not.allocated(y%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf') return end if @@ -987,22 +987,22 @@ module psb_i_base_multivect_mod use psb_i_base_vect_mod !> \namespace psb_base_mod \class psb_i_base_vect_type - !! The psb_i_base_vect_type + !! The psb_i_base_vect_type !! defines a middle level integer(psb_ipk_) encapsulated dense vector. - !! The encapsulation is needed, in place of a simple array, to allow + !! The encapsulation is needed, in place of a simple array, to allow !! for complicated situations, such as GPU programming, where the memory !! area we are interested in is not easily accessible from the host/Fortran !! side. It is also meant to be encapsulated in an outer type, to allow !! runtime switching as per the STATE design pattern, similar to the !! sparse matrix types. !! - private + private public :: psb_i_base_multivect, psb_i_base_multivect_type type psb_i_base_multivect_type - !> Values. + !> Values. integer(psb_ipk_), allocatable :: v(:,:) - integer(psb_ipk_), allocatable :: combuf(:) + integer(psb_ipk_), allocatable :: combuf(:) integer(psb_mpk_), allocatable :: comid(:,:) contains ! @@ -1016,7 +1016,7 @@ module psb_i_base_multivect_mod ! ! Insert/set. Assembly and free. ! Assembly does almost nothing here, but is important - ! in derived classes. + ! in derived classes. ! procedure, pass(x) :: ins => i_base_mlv_ins procedure, pass(x) :: zero => i_base_mlv_zero @@ -1027,7 +1027,7 @@ module psb_i_base_multivect_mod ! Any derived class having extra storage upon sync ! will guarantee that both fortran/host side and ! external side contain the same data. The base - ! version is only a placeholder. + ! version is only a placeholder. ! procedure, pass(x) :: sync => i_base_mlv_sync procedure, pass(x) :: is_host => i_base_mlv_is_host @@ -1067,7 +1067,7 @@ module psb_i_base_multivect_mod ! ! Gather/scatter. These are needed for MPI interfacing. - ! May have to be reworked. + ! May have to be reworked. ! procedure, pass(x) :: gthab => i_base_mlv_gthab procedure, pass(x) :: gthzv => i_base_mlv_gthzv @@ -1089,7 +1089,7 @@ module psb_i_base_multivect_mod contains ! - ! Constructors. + ! Constructors. ! !> Function constructor: @@ -1108,7 +1108,7 @@ contains !> Function constructor: !! \brief Constructor from size - !! \param n Size of vector to be built. + !! \param n Size of vector to be built. !! function size_const(m,n) result(this) integer(psb_ipk_), intent(in) :: m,n @@ -1135,7 +1135,7 @@ contains integer(psb_ipk_) :: info call psb_realloc(size(this,1),size(this,2),x%v,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_mlv_vect_bld') return end if @@ -1150,7 +1150,7 @@ contains !> Function bld_n: !! \memberof psb_i_base_multivect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine i_base_mlv_bld_n(x,m,n) use psb_realloc_mod @@ -1167,13 +1167,13 @@ contains !! \memberof psb_i_base_multivect_type !! \brief Build method with size (uninitialized data) and !! allocation return code. - !! \param n size to be allocated. + !! \param n size to be allocated. !! \param info return code !! subroutine i_base_mlv_all(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_i_base_multivect_type), intent(out) :: x integer(psb_ipk_), intent(out) :: info @@ -1191,7 +1191,7 @@ contains subroutine i_base_mlv_mold(x, y, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_i_base_multivect_type), intent(in) :: x class(psb_i_base_multivect_type), intent(out), allocatable :: y integer(psb_ipk_), intent(out) :: info @@ -1205,21 +1205,21 @@ contains ! !> Function base_mlv_ins: !! \memberof psb_i_base_multivect_type - !! \brief Insert coefficients. + !! \brief Insert coefficients. !! !! !! Given a list of N pairs !! (IRL(i),VAL(i)) !! record a new coefficient in X such that !! X(IRL(1:N)) = VAL(1:N). - !! + !! !! - the update operation will perform either !! X(IRL(1:n)) = VAL(1:N) !! or !! X(IRL(1:n)) = X(IRL(1:n))+VAL(1:N) !! according to the value of DUPLICATE. - !! - !! + !! + !! !! \param n number of pairs in input !! \param irl(:) the input row indices !! \param val(:) the input coefficients @@ -1229,7 +1229,7 @@ contains ! subroutine i_base_mlv_ins(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -1239,21 +1239,21 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ - else if (n > min(size(irl),size(val))) then + else if (n > min(size(irl),size(val))) then info = psb_err_invalid_input_ - else + else isz = size(x%v,1) - select case(dupl) - case(psb_dupl_ovwrt_) + select case(dupl) + case(psb_dupl_ovwrt_) do i = 1, n !loop over all val's rows - ! row actual block row + ! row actual block row if ((1 <= irl(i)).and.(irl(i) <= isz)) then ! this row belongs to me ! copy i-th row of block val in x @@ -1261,7 +1261,7 @@ contains end if enddo - case(psb_dupl_add_) + case(psb_dupl_add_) do i = 1, n !loop over all val's rows @@ -1278,7 +1278,7 @@ contains ! !$ goto 9999 end select end if - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_mlv_vect_ins') return end if @@ -1293,7 +1293,7 @@ contains ! subroutine i_base_mlv_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x if (allocated(x%v)) x%v=izero @@ -1309,7 +1309,7 @@ contains !> Function base_mlv_asb: !! \memberof psb_i_base_multivect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! @@ -1318,7 +1318,7 @@ contains subroutine i_base_mlv_asb(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_i_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1335,20 +1335,20 @@ contains !> Function base_mlv_free: !! \memberof psb_i_base_multivect_type !! \brief Free vector - !! + !! !! \param info return code !! ! subroutine i_base_mlv_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 if (allocated(x%v)) deallocate(x%v, stat=info) - if (info /= 0) call & + if (info /= 0) call & & psb_errpush(psb_err_alloc_dealloc_,'vect_free') end subroutine i_base_mlv_free @@ -1358,15 +1358,15 @@ contains ! ! The base version of SYNC & friends does nothing, it's just ! a placeholder. - ! + ! ! !> Function base_mlv_sync: !! \memberof psb_i_base_multivect_type !! \brief Sync: base version is a no-op. - !! + !! ! subroutine i_base_mlv_sync(x) - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x end subroutine i_base_mlv_sync @@ -1375,10 +1375,10 @@ contains !> Function base_mlv_set_host: !! \memberof psb_i_base_multivect_type !! \brief Set_host: base version is a no-op. - !! + !! ! subroutine i_base_mlv_set_host(x) - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x end subroutine i_base_mlv_set_host @@ -1387,10 +1387,10 @@ contains !> Function base_mlv_set_dev: !! \memberof psb_i_base_multivect_type !! \brief Set_dev: base version is a no-op. - !! + !! ! subroutine i_base_mlv_set_dev(x) - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x end subroutine i_base_mlv_set_dev @@ -1399,10 +1399,10 @@ contains !> Function base_mlv_set_sync: !! \memberof psb_i_base_multivect_type !! \brief Set_sync: base version is a no-op. - !! + !! ! subroutine i_base_mlv_set_sync(x) - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x end subroutine i_base_mlv_set_sync @@ -1411,10 +1411,10 @@ contains !> Function base_mlv_is_dev: !! \memberof psb_i_base_multivect_type !! \brief Is vector on external device . - !! + !! ! function i_base_mlv_is_dev(x) result(res) - implicit none + implicit none class(psb_i_base_multivect_type), intent(in) :: x logical :: res @@ -1425,10 +1425,10 @@ contains !> Function base_mlv_is_host !! \memberof psb_i_base_multivect_type !! \brief Is vector on standard memory . - !! + !! ! function i_base_mlv_is_host(x) result(res) - implicit none + implicit none class(psb_i_base_multivect_type), intent(in) :: x logical :: res @@ -1439,10 +1439,10 @@ contains !> Function base_mlv_is_sync !! \memberof psb_i_base_multivect_type !! \brief Is vector on sync . - !! + !! ! function i_base_mlv_is_sync(x) result(res) - implicit none + implicit none class(psb_i_base_multivect_type), intent(in) :: x logical :: res @@ -1451,16 +1451,16 @@ contains ! - ! Size info. + ! Size info. ! ! !> Function base_mlv_get_nrows !! \memberof psb_i_base_multivect_type !! \brief Number of entries - !! + !! ! function i_base_mlv_get_nrows(x) result(res) - implicit none + implicit none class(psb_i_base_multivect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -1470,7 +1470,7 @@ contains end function i_base_mlv_get_nrows function i_base_mlv_get_ncols(x) result(res) - implicit none + implicit none class(psb_i_base_multivect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -1483,10 +1483,10 @@ contains !> Function base_mlv_get_sizeof !! \memberof psb_i_base_multivect_type !! \brief Size in bytesa - !! + !! ! function i_base_mlv_sizeof(x) result(res) - implicit none + implicit none class(psb_i_base_multivect_type), intent(in) :: x integer(psb_epk_) :: res @@ -1499,10 +1499,10 @@ contains !> Function base_mlv_get_fmt !! \memberof psb_i_base_multivect_type !! \brief Format - !! + !! ! function i_base_mlv_get_fmt() result(res) - implicit none + implicit none character(len=5) :: res res = 'BASE' end function i_base_mlv_get_fmt @@ -1515,18 +1515,18 @@ contains !! \memberof psb_i_base_multivect_type !! \brief Extract a copy of the contents !! - ! + ! function i_base_mlv_get_vect(x) result(res) - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x integer(psb_ipk_), allocatable :: res(:,:) integer(psb_ipk_) :: info,m,n m = x%get_nrows() n = x%get_ncols() - if (.not.allocated(x%v)) return + if (.not.allocated(x%v)) return call x%sync() - allocate(res(m,n),stat=info) - if (info /= 0) then + allocate(res(m,n),stat=info) + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_mlv_get_vect') return end if @@ -1534,7 +1534,7 @@ contains end function i_base_mlv_get_vect ! - ! Reset all values + ! Reset all values ! ! !> Function base_mlv_set_scal @@ -1543,7 +1543,7 @@ contains !! \param val The value to set !! subroutine i_base_mlv_set_scal(x,val) - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: val @@ -1556,16 +1556,16 @@ contains !> Function base_mlv_set_vect !! \memberof psb_i_base_multivect_type !! \brief Set all entries - !! \param val(:) The vector to be copied in + !! \param val(:) The vector to be copied in !! subroutine i_base_mlv_set_vect(x,val) - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: val(:,:) integer(psb_ipk_) :: nr, nc integer(psb_ipk_) :: info - if (allocated(x%v)) then + if (allocated(x%v)) then nr = min(size(x%v,1),size(val,1)) nc = min(size(x%v,2),size(val,2)) @@ -1578,15 +1578,15 @@ contains function i_base_mlv_use_buffer() result(res) - implicit none + implicit none logical :: res - + res = .true. end function i_base_mlv_use_buffer subroutine i_base_mlv_new_buffer(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -1598,7 +1598,7 @@ contains subroutine i_base_mlv_new_comid(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -1609,12 +1609,12 @@ contains subroutine i_base_mlv_maybe_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (psb_get_maybe_free_buffer())& & call x%free_buffer(info) @@ -1622,7 +1622,7 @@ contains subroutine i_base_mlv_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1632,7 +1632,7 @@ contains subroutine i_base_mlv_free_comid(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_i_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1655,7 +1655,7 @@ contains !! \param beta subroutine i_base_mlv_gthab(n,idx,alpha,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_ipk_) :: alpha, beta, y(:) class(psb_i_base_multivect_type) :: x @@ -1671,7 +1671,7 @@ contains end subroutine i_base_mlv_gthab ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_i_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1680,7 +1680,7 @@ contains !! \param idx(:) indices subroutine i_base_mlv_gthzv_x(i,n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx integer(psb_ipk_) :: y(:) @@ -1693,7 +1693,7 @@ contains ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_i_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1702,7 +1702,7 @@ contains !! \param idx(:) indices subroutine i_base_mlv_gthzv(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_ipk_) :: y(:) class(psb_i_base_multivect_type) :: x @@ -1719,7 +1719,7 @@ contains end subroutine i_base_mlv_gthzv ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_i_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1728,7 +1728,7 @@ contains !! \param idx(:) indices subroutine i_base_mlv_gthzm(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_ipk_) :: y(:,:) class(psb_i_base_multivect_type) :: x @@ -1745,17 +1745,17 @@ contains end subroutine i_base_mlv_gthzm ! - ! New comm internals impl. + ! New comm internals impl. ! subroutine i_base_mlv_gthzbuf(i,ixb,n,idx,x) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, ixb, n class(psb_i_base_vect_type) :: idx class(psb_i_base_multivect_type) :: x integer(psb_ipk_) :: nc - - if (.not.allocated(x%combuf)) then + + if (.not.allocated(x%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf') return end if @@ -1767,9 +1767,9 @@ contains end subroutine i_base_mlv_gthzbuf ! - ! Scatter: + ! Scatter: ! Y(IDX(:),:) = beta*Y(IDX(:),:) + X(:) - ! + ! ! !> Function base_mlv_sctb !! \memberof psb_i_base_multivect_type @@ -1778,10 +1778,10 @@ contains !! \param n how many entries to consider !! \param idx(:) indices !! \param beta - !! \param x(:) + !! \param x(:) subroutine i_base_mlv_sctb(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_ipk_) :: beta, x(:) class(psb_i_base_multivect_type) :: y @@ -1796,7 +1796,7 @@ contains subroutine i_base_mlv_sctbr2(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_ipk_) :: beta, x(:,:) class(psb_i_base_multivect_type) :: y @@ -1811,7 +1811,7 @@ contains subroutine i_base_mlv_sctb_x(i,n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx integer( psb_ipk_) :: beta, x(:) @@ -1823,14 +1823,14 @@ contains subroutine i_base_mlv_sctb_buf(i,iyb,n,idx,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, iyb, n class(psb_i_base_vect_type) :: idx integer(psb_ipk_) :: beta class(psb_i_base_multivect_type) :: y integer(psb_ipk_) :: nc - - if (.not.allocated(y%combuf)) then + + if (.not.allocated(y%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf') return end if @@ -1839,19 +1839,18 @@ contains nc = y%get_ncols() call y%sct(n,idx%v(i:),y%combuf(iyb:),beta) call y%set_host() - + end subroutine i_base_mlv_sctb_buf ! !> Function base_device_wait: !! \memberof psb_i_base_vect_type !! \brief device_wait: base version is a no-op. - !! + !! ! subroutine i_base_mlv_device_wait() - implicit none - + implicit none + end subroutine i_base_mlv_device_wait end module psb_i_base_multivect_mod - diff --git a/base/modules/serial/psb_i_vect_mod.F90 b/base/modules/serial/psb_i_vect_mod.F90 index 0661fbe00..d3aaa48ed 100644 --- a/base/modules/serial/psb_i_vect_mod.F90 +++ b/base/modules/serial/psb_i_vect_mod.F90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,22 +27,22 @@ ! 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. -! -! +! +! ! ! package: psb_i_vect_mod ! ! This module contains the definition of the psb_i_vect type which ! is the outer container for dense vectors. ! Therefore all methods simply invoke the corresponding methods of the -! inner component. +! inner component. ! module psb_i_vect_mod use psb_i_base_vect_mod type psb_i_vect_type - class(psb_i_base_vect_type), allocatable :: v + class(psb_i_base_vect_type), allocatable :: v contains procedure, pass(x) :: get_nrows => i_vect_get_nrows procedure, pass(x) :: sizeof => i_vect_sizeof @@ -114,11 +114,11 @@ module psb_i_vect_mod contains - subroutine psb_i_set_vect_default(v) - implicit none + subroutine psb_i_set_vect_default(v) + implicit none class(psb_i_base_vect_type), intent(in) :: v - if (allocated(psb_i_base_vect_default)) then + if (allocated(psb_i_base_vect_default)) then deallocate(psb_i_base_vect_default) end if allocate(psb_i_base_vect_default, mold=v) @@ -126,7 +126,7 @@ contains end subroutine psb_i_set_vect_default function psb_i_get_vect_default(v) result(res) - implicit none + implicit none class(psb_i_vect_type), intent(in) :: v class(psb_i_base_vect_type), pointer :: res @@ -136,10 +136,10 @@ contains function psb_i_get_base_vect_default() result(res) - implicit none + implicit none class(psb_i_base_vect_type), pointer :: res - if (.not.allocated(psb_i_base_vect_default)) then + if (.not.allocated(psb_i_base_vect_default)) then allocate(psb_i_base_vect_type :: psb_i_base_vect_default) end if @@ -149,14 +149,14 @@ contains subroutine i_vect_clone(x,y,info) - implicit none + implicit none class(psb_i_vect_type), intent(inout) :: x class(psb_i_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info info = psb_success_ call y%free(info) - if ((info==0).and.allocated(x%v)) then + if ((info==0).and.allocated(x%v)) then call y%bld(x%get_vect(),mold=x%v) end if end subroutine i_vect_clone @@ -171,7 +171,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_i_get_base_vect_default()) @@ -193,7 +193,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_i_get_base_vect_default()) @@ -214,7 +214,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_i_get_base_vect_default()) @@ -277,7 +277,7 @@ contains end function size_const function i_vect_get_nrows(x) result(res) - implicit none + implicit none class(psb_i_vect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -285,7 +285,7 @@ contains end function i_vect_get_nrows function i_vect_sizeof(x) result(res) - implicit none + implicit none class(psb_i_vect_type), intent(in) :: x integer(psb_epk_) :: res res = 0 @@ -293,7 +293,7 @@ contains end function i_vect_sizeof function i_vect_get_fmt(x) result(res) - implicit none + implicit none class(psb_i_vect_type), intent(in) :: x character(len=5) :: res res = 'NULL' @@ -302,7 +302,7 @@ contains subroutine i_vect_all(n, x, info, mold) - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_i_vect_type), intent(inout) :: x class(psb_i_base_vect_type), intent(in), optional :: mold @@ -311,12 +311,12 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(psb_i_base_vect_type :: x%v,stat=info) endif - if (info == 0) then + if (info == 0) then call x%v%all(n,info) else info = psb_err_alloc_dealloc_ @@ -326,12 +326,12 @@ contains subroutine i_vect_reall(n, x, info) - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_i_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (.not.allocated(x%v)) & & call x%all(n,info) if (info == 0) & @@ -341,7 +341,7 @@ contains subroutine i_vect_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_i_vect_type), intent(inout) :: x if (allocated(x%v)) call x%v%zero() @@ -351,7 +351,7 @@ contains subroutine i_vect_asb(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_i_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -397,12 +397,12 @@ contains subroutine i_vect_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_i_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%free(info) if (info == 0) deallocate(x%v,stat=info) end if @@ -411,7 +411,7 @@ contains subroutine i_vect_ins_a(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_i_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -421,7 +421,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ return end if @@ -432,7 +432,7 @@ contains subroutine i_vect_ins_v(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_i_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl class(psb_i_vect_type), intent(inout) :: irl @@ -442,7 +442,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then + if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then info = psb_err_invalid_vect_state_ return end if @@ -460,12 +460,12 @@ contains integer(psb_ipk_) :: info info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(tmp,stat=info,mold=mold) else allocate(tmp,stat=info,mold=psb_i_get_base_vect_default()) end if - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%sync() if (info == psb_success_) call tmp%bld(x%v%v) call x%v%free(info) @@ -476,7 +476,7 @@ contains subroutine i_vect_sync(x) - implicit none + implicit none class(psb_i_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -485,7 +485,7 @@ contains end subroutine i_vect_sync subroutine i_vect_set_sync(x) - implicit none + implicit none class(psb_i_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -494,7 +494,7 @@ contains end subroutine i_vect_set_sync subroutine i_vect_set_host(x) - implicit none + implicit none class(psb_i_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -503,7 +503,7 @@ contains end subroutine i_vect_set_host subroutine i_vect_set_dev(x) - implicit none + implicit none class(psb_i_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -512,7 +512,7 @@ contains end subroutine i_vect_set_dev function i_vect_is_sync(x) result(res) - implicit none + implicit none logical :: res class(psb_i_vect_type), intent(inout) :: x @@ -523,7 +523,7 @@ contains end function i_vect_is_sync function i_vect_is_host(x) result(res) - implicit none + implicit none logical :: res class(psb_i_vect_type), intent(inout) :: x @@ -534,11 +534,11 @@ contains end function i_vect_is_host function i_vect_is_dev(x) result(res) - implicit none + implicit none logical :: res class(psb_i_vect_type), intent(inout) :: x - res = .false. + res = .false. if (allocated(x%v)) & & res = x%v%is_dev() @@ -559,7 +559,7 @@ module psb_i_multivect_mod !private type psb_i_multivect_type - class(psb_i_base_multivect_type), allocatable :: v + class(psb_i_base_multivect_type), allocatable :: v contains procedure, pass(x) :: get_nrows => i_vect_get_nrows procedure, pass(x) :: get_ncols => i_vect_get_ncols @@ -615,11 +615,11 @@ module psb_i_multivect_mod contains - subroutine psb_i_set_multivect_default(v) - implicit none + subroutine psb_i_set_multivect_default(v) + implicit none class(psb_i_base_multivect_type), intent(in) :: v - if (allocated(psb_i_base_multivect_default)) then + if (allocated(psb_i_base_multivect_default)) then deallocate(psb_i_base_multivect_default) end if allocate(psb_i_base_multivect_default, mold=v) @@ -627,7 +627,7 @@ contains end subroutine psb_i_set_multivect_default function psb_i_get_multivect_default(v) result(res) - implicit none + implicit none class(psb_i_multivect_type), intent(in) :: v class(psb_i_base_multivect_type), pointer :: res @@ -637,10 +637,10 @@ contains function psb_i_get_base_multivect_default() result(res) - implicit none + implicit none class(psb_i_base_multivect_type), pointer :: res - if (.not.allocated(psb_i_base_multivect_default)) then + if (.not.allocated(psb_i_base_multivect_default)) then allocate(psb_i_base_multivect_type :: psb_i_base_multivect_default) end if @@ -650,14 +650,14 @@ contains subroutine i_vect_clone(x,y,info) - implicit none + implicit none class(psb_i_multivect_type), intent(inout) :: x class(psb_i_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info info = psb_success_ call y%free(info) - if ((info==0).and.allocated(x%v)) then + if ((info==0).and.allocated(x%v)) then call y%bld(x%get_vect(),mold=x%v) end if end subroutine i_vect_clone @@ -670,7 +670,7 @@ contains class(psb_i_base_multivect_type), pointer :: mld info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_i_get_base_multivect_default()) @@ -688,7 +688,7 @@ contains integer(psb_ipk_) :: info info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_i_get_base_multivect_default()) @@ -748,7 +748,7 @@ contains end function size_const function i_vect_get_nrows(x) result(res) - implicit none + implicit none class(psb_i_multivect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -756,7 +756,7 @@ contains end function i_vect_get_nrows function i_vect_get_ncols(x) result(res) - implicit none + implicit none class(psb_i_multivect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -764,7 +764,7 @@ contains end function i_vect_get_ncols function i_vect_sizeof(x) result(res) - implicit none + implicit none class(psb_i_multivect_type), intent(in) :: x integer(psb_epk_) :: res res = 0 @@ -772,7 +772,7 @@ contains end function i_vect_sizeof function i_vect_get_fmt(x) result(res) - implicit none + implicit none class(psb_i_multivect_type), intent(in) :: x character(len=5) :: res res = 'NULL' @@ -781,18 +781,18 @@ contains subroutine i_vect_all(m,n, x, info, mold) - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_i_multivect_type), intent(out) :: x class(psb_i_base_multivect_type), intent(in), optional :: mold integer(psb_ipk_), intent(out) :: info - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(psb_i_base_multivect_type :: x%v,stat=info) endif - if (info == 0) then + if (info == 0) then call x%v%all(m,n,info) else info = psb_err_alloc_dealloc_ @@ -802,12 +802,12 @@ contains subroutine i_vect_reall(m,n, x, info) - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_i_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (.not.allocated(x%v)) & & call x%all(m,n,info) if (info == 0) & @@ -817,7 +817,7 @@ contains subroutine i_vect_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_i_multivect_type), intent(inout) :: x if (allocated(x%v)) call x%v%zero() @@ -827,7 +827,7 @@ contains subroutine i_vect_asb(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_i_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -838,7 +838,7 @@ contains end subroutine i_vect_asb subroutine i_vect_sync(x) - implicit none + implicit none class(psb_i_multivect_type), intent(inout) :: x if (allocated(x%v)) & @@ -906,12 +906,12 @@ contains subroutine i_vect_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_i_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%free(info) if (info == 0) deallocate(x%v,stat=info) end if @@ -920,7 +920,7 @@ contains subroutine i_vect_ins(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_i_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -930,7 +930,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ return end if @@ -946,12 +946,12 @@ contains class(psb_i_base_multivect_type), allocatable :: tmp integer(psb_ipk_) :: info - if (present(mold)) then + if (present(mold)) then allocate(tmp,stat=info,mold=mold) else allocate(tmp,stat=info, mold=psb_i_get_base_multivect_default()) - endif - if (allocated(x%v)) then + endif + if (allocated(x%v)) then call x%v%sync() if (info == psb_success_) call tmp%bld(x%v%v) call x%v%free(info) diff --git a/base/modules/serial/psb_l_base_vect_mod.f90 b/base/modules/serial/psb_l_base_vect_mod.f90 index ab7b49f1f..37bdf485e 100644 --- a/base/modules/serial/psb_l_base_vect_mod.f90 +++ b/base/modules/serial/psb_l_base_vect_mod.f90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,14 +27,14 @@ ! 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. -! -! +! +! ! ! package: psb_l_base_vect_mod ! ! This module contains the definition of the psb_l_base_vect type which ! is a container for dense vectors. -! This is encapsulated instead of being just a simple array to allow for +! This is encapsulated instead of being just a simple array to allow for ! more complicated situations, such as GPU programming, where the memory ! area we are interested in is not easily accessible from the host/Fortran ! side. It is also meant to be encapsulated in an outer type, to allow @@ -43,16 +43,16 @@ ! ! module psb_l_base_vect_mod - + use psb_const_mod use psb_error_mod use psb_realloc_mod use psb_i_base_vect_mod !> \namespace psb_base_mod \class psb_l_base_vect_type - !! The psb_l_base_vect_type + !! The psb_l_base_vect_type !! defines a middle level integer(psb_lpk_) encapsulated dense vector. - !! The encapsulation is needed, in place of a simple array, to allow + !! The encapsulation is needed, in place of a simple array, to allow !! for complicated situations, such as GPU programming, where the memory !! area we are interested in is not easily accessible from the host/Fortran !! side. It is also meant to be encapsulated in an outer type, to allow @@ -60,9 +60,9 @@ module psb_l_base_vect_mod !! sparse matrix types. !! type psb_l_base_vect_type - !> Values. + !> Values. integer(psb_lpk_), allocatable :: v(:) - integer(psb_lpk_), allocatable :: combuf(:) + integer(psb_lpk_), allocatable :: combuf(:) integer(psb_mpk_), allocatable :: comid(:,:) contains ! @@ -77,7 +77,7 @@ module psb_l_base_vect_mod ! ! Insert/set. Assembly and free. ! Assembly does almost nothing here, but is important - ! in derived classes. + ! in derived classes. ! procedure, pass(x) :: ins_a => l_base_ins_a procedure, pass(x) :: ins_v => l_base_ins_v @@ -92,7 +92,7 @@ module psb_l_base_vect_mod ! Any derived class having extra storage upon sync ! will guarantee that both fortran/host side and ! external side contain the same data. The base - ! version is only a placeholder. + ! version is only a placeholder. ! procedure, pass(x) :: sync => l_base_sync procedure, pass(x) :: is_host => l_base_is_host @@ -129,7 +129,7 @@ module psb_l_base_vect_mod generic, public :: set => set_vect, set_scal ! ! Gather/scatter. These are needed for MPI interfacing. - ! May have to be reworked. + ! May have to be reworked. ! procedure, pass(x) :: gthab => l_base_gthab procedure, pass(x) :: gthzv => l_base_gthzv @@ -152,11 +152,11 @@ module psb_l_base_vect_mod end interface psb_l_base_vect contains - + ! - ! Constructors. + ! Constructors. ! - + !> Function constructor: !! \brief Constructor from an array !! \param x(:) input array to be copied @@ -169,11 +169,11 @@ contains this%v = x call this%asb(size(x,kind=psb_ipk_),info) end function constructor - - + + !> Function constructor: !! \brief Constructor from size - !! \param n Size of vector to be built. + !! \param n Size of vector to be built. !! function size_const(n) result(this) integer(psb_ipk_), intent(in) :: n @@ -183,7 +183,7 @@ contains call this%asb(n,info) end function size_const - + ! ! Build from a sample ! @@ -195,20 +195,20 @@ contains !! subroutine l_base_bld_x(x,this) use psb_realloc_mod - implicit none + implicit none integer(psb_lpk_), intent(in) :: this(:) class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info call psb_realloc(size(this),x%v,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_vect_bld') return end if x%v(:) = this(:) end subroutine l_base_bld_x - + ! ! Create with size, but no initialization ! @@ -216,11 +216,11 @@ contains !> Function bld_mn: !! \memberof psb_l_base_vect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine l_base_bld_mn(x,n) use psb_realloc_mod - implicit none + implicit none integer(psb_mpk_), intent(in) :: n class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info @@ -229,15 +229,15 @@ contains call x%asb(n,info) end subroutine l_base_bld_mn - + !> Function bld_en: !! \memberof psb_l_base_vect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine l_base_bld_en(x,n) use psb_realloc_mod - implicit none + implicit none integer(psb_epk_), intent(in) :: n class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info @@ -246,24 +246,24 @@ contains call x%asb(n,info) end subroutine l_base_bld_en - + !> Function base_all: !! \memberof psb_l_base_vect_type !! \brief Build method with size (uninitialized data) and !! allocation return code. - !! \param n size to be allocated. + !! \param n size to be allocated. !! \param info return code !! subroutine l_base_all(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_l_base_vect_type), intent(out) :: x integer(psb_ipk_), intent(out) :: info - + call psb_realloc(n,x%v,info) - + end subroutine l_base_all !> Function base_mold: @@ -275,11 +275,11 @@ contains subroutine l_base_mold(x, y, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_l_base_vect_type), intent(in) :: x class(psb_l_base_vect_type), intent(out), allocatable :: y integer(psb_ipk_), intent(out) :: info - + allocate(psb_l_base_vect_type :: y, stat=info) end subroutine l_base_mold @@ -289,21 +289,21 @@ contains ! !> Function base_ins: !! \memberof psb_l_base_vect_type - !! \brief Insert coefficients. + !! \brief Insert coefficients. !! !! !! Given a list of N pairs !! (IRL(i),VAL(i)) !! record a new coefficient in X such that !! X(IRL(1:N)) = VAL(1:N). - !! + !! !! - the update operation will perform either !! X(IRL(1:n)) = VAL(1:N) !! or !! X(IRL(1:n)) = X(IRL(1:n))+VAL(1:N) !! according to the value of DUPLICATE. - !! - !! + !! + !! !! \param n number of pairs in input !! \param irl(:) the input row indices !! \param val(:) the input coefficients @@ -313,7 +313,7 @@ contains ! subroutine l_base_ins_a(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -323,21 +323,21 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ - else if (n > min(size(irl),size(val))) then + else if (n > min(size(irl),size(val))) then info = psb_err_invalid_input_ - else + else isz = size(x%v) - select case(dupl) - case(psb_dupl_ovwrt_) + select case(dupl) + case(psb_dupl_ovwrt_) do i = 1, n !loop over all val's rows - ! row actual block row + ! row actual block row if ((1 <= irl(i)).and.(irl(i) <= isz)) then ! this row belongs to me ! copy i-th row of block val in x @@ -345,7 +345,7 @@ contains end if enddo - case(psb_dupl_add_) + case(psb_dupl_add_) do i = 1, n !loop over all val's rows @@ -363,7 +363,7 @@ contains end select end if call x%set_host() - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_vect_ins') return end if @@ -372,7 +372,7 @@ contains subroutine l_base_ins_v(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl class(psb_i_base_vect_type), intent(inout) :: irl @@ -382,14 +382,14 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return if (irl%is_dev()) call irl%sync() if (val%is_dev()) call val%sync() if (x%is_dev()) call x%sync() call x%ins(n,irl%v,val%v,dupl,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_vect_ins') return end if @@ -405,14 +405,14 @@ contains ! subroutine l_base_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x - + if (allocated(x%v)) x%v=lzero call x%set_host() end subroutine l_base_zero - + ! ! Assembly. ! For derived classes: after this the vector @@ -421,20 +421,20 @@ contains !> Function base_asb: !! \memberof psb_l_base_vect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! ! - + subroutine l_base_asb_m(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_mpk_), intent(in) :: n class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (x%get_nrows() < n) & & call psb_realloc(n,x%v,info) @@ -451,20 +451,20 @@ contains !> Function base_asb: !! \memberof psb_l_base_vect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! ! - + subroutine l_base_asb_e(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_epk_), intent(in) :: n class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (x%get_nrows() < n) & & call psb_realloc(n,x%v,info) @@ -477,39 +477,39 @@ contains !> Function base_free: !! \memberof psb_l_base_vect_type !! \brief Free vector - !! + !! !! \param info return code !! ! subroutine l_base_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (allocated(x%v)) deallocate(x%v, stat=info) if (info == 0) call x%free_buffer(info) if (info == 0) call x%free_comid(info) - if (info /= 0) call & + if (info /= 0) call & & psb_errpush(psb_err_alloc_dealloc_,'vect_free') - + end subroutine l_base_free - + ! !> Function base_free_buffer: !! \memberof psb_l_base_vect_type !! \brief Free aux buffer - !! + !! !! \param info return code !! ! subroutine l_base_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -524,17 +524,17 @@ contains !! In some derived classes, e.g. GPU, !! does not really frees to avoid runtime !! costs - !! + !! !! \param info return code !! ! subroutine l_base_maybe_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (psb_get_maybe_free_buffer())& & call x%free_buffer(info) @@ -544,13 +544,13 @@ contains !> Function base_free_comid: !! \memberof psb_l_base_vect_type !! \brief Free aux MPI communication id buffer - !! + !! !! \param info return code !! ! subroutine l_base_free_comid(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -562,77 +562,77 @@ contains ! ! The base version of SYNC & friends does nothing, it's just ! a placeholder. - ! + ! ! !> Function base_sync: !! \memberof psb_l_base_vect_type !! \brief Sync: base version is a no-op. - !! + !! ! subroutine l_base_sync(x) - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x - + end subroutine l_base_sync ! !> Function base_set_host: !! \memberof psb_l_base_vect_type !! \brief Set_host: base version is a no-op. - !! + !! ! subroutine l_base_set_host(x) - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x - + end subroutine l_base_set_host ! !> Function base_set_dev: !! \memberof psb_l_base_vect_type !! \brief Set_dev: base version is a no-op. - !! + !! ! subroutine l_base_set_dev(x) - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x - + end subroutine l_base_set_dev ! !> Function base_set_sync: !! \memberof psb_l_base_vect_type !! \brief Set_sync: base version is a no-op. - !! + !! ! subroutine l_base_set_sync(x) - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x - + end subroutine l_base_set_sync ! !> Function base_is_dev: !! \memberof psb_l_base_vect_type !! \brief Is vector on external device . - !! + !! ! function l_base_is_dev(x) result(res) - implicit none + implicit none class(psb_l_base_vect_type), intent(in) :: x logical :: res - + res = .false. end function l_base_is_dev - + ! !> Function base_is_host !! \memberof psb_l_base_vect_type !! \brief Is vector on standard memory . - !! + !! ! function l_base_is_host(x) result(res) - implicit none + implicit none class(psb_l_base_vect_type), intent(in) :: x logical :: res @@ -643,10 +643,10 @@ contains !> Function base_is_sync !! \memberof psb_l_base_vect_type !! \brief Is vector on sync . - !! + !! ! function l_base_is_sync(x) result(res) - implicit none + implicit none class(psb_l_base_vect_type), intent(in) :: x logical :: res @@ -655,16 +655,16 @@ contains ! - ! Size info. + ! Size info. ! ! !> Function base_get_nrows !! \memberof psb_l_base_vect_type !! \brief Number of entries - !! + !! ! function l_base_get_nrows(x) result(res) - implicit none + implicit none class(psb_l_base_vect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -677,13 +677,13 @@ contains !> Function base_get_sizeof !! \memberof psb_l_base_vect_type !! \brief Size in bytes - !! + !! ! function l_base_sizeof(x) result(res) - implicit none + implicit none class(psb_l_base_vect_type), intent(in) :: x integer(psb_epk_) :: res - + ! Force 8-byte integers. res = (1_psb_epk_ * psb_sizeof_lp) * x%get_nrows() @@ -693,14 +693,14 @@ contains !> Function base_get_fmt !! \memberof psb_l_base_vect_type !! \brief Format - !! + !! ! function l_base_get_fmt() result(res) - implicit none + implicit none character(len=5) :: res res = 'BASE' end function l_base_get_fmt - + ! ! @@ -709,7 +709,7 @@ contains !! \memberof psb_l_base_vect_type !! \brief Extract a copy of the contents !! - ! + ! function l_base_get_vect(x,n) result(res) class(psb_l_base_vect_type), intent(inout) :: x integer(psb_lpk_), allocatable :: res(:) @@ -717,21 +717,21 @@ contains integer(psb_ipk_), optional :: n ! Local variables integer(psb_ipk_) :: isz - - if (.not.allocated(x%v)) return + + if (.not.allocated(x%v)) return if (.not.x%is_host()) call x%sync() isz = x%get_nrows() if (present(n)) isz = max(0,min(isz,n)) - allocate(res(isz),stat=info) - if (info /= 0) then + allocate(res(isz),stat=info) + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_get_vect') return end if res(1:isz) = x%v(1:isz) end function l_base_get_vect - + ! - ! Reset all values + ! Reset all values ! ! !> Function base_set_scal @@ -740,18 +740,18 @@ contains !! \param val The value to set !! subroutine l_base_set_scal(x,val,first,last) - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x integer(psb_lpk_), intent(in) :: val integer(psb_ipk_), optional :: first, last - + integer(psb_ipk_) :: info, first_, last_ first_=1 last_=size(x%v) if (present(first)) first_ = max(1,first) if (present(last)) last_ = min(last,last_) - + if (x%is_dev()) call x%sync() x%v(first_:last_) = val call x%set_host() @@ -763,14 +763,14 @@ contains !> Function base_set_vect !! \memberof psb_l_base_vect_type !! \brief Set all entries - !! \param val(:) The vector to be copied in + !! \param val(:) The vector to be copied in !! subroutine l_base_set_vect(x,val,first,last) - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x integer(psb_lpk_), intent(in) :: val(:) integer(psb_ipk_), optional :: first, last - + integer(psb_ipk_) :: info, first_, last_, nr first_ = 1 @@ -778,7 +778,7 @@ contains last_ = min(psb_size(x%v),first_+size(val)-1) if (present(last)) last_ = min(last,last_) - if (allocated(x%v)) then + if (allocated(x%v)) then if (x%is_dev()) call x%sync() x%v(first_:last_) = val(1:last_-first_+1) else @@ -789,8 +789,8 @@ contains end subroutine l_base_set_vect - - + + ! ! Gather: Y = beta * Y + alpha * X(IDX(:)) ! @@ -805,18 +805,18 @@ contains !! \param beta subroutine l_base_gthab(n,idx,alpha,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_lpk_) :: alpha, beta, y(:) class(psb_l_base_vect_type) :: x - + if (x%is_dev()) call x%sync() call psi_gth(n,idx,alpha,x%v,beta,y) end subroutine l_base_gthab ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_gthzv !! \memberof psb_l_base_vect_type !! \brief gather into an array special alpha=1 beta=0 @@ -825,28 +825,28 @@ contains !! \param idx(:) indices subroutine l_base_gthzv_x(i,n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx integer(psb_lpk_) :: y(:) class(psb_l_base_vect_type) :: x - + if (idx%is_dev()) call idx%sync() call x%gth(n,idx%v(i:),y) end subroutine l_base_gthzv_x ! - ! New comm internals impl. + ! New comm internals impl. ! subroutine l_base_gthzbuf(i,n,idx,x) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx class(psb_l_base_vect_type) :: x - - if (.not.allocated(x%combuf)) then + + if (.not.allocated(x%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf') return end if @@ -859,22 +859,22 @@ contains !> Function base_device_wait: !! \memberof psb_l_base_vect_type !! \brief device_wait: base version is a no-op. - !! + !! ! subroutine l_base_device_wait() - implicit none - + implicit none + end subroutine l_base_device_wait function l_base_use_buffer() result(res) logical :: res - + res = .true. end function l_base_use_buffer subroutine l_base_new_buffer(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -884,7 +884,7 @@ contains subroutine l_base_new_comid(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_l_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -895,7 +895,7 @@ contains ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_gthzv !! \memberof psb_l_base_vect_type !! \brief gather into an array special alpha=1 beta=0 @@ -904,20 +904,20 @@ contains !! \param idx(:) indices subroutine l_base_gthzv(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_lpk_) :: y(:) class(psb_l_base_vect_type) :: x - + if (x%is_dev()) call x%sync() call psi_gth(n,idx,x%v,y) end subroutine l_base_gthzv ! - ! Scatter: + ! Scatter: ! Y(IDX(:)) = beta*Y(IDX(:)) + X(:) - ! + ! ! !> Function base_sctb !! \memberof psb_l_base_vect_type @@ -926,14 +926,14 @@ contains !! \param n how many entries to consider !! \param idx(:) indices !! \param beta - !! \param x(:) + !! \param x(:) subroutine l_base_sctb(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_lpk_) :: beta, x(:) class(psb_l_base_vect_type) :: y - + if (y%is_dev()) call y%sync() call psi_sct(n,idx,x,beta,y%v) call y%set_host() @@ -942,12 +942,12 @@ contains subroutine l_base_sctb_x(i,n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx integer(psb_lpk_) :: beta, x(:) class(psb_l_base_vect_type) :: y - + if (idx%is_dev()) call idx%sync() call y%sct(n,idx%v(i:),x,beta) call y%set_host() @@ -956,14 +956,14 @@ contains subroutine l_base_sctb_buf(i,n,idx,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx integer(psb_lpk_) :: beta class(psb_l_base_vect_type) :: y - - - if (.not.allocated(y%combuf)) then + + + if (.not.allocated(y%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf') return end if @@ -988,22 +988,22 @@ module psb_l_base_multivect_mod use psb_l_base_vect_mod !> \namespace psb_base_mod \class psb_l_base_vect_type - !! The psb_l_base_vect_type + !! The psb_l_base_vect_type !! defines a middle level integer(psb_ipk_) encapsulated dense vector. - !! The encapsulation is needed, in place of a simple array, to allow + !! The encapsulation is needed, in place of a simple array, to allow !! for complicated situations, such as GPU programming, where the memory !! area we are interested in is not easily accessible from the host/Fortran !! side. It is also meant to be encapsulated in an outer type, to allow !! runtime switching as per the STATE design pattern, similar to the !! sparse matrix types. !! - private + private public :: psb_l_base_multivect, psb_l_base_multivect_type type psb_l_base_multivect_type - !> Values. + !> Values. integer(psb_lpk_), allocatable :: v(:,:) - integer(psb_lpk_), allocatable :: combuf(:) + integer(psb_lpk_), allocatable :: combuf(:) integer(psb_mpk_), allocatable :: comid(:,:) contains ! @@ -1017,7 +1017,7 @@ module psb_l_base_multivect_mod ! ! Insert/set. Assembly and free. ! Assembly does almost nothing here, but is important - ! in derived classes. + ! in derived classes. ! procedure, pass(x) :: ins => l_base_mlv_ins procedure, pass(x) :: zero => l_base_mlv_zero @@ -1028,7 +1028,7 @@ module psb_l_base_multivect_mod ! Any derived class having extra storage upon sync ! will guarantee that both fortran/host side and ! external side contain the same data. The base - ! version is only a placeholder. + ! version is only a placeholder. ! procedure, pass(x) :: sync => l_base_mlv_sync procedure, pass(x) :: is_host => l_base_mlv_is_host @@ -1068,7 +1068,7 @@ module psb_l_base_multivect_mod ! ! Gather/scatter. These are needed for MPI interfacing. - ! May have to be reworked. + ! May have to be reworked. ! procedure, pass(x) :: gthab => l_base_mlv_gthab procedure, pass(x) :: gthzv => l_base_mlv_gthzv @@ -1090,7 +1090,7 @@ module psb_l_base_multivect_mod contains ! - ! Constructors. + ! Constructors. ! !> Function constructor: @@ -1109,7 +1109,7 @@ contains !> Function constructor: !! \brief Constructor from size - !! \param n Size of vector to be built. + !! \param n Size of vector to be built. !! function size_const(m,n) result(this) integer(psb_ipk_), intent(in) :: m,n @@ -1136,7 +1136,7 @@ contains integer(psb_ipk_) :: info call psb_realloc(size(this,1),size(this,2),x%v,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_mlv_vect_bld') return end if @@ -1151,7 +1151,7 @@ contains !> Function bld_n: !! \memberof psb_l_base_multivect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine l_base_mlv_bld_n(x,m,n) use psb_realloc_mod @@ -1168,13 +1168,13 @@ contains !! \memberof psb_l_base_multivect_type !! \brief Build method with size (uninitialized data) and !! allocation return code. - !! \param n size to be allocated. + !! \param n size to be allocated. !! \param info return code !! subroutine l_base_mlv_all(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_l_base_multivect_type), intent(out) :: x integer(psb_ipk_), intent(out) :: info @@ -1192,7 +1192,7 @@ contains subroutine l_base_mlv_mold(x, y, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_l_base_multivect_type), intent(in) :: x class(psb_l_base_multivect_type), intent(out), allocatable :: y integer(psb_ipk_), intent(out) :: info @@ -1206,21 +1206,21 @@ contains ! !> Function base_mlv_ins: !! \memberof psb_l_base_multivect_type - !! \brief Insert coefficients. + !! \brief Insert coefficients. !! !! !! Given a list of N pairs !! (IRL(i),VAL(i)) !! record a new coefficient in X such that !! X(IRL(1:N)) = VAL(1:N). - !! + !! !! - the update operation will perform either !! X(IRL(1:n)) = VAL(1:N) !! or !! X(IRL(1:n)) = X(IRL(1:n))+VAL(1:N) !! according to the value of DUPLICATE. - !! - !! + !! + !! !! \param n number of pairs in input !! \param irl(:) the input row indices !! \param val(:) the input coefficients @@ -1230,7 +1230,7 @@ contains ! subroutine l_base_mlv_ins(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -1240,21 +1240,21 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ - else if (n > min(size(irl),size(val))) then + else if (n > min(size(irl),size(val))) then info = psb_err_invalid_input_ - else + else isz = size(x%v,1) - select case(dupl) - case(psb_dupl_ovwrt_) + select case(dupl) + case(psb_dupl_ovwrt_) do i = 1, n !loop over all val's rows - ! row actual block row + ! row actual block row if ((1 <= irl(i)).and.(irl(i) <= isz)) then ! this row belongs to me ! copy i-th row of block val in x @@ -1262,7 +1262,7 @@ contains end if enddo - case(psb_dupl_add_) + case(psb_dupl_add_) do i = 1, n !loop over all val's rows @@ -1279,7 +1279,7 @@ contains ! !$ goto 9999 end select end if - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_mlv_vect_ins') return end if @@ -1294,7 +1294,7 @@ contains ! subroutine l_base_mlv_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x if (allocated(x%v)) x%v=lzero @@ -1310,7 +1310,7 @@ contains !> Function base_mlv_asb: !! \memberof psb_l_base_multivect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! @@ -1319,7 +1319,7 @@ contains subroutine l_base_mlv_asb(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_l_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1336,20 +1336,20 @@ contains !> Function base_mlv_free: !! \memberof psb_l_base_multivect_type !! \brief Free vector - !! + !! !! \param info return code !! ! subroutine l_base_mlv_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 if (allocated(x%v)) deallocate(x%v, stat=info) - if (info /= 0) call & + if (info /= 0) call & & psb_errpush(psb_err_alloc_dealloc_,'vect_free') end subroutine l_base_mlv_free @@ -1359,15 +1359,15 @@ contains ! ! The base version of SYNC & friends does nothing, it's just ! a placeholder. - ! + ! ! !> Function base_mlv_sync: !! \memberof psb_l_base_multivect_type !! \brief Sync: base version is a no-op. - !! + !! ! subroutine l_base_mlv_sync(x) - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x end subroutine l_base_mlv_sync @@ -1376,10 +1376,10 @@ contains !> Function base_mlv_set_host: !! \memberof psb_l_base_multivect_type !! \brief Set_host: base version is a no-op. - !! + !! ! subroutine l_base_mlv_set_host(x) - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x end subroutine l_base_mlv_set_host @@ -1388,10 +1388,10 @@ contains !> Function base_mlv_set_dev: !! \memberof psb_l_base_multivect_type !! \brief Set_dev: base version is a no-op. - !! + !! ! subroutine l_base_mlv_set_dev(x) - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x end subroutine l_base_mlv_set_dev @@ -1400,10 +1400,10 @@ contains !> Function base_mlv_set_sync: !! \memberof psb_l_base_multivect_type !! \brief Set_sync: base version is a no-op. - !! + !! ! subroutine l_base_mlv_set_sync(x) - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x end subroutine l_base_mlv_set_sync @@ -1412,10 +1412,10 @@ contains !> Function base_mlv_is_dev: !! \memberof psb_l_base_multivect_type !! \brief Is vector on external device . - !! + !! ! function l_base_mlv_is_dev(x) result(res) - implicit none + implicit none class(psb_l_base_multivect_type), intent(in) :: x logical :: res @@ -1426,10 +1426,10 @@ contains !> Function base_mlv_is_host !! \memberof psb_l_base_multivect_type !! \brief Is vector on standard memory . - !! + !! ! function l_base_mlv_is_host(x) result(res) - implicit none + implicit none class(psb_l_base_multivect_type), intent(in) :: x logical :: res @@ -1440,10 +1440,10 @@ contains !> Function base_mlv_is_sync !! \memberof psb_l_base_multivect_type !! \brief Is vector on sync . - !! + !! ! function l_base_mlv_is_sync(x) result(res) - implicit none + implicit none class(psb_l_base_multivect_type), intent(in) :: x logical :: res @@ -1452,16 +1452,16 @@ contains ! - ! Size info. + ! Size info. ! ! !> Function base_mlv_get_nrows !! \memberof psb_l_base_multivect_type !! \brief Number of entries - !! + !! ! function l_base_mlv_get_nrows(x) result(res) - implicit none + implicit none class(psb_l_base_multivect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -1471,7 +1471,7 @@ contains end function l_base_mlv_get_nrows function l_base_mlv_get_ncols(x) result(res) - implicit none + implicit none class(psb_l_base_multivect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -1484,10 +1484,10 @@ contains !> Function base_mlv_get_sizeof !! \memberof psb_l_base_multivect_type !! \brief Size in bytesa - !! + !! ! function l_base_mlv_sizeof(x) result(res) - implicit none + implicit none class(psb_l_base_multivect_type), intent(in) :: x integer(psb_epk_) :: res @@ -1500,10 +1500,10 @@ contains !> Function base_mlv_get_fmt !! \memberof psb_l_base_multivect_type !! \brief Format - !! + !! ! function l_base_mlv_get_fmt() result(res) - implicit none + implicit none character(len=5) :: res res = 'BASE' end function l_base_mlv_get_fmt @@ -1516,18 +1516,18 @@ contains !! \memberof psb_l_base_multivect_type !! \brief Extract a copy of the contents !! - ! + ! function l_base_mlv_get_vect(x) result(res) - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x integer(psb_lpk_), allocatable :: res(:,:) integer(psb_ipk_) :: info,m,n m = x%get_nrows() n = x%get_ncols() - if (.not.allocated(x%v)) return + if (.not.allocated(x%v)) return call x%sync() - allocate(res(m,n),stat=info) - if (info /= 0) then + allocate(res(m,n),stat=info) + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_mlv_get_vect') return end if @@ -1535,7 +1535,7 @@ contains end function l_base_mlv_get_vect ! - ! Reset all values + ! Reset all values ! ! !> Function base_mlv_set_scal @@ -1544,7 +1544,7 @@ contains !! \param val The value to set !! subroutine l_base_mlv_set_scal(x,val) - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x integer(psb_lpk_), intent(in) :: val @@ -1557,16 +1557,16 @@ contains !> Function base_mlv_set_vect !! \memberof psb_l_base_multivect_type !! \brief Set all entries - !! \param val(:) The vector to be copied in + !! \param val(:) The vector to be copied in !! subroutine l_base_mlv_set_vect(x,val) - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x integer(psb_lpk_), intent(in) :: val(:,:) integer(psb_ipk_) :: nr, nc integer(psb_ipk_) :: info - if (allocated(x%v)) then + if (allocated(x%v)) then nr = min(size(x%v,1),size(val,1)) nc = min(size(x%v,2),size(val,2)) @@ -1579,15 +1579,15 @@ contains function l_base_mlv_use_buffer() result(res) - implicit none + implicit none logical :: res - + res = .true. end function l_base_mlv_use_buffer subroutine l_base_mlv_new_buffer(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -1599,7 +1599,7 @@ contains subroutine l_base_mlv_new_comid(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -1610,12 +1610,12 @@ contains subroutine l_base_mlv_maybe_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (psb_get_maybe_free_buffer())& & call x%free_buffer(info) @@ -1623,7 +1623,7 @@ contains subroutine l_base_mlv_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1633,7 +1633,7 @@ contains subroutine l_base_mlv_free_comid(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_l_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1656,7 +1656,7 @@ contains !! \param beta subroutine l_base_mlv_gthab(n,idx,alpha,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_lpk_) :: alpha, beta, y(:) class(psb_l_base_multivect_type) :: x @@ -1672,7 +1672,7 @@ contains end subroutine l_base_mlv_gthab ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_l_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1681,7 +1681,7 @@ contains !! \param idx(:) indices subroutine l_base_mlv_gthzv_x(i,n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx integer(psb_lpk_) :: y(:) @@ -1694,7 +1694,7 @@ contains ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_l_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1703,7 +1703,7 @@ contains !! \param idx(:) indices subroutine l_base_mlv_gthzv(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_lpk_) :: y(:) class(psb_l_base_multivect_type) :: x @@ -1720,7 +1720,7 @@ contains end subroutine l_base_mlv_gthzv ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_l_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1729,7 +1729,7 @@ contains !! \param idx(:) indices subroutine l_base_mlv_gthzm(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_lpk_) :: y(:,:) class(psb_l_base_multivect_type) :: x @@ -1746,17 +1746,17 @@ contains end subroutine l_base_mlv_gthzm ! - ! New comm internals impl. + ! New comm internals impl. ! subroutine l_base_mlv_gthzbuf(i,ixb,n,idx,x) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, ixb, n class(psb_i_base_vect_type) :: idx class(psb_l_base_multivect_type) :: x integer(psb_ipk_) :: nc - - if (.not.allocated(x%combuf)) then + + if (.not.allocated(x%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf') return end if @@ -1768,9 +1768,9 @@ contains end subroutine l_base_mlv_gthzbuf ! - ! Scatter: + ! Scatter: ! Y(IDX(:),:) = beta*Y(IDX(:),:) + X(:) - ! + ! ! !> Function base_mlv_sctb !! \memberof psb_l_base_multivect_type @@ -1779,10 +1779,10 @@ contains !! \param n how many entries to consider !! \param idx(:) indices !! \param beta - !! \param x(:) + !! \param x(:) subroutine l_base_mlv_sctb(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_lpk_) :: beta, x(:) class(psb_l_base_multivect_type) :: y @@ -1797,7 +1797,7 @@ contains subroutine l_base_mlv_sctbr2(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) integer(psb_lpk_) :: beta, x(:,:) class(psb_l_base_multivect_type) :: y @@ -1812,7 +1812,7 @@ contains subroutine l_base_mlv_sctb_x(i,n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx integer( psb_lpk_) :: beta, x(:) @@ -1824,14 +1824,14 @@ contains subroutine l_base_mlv_sctb_buf(i,iyb,n,idx,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, iyb, n class(psb_i_base_vect_type) :: idx integer(psb_lpk_) :: beta class(psb_l_base_multivect_type) :: y integer(psb_ipk_) :: nc - - if (.not.allocated(y%combuf)) then + + if (.not.allocated(y%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf') return end if @@ -1840,19 +1840,18 @@ contains nc = y%get_ncols() call y%sct(n,idx%v(i:),y%combuf(iyb:),beta) call y%set_host() - + end subroutine l_base_mlv_sctb_buf ! !> Function base_device_wait: !! \memberof psb_l_base_vect_type !! \brief device_wait: base version is a no-op. - !! + !! ! subroutine l_base_mlv_device_wait() - implicit none - + implicit none + end subroutine l_base_mlv_device_wait end module psb_l_base_multivect_mod - diff --git a/base/modules/serial/psb_l_vect_mod.F90 b/base/modules/serial/psb_l_vect_mod.F90 index 5d0369d6d..ece6ee668 100644 --- a/base/modules/serial/psb_l_vect_mod.F90 +++ b/base/modules/serial/psb_l_vect_mod.F90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,15 +27,15 @@ ! 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. -! -! +! +! ! ! package: psb_l_vect_mod ! ! This module contains the definition of the psb_l_vect type which ! is the outer container for dense vectors. ! Therefore all methods simply invoke the corresponding methods of the -! inner component. +! inner component. ! module psb_l_vect_mod @@ -43,7 +43,7 @@ module psb_l_vect_mod use psb_i_vect_mod type psb_l_vect_type - class(psb_l_base_vect_type), allocatable :: v + class(psb_l_base_vect_type), allocatable :: v contains procedure, pass(x) :: get_nrows => l_vect_get_nrows procedure, pass(x) :: sizeof => l_vect_sizeof @@ -115,11 +115,11 @@ module psb_l_vect_mod contains - subroutine psb_l_set_vect_default(v) - implicit none + subroutine psb_l_set_vect_default(v) + implicit none class(psb_l_base_vect_type), intent(in) :: v - if (allocated(psb_l_base_vect_default)) then + if (allocated(psb_l_base_vect_default)) then deallocate(psb_l_base_vect_default) end if allocate(psb_l_base_vect_default, mold=v) @@ -127,7 +127,7 @@ contains end subroutine psb_l_set_vect_default function psb_l_get_vect_default(v) result(res) - implicit none + implicit none class(psb_l_vect_type), intent(in) :: v class(psb_l_base_vect_type), pointer :: res @@ -137,10 +137,10 @@ contains function psb_l_get_base_vect_default() result(res) - implicit none + implicit none class(psb_l_base_vect_type), pointer :: res - if (.not.allocated(psb_l_base_vect_default)) then + if (.not.allocated(psb_l_base_vect_default)) then allocate(psb_l_base_vect_type :: psb_l_base_vect_default) end if @@ -150,14 +150,14 @@ contains subroutine l_vect_clone(x,y,info) - implicit none + implicit none class(psb_l_vect_type), intent(inout) :: x class(psb_l_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info info = psb_success_ call y%free(info) - if ((info==0).and.allocated(x%v)) then + if ((info==0).and.allocated(x%v)) then call y%bld(x%get_vect(),mold=x%v) end if end subroutine l_vect_clone @@ -172,7 +172,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_l_get_base_vect_default()) @@ -194,7 +194,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_l_get_base_vect_default()) @@ -215,7 +215,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_l_get_base_vect_default()) @@ -278,7 +278,7 @@ contains end function size_const function l_vect_get_nrows(x) result(res) - implicit none + implicit none class(psb_l_vect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -286,7 +286,7 @@ contains end function l_vect_get_nrows function l_vect_sizeof(x) result(res) - implicit none + implicit none class(psb_l_vect_type), intent(in) :: x integer(psb_epk_) :: res res = 0 @@ -294,7 +294,7 @@ contains end function l_vect_sizeof function l_vect_get_fmt(x) result(res) - implicit none + implicit none class(psb_l_vect_type), intent(in) :: x character(len=5) :: res res = 'NULL' @@ -303,7 +303,7 @@ contains subroutine l_vect_all(n, x, info, mold) - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_l_vect_type), intent(inout) :: x class(psb_l_base_vect_type), intent(in), optional :: mold @@ -312,12 +312,12 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(psb_l_base_vect_type :: x%v,stat=info) endif - if (info == 0) then + if (info == 0) then call x%v%all(n,info) else info = psb_err_alloc_dealloc_ @@ -327,12 +327,12 @@ contains subroutine l_vect_reall(n, x, info) - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_l_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (.not.allocated(x%v)) & & call x%all(n,info) if (info == 0) & @@ -342,7 +342,7 @@ contains subroutine l_vect_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_l_vect_type), intent(inout) :: x if (allocated(x%v)) call x%v%zero() @@ -352,7 +352,7 @@ contains subroutine l_vect_asb(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_l_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -398,12 +398,12 @@ contains subroutine l_vect_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_l_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%free(info) if (info == 0) deallocate(x%v,stat=info) end if @@ -412,7 +412,7 @@ contains subroutine l_vect_ins_a(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_l_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -422,7 +422,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ return end if @@ -433,7 +433,7 @@ contains subroutine l_vect_ins_v(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_l_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl class(psb_i_vect_type), intent(inout) :: irl @@ -443,7 +443,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then + if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then info = psb_err_invalid_vect_state_ return end if @@ -461,12 +461,12 @@ contains integer(psb_ipk_) :: info info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(tmp,stat=info,mold=mold) else allocate(tmp,stat=info,mold=psb_l_get_base_vect_default()) end if - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%sync() if (info == psb_success_) call tmp%bld(x%v%v) call x%v%free(info) @@ -477,7 +477,7 @@ contains subroutine l_vect_sync(x) - implicit none + implicit none class(psb_l_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -486,7 +486,7 @@ contains end subroutine l_vect_sync subroutine l_vect_set_sync(x) - implicit none + implicit none class(psb_l_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -495,7 +495,7 @@ contains end subroutine l_vect_set_sync subroutine l_vect_set_host(x) - implicit none + implicit none class(psb_l_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -504,7 +504,7 @@ contains end subroutine l_vect_set_host subroutine l_vect_set_dev(x) - implicit none + implicit none class(psb_l_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -513,7 +513,7 @@ contains end subroutine l_vect_set_dev function l_vect_is_sync(x) result(res) - implicit none + implicit none logical :: res class(psb_l_vect_type), intent(inout) :: x @@ -524,7 +524,7 @@ contains end function l_vect_is_sync function l_vect_is_host(x) result(res) - implicit none + implicit none logical :: res class(psb_l_vect_type), intent(inout) :: x @@ -535,11 +535,11 @@ contains end function l_vect_is_host function l_vect_is_dev(x) result(res) - implicit none + implicit none logical :: res class(psb_l_vect_type), intent(inout) :: x - res = .false. + res = .false. if (allocated(x%v)) & & res = x%v%is_dev() @@ -560,7 +560,7 @@ module psb_l_multivect_mod !private type psb_l_multivect_type - class(psb_l_base_multivect_type), allocatable :: v + class(psb_l_base_multivect_type), allocatable :: v contains procedure, pass(x) :: get_nrows => l_vect_get_nrows procedure, pass(x) :: get_ncols => l_vect_get_ncols @@ -616,11 +616,11 @@ module psb_l_multivect_mod contains - subroutine psb_l_set_multivect_default(v) - implicit none + subroutine psb_l_set_multivect_default(v) + implicit none class(psb_l_base_multivect_type), intent(in) :: v - if (allocated(psb_l_base_multivect_default)) then + if (allocated(psb_l_base_multivect_default)) then deallocate(psb_l_base_multivect_default) end if allocate(psb_l_base_multivect_default, mold=v) @@ -628,7 +628,7 @@ contains end subroutine psb_l_set_multivect_default function psb_l_get_multivect_default(v) result(res) - implicit none + implicit none class(psb_l_multivect_type), intent(in) :: v class(psb_l_base_multivect_type), pointer :: res @@ -638,10 +638,10 @@ contains function psb_l_get_base_multivect_default() result(res) - implicit none + implicit none class(psb_l_base_multivect_type), pointer :: res - if (.not.allocated(psb_l_base_multivect_default)) then + if (.not.allocated(psb_l_base_multivect_default)) then allocate(psb_l_base_multivect_type :: psb_l_base_multivect_default) end if @@ -651,14 +651,14 @@ contains subroutine l_vect_clone(x,y,info) - implicit none + implicit none class(psb_l_multivect_type), intent(inout) :: x class(psb_l_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info info = psb_success_ call y%free(info) - if ((info==0).and.allocated(x%v)) then + if ((info==0).and.allocated(x%v)) then call y%bld(x%get_vect(),mold=x%v) end if end subroutine l_vect_clone @@ -671,7 +671,7 @@ contains class(psb_l_base_multivect_type), pointer :: mld info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_l_get_base_multivect_default()) @@ -689,7 +689,7 @@ contains integer(psb_ipk_) :: info info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_l_get_base_multivect_default()) @@ -749,7 +749,7 @@ contains end function size_const function l_vect_get_nrows(x) result(res) - implicit none + implicit none class(psb_l_multivect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -757,7 +757,7 @@ contains end function l_vect_get_nrows function l_vect_get_ncols(x) result(res) - implicit none + implicit none class(psb_l_multivect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -765,7 +765,7 @@ contains end function l_vect_get_ncols function l_vect_sizeof(x) result(res) - implicit none + implicit none class(psb_l_multivect_type), intent(in) :: x integer(psb_epk_) :: res res = 0 @@ -773,7 +773,7 @@ contains end function l_vect_sizeof function l_vect_get_fmt(x) result(res) - implicit none + implicit none class(psb_l_multivect_type), intent(in) :: x character(len=5) :: res res = 'NULL' @@ -782,18 +782,18 @@ contains subroutine l_vect_all(m,n, x, info, mold) - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_l_multivect_type), intent(out) :: x class(psb_l_base_multivect_type), intent(in), optional :: mold integer(psb_ipk_), intent(out) :: info - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(psb_l_base_multivect_type :: x%v,stat=info) endif - if (info == 0) then + if (info == 0) then call x%v%all(m,n,info) else info = psb_err_alloc_dealloc_ @@ -803,12 +803,12 @@ contains subroutine l_vect_reall(m,n, x, info) - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_l_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (.not.allocated(x%v)) & & call x%all(m,n,info) if (info == 0) & @@ -818,7 +818,7 @@ contains subroutine l_vect_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_l_multivect_type), intent(inout) :: x if (allocated(x%v)) call x%v%zero() @@ -828,7 +828,7 @@ contains subroutine l_vect_asb(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_l_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -839,7 +839,7 @@ contains end subroutine l_vect_asb subroutine l_vect_sync(x) - implicit none + implicit none class(psb_l_multivect_type), intent(inout) :: x if (allocated(x%v)) & @@ -907,12 +907,12 @@ contains subroutine l_vect_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_l_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%free(info) if (info == 0) deallocate(x%v,stat=info) end if @@ -921,7 +921,7 @@ contains subroutine l_vect_ins(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_l_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -931,7 +931,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ return end if @@ -947,12 +947,12 @@ contains class(psb_l_base_multivect_type), allocatable :: tmp integer(psb_ipk_) :: info - if (present(mold)) then + if (present(mold)) then allocate(tmp,stat=info,mold=mold) else allocate(tmp,stat=info, mold=psb_l_get_base_multivect_default()) - endif - if (allocated(x%v)) then + endif + if (allocated(x%v)) then call x%v%sync() if (info == psb_success_) call tmp%bld(x%v%v) call x%v%free(info) diff --git a/base/modules/serial/psb_s_base_vect_mod.f90 b/base/modules/serial/psb_s_base_vect_mod.f90 index 2d716290b..a47d63775 100644 --- a/base/modules/serial/psb_s_base_vect_mod.f90 +++ b/base/modules/serial/psb_s_base_vect_mod.f90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,14 +27,14 @@ ! 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. -! -! +! +! ! ! package: psb_s_base_vect_mod ! ! This module contains the definition of the psb_s_base_vect type which ! is a container for dense vectors. -! This is encapsulated instead of being just a simple array to allow for +! This is encapsulated instead of being just a simple array to allow for ! more complicated situations, such as GPU programming, where the memory ! area we are interested in is not easily accessible from the host/Fortran ! side. It is also meant to be encapsulated in an outer type, to allow @@ -43,7 +43,7 @@ ! ! module psb_s_base_vect_mod - + use psb_const_mod use psb_error_mod use psb_realloc_mod @@ -51,9 +51,9 @@ module psb_s_base_vect_mod use psb_l_base_vect_mod !> \namespace psb_base_mod \class psb_s_base_vect_type - !! The psb_s_base_vect_type + !! The psb_s_base_vect_type !! defines a middle level real(psb_spk_) encapsulated dense vector. - !! The encapsulation is needed, in place of a simple array, to allow + !! The encapsulation is needed, in place of a simple array, to allow !! for complicated situations, such as GPU programming, where the memory !! area we are interested in is not easily accessible from the host/Fortran !! side. It is also meant to be encapsulated in an outer type, to allow @@ -61,9 +61,9 @@ module psb_s_base_vect_mod !! sparse matrix types. !! type psb_s_base_vect_type - !> Values. + !> Values. real(psb_spk_), allocatable :: v(:) - real(psb_spk_), allocatable :: combuf(:) + real(psb_spk_), allocatable :: combuf(:) integer(psb_mpk_), allocatable :: comid(:,:) contains ! @@ -78,7 +78,7 @@ module psb_s_base_vect_mod ! ! Insert/set. Assembly and free. ! Assembly does almost nothing here, but is important - ! in derived classes. + ! in derived classes. ! procedure, pass(x) :: ins_a => s_base_ins_a procedure, pass(x) :: ins_v => s_base_ins_v @@ -93,7 +93,7 @@ module psb_s_base_vect_mod ! Any derived class having extra storage upon sync ! will guarantee that both fortran/host side and ! external side contain the same data. The base - ! version is only a placeholder. + ! version is only a placeholder. ! procedure, pass(x) :: sync => s_base_sync procedure, pass(x) :: is_host => s_base_is_host @@ -130,7 +130,7 @@ module psb_s_base_vect_mod generic, public :: set => set_vect, set_scal ! ! Gather/scatter. These are needed for MPI interfacing. - ! May have to be reworked. + ! May have to be reworked. ! procedure, pass(x) :: gthab => s_base_gthab procedure, pass(x) :: gthzv => s_base_gthzv @@ -164,6 +164,12 @@ module psb_s_base_vect_mod procedure, pass(z) :: mlt_av => s_base_mlt_av generic, public :: mlt => mlt_v, mlt_a, mlt_a_2, mlt_v_2, mlt_av, mlt_va ! + ! Vector-Vector operations + ! + procedure, pass(x) :: div_v => s_base_div_v + procedure, pass(z) :: div_a2 => s_base_div_a2 + generic, public :: div => div_v, div_a2 + ! ! Scaling and norms ! procedure, pass(x) :: scal => s_base_scal @@ -183,11 +189,11 @@ module psb_s_base_vect_mod end interface psb_s_base_vect contains - + ! - ! Constructors. + ! Constructors. ! - + !> Function constructor: !! \brief Constructor from an array !! \param x(:) input array to be copied @@ -200,11 +206,11 @@ contains this%v = x call this%asb(size(x,kind=psb_ipk_),info) end function constructor - - + + !> Function constructor: !! \brief Constructor from size - !! \param n Size of vector to be built. + !! \param n Size of vector to be built. !! function size_const(n) result(this) integer(psb_ipk_), intent(in) :: n @@ -214,7 +220,7 @@ contains call this%asb(n,info) end function size_const - + ! ! Build from a sample ! @@ -226,20 +232,20 @@ contains !! subroutine s_base_bld_x(x,this) use psb_realloc_mod - implicit none + implicit none real(psb_spk_), intent(in) :: this(:) class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info call psb_realloc(size(this),x%v,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_vect_bld') return end if x%v(:) = this(:) end subroutine s_base_bld_x - + ! ! Create with size, but no initialization ! @@ -247,11 +253,11 @@ contains !> Function bld_mn: !! \memberof psb_s_base_vect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine s_base_bld_mn(x,n) use psb_realloc_mod - implicit none + implicit none integer(psb_mpk_), intent(in) :: n class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info @@ -260,15 +266,15 @@ contains call x%asb(n,info) end subroutine s_base_bld_mn - + !> Function bld_en: !! \memberof psb_s_base_vect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine s_base_bld_en(x,n) use psb_realloc_mod - implicit none + implicit none integer(psb_epk_), intent(in) :: n class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info @@ -277,24 +283,24 @@ contains call x%asb(n,info) end subroutine s_base_bld_en - + !> Function base_all: !! \memberof psb_s_base_vect_type !! \brief Build method with size (uninitialized data) and !! allocation return code. - !! \param n size to be allocated. + !! \param n size to be allocated. !! \param info return code !! subroutine s_base_all(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_s_base_vect_type), intent(out) :: x integer(psb_ipk_), intent(out) :: info - + call psb_realloc(n,x%v,info) - + end subroutine s_base_all !> Function base_mold: @@ -306,11 +312,11 @@ contains subroutine s_base_mold(x, y, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(in) :: x class(psb_s_base_vect_type), intent(out), allocatable :: y integer(psb_ipk_), intent(out) :: info - + allocate(psb_s_base_vect_type :: y, stat=info) end subroutine s_base_mold @@ -320,21 +326,21 @@ contains ! !> Function base_ins: !! \memberof psb_s_base_vect_type - !! \brief Insert coefficients. + !! \brief Insert coefficients. !! !! !! Given a list of N pairs !! (IRL(i),VAL(i)) !! record a new coefficient in X such that !! X(IRL(1:N)) = VAL(1:N). - !! + !! !! - the update operation will perform either !! X(IRL(1:n)) = VAL(1:N) !! or !! X(IRL(1:n)) = X(IRL(1:n))+VAL(1:N) !! according to the value of DUPLICATE. - !! - !! + !! + !! !! \param n number of pairs in input !! \param irl(:) the input row indices !! \param val(:) the input coefficients @@ -344,7 +350,7 @@ contains ! subroutine s_base_ins_a(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -354,21 +360,21 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ - else if (n > min(size(irl),size(val))) then + else if (n > min(size(irl),size(val))) then info = psb_err_invalid_input_ - else + else isz = size(x%v) - select case(dupl) - case(psb_dupl_ovwrt_) + select case(dupl) + case(psb_dupl_ovwrt_) do i = 1, n !loop over all val's rows - ! row actual block row + ! row actual block row if ((1 <= irl(i)).and.(irl(i) <= isz)) then ! this row belongs to me ! copy i-th row of block val in x @@ -376,7 +382,7 @@ contains end if enddo - case(psb_dupl_add_) + case(psb_dupl_add_) do i = 1, n !loop over all val's rows @@ -394,7 +400,7 @@ contains end select end if call x%set_host() - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_vect_ins') return end if @@ -403,7 +409,7 @@ contains subroutine s_base_ins_v(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl class(psb_i_base_vect_type), intent(inout) :: irl @@ -413,14 +419,14 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return if (irl%is_dev()) call irl%sync() if (val%is_dev()) call val%sync() if (x%is_dev()) call x%sync() call x%ins(n,irl%v,val%v,dupl,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_vect_ins') return end if @@ -436,14 +442,14 @@ contains ! subroutine s_base_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x - + if (allocated(x%v)) x%v=szero call x%set_host() end subroutine s_base_zero - + ! ! Assembly. ! For derived classes: after this the vector @@ -452,20 +458,20 @@ contains !> Function base_asb: !! \memberof psb_s_base_vect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! ! - + subroutine s_base_asb_m(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_mpk_), intent(in) :: n class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (x%get_nrows() < n) & & call psb_realloc(n,x%v,info) @@ -482,20 +488,20 @@ contains !> Function base_asb: !! \memberof psb_s_base_vect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! ! - + subroutine s_base_asb_e(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_epk_), intent(in) :: n class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (x%get_nrows() < n) & & call psb_realloc(n,x%v,info) @@ -508,39 +514,39 @@ contains !> Function base_free: !! \memberof psb_s_base_vect_type !! \brief Free vector - !! + !! !! \param info return code !! ! subroutine s_base_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (allocated(x%v)) deallocate(x%v, stat=info) if (info == 0) call x%free_buffer(info) if (info == 0) call x%free_comid(info) - if (info /= 0) call & + if (info /= 0) call & & psb_errpush(psb_err_alloc_dealloc_,'vect_free') - + end subroutine s_base_free - + ! !> Function base_free_buffer: !! \memberof psb_s_base_vect_type !! \brief Free aux buffer - !! + !! !! \param info return code !! ! subroutine s_base_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -555,17 +561,17 @@ contains !! In some derived classes, e.g. GPU, !! does not really frees to avoid runtime !! costs - !! + !! !! \param info return code !! ! subroutine s_base_maybe_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (psb_get_maybe_free_buffer())& & call x%free_buffer(info) @@ -575,13 +581,13 @@ contains !> Function base_free_comid: !! \memberof psb_s_base_vect_type !! \brief Free aux MPI communication id buffer - !! + !! !! \param info return code !! ! subroutine s_base_free_comid(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -593,77 +599,77 @@ contains ! ! The base version of SYNC & friends does nothing, it's just ! a placeholder. - ! + ! ! !> Function base_sync: !! \memberof psb_s_base_vect_type !! \brief Sync: base version is a no-op. - !! + !! ! subroutine s_base_sync(x) - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x - + end subroutine s_base_sync ! !> Function base_set_host: !! \memberof psb_s_base_vect_type !! \brief Set_host: base version is a no-op. - !! + !! ! subroutine s_base_set_host(x) - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x - + end subroutine s_base_set_host ! !> Function base_set_dev: !! \memberof psb_s_base_vect_type !! \brief Set_dev: base version is a no-op. - !! + !! ! subroutine s_base_set_dev(x) - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x - + end subroutine s_base_set_dev ! !> Function base_set_sync: !! \memberof psb_s_base_vect_type !! \brief Set_sync: base version is a no-op. - !! + !! ! subroutine s_base_set_sync(x) - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x - + end subroutine s_base_set_sync ! !> Function base_is_dev: !! \memberof psb_s_base_vect_type !! \brief Is vector on external device . - !! + !! ! function s_base_is_dev(x) result(res) - implicit none + implicit none class(psb_s_base_vect_type), intent(in) :: x logical :: res - + res = .false. end function s_base_is_dev - + ! !> Function base_is_host !! \memberof psb_s_base_vect_type !! \brief Is vector on standard memory . - !! + !! ! function s_base_is_host(x) result(res) - implicit none + implicit none class(psb_s_base_vect_type), intent(in) :: x logical :: res @@ -674,10 +680,10 @@ contains !> Function base_is_sync !! \memberof psb_s_base_vect_type !! \brief Is vector on sync . - !! + !! ! function s_base_is_sync(x) result(res) - implicit none + implicit none class(psb_s_base_vect_type), intent(in) :: x logical :: res @@ -686,16 +692,16 @@ contains ! - ! Size info. + ! Size info. ! ! !> Function base_get_nrows !! \memberof psb_s_base_vect_type !! \brief Number of entries - !! + !! ! function s_base_get_nrows(x) result(res) - implicit none + implicit none class(psb_s_base_vect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -708,13 +714,13 @@ contains !> Function base_get_sizeof !! \memberof psb_s_base_vect_type !! \brief Size in bytes - !! + !! ! function s_base_sizeof(x) result(res) - implicit none + implicit none class(psb_s_base_vect_type), intent(in) :: x integer(psb_epk_) :: res - + ! Force 8-byte integers. res = (1_psb_epk_ * psb_sizeof_sp) * x%get_nrows() @@ -724,14 +730,14 @@ contains !> Function base_get_fmt !! \memberof psb_s_base_vect_type !! \brief Format - !! + !! ! function s_base_get_fmt() result(res) - implicit none + implicit none character(len=5) :: res res = 'BASE' end function s_base_get_fmt - + ! ! @@ -740,7 +746,7 @@ contains !! \memberof psb_s_base_vect_type !! \brief Extract a copy of the contents !! - ! + ! function s_base_get_vect(x,n) result(res) class(psb_s_base_vect_type), intent(inout) :: x real(psb_spk_), allocatable :: res(:) @@ -748,21 +754,21 @@ contains integer(psb_ipk_), optional :: n ! Local variables integer(psb_ipk_) :: isz - - if (.not.allocated(x%v)) return + + if (.not.allocated(x%v)) return if (.not.x%is_host()) call x%sync() isz = x%get_nrows() if (present(n)) isz = max(0,min(isz,n)) - allocate(res(isz),stat=info) - if (info /= 0) then + allocate(res(isz),stat=info) + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_get_vect') return end if res(1:isz) = x%v(1:isz) end function s_base_get_vect - + ! - ! Reset all values + ! Reset all values ! ! !> Function base_set_scal @@ -771,18 +777,18 @@ contains !! \param val The value to set !! subroutine s_base_set_scal(x,val,first,last) - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x real(psb_spk_), intent(in) :: val integer(psb_ipk_), optional :: first, last - + integer(psb_ipk_) :: info, first_, last_ first_=1 last_=size(x%v) if (present(first)) first_ = max(1,first) if (present(last)) last_ = min(last,last_) - + if (x%is_dev()) call x%sync() x%v(first_:last_) = val call x%set_host() @@ -794,14 +800,14 @@ contains !> Function base_set_vect !! \memberof psb_s_base_vect_type !! \brief Set all entries - !! \param val(:) The vector to be copied in + !! \param val(:) The vector to be copied in !! subroutine s_base_set_vect(x,val,first,last) - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x real(psb_spk_), intent(in) :: val(:) integer(psb_ipk_), optional :: first, last - + integer(psb_ipk_) :: info, first_, last_, nr first_ = 1 @@ -809,7 +815,7 @@ contains last_ = min(psb_size(x%v),first_+size(val)-1) if (present(last)) last_ = min(last,last_) - if (allocated(x%v)) then + if (allocated(x%v)) then if (x%is_dev()) call x%sync() x%v(first_:last_) = val(1:last_-first_+1) else @@ -829,7 +835,7 @@ contains !! \brief Set all entries to their respective absolute values. !! subroutine s_base_absval1(x) - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x if (allocated(x%v)) then @@ -841,21 +847,21 @@ contains end subroutine s_base_absval1 subroutine s_base_absval2(x,y) - implicit none - class(psb_s_base_vect_type), intent(inout) :: x + implicit none + class(psb_s_base_vect_type), intent(inout) :: x class(psb_s_base_vect_type), intent(inout) :: y integer(psb_ipk_) :: info if (.not.x%is_host()) call x%sync() - if (allocated(x%v)) then + if (allocated(x%v)) then call y%axpby(ione*min(x%get_nrows(),y%get_nrows()),sone,x,szero,info) call y%absval() end if - + end subroutine s_base_absval2 ! - ! Dot products - ! + ! Dot products + ! ! !> Function base_dot_v !! \memberof psb_s_base_vect_type @@ -864,12 +870,12 @@ contains !! \param y The other (base_vect) to be multiplied by !! function s_base_dot_v(n,x,y) result(res) - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x, y integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res real(psb_spk_), external :: sdot - + res = szero ! ! Note: this is the base implementation. @@ -898,19 +904,19 @@ contains !! \param y(:) The array to be multiplied by !! function s_base_dot_a(n,x,y) result(res) - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x real(psb_spk_), intent(in) :: y(:) integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res real(psb_spk_), external :: sdot - + res = sdot(n,y,1,x%v,1) end function s_base_dot_a - + ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! ! @@ -925,13 +931,13 @@ contains !! subroutine s_base_axpby_v(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m class(psb_s_base_vect_type), intent(inout) :: x class(psb_s_base_vect_type), intent(inout) :: y real(psb_spk_), intent (in) :: alpha, beta integer(psb_ipk_), intent(out) :: info - + if (x%is_dev()) call x%sync() call y%axpby(m,alpha,x%v,beta,info) @@ -939,7 +945,7 @@ contains end subroutine s_base_axpby_v ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! !> Function base_axpby_a @@ -953,20 +959,20 @@ contains !! subroutine s_base_axpby_a(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m real(psb_spk_), intent(in) :: x(:) class(psb_s_base_vect_type), intent(inout) :: y real(psb_spk_), intent (in) :: alpha, beta integer(psb_ipk_), intent(out) :: info - + if (y%is_dev()) call y%sync() call psb_geaxpby(m,alpha,x,beta,y%v,info) call y%set_host() - + end subroutine s_base_axpby_a - + ! ! Multiple variants of two operations: ! Simple multiplication Y(:) = X(:)*Y(:) @@ -984,10 +990,10 @@ contains !! subroutine s_base_mlt_v(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x class(psb_s_base_vect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -1005,7 +1011,7 @@ contains !! subroutine s_base_mlt_a(x, y, info) use psi_serial_mod - implicit none + implicit none real(psb_spk_), intent(in) :: x(:) class(psb_s_base_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -1014,7 +1020,7 @@ contains info = 0 if (y%is_dev()) call y%sync() n = min(size(y%v), size(x)) - do i=1, n + do i=1, n y%v(i) = y%v(i)*x(i) end do call y%set_host() @@ -1035,7 +1041,7 @@ contains !! subroutine s_base_mlt_a_2(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_spk_), intent(in) :: alpha,beta real(psb_spk_), intent(in) :: y(:) real(psb_spk_), intent(in) :: x(:) @@ -1043,58 +1049,58 @@ contains integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n - info = 0 + info = 0 if (z%is_dev()) call z%sync() n = min(size(z%v), size(x), size(y)) - if (alpha == szero) then - if (beta == sone) then - return + if (alpha == szero) then + if (beta == sone) then + return else do i=1, n z%v(i) = beta*z%v(i) end do end if else - if (alpha == sone) then - if (beta == szero) then - do i=1, n + if (alpha == sone) then + if (beta == szero) then + do i=1, n z%v(i) = y(i)*x(i) end do - else if (beta == sone) then - do i=1, n + else if (beta == sone) then + do i=1, n z%v(i) = z%v(i) + y(i)*x(i) end do - else - do i=1, n + else + do i=1, n z%v(i) = beta*z%v(i) + y(i)*x(i) end do end if - else if (alpha == -sone) then - if (beta == szero) then - do i=1, n + else if (alpha == -sone) then + if (beta == szero) then + do i=1, n z%v(i) = -y(i)*x(i) end do - else if (beta == sone) then - do i=1, n + else if (beta == sone) then + do i=1, n z%v(i) = z%v(i) - y(i)*x(i) end do - else - do i=1, n + else + do i=1, n z%v(i) = beta*z%v(i) - y(i)*x(i) end do end if else - if (beta == szero) then - do i=1, n + if (beta == szero) then + do i=1, n z%v(i) = alpha*y(i)*x(i) end do - else if (beta == sone) then - do i=1, n + else if (beta == sone) then + do i=1, n z%v(i) = z%v(i) + alpha*y(i)*x(i) end do - else - do i=1, n + else + do i=1, n z%v(i) = beta*z%v(i) + alpha*y(i)*x(i) end do end if @@ -1118,12 +1124,12 @@ contains subroutine s_base_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) use psi_serial_mod use psb_string_mod - implicit none + implicit none real(psb_spk_), intent(in) :: alpha,beta class(psb_s_base_vect_type), intent(inout) :: x class(psb_s_base_vect_type), intent(inout) :: y class(psb_s_base_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info character(len=1), intent(in), optional :: conjgx, conjgy integer(psb_ipk_) :: i, n logical :: conjgx_, conjgy_ @@ -1133,7 +1139,7 @@ contains if (x%is_dev()) call x%sync() if (.not.psb_s_is_complex_) then call z%mlt(alpha,x%v,y%v,beta,info) - else + else conjgx_=.false. if (present(conjgx)) conjgx_ = (psb_toupper(conjgx)=='C') conjgy_=.false. @@ -1148,12 +1154,12 @@ contains subroutine s_base_mlt_av(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_spk_), intent(in) :: alpha,beta real(psb_spk_), intent(in) :: x(:) class(psb_s_base_vect_type), intent(inout) :: y class(psb_s_base_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -1164,12 +1170,12 @@ contains subroutine s_base_mlt_va(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_spk_), intent(in) :: alpha,beta real(psb_spk_), intent(in) :: y(:) class(psb_s_base_vect_type), intent(inout) :: x class(psb_s_base_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -1177,10 +1183,57 @@ contains call z%mlt(alpha,y,x,beta,info) end subroutine s_base_mlt_va + ! + !> Function base_div_v + !! \memberof psb_s_base_vect_type + !! \brief Vector entry-by-entry divide by a vector x=x/y + !! \param y The array to be divided by + !! \param info return code + !! + subroutine s_base_div_v(x, y, info) + use psi_serial_mod + implicit none + class(psb_s_base_vect_type), intent(inout) :: x + class(psb_s_base_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (x%is_dev()) call x%sync() + call x%div(x%v,y%v,info) + + + end subroutine s_base_div_v + ! + !> Function base_div_a2 + !! \memberof psb_s_base_vect_type + !! \brief Entry-by-entry divide between normal array x=x/y + !! \param x(:) The array to be multiplied by + !! \param info return code + !! + subroutine s_base_div_a2(x, y, z, info) + use psi_serial_mod + implicit none + class(psb_s_base_vect_type), intent(inout) :: z + real(psb_spk_), intent(in) :: x(:) + real(psb_spk_), intent(in) :: y(:) + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (z%is_dev()) call z%sync() + + n = min(size(y), size(x)) + do i=1, n + z%v(i) = x(i)/y(i) + end do + + end subroutine s_base_div_a2 + ! - ! Simple scaling + ! Simple scaling ! !> Function base_scal !! \memberof psb_s_base_vect_type @@ -1189,17 +1242,17 @@ contains !! subroutine s_base_scal(alpha, x) use psi_serial_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x real(psb_spk_), intent (in) :: alpha - - if (allocated(x%v)) then + + if (allocated(x%v)) then x%v = alpha*x%v call x%set_host() end if end subroutine s_base_scal - + ! ! Norms 1, 2 and infinity ! @@ -1208,28 +1261,28 @@ contains !! \brief 2-norm |x(1:n)|_2 !! \param n how many entries to consider function s_base_nrm2(n,x) result(res) - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res real(psb_spk_), external :: snrm2 - + if (x%is_dev()) call x%sync() res = snrm2(n,x%v,1) end function s_base_nrm2 - + ! !> Function base_amax !! \memberof psb_s_base_vect_type !! \brief infinity-norm |x(1:n)|_\infty !! \param n how many entries to consider function s_base_amax(n,x) result(res) - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res - + if (x%is_dev()) call x%sync() res = maxval(abs(x%v(1:n))) @@ -1241,17 +1294,17 @@ contains !! \brief 1-norm |x(1:n)|_1 !! \param n how many entries to consider function s_base_asum(n,x) result(res) - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res - + if (x%is_dev()) call x%sync() res = sum(abs(x%v(1:n))) end function s_base_asum - - + + ! ! Gather: Y = beta * Y + alpha * X(IDX(:)) ! @@ -1266,18 +1319,18 @@ contains !! \param beta subroutine s_base_gthab(n,idx,alpha,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_spk_) :: alpha, beta, y(:) class(psb_s_base_vect_type) :: x - + if (x%is_dev()) call x%sync() call psi_gth(n,idx,alpha,x%v,beta,y) end subroutine s_base_gthab ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_gthzv !! \memberof psb_s_base_vect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1286,28 +1339,28 @@ contains !! \param idx(:) indices subroutine s_base_gthzv_x(i,n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx real(psb_spk_) :: y(:) class(psb_s_base_vect_type) :: x - + if (idx%is_dev()) call idx%sync() call x%gth(n,idx%v(i:),y) end subroutine s_base_gthzv_x ! - ! New comm internals impl. + ! New comm internals impl. ! subroutine s_base_gthzbuf(i,n,idx,x) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx class(psb_s_base_vect_type) :: x - - if (.not.allocated(x%combuf)) then + + if (.not.allocated(x%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf') return end if @@ -1320,22 +1373,22 @@ contains !> Function base_device_wait: !! \memberof psb_s_base_vect_type !! \brief device_wait: base version is a no-op. - !! + !! ! subroutine s_base_device_wait() - implicit none - + implicit none + end subroutine s_base_device_wait function s_base_use_buffer() result(res) logical :: res - + res = .true. end function s_base_use_buffer subroutine s_base_new_buffer(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -1345,7 +1398,7 @@ contains subroutine s_base_new_comid(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -1356,7 +1409,7 @@ contains ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_gthzv !! \memberof psb_s_base_vect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1365,20 +1418,20 @@ contains !! \param idx(:) indices subroutine s_base_gthzv(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_spk_) :: y(:) class(psb_s_base_vect_type) :: x - + if (x%is_dev()) call x%sync() call psi_gth(n,idx,x%v,y) end subroutine s_base_gthzv ! - ! Scatter: + ! Scatter: ! Y(IDX(:)) = beta*Y(IDX(:)) + X(:) - ! + ! ! !> Function base_sctb !! \memberof psb_s_base_vect_type @@ -1387,14 +1440,14 @@ contains !! \param n how many entries to consider !! \param idx(:) indices !! \param beta - !! \param x(:) + !! \param x(:) subroutine s_base_sctb(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_spk_) :: beta, x(:) class(psb_s_base_vect_type) :: y - + if (y%is_dev()) call y%sync() call psi_sct(n,idx,x,beta,y%v) call y%set_host() @@ -1403,12 +1456,12 @@ contains subroutine s_base_sctb_x(i,n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx real(psb_spk_) :: beta, x(:) class(psb_s_base_vect_type) :: y - + if (idx%is_dev()) call idx%sync() call y%sct(n,idx%v(i:),x,beta) call y%set_host() @@ -1417,14 +1470,14 @@ contains subroutine s_base_sctb_buf(i,n,idx,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx real(psb_spk_) :: beta class(psb_s_base_vect_type) :: y - - - if (.not.allocated(y%combuf)) then + + + if (.not.allocated(y%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf') return end if @@ -1449,22 +1502,22 @@ module psb_s_base_multivect_mod use psb_s_base_vect_mod !> \namespace psb_base_mod \class psb_s_base_vect_type - !! The psb_s_base_vect_type + !! The psb_s_base_vect_type !! defines a middle level integer(psb_ipk_) encapsulated dense vector. - !! The encapsulation is needed, in place of a simple array, to allow + !! The encapsulation is needed, in place of a simple array, to allow !! for complicated situations, such as GPU programming, where the memory !! area we are interested in is not easily accessible from the host/Fortran !! side. It is also meant to be encapsulated in an outer type, to allow !! runtime switching as per the STATE design pattern, similar to the !! sparse matrix types. !! - private + private public :: psb_s_base_multivect, psb_s_base_multivect_type type psb_s_base_multivect_type - !> Values. + !> Values. real(psb_spk_), allocatable :: v(:,:) - real(psb_spk_), allocatable :: combuf(:) + real(psb_spk_), allocatable :: combuf(:) integer(psb_mpk_), allocatable :: comid(:,:) contains ! @@ -1478,7 +1531,7 @@ module psb_s_base_multivect_mod ! ! Insert/set. Assembly and free. ! Assembly does almost nothing here, but is important - ! in derived classes. + ! in derived classes. ! procedure, pass(x) :: ins => s_base_mlv_ins procedure, pass(x) :: zero => s_base_mlv_zero @@ -1489,7 +1542,7 @@ module psb_s_base_multivect_mod ! Any derived class having extra storage upon sync ! will guarantee that both fortran/host side and ! external side contain the same data. The base - ! version is only a placeholder. + ! version is only a placeholder. ! procedure, pass(x) :: sync => s_base_mlv_sync procedure, pass(x) :: is_host => s_base_mlv_is_host @@ -1562,7 +1615,7 @@ module psb_s_base_multivect_mod ! ! Gather/scatter. These are needed for MPI interfacing. - ! May have to be reworked. + ! May have to be reworked. ! procedure, pass(x) :: gthab => s_base_mlv_gthab procedure, pass(x) :: gthzv => s_base_mlv_gthzv @@ -1584,7 +1637,7 @@ module psb_s_base_multivect_mod contains ! - ! Constructors. + ! Constructors. ! !> Function constructor: @@ -1603,7 +1656,7 @@ contains !> Function constructor: !! \brief Constructor from size - !! \param n Size of vector to be built. + !! \param n Size of vector to be built. !! function size_const(m,n) result(this) integer(psb_ipk_), intent(in) :: m,n @@ -1630,7 +1683,7 @@ contains integer(psb_ipk_) :: info call psb_realloc(size(this,1),size(this,2),x%v,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_mlv_vect_bld') return end if @@ -1645,7 +1698,7 @@ contains !> Function bld_n: !! \memberof psb_s_base_multivect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine s_base_mlv_bld_n(x,m,n) use psb_realloc_mod @@ -1662,13 +1715,13 @@ contains !! \memberof psb_s_base_multivect_type !! \brief Build method with size (uninitialized data) and !! allocation return code. - !! \param n size to be allocated. + !! \param n size to be allocated. !! \param info return code !! subroutine s_base_mlv_all(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_s_base_multivect_type), intent(out) :: x integer(psb_ipk_), intent(out) :: info @@ -1686,7 +1739,7 @@ contains subroutine s_base_mlv_mold(x, y, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_s_base_multivect_type), intent(in) :: x class(psb_s_base_multivect_type), intent(out), allocatable :: y integer(psb_ipk_), intent(out) :: info @@ -1700,21 +1753,21 @@ contains ! !> Function base_mlv_ins: !! \memberof psb_s_base_multivect_type - !! \brief Insert coefficients. + !! \brief Insert coefficients. !! !! !! Given a list of N pairs !! (IRL(i),VAL(i)) !! record a new coefficient in X such that !! X(IRL(1:N)) = VAL(1:N). - !! + !! !! - the update operation will perform either !! X(IRL(1:n)) = VAL(1:N) !! or !! X(IRL(1:n)) = X(IRL(1:n))+VAL(1:N) !! according to the value of DUPLICATE. - !! - !! + !! + !! !! \param n number of pairs in input !! \param irl(:) the input row indices !! \param val(:) the input coefficients @@ -1724,7 +1777,7 @@ contains ! subroutine s_base_mlv_ins(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -1734,21 +1787,21 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ - else if (n > min(size(irl),size(val))) then + else if (n > min(size(irl),size(val))) then info = psb_err_invalid_input_ - else + else isz = size(x%v,1) - select case(dupl) - case(psb_dupl_ovwrt_) + select case(dupl) + case(psb_dupl_ovwrt_) do i = 1, n !loop over all val's rows - ! row actual block row + ! row actual block row if ((1 <= irl(i)).and.(irl(i) <= isz)) then ! this row belongs to me ! copy i-th row of block val in x @@ -1756,7 +1809,7 @@ contains end if enddo - case(psb_dupl_add_) + case(psb_dupl_add_) do i = 1, n !loop over all val's rows @@ -1773,7 +1826,7 @@ contains ! !$ goto 9999 end select end if - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_mlv_vect_ins') return end if @@ -1788,7 +1841,7 @@ contains ! subroutine s_base_mlv_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x if (allocated(x%v)) x%v=szero @@ -1804,7 +1857,7 @@ contains !> Function base_mlv_asb: !! \memberof psb_s_base_multivect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! @@ -1813,7 +1866,7 @@ contains subroutine s_base_mlv_asb(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_s_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1830,20 +1883,20 @@ contains !> Function base_mlv_free: !! \memberof psb_s_base_multivect_type !! \brief Free vector - !! + !! !! \param info return code !! ! subroutine s_base_mlv_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 if (allocated(x%v)) deallocate(x%v, stat=info) - if (info /= 0) call & + if (info /= 0) call & & psb_errpush(psb_err_alloc_dealloc_,'vect_free') end subroutine s_base_mlv_free @@ -1853,15 +1906,15 @@ contains ! ! The base version of SYNC & friends does nothing, it's just ! a placeholder. - ! + ! ! !> Function base_mlv_sync: !! \memberof psb_s_base_multivect_type !! \brief Sync: base version is a no-op. - !! + !! ! subroutine s_base_mlv_sync(x) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x end subroutine s_base_mlv_sync @@ -1870,10 +1923,10 @@ contains !> Function base_mlv_set_host: !! \memberof psb_s_base_multivect_type !! \brief Set_host: base version is a no-op. - !! + !! ! subroutine s_base_mlv_set_host(x) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x end subroutine s_base_mlv_set_host @@ -1882,10 +1935,10 @@ contains !> Function base_mlv_set_dev: !! \memberof psb_s_base_multivect_type !! \brief Set_dev: base version is a no-op. - !! + !! ! subroutine s_base_mlv_set_dev(x) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x end subroutine s_base_mlv_set_dev @@ -1894,10 +1947,10 @@ contains !> Function base_mlv_set_sync: !! \memberof psb_s_base_multivect_type !! \brief Set_sync: base version is a no-op. - !! + !! ! subroutine s_base_mlv_set_sync(x) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x end subroutine s_base_mlv_set_sync @@ -1906,10 +1959,10 @@ contains !> Function base_mlv_is_dev: !! \memberof psb_s_base_multivect_type !! \brief Is vector on external device . - !! + !! ! function s_base_mlv_is_dev(x) result(res) - implicit none + implicit none class(psb_s_base_multivect_type), intent(in) :: x logical :: res @@ -1920,10 +1973,10 @@ contains !> Function base_mlv_is_host !! \memberof psb_s_base_multivect_type !! \brief Is vector on standard memory . - !! + !! ! function s_base_mlv_is_host(x) result(res) - implicit none + implicit none class(psb_s_base_multivect_type), intent(in) :: x logical :: res @@ -1934,10 +1987,10 @@ contains !> Function base_mlv_is_sync !! \memberof psb_s_base_multivect_type !! \brief Is vector on sync . - !! + !! ! function s_base_mlv_is_sync(x) result(res) - implicit none + implicit none class(psb_s_base_multivect_type), intent(in) :: x logical :: res @@ -1946,16 +1999,16 @@ contains ! - ! Size info. + ! Size info. ! ! !> Function base_mlv_get_nrows !! \memberof psb_s_base_multivect_type !! \brief Number of entries - !! + !! ! function s_base_mlv_get_nrows(x) result(res) - implicit none + implicit none class(psb_s_base_multivect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -1965,7 +2018,7 @@ contains end function s_base_mlv_get_nrows function s_base_mlv_get_ncols(x) result(res) - implicit none + implicit none class(psb_s_base_multivect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -1978,10 +2031,10 @@ contains !> Function base_mlv_get_sizeof !! \memberof psb_s_base_multivect_type !! \brief Size in bytesa - !! + !! ! function s_base_mlv_sizeof(x) result(res) - implicit none + implicit none class(psb_s_base_multivect_type), intent(in) :: x integer(psb_epk_) :: res @@ -1994,10 +2047,10 @@ contains !> Function base_mlv_get_fmt !! \memberof psb_s_base_multivect_type !! \brief Format - !! + !! ! function s_base_mlv_get_fmt() result(res) - implicit none + implicit none character(len=5) :: res res = 'BASE' end function s_base_mlv_get_fmt @@ -2010,18 +2063,18 @@ contains !! \memberof psb_s_base_multivect_type !! \brief Extract a copy of the contents !! - ! + ! function s_base_mlv_get_vect(x) result(res) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x real(psb_spk_), allocatable :: res(:,:) integer(psb_ipk_) :: info,m,n m = x%get_nrows() n = x%get_ncols() - if (.not.allocated(x%v)) return + if (.not.allocated(x%v)) return call x%sync() - allocate(res(m,n),stat=info) - if (info /= 0) then + allocate(res(m,n),stat=info) + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_mlv_get_vect') return end if @@ -2029,7 +2082,7 @@ contains end function s_base_mlv_get_vect ! - ! Reset all values + ! Reset all values ! ! !> Function base_mlv_set_scal @@ -2038,7 +2091,7 @@ contains !! \param val The value to set !! subroutine s_base_mlv_set_scal(x,val) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x real(psb_spk_), intent(in) :: val @@ -2051,16 +2104,16 @@ contains !> Function base_mlv_set_vect !! \memberof psb_s_base_multivect_type !! \brief Set all entries - !! \param val(:) The vector to be copied in + !! \param val(:) The vector to be copied in !! subroutine s_base_mlv_set_vect(x,val) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x real(psb_spk_), intent(in) :: val(:,:) integer(psb_ipk_) :: nr, nc integer(psb_ipk_) :: info - if (allocated(x%v)) then + if (allocated(x%v)) then nr = min(size(x%v,1),size(val,1)) nc = min(size(x%v,2),size(val,2)) @@ -2072,8 +2125,8 @@ contains end subroutine s_base_mlv_set_vect ! - ! Dot products - ! + ! Dot products + ! ! !> Function base_mlv_dot_v !! \memberof psb_s_base_multivect_type @@ -2082,7 +2135,7 @@ contains !! \param y The other (base_mlv_vect) to be multiplied by !! function s_base_mlv_dot_v(n,x,y) result(res) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x, y integer(psb_ipk_), intent(in) :: n real(psb_spk_), allocatable :: res(:) @@ -2094,7 +2147,7 @@ contains ! ! Note: this is the base implementation. ! When we get here, we are sure that X is of - ! TYPE psb_s_base_mlv_vect (or its class does not care). + ! TYPE psb_s_base_mlv_vect (or its class does not care). ! If Y is not, throw the burden on it, implicitly ! calling dot_a ! @@ -2123,7 +2176,7 @@ contains !! \param y(:) The array to be multiplied by !! function s_base_mlv_dot_a(n,x,y) result(res) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x real(psb_spk_), intent(in) :: y(:,:) integer(psb_ipk_), intent(in) :: n @@ -2141,7 +2194,7 @@ contains end function s_base_mlv_dot_a ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! ! @@ -2156,7 +2209,7 @@ contains !! subroutine s_base_mlv_axpby_v(m,alpha, x, beta, y, info, n) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m class(psb_s_base_multivect_type), intent(inout) :: x class(psb_s_base_multivect_type), intent(inout) :: y @@ -2180,7 +2233,7 @@ contains end subroutine s_base_mlv_axpby_v ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! !> Function base_mlv_axpby_a @@ -2194,7 +2247,7 @@ contains !! subroutine s_base_mlv_axpby_a(m,alpha, x, beta, y, info,n) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m real(psb_spk_), intent(in) :: x(:,:) class(psb_s_base_multivect_type), intent(inout) :: y @@ -2230,10 +2283,10 @@ contains !! subroutine s_base_mlv_mlt_mv(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x class(psb_s_base_multivect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info info = 0 if (x%is_dev()) call x%sync() @@ -2243,10 +2296,10 @@ contains subroutine s_base_mlv_mlt_mv_v(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_s_base_vect_type), intent(inout) :: x class(psb_s_base_multivect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info info = 0 if (x%is_dev()) call x%sync() @@ -2263,7 +2316,7 @@ contains !! subroutine s_base_mlv_mlt_ar1(x, y, info) use psi_serial_mod - implicit none + implicit none real(psb_spk_), intent(in) :: x(:) class(psb_s_base_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -2271,7 +2324,7 @@ contains info = 0 n = min(psb_size(y%v,1_psb_ipk_), size(x)) - do i=1, n + do i=1, n y%v(i,:) = y%v(i,:)*x(i) end do @@ -2286,7 +2339,7 @@ contains !! subroutine s_base_mlv_mlt_ar2(x, y, info) use psi_serial_mod - implicit none + implicit none real(psb_spk_), intent(in) :: x(:,:) class(psb_s_base_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -2313,7 +2366,7 @@ contains !! subroutine s_base_mlv_mlt_a_2(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_spk_), intent(in) :: alpha,beta real(psb_spk_), intent(in) :: y(:,:) real(psb_spk_), intent(in) :: x(:,:) @@ -2321,38 +2374,38 @@ contains integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, nr, nc - info = 0 + info = 0 nr = min(psb_size(z%v,1_psb_ipk_), size(x,1), size(y,1)) - nc = min(psb_size(z%v,2_psb_ipk_), size(x,2), size(y,2)) - if (alpha == szero) then - if (beta == sone) then - return + nc = min(psb_size(z%v,2_psb_ipk_), size(x,2), size(y,2)) + if (alpha == szero) then + if (beta == sone) then + return else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) end if else - if (alpha == sone) then - if (beta == szero) then + if (alpha == sone) then + if (beta == szero) then z%v(1:nr,1:nc) = y(1:nr,1:nc)*x(1:nr,1:nc) - else if (beta == sone) then + else if (beta == sone) then z%v(1:nr,1:nc) = z%v(1:nr,1:nc) + y(1:nr,1:nc)*x(1:nr,1:nc) - else + else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) + y(1:nr,1:nc)*x(1:nr,1:nc) end if - else if (alpha == -sone) then - if (beta == szero) then + else if (alpha == -sone) then + if (beta == szero) then z%v(1:nr,1:nc) = -y(1:nr,1:nc)*x(1:nr,1:nc) - else if (beta == sone) then + else if (beta == sone) then z%v(1:nr,1:nc) = z%v(1:nr,1:nc) - y(1:nr,1:nc)*x(1:nr,1:nc) - else + else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) - y(1:nr,1:nc)*x(1:nr,1:nc) end if else - if (beta == szero) then + if (beta == szero) then z%v(1:nr,1:nc) = alpha*y(1:nr,1:nc)*x(1:nr,1:nc) - else if (beta == sone) then + else if (beta == sone) then z%v(1:nr,1:nc) = z%v(1:nr,1:nc) + alpha*y(1:nr,1:nc)*x(1:nr,1:nc) - else + else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) + alpha*y(1:nr,1:nc)*x(1:nr,1:nc) end if end if @@ -2373,12 +2426,12 @@ contains subroutine s_base_mlv_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) use psi_serial_mod use psb_string_mod - implicit none + implicit none real(psb_spk_), intent(in) :: alpha,beta class(psb_s_base_multivect_type), intent(inout) :: x class(psb_s_base_multivect_type), intent(inout) :: y class(psb_s_base_multivect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info character(len=1), intent(in), optional :: conjgx, conjgy integer(psb_ipk_) :: i, n logical :: conjgx_, conjgy_ @@ -2389,7 +2442,7 @@ contains if (z%is_dev()) call z%sync() if (.not.psb_s_is_complex_) then call z%mlt(alpha,x%v,y%v,beta,info) - else + else conjgx_=.false. if (present(conjgx)) conjgx_ = (psb_toupper(conjgx)=='C') conjgy_=.false. @@ -2404,39 +2457,39 @@ contains !!$ !!$ subroutine s_base_mlv_mlt_av(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_spk_), intent(in) :: alpha,beta !!$ real(psb_spk_), intent(in) :: x(:) !!$ class(psb_s_base_multivect_type), intent(inout) :: y !!$ class(psb_s_base_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 -!!$ +!!$ !!$ call z%mlt(alpha,x,y%v,beta,info) !!$ !!$ end subroutine s_base_mlv_mlt_av !!$ !!$ subroutine s_base_mlv_mlt_va(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_spk_), intent(in) :: alpha,beta !!$ real(psb_spk_), intent(in) :: y(:) !!$ class(psb_s_base_multivect_type), intent(inout) :: x !!$ class(psb_s_base_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 -!!$ +!!$ !!$ call z%mlt(alpha,y,x,beta,info) !!$ !!$ end subroutine s_base_mlv_mlt_va !!$ !!$ ! - ! Simple scaling + ! Simple scaling ! !> Function base_mlv_scal !! \memberof psb_s_base_multivect_type @@ -2445,7 +2498,7 @@ contains !! subroutine s_base_mlv_scal(alpha, x) use psi_serial_mod - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x real(psb_spk_), intent (in) :: alpha @@ -2462,7 +2515,7 @@ contains !! \brief 2-norm |x(1:n)|_2 !! \param n how many entries to consider function s_base_mlv_nrm2(n,x) result(res) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_), allocatable :: res(:) @@ -2484,7 +2537,7 @@ contains !! \brief infinity-norm |x(1:n)|_\infty !! \param n how many entries to consider function s_base_mlv_amax(n,x) result(res) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_), allocatable :: res(:) @@ -2505,7 +2558,7 @@ contains !! \brief 1-norm |x(1:n)|_1 !! \param n how many entries to consider function s_base_mlv_asum(n,x) result(res) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_), allocatable :: res(:) @@ -2528,7 +2581,7 @@ contains !! \brief Set all entries to their respective absolute values. !! subroutine s_base_mlv_absval1(x) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x if (allocated(x%v)) then @@ -2540,13 +2593,13 @@ contains end subroutine s_base_mlv_absval1 subroutine s_base_mlv_absval2(x,y) - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x class(psb_s_base_multivect_type), intent(inout) :: y integer(psb_ipk_) :: info - + if (x%is_dev()) call x%sync() - if (allocated(x%v)) then + if (allocated(x%v)) then call y%axpby(min(x%get_nrows(),y%get_nrows()),sone,x,szero,info) call y%absval() end if @@ -2555,15 +2608,15 @@ contains function s_base_mlv_use_buffer() result(res) - implicit none + implicit none logical :: res - + res = .true. end function s_base_mlv_use_buffer subroutine s_base_mlv_new_buffer(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -2575,7 +2628,7 @@ contains subroutine s_base_mlv_new_comid(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -2586,12 +2639,12 @@ contains subroutine s_base_mlv_maybe_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (psb_get_maybe_free_buffer())& & call x%free_buffer(info) @@ -2599,7 +2652,7 @@ contains subroutine s_base_mlv_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -2609,7 +2662,7 @@ contains subroutine s_base_mlv_free_comid(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_s_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -2632,7 +2685,7 @@ contains !! \param beta subroutine s_base_mlv_gthab(n,idx,alpha,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_spk_) :: alpha, beta, y(:) class(psb_s_base_multivect_type) :: x @@ -2648,7 +2701,7 @@ contains end subroutine s_base_mlv_gthab ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_s_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -2657,7 +2710,7 @@ contains !! \param idx(:) indices subroutine s_base_mlv_gthzv_x(i,n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx real(psb_spk_) :: y(:) @@ -2670,7 +2723,7 @@ contains ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_s_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -2679,7 +2732,7 @@ contains !! \param idx(:) indices subroutine s_base_mlv_gthzv(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_spk_) :: y(:) class(psb_s_base_multivect_type) :: x @@ -2696,7 +2749,7 @@ contains end subroutine s_base_mlv_gthzv ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_s_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -2705,7 +2758,7 @@ contains !! \param idx(:) indices subroutine s_base_mlv_gthzm(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_spk_) :: y(:,:) class(psb_s_base_multivect_type) :: x @@ -2722,17 +2775,17 @@ contains end subroutine s_base_mlv_gthzm ! - ! New comm internals impl. + ! New comm internals impl. ! subroutine s_base_mlv_gthzbuf(i,ixb,n,idx,x) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, ixb, n class(psb_i_base_vect_type) :: idx class(psb_s_base_multivect_type) :: x integer(psb_ipk_) :: nc - - if (.not.allocated(x%combuf)) then + + if (.not.allocated(x%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf') return end if @@ -2744,9 +2797,9 @@ contains end subroutine s_base_mlv_gthzbuf ! - ! Scatter: + ! Scatter: ! Y(IDX(:),:) = beta*Y(IDX(:),:) + X(:) - ! + ! ! !> Function base_mlv_sctb !! \memberof psb_s_base_multivect_type @@ -2755,10 +2808,10 @@ contains !! \param n how many entries to consider !! \param idx(:) indices !! \param beta - !! \param x(:) + !! \param x(:) subroutine s_base_mlv_sctb(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_spk_) :: beta, x(:) class(psb_s_base_multivect_type) :: y @@ -2773,7 +2826,7 @@ contains subroutine s_base_mlv_sctbr2(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) real(psb_spk_) :: beta, x(:,:) class(psb_s_base_multivect_type) :: y @@ -2788,7 +2841,7 @@ contains subroutine s_base_mlv_sctb_x(i,n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx real( psb_spk_) :: beta, x(:) @@ -2800,14 +2853,14 @@ contains subroutine s_base_mlv_sctb_buf(i,iyb,n,idx,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, iyb, n class(psb_i_base_vect_type) :: idx real(psb_spk_) :: beta class(psb_s_base_multivect_type) :: y integer(psb_ipk_) :: nc - - if (.not.allocated(y%combuf)) then + + if (.not.allocated(y%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf') return end if @@ -2816,19 +2869,18 @@ contains nc = y%get_ncols() call y%sct(n,idx%v(i:),y%combuf(iyb:),beta) call y%set_host() - + end subroutine s_base_mlv_sctb_buf ! !> Function base_device_wait: !! \memberof psb_s_base_vect_type !! \brief device_wait: base version is a no-op. - !! + !! ! subroutine s_base_mlv_device_wait() - implicit none - + implicit none + end subroutine s_base_mlv_device_wait end module psb_s_base_multivect_mod - diff --git a/base/modules/serial/psb_s_vect_mod.F90 b/base/modules/serial/psb_s_vect_mod.F90 index 0907f06ed..d835bc5aa 100644 --- a/base/modules/serial/psb_s_vect_mod.F90 +++ b/base/modules/serial/psb_s_vect_mod.F90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,15 +27,15 @@ ! 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. -! -! +! +! ! ! package: psb_s_vect_mod ! ! This module contains the definition of the psb_s_vect type which ! is the outer container for dense vectors. ! Therefore all methods simply invoke the corresponding methods of the -! inner component. +! inner component. ! module psb_s_vect_mod @@ -43,7 +43,7 @@ module psb_s_vect_mod use psb_i_vect_mod type psb_s_vect_type - class(psb_s_base_vect_type), allocatable :: v + class(psb_s_base_vect_type), allocatable :: v contains procedure, pass(x) :: get_nrows => s_vect_get_nrows procedure, pass(x) :: sizeof => s_vect_sizeof @@ -94,13 +94,16 @@ module psb_s_vect_mod procedure, pass(z) :: mlt_av => s_vect_mlt_av generic, public :: mlt => mlt_v, mlt_a, mlt_a_2,& & mlt_v_2, mlt_av, mlt_va + procedure, pass(x) :: div_v => s_vect_div_v + procedure, pass(z) :: div_a2 => s_vect_div_a2 + generic, public :: div => div_v, div_a2 procedure, pass(x) :: scal => s_vect_scal procedure, pass(x) :: absval1 => s_vect_absval1 procedure, pass(x) :: absval2 => s_vect_absval2 generic, public :: absval => absval1, absval2 procedure, pass(x) :: nrm2 => s_vect_nrm2 procedure, pass(x) :: amax => s_vect_amax - procedure, pass(x) :: asum => s_vect_asum + procedure, pass(x) :: asum => s_vect_asum end type psb_s_vect_type public :: psb_s_vect @@ -122,7 +125,7 @@ module psb_s_vect_mod private :: s_vect_dot_v, s_vect_dot_a, s_vect_axpby_v, s_vect_axpby_a, & & s_vect_mlt_v, s_vect_mlt_a, s_vect_mlt_a_2, s_vect_mlt_v_2, & & s_vect_mlt_va, s_vect_mlt_av, s_vect_scal, s_vect_absval1, & - & s_vect_absval2, s_vect_nrm2, s_vect_amax, s_vect_asum + & s_vect_absval2, s_vect_nrm2, s_vect_amax, s_vect_asum @@ -141,11 +144,11 @@ module psb_s_vect_mod contains - subroutine psb_s_set_vect_default(v) - implicit none + subroutine psb_s_set_vect_default(v) + implicit none class(psb_s_base_vect_type), intent(in) :: v - if (allocated(psb_s_base_vect_default)) then + if (allocated(psb_s_base_vect_default)) then deallocate(psb_s_base_vect_default) end if allocate(psb_s_base_vect_default, mold=v) @@ -153,7 +156,7 @@ contains end subroutine psb_s_set_vect_default function psb_s_get_vect_default(v) result(res) - implicit none + implicit none class(psb_s_vect_type), intent(in) :: v class(psb_s_base_vect_type), pointer :: res @@ -163,10 +166,10 @@ contains function psb_s_get_base_vect_default() result(res) - implicit none + implicit none class(psb_s_base_vect_type), pointer :: res - if (.not.allocated(psb_s_base_vect_default)) then + if (.not.allocated(psb_s_base_vect_default)) then allocate(psb_s_base_vect_type :: psb_s_base_vect_default) end if @@ -176,14 +179,14 @@ contains subroutine s_vect_clone(x,y,info) - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x class(psb_s_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info info = psb_success_ call y%free(info) - if ((info==0).and.allocated(x%v)) then + if ((info==0).and.allocated(x%v)) then call y%bld(x%get_vect(),mold=x%v) end if end subroutine s_vect_clone @@ -198,7 +201,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_s_get_base_vect_default()) @@ -220,7 +223,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_s_get_base_vect_default()) @@ -241,7 +244,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_s_get_base_vect_default()) @@ -304,7 +307,7 @@ contains end function size_const function s_vect_get_nrows(x) result(res) - implicit none + implicit none class(psb_s_vect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -312,7 +315,7 @@ contains end function s_vect_get_nrows function s_vect_sizeof(x) result(res) - implicit none + implicit none class(psb_s_vect_type), intent(in) :: x integer(psb_epk_) :: res res = 0 @@ -320,7 +323,7 @@ contains end function s_vect_sizeof function s_vect_get_fmt(x) result(res) - implicit none + implicit none class(psb_s_vect_type), intent(in) :: x character(len=5) :: res res = 'NULL' @@ -329,7 +332,7 @@ contains subroutine s_vect_all(n, x, info, mold) - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_s_vect_type), intent(inout) :: x class(psb_s_base_vect_type), intent(in), optional :: mold @@ -338,12 +341,12 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(psb_s_base_vect_type :: x%v,stat=info) endif - if (info == 0) then + if (info == 0) then call x%v%all(n,info) else info = psb_err_alloc_dealloc_ @@ -353,12 +356,12 @@ contains subroutine s_vect_reall(n, x, info) - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_s_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (.not.allocated(x%v)) & & call x%all(n,info) if (info == 0) & @@ -368,7 +371,7 @@ contains subroutine s_vect_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x if (allocated(x%v)) call x%v%zero() @@ -378,7 +381,7 @@ contains subroutine s_vect_asb(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_s_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -424,12 +427,12 @@ contains subroutine s_vect_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%free(info) if (info == 0) deallocate(x%v,stat=info) end if @@ -438,7 +441,7 @@ contains subroutine s_vect_ins_a(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -448,7 +451,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ return end if @@ -459,7 +462,7 @@ contains subroutine s_vect_ins_v(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl class(psb_i_vect_type), intent(inout) :: irl @@ -469,7 +472,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then + if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then info = psb_err_invalid_vect_state_ return end if @@ -487,12 +490,12 @@ contains integer(psb_ipk_) :: info info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(tmp,stat=info,mold=mold) else allocate(tmp,stat=info,mold=psb_s_get_base_vect_default()) end if - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%sync() if (info == psb_success_) call tmp%bld(x%v%v) call x%v%free(info) @@ -503,7 +506,7 @@ contains subroutine s_vect_sync(x) - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -512,7 +515,7 @@ contains end subroutine s_vect_sync subroutine s_vect_set_sync(x) - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -521,7 +524,7 @@ contains end subroutine s_vect_set_sync subroutine s_vect_set_host(x) - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -530,7 +533,7 @@ contains end subroutine s_vect_set_host subroutine s_vect_set_dev(x) - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -539,7 +542,7 @@ contains end subroutine s_vect_set_dev function s_vect_is_sync(x) result(res) - implicit none + implicit none logical :: res class(psb_s_vect_type), intent(inout) :: x @@ -550,7 +553,7 @@ contains end function s_vect_is_sync function s_vect_is_host(x) result(res) - implicit none + implicit none logical :: res class(psb_s_vect_type), intent(inout) :: x @@ -561,11 +564,11 @@ contains end function s_vect_is_host function s_vect_is_dev(x) result(res) - implicit none + implicit none logical :: res class(psb_s_vect_type), intent(inout) :: x - res = .false. + res = .false. if (allocated(x%v)) & & res = x%v%is_dev() @@ -573,7 +576,7 @@ contains function s_vect_dot_v(n,x,y) result(res) - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x, y integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res @@ -585,7 +588,7 @@ contains end function s_vect_dot_v function s_vect_dot_a(n,x,y) result(res) - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x real(psb_spk_), intent(in) :: y(:) integer(psb_ipk_), intent(in) :: n @@ -599,14 +602,14 @@ contains subroutine s_vect_axpby_v(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m class(psb_s_vect_type), intent(inout) :: x class(psb_s_vect_type), intent(inout) :: y real(psb_spk_), intent (in) :: alpha, beta integer(psb_ipk_), intent(out) :: info - if (allocated(x%v).and.allocated(y%v)) then + if (allocated(x%v).and.allocated(y%v)) then call y%v%axpby(m,alpha,x%v,beta,info) else info = psb_err_invalid_vect_state_ @@ -616,7 +619,7 @@ contains subroutine s_vect_axpby_a(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m real(psb_spk_), intent(in) :: x(:) class(psb_s_vect_type), intent(inout) :: y @@ -631,10 +634,10 @@ contains subroutine s_vect_mlt_v(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x class(psb_s_vect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -645,7 +648,7 @@ contains subroutine s_vect_mlt_a(x, y, info) use psi_serial_mod - implicit none + implicit none real(psb_spk_), intent(in) :: x(:) class(psb_s_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -661,7 +664,7 @@ contains subroutine s_vect_mlt_a_2(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_spk_), intent(in) :: alpha,beta real(psb_spk_), intent(in) :: y(:) real(psb_spk_), intent(in) :: x(:) @@ -669,7 +672,7 @@ contains integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n - info = 0 + info = 0 if (allocated(z%v)) & & call z%v%mlt(alpha,x,y,beta,info) @@ -677,12 +680,12 @@ contains subroutine s_vect_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) use psi_serial_mod - implicit none + implicit none real(psb_spk_), intent(in) :: alpha,beta class(psb_s_vect_type), intent(inout) :: x class(psb_s_vect_type), intent(inout) :: y class(psb_s_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info character(len=1), intent(in), optional :: conjgx, conjgy integer(psb_ipk_) :: i, n @@ -696,12 +699,12 @@ contains subroutine s_vect_mlt_av(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_spk_), intent(in) :: alpha,beta real(psb_spk_), intent(in) :: x(:) class(psb_s_vect_type), intent(inout) :: y class(psb_s_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -712,12 +715,12 @@ contains subroutine s_vect_mlt_va(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none real(psb_spk_), intent(in) :: alpha,beta real(psb_spk_), intent(in) :: y(:) class(psb_s_vect_type), intent(inout) :: x class(psb_s_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -727,9 +730,38 @@ contains end subroutine s_vect_mlt_va + subroutine s_vect_div_v(x, y, info) + use psi_serial_mod + implicit none + class(psb_s_vect_type), intent(inout) :: x + class(psb_s_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (allocated(x%v).and.allocated(y%v)) & + & call x%v%div(y%v,info) + + end subroutine s_vect_div_v + + subroutine s_vect_div_a2(x, y, z, info) + use psi_serial_mod + implicit none + real(psb_spk_), intent(in) :: x(:) + real(psb_spk_), intent(in) :: y(:) + class(psb_s_vect_type), intent(inout) :: z + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (allocated(z%v)) & + & call z%v%div(x,y,info) + + end subroutine s_vect_div_a2 + subroutine s_vect_scal(alpha, x) use psi_serial_mod - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x real(psb_spk_), intent (in) :: alpha @@ -749,19 +781,19 @@ contains class(psb_s_vect_type), intent(inout) :: x class(psb_s_vect_type), intent(inout) :: y - if (allocated(x%v)) then + if (allocated(x%v)) then if (.not.allocated(y%v)) call y%bld(psb_size(x%v%v)) call x%v%absval(y%v) end if end subroutine s_vect_absval2 function s_vect_nrm2(n,x) result(res) - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res - if (allocated(x%v)) then + if (allocated(x%v)) then res = x%v%nrm2(n) else res = szero @@ -770,12 +802,12 @@ contains end function s_vect_nrm2 function s_vect_amax(n,x) result(res) - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res - if (allocated(x%v)) then + if (allocated(x%v)) then res = x%v%amax(n) else res = szero @@ -784,12 +816,12 @@ contains end function s_vect_amax function s_vect_asum(n,x) result(res) - implicit none + implicit none class(psb_s_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_spk_) :: res - if (allocated(x%v)) then + if (allocated(x%v)) then res = x%v%asum(n) else res = szero @@ -812,7 +844,7 @@ module psb_s_multivect_mod !private type psb_s_multivect_type - class(psb_s_base_multivect_type), allocatable :: v + class(psb_s_base_multivect_type), allocatable :: v contains procedure, pass(x) :: get_nrows => s_vect_get_nrows procedure, pass(x) :: get_ncols => s_vect_get_ncols @@ -886,11 +918,11 @@ module psb_s_multivect_mod contains - subroutine psb_s_set_multivect_default(v) - implicit none + subroutine psb_s_set_multivect_default(v) + implicit none class(psb_s_base_multivect_type), intent(in) :: v - if (allocated(psb_s_base_multivect_default)) then + if (allocated(psb_s_base_multivect_default)) then deallocate(psb_s_base_multivect_default) end if allocate(psb_s_base_multivect_default, mold=v) @@ -898,7 +930,7 @@ contains end subroutine psb_s_set_multivect_default function psb_s_get_multivect_default(v) result(res) - implicit none + implicit none class(psb_s_multivect_type), intent(in) :: v class(psb_s_base_multivect_type), pointer :: res @@ -908,10 +940,10 @@ contains function psb_s_get_base_multivect_default() result(res) - implicit none + implicit none class(psb_s_base_multivect_type), pointer :: res - if (.not.allocated(psb_s_base_multivect_default)) then + if (.not.allocated(psb_s_base_multivect_default)) then allocate(psb_s_base_multivect_type :: psb_s_base_multivect_default) end if @@ -921,14 +953,14 @@ contains subroutine s_vect_clone(x,y,info) - implicit none + implicit none class(psb_s_multivect_type), intent(inout) :: x class(psb_s_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info info = psb_success_ call y%free(info) - if ((info==0).and.allocated(x%v)) then + if ((info==0).and.allocated(x%v)) then call y%bld(x%get_vect(),mold=x%v) end if end subroutine s_vect_clone @@ -941,7 +973,7 @@ contains class(psb_s_base_multivect_type), pointer :: mld info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_s_get_base_multivect_default()) @@ -959,7 +991,7 @@ contains integer(psb_ipk_) :: info info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_s_get_base_multivect_default()) @@ -1019,7 +1051,7 @@ contains end function size_const function s_vect_get_nrows(x) result(res) - implicit none + implicit none class(psb_s_multivect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -1027,7 +1059,7 @@ contains end function s_vect_get_nrows function s_vect_get_ncols(x) result(res) - implicit none + implicit none class(psb_s_multivect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -1035,7 +1067,7 @@ contains end function s_vect_get_ncols function s_vect_sizeof(x) result(res) - implicit none + implicit none class(psb_s_multivect_type), intent(in) :: x integer(psb_epk_) :: res res = 0 @@ -1043,7 +1075,7 @@ contains end function s_vect_sizeof function s_vect_get_fmt(x) result(res) - implicit none + implicit none class(psb_s_multivect_type), intent(in) :: x character(len=5) :: res res = 'NULL' @@ -1052,18 +1084,18 @@ contains subroutine s_vect_all(m,n, x, info, mold) - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_s_multivect_type), intent(out) :: x class(psb_s_base_multivect_type), intent(in), optional :: mold integer(psb_ipk_), intent(out) :: info - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(psb_s_base_multivect_type :: x%v,stat=info) endif - if (info == 0) then + if (info == 0) then call x%v%all(m,n,info) else info = psb_err_alloc_dealloc_ @@ -1073,12 +1105,12 @@ contains subroutine s_vect_reall(m,n, x, info) - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_s_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (.not.allocated(x%v)) & & call x%all(m,n,info) if (info == 0) & @@ -1088,7 +1120,7 @@ contains subroutine s_vect_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_s_multivect_type), intent(inout) :: x if (allocated(x%v)) call x%v%zero() @@ -1098,7 +1130,7 @@ contains subroutine s_vect_asb(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_s_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1109,7 +1141,7 @@ contains end subroutine s_vect_asb subroutine s_vect_sync(x) - implicit none + implicit none class(psb_s_multivect_type), intent(inout) :: x if (allocated(x%v)) & @@ -1177,12 +1209,12 @@ contains subroutine s_vect_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_s_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%free(info) if (info == 0) deallocate(x%v,stat=info) end if @@ -1191,7 +1223,7 @@ contains subroutine s_vect_ins(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_s_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -1201,7 +1233,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ return end if @@ -1217,12 +1249,12 @@ contains class(psb_s_base_multivect_type), allocatable :: tmp integer(psb_ipk_) :: info - if (present(mold)) then + if (present(mold)) then allocate(tmp,stat=info,mold=mold) else allocate(tmp,stat=info, mold=psb_s_get_base_multivect_default()) - endif - if (allocated(x%v)) then + endif + if (allocated(x%v)) then call x%v%sync() if (info == psb_success_) call tmp%bld(x%v%v) call x%v%free(info) @@ -1232,7 +1264,7 @@ contains !!$ function s_vect_dot_v(n,x,y) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_s_multivect_type), intent(inout) :: x, y !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_spk_) :: res @@ -1244,28 +1276,28 @@ contains !!$ end function s_vect_dot_v !!$ !!$ function s_vect_dot_a(n,x,y) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_s_multivect_type), intent(inout) :: x !!$ real(psb_spk_), intent(in) :: y(:) !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_spk_) :: res -!!$ +!!$ !!$ res = szero !!$ if (allocated(x%v)) & !!$ & res = x%v%dot(n,y) -!!$ +!!$ !!$ end function s_vect_dot_a -!!$ +!!$ !!$ subroutine s_vect_axpby_v(m,alpha, x, beta, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ integer(psb_ipk_), intent(in) :: m !!$ class(psb_s_multivect_type), intent(inout) :: x !!$ class(psb_s_multivect_type), intent(inout) :: y !!$ real(psb_spk_), intent (in) :: alpha, beta !!$ integer(psb_ipk_), intent(out) :: info -!!$ -!!$ if (allocated(x%v).and.allocated(y%v)) then +!!$ +!!$ if (allocated(x%v).and.allocated(y%v)) then !!$ call y%v%axpby(m,alpha,x%v,beta,info) !!$ else !!$ info = psb_err_invalid_vect_state_ @@ -1275,25 +1307,25 @@ contains !!$ !!$ subroutine s_vect_axpby_a(m,alpha, x, beta, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ integer(psb_ipk_), intent(in) :: m !!$ real(psb_spk_), intent(in) :: x(:) !!$ class(psb_s_multivect_type), intent(inout) :: y !!$ real(psb_spk_), intent (in) :: alpha, beta !!$ integer(psb_ipk_), intent(out) :: info -!!$ +!!$ !!$ if (allocated(y%v)) & !!$ & call y%v%axpby(m,alpha,x,beta,info) -!!$ +!!$ !!$ end subroutine s_vect_axpby_a !!$ -!!$ +!!$ !!$ subroutine s_vect_mlt_v(x, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ class(psb_s_multivect_type), intent(inout) :: x !!$ class(psb_s_multivect_type), intent(inout) :: y -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 @@ -1304,7 +1336,7 @@ contains !!$ !!$ subroutine s_vect_mlt_a(x, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_spk_), intent(in) :: x(:) !!$ class(psb_s_multivect_type), intent(inout) :: y !!$ integer(psb_ipk_), intent(out) :: info @@ -1314,13 +1346,13 @@ contains !!$ info = 0 !!$ if (allocated(y%v)) & !!$ & call y%v%mlt(x,info) -!!$ +!!$ !!$ end subroutine s_vect_mlt_a !!$ !!$ !!$ subroutine s_vect_mlt_a_2(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_spk_), intent(in) :: alpha,beta !!$ real(psb_spk_), intent(in) :: y(:) !!$ real(psb_spk_), intent(in) :: x(:) @@ -1328,20 +1360,20 @@ contains !!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ -!!$ info = 0 +!!$ info = 0 !!$ if (allocated(z%v)) & !!$ & call z%v%mlt(alpha,x,y,beta,info) -!!$ +!!$ !!$ end subroutine s_vect_mlt_a_2 !!$ !!$ subroutine s_vect_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_spk_), intent(in) :: alpha,beta !!$ class(psb_s_multivect_type), intent(inout) :: x !!$ class(psb_s_multivect_type), intent(inout) :: y !!$ class(psb_s_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ character(len=1), intent(in), optional :: conjgx, conjgy !!$ !!$ integer(psb_ipk_) :: i, n @@ -1355,12 +1387,12 @@ contains !!$ !!$ subroutine s_vect_mlt_av(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_spk_), intent(in) :: alpha,beta !!$ real(psb_spk_), intent(in) :: x(:) !!$ class(psb_s_multivect_type), intent(inout) :: y !!$ class(psb_s_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 @@ -1371,16 +1403,16 @@ contains !!$ !!$ subroutine s_vect_mlt_va(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ real(psb_spk_), intent(in) :: alpha,beta !!$ real(psb_spk_), intent(in) :: y(:) !!$ class(psb_s_multivect_type), intent(inout) :: x !!$ class(psb_s_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 -!!$ +!!$ !!$ if (allocated(z%v).and.allocated(x%v)) & !!$ & call z%v%mlt(alpha,x%v,y,beta,info) !!$ @@ -1388,36 +1420,36 @@ contains !!$ !!$ subroutine s_vect_scal(alpha, x) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ class(psb_s_multivect_type), intent(inout) :: x !!$ real(psb_spk_), intent (in) :: alpha -!!$ +!!$ !!$ if (allocated(x%v)) call x%v%scal(alpha) !!$ !!$ end subroutine s_vect_scal !!$ !!$ !!$ function s_vect_nrm2(n,x) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_s_multivect_type), intent(inout) :: x !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_spk_) :: res -!!$ -!!$ if (allocated(x%v)) then +!!$ +!!$ if (allocated(x%v)) then !!$ res = x%v%nrm2(n) !!$ else !!$ res = szero !!$ end if !!$ !!$ end function s_vect_nrm2 -!!$ +!!$ !!$ function s_vect_amax(n,x) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_s_multivect_type), intent(inout) :: x !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_spk_) :: res !!$ -!!$ if (allocated(x%v)) then +!!$ if (allocated(x%v)) then !!$ res = x%v%amax(n) !!$ else !!$ res = szero @@ -1426,12 +1458,12 @@ contains !!$ end function s_vect_amax !!$ !!$ function s_vect_asum(n,x) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_s_multivect_type), intent(inout) :: x !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_spk_) :: res !!$ -!!$ if (allocated(x%v)) then +!!$ if (allocated(x%v)) then !!$ res = x%v%asum(n) !!$ else !!$ res = szero diff --git a/base/modules/serial/psb_z_base_vect_mod.f90 b/base/modules/serial/psb_z_base_vect_mod.f90 index 6dd242cc3..350e70340 100644 --- a/base/modules/serial/psb_z_base_vect_mod.f90 +++ b/base/modules/serial/psb_z_base_vect_mod.f90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,14 +27,14 @@ ! 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. -! -! +! +! ! ! package: psb_z_base_vect_mod ! ! This module contains the definition of the psb_z_base_vect type which ! is a container for dense vectors. -! This is encapsulated instead of being just a simple array to allow for +! This is encapsulated instead of being just a simple array to allow for ! more complicated situations, such as GPU programming, where the memory ! area we are interested in is not easily accessible from the host/Fortran ! side. It is also meant to be encapsulated in an outer type, to allow @@ -43,7 +43,7 @@ ! ! module psb_z_base_vect_mod - + use psb_const_mod use psb_error_mod use psb_realloc_mod @@ -51,9 +51,9 @@ module psb_z_base_vect_mod use psb_l_base_vect_mod !> \namespace psb_base_mod \class psb_z_base_vect_type - !! The psb_z_base_vect_type + !! The psb_z_base_vect_type !! defines a middle level complex(psb_dpk_) encapsulated dense vector. - !! The encapsulation is needed, in place of a simple array, to allow + !! The encapsulation is needed, in place of a simple array, to allow !! for complicated situations, such as GPU programming, where the memory !! area we are interested in is not easily accessible from the host/Fortran !! side. It is also meant to be encapsulated in an outer type, to allow @@ -61,9 +61,9 @@ module psb_z_base_vect_mod !! sparse matrix types. !! type psb_z_base_vect_type - !> Values. + !> Values. complex(psb_dpk_), allocatable :: v(:) - complex(psb_dpk_), allocatable :: combuf(:) + complex(psb_dpk_), allocatable :: combuf(:) integer(psb_mpk_), allocatable :: comid(:,:) contains ! @@ -78,7 +78,7 @@ module psb_z_base_vect_mod ! ! Insert/set. Assembly and free. ! Assembly does almost nothing here, but is important - ! in derived classes. + ! in derived classes. ! procedure, pass(x) :: ins_a => z_base_ins_a procedure, pass(x) :: ins_v => z_base_ins_v @@ -93,7 +93,7 @@ module psb_z_base_vect_mod ! Any derived class having extra storage upon sync ! will guarantee that both fortran/host side and ! external side contain the same data. The base - ! version is only a placeholder. + ! version is only a placeholder. ! procedure, pass(x) :: sync => z_base_sync procedure, pass(x) :: is_host => z_base_is_host @@ -130,7 +130,7 @@ module psb_z_base_vect_mod generic, public :: set => set_vect, set_scal ! ! Gather/scatter. These are needed for MPI interfacing. - ! May have to be reworked. + ! May have to be reworked. ! procedure, pass(x) :: gthab => z_base_gthab procedure, pass(x) :: gthzv => z_base_gthzv @@ -164,6 +164,12 @@ module psb_z_base_vect_mod procedure, pass(z) :: mlt_av => z_base_mlt_av generic, public :: mlt => mlt_v, mlt_a, mlt_a_2, mlt_v_2, mlt_av, mlt_va ! + ! Vector-Vector operations + ! + procedure, pass(x) :: div_v => z_base_div_v + procedure, pass(z) :: div_a2 => z_base_div_a2 + generic, public :: div => div_v, div_a2 + ! ! Scaling and norms ! procedure, pass(x) :: scal => z_base_scal @@ -183,11 +189,11 @@ module psb_z_base_vect_mod end interface psb_z_base_vect contains - + ! - ! Constructors. + ! Constructors. ! - + !> Function constructor: !! \brief Constructor from an array !! \param x(:) input array to be copied @@ -200,11 +206,11 @@ contains this%v = x call this%asb(size(x,kind=psb_ipk_),info) end function constructor - - + + !> Function constructor: !! \brief Constructor from size - !! \param n Size of vector to be built. + !! \param n Size of vector to be built. !! function size_const(n) result(this) integer(psb_ipk_), intent(in) :: n @@ -214,7 +220,7 @@ contains call this%asb(n,info) end function size_const - + ! ! Build from a sample ! @@ -226,20 +232,20 @@ contains !! subroutine z_base_bld_x(x,this) use psb_realloc_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: this(:) class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info call psb_realloc(size(this),x%v,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_vect_bld') return end if x%v(:) = this(:) end subroutine z_base_bld_x - + ! ! Create with size, but no initialization ! @@ -247,11 +253,11 @@ contains !> Function bld_mn: !! \memberof psb_z_base_vect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine z_base_bld_mn(x,n) use psb_realloc_mod - implicit none + implicit none integer(psb_mpk_), intent(in) :: n class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info @@ -260,15 +266,15 @@ contains call x%asb(n,info) end subroutine z_base_bld_mn - + !> Function bld_en: !! \memberof psb_z_base_vect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine z_base_bld_en(x,n) use psb_realloc_mod - implicit none + implicit none integer(psb_epk_), intent(in) :: n class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_) :: info @@ -277,24 +283,24 @@ contains call x%asb(n,info) end subroutine z_base_bld_en - + !> Function base_all: !! \memberof psb_z_base_vect_type !! \brief Build method with size (uninitialized data) and !! allocation return code. - !! \param n size to be allocated. + !! \param n size to be allocated. !! \param info return code !! subroutine z_base_all(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_z_base_vect_type), intent(out) :: x integer(psb_ipk_), intent(out) :: info - + call psb_realloc(n,x%v,info) - + end subroutine z_base_all !> Function base_mold: @@ -306,11 +312,11 @@ contains subroutine z_base_mold(x, y, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(in) :: x class(psb_z_base_vect_type), intent(out), allocatable :: y integer(psb_ipk_), intent(out) :: info - + allocate(psb_z_base_vect_type :: y, stat=info) end subroutine z_base_mold @@ -320,21 +326,21 @@ contains ! !> Function base_ins: !! \memberof psb_z_base_vect_type - !! \brief Insert coefficients. + !! \brief Insert coefficients. !! !! !! Given a list of N pairs !! (IRL(i),VAL(i)) !! record a new coefficient in X such that !! X(IRL(1:N)) = VAL(1:N). - !! + !! !! - the update operation will perform either !! X(IRL(1:n)) = VAL(1:N) !! or !! X(IRL(1:n)) = X(IRL(1:n))+VAL(1:N) !! according to the value of DUPLICATE. - !! - !! + !! + !! !! \param n number of pairs in input !! \param irl(:) the input row indices !! \param val(:) the input coefficients @@ -344,7 +350,7 @@ contains ! subroutine z_base_ins_a(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -354,21 +360,21 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ - else if (n > min(size(irl),size(val))) then + else if (n > min(size(irl),size(val))) then info = psb_err_invalid_input_ - else + else isz = size(x%v) - select case(dupl) - case(psb_dupl_ovwrt_) + select case(dupl) + case(psb_dupl_ovwrt_) do i = 1, n !loop over all val's rows - ! row actual block row + ! row actual block row if ((1 <= irl(i)).and.(irl(i) <= isz)) then ! this row belongs to me ! copy i-th row of block val in x @@ -376,7 +382,7 @@ contains end if enddo - case(psb_dupl_add_) + case(psb_dupl_add_) do i = 1, n !loop over all val's rows @@ -394,7 +400,7 @@ contains end select end if call x%set_host() - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_vect_ins') return end if @@ -403,7 +409,7 @@ contains subroutine z_base_ins_v(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl class(psb_i_base_vect_type), intent(inout) :: irl @@ -413,14 +419,14 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return if (irl%is_dev()) call irl%sync() if (val%is_dev()) call val%sync() if (x%is_dev()) call x%sync() call x%ins(n,irl%v,val%v,dupl,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_vect_ins') return end if @@ -436,14 +442,14 @@ contains ! subroutine z_base_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x - + if (allocated(x%v)) x%v=zzero call x%set_host() end subroutine z_base_zero - + ! ! Assembly. ! For derived classes: after this the vector @@ -452,20 +458,20 @@ contains !> Function base_asb: !! \memberof psb_z_base_vect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! ! - + subroutine z_base_asb_m(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_mpk_), intent(in) :: n class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (x%get_nrows() < n) & & call psb_realloc(n,x%v,info) @@ -482,20 +488,20 @@ contains !> Function base_asb: !! \memberof psb_z_base_vect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! ! - + subroutine z_base_asb_e(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_epk_), intent(in) :: n class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (x%get_nrows() < n) & & call psb_realloc(n,x%v,info) @@ -508,39 +514,39 @@ contains !> Function base_free: !! \memberof psb_z_base_vect_type !! \brief Free vector - !! + !! !! \param info return code !! ! subroutine z_base_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - + info = 0 if (allocated(x%v)) deallocate(x%v, stat=info) if (info == 0) call x%free_buffer(info) if (info == 0) call x%free_comid(info) - if (info /= 0) call & + if (info /= 0) call & & psb_errpush(psb_err_alloc_dealloc_,'vect_free') - + end subroutine z_base_free - + ! !> Function base_free_buffer: !! \memberof psb_z_base_vect_type !! \brief Free aux buffer - !! + !! !! \param info return code !! ! subroutine z_base_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -555,17 +561,17 @@ contains !! In some derived classes, e.g. GPU, !! does not really frees to avoid runtime !! costs - !! + !! !! \param info return code !! ! subroutine z_base_maybe_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (psb_get_maybe_free_buffer())& & call x%free_buffer(info) @@ -575,13 +581,13 @@ contains !> Function base_free_comid: !! \memberof psb_z_base_vect_type !! \brief Free aux MPI communication id buffer - !! + !! !! \param info return code !! ! subroutine z_base_free_comid(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -593,77 +599,77 @@ contains ! ! The base version of SYNC & friends does nothing, it's just ! a placeholder. - ! + ! ! !> Function base_sync: !! \memberof psb_z_base_vect_type !! \brief Sync: base version is a no-op. - !! + !! ! subroutine z_base_sync(x) - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x - + end subroutine z_base_sync ! !> Function base_set_host: !! \memberof psb_z_base_vect_type !! \brief Set_host: base version is a no-op. - !! + !! ! subroutine z_base_set_host(x) - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x - + end subroutine z_base_set_host ! !> Function base_set_dev: !! \memberof psb_z_base_vect_type !! \brief Set_dev: base version is a no-op. - !! + !! ! subroutine z_base_set_dev(x) - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x - + end subroutine z_base_set_dev ! !> Function base_set_sync: !! \memberof psb_z_base_vect_type !! \brief Set_sync: base version is a no-op. - !! + !! ! subroutine z_base_set_sync(x) - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x - + end subroutine z_base_set_sync ! !> Function base_is_dev: !! \memberof psb_z_base_vect_type !! \brief Is vector on external device . - !! + !! ! function z_base_is_dev(x) result(res) - implicit none + implicit none class(psb_z_base_vect_type), intent(in) :: x logical :: res - + res = .false. end function z_base_is_dev - + ! !> Function base_is_host !! \memberof psb_z_base_vect_type !! \brief Is vector on standard memory . - !! + !! ! function z_base_is_host(x) result(res) - implicit none + implicit none class(psb_z_base_vect_type), intent(in) :: x logical :: res @@ -674,10 +680,10 @@ contains !> Function base_is_sync !! \memberof psb_z_base_vect_type !! \brief Is vector on sync . - !! + !! ! function z_base_is_sync(x) result(res) - implicit none + implicit none class(psb_z_base_vect_type), intent(in) :: x logical :: res @@ -686,16 +692,16 @@ contains ! - ! Size info. + ! Size info. ! ! !> Function base_get_nrows !! \memberof psb_z_base_vect_type !! \brief Number of entries - !! + !! ! function z_base_get_nrows(x) result(res) - implicit none + implicit none class(psb_z_base_vect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -708,13 +714,13 @@ contains !> Function base_get_sizeof !! \memberof psb_z_base_vect_type !! \brief Size in bytes - !! + !! ! function z_base_sizeof(x) result(res) - implicit none + implicit none class(psb_z_base_vect_type), intent(in) :: x integer(psb_epk_) :: res - + ! Force 8-byte integers. res = (1_psb_epk_ * (2*psb_sizeof_dp)) * x%get_nrows() @@ -724,14 +730,14 @@ contains !> Function base_get_fmt !! \memberof psb_z_base_vect_type !! \brief Format - !! + !! ! function z_base_get_fmt() result(res) - implicit none + implicit none character(len=5) :: res res = 'BASE' end function z_base_get_fmt - + ! ! @@ -740,7 +746,7 @@ contains !! \memberof psb_z_base_vect_type !! \brief Extract a copy of the contents !! - ! + ! function z_base_get_vect(x,n) result(res) class(psb_z_base_vect_type), intent(inout) :: x complex(psb_dpk_), allocatable :: res(:) @@ -748,21 +754,21 @@ contains integer(psb_ipk_), optional :: n ! Local variables integer(psb_ipk_) :: isz - - if (.not.allocated(x%v)) return + + if (.not.allocated(x%v)) return if (.not.x%is_host()) call x%sync() isz = x%get_nrows() if (present(n)) isz = max(0,min(isz,n)) - allocate(res(isz),stat=info) - if (info /= 0) then + allocate(res(isz),stat=info) + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_get_vect') return end if res(1:isz) = x%v(1:isz) end function z_base_get_vect - + ! - ! Reset all values + ! Reset all values ! ! !> Function base_set_scal @@ -771,18 +777,18 @@ contains !! \param val The value to set !! subroutine z_base_set_scal(x,val,first,last) - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x complex(psb_dpk_), intent(in) :: val integer(psb_ipk_), optional :: first, last - + integer(psb_ipk_) :: info, first_, last_ first_=1 last_=size(x%v) if (present(first)) first_ = max(1,first) if (present(last)) last_ = min(last,last_) - + if (x%is_dev()) call x%sync() x%v(first_:last_) = val call x%set_host() @@ -794,14 +800,14 @@ contains !> Function base_set_vect !! \memberof psb_z_base_vect_type !! \brief Set all entries - !! \param val(:) The vector to be copied in + !! \param val(:) The vector to be copied in !! subroutine z_base_set_vect(x,val,first,last) - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x complex(psb_dpk_), intent(in) :: val(:) integer(psb_ipk_), optional :: first, last - + integer(psb_ipk_) :: info, first_, last_, nr first_ = 1 @@ -809,7 +815,7 @@ contains last_ = min(psb_size(x%v),first_+size(val)-1) if (present(last)) last_ = min(last,last_) - if (allocated(x%v)) then + if (allocated(x%v)) then if (x%is_dev()) call x%sync() x%v(first_:last_) = val(1:last_-first_+1) else @@ -829,7 +835,7 @@ contains !! \brief Set all entries to their respective absolute values. !! subroutine z_base_absval1(x) - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x if (allocated(x%v)) then @@ -841,21 +847,21 @@ contains end subroutine z_base_absval1 subroutine z_base_absval2(x,y) - implicit none - class(psb_z_base_vect_type), intent(inout) :: x + implicit none + class(psb_z_base_vect_type), intent(inout) :: x class(psb_z_base_vect_type), intent(inout) :: y integer(psb_ipk_) :: info if (.not.x%is_host()) call x%sync() - if (allocated(x%v)) then + if (allocated(x%v)) then call y%axpby(ione*min(x%get_nrows(),y%get_nrows()),zone,x,zzero,info) call y%absval() end if - + end subroutine z_base_absval2 ! - ! Dot products - ! + ! Dot products + ! ! !> Function base_dot_v !! \memberof psb_z_base_vect_type @@ -864,12 +870,12 @@ contains !! \param y The other (base_vect) to be multiplied by !! function z_base_dot_v(n,x,y) result(res) - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x, y integer(psb_ipk_), intent(in) :: n complex(psb_dpk_) :: res complex(psb_dpk_), external :: zdotc - + res = zzero ! ! Note: this is the base implementation. @@ -898,19 +904,19 @@ contains !! \param y(:) The array to be multiplied by !! function z_base_dot_a(n,x,y) result(res) - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x complex(psb_dpk_), intent(in) :: y(:) integer(psb_ipk_), intent(in) :: n complex(psb_dpk_) :: res complex(psb_dpk_), external :: zdotc - + res = zdotc(n,y,1,x%v,1) end function z_base_dot_a - + ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! ! @@ -925,13 +931,13 @@ contains !! subroutine z_base_axpby_v(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m class(psb_z_base_vect_type), intent(inout) :: x class(psb_z_base_vect_type), intent(inout) :: y complex(psb_dpk_), intent (in) :: alpha, beta integer(psb_ipk_), intent(out) :: info - + if (x%is_dev()) call x%sync() call y%axpby(m,alpha,x%v,beta,info) @@ -939,7 +945,7 @@ contains end subroutine z_base_axpby_v ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! !> Function base_axpby_a @@ -953,20 +959,20 @@ contains !! subroutine z_base_axpby_a(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m complex(psb_dpk_), intent(in) :: x(:) class(psb_z_base_vect_type), intent(inout) :: y complex(psb_dpk_), intent (in) :: alpha, beta integer(psb_ipk_), intent(out) :: info - + if (y%is_dev()) call y%sync() call psb_geaxpby(m,alpha,x,beta,y%v,info) call y%set_host() - + end subroutine z_base_axpby_a - + ! ! Multiple variants of two operations: ! Simple multiplication Y(:) = X(:)*Y(:) @@ -984,10 +990,10 @@ contains !! subroutine z_base_mlt_v(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x class(psb_z_base_vect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -1005,7 +1011,7 @@ contains !! subroutine z_base_mlt_a(x, y, info) use psi_serial_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: x(:) class(psb_z_base_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -1014,7 +1020,7 @@ contains info = 0 if (y%is_dev()) call y%sync() n = min(size(y%v), size(x)) - do i=1, n + do i=1, n y%v(i) = y%v(i)*x(i) end do call y%set_host() @@ -1035,7 +1041,7 @@ contains !! subroutine z_base_mlt_a_2(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: alpha,beta complex(psb_dpk_), intent(in) :: y(:) complex(psb_dpk_), intent(in) :: x(:) @@ -1043,58 +1049,58 @@ contains integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n - info = 0 + info = 0 if (z%is_dev()) call z%sync() n = min(size(z%v), size(x), size(y)) - if (alpha == zzero) then - if (beta == zone) then - return + if (alpha == zzero) then + if (beta == zone) then + return else do i=1, n z%v(i) = beta*z%v(i) end do end if else - if (alpha == zone) then - if (beta == zzero) then - do i=1, n + if (alpha == zone) then + if (beta == zzero) then + do i=1, n z%v(i) = y(i)*x(i) end do - else if (beta == zone) then - do i=1, n + else if (beta == zone) then + do i=1, n z%v(i) = z%v(i) + y(i)*x(i) end do - else - do i=1, n + else + do i=1, n z%v(i) = beta*z%v(i) + y(i)*x(i) end do end if - else if (alpha == -zone) then - if (beta == zzero) then - do i=1, n + else if (alpha == -zone) then + if (beta == zzero) then + do i=1, n z%v(i) = -y(i)*x(i) end do - else if (beta == zone) then - do i=1, n + else if (beta == zone) then + do i=1, n z%v(i) = z%v(i) - y(i)*x(i) end do - else - do i=1, n + else + do i=1, n z%v(i) = beta*z%v(i) - y(i)*x(i) end do end if else - if (beta == zzero) then - do i=1, n + if (beta == zzero) then + do i=1, n z%v(i) = alpha*y(i)*x(i) end do - else if (beta == zone) then - do i=1, n + else if (beta == zone) then + do i=1, n z%v(i) = z%v(i) + alpha*y(i)*x(i) end do - else - do i=1, n + else + do i=1, n z%v(i) = beta*z%v(i) + alpha*y(i)*x(i) end do end if @@ -1118,12 +1124,12 @@ contains subroutine z_base_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) use psi_serial_mod use psb_string_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: alpha,beta class(psb_z_base_vect_type), intent(inout) :: x class(psb_z_base_vect_type), intent(inout) :: y class(psb_z_base_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info character(len=1), intent(in), optional :: conjgx, conjgy integer(psb_ipk_) :: i, n logical :: conjgx_, conjgy_ @@ -1133,7 +1139,7 @@ contains if (x%is_dev()) call x%sync() if (.not.psb_z_is_complex_) then call z%mlt(alpha,x%v,y%v,beta,info) - else + else conjgx_=.false. if (present(conjgx)) conjgx_ = (psb_toupper(conjgx)=='C') conjgy_=.false. @@ -1148,12 +1154,12 @@ contains subroutine z_base_mlt_av(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: alpha,beta complex(psb_dpk_), intent(in) :: x(:) class(psb_z_base_vect_type), intent(inout) :: y class(psb_z_base_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -1164,12 +1170,12 @@ contains subroutine z_base_mlt_va(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: alpha,beta complex(psb_dpk_), intent(in) :: y(:) class(psb_z_base_vect_type), intent(inout) :: x class(psb_z_base_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -1177,10 +1183,57 @@ contains call z%mlt(alpha,y,x,beta,info) end subroutine z_base_mlt_va + ! + !> Function base_div_v + !! \memberof psb_z_base_vect_type + !! \brief Vector entry-by-entry divide by a vector x=x/y + !! \param y The array to be divided by + !! \param info return code + !! + subroutine z_base_div_v(x, y, info) + use psi_serial_mod + implicit none + class(psb_z_base_vect_type), intent(inout) :: x + class(psb_z_base_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (x%is_dev()) call x%sync() + call x%div(x%v,y%v,info) + + + end subroutine z_base_div_v + ! + !> Function base_div_a2 + !! \memberof psb_z_base_vect_type + !! \brief Entry-by-entry divide between normal array x=x/y + !! \param x(:) The array to be multiplied by + !! \param info return code + !! + subroutine z_base_div_a2(x, y, z, info) + use psi_serial_mod + implicit none + class(psb_z_base_vect_type), intent(inout) :: z + complex(psb_dpk_), intent(in) :: x(:) + complex(psb_dpk_), intent(in) :: y(:) + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (z%is_dev()) call z%sync() + + n = min(size(y), size(x)) + do i=1, n + z%v(i) = x(i)/y(i) + end do + + end subroutine z_base_div_a2 + ! - ! Simple scaling + ! Simple scaling ! !> Function base_scal !! \memberof psb_z_base_vect_type @@ -1189,17 +1242,17 @@ contains !! subroutine z_base_scal(alpha, x) use psi_serial_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x complex(psb_dpk_), intent (in) :: alpha - - if (allocated(x%v)) then + + if (allocated(x%v)) then x%v = alpha*x%v call x%set_host() end if end subroutine z_base_scal - + ! ! Norms 1, 2 and infinity ! @@ -1208,28 +1261,28 @@ contains !! \brief 2-norm |x(1:n)|_2 !! \param n how many entries to consider function z_base_nrm2(n,x) result(res) - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res real(psb_dpk_), external :: dznrm2 - + if (x%is_dev()) call x%sync() res = dznrm2(n,x%v,1) end function z_base_nrm2 - + ! !> Function base_amax !! \memberof psb_z_base_vect_type !! \brief infinity-norm |x(1:n)|_\infty !! \param n how many entries to consider function z_base_amax(n,x) result(res) - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res - + if (x%is_dev()) call x%sync() res = maxval(abs(x%v(1:n))) @@ -1241,17 +1294,17 @@ contains !! \brief 1-norm |x(1:n)|_1 !! \param n how many entries to consider function z_base_asum(n,x) result(res) - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res - + if (x%is_dev()) call x%sync() res = sum(abs(x%v(1:n))) end function z_base_asum - - + + ! ! Gather: Y = beta * Y + alpha * X(IDX(:)) ! @@ -1266,18 +1319,18 @@ contains !! \param beta subroutine z_base_gthab(n,idx,alpha,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_dpk_) :: alpha, beta, y(:) class(psb_z_base_vect_type) :: x - + if (x%is_dev()) call x%sync() call psi_gth(n,idx,alpha,x%v,beta,y) end subroutine z_base_gthab ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_gthzv !! \memberof psb_z_base_vect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1286,28 +1339,28 @@ contains !! \param idx(:) indices subroutine z_base_gthzv_x(i,n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx complex(psb_dpk_) :: y(:) class(psb_z_base_vect_type) :: x - + if (idx%is_dev()) call idx%sync() call x%gth(n,idx%v(i:),y) end subroutine z_base_gthzv_x ! - ! New comm internals impl. + ! New comm internals impl. ! subroutine z_base_gthzbuf(i,n,idx,x) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx class(psb_z_base_vect_type) :: x - - if (.not.allocated(x%combuf)) then + + if (.not.allocated(x%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf') return end if @@ -1320,22 +1373,22 @@ contains !> Function base_device_wait: !! \memberof psb_z_base_vect_type !! \brief device_wait: base version is a no-op. - !! + !! ! subroutine z_base_device_wait() - implicit none - + implicit none + end subroutine z_base_device_wait function z_base_use_buffer() result(res) logical :: res - + res = .true. end function z_base_use_buffer subroutine z_base_new_buffer(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -1345,7 +1398,7 @@ contains subroutine z_base_new_comid(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -1356,7 +1409,7 @@ contains ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_gthzv !! \memberof psb_z_base_vect_type !! \brief gather into an array special alpha=1 beta=0 @@ -1365,20 +1418,20 @@ contains !! \param idx(:) indices subroutine z_base_gthzv(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_dpk_) :: y(:) class(psb_z_base_vect_type) :: x - + if (x%is_dev()) call x%sync() call psi_gth(n,idx,x%v,y) end subroutine z_base_gthzv ! - ! Scatter: + ! Scatter: ! Y(IDX(:)) = beta*Y(IDX(:)) + X(:) - ! + ! ! !> Function base_sctb !! \memberof psb_z_base_vect_type @@ -1387,14 +1440,14 @@ contains !! \param n how many entries to consider !! \param idx(:) indices !! \param beta - !! \param x(:) + !! \param x(:) subroutine z_base_sctb(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_dpk_) :: beta, x(:) class(psb_z_base_vect_type) :: y - + if (y%is_dev()) call y%sync() call psi_sct(n,idx,x,beta,y%v) call y%set_host() @@ -1403,12 +1456,12 @@ contains subroutine z_base_sctb_x(i,n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx complex(psb_dpk_) :: beta, x(:) class(psb_z_base_vect_type) :: y - + if (idx%is_dev()) call idx%sync() call y%sct(n,idx%v(i:),x,beta) call y%set_host() @@ -1417,14 +1470,14 @@ contains subroutine z_base_sctb_buf(i,n,idx,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx complex(psb_dpk_) :: beta class(psb_z_base_vect_type) :: y - - - if (.not.allocated(y%combuf)) then + + + if (.not.allocated(y%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf') return end if @@ -1449,22 +1502,22 @@ module psb_z_base_multivect_mod use psb_z_base_vect_mod !> \namespace psb_base_mod \class psb_z_base_vect_type - !! The psb_z_base_vect_type + !! The psb_z_base_vect_type !! defines a middle level integer(psb_ipk_) encapsulated dense vector. - !! The encapsulation is needed, in place of a simple array, to allow + !! The encapsulation is needed, in place of a simple array, to allow !! for complicated situations, such as GPU programming, where the memory !! area we are interested in is not easily accessible from the host/Fortran !! side. It is also meant to be encapsulated in an outer type, to allow !! runtime switching as per the STATE design pattern, similar to the !! sparse matrix types. !! - private + private public :: psb_z_base_multivect, psb_z_base_multivect_type type psb_z_base_multivect_type - !> Values. + !> Values. complex(psb_dpk_), allocatable :: v(:,:) - complex(psb_dpk_), allocatable :: combuf(:) + complex(psb_dpk_), allocatable :: combuf(:) integer(psb_mpk_), allocatable :: comid(:,:) contains ! @@ -1478,7 +1531,7 @@ module psb_z_base_multivect_mod ! ! Insert/set. Assembly and free. ! Assembly does almost nothing here, but is important - ! in derived classes. + ! in derived classes. ! procedure, pass(x) :: ins => z_base_mlv_ins procedure, pass(x) :: zero => z_base_mlv_zero @@ -1489,7 +1542,7 @@ module psb_z_base_multivect_mod ! Any derived class having extra storage upon sync ! will guarantee that both fortran/host side and ! external side contain the same data. The base - ! version is only a placeholder. + ! version is only a placeholder. ! procedure, pass(x) :: sync => z_base_mlv_sync procedure, pass(x) :: is_host => z_base_mlv_is_host @@ -1562,7 +1615,7 @@ module psb_z_base_multivect_mod ! ! Gather/scatter. These are needed for MPI interfacing. - ! May have to be reworked. + ! May have to be reworked. ! procedure, pass(x) :: gthab => z_base_mlv_gthab procedure, pass(x) :: gthzv => z_base_mlv_gthzv @@ -1584,7 +1637,7 @@ module psb_z_base_multivect_mod contains ! - ! Constructors. + ! Constructors. ! !> Function constructor: @@ -1603,7 +1656,7 @@ contains !> Function constructor: !! \brief Constructor from size - !! \param n Size of vector to be built. + !! \param n Size of vector to be built. !! function size_const(m,n) result(this) integer(psb_ipk_), intent(in) :: m,n @@ -1630,7 +1683,7 @@ contains integer(psb_ipk_) :: info call psb_realloc(size(this,1),size(this,2),x%v,info) - if (info /= 0) then + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_mlv_vect_bld') return end if @@ -1645,7 +1698,7 @@ contains !> Function bld_n: !! \memberof psb_z_base_multivect_type !! \brief Build method with size (uninitialized data) - !! \param n size to be allocated. + !! \param n size to be allocated. !! subroutine z_base_mlv_bld_n(x,m,n) use psb_realloc_mod @@ -1662,13 +1715,13 @@ contains !! \memberof psb_z_base_multivect_type !! \brief Build method with size (uninitialized data) and !! allocation return code. - !! \param n size to be allocated. + !! \param n size to be allocated. !! \param info return code !! subroutine z_base_mlv_all(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_z_base_multivect_type), intent(out) :: x integer(psb_ipk_), intent(out) :: info @@ -1686,7 +1739,7 @@ contains subroutine z_base_mlv_mold(x, y, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_z_base_multivect_type), intent(in) :: x class(psb_z_base_multivect_type), intent(out), allocatable :: y integer(psb_ipk_), intent(out) :: info @@ -1700,21 +1753,21 @@ contains ! !> Function base_mlv_ins: !! \memberof psb_z_base_multivect_type - !! \brief Insert coefficients. + !! \brief Insert coefficients. !! !! !! Given a list of N pairs !! (IRL(i),VAL(i)) !! record a new coefficient in X such that !! X(IRL(1:N)) = VAL(1:N). - !! + !! !! - the update operation will perform either !! X(IRL(1:n)) = VAL(1:N) !! or !! X(IRL(1:n)) = X(IRL(1:n))+VAL(1:N) !! according to the value of DUPLICATE. - !! - !! + !! + !! !! \param n number of pairs in input !! \param irl(:) the input row indices !! \param val(:) the input coefficients @@ -1724,7 +1777,7 @@ contains ! subroutine z_base_mlv_ins(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -1734,21 +1787,21 @@ contains integer(psb_ipk_) :: i, isz info = 0 - if (psb_errstatus_fatal()) return + if (psb_errstatus_fatal()) return - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ - else if (n > min(size(irl),size(val))) then + else if (n > min(size(irl),size(val))) then info = psb_err_invalid_input_ - else + else isz = size(x%v,1) - select case(dupl) - case(psb_dupl_ovwrt_) + select case(dupl) + case(psb_dupl_ovwrt_) do i = 1, n !loop over all val's rows - ! row actual block row + ! row actual block row if ((1 <= irl(i)).and.(irl(i) <= isz)) then ! this row belongs to me ! copy i-th row of block val in x @@ -1756,7 +1809,7 @@ contains end if enddo - case(psb_dupl_add_) + case(psb_dupl_add_) do i = 1, n !loop over all val's rows @@ -1773,7 +1826,7 @@ contains ! !$ goto 9999 end select end if - if (info /= 0) then + if (info /= 0) then call psb_errpush(info,'base_mlv_vect_ins') return end if @@ -1788,7 +1841,7 @@ contains ! subroutine z_base_mlv_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x if (allocated(x%v)) x%v=zzero @@ -1804,7 +1857,7 @@ contains !> Function base_mlv_asb: !! \memberof psb_z_base_multivect_type !! \brief Assemble vector: reallocate as necessary. - !! + !! !! \param n final size !! \param info return code !! @@ -1813,7 +1866,7 @@ contains subroutine z_base_mlv_asb(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_z_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1830,20 +1883,20 @@ contains !> Function base_mlv_free: !! \memberof psb_z_base_multivect_type !! \brief Free vector - !! + !! !! \param info return code !! ! subroutine z_base_mlv_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 if (allocated(x%v)) deallocate(x%v, stat=info) - if (info /= 0) call & + if (info /= 0) call & & psb_errpush(psb_err_alloc_dealloc_,'vect_free') end subroutine z_base_mlv_free @@ -1853,15 +1906,15 @@ contains ! ! The base version of SYNC & friends does nothing, it's just ! a placeholder. - ! + ! ! !> Function base_mlv_sync: !! \memberof psb_z_base_multivect_type !! \brief Sync: base version is a no-op. - !! + !! ! subroutine z_base_mlv_sync(x) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x end subroutine z_base_mlv_sync @@ -1870,10 +1923,10 @@ contains !> Function base_mlv_set_host: !! \memberof psb_z_base_multivect_type !! \brief Set_host: base version is a no-op. - !! + !! ! subroutine z_base_mlv_set_host(x) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x end subroutine z_base_mlv_set_host @@ -1882,10 +1935,10 @@ contains !> Function base_mlv_set_dev: !! \memberof psb_z_base_multivect_type !! \brief Set_dev: base version is a no-op. - !! + !! ! subroutine z_base_mlv_set_dev(x) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x end subroutine z_base_mlv_set_dev @@ -1894,10 +1947,10 @@ contains !> Function base_mlv_set_sync: !! \memberof psb_z_base_multivect_type !! \brief Set_sync: base version is a no-op. - !! + !! ! subroutine z_base_mlv_set_sync(x) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x end subroutine z_base_mlv_set_sync @@ -1906,10 +1959,10 @@ contains !> Function base_mlv_is_dev: !! \memberof psb_z_base_multivect_type !! \brief Is vector on external device . - !! + !! ! function z_base_mlv_is_dev(x) result(res) - implicit none + implicit none class(psb_z_base_multivect_type), intent(in) :: x logical :: res @@ -1920,10 +1973,10 @@ contains !> Function base_mlv_is_host !! \memberof psb_z_base_multivect_type !! \brief Is vector on standard memory . - !! + !! ! function z_base_mlv_is_host(x) result(res) - implicit none + implicit none class(psb_z_base_multivect_type), intent(in) :: x logical :: res @@ -1934,10 +1987,10 @@ contains !> Function base_mlv_is_sync !! \memberof psb_z_base_multivect_type !! \brief Is vector on sync . - !! + !! ! function z_base_mlv_is_sync(x) result(res) - implicit none + implicit none class(psb_z_base_multivect_type), intent(in) :: x logical :: res @@ -1946,16 +1999,16 @@ contains ! - ! Size info. + ! Size info. ! ! !> Function base_mlv_get_nrows !! \memberof psb_z_base_multivect_type !! \brief Number of entries - !! + !! ! function z_base_mlv_get_nrows(x) result(res) - implicit none + implicit none class(psb_z_base_multivect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -1965,7 +2018,7 @@ contains end function z_base_mlv_get_nrows function z_base_mlv_get_ncols(x) result(res) - implicit none + implicit none class(psb_z_base_multivect_type), intent(in) :: x integer(psb_ipk_) :: res @@ -1978,10 +2031,10 @@ contains !> Function base_mlv_get_sizeof !! \memberof psb_z_base_multivect_type !! \brief Size in bytesa - !! + !! ! function z_base_mlv_sizeof(x) result(res) - implicit none + implicit none class(psb_z_base_multivect_type), intent(in) :: x integer(psb_epk_) :: res @@ -1994,10 +2047,10 @@ contains !> Function base_mlv_get_fmt !! \memberof psb_z_base_multivect_type !! \brief Format - !! + !! ! function z_base_mlv_get_fmt() result(res) - implicit none + implicit none character(len=5) :: res res = 'BASE' end function z_base_mlv_get_fmt @@ -2010,18 +2063,18 @@ contains !! \memberof psb_z_base_multivect_type !! \brief Extract a copy of the contents !! - ! + ! function z_base_mlv_get_vect(x) result(res) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x complex(psb_dpk_), allocatable :: res(:,:) integer(psb_ipk_) :: info,m,n m = x%get_nrows() n = x%get_ncols() - if (.not.allocated(x%v)) return + if (.not.allocated(x%v)) return call x%sync() - allocate(res(m,n),stat=info) - if (info /= 0) then + allocate(res(m,n),stat=info) + if (info /= 0) then call psb_errpush(psb_err_alloc_dealloc_,'base_mlv_get_vect') return end if @@ -2029,7 +2082,7 @@ contains end function z_base_mlv_get_vect ! - ! Reset all values + ! Reset all values ! ! !> Function base_mlv_set_scal @@ -2038,7 +2091,7 @@ contains !! \param val The value to set !! subroutine z_base_mlv_set_scal(x,val) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x complex(psb_dpk_), intent(in) :: val @@ -2051,16 +2104,16 @@ contains !> Function base_mlv_set_vect !! \memberof psb_z_base_multivect_type !! \brief Set all entries - !! \param val(:) The vector to be copied in + !! \param val(:) The vector to be copied in !! subroutine z_base_mlv_set_vect(x,val) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x complex(psb_dpk_), intent(in) :: val(:,:) integer(psb_ipk_) :: nr, nc integer(psb_ipk_) :: info - if (allocated(x%v)) then + if (allocated(x%v)) then nr = min(size(x%v,1),size(val,1)) nc = min(size(x%v,2),size(val,2)) @@ -2072,8 +2125,8 @@ contains end subroutine z_base_mlv_set_vect ! - ! Dot products - ! + ! Dot products + ! ! !> Function base_mlv_dot_v !! \memberof psb_z_base_multivect_type @@ -2082,7 +2135,7 @@ contains !! \param y The other (base_mlv_vect) to be multiplied by !! function z_base_mlv_dot_v(n,x,y) result(res) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x, y integer(psb_ipk_), intent(in) :: n complex(psb_dpk_), allocatable :: res(:) @@ -2094,7 +2147,7 @@ contains ! ! Note: this is the base implementation. ! When we get here, we are sure that X is of - ! TYPE psb_z_base_mlv_vect (or its class does not care). + ! TYPE psb_z_base_mlv_vect (or its class does not care). ! If Y is not, throw the burden on it, implicitly ! calling dot_a ! @@ -2123,7 +2176,7 @@ contains !! \param y(:) The array to be multiplied by !! function z_base_mlv_dot_a(n,x,y) result(res) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x complex(psb_dpk_), intent(in) :: y(:,:) integer(psb_ipk_), intent(in) :: n @@ -2141,7 +2194,7 @@ contains end function z_base_mlv_dot_a ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! ! @@ -2156,7 +2209,7 @@ contains !! subroutine z_base_mlv_axpby_v(m,alpha, x, beta, y, info, n) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m class(psb_z_base_multivect_type), intent(inout) :: x class(psb_z_base_multivect_type), intent(inout) :: y @@ -2180,7 +2233,7 @@ contains end subroutine z_base_mlv_axpby_v ! - ! AXPBY is invoked via Y, hence the structure below. + ! AXPBY is invoked via Y, hence the structure below. ! ! !> Function base_mlv_axpby_a @@ -2194,7 +2247,7 @@ contains !! subroutine z_base_mlv_axpby_a(m,alpha, x, beta, y, info,n) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m complex(psb_dpk_), intent(in) :: x(:,:) class(psb_z_base_multivect_type), intent(inout) :: y @@ -2230,10 +2283,10 @@ contains !! subroutine z_base_mlv_mlt_mv(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x class(psb_z_base_multivect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info info = 0 if (x%is_dev()) call x%sync() @@ -2243,10 +2296,10 @@ contains subroutine z_base_mlv_mlt_mv_v(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_z_base_vect_type), intent(inout) :: x class(psb_z_base_multivect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info info = 0 if (x%is_dev()) call x%sync() @@ -2263,7 +2316,7 @@ contains !! subroutine z_base_mlv_mlt_ar1(x, y, info) use psi_serial_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: x(:) class(psb_z_base_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -2271,7 +2324,7 @@ contains info = 0 n = min(psb_size(y%v,1_psb_ipk_), size(x)) - do i=1, n + do i=1, n y%v(i,:) = y%v(i,:)*x(i) end do @@ -2286,7 +2339,7 @@ contains !! subroutine z_base_mlv_mlt_ar2(x, y, info) use psi_serial_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: x(:,:) class(psb_z_base_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -2313,7 +2366,7 @@ contains !! subroutine z_base_mlv_mlt_a_2(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: alpha,beta complex(psb_dpk_), intent(in) :: y(:,:) complex(psb_dpk_), intent(in) :: x(:,:) @@ -2321,38 +2374,38 @@ contains integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, nr, nc - info = 0 + info = 0 nr = min(psb_size(z%v,1_psb_ipk_), size(x,1), size(y,1)) - nc = min(psb_size(z%v,2_psb_ipk_), size(x,2), size(y,2)) - if (alpha == zzero) then - if (beta == zone) then - return + nc = min(psb_size(z%v,2_psb_ipk_), size(x,2), size(y,2)) + if (alpha == zzero) then + if (beta == zone) then + return else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) end if else - if (alpha == zone) then - if (beta == zzero) then + if (alpha == zone) then + if (beta == zzero) then z%v(1:nr,1:nc) = y(1:nr,1:nc)*x(1:nr,1:nc) - else if (beta == zone) then + else if (beta == zone) then z%v(1:nr,1:nc) = z%v(1:nr,1:nc) + y(1:nr,1:nc)*x(1:nr,1:nc) - else + else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) + y(1:nr,1:nc)*x(1:nr,1:nc) end if - else if (alpha == -zone) then - if (beta == zzero) then + else if (alpha == -zone) then + if (beta == zzero) then z%v(1:nr,1:nc) = -y(1:nr,1:nc)*x(1:nr,1:nc) - else if (beta == zone) then + else if (beta == zone) then z%v(1:nr,1:nc) = z%v(1:nr,1:nc) - y(1:nr,1:nc)*x(1:nr,1:nc) - else + else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) - y(1:nr,1:nc)*x(1:nr,1:nc) end if else - if (beta == zzero) then + if (beta == zzero) then z%v(1:nr,1:nc) = alpha*y(1:nr,1:nc)*x(1:nr,1:nc) - else if (beta == zone) then + else if (beta == zone) then z%v(1:nr,1:nc) = z%v(1:nr,1:nc) + alpha*y(1:nr,1:nc)*x(1:nr,1:nc) - else + else z%v(1:nr,1:nc) = beta*z%v(1:nr,1:nc) + alpha*y(1:nr,1:nc)*x(1:nr,1:nc) end if end if @@ -2373,12 +2426,12 @@ contains subroutine z_base_mlv_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) use psi_serial_mod use psb_string_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: alpha,beta class(psb_z_base_multivect_type), intent(inout) :: x class(psb_z_base_multivect_type), intent(inout) :: y class(psb_z_base_multivect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info character(len=1), intent(in), optional :: conjgx, conjgy integer(psb_ipk_) :: i, n logical :: conjgx_, conjgy_ @@ -2389,7 +2442,7 @@ contains if (z%is_dev()) call z%sync() if (.not.psb_z_is_complex_) then call z%mlt(alpha,x%v,y%v,beta,info) - else + else conjgx_=.false. if (present(conjgx)) conjgx_ = (psb_toupper(conjgx)=='C') conjgy_=.false. @@ -2404,39 +2457,39 @@ contains !!$ !!$ subroutine z_base_mlv_mlt_av(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_dpk_), intent(in) :: alpha,beta !!$ complex(psb_dpk_), intent(in) :: x(:) !!$ class(psb_z_base_multivect_type), intent(inout) :: y !!$ class(psb_z_base_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 -!!$ +!!$ !!$ call z%mlt(alpha,x,y%v,beta,info) !!$ !!$ end subroutine z_base_mlv_mlt_av !!$ !!$ subroutine z_base_mlv_mlt_va(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_dpk_), intent(in) :: alpha,beta !!$ complex(psb_dpk_), intent(in) :: y(:) !!$ class(psb_z_base_multivect_type), intent(inout) :: x !!$ class(psb_z_base_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 -!!$ +!!$ !!$ call z%mlt(alpha,y,x,beta,info) !!$ !!$ end subroutine z_base_mlv_mlt_va !!$ !!$ ! - ! Simple scaling + ! Simple scaling ! !> Function base_mlv_scal !! \memberof psb_z_base_multivect_type @@ -2445,7 +2498,7 @@ contains !! subroutine z_base_mlv_scal(alpha, x) use psi_serial_mod - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x complex(psb_dpk_), intent (in) :: alpha @@ -2462,7 +2515,7 @@ contains !! \brief 2-norm |x(1:n)|_2 !! \param n how many entries to consider function z_base_mlv_nrm2(n,x) result(res) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_), allocatable :: res(:) @@ -2484,7 +2537,7 @@ contains !! \brief infinity-norm |x(1:n)|_\infty !! \param n how many entries to consider function z_base_mlv_amax(n,x) result(res) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_), allocatable :: res(:) @@ -2505,7 +2558,7 @@ contains !! \brief 1-norm |x(1:n)|_1 !! \param n how many entries to consider function z_base_mlv_asum(n,x) result(res) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_), allocatable :: res(:) @@ -2528,7 +2581,7 @@ contains !! \brief Set all entries to their respective absolute values. !! subroutine z_base_mlv_absval1(x) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x if (allocated(x%v)) then @@ -2540,13 +2593,13 @@ contains end subroutine z_base_mlv_absval1 subroutine z_base_mlv_absval2(x,y) - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x class(psb_z_base_multivect_type), intent(inout) :: y integer(psb_ipk_) :: info - + if (x%is_dev()) call x%sync() - if (allocated(x%v)) then + if (allocated(x%v)) then call y%axpby(min(x%get_nrows(),y%get_nrows()),zone,x,zzero,info) call y%absval() end if @@ -2555,15 +2608,15 @@ contains function z_base_mlv_use_buffer() result(res) - implicit none + implicit none logical :: res - + res = .true. end function z_base_mlv_use_buffer subroutine z_base_mlv_new_buffer(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -2575,7 +2628,7 @@ contains subroutine z_base_mlv_new_comid(n,x,info) use psb_realloc_mod - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(out) :: info @@ -2586,12 +2639,12 @@ contains subroutine z_base_mlv_maybe_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (psb_get_maybe_free_buffer())& & call x%free_buffer(info) @@ -2599,7 +2652,7 @@ contains subroutine z_base_mlv_free_buffer(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -2609,7 +2662,7 @@ contains subroutine z_base_mlv_free_comid(x,info) use psb_realloc_mod - implicit none + implicit none class(psb_z_base_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -2632,7 +2685,7 @@ contains !! \param beta subroutine z_base_mlv_gthab(n,idx,alpha,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_dpk_) :: alpha, beta, y(:) class(psb_z_base_multivect_type) :: x @@ -2648,7 +2701,7 @@ contains end subroutine z_base_mlv_gthab ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_z_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -2657,7 +2710,7 @@ contains !! \param idx(:) indices subroutine z_base_mlv_gthzv_x(i,n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i,n class(psb_i_base_vect_type) :: idx complex(psb_dpk_) :: y(:) @@ -2670,7 +2723,7 @@ contains ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_z_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -2679,7 +2732,7 @@ contains !! \param idx(:) indices subroutine z_base_mlv_gthzv(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_dpk_) :: y(:) class(psb_z_base_multivect_type) :: x @@ -2696,7 +2749,7 @@ contains end subroutine z_base_mlv_gthzv ! ! shortcut alpha=1 beta=0 - ! + ! !> Function base_mlv_gthzv !! \memberof psb_z_base_multivect_type !! \brief gather into an array special alpha=1 beta=0 @@ -2705,7 +2758,7 @@ contains !! \param idx(:) indices subroutine z_base_mlv_gthzm(n,idx,x,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_dpk_) :: y(:,:) class(psb_z_base_multivect_type) :: x @@ -2722,17 +2775,17 @@ contains end subroutine z_base_mlv_gthzm ! - ! New comm internals impl. + ! New comm internals impl. ! subroutine z_base_mlv_gthzbuf(i,ixb,n,idx,x) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, ixb, n class(psb_i_base_vect_type) :: idx class(psb_z_base_multivect_type) :: x integer(psb_ipk_) :: nc - - if (.not.allocated(x%combuf)) then + + if (.not.allocated(x%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf') return end if @@ -2744,9 +2797,9 @@ contains end subroutine z_base_mlv_gthzbuf ! - ! Scatter: + ! Scatter: ! Y(IDX(:),:) = beta*Y(IDX(:),:) + X(:) - ! + ! ! !> Function base_mlv_sctb !! \memberof psb_z_base_multivect_type @@ -2755,10 +2808,10 @@ contains !! \param n how many entries to consider !! \param idx(:) indices !! \param beta - !! \param x(:) + !! \param x(:) subroutine z_base_mlv_sctb(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_dpk_) :: beta, x(:) class(psb_z_base_multivect_type) :: y @@ -2773,7 +2826,7 @@ contains subroutine z_base_mlv_sctbr2(n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: n, idx(:) complex(psb_dpk_) :: beta, x(:,:) class(psb_z_base_multivect_type) :: y @@ -2788,7 +2841,7 @@ contains subroutine z_base_mlv_sctb_x(i,n,idx,x,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, n class(psb_i_base_vect_type) :: idx complex( psb_dpk_) :: beta, x(:) @@ -2800,14 +2853,14 @@ contains subroutine z_base_mlv_sctb_buf(i,iyb,n,idx,beta,y) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_) :: i, iyb, n class(psb_i_base_vect_type) :: idx complex(psb_dpk_) :: beta class(psb_z_base_multivect_type) :: y integer(psb_ipk_) :: nc - - if (.not.allocated(y%combuf)) then + + if (.not.allocated(y%combuf)) then call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf') return end if @@ -2816,19 +2869,18 @@ contains nc = y%get_ncols() call y%sct(n,idx%v(i:),y%combuf(iyb:),beta) call y%set_host() - + end subroutine z_base_mlv_sctb_buf ! !> Function base_device_wait: !! \memberof psb_z_base_vect_type !! \brief device_wait: base version is a no-op. - !! + !! ! subroutine z_base_mlv_device_wait() - implicit none - + implicit none + end subroutine z_base_mlv_device_wait end module psb_z_base_multivect_mod - diff --git a/base/modules/serial/psb_z_vect_mod.F90 b/base/modules/serial/psb_z_vect_mod.F90 index f6da1ded4..b65ba18bd 100644 --- a/base/modules/serial/psb_z_vect_mod.F90 +++ b/base/modules/serial/psb_z_vect_mod.F90 @@ -1,9 +1,9 @@ -! +! ! Parallel Sparse BLAS version 3.5 ! (C) Copyright 2006-2018 -! Salvatore Filippone -! Alfredo Buttari -! +! Salvatore Filippone +! Alfredo Buttari +! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions ! are met: @@ -15,7 +15,7 @@ ! 3. The name of the PSBLAS group or the names of its contributors may ! not be used to endorse or promote products derived from this ! software without specific written permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -27,15 +27,15 @@ ! 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. -! -! +! +! ! ! package: psb_z_vect_mod ! ! This module contains the definition of the psb_z_vect type which ! is the outer container for dense vectors. ! Therefore all methods simply invoke the corresponding methods of the -! inner component. +! inner component. ! module psb_z_vect_mod @@ -43,7 +43,7 @@ module psb_z_vect_mod use psb_i_vect_mod type psb_z_vect_type - class(psb_z_base_vect_type), allocatable :: v + class(psb_z_base_vect_type), allocatable :: v contains procedure, pass(x) :: get_nrows => z_vect_get_nrows procedure, pass(x) :: sizeof => z_vect_sizeof @@ -94,13 +94,16 @@ module psb_z_vect_mod procedure, pass(z) :: mlt_av => z_vect_mlt_av generic, public :: mlt => mlt_v, mlt_a, mlt_a_2,& & mlt_v_2, mlt_av, mlt_va + procedure, pass(x) :: div_v => z_vect_div_v + procedure, pass(z) :: div_a2 => z_vect_div_a2 + generic, public :: div => div_v, div_a2 procedure, pass(x) :: scal => z_vect_scal procedure, pass(x) :: absval1 => z_vect_absval1 procedure, pass(x) :: absval2 => z_vect_absval2 generic, public :: absval => absval1, absval2 procedure, pass(x) :: nrm2 => z_vect_nrm2 procedure, pass(x) :: amax => z_vect_amax - procedure, pass(x) :: asum => z_vect_asum + procedure, pass(x) :: asum => z_vect_asum end type psb_z_vect_type public :: psb_z_vect @@ -122,7 +125,7 @@ module psb_z_vect_mod private :: z_vect_dot_v, z_vect_dot_a, z_vect_axpby_v, z_vect_axpby_a, & & z_vect_mlt_v, z_vect_mlt_a, z_vect_mlt_a_2, z_vect_mlt_v_2, & & z_vect_mlt_va, z_vect_mlt_av, z_vect_scal, z_vect_absval1, & - & z_vect_absval2, z_vect_nrm2, z_vect_amax, z_vect_asum + & z_vect_absval2, z_vect_nrm2, z_vect_amax, z_vect_asum @@ -141,11 +144,11 @@ module psb_z_vect_mod contains - subroutine psb_z_set_vect_default(v) - implicit none + subroutine psb_z_set_vect_default(v) + implicit none class(psb_z_base_vect_type), intent(in) :: v - if (allocated(psb_z_base_vect_default)) then + if (allocated(psb_z_base_vect_default)) then deallocate(psb_z_base_vect_default) end if allocate(psb_z_base_vect_default, mold=v) @@ -153,7 +156,7 @@ contains end subroutine psb_z_set_vect_default function psb_z_get_vect_default(v) result(res) - implicit none + implicit none class(psb_z_vect_type), intent(in) :: v class(psb_z_base_vect_type), pointer :: res @@ -163,10 +166,10 @@ contains function psb_z_get_base_vect_default() result(res) - implicit none + implicit none class(psb_z_base_vect_type), pointer :: res - if (.not.allocated(psb_z_base_vect_default)) then + if (.not.allocated(psb_z_base_vect_default)) then allocate(psb_z_base_vect_type :: psb_z_base_vect_default) end if @@ -176,14 +179,14 @@ contains subroutine z_vect_clone(x,y,info) - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x class(psb_z_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info info = psb_success_ call y%free(info) - if ((info==0).and.allocated(x%v)) then + if ((info==0).and.allocated(x%v)) then call y%bld(x%get_vect(),mold=x%v) end if end subroutine z_vect_clone @@ -198,7 +201,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_z_get_base_vect_default()) @@ -220,7 +223,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_z_get_base_vect_default()) @@ -241,7 +244,7 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_z_get_base_vect_default()) @@ -304,7 +307,7 @@ contains end function size_const function z_vect_get_nrows(x) result(res) - implicit none + implicit none class(psb_z_vect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -312,7 +315,7 @@ contains end function z_vect_get_nrows function z_vect_sizeof(x) result(res) - implicit none + implicit none class(psb_z_vect_type), intent(in) :: x integer(psb_epk_) :: res res = 0 @@ -320,7 +323,7 @@ contains end function z_vect_sizeof function z_vect_get_fmt(x) result(res) - implicit none + implicit none class(psb_z_vect_type), intent(in) :: x character(len=5) :: res res = 'NULL' @@ -329,7 +332,7 @@ contains subroutine z_vect_all(n, x, info, mold) - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_z_vect_type), intent(inout) :: x class(psb_z_base_vect_type), intent(in), optional :: mold @@ -338,12 +341,12 @@ contains if (allocated(x%v)) & & call x%free(info) - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(psb_z_base_vect_type :: x%v,stat=info) endif - if (info == 0) then + if (info == 0) then call x%v%all(n,info) else info = psb_err_alloc_dealloc_ @@ -353,12 +356,12 @@ contains subroutine z_vect_reall(n, x, info) - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_z_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (.not.allocated(x%v)) & & call x%all(n,info) if (info == 0) & @@ -368,7 +371,7 @@ contains subroutine z_vect_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x if (allocated(x%v)) call x%v%zero() @@ -378,7 +381,7 @@ contains subroutine z_vect_asb(n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: n class(psb_z_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -424,12 +427,12 @@ contains subroutine z_vect_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%free(info) if (info == 0) deallocate(x%v,stat=info) end if @@ -438,7 +441,7 @@ contains subroutine z_vect_ins_a(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -448,7 +451,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ return end if @@ -459,7 +462,7 @@ contains subroutine z_vect_ins_v(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl class(psb_i_vect_type), intent(inout) :: irl @@ -469,7 +472,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then + if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then info = psb_err_invalid_vect_state_ return end if @@ -487,12 +490,12 @@ contains integer(psb_ipk_) :: info info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(tmp,stat=info,mold=mold) else allocate(tmp,stat=info,mold=psb_z_get_base_vect_default()) end if - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%sync() if (info == psb_success_) call tmp%bld(x%v%v) call x%v%free(info) @@ -503,7 +506,7 @@ contains subroutine z_vect_sync(x) - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -512,7 +515,7 @@ contains end subroutine z_vect_sync subroutine z_vect_set_sync(x) - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -521,7 +524,7 @@ contains end subroutine z_vect_set_sync subroutine z_vect_set_host(x) - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -530,7 +533,7 @@ contains end subroutine z_vect_set_host subroutine z_vect_set_dev(x) - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x if (allocated(x%v)) & @@ -539,7 +542,7 @@ contains end subroutine z_vect_set_dev function z_vect_is_sync(x) result(res) - implicit none + implicit none logical :: res class(psb_z_vect_type), intent(inout) :: x @@ -550,7 +553,7 @@ contains end function z_vect_is_sync function z_vect_is_host(x) result(res) - implicit none + implicit none logical :: res class(psb_z_vect_type), intent(inout) :: x @@ -561,11 +564,11 @@ contains end function z_vect_is_host function z_vect_is_dev(x) result(res) - implicit none + implicit none logical :: res class(psb_z_vect_type), intent(inout) :: x - res = .false. + res = .false. if (allocated(x%v)) & & res = x%v%is_dev() @@ -573,7 +576,7 @@ contains function z_vect_dot_v(n,x,y) result(res) - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x, y integer(psb_ipk_), intent(in) :: n complex(psb_dpk_) :: res @@ -585,7 +588,7 @@ contains end function z_vect_dot_v function z_vect_dot_a(n,x,y) result(res) - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x complex(psb_dpk_), intent(in) :: y(:) integer(psb_ipk_), intent(in) :: n @@ -599,14 +602,14 @@ contains subroutine z_vect_axpby_v(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m class(psb_z_vect_type), intent(inout) :: x class(psb_z_vect_type), intent(inout) :: y complex(psb_dpk_), intent (in) :: alpha, beta integer(psb_ipk_), intent(out) :: info - if (allocated(x%v).and.allocated(y%v)) then + if (allocated(x%v).and.allocated(y%v)) then call y%v%axpby(m,alpha,x%v,beta,info) else info = psb_err_invalid_vect_state_ @@ -616,7 +619,7 @@ contains subroutine z_vect_axpby_a(m,alpha, x, beta, y, info) use psi_serial_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m complex(psb_dpk_), intent(in) :: x(:) class(psb_z_vect_type), intent(inout) :: y @@ -631,10 +634,10 @@ contains subroutine z_vect_mlt_v(x, y, info) use psi_serial_mod - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x class(psb_z_vect_type), intent(inout) :: y - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -645,7 +648,7 @@ contains subroutine z_vect_mlt_a(x, y, info) use psi_serial_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: x(:) class(psb_z_vect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info @@ -661,7 +664,7 @@ contains subroutine z_vect_mlt_a_2(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: alpha,beta complex(psb_dpk_), intent(in) :: y(:) complex(psb_dpk_), intent(in) :: x(:) @@ -669,7 +672,7 @@ contains integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n - info = 0 + info = 0 if (allocated(z%v)) & & call z%v%mlt(alpha,x,y,beta,info) @@ -677,12 +680,12 @@ contains subroutine z_vect_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) use psi_serial_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: alpha,beta class(psb_z_vect_type), intent(inout) :: x class(psb_z_vect_type), intent(inout) :: y class(psb_z_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info character(len=1), intent(in), optional :: conjgx, conjgy integer(psb_ipk_) :: i, n @@ -696,12 +699,12 @@ contains subroutine z_vect_mlt_av(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: alpha,beta complex(psb_dpk_), intent(in) :: x(:) class(psb_z_vect_type), intent(inout) :: y class(psb_z_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -712,12 +715,12 @@ contains subroutine z_vect_mlt_va(alpha,x,y,beta,z,info) use psi_serial_mod - implicit none + implicit none complex(psb_dpk_), intent(in) :: alpha,beta complex(psb_dpk_), intent(in) :: y(:) class(psb_z_vect_type), intent(inout) :: x class(psb_z_vect_type), intent(inout) :: z - integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_), intent(out) :: info integer(psb_ipk_) :: i, n info = 0 @@ -727,9 +730,38 @@ contains end subroutine z_vect_mlt_va + subroutine z_vect_div_v(x, y, info) + use psi_serial_mod + implicit none + class(psb_z_vect_type), intent(inout) :: x + class(psb_z_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (allocated(x%v).and.allocated(y%v)) & + & call x%v%div(y%v,info) + + end subroutine z_vect_div_v + + subroutine z_vect_div_a2(x, y, z, info) + use psi_serial_mod + implicit none + complex(psb_dpk_), intent(in) :: x(:) + complex(psb_dpk_), intent(in) :: y(:) + class(psb_z_vect_type), intent(inout) :: z + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + + info = 0 + if (allocated(z%v)) & + & call z%v%div(x,y,info) + + end subroutine z_vect_div_a2 + subroutine z_vect_scal(alpha, x) use psi_serial_mod - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x complex(psb_dpk_), intent (in) :: alpha @@ -749,19 +781,19 @@ contains class(psb_z_vect_type), intent(inout) :: x class(psb_z_vect_type), intent(inout) :: y - if (allocated(x%v)) then + if (allocated(x%v)) then if (.not.allocated(y%v)) call y%bld(psb_size(x%v%v)) call x%v%absval(y%v) end if end subroutine z_vect_absval2 function z_vect_nrm2(n,x) result(res) - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res - if (allocated(x%v)) then + if (allocated(x%v)) then res = x%v%nrm2(n) else res = dzero @@ -770,12 +802,12 @@ contains end function z_vect_nrm2 function z_vect_amax(n,x) result(res) - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res - if (allocated(x%v)) then + if (allocated(x%v)) then res = x%v%amax(n) else res = dzero @@ -784,12 +816,12 @@ contains end function z_vect_amax function z_vect_asum(n,x) result(res) - implicit none + implicit none class(psb_z_vect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n real(psb_dpk_) :: res - if (allocated(x%v)) then + if (allocated(x%v)) then res = x%v%asum(n) else res = dzero @@ -812,7 +844,7 @@ module psb_z_multivect_mod !private type psb_z_multivect_type - class(psb_z_base_multivect_type), allocatable :: v + class(psb_z_base_multivect_type), allocatable :: v contains procedure, pass(x) :: get_nrows => z_vect_get_nrows procedure, pass(x) :: get_ncols => z_vect_get_ncols @@ -886,11 +918,11 @@ module psb_z_multivect_mod contains - subroutine psb_z_set_multivect_default(v) - implicit none + subroutine psb_z_set_multivect_default(v) + implicit none class(psb_z_base_multivect_type), intent(in) :: v - if (allocated(psb_z_base_multivect_default)) then + if (allocated(psb_z_base_multivect_default)) then deallocate(psb_z_base_multivect_default) end if allocate(psb_z_base_multivect_default, mold=v) @@ -898,7 +930,7 @@ contains end subroutine psb_z_set_multivect_default function psb_z_get_multivect_default(v) result(res) - implicit none + implicit none class(psb_z_multivect_type), intent(in) :: v class(psb_z_base_multivect_type), pointer :: res @@ -908,10 +940,10 @@ contains function psb_z_get_base_multivect_default() result(res) - implicit none + implicit none class(psb_z_base_multivect_type), pointer :: res - if (.not.allocated(psb_z_base_multivect_default)) then + if (.not.allocated(psb_z_base_multivect_default)) then allocate(psb_z_base_multivect_type :: psb_z_base_multivect_default) end if @@ -921,14 +953,14 @@ contains subroutine z_vect_clone(x,y,info) - implicit none + implicit none class(psb_z_multivect_type), intent(inout) :: x class(psb_z_multivect_type), intent(inout) :: y integer(psb_ipk_), intent(out) :: info info = psb_success_ call y%free(info) - if ((info==0).and.allocated(x%v)) then + if ((info==0).and.allocated(x%v)) then call y%bld(x%get_vect(),mold=x%v) end if end subroutine z_vect_clone @@ -941,7 +973,7 @@ contains class(psb_z_base_multivect_type), pointer :: mld info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_z_get_base_multivect_default()) @@ -959,7 +991,7 @@ contains integer(psb_ipk_) :: info info = psb_success_ - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(x%v,stat=info, mold=psb_z_get_base_multivect_default()) @@ -1019,7 +1051,7 @@ contains end function size_const function z_vect_get_nrows(x) result(res) - implicit none + implicit none class(psb_z_multivect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -1027,7 +1059,7 @@ contains end function z_vect_get_nrows function z_vect_get_ncols(x) result(res) - implicit none + implicit none class(psb_z_multivect_type), intent(in) :: x integer(psb_ipk_) :: res res = 0 @@ -1035,7 +1067,7 @@ contains end function z_vect_get_ncols function z_vect_sizeof(x) result(res) - implicit none + implicit none class(psb_z_multivect_type), intent(in) :: x integer(psb_epk_) :: res res = 0 @@ -1043,7 +1075,7 @@ contains end function z_vect_sizeof function z_vect_get_fmt(x) result(res) - implicit none + implicit none class(psb_z_multivect_type), intent(in) :: x character(len=5) :: res res = 'NULL' @@ -1052,18 +1084,18 @@ contains subroutine z_vect_all(m,n, x, info, mold) - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_z_multivect_type), intent(out) :: x class(psb_z_base_multivect_type), intent(in), optional :: mold integer(psb_ipk_), intent(out) :: info - if (present(mold)) then + if (present(mold)) then allocate(x%v,stat=info,mold=mold) else allocate(psb_z_base_multivect_type :: x%v,stat=info) endif - if (info == 0) then + if (info == 0) then call x%v%all(m,n,info) else info = psb_err_alloc_dealloc_ @@ -1073,12 +1105,12 @@ contains subroutine z_vect_reall(m,n, x, info) - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_z_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info - info = 0 + info = 0 if (.not.allocated(x%v)) & & call x%all(m,n,info) if (info == 0) & @@ -1088,7 +1120,7 @@ contains subroutine z_vect_zero(x) use psi_serial_mod - implicit none + implicit none class(psb_z_multivect_type), intent(inout) :: x if (allocated(x%v)) call x%v%zero() @@ -1098,7 +1130,7 @@ contains subroutine z_vect_asb(m,n, x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none integer(psb_ipk_), intent(in) :: m,n class(psb_z_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info @@ -1109,7 +1141,7 @@ contains end subroutine z_vect_asb subroutine z_vect_sync(x) - implicit none + implicit none class(psb_z_multivect_type), intent(inout) :: x if (allocated(x%v)) & @@ -1177,12 +1209,12 @@ contains subroutine z_vect_free(x, info) use psi_serial_mod use psb_realloc_mod - implicit none + implicit none class(psb_z_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(out) :: info info = 0 - if (allocated(x%v)) then + if (allocated(x%v)) then call x%v%free(info) if (info == 0) deallocate(x%v,stat=info) end if @@ -1191,7 +1223,7 @@ contains subroutine z_vect_ins(n,irl,val,dupl,x,info) use psi_serial_mod - implicit none + implicit none class(psb_z_multivect_type), intent(inout) :: x integer(psb_ipk_), intent(in) :: n, dupl integer(psb_ipk_), intent(in) :: irl(:) @@ -1201,7 +1233,7 @@ contains integer(psb_ipk_) :: i info = 0 - if (.not.allocated(x%v)) then + if (.not.allocated(x%v)) then info = psb_err_invalid_vect_state_ return end if @@ -1217,12 +1249,12 @@ contains class(psb_z_base_multivect_type), allocatable :: tmp integer(psb_ipk_) :: info - if (present(mold)) then + if (present(mold)) then allocate(tmp,stat=info,mold=mold) else allocate(tmp,stat=info, mold=psb_z_get_base_multivect_default()) - endif - if (allocated(x%v)) then + endif + if (allocated(x%v)) then call x%v%sync() if (info == psb_success_) call tmp%bld(x%v%v) call x%v%free(info) @@ -1232,7 +1264,7 @@ contains !!$ function z_vect_dot_v(n,x,y) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_z_multivect_type), intent(inout) :: x, y !!$ integer(psb_ipk_), intent(in) :: n !!$ complex(psb_dpk_) :: res @@ -1244,28 +1276,28 @@ contains !!$ end function z_vect_dot_v !!$ !!$ function z_vect_dot_a(n,x,y) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_z_multivect_type), intent(inout) :: x !!$ complex(psb_dpk_), intent(in) :: y(:) !!$ integer(psb_ipk_), intent(in) :: n !!$ complex(psb_dpk_) :: res -!!$ +!!$ !!$ res = zzero !!$ if (allocated(x%v)) & !!$ & res = x%v%dot(n,y) -!!$ +!!$ !!$ end function z_vect_dot_a -!!$ +!!$ !!$ subroutine z_vect_axpby_v(m,alpha, x, beta, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ integer(psb_ipk_), intent(in) :: m !!$ class(psb_z_multivect_type), intent(inout) :: x !!$ class(psb_z_multivect_type), intent(inout) :: y !!$ complex(psb_dpk_), intent (in) :: alpha, beta !!$ integer(psb_ipk_), intent(out) :: info -!!$ -!!$ if (allocated(x%v).and.allocated(y%v)) then +!!$ +!!$ if (allocated(x%v).and.allocated(y%v)) then !!$ call y%v%axpby(m,alpha,x%v,beta,info) !!$ else !!$ info = psb_err_invalid_vect_state_ @@ -1275,25 +1307,25 @@ contains !!$ !!$ subroutine z_vect_axpby_a(m,alpha, x, beta, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ integer(psb_ipk_), intent(in) :: m !!$ complex(psb_dpk_), intent(in) :: x(:) !!$ class(psb_z_multivect_type), intent(inout) :: y !!$ complex(psb_dpk_), intent (in) :: alpha, beta !!$ integer(psb_ipk_), intent(out) :: info -!!$ +!!$ !!$ if (allocated(y%v)) & !!$ & call y%v%axpby(m,alpha,x,beta,info) -!!$ +!!$ !!$ end subroutine z_vect_axpby_a !!$ -!!$ +!!$ !!$ subroutine z_vect_mlt_v(x, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ class(psb_z_multivect_type), intent(inout) :: x !!$ class(psb_z_multivect_type), intent(inout) :: y -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 @@ -1304,7 +1336,7 @@ contains !!$ !!$ subroutine z_vect_mlt_a(x, y, info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_dpk_), intent(in) :: x(:) !!$ class(psb_z_multivect_type), intent(inout) :: y !!$ integer(psb_ipk_), intent(out) :: info @@ -1314,13 +1346,13 @@ contains !!$ info = 0 !!$ if (allocated(y%v)) & !!$ & call y%v%mlt(x,info) -!!$ +!!$ !!$ end subroutine z_vect_mlt_a !!$ !!$ !!$ subroutine z_vect_mlt_a_2(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_dpk_), intent(in) :: alpha,beta !!$ complex(psb_dpk_), intent(in) :: y(:) !!$ complex(psb_dpk_), intent(in) :: x(:) @@ -1328,20 +1360,20 @@ contains !!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ -!!$ info = 0 +!!$ info = 0 !!$ if (allocated(z%v)) & !!$ & call z%v%mlt(alpha,x,y,beta,info) -!!$ +!!$ !!$ end subroutine z_vect_mlt_a_2 !!$ !!$ subroutine z_vect_mlt_v_2(alpha,x,y,beta,z,info,conjgx,conjgy) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_dpk_), intent(in) :: alpha,beta !!$ class(psb_z_multivect_type), intent(inout) :: x !!$ class(psb_z_multivect_type), intent(inout) :: y !!$ class(psb_z_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ character(len=1), intent(in), optional :: conjgx, conjgy !!$ !!$ integer(psb_ipk_) :: i, n @@ -1355,12 +1387,12 @@ contains !!$ !!$ subroutine z_vect_mlt_av(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_dpk_), intent(in) :: alpha,beta !!$ complex(psb_dpk_), intent(in) :: x(:) !!$ class(psb_z_multivect_type), intent(inout) :: y !!$ class(psb_z_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 @@ -1371,16 +1403,16 @@ contains !!$ !!$ subroutine z_vect_mlt_va(alpha,x,y,beta,z,info) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ complex(psb_dpk_), intent(in) :: alpha,beta !!$ complex(psb_dpk_), intent(in) :: y(:) !!$ class(psb_z_multivect_type), intent(inout) :: x !!$ class(psb_z_multivect_type), intent(inout) :: z -!!$ integer(psb_ipk_), intent(out) :: info +!!$ integer(psb_ipk_), intent(out) :: info !!$ integer(psb_ipk_) :: i, n !!$ !!$ info = 0 -!!$ +!!$ !!$ if (allocated(z%v).and.allocated(x%v)) & !!$ & call z%v%mlt(alpha,x%v,y,beta,info) !!$ @@ -1388,36 +1420,36 @@ contains !!$ !!$ subroutine z_vect_scal(alpha, x) !!$ use psi_serial_mod -!!$ implicit none +!!$ implicit none !!$ class(psb_z_multivect_type), intent(inout) :: x !!$ complex(psb_dpk_), intent (in) :: alpha -!!$ +!!$ !!$ if (allocated(x%v)) call x%v%scal(alpha) !!$ !!$ end subroutine z_vect_scal !!$ !!$ !!$ function z_vect_nrm2(n,x) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_z_multivect_type), intent(inout) :: x !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_dpk_) :: res -!!$ -!!$ if (allocated(x%v)) then +!!$ +!!$ if (allocated(x%v)) then !!$ res = x%v%nrm2(n) !!$ else !!$ res = dzero !!$ end if !!$ !!$ end function z_vect_nrm2 -!!$ +!!$ !!$ function z_vect_amax(n,x) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_z_multivect_type), intent(inout) :: x !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_dpk_) :: res !!$ -!!$ if (allocated(x%v)) then +!!$ if (allocated(x%v)) then !!$ res = x%v%amax(n) !!$ else !!$ res = dzero @@ -1426,12 +1458,12 @@ contains !!$ end function z_vect_amax !!$ !!$ function z_vect_asum(n,x) result(res) -!!$ implicit none +!!$ implicit none !!$ class(psb_z_multivect_type), intent(inout) :: x !!$ integer(psb_ipk_), intent(in) :: n !!$ real(psb_dpk_) :: res !!$ -!!$ if (allocated(x%v)) then +!!$ if (allocated(x%v)) then !!$ res = x%v%asum(n) !!$ else !!$ res = dzero diff --git a/base/psblas/Makefile b/base/psblas/Makefile index bc583f17f..6e1b1a70a 100644 --- a/base/psblas/Makefile +++ b/base/psblas/Makefile @@ -10,25 +10,26 @@ OBJS= psb_ddot.o psb_damax.o psb_dasum.o psb_daxpby.o\ psb_snrm2.o psb_snrmi.o psb_sspmm.o psb_sspsm.o\ psb_camax.o psb_casum.o psb_caxpby.o psb_cdot.o \ psb_cnrm2.o psb_cnrmi.o psb_cspmm.o psb_cspsm.o \ - psb_cmlt_vect.o psb_dmlt_vect.o psb_zmlt_vect.o psb_smlt_vect.o + psb_cmlt_vect.o psb_dmlt_vect.o psb_zmlt_vect.o psb_smlt_vect.o\ + psb_cdiv_vect.o psb_ddiv_vect.o psb_zdiv_vect.o psb_sdiv_vect.o LIBDIR=.. INCDIR=.. MODDIR=../modules -FINCLUDES=$(FMFLAG). $(FMFLAG)$(MODDIR) $(FMFLAG)$(INCDIR) +FINCLUDES=$(FMFLAG). $(FMFLAG)$(MODDIR) $(FMFLAG)$(INCDIR) -lib: $(OBJS) +lib: $(OBJS) $(AR) $(LIBDIR)/$(LIBNAME) $(OBJS) $(RANLIB) $(LIBDIR)/$(LIBNAME) -#$(F90_PSDOBJS): $(MODS) +#$(F90_PSDOBJS): $(MODS) veryclean: clean /bin/rm -f $(LIBNAME) -clean: +clean: /bin/rm -f $(OBJS) $(LOCAL_MODS) veryclean: clean diff --git a/base/psblas/psb_cdiv_vect.f90 b/base/psblas/psb_cdiv_vect.f90 new file mode 100644 index 000000000..38c7ce6a2 --- /dev/null +++ b/base/psblas/psb_cdiv_vect.f90 @@ -0,0 +1,105 @@ +! +! Parallel Sparse BLAS version 3.5 +! (C) Copyright 2006-2018 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: psb_cdiv_vect + +subroutine psb_cdiv_vect(x,y,desc_a,info) + use psb_base_mod, psb_protect_name => psb_cdiv_vect + implicit none + type(psb_c_vect_type), intent (inout) :: x + type(psb_c_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_c_div_vect' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if(desc_a%get_local_rows() > 0) then + call x%div(y,info) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_cdiv_vect diff --git a/base/psblas/psb_ddiv_vect.f90 b/base/psblas/psb_ddiv_vect.f90 new file mode 100644 index 000000000..d9ab02037 --- /dev/null +++ b/base/psblas/psb_ddiv_vect.f90 @@ -0,0 +1,105 @@ +! +! Parallel Sparse BLAS version 3.5 +! (C) Copyright 2006-2018 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: psb_ddiv_vect + +subroutine psb_ddiv_vect(x,y,desc_a,info) + use psb_base_mod, psb_protect_name => psb_ddiv_vect + implicit none + type(psb_d_vect_type), intent (inout) :: x + type(psb_d_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_d_div_vect' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if(desc_a%get_local_rows() > 0) then + call x%div(y,info) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_ddiv_vect diff --git a/base/psblas/psb_sdiv_vect.f90 b/base/psblas/psb_sdiv_vect.f90 new file mode 100644 index 000000000..99a1ce7ca --- /dev/null +++ b/base/psblas/psb_sdiv_vect.f90 @@ -0,0 +1,105 @@ +! +! Parallel Sparse BLAS version 3.5 +! (C) Copyright 2006-2018 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: psb_sdiv_vect + +subroutine psb_sdiv_vect(x,y,desc_a,info) + use psb_base_mod, psb_protect_name => psb_sdiv_vect + implicit none + type(psb_s_vect_type), intent (inout) :: x + type(psb_s_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_s_div_vect' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if(desc_a%get_local_rows() > 0) then + call x%div(y,info) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_sdiv_vect diff --git a/base/psblas/psb_zdiv_vect.f90 b/base/psblas/psb_zdiv_vect.f90 new file mode 100644 index 000000000..949cbf7d5 --- /dev/null +++ b/base/psblas/psb_zdiv_vect.f90 @@ -0,0 +1,105 @@ +! +! Parallel Sparse BLAS version 3.5 +! (C) Copyright 2006-2018 +! Salvatore Filippone +! Alfredo Buttari +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions +! are met: +! 1. Redistributions of source code must retain the above copyright +! notice, this list of conditions and the following disclaimer. +! 2. Redistributions in binary form must reproduce the above copyright +! notice, this list of conditions, and the following disclaimer in the +! documentation and/or other materials provided with the distribution. +! 3. The name of the PSBLAS group or the names of its contributors may +! not be used to endorse or promote products derived from this +! software without specific written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS +! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +! POSSIBILITY OF SUCH DAMAGE. +! +! +! File: psb_zdiv_vect + +subroutine psb_zdiv_vect(x,y,desc_a,info) + use psb_base_mod, psb_protect_name => psb_zdiv_vect + implicit none + type(psb_z_vect_type), intent (inout) :: x + type(psb_z_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_z_div_vect' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if(desc_a%get_local_rows() > 0) then + call x%div(y,info) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_zdiv_vect diff --git a/test/kernel/vecoperation.f90 b/test/kernel/vecoperation.f90 index 732a47087..e9cc88a8d 100644 --- a/test/kernel/vecoperation.f90 +++ b/test/kernel/vecoperation.f90 @@ -55,6 +55,7 @@ program vecoperation integer(psb_lpk_), allocatable :: myidx(:) real(psb_dpk_) :: zt(1), dotresult, norm2, norm1, norminf character(len=20) :: name,ch_err,readinput + real(psb_dpk_), allocatable :: vx(:), vy(:) info=psb_success_ @@ -139,6 +140,12 @@ program vecoperation t2 = psb_wtime() - t1 if (iam == psb_root_) write(psb_out_unit,'("Overall vector creation time : ",es12.5)')t2 + if (iam == psb_root_) then + vx = x%get_vect() + write(psb_out_unit,'("x = ",es12.1)')vx(:) + vy = y%get_vect() + write(psb_out_unit,'("y = ",es12.1)')vy(:) + end if ! ! Vector operations @@ -150,8 +157,33 @@ program vecoperation norminf = psb_normi(x,desc_a,info) if (iam == psb_root_) write(psb_out_unit,'("\|x\|_inf : ",es12.5," \|x\|_1 :",es12.5," \|x\|_2",es12.5)')norminf,norm1,norm2 call psb_geaxpby(1.0_psb_dpk_, x, 1.0_psb_dpk_, y, desc_a, info) ! \alpha x + \beta y + + if (iam == psb_root_) then + vx = x%get_vect() + write(psb_out_unit,'("x = ",es12.1)')vx(:) + vy = y%get_vect() + write(psb_out_unit,'("y = ",es12.1)')vy(:) + end if + call psb_gemlt(x,y,desc_a,info) + if (iam == psb_root_) then + vx = x%get_vect() + write(psb_out_unit,'("x = ",es12.1)')vx(:) + vy = y%get_vect() + write(psb_out_unit,'("y = ",es12.1)')vy(:) + end if + + call psb_gediv(x,y,desc_a,info) + + if (iam == psb_root_) then + vx = x%get_vect() + write(psb_out_unit,'("x = ",es12.1)')vx(:) + vy = y%get_vect() + write(psb_out_unit,'("y = ",es12.1)')vy(:) + end if + + ! From db7b882e9ce97ae7e734062b0a27779ddb431c41 Mon Sep 17 00:00:00 2001 From: cirdans-home Date: Wed, 20 Nov 2019 18:22:38 +0100 Subject: [PATCH 03/61] entrywise divide with zero check --- base/modules/psblas/psb_c_psblas_mod.F90 | 9 +++ base/modules/psblas/psb_d_psblas_mod.F90 | 9 +++ base/modules/psblas/psb_s_psblas_mod.F90 | 9 +++ base/modules/psblas/psb_z_psblas_mod.F90 | 9 +++ base/modules/serial/psb_c_base_vect_mod.f90 | 68 +++++++++++++++++-- base/modules/serial/psb_c_vect_mod.F90 | 35 +++++++++- base/modules/serial/psb_d_base_vect_mod.f90 | 68 +++++++++++++++++-- base/modules/serial/psb_d_vect_mod.F90 | 35 +++++++++- base/modules/serial/psb_s_base_vect_mod.f90 | 68 +++++++++++++++++-- base/modules/serial/psb_s_vect_mod.F90 | 35 +++++++++- base/modules/serial/psb_z_base_vect_mod.f90 | 68 +++++++++++++++++-- base/modules/serial/psb_z_vect_mod.F90 | 35 +++++++++- base/psblas/psb_cdiv_vect.f90 | 74 +++++++++++++++++++++ base/psblas/psb_ddiv_vect.f90 | 74 +++++++++++++++++++++ base/psblas/psb_sdiv_vect.f90 | 74 +++++++++++++++++++++ base/psblas/psb_zdiv_vect.f90 | 74 +++++++++++++++++++++ 16 files changed, 724 insertions(+), 20 deletions(-) diff --git a/base/modules/psblas/psb_c_psblas_mod.F90 b/base/modules/psblas/psb_c_psblas_mod.F90 index 1e16312d4..8e9a286a0 100644 --- a/base/modules/psblas/psb_c_psblas_mod.F90 +++ b/base/modules/psblas/psb_c_psblas_mod.F90 @@ -448,6 +448,15 @@ module psb_c_psblas_mod type(psb_desc_type), intent (in) :: desc_a integer(psb_ipk_), intent(out) :: info end subroutine psb_cdiv_vect + subroutine psb_cdiv_vect_check(x,y,desc_a,info,flag) + import :: psb_desc_type, psb_ipk_, & + & psb_c_vect_type + type(psb_c_vect_type), intent (inout) :: x + type(psb_c_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + logical, intent(in) :: flag + end subroutine psb_cdiv_vect_check end interface end module psb_c_psblas_mod diff --git a/base/modules/psblas/psb_d_psblas_mod.F90 b/base/modules/psblas/psb_d_psblas_mod.F90 index f7bdfa8f1..993ac5422 100644 --- a/base/modules/psblas/psb_d_psblas_mod.F90 +++ b/base/modules/psblas/psb_d_psblas_mod.F90 @@ -448,6 +448,15 @@ module psb_d_psblas_mod type(psb_desc_type), intent (in) :: desc_a integer(psb_ipk_), intent(out) :: info end subroutine psb_ddiv_vect + subroutine psb_ddiv_vect_check(x,y,desc_a,info,flag) + import :: psb_desc_type, psb_ipk_, & + & psb_d_vect_type + type(psb_d_vect_type), intent (inout) :: x + type(psb_d_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + logical, intent(in) :: flag + end subroutine psb_ddiv_vect_check end interface end module psb_d_psblas_mod diff --git a/base/modules/psblas/psb_s_psblas_mod.F90 b/base/modules/psblas/psb_s_psblas_mod.F90 index af2c17f6d..1a2347d1a 100644 --- a/base/modules/psblas/psb_s_psblas_mod.F90 +++ b/base/modules/psblas/psb_s_psblas_mod.F90 @@ -448,6 +448,15 @@ module psb_s_psblas_mod type(psb_desc_type), intent (in) :: desc_a integer(psb_ipk_), intent(out) :: info end subroutine psb_sdiv_vect + subroutine psb_sdiv_vect_check(x,y,desc_a,info,flag) + import :: psb_desc_type, psb_ipk_, & + & psb_s_vect_type + type(psb_s_vect_type), intent (inout) :: x + type(psb_s_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + logical, intent(in) :: flag + end subroutine psb_sdiv_vect_check end interface end module psb_s_psblas_mod diff --git a/base/modules/psblas/psb_z_psblas_mod.F90 b/base/modules/psblas/psb_z_psblas_mod.F90 index 807ec7cd8..7fd96c4ce 100644 --- a/base/modules/psblas/psb_z_psblas_mod.F90 +++ b/base/modules/psblas/psb_z_psblas_mod.F90 @@ -448,6 +448,15 @@ module psb_z_psblas_mod type(psb_desc_type), intent (in) :: desc_a integer(psb_ipk_), intent(out) :: info end subroutine psb_zdiv_vect + subroutine psb_zdiv_vect_check(x,y,desc_a,info,flag) + import :: psb_desc_type, psb_ipk_, & + & psb_z_vect_type + type(psb_z_vect_type), intent (inout) :: x + type(psb_z_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + logical, intent(in) :: flag + end subroutine psb_zdiv_vect_check end interface end module psb_z_psblas_mod diff --git a/base/modules/serial/psb_c_base_vect_mod.f90 b/base/modules/serial/psb_c_base_vect_mod.f90 index d95314747..3927a60b1 100644 --- a/base/modules/serial/psb_c_base_vect_mod.f90 +++ b/base/modules/serial/psb_c_base_vect_mod.f90 @@ -166,9 +166,11 @@ module psb_c_base_vect_mod ! ! Vector-Vector operations ! - procedure, pass(x) :: div_v => c_base_div_v - procedure, pass(z) :: div_a2 => c_base_div_a2 - generic, public :: div => div_v, div_a2 + procedure, pass(x) :: div_v => c_base_div_v + procedure, pass(x) :: div_v_check => c_base_div_v_check + procedure, pass(z) :: div_a2 => c_base_div_a2 + procedure, pass(z) :: div_a2_check => c_base_div_a2_check + generic, public :: div => div_v, div_v_check, div_a2, div_a2_check ! ! Scaling and norms ! @@ -1205,10 +1207,32 @@ contains end subroutine c_base_div_v ! + !> Function base_div_v_check + !! \memberof psb_c_base_vect_type + !! \brief Vector entry-by-entry divide by a vector x=x/y + !! \param y The array to be divided by + !! \param info return code + !! + subroutine c_base_div_v_check(x, y, info, flag) + use psi_serial_mod + implicit none + class(psb_c_base_vect_type), intent(inout) :: x + class(psb_c_base_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + logical, intent(in) :: flag + + info = 0 + if (x%is_dev()) call x%sync() + call x%div(x%v,y%v,info,flag) + + + end subroutine c_base_div_v_check + ! !> Function base_div_a2 !! \memberof psb_c_base_vect_type !! \brief Entry-by-entry divide between normal array x=x/y - !! \param x(:) The array to be multiplied by + !! \param y(:) The array to be divided by !! \param info return code !! subroutine c_base_div_a2(x, y, z, info) @@ -1229,7 +1253,43 @@ contains end do end subroutine c_base_div_a2 + ! + !> Function base_div_a2_check + !! \memberof psb_c_base_vect_type + !! \brief Entry-by-entry divide between normal array x=x/y and check if y(i) + !! is different from zero + !! \param y(:) The array to be dived by + !! \param info return code + !! + subroutine c_base_div_a2_check(x, y, z, info, flag) + use psi_serial_mod + implicit none + class(psb_c_base_vect_type), intent(inout) :: z + complex(psb_spk_), intent(in) :: x(:) + complex(psb_spk_), intent(in) :: y(:) + integer(psb_ipk_), intent(out) :: info + logical, intent(in) :: flag + integer(psb_ipk_) :: i, n + if (flag .eqv. .false.) then + call c_base_div_a2(x, y, z, info) + else + info = 0 + if (z%is_dev()) call z%sync() + + n = min(size(y), size(x)) + do i=1, n + if (y(i) /= 0) then + z%v(i) = x(i)/y(i) + else + info = 1 + exit + end if + end do + end if + + + end subroutine c_base_div_a2_check ! diff --git a/base/modules/serial/psb_c_vect_mod.F90 b/base/modules/serial/psb_c_vect_mod.F90 index 02965a3c3..d4eb5a2a4 100644 --- a/base/modules/serial/psb_c_vect_mod.F90 +++ b/base/modules/serial/psb_c_vect_mod.F90 @@ -95,8 +95,10 @@ module psb_c_vect_mod generic, public :: mlt => mlt_v, mlt_a, mlt_a_2,& & mlt_v_2, mlt_av, mlt_va procedure, pass(x) :: div_v => c_vect_div_v + procedure, pass(x) :: div_v_check => c_vect_div_v_check procedure, pass(z) :: div_a2 => c_vect_div_a2 - generic, public :: div => div_v, div_a2 + procedure, pass(z) :: div_a2_check => c_vect_div_a2_check + generic, public :: div => div_v, div_v_check, div_a2, div_a2_check procedure, pass(x) :: scal => c_vect_scal procedure, pass(x) :: absval1 => c_vect_absval1 procedure, pass(x) :: absval2 => c_vect_absval2 @@ -744,6 +746,21 @@ contains end subroutine c_vect_div_v + subroutine c_vect_div_v_check(x, y, info, flag) + use psi_serial_mod + implicit none + class(psb_c_vect_type), intent(inout) :: x + class(psb_c_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + logical, intent(in) :: flag + + info = 0 + if (allocated(x%v).and.allocated(y%v)) & + & call x%v%div(y%v,info,flag) + + end subroutine c_vect_div_v_check + subroutine c_vect_div_a2(x, y, z, info) use psi_serial_mod implicit none @@ -759,6 +776,22 @@ contains end subroutine c_vect_div_a2 + subroutine c_vect_div_a2_check(x, y, z, info,flag) + use psi_serial_mod + implicit none + complex(psb_spk_), intent(in) :: x(:) + complex(psb_spk_), intent(in) :: y(:) + class(psb_c_vect_type), intent(inout) :: z + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + logical, intent(in) :: flag + + info = 0 + if (allocated(z%v)) & + & call z%v%div(x,y,info,flag) + + end subroutine c_vect_div_a2_check + subroutine c_vect_scal(alpha, x) use psi_serial_mod implicit none diff --git a/base/modules/serial/psb_d_base_vect_mod.f90 b/base/modules/serial/psb_d_base_vect_mod.f90 index 4d3bb1617..3d00bbef8 100644 --- a/base/modules/serial/psb_d_base_vect_mod.f90 +++ b/base/modules/serial/psb_d_base_vect_mod.f90 @@ -166,9 +166,11 @@ module psb_d_base_vect_mod ! ! Vector-Vector operations ! - procedure, pass(x) :: div_v => d_base_div_v - procedure, pass(z) :: div_a2 => d_base_div_a2 - generic, public :: div => div_v, div_a2 + procedure, pass(x) :: div_v => d_base_div_v + procedure, pass(x) :: div_v_check => d_base_div_v_check + procedure, pass(z) :: div_a2 => d_base_div_a2 + procedure, pass(z) :: div_a2_check => d_base_div_a2_check + generic, public :: div => div_v, div_v_check, div_a2, div_a2_check ! ! Scaling and norms ! @@ -1205,10 +1207,32 @@ contains end subroutine d_base_div_v ! + !> Function base_div_v_check + !! \memberof psb_d_base_vect_type + !! \brief Vector entry-by-entry divide by a vector x=x/y + !! \param y The array to be divided by + !! \param info return code + !! + subroutine d_base_div_v_check(x, y, info, flag) + use psi_serial_mod + implicit none + class(psb_d_base_vect_type), intent(inout) :: x + class(psb_d_base_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + logical, intent(in) :: flag + + info = 0 + if (x%is_dev()) call x%sync() + call x%div(x%v,y%v,info,flag) + + + end subroutine d_base_div_v_check + ! !> Function base_div_a2 !! \memberof psb_d_base_vect_type !! \brief Entry-by-entry divide between normal array x=x/y - !! \param x(:) The array to be multiplied by + !! \param y(:) The array to be divided by !! \param info return code !! subroutine d_base_div_a2(x, y, z, info) @@ -1229,7 +1253,43 @@ contains end do end subroutine d_base_div_a2 + ! + !> Function base_div_a2_check + !! \memberof psb_d_base_vect_type + !! \brief Entry-by-entry divide between normal array x=x/y and check if y(i) + !! is different from zero + !! \param y(:) The array to be dived by + !! \param info return code + !! + subroutine d_base_div_a2_check(x, y, z, info, flag) + use psi_serial_mod + implicit none + class(psb_d_base_vect_type), intent(inout) :: z + real(psb_dpk_), intent(in) :: x(:) + real(psb_dpk_), intent(in) :: y(:) + integer(psb_ipk_), intent(out) :: info + logical, intent(in) :: flag + integer(psb_ipk_) :: i, n + if (flag .eqv. .false.) then + call d_base_div_a2(x, y, z, info) + else + info = 0 + if (z%is_dev()) call z%sync() + + n = min(size(y), size(x)) + do i=1, n + if (y(i) /= 0) then + z%v(i) = x(i)/y(i) + else + info = 1 + exit + end if + end do + end if + + + end subroutine d_base_div_a2_check ! diff --git a/base/modules/serial/psb_d_vect_mod.F90 b/base/modules/serial/psb_d_vect_mod.F90 index 469cb56df..e7cf67573 100644 --- a/base/modules/serial/psb_d_vect_mod.F90 +++ b/base/modules/serial/psb_d_vect_mod.F90 @@ -95,8 +95,10 @@ module psb_d_vect_mod generic, public :: mlt => mlt_v, mlt_a, mlt_a_2,& & mlt_v_2, mlt_av, mlt_va procedure, pass(x) :: div_v => d_vect_div_v + procedure, pass(x) :: div_v_check => d_vect_div_v_check procedure, pass(z) :: div_a2 => d_vect_div_a2 - generic, public :: div => div_v, div_a2 + procedure, pass(z) :: div_a2_check => d_vect_div_a2_check + generic, public :: div => div_v, div_v_check, div_a2, div_a2_check procedure, pass(x) :: scal => d_vect_scal procedure, pass(x) :: absval1 => d_vect_absval1 procedure, pass(x) :: absval2 => d_vect_absval2 @@ -744,6 +746,21 @@ contains end subroutine d_vect_div_v + subroutine d_vect_div_v_check(x, y, info, flag) + use psi_serial_mod + implicit none + class(psb_d_vect_type), intent(inout) :: x + class(psb_d_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + logical, intent(in) :: flag + + info = 0 + if (allocated(x%v).and.allocated(y%v)) & + & call x%v%div(y%v,info,flag) + + end subroutine d_vect_div_v_check + subroutine d_vect_div_a2(x, y, z, info) use psi_serial_mod implicit none @@ -759,6 +776,22 @@ contains end subroutine d_vect_div_a2 + subroutine d_vect_div_a2_check(x, y, z, info,flag) + use psi_serial_mod + implicit none + real(psb_dpk_), intent(in) :: x(:) + real(psb_dpk_), intent(in) :: y(:) + class(psb_d_vect_type), intent(inout) :: z + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + logical, intent(in) :: flag + + info = 0 + if (allocated(z%v)) & + & call z%v%div(x,y,info,flag) + + end subroutine d_vect_div_a2_check + subroutine d_vect_scal(alpha, x) use psi_serial_mod implicit none diff --git a/base/modules/serial/psb_s_base_vect_mod.f90 b/base/modules/serial/psb_s_base_vect_mod.f90 index a47d63775..bf229956f 100644 --- a/base/modules/serial/psb_s_base_vect_mod.f90 +++ b/base/modules/serial/psb_s_base_vect_mod.f90 @@ -166,9 +166,11 @@ module psb_s_base_vect_mod ! ! Vector-Vector operations ! - procedure, pass(x) :: div_v => s_base_div_v - procedure, pass(z) :: div_a2 => s_base_div_a2 - generic, public :: div => div_v, div_a2 + procedure, pass(x) :: div_v => s_base_div_v + procedure, pass(x) :: div_v_check => s_base_div_v_check + procedure, pass(z) :: div_a2 => s_base_div_a2 + procedure, pass(z) :: div_a2_check => s_base_div_a2_check + generic, public :: div => div_v, div_v_check, div_a2, div_a2_check ! ! Scaling and norms ! @@ -1205,10 +1207,32 @@ contains end subroutine s_base_div_v ! + !> Function base_div_v_check + !! \memberof psb_s_base_vect_type + !! \brief Vector entry-by-entry divide by a vector x=x/y + !! \param y The array to be divided by + !! \param info return code + !! + subroutine s_base_div_v_check(x, y, info, flag) + use psi_serial_mod + implicit none + class(psb_s_base_vect_type), intent(inout) :: x + class(psb_s_base_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + logical, intent(in) :: flag + + info = 0 + if (x%is_dev()) call x%sync() + call x%div(x%v,y%v,info,flag) + + + end subroutine s_base_div_v_check + ! !> Function base_div_a2 !! \memberof psb_s_base_vect_type !! \brief Entry-by-entry divide between normal array x=x/y - !! \param x(:) The array to be multiplied by + !! \param y(:) The array to be divided by !! \param info return code !! subroutine s_base_div_a2(x, y, z, info) @@ -1229,7 +1253,43 @@ contains end do end subroutine s_base_div_a2 + ! + !> Function base_div_a2_check + !! \memberof psb_s_base_vect_type + !! \brief Entry-by-entry divide between normal array x=x/y and check if y(i) + !! is different from zero + !! \param y(:) The array to be dived by + !! \param info return code + !! + subroutine s_base_div_a2_check(x, y, z, info, flag) + use psi_serial_mod + implicit none + class(psb_s_base_vect_type), intent(inout) :: z + real(psb_spk_), intent(in) :: x(:) + real(psb_spk_), intent(in) :: y(:) + integer(psb_ipk_), intent(out) :: info + logical, intent(in) :: flag + integer(psb_ipk_) :: i, n + if (flag .eqv. .false.) then + call s_base_div_a2(x, y, z, info) + else + info = 0 + if (z%is_dev()) call z%sync() + + n = min(size(y), size(x)) + do i=1, n + if (y(i) /= 0) then + z%v(i) = x(i)/y(i) + else + info = 1 + exit + end if + end do + end if + + + end subroutine s_base_div_a2_check ! diff --git a/base/modules/serial/psb_s_vect_mod.F90 b/base/modules/serial/psb_s_vect_mod.F90 index d835bc5aa..225194563 100644 --- a/base/modules/serial/psb_s_vect_mod.F90 +++ b/base/modules/serial/psb_s_vect_mod.F90 @@ -95,8 +95,10 @@ module psb_s_vect_mod generic, public :: mlt => mlt_v, mlt_a, mlt_a_2,& & mlt_v_2, mlt_av, mlt_va procedure, pass(x) :: div_v => s_vect_div_v + procedure, pass(x) :: div_v_check => s_vect_div_v_check procedure, pass(z) :: div_a2 => s_vect_div_a2 - generic, public :: div => div_v, div_a2 + procedure, pass(z) :: div_a2_check => s_vect_div_a2_check + generic, public :: div => div_v, div_v_check, div_a2, div_a2_check procedure, pass(x) :: scal => s_vect_scal procedure, pass(x) :: absval1 => s_vect_absval1 procedure, pass(x) :: absval2 => s_vect_absval2 @@ -744,6 +746,21 @@ contains end subroutine s_vect_div_v + subroutine s_vect_div_v_check(x, y, info, flag) + use psi_serial_mod + implicit none + class(psb_s_vect_type), intent(inout) :: x + class(psb_s_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + logical, intent(in) :: flag + + info = 0 + if (allocated(x%v).and.allocated(y%v)) & + & call x%v%div(y%v,info,flag) + + end subroutine s_vect_div_v_check + subroutine s_vect_div_a2(x, y, z, info) use psi_serial_mod implicit none @@ -759,6 +776,22 @@ contains end subroutine s_vect_div_a2 + subroutine s_vect_div_a2_check(x, y, z, info,flag) + use psi_serial_mod + implicit none + real(psb_spk_), intent(in) :: x(:) + real(psb_spk_), intent(in) :: y(:) + class(psb_s_vect_type), intent(inout) :: z + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + logical, intent(in) :: flag + + info = 0 + if (allocated(z%v)) & + & call z%v%div(x,y,info,flag) + + end subroutine s_vect_div_a2_check + subroutine s_vect_scal(alpha, x) use psi_serial_mod implicit none diff --git a/base/modules/serial/psb_z_base_vect_mod.f90 b/base/modules/serial/psb_z_base_vect_mod.f90 index 350e70340..91663600c 100644 --- a/base/modules/serial/psb_z_base_vect_mod.f90 +++ b/base/modules/serial/psb_z_base_vect_mod.f90 @@ -166,9 +166,11 @@ module psb_z_base_vect_mod ! ! Vector-Vector operations ! - procedure, pass(x) :: div_v => z_base_div_v - procedure, pass(z) :: div_a2 => z_base_div_a2 - generic, public :: div => div_v, div_a2 + procedure, pass(x) :: div_v => z_base_div_v + procedure, pass(x) :: div_v_check => z_base_div_v_check + procedure, pass(z) :: div_a2 => z_base_div_a2 + procedure, pass(z) :: div_a2_check => z_base_div_a2_check + generic, public :: div => div_v, div_v_check, div_a2, div_a2_check ! ! Scaling and norms ! @@ -1205,10 +1207,32 @@ contains end subroutine z_base_div_v ! + !> Function base_div_v_check + !! \memberof psb_z_base_vect_type + !! \brief Vector entry-by-entry divide by a vector x=x/y + !! \param y The array to be divided by + !! \param info return code + !! + subroutine z_base_div_v_check(x, y, info, flag) + use psi_serial_mod + implicit none + class(psb_z_base_vect_type), intent(inout) :: x + class(psb_z_base_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + logical, intent(in) :: flag + + info = 0 + if (x%is_dev()) call x%sync() + call x%div(x%v,y%v,info,flag) + + + end subroutine z_base_div_v_check + ! !> Function base_div_a2 !! \memberof psb_z_base_vect_type !! \brief Entry-by-entry divide between normal array x=x/y - !! \param x(:) The array to be multiplied by + !! \param y(:) The array to be divided by !! \param info return code !! subroutine z_base_div_a2(x, y, z, info) @@ -1229,7 +1253,43 @@ contains end do end subroutine z_base_div_a2 + ! + !> Function base_div_a2_check + !! \memberof psb_z_base_vect_type + !! \brief Entry-by-entry divide between normal array x=x/y and check if y(i) + !! is different from zero + !! \param y(:) The array to be dived by + !! \param info return code + !! + subroutine z_base_div_a2_check(x, y, z, info, flag) + use psi_serial_mod + implicit none + class(psb_z_base_vect_type), intent(inout) :: z + complex(psb_dpk_), intent(in) :: x(:) + complex(psb_dpk_), intent(in) :: y(:) + integer(psb_ipk_), intent(out) :: info + logical, intent(in) :: flag + integer(psb_ipk_) :: i, n + if (flag .eqv. .false.) then + call z_base_div_a2(x, y, z, info) + else + info = 0 + if (z%is_dev()) call z%sync() + + n = min(size(y), size(x)) + do i=1, n + if (y(i) /= 0) then + z%v(i) = x(i)/y(i) + else + info = 1 + exit + end if + end do + end if + + + end subroutine z_base_div_a2_check ! diff --git a/base/modules/serial/psb_z_vect_mod.F90 b/base/modules/serial/psb_z_vect_mod.F90 index b65ba18bd..f5e4f31ae 100644 --- a/base/modules/serial/psb_z_vect_mod.F90 +++ b/base/modules/serial/psb_z_vect_mod.F90 @@ -95,8 +95,10 @@ module psb_z_vect_mod generic, public :: mlt => mlt_v, mlt_a, mlt_a_2,& & mlt_v_2, mlt_av, mlt_va procedure, pass(x) :: div_v => z_vect_div_v + procedure, pass(x) :: div_v_check => z_vect_div_v_check procedure, pass(z) :: div_a2 => z_vect_div_a2 - generic, public :: div => div_v, div_a2 + procedure, pass(z) :: div_a2_check => z_vect_div_a2_check + generic, public :: div => div_v, div_v_check, div_a2, div_a2_check procedure, pass(x) :: scal => z_vect_scal procedure, pass(x) :: absval1 => z_vect_absval1 procedure, pass(x) :: absval2 => z_vect_absval2 @@ -744,6 +746,21 @@ contains end subroutine z_vect_div_v + subroutine z_vect_div_v_check(x, y, info, flag) + use psi_serial_mod + implicit none + class(psb_z_vect_type), intent(inout) :: x + class(psb_z_vect_type), intent(inout) :: y + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + logical, intent(in) :: flag + + info = 0 + if (allocated(x%v).and.allocated(y%v)) & + & call x%v%div(y%v,info,flag) + + end subroutine z_vect_div_v_check + subroutine z_vect_div_a2(x, y, z, info) use psi_serial_mod implicit none @@ -759,6 +776,22 @@ contains end subroutine z_vect_div_a2 + subroutine z_vect_div_a2_check(x, y, z, info,flag) + use psi_serial_mod + implicit none + complex(psb_dpk_), intent(in) :: x(:) + complex(psb_dpk_), intent(in) :: y(:) + class(psb_z_vect_type), intent(inout) :: z + integer(psb_ipk_), intent(out) :: info + integer(psb_ipk_) :: i, n + logical, intent(in) :: flag + + info = 0 + if (allocated(z%v)) & + & call z%v%div(x,y,info,flag) + + end subroutine z_vect_div_a2_check + subroutine z_vect_scal(alpha, x) use psi_serial_mod implicit none diff --git a/base/psblas/psb_cdiv_vect.f90 b/base/psblas/psb_cdiv_vect.f90 index 38c7ce6a2..99e4fef64 100644 --- a/base/psblas/psb_cdiv_vect.f90 +++ b/base/psblas/psb_cdiv_vect.f90 @@ -103,3 +103,77 @@ subroutine psb_cdiv_vect(x,y,desc_a,info) return end subroutine psb_cdiv_vect + +subroutine psb_cdiv_vect_check(x,y,desc_a,info,flag) + use psb_base_mod, psb_protect_name => psb_cdiv_vect_check + implicit none + type(psb_c_vect_type), intent (inout) :: x + type(psb_c_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + logical, intent(in) :: flag + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_c_div_vect_check' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if(desc_a%get_local_rows() > 0) then + call x%div(y,info,flag) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_cdiv_vect_check diff --git a/base/psblas/psb_ddiv_vect.f90 b/base/psblas/psb_ddiv_vect.f90 index d9ab02037..20536a2c8 100644 --- a/base/psblas/psb_ddiv_vect.f90 +++ b/base/psblas/psb_ddiv_vect.f90 @@ -103,3 +103,77 @@ subroutine psb_ddiv_vect(x,y,desc_a,info) return end subroutine psb_ddiv_vect + +subroutine psb_ddiv_vect_check(x,y,desc_a,info,flag) + use psb_base_mod, psb_protect_name => psb_ddiv_vect_check + implicit none + type(psb_d_vect_type), intent (inout) :: x + type(psb_d_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + logical, intent(in) :: flag + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_d_div_vect_check' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if(desc_a%get_local_rows() > 0) then + call x%div(y,info,flag) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_ddiv_vect_check diff --git a/base/psblas/psb_sdiv_vect.f90 b/base/psblas/psb_sdiv_vect.f90 index 99a1ce7ca..42bc8b832 100644 --- a/base/psblas/psb_sdiv_vect.f90 +++ b/base/psblas/psb_sdiv_vect.f90 @@ -103,3 +103,77 @@ subroutine psb_sdiv_vect(x,y,desc_a,info) return end subroutine psb_sdiv_vect + +subroutine psb_sdiv_vect_check(x,y,desc_a,info,flag) + use psb_base_mod, psb_protect_name => psb_sdiv_vect_check + implicit none + type(psb_s_vect_type), intent (inout) :: x + type(psb_s_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + logical, intent(in) :: flag + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_s_div_vect_check' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if(desc_a%get_local_rows() > 0) then + call x%div(y,info,flag) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_sdiv_vect_check diff --git a/base/psblas/psb_zdiv_vect.f90 b/base/psblas/psb_zdiv_vect.f90 index 949cbf7d5..5ef0552a5 100644 --- a/base/psblas/psb_zdiv_vect.f90 +++ b/base/psblas/psb_zdiv_vect.f90 @@ -103,3 +103,77 @@ subroutine psb_zdiv_vect(x,y,desc_a,info) return end subroutine psb_zdiv_vect + +subroutine psb_zdiv_vect_check(x,y,desc_a,info,flag) + use psb_base_mod, psb_protect_name => psb_zdiv_vect_check + implicit none + type(psb_z_vect_type), intent (inout) :: x + type(psb_z_vect_type), intent (inout) :: y + type(psb_desc_type), intent (in) :: desc_a + integer(psb_ipk_), intent(out) :: info + logical, intent(in) :: flag + + ! locals + integer(psb_ipk_) :: ictxt, np, me,& + & err_act, iix, jjx, iiy, jjy + integer(psb_lpk_) :: ix, ijx, iy, ijy, m + character(len=20) :: name, ch_err + + name='psb_z_div_vect_check' + if (psb_errstatus_fatal()) return + info=psb_success_ + call psb_erractionsave(err_act) + + ictxt=desc_a%get_context() + + call psb_info(ictxt, me, np) + if (np == -ione) then + info = psb_err_context_error_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(x%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + if (.not.allocated(y%v)) then + info = psb_err_invalid_vect_state_ + call psb_errpush(info,name) + goto 9999 + endif + + + ix = ione + iy = ione + + m = desc_a%get_global_rows() + + ! check vector correctness + call psb_chkvect(m,lone,x%get_nrows(),ix,lone,desc_a,info,iix,jjx) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 1' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + call psb_chkvect(m,lone,y%get_nrows(),iy,lone,desc_a,info,iiy,jjy) + if(info /= psb_success_) then + info=psb_err_from_subroutine_ + ch_err='psb_chkvect 2' + call psb_errpush(info,name,a_err=ch_err) + goto 9999 + end if + + if(desc_a%get_local_rows() > 0) then + call x%div(y,info,flag) + end if + + call psb_erractionrestore(err_act) + return + +9999 call psb_error_handler(ictxt,err_act) + + return + +end subroutine psb_zdiv_vect_check From b3c4971146295f2571cfdb685b78550cdbaff511 Mon Sep 17 00:00:00 2001 From: cirdans-home Date: Thu, 21 Nov 2019 13:56:22 +0100 Subject: [PATCH 04/61] Added entrywise inversion and documentation for vec-vec operation --- docs/html/WARNINGS | 12 + docs/html/footnode.html | 14 +- docs/html/images.aux | 18 + docs/html/images.log | 507 + docs/html/images.out | 0 docs/html/images.pl | 1182 ++ docs/html/images.tex | 273 + docs/html/img1.png | Bin 200 -> 210 bytes docs/html/img10.png | Bin 404 -> 447 bytes docs/html/img100.png | Bin 178 -> 603 bytes docs/html/img101.png | Bin 363 -> 318 bytes docs/html/img102.png | Bin 533 -> 487 bytes docs/html/img103.png | Bin 359 -> 397 bytes docs/html/img104.png | Bin 368 -> 281 bytes docs/html/img105.png | Bin 228 -> 423 bytes docs/html/img106.png | Bin 340 -> 190 bytes docs/html/img107.png | Bin 259 -> 387 bytes docs/html/img108.png | Bin 0 -> 520 bytes docs/html/img109.png | Bin 194 -> 350 bytes docs/html/img11.png | Bin 526 -> 576 bytes docs/html/img110.png | Bin 737 -> 374 bytes docs/html/img111.png | Bin 373 -> 237 bytes docs/html/img112.png | Bin 0 -> 358 bytes docs/html/img113.png | Bin 0 -> 279 bytes docs/html/img114.png | Bin 0 -> 303 bytes docs/html/img115.png | Bin 0 -> 199 bytes docs/html/img116.png | Bin 134 -> 682 bytes docs/html/img117.png | Bin 257 -> 411 bytes docs/html/img118.png | Bin 390 -> 366 bytes docs/html/img119.png | Bin 263 -> 857 bytes docs/html/img120.png | Bin 244 -> 745 bytes docs/html/img121.png | Bin 276 -> 423 bytes docs/html/img122.png | Bin 374 -> 151 bytes docs/html/img123.png | Bin 222 -> 272 bytes docs/html/img124.png | Bin 259 -> 390 bytes docs/html/img125.png | Bin 808 -> 260 bytes docs/html/img126.png | Bin 412 -> 268 bytes docs/html/img127.png | Bin 431 -> 270 bytes docs/html/img128.png | Bin 354 -> 420 bytes docs/html/img129.png | Bin 310 -> 221 bytes docs/html/img13.png | Bin 3167 -> 3564 bytes docs/html/img130.png | Bin 839 -> 263 bytes docs/html/img131.png | Bin 335 -> 943 bytes docs/html/img132.png | Bin 500 -> 423 bytes docs/html/img133.png | Bin 402 -> 425 bytes docs/html/img134.png | Bin 267 -> 359 bytes docs/html/img135.png | Bin 533 -> 330 bytes docs/html/img136.png | Bin 545 -> 860 bytes docs/html/img137.png | Bin 335 -> 336 bytes docs/html/img138.png | Bin 232 -> 532 bytes docs/html/img139.png | Bin 520 -> 412 bytes docs/html/img14.png | Bin 643 -> 694 bytes docs/html/img140.png | Bin 613 -> 251 bytes docs/html/img141.png | Bin 581 -> 619 bytes docs/html/img142.png | Bin 312 -> 626 bytes docs/html/img143.png | Bin 277 -> 395 bytes docs/html/img144.png | Bin 870 -> 243 bytes docs/html/img145.png | Bin 215 -> 568 bytes docs/html/img146.png | Bin 583 -> 614 bytes docs/html/img147.png | Bin 732 -> 578 bytes docs/html/img148.png | Bin 523 -> 306 bytes docs/html/img149.png | Bin 268 -> 271 bytes docs/html/img15.png | Bin 230 -> 250 bytes docs/html/img150.png | Bin 572 -> 889 bytes docs/html/img151.png | Bin 240 -> 226 bytes docs/html/img152.png | Bin 0 -> 630 bytes docs/html/img153.png | Bin 8603 -> 750 bytes docs/html/img154.png | Bin 0 -> 534 bytes docs/html/img155.png | Bin 1099 -> 273 bytes docs/html/img156.png | Bin 758 -> 569 bytes docs/html/img157.png | Bin 875 -> 250 bytes docs/html/img158.old | 0 docs/html/img158.png | Bin 867 -> 0 bytes docs/html/img159.png | Bin 1172 -> 9773 bytes docs/html/img16.png | Bin 196 -> 203 bytes docs/html/img160.old | 0 docs/html/img160.png | Bin 1348 -> 0 bytes docs/html/img161.png | Bin 1029 -> 1148 bytes docs/html/img162.png | Bin 1121 -> 801 bytes docs/html/img163.png | Bin 1209 -> 934 bytes docs/html/img164.png | Bin 1156 -> 966 bytes docs/html/img165.png | Bin 373 -> 1251 bytes docs/html/img166.png | Bin 431 -> 1436 bytes docs/html/img167.png | Bin 304 -> 1126 bytes docs/html/img168.png | Bin 915 -> 1188 bytes docs/html/img169.png | Bin 678 -> 1238 bytes docs/html/img17.png | Bin 371 -> 384 bytes docs/html/img170.png | Bin 659 -> 1211 bytes docs/html/img171.png | Bin 219 -> 356 bytes docs/html/img172.png | Bin 429 -> 440 bytes docs/html/img173.png | Bin 2452 -> 302 bytes docs/html/img174.png | Bin 449 -> 998 bytes docs/html/img175.png | Bin 0 -> 719 bytes docs/html/img176.png | Bin 0 -> 746 bytes docs/html/img177.png | Bin 0 -> 228 bytes docs/html/img178.png | Bin 0 -> 442 bytes docs/html/img179.png | Bin 0 -> 2571 bytes docs/html/img18.png | Bin 540 -> 581 bytes docs/html/img180.png | Bin 0 -> 477 bytes docs/html/img181.png | Bin 0 -> 480 bytes docs/html/img182.png | Bin 0 -> 465 bytes docs/html/img183.png | Bin 0 -> 345 bytes docs/html/img184.png | Bin 0 -> 226 bytes docs/html/img185.png | Bin 0 -> 452 bytes docs/html/img186.png | Bin 0 -> 425 bytes docs/html/img187.png | Bin 0 -> 279 bytes docs/html/img19.png | Bin 486 -> 524 bytes docs/html/img2.png | Bin 3108 -> 3875 bytes docs/html/img20.png | Bin 184 -> 189 bytes docs/html/img21.png | Bin 231 -> 216 bytes docs/html/img22.png | Bin 201 -> 205 bytes docs/html/img23.png | Bin 225 -> 225 bytes docs/html/img24.png | Bin 469 -> 476 bytes docs/html/img25.png | Bin 482 -> 486 bytes docs/html/img26.png | Bin 267 -> 273 bytes docs/html/img27.png | Bin 4180 -> 4602 bytes docs/html/img28.png | Bin 791 -> 769 bytes docs/html/img29.png | Bin 245 -> 254 bytes docs/html/img3.png | Bin 3149 -> 3855 bytes docs/html/img30.png | Bin 591 -> 618 bytes docs/html/img31.png | Bin 1090 -> 1060 bytes docs/html/img32.png | Bin 311 -> 321 bytes docs/html/img33.png | Bin 3994 -> 4351 bytes docs/html/img34.png | Bin 799 -> 808 bytes docs/html/img35.png | Bin 454 -> 495 bytes docs/html/img36.png | Bin 875 -> 873 bytes docs/html/img37.png | Bin 311 -> 326 bytes docs/html/img38.png | Bin 3960 -> 4251 bytes docs/html/img39.png | Bin 508 -> 536 bytes docs/html/img4.png | Bin 178 -> 179 bytes docs/html/img40.png | Bin 909 -> 881 bytes docs/html/img41.png | Bin 564 -> 576 bytes docs/html/img42.png | Bin 572 -> 594 bytes docs/html/img43.png | Bin 320 -> 338 bytes docs/html/img44.png | Bin 4024 -> 4294 bytes docs/html/img45.png | Bin 655 -> 685 bytes docs/html/img46.png | Bin 476 -> 501 bytes docs/html/img47.png | Bin 498 -> 521 bytes docs/html/img48.png | Bin 536 -> 554 bytes docs/html/img49.png | Bin 572 -> 622 bytes docs/html/img5.png | Bin 200 -> 228 bytes docs/html/img50.png | Bin 597 -> 621 bytes docs/html/img51.png | Bin 243 -> 243 bytes docs/html/img52.png | Bin 256 -> 251 bytes docs/html/img53.png | Bin 415 -> 429 bytes docs/html/img54.png | Bin 2923 -> 2775 bytes docs/html/img55.png | Bin 192 -> 214 bytes docs/html/img56.png | Bin 229 -> 233 bytes docs/html/img57.png | Bin 421 -> 444 bytes docs/html/img58.png | Bin 824 -> 816 bytes docs/html/img59.png | Bin 283 -> 620 bytes docs/html/img6.png | Bin 376 -> 431 bytes docs/html/img60.png | Bin 1916 -> 553 bytes docs/html/img61.png | Bin 3748 -> 179 bytes docs/html/img62.png | Bin 3122 -> 416 bytes docs/html/img63.png | Bin 367 -> 467 bytes docs/html/img64.png | Bin 253 -> 416 bytes docs/html/img65.png | Bin 247 -> 266 bytes docs/html/img66.png | Bin 261 -> 2084 bytes docs/html/img67.png | Bin 2398 -> 3225 bytes docs/html/img68.png | Bin 261 -> 3213 bytes docs/html/img69.png | Bin 335 -> 370 bytes docs/html/img7.png | Bin 202 -> 205 bytes docs/html/img70.png | Bin 773 -> 258 bytes docs/html/img71.png | Bin 5090 -> 250 bytes docs/html/img72.png | Bin 5450 -> 255 bytes docs/html/img73.png | Bin 805 -> 2512 bytes docs/html/img74.png | Bin 368 -> 255 bytes docs/html/img75.png | Bin 502 -> 337 bytes docs/html/img76.png | Bin 326 -> 789 bytes docs/html/img77.png | Bin 366 -> 5441 bytes docs/html/img78.png | Bin 301 -> 6161 bytes docs/html/img79.png | Bin 2461 -> 803 bytes docs/html/img8.png | Bin 231 -> 242 bytes docs/html/img80.png | Bin 373 -> 387 bytes docs/html/img81.png | Bin 539 -> 523 bytes docs/html/img82.png | Bin 167 -> 334 bytes docs/html/img83.png | Bin 800 -> 363 bytes docs/html/img84.png | Bin 369 -> 312 bytes docs/html/img85.png | Bin 1401 -> 2611 bytes docs/html/img86.png | Bin 502 -> 438 bytes docs/html/img87.png | Bin 366 -> 554 bytes docs/html/img88.png | Bin 256 -> 178 bytes docs/html/img89.png | Bin 243 -> 939 bytes docs/html/img9.png | Bin 242 -> 246 bytes docs/html/img90.png | Bin 186 -> 373 bytes docs/html/img91.png | Bin 418 -> 1540 bytes docs/html/img92.png | Bin 507 -> 508 bytes docs/html/img93.png | Bin 219 -> 370 bytes docs/html/img94.png | Bin 582 -> 252 bytes docs/html/img95.png | Bin 319 -> 264 bytes docs/html/img96.png | Bin 457 -> 202 bytes docs/html/img97.png | Bin 394 -> 440 bytes docs/html/img98.png | Bin 285 -> 520 bytes docs/html/img99.png | Bin 415 -> 229 bytes docs/html/index.html | 442 +- docs/html/internals.pl | 206 + docs/html/labels.pl | 421 + docs/html/node1.html | 66 +- docs/html/node10.html | 70 +- docs/html/node100.html | 150 +- docs/html/node101.html | 275 +- docs/html/node102.html | 181 +- docs/html/node103.html | 132 +- docs/html/node104.html | 109 +- docs/html/node105.html | 120 +- docs/html/node106.html | 58 +- docs/html/node107.html | 76 +- docs/html/node108.html | 105 +- docs/html/node109.html | 132 +- docs/html/node11.html | 16 +- docs/html/node110.html | 131 +- docs/html/node111.html | 110 +- docs/html/node112.html | 87 +- docs/html/node113.html | 86 +- docs/html/node114.html | 118 +- docs/html/node115.html | 142 +- docs/html/node116.html | 177 +- docs/html/node117.html | 384 +- docs/html/node118.html | 195 +- docs/html/node119.html | 184 +- docs/html/node12.html | 18 +- docs/html/node120.html | 332 +- docs/html/node121.html | 130 +- docs/html/node122.html | 88 +- docs/html/node123.html | 99 +- docs/html/node124.html | 56 +- docs/html/node125.html | 131 +- docs/html/node126.html | 141 +- docs/html/node127.html | 169 +- docs/html/node128.html | 175 +- docs/html/node129.html | 128 +- docs/html/node13.html | 18 +- docs/html/node130.html | 154 +- docs/html/node131.html | 108 +- docs/html/node132.html | 110 +- docs/html/node133.html | 410 +- docs/html/node134.html | 201 +- docs/html/node135.html | 63 +- docs/html/node136.html | 440 + docs/html/node137.html | 180 + docs/html/node138.html | 67 + docs/html/node14.html | 16 +- docs/html/node15.html | 16 +- docs/html/node16.html | 16 +- docs/html/node17.html | 16 +- docs/html/node18.html | 16 +- docs/html/node19.html | 16 +- docs/html/node2.html | 52 +- docs/html/node20.html | 16 +- docs/html/node21.html | 16 +- docs/html/node22.html | 16 +- docs/html/node23.html | 84 +- docs/html/node24.html | 16 +- docs/html/node25.html | 16 +- docs/html/node26.html | 16 +- docs/html/node27.html | 16 +- docs/html/node28.html | 16 +- docs/html/node29.html | 16 +- docs/html/node3.html | 50 +- docs/html/node30.html | 16 +- docs/html/node31.html | 16 +- docs/html/node32.html | 16 +- docs/html/node33.html | 16 +- docs/html/node34.html | 16 +- docs/html/node35.html | 16 +- docs/html/node36.html | 16 +- docs/html/node37.html | 16 +- docs/html/node38.html | 16 +- docs/html/node39.html | 16 +- docs/html/node4.html | 60 +- docs/html/node40.html | 16 +- docs/html/node41.html | 16 +- docs/html/node42.html | 16 +- docs/html/node43.html | 46 +- docs/html/node44.html | 16 +- docs/html/node45.html | 16 +- docs/html/node46.html | 16 +- docs/html/node47.html | 16 +- docs/html/node48.html | 22 +- docs/html/node49.html | 16 +- docs/html/node5.html | 34 +- docs/html/node50.html | 16 +- docs/html/node51.html | 18 +- docs/html/node52.html | 60 +- docs/html/node53.html | 60 +- docs/html/node54.html | 72 +- docs/html/node55.html | 70 +- docs/html/node56.html | 54 +- docs/html/node57.html | 46 +- docs/html/node58.html | 54 +- docs/html/node59.html | 56 +- docs/html/node6.html | 56 +- docs/html/node60.html | 54 +- docs/html/node61.html | 46 +- docs/html/node62.html | 32 +- docs/html/node63.html | 32 +- docs/html/node64.html | 84 +- docs/html/node65.html | 93 +- docs/html/node66.html | 236 +- docs/html/node67.html | 592 +- docs/html/node68.html | 701 +- docs/html/node69.html | 269 +- docs/html/node7.html | 20 +- docs/html/node70.html | 586 +- docs/html/node71.html | 816 +- docs/html/node72.html | 542 +- docs/html/node73.html | 364 +- docs/html/node74.html | 190 +- docs/html/node75.html | 392 +- docs/html/node76.html | 214 +- docs/html/node77.html | 127 +- docs/html/node78.html | 81 +- docs/html/node79.html | 265 +- docs/html/node8.html | 32 +- docs/html/node80.html | 163 +- docs/html/node81.html | 87 +- docs/html/node82.html | 298 +- docs/html/node83.html | 180 +- docs/html/node84.html | 159 +- docs/html/node85.html | 93 +- docs/html/node86.html | 99 +- docs/html/node87.html | 187 +- docs/html/node88.html | 163 +- docs/html/node89.html | 111 +- docs/html/node9.html | 136 +- docs/html/node90.html | 103 +- docs/html/node91.html | 126 +- docs/html/node92.html | 116 +- docs/html/node93.html | 82 +- docs/html/node94.html | 85 +- docs/html/node95.html | 82 +- docs/html/node96.html | 213 +- docs/html/node97.html | 115 +- docs/html/node98.html | 264 +- docs/html/node99.html | 284 +- docs/html/userhtml.html | 442 +- docs/psblas-3.6.pdf | 24843 ++++++++++++++++++++------------------ docs/src/psbrout.tex | 211 + docs/src/userguide.pdf | 1 + 340 files changed, 24932 insertions(+), 20314 deletions(-) create mode 100644 docs/html/WARNINGS create mode 100644 docs/html/images.aux create mode 100644 docs/html/images.log create mode 100644 docs/html/images.out create mode 100644 docs/html/images.pl create mode 100644 docs/html/images.tex create mode 100644 docs/html/img108.png create mode 100644 docs/html/img112.png create mode 100644 docs/html/img113.png create mode 100644 docs/html/img114.png create mode 100644 docs/html/img115.png create mode 100644 docs/html/img158.old create mode 100644 docs/html/img160.old create mode 100644 docs/html/img175.png create mode 100644 docs/html/img176.png create mode 100644 docs/html/img177.png create mode 100644 docs/html/img178.png create mode 100644 docs/html/img179.png create mode 100644 docs/html/img180.png create mode 100644 docs/html/img181.png create mode 100644 docs/html/img182.png create mode 100644 docs/html/img183.png create mode 100644 docs/html/img184.png create mode 100644 docs/html/img185.png create mode 100644 docs/html/img186.png create mode 100644 docs/html/img187.png create mode 100644 docs/html/internals.pl create mode 100644 docs/html/labels.pl create mode 100644 docs/html/node136.html create mode 100644 docs/html/node137.html create mode 100644 docs/html/node138.html create mode 120000 docs/src/userguide.pdf diff --git a/docs/html/WARNINGS b/docs/html/WARNINGS new file mode 100644 index 000000000..5b6c6c23e --- /dev/null +++ b/docs/html/WARNINGS @@ -0,0 +1,12 @@ +No implementation found for style `pstricks' +No implementation found for style `fancybox' +No implementation found for style `ifthen' +No implementation found for style `listings' + +redefining command \thepage + +Substitution of arg to newlabelxx delayed. + +? brace missing for \oldcontentsline + +? brace missing for \textrm diff --git a/docs/html/footnode.html b/docs/html/footnode.html index 9b6f0db57..17cb83328 100644 --- a/docs/html/footnode.html +++ b/docs/html/footnode.html @@ -14,7 +14,7 @@ - + @@ -137,8 +137,8 @@ sample scatter/gather routines. . -
... follows4
+
... follows4
The string is case-insensitive
.
@@ -173,12 +173,12 @@ sample scatter/gather routines.
 .
 
-
... method5
+
... method5
Note: the implementation is for $FCG(1)$.
.
diff --git a/docs/html/images.aux b/docs/html/images.aux
new file mode 100644
index 000000000..075990843
--- /dev/null
+++ b/docs/html/images.aux
@@ -0,0 +1,18 @@
+\relax 
+\providecommand\hyper@newdestlabel[2]{}
+\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument}
+\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined
+\global\let\oldcontentsline\contentsline
+\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}}
+\global\let\oldnewlabel\newlabel
+\gdef\newlabel#1#2{\newlabelxx{#1}#2}
+\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}}
+\AtEndDocument{\ifx\hyper@anchor\@undefined
+\let\contentsline\oldcontentsline
+\let\newlabel\oldnewlabel
+\fi}
+\fi}
+\global\let\hyper@last\relax 
+\gdef\HyperFirstAtBeginDocument#1{#1}
+\providecommand*\HyPL@Entry[1]{}
+\HyPL@Entry{0<>}
diff --git a/docs/html/images.log b/docs/html/images.log
new file mode 100644
index 000000000..fc4875b53
--- /dev/null
+++ b/docs/html/images.log
@@ -0,0 +1,507 @@
+This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/Debian) (preloaded format=latex 2019.9.9)  21 NOV 2019 13:53
+entering extended mode
+ restricted \write18 enabled.
+ %&-line parsing enabled.
+**./images.tex
+(./images.tex
+LaTeX2e <2017-04-15>
+Babel <3.18> and hyphenation patterns for 10 language(s) loaded.
+
+(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
+Document Class: article 2014/09/29 v1.4h Standard LaTeX document class
+(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo
+File: size10.clo 2014/09/29 v1.4h Standard LaTeX file (size option)
+)
+\c@part=\count79
+\c@section=\count80
+\c@subsection=\count81
+\c@subsubsection=\count82
+\c@paragraph=\count83
+\c@subparagraph=\count84
+\c@figure=\count85
+\c@table=\count86
+\abovecaptionskip=\skip41
+\belowcaptionskip=\skip42
+\bibindent=\dimen102
+) (/usr/share/texlive/texmf-dist/tex/latex/pstricks/pstricks.sty
+Package: pstricks 2018/01/06 v0.67 LaTeX wrapper for `PSTricks' (RN,HV)
+(/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty
+Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, 
+and LuaTeX
+) (/usr/share/texlive/texmf-dist/tex/latex/tools/shellesc.sty
+Package: shellesc 2016/06/07 v0.02a unified shell escape interface for LaTeX
+Package shellesc Info: Restricted shell escape enabled on input line 69.
+) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty
+Package: xcolor 2016/05/11 v2.12 LaTeX color extensions (UK)
+(/usr/share/texlive/texmf-dist/tex/latex/graphics-cfg/color.cfg
+File: color.cfg 2016/01/02 v1.6 sample color configuration
+)
+Package xcolor Info: Driver file: dvips.def on input line 225.
+(/usr/share/texlive/texmf-dist/tex/latex/graphics-def/dvips.def
+File: dvips.def 2017/06/20 v3.1d Graphics/color driver for dvips
+)
+Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1348.
+Package xcolor Info: Model `RGB' extended on input line 1364.
+Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1366.
+Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1367.
+Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1368.
+Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1369.
+Package xcolor Info: Model `Gray' substituted by `gray' on input line 1370.
+Package xcolor Info: Model `wave' substituted by `hsb' on input line 1371.
+) (/usr/share/texlive/texmf-dist/tex/generic/xkeyval/pst-xkey.tex
+File: pst-xkey.tex 2005/11/25 v1.6 PSTricks specialization of xkeyval (HA)
+(/usr/share/texlive/texmf-dist/tex/latex/xkeyval/xkeyval.sty
+Package: xkeyval 2014/12/03 v2.7a package option processing (HA)
+(/usr/share/texlive/texmf-dist/tex/generic/xkeyval/xkeyval.tex (/usr/share/texl
+ive/texmf-dist/tex/generic/xkeyval/xkvutils.tex
+\XKV@toks=\toks14
+\XKV@tempa@toks=\toks15
+(/usr/share/texlive/texmf-dist/tex/generic/xkeyval/keyval.tex))
+\XKV@depth=\count87
+File: xkeyval.tex 2014/12/03 v2.7a key=value parser (HA)
+))) (/usr/share/texlive/texmf-dist/tex/generic/pstricks/pstricks.tex (/usr/shar
+e/texlive/texmf-dist/tex/generic/pstricks/pst-fp.tex `pst-fp' v0.05, 2010/01/17
+ (hv)
+\pstFP@xs=\count88
+\pstFP@xia=\count89
+\pstFP@xib=\count90
+\pstFP@xfa=\count91
+\pstFP@xfb=\count92
+\pstFP@rega=\count93
+\pstFP@regb=\count94
+\pstFP@regs=\count95
+\pstFP@times=\count96
+) (/usr/share/texlive/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex
+\pgfutil@everybye=\toks16
+\pgfutil@tempdima=\dimen103
+\pgfutil@tempdimb=\dimen104
+
+(/usr/share/texlive/texmf-dist/tex/generic/pgf/utilities/pgfutil-common-lists.t
+ex)) (/usr/share/texlive/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex
+\pgfkeys@pathtoks=\toks17
+\pgfkeys@temptoks=\toks18
+
+(/usr/share/texlive/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.t
+ex
+\pgfkeys@tmptoks=\toks19
+)) (/usr/share/texlive/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex (/u
+sr/share/texlive/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex (/usr/share/t
+exlive/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex (/usr/share/texlive
+/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex
+\pgf@x=\dimen105
+\pgf@xa=\dimen106
+\pgf@xb=\dimen107
+\pgf@xc=\dimen108
+\pgf@y=\dimen109
+\pgf@ya=\dimen110
+\pgf@yb=\dimen111
+\pgf@yc=\dimen112
+\c@pgf@counta=\count97
+\c@pgf@countb=\count98
+\c@pgf@countc=\count99
+\c@pgf@countd=\count100
+\pgfutil@tempcnta=\count101
+\pgfutil@tempcntb=\count102
+) (/usr/share/texlive/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
+\pgfmath@dimen=\dimen113
+\pgfmath@count=\count103
+\pgfmath@box=\box26
+\pgfmath@toks=\toks20
+\pgfmath@stack@operand=\toks21
+\pgfmath@stack@operation=\toks22
+) (/usr/share/texlive/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex
+
+(/usr/share/texlive/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code
+.tex)
+(/usr/share/texlive/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonomet
+ric.code.tex)
+(/usr/share/texlive/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.random.cod
+e.tex)
+(/usr/share/texlive/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.comparison
+.code.tex)
+(/usr/share/texlive/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.
+tex)
+(/usr/share/texlive/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.round.code
+.tex)
+(/usr/share/texlive/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.
+tex)
+(/usr/share/texlive/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integerari
+thmetics.code.tex))) (/usr/share/texlive/texmf-dist/tex/generic/pgf/math/pgfmat
+hfloat.code.tex
+\c@pgfmathroundto@lastzeros=\count104
+))
+\pgffor@iter=\dimen114
+\pgffor@skip=\dimen115
+\pgffor@stack=\toks23
+\pgffor@toks=\toks24
+)
+\psLoopIndex=\count105
+`PSTricks' v2.82  <2018/01/06> (tvz,hv)
+\pst@dima=\dimen116
+\pst@dimb=\dimen117
+\pst@dimc=\dimen118
+\pst@dimd=\dimen119
+\pst@dimg=\dimen120
+\pst@dimh=\dimen121
+\pst@dimm=\dimen122
+\pst@dimn=\dimen123
+\pst@dimo=\dimen124
+\pst@dimp=\dimen125
+\pst@hbox=\box27
+\pst@ibox=\box28
+\pst@boxg=\box29
+\pst@cnta=\count106
+\pst@cntb=\count107
+\pst@cntc=\count108
+\pst@cntd=\count109
+\pst@cntg=\count110
+\pst@cnth=\count111
+\pst@cntm=\count112
+\pst@cntn=\count113
+\pst@cnto=\count114
+\pst@cntp=\count115
+\@zero=\count116
+\pst@toks=\toks25
+(/usr/share/texlive/texmf-dist/tex/generic/pstricks/pstricks.con)
+\psunit=\dimen126
+\psxunit=\dimen127
+\psyunit=\dimen128
+\pst@C@@rType=\count117
+\pslinewidth=\dimen129
+\psk@startLW=\dimen130
+\psk@endLW=\dimen131
+\pst@customdefs=\toks26
+\pslinearc=\dimen132
+\pst@symbolStep=\dimen133
+\pst@symbolWidth=\dimen134
+\pst@symbolLinewidth=\dimen135
+\everypsbox=\toks27
+\psframesep=\dimen136
+\pslabelsep=\dimen137
+\sh@wgridXunit=\dimen138
+\sh@wgridYunit=\dimen139
+\pst@shift=\dimen140
+)
+File: pstricks.tex 2018/01/06 v2.82 `PSTricks' (tvz,hv)
+(/usr/share/texlive/texmf-dist/tex/generic/pstricks/pst-fp.tex)
+File: pst-fp.tex 2018/01/06 v2.82 `PST-fp' (hv)
+) (/usr/share/texlive/texmf-dist/tex/latex/fancybox/fancybox.sty
+Package: fancybox 2010/05/15 1.4
+Style option: `fancybox' v1.4 <2010/05/15> (tvz)
+\@fancybox=\box30
+\shadowsize=\dimen141
+\@Sbox=\box31
+\do@VerbBox=\toks28
+\the@fancyput=\toks29
+\this@fancyput=\toks30
+\EndVerbatimTokens=\toks31
+\Verbatim@Outfile=\write3
+\Verbatim@Infile=\read1
+) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty
+Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support
+\@emptytoks=\toks32
+\symAMSa=\mathgroup4
+\symAMSb=\mathgroup5
+LaTeX Font Info:    Overwriting math alphabet `\mathfrak' in version `bold'
+(Font)                  U/euf/m/n --> U/euf/b/n on input line 106.
+) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty
+Package: hyperref 2018/02/06 v6.86b Hypertext links for LaTeX
+(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty
+Package: hobsub-hyperref 2016/05/16 v1.14 Bundle oberdiek, subset hyperref (HO)
+
+(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty
+Package: hobsub-generic 2016/05/16 v1.14 Bundle oberdiek, subset generic (HO)
+Package: hobsub 2016/05/16 v1.14 Construct package bundles (HO)
+Package: infwarerr 2016/05/16 v1.4 Providing info/warning/error messages (HO)
+Package: ltxcmds 2016/05/16 v1.23 LaTeX kernel commands for general use (HO)
+Package: ifluatex 2016/05/16 v1.4 Provides the ifluatex switch (HO)
+Package ifluatex Info: LuaTeX not detected.
+Package: ifvtex 2016/05/16 v1.6 Detect VTeX and its facilities (HO)
+Package ifvtex Info: VTeX not detected.
+Package: intcalc 2016/05/16 v1.2 Expandable calculations with integers (HO)
+Package: ifpdf 2017/03/15 v3.2 Provides the ifpdf switch
+Package: etexcmds 2016/05/16 v1.6 Avoid name clashes with e-TeX commands (HO)
+Package etexcmds Info: Could not find \expanded.
+(etexcmds)             That can mean that you are not using pdfTeX 1.50 or
+(etexcmds)             that some package has redefined \expanded.
+(etexcmds)             In the latter case, load this package earlier.
+Package: kvsetkeys 2016/05/16 v1.17 Key value parser (HO)
+Package: kvdefinekeys 2016/05/16 v1.4 Define keys (HO)
+Package: pdftexcmds 2018/01/21 v0.26 Utility functions of pdfTeX for LuaTeX (HO
+)
+Package pdftexcmds Info: LuaTeX not detected.
+Package pdftexcmds Info: \pdf@primitive is available.
+Package pdftexcmds Info: \pdf@ifprimitive is available.
+Package pdftexcmds Info: \pdfdraftmode is ignored in DVI mode.
+Package: pdfescape 2016/05/16 v1.14 Implements pdfTeX's escape features (HO)
+Package: bigintcalc 2016/05/16 v1.4 Expandable calculations on big integers (HO
+)
+Package: bitset 2016/05/16 v1.2 Handle bit-vector datatype (HO)
+Package: uniquecounter 2016/05/16 v1.3 Provide unlimited unique counter (HO)
+)
+Package hobsub Info: Skipping package `hobsub' (already loaded).
+Package: letltxmacro 2016/05/16 v1.5 Let assignment for LaTeX macros (HO)
+Package: hopatch 2016/05/16 v1.3 Wrapper for package hooks (HO)
+Package: xcolor-patch 2016/05/16 xcolor patch
+Package: atveryend 2016/05/16 v1.9 Hooks at the very end of document (HO)
+Package atveryend Info: \enddocument detected (standard20110627).
+Package: atbegshi 2016/06/09 v1.18 At begin shipout hook (HO)
+Package: refcount 2016/05/16 v3.5 Data extraction from label references (HO)
+Package: hycolor 2016/05/16 v1.8 Color options for hyperref/bookmark (HO)
+) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty
+Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional
+) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty
+Package: auxhook 2016/05/16 v1.4 Hooks for auxiliary files (HO)
+) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty
+Package: kvoptions 2016/05/16 v3.12 Key value format for package options (HO)
+)
+\@linkdim=\dimen142
+\Hy@linkcounter=\count118
+\Hy@pagecounter=\count119
+(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def
+File: pd1enc.def 2018/02/06 v6.86b Hyperref: PDFDocEncoding definition (HO)
+)
+\Hy@SavedSpaceFactor=\count120
+(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg
+File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive
+)
+Package hyperref Info: Option `bookmarks' set `true' on input line 4383.
+Package hyperref Info: Option `bookmarksnumbered' set `true' on input line 4383
+.
+Package hyperref Info: Option `bookmarksopen' set `false' on input line 4383.
+Package hyperref Info: Option `plainpages' set `false' on input line 4383.
+Package hyperref Info: Option `pdfpagelabels' set `true' on input line 4383.
+Package hyperref Info: Option `colorlinks' set `true' on input line 4383.
+Package hyperref Info: Hyper figures OFF on input line 4509.
+Package hyperref Info: Link nesting OFF on input line 4514.
+Package hyperref Info: Hyper index ON on input line 4517.
+Package hyperref Info: Plain pages OFF on input line 4524.
+Package hyperref Info: Backreferencing OFF on input line 4529.
+Package hyperref Info: Implicit mode ON; LaTeX internals redefined.
+Package hyperref Info: Bookmarks ON on input line 4762.
+\c@Hy@tempcnt=\count121
+(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty
+\Urlmuskip=\muskip10
+Package: url 2013/09/16  ver 3.4  Verb mode for urls, etc.
+)
+LaTeX Info: Redefining \url on input line 5115.
+\XeTeXLinkMargin=\dimen143
+\Fld@menulength=\count122
+\Field@Width=\dimen144
+\Fld@charsize=\dimen145
+Package hyperref Info: Hyper figures OFF on input line 6369.
+Package hyperref Info: Link nesting OFF on input line 6374.
+Package hyperref Info: Hyper index ON on input line 6377.
+Package hyperref Info: backreferencing OFF on input line 6384.
+Package hyperref Info: Link coloring ON on input line 6387.
+Package hyperref Info: Link coloring with OCG OFF on input line 6394.
+Package hyperref Info: PDF/A mode OFF on input line 6399.
+LaTeX Info: Redefining \ref on input line 6439.
+LaTeX Info: Redefining \pageref on input line 6443.
+\Hy@abspage=\count123
+\c@Item=\count124
+\c@Hfootnote=\count125
+)
+Package hyperref Info: Driver (default): hdvips.
+(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hdvips.def
+File: hdvips.def 2018/02/06 v6.86b Hyperref driver for dvips
+(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pdfmark.def
+File: pdfmark.def 2018/02/06 v6.86b Hyperref definitions for pdfmark specials
+\pdf@docset=\toks33
+\pdf@box=\box32
+\pdf@toks=\toks34
+\pdf@defaulttoks=\toks35
+\HyField@AnnotCount=\count126
+\Fld@listcount=\count127
+\c@bookmark@seq@number=\count128
+(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty
+Package: rerunfilecheck 2016/05/16 v1.8 Rerun checks for auxiliary files (HO)
+Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 2
+82.
+)
+\Hy@SectionHShift=\skip43
+)) (/usr/share/texlive/texmf-dist/tex/latex/base/ifthen.sty
+Package: ifthen 2014/09/29 v1.1c Standard LaTeX ifthen package (DPC)
+) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty
+Package: graphicx 2017/06/01 v1.1a Enhanced LaTeX Graphics (DPC,SPQR)
+(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty
+Package: graphics 2017/06/25 v1.2c Standard LaTeX Graphics (DPC,SPQR)
+(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty
+Package: trig 2016/01/03 v1.10 sin cos tan (DPC)
+) (/usr/share/texlive/texmf-dist/tex/latex/graphics-cfg/graphics.cfg
+File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration
+)
+Package graphics Info: Driver file: dvips.def on input line 99.
+)
+\Gin@req@height=\dimen146
+\Gin@req@width=\dimen147
+)
+\c@theorem=\count129
+\c@corollary=\count130
+(/usr/share/texlive/texmf-dist/tex/latex/listings/listings.sty
+\lst@mode=\count131
+\lst@gtempboxa=\box33
+\lst@token=\toks36
+\lst@length=\count132
+\lst@currlwidth=\dimen148
+\lst@column=\count133
+\lst@pos=\count134
+\lst@lostspace=\dimen149
+\lst@width=\dimen150
+\lst@newlines=\count135
+\lst@lineno=\count136
+\lst@maxwidth=\dimen151
+(/usr/share/texlive/texmf-dist/tex/latex/listings/lstmisc.sty
+File: lstmisc.sty 2015/06/04 1.6 (Carsten Heinz)
+\c@lstnumber=\count137
+\lst@skipnumbers=\count138
+\lst@framebox=\box34
+) (/usr/share/texlive/texmf-dist/tex/latex/listings/listings.cfg
+File: listings.cfg 2015/06/04 1.6 listings configuration
+))
+Package: listings 2015/06/04 1.6 (Carsten Heinz)
+\c@subroutine=\count139
+\c@example=\count140
+(/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty
+Package: inputenc 2015/03/17 v1.2c Input encoding file
+\inpenc@prehook=\toks37
+\inpenc@posthook=\toks38
+(/usr/share/texlive/texmf-dist/tex/latex/base/latin1.def
+File: latin1.def 2015/03/17 v1.2c Input encoding file
+))
+\sizebox=\box35
+\lthtmlwrite=\write4
+(./images.aux (/home/cirdan/VersioniPSBLAS/8Bytes/psblas3/docs/src/tmp/intro.au
+x) (/home/cirdan/VersioniPSBLAS/8Bytes/psblas3/docs/src/tmp/datastruct.aux) (/h
+ome/cirdan/VersioniPSBLAS/8Bytes/psblas3/docs/src/tmp/psbrout.aux) (/home/cirda
+n/VersioniPSBLAS/8Bytes/psblas3/docs/src/tmp/commrout.aux) (/home/cirdan/Versio
+niPSBLAS/8Bytes/psblas3/docs/src/tmp/toolsrout.aux) (/home/cirdan/VersioniPSBLA
+S/8Bytes/psblas3/docs/src/tmp/penv.aux) (/home/cirdan/VersioniPSBLAS/8Bytes/psb
+las3/docs/src/tmp/error.aux) (/home/cirdan/VersioniPSBLAS/8Bytes/psblas3/docs/s
+rc/tmp/util.aux) (/home/cirdan/VersioniPSBLAS/8Bytes/psblas3/docs/src/tmp/precs
+.aux) (/home/cirdan/VersioniPSBLAS/8Bytes/psblas3/docs/src/tmp/methods.aux))
+\openout1 = `images.aux'.
+
+LaTeX Font Info:    Checking defaults for OML/cmm/m/it on input line 149.
+LaTeX Font Info:    ... okay on input line 149.
+LaTeX Font Info:    Checking defaults for T1/cmr/m/n on input line 149.
+LaTeX Font Info:    ... okay on input line 149.
+LaTeX Font Info:    Checking defaults for OT1/cmr/m/n on input line 149.
+LaTeX Font Info:    ... okay on input line 149.
+LaTeX Font Info:    Checking defaults for OMS/cmsy/m/n on input line 149.
+LaTeX Font Info:    ... okay on input line 149.
+LaTeX Font Info:    Checking defaults for OMX/cmex/m/n on input line 149.
+LaTeX Font Info:    ... okay on input line 149.
+LaTeX Font Info:    Checking defaults for U/cmr/m/n on input line 149.
+LaTeX Font Info:    ... okay on input line 149.
+LaTeX Font Info:    Checking defaults for PD1/pdf/m/n on input line 149.
+LaTeX Font Info:    ... okay on input line 149.
+\AtBeginShipoutBox=\box36
+Package hyperref Info: Link coloring ON on input line 149.
+(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty
+Package: nameref 2016/05/21 v2.44 Cross-referencing by name of section
+(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty
+Package: gettitlestring 2016/05/16 v1.5 Cleanup title references (HO)
+)
+\c@section@level=\count141
+)
+LaTeX Info: Redefining \ref on input line 149.
+LaTeX Info: Redefining \pageref on input line 149.
+LaTeX Info: Redefining \nameref on input line 149.
+(./images.out) (./images.out)
+\@outlinefile=\write5
+\openout5 = `images.out'.
+
+\c@lstlisting=\count142
+
+latex2htmlLength hsize=349.0pt
+
+latex2htmlLength vsize=682.0pt
+
+latex2htmlLength hoffset=0.0pt
+
+latex2htmlLength voffset=0.0pt
+
+latex2htmlLength topmargin=0.0pt
+
+latex2htmlLength topskip=0.00003pt
+
+latex2htmlLength headheight=0.0pt
+
+latex2htmlLength headsep=0.0pt
+
+latex2htmlLength parskip=0.0pt plus 1.0pt
+
+latex2htmlLength oddsidemargin=28.0pt
+
+latex2htmlLength evensidemargin=79.0pt
+
+LaTeX Font Info:    Try loading font information for OMS+cmr on input line 225.
+
+(/usr/share/texlive/texmf-dist/tex/latex/base/omscmr.fd
+File: omscmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions
+)
+LaTeX Font Info:    Font shape `OMS/cmr/m/n' in size <9> not available
+(Font)              Font shape `OMS/cmsy/m/n' tried instead on input line 225.
+LaTeX Font Info:    Try loading font information for U+msa on input line 228.
+(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd
+File: umsa.fd 2013/01/14 v3.01 AMS symbols A
+)
+LaTeX Font Info:    Try loading font information for U+msb on input line 228.
+(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd
+File: umsb.fd 2013/01/14 v3.01 AMS symbols B
+)
+
+! LaTeX Error: Misplaced \endSbox! Should be in LR mode.
+
+See the LaTeX manual or LaTeX Companion for explanation.
+Type  H   for immediate help.
+ ...                                              
+                                                  
+l.229   \end{Sbox}
+                  %
+You're in trouble here.  Try typing    to proceed.
+If that doesn't work, type  X   to quit.
+
+l2hSize :Sbox7771:0.0pt::0.0pt::0.0pt.
+[1
+
+
+
+]
+
+! LaTeX Error: Misplaced \endSbox! Should be in LR mode.
+
+See the LaTeX manual or LaTeX Companion for explanation.
+Type  H   for immediate help.
+ ...                                              
+                                                  
+l.260   \end{Sbox}
+                  %
+You're in trouble here.  Try typing    to proceed.
+If that doesn't work, type  X   to quit.
+
+l2hSize :Sbox7788:0.0pt::0.0pt::0.0pt.
+[2
+
+
+]
+Package atveryend Info: Empty hook `BeforeClearDocument' on input line 273.
+Package atveryend Info: Empty hook `AfterLastShipout' on input line 273.
+(./images.aux)
+Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 273.
+Package atveryend Info: Executing hook `AtEndAfterFileList' on input line 273.
+Package rerunfilecheck Info: File `images.out' has not changed.
+(rerunfilecheck)             Checksum: D41D8CD98F00B204E9800998ECF8427E;0.
+Package atveryend Info: Empty hook `AtVeryVeryEnd' on input line 273.
+ ) 
+Here is how much of TeX's memory you used:
+ 13704 strings out of 494799
+ 227394 string characters out of 6177696
+ 322233 words of memory out of 5000000
+ 16868 multiletter control sequences out of 15000+600000
+ 6061 words of font info for 25 fonts, out of 8000000 for 9000
+ 81 hyphenation exceptions out of 8191
+ 36i,6n,40p,409b,1382s stack positions out of 5000i,500n,10000p,200000b,80000s
+
+Output written on images.dvi (2 pages, 3212 bytes).
diff --git a/docs/html/images.out b/docs/html/images.out
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/html/images.pl b/docs/html/images.pl
new file mode 100644
index 000000000..2fcccff4e
--- /dev/null
+++ b/docs/html/images.pl
@@ -0,0 +1,1182 @@
+# LaTeX2HTML 2018 (Released Feb 1, 2018)
+# Associate images original text with physical files.
+
+
+$key = q/(0dotsnp-1);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$(0\dots np-1)$|; 
+
+$key = q/(1dotsmg);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$(1\dots mg)$|; 
+
+$key = q/(1dotsnp);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$(1\dots np)$|; 
+
+$key = q/(i+irw-1),ja(j),val(j);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$(i+irw-1),ja(j),val(j)$|; 
+
+$key = q/-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$-1$|; 
+
+$key = q/-1<=root<=np-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$-1<= root <= np-1$|; 
+
+$key = q/-1leiamlenp-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$-1 \le iam \le np-1$|; 
+
+$key = q/-1lerootlenp-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$-1\le root\le np-1$|; 
+
+$key = q/0,1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$0,1$|; 
+
+$key = q/0;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$0$|; 
+
+$key = q/0<=dst<=np-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$0<= dst <= np-1$|; 
+
+$key = q/0<=m<=size(dat,1);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$0<= m <= size(dat,1)$|; 
+
+$key = q/0<=root<=np-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$0<= root <= np-1$|; 
+
+$key = q/0<=src<=np-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$0<= src <= np-1$|; 
+
+$key = q/0leiamlenp-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$0 \le iam \le np-1$|; 
+
+$key = q/0leidlenp-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$0 \le id \le np-1$|; 
+
+$key = q/0lepv(i)|; 
+
+$key = q/1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$1$|; 
+
+$key = q/1dotsn;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$1\dots n$|; 
+
+$key = q/1dotsn_{hbox{row}_i};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$1\dots n_{\hbox{row}_i}$|; 
+
+$key = q/=0;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$=0$|; 
+
+$key = q/>0;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$>0$|; 
+
+$key = q/A;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$A$|; 
+
+$key = q/A^T;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$A^T$|; 
+
+$key = q/CG;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$CG$|; 
+
+$key = q/D;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$D$|; 
+
+$key = q/FCG(1);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$FCG(1)$|; 
+
+$key = q/I;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$I$|; 
+
+$key = q/ILU(0);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$ILU(0)$|; 
+
+$key = q/IX;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$IX$|; 
+
+$key = q/N_I=nl;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$N_I=nl$|; 
+
+$key = q/O(n^2);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$O(n^2)$|; 
+
+$key = q/O(nlogn);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$O(n \log n)$|; 
+
+$key = q/P^T;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$P^T$|; 
+
+$key = q/P^{T};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$P^{T}$|; 
+
+$key = q/P_a;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$P_a$|; 
+
+$key = q/P_aP^T;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$P_aP^T$|; 
+
+$key = q/Q;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$Q$|; 
+
+$key = q/T;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$T$|; 
+
+$key = q/X;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$X$|; 
+
+$key = q/a;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$a$|; 
+
+$key = q/a_{ij}ne0;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$a_{ij} \ne0$|; 
+
+$key = q/alpha;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$\alpha$|; 
+
+$key = q/amax;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$amax$|; 
+
+$key = q/asum;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$asum$|; 
+
+$key = q/beta;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$\beta$|; 
+
+$key = q/calB;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$\cal B$|; 
+
+$key = q/calH;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$\cal H$|; 
+
+$key = q/calI;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$\cal I$|; 
+
+$key = q/collect;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$collect$|; 
+
+$key = q/dat;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$dat$|; 
+
+$key = q/dat_i;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$dat_i$|; 
+
+$key = q/diag(1)=1(noscaling);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$diag(1) = 1 (no scaling)$|; 
+
+$key = q/dot;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$dot$|; 
+
+$key = q/dst;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$dst$|; 
+
+$key = q/fbox{TheSbox};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\fbox{\TheSbox}|; 
+
+$key = q/flag=psb_sort_keep_idx_;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$flag = psb\_sort\_keep\_idx\_$|; 
+
+$key = q/flag=psb_sort_ovw_idx_;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$flag = psb\_sort\_ovw\_idx\_$|; 
+
+$key = q/glob_x;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$glob\_x$|; 
+
+$key = q/glob_x_{1:m,1:n};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$glob\_x_{1:m,1:n}$|; 
+
+$key = q/i+irw-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$i+irw-1$|; 
+
+$key = q/i;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$i$|; 
+
+$key = q/i=1,dots,nz;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$i=1,\dots,nz$|; 
+
+$key = q/i=1,nr;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$i=1,nr$|; 
+
+$key = q/ia(i),ja(i),val(i);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$ia(i),ja(i),val(i)$|; 
+
+$key = q/ia(i),ja(i);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$ia(i),ja(i)$|; 
+
+$key = q/ia(i);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$ia(i)$|; 
+
+$key = q/iam=-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$iam=-1$|; 
+
+$key = q/id;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$id$|; 
+
+$key = q/iin{1dotsmg};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$i\in \{1\dots mg\}$|; 
+
+$key = q/includegraphics[scale=0.45]{figuresslashtry8x8.eps};FSF=1.6;AAT/;
+$cached_env_img{$key} = q|\includegraphics[scale=0.45]{figures/try8x8.eps}|; 
+
+$key = q/includegraphics[scale=0.45]{figuresslashtry8x8};FSF=1.6;AAT/;
+$cached_env_img{$key} = q|\includegraphics[scale=0.45]{figures/try8x8}|; 
+
+$key = q/includegraphics[scale=0.65]{figuresslashpoints.eps};FSF=1.6;AAT/;
+$cached_env_img{$key} = q|\includegraphics[scale=0.65]{figures/points.eps}|; 
+
+$key = q/includegraphics[scale=0.65]{figuresslashpsblas.eps};FSF=1.6;AAT/;
+$cached_env_img{$key} = q|\includegraphics[scale=0.65]{figures/psblas.eps}|; 
+
+$key = q/includegraphics[scale=0.65]{figuresslashpsblas};FSF=1.6;AAT/;
+$cached_env_img{$key} = q|\includegraphics[scale=0.65]{figures/psblas}|; 
+
+$key = q/includegraphics[scale=0.65]{figuresslashtry8x8_ov.eps};FSF=1.6;AAT/;
+$cached_env_img{$key} = q|\includegraphics[scale=0.65]{figures/try8x8_ov.eps}|; 
+
+$key = q/includegraphics[scale=0.65]{figuresslashtry8x8_ov};FSF=1.6;AAT/;
+$cached_env_img{$key} = q|\includegraphics[scale=0.65]{figures/try8x8_ov}|; 
+
+$key = q/irst>0;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$irst>0$|; 
+
+$key = q/irw(i);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$irw(i)$|; 
+
+$key = q/itmax=1000;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$itmax = 1000$|; 
+
+$key = q/itmaxge1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$itmax \ge 1$|; 
+
+$key = q/itrace;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$itrace$|; 
+
+$key = q/itrace=-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$itrace = -1$|; 
+
+$key = q/ix(1:n);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$ix(1:n)$|; 
+
+$key = q/ix(:);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$ix(:)$|; 
+
+$key = q/ix(i);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$ix(i)$|; 
+
+$key = q/ix(i)leftarrowi;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$ix(i) \leftarrow
+i$|; 
+
+$key = q/j;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$j$|; 
+
+$key = q/j=irp(i),dots,irp(i+1)-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$j=irp(i),\dots,irp(i+1)-1$|; 
+
+$key = q/ja(i);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$ja(i)$|; 
+
+$key = q/lidx(1:nl);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$lidx(1:nl)$|; 
+
+$key = q/loc_x_i;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$loc\_x_i$|; 
+
+$key = q/m;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$m$|; 
+
+$key = q/mg;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$mg$|; 
+
+$key = q/n;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$n$|; 
+
+$key = q/n_{hbox{row}_i}+1dotsn_{hbox{col}_i};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$n_{\hbox{row}_i}+1\dots n_{\hbox{col}_i}$|; 
+
+$key = q/nlge0;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$nl\ge 0$|; 
+
+$key = q/nnz;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$nnz$|; 
+
+$key = q/np-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$np-1$|; 
+
+$key = q/np;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$np$|; 
+
+$key = q/nr+1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$nr+1$|; 
+
+$key = q/nrm2;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$nrm2$|; 
+
+$key = q/nv>1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$nv>1$|; 
+
+$key = q/nz;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$nz$|; 
+
+$key = q/nzin+nz;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$nzin+nz$|; 
+
+$key = q/ptype;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$ptype$|; 
+
+$key = q/r_i=b-Ax_i;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$r_i=b-Ax_i$|; 
+
+$key = q/res;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$res$|; 
+
+$key = q/root=-1;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$root=-1$|; 
+
+$key = q/rotatebox{-90}{includegraphics[scale=0.65]{figuresslashpoints}};FSF=1.6;AAT/;
+$cached_env_img{$key} = q|\rotatebox{-90}{\includegraphics[scale=0.65]{figures/points}}|; 
+
+$key = q/row;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$row$|; 
+
+$key = q/scatter;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$scatter$|; 
+
+$key = q/size(dat,1);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$size(dat,1)$|; 
+
+$key = q/slash;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$/$|; 
+
+$key = q/src;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$src$|; 
+
+$key = q/trans=N;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$trans = N$|; 
+
+$key = q/unitd=U;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$unitd = U$|; 
+
+$key = q/update_type=psb_avg_;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$update\_type = psb\_avg\_ $|; 
+
+$key = q/val;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$val$|; 
+
+$key = q/vg(i);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$vg(i)$|; 
+
+$key = q/vg;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$vg$|; 
+
+$key = q/vl(1:nl);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$vl(1:nl)$|; 
+
+$key = q/vl;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$vl$|; 
+
+$key = q/x(i);MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$x(i)$|; 
+
+$key = q/x(i)=0;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$x(i) = 0$|; 
+
+$key = q/x;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$x$|; 
+
+$key = q/x_i,y;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$x_i, y$|; 
+
+$key = q/x_i;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$x_i$|; 
+
+$key = q/x_{:,:};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$x_{:, :}$|; 
+
+$key = q/y(i)=0;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$y(i) = 0$|; 
+
+$key = q/y;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$y$|; 
+
+$key = q/y_{:,:};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$y_{:, :}$|; 
+
+$key = q/{displaymath}14{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}\verb\vert psb_version_string_\vert\end{displaymath}|; 
+
+$key = q/{displaymath}amaxleftarrowmax_i{(|re(x_i)|+|im(x_i)|)}{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}amax \leftarrow \max_i {(\vert re(x_i)\vert + \vert im(x_i)\vert)}\end{displaymath}|; 
+
+$key = q/{displaymath}amaxleftarrowmax_i|x_i|{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}amax \leftarrow \max_i \vert x_i\vert\end{displaymath}|; 
+
+$key = q/{displaymath}asumleftarrow|re(x)|_1+|im(x)|_1{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}asum \leftarrow \Vert re(x)\Vert _1 + \Vert im(x)\Vert _1\end{displaymath}|; 
+
+$key = q/{displaymath}asumleftarrow|x_i|{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}asum \leftarrow \Vert x_i\Vert\end{displaymath}|; 
+
+$key = q/{displaymath}dotleftarrowx(i)y(i).{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}dot \leftarrow x(i) y(i).\end{displaymath}|; 
+
+$key = q/{displaymath}dotleftarrowx^Hy{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}dot \leftarrow x^H y\end{displaymath}|; 
+
+$key = q/{displaymath}dotleftarrowx^Ty{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}dot \leftarrow x^T y\end{displaymath}|; 
+
+$key = q/{displaymath}err=frac{|r_i|}{(|A||x_i|+|b|)}|; 
+
+$key = q/{displaymath}err=frac{|r_i|}{|b|_2}|; 
+
+$key = q/{displaymath}err=frac{|r_i|}{|r_0|_2}|; 
+
+$key = q/{displaymath}glob_xleftarrowcollect(loc_x_i){displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}glob\_x \leftarrow collect(loc\_x_i) \end{displaymath}|; 
+
+$key = q/{displaymath}loc_x_ileftarrowscatter(glob_x){displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}loc\_x_i \leftarrow scatter(glob\_x) \end{displaymath}|; 
+
+$key = q/{displaymath}nrm1leftarrow|A|_1{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}nrm1 \leftarrow \Vert A\Vert _1 \end{displaymath}|; 
+
+$key = q/{displaymath}nrm2leftarrowsqrt{x^Hx}{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}nrm2 \leftarrow \sqrt{x^H x}\end{displaymath}|; 
+
+$key = q/{displaymath}nrm2leftarrowsqrt{x^Tx}{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}nrm2 \leftarrow \sqrt{x^T x}\end{displaymath}|; 
+
+$key = q/{displaymath}nrmileftarrow|A|_infty{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}nrmi \leftarrow \Vert A\Vert _\infty \end{displaymath}|; 
+
+$key = q/{displaymath}res(i)leftarrowmax_k|x(k,i)|{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}res(i) \leftarrow \max_k \vert x(k,i)\vert \end{displaymath}|; 
+
+$key = q/{displaymath}res(i)leftarrowx(:,i)^Ty(:,i){displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}res(i) \leftarrow x(:,i)^T y(:,i)\end{displaymath}|; 
+
+$key = q/{displaymath}res(i)leftarrow|re(x)|_1+|im(x)|_1{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}res(i) \leftarrow \Vert re(x)\Vert _1 + \Vert im(x)\Vert _1\end{displaymath}|; 
+
+$key = q/{displaymath}res(i)leftarrow|x(:,i)|_2{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}res(i) \leftarrow \Vert x(:,i)\Vert _2 \end{displaymath}|; 
+
+$key = q/{displaymath}res(i)leftarrow|x_i|{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}res(i) \leftarrow \Vert x_i\Vert\end{displaymath}|; 
+
+$key = q/{displaymath}res=sqrt{sum_idat_i^2},{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}res = \sqrt{\sum_i dat_i^2},\end{displaymath}|; 
+
+$key = q/{displaymath}slashleftarrow1slashx(i).{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}/ \leftarrow 1/x(i).\end{displaymath}|; 
+
+$key = q/{displaymath}slashleftarrowx(i)slashy(i).{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}/ \leftarrow x(i)/y(i).\end{displaymath}|; 
+
+$key = q/{displaymath}xleftarrowQx{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}x \leftarrow Q x \end{displaymath}|; 
+
+$key = q/{displaymath}xleftarrowx{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}x \leftarrow x \end{displaymath}|; 
+
+$key = q/{displaymath}yleftarrowalpha>x+betay{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}y \leftarrow \alpha\> x+ \beta y \end{displaymath}|; 
+
+$key = q/{displaymath}yleftarrowalphaA^Hx+betay{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}
+y \leftarrow \alpha A^H x + \beta y
+\end{displaymath}|; 
+
+$key = q/{displaymath}yleftarrowalphaA^Tx+betay{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}
+y \leftarrow \alpha A^T x + \beta y
+\end{displaymath}|; 
+
+$key = q/{displaymath}yleftarrowalphaAx+betay{displaymath};MSF=1.6;AAT/;
+$cached_env_img{$key} = q|\begin{displaymath}
+y \leftarrow \alpha A x + \beta y
+\end{displaymath}|; 
+
+$key = q/{eqnarraystar}y&leftarrow&alphaT^{-1}x+betayy&leftarrow&alphaDT^{-1}x+betayy&lefhaDT^{-H}x+betayy&leftarrow&alphaT^{-H}Dx+betay{eqnarraystar};MSF=1.6;TAGS=R;AAT/;
+$cached_env_img{$key} = q|\begin{eqnarray*}
+y &\leftarrow& \alpha T^{-1} x + \beta y\\\\
+y &\leftarrow& \al...
+...-H} x + \beta y\\\\
+y &\leftarrow& \alpha T^{-H} D x + \beta y\\\\
+\end{eqnarray*}|; 
+
+$key = q/{lstlisting}callhb_read(a,iret,iunit,filename,b,mtitle){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call hb_read(a, iret, iunit, filename, b, mtitle)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callhb_write(a,iret,iunit,filename,key,rhs,mtitle){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call hb_write(a, iret, iunit, filename, key, rhs, mtitle)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callmm_array_read(b,iret,iunit,filename){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call mm_array_read(b, iret, iunit, filename)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callmm_array_write(b,iret,iunit,filename){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call mm_array_write(b, iret, iunit, filename)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callmm_mat_read(a,iret,iunit,filename){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call mm_mat_read(a, iret, iunit, filename)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callmm_mat_write(a,mtitle,iret,iunit,filename){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call mm_mat_write(a, mtitle, iret, iunit, filename)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callpsb_error(icontxt){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call psb_error(icontxt)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callpsb_errpush(err_c,r_name,i_err,a_err){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call psb_errpush(err_c, r_name, i_err, a_err)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callpsb_gather(glob_x,loc_x,desc_a,info,root)callpsb_gather(glob_x,loc_x,desc_a,info,root){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call psb_gather(glob_x, loc_x, desc_a, info, root)
+call psb_gather(glob_x, loc_x, desc_a, info, root)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callpsb_halo(x,desc_a,info)callpsb_halo(x,desc_a,info,work,data){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call psb_halo(x, desc_a, info)
+call psb_halo(x, desc_a, info, work, data)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callpsb_krylov(method,a,prec,b,x,eps,desc_a,info,&&itmax,iter,err,itrace,irst,istop,cond){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call psb_krylov(method,a,prec,b,x,eps,desc_a,info,&
+& itmax,iter,err,itrace,irst,istop,cond)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callpsb_ovrl(x,desc_a,info)callpsb_ovrl(x,desc_a,info,update=update_type,work=work){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call psb_ovrl(x, desc_a, info)
+call psb_ovrl(x, desc_a, info, update=update_type, work=work)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callpsb_scatter(glob_x,loc_x,desc_a,info,root,mold){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call psb_scatter(glob_x, loc_x, desc_a, info, root, mold)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callpsb_set_erraction(err_act){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call psb_set_erraction(err_act)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}callpsb_set_errverbosity(v){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+call psb_set_errverbosity(v)
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}vres(1)=psb_geamax(x1,desc_a,info,global=.false.)vres(2)=psb_geamax(eamax(x3,desc_a,info,global=.false.)callpsb_amx(ictxt,vres(1:3)){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+vres(1) = psb_geamax(x1,desc_a,info,global=.false.)
+vres(2)...
+...(x3,desc_a,info,global=.false.)
+call psb_amx(ictxt,vres(1:3))
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}vres(1)=psb_geasum(x1,desc_a,info,global=.false.)vres(2)=psb_geasum(easum(x3,desc_a,info,global=.false.)callpsb_sum(ictxt,vres(1:3)){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+vres(1) = psb_geasum(x1,desc_a,info,global=.false.)
+vres(2)...
+...(x3,desc_a,info,global=.false.)
+call psb_sum(ictxt,vres(1:3))
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}vres(1)=psb_gedot(x1,y1,desc_a,info,global=.false.)vres(2)=psb_gedotot(x3,y3,desc_a,info,global=.false.)callpsb_sum(ictxt,vres(1:3)){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+vres(1) = psb_gedot(x1,y1,desc_a,info,global=.false.)
+vres(...
+...,y3,desc_a,info,global=.false.)
+call psb_sum(ictxt,vres(1:3))
+\end{lstlisting}|; 
+
+$key = q/{lstlisting}vres(1)=psb_genrm2(x1,desc_a,info,global=.false.)vres(2)=psb_genrm2(nrm2(x3,desc_a,info,global=.false.)callpsb_nrm2(ictxt,vres(1:3)){lstlisting};AAT/;
+$cached_env_img{$key} = q|\begin{lstlisting}
+vres(1) = psb_genrm2(x1,desc_a,info,global=.false.)
+vres(2)...
+...x3,desc_a,info,global=.false.)
+call psb_nrm2(ictxt,vres(1:3))
+\end{lstlisting}|; 
+
+$key = q/|{calI}_i|+|{calB}_i|+|{calH}_i|;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$\vert{\cal I}_i\vert + \vert{\cal B}_i\vert +\vert{\cal H}_i\vert$|; 
+
+$key = q/|{calI}_i|+|{calB}_i|;MSF=1.6;AAT/;
+$cached_env_img{$key} = q|$\vert{\cal I}_i\vert + \vert{\cal B}_i\vert$|; 
+
+1;
+
diff --git a/docs/html/images.tex b/docs/html/images.tex
new file mode 100644
index 000000000..2191e46c8
--- /dev/null
+++ b/docs/html/images.tex
@@ -0,0 +1,273 @@
+\batchmode
+\documentclass[10pt,a4paper,twoside]{article}
+
+\usepackage{pstricks}
+\usepackage{fancybox}
+\usepackage{amsfonts}
+\usepackage[bookmarks=true,             bookmarksnumbered=true,             bookmarksopen=false,             plainpages=false,            pdfpagelabels,            colorlinks,             linkcolor=blue]{hyperref}
+\usepackage{ifthen}
+\usepackage{graphicx}
+
+\newtheorem{theorem}{Theorem} 
+\newtheorem{corollary}{Corollary} \usepackage{listings}
+
+
+\pdfoutput=0
+
+
+
+\newcounter{subroutine}[subsection] 
+\newcounter{example}[subroutine] \makeatletter%
+\providecommand{\subsubroutine}[2]{%
+\stepcounter{subroutine}%
+      \subsection*{\flushleft #1---#2 \endflushleft}%
+      \addcontentsline{toc}{subsubsection}{#1}%
+      \markright{#1}}%%
+\providecommand{\subsubsubroutine}[2]{%
+\stepcounter{subroutine}%
+      \subsubsection*{\flushleft #1---#2 \endflushleft}%
+      \addcontentsline{toc}{paragraph}{#1}%
+      \markright{#1}}%%
+\providecommand{\examplename}{Example}%
+\providecommand{\syntaxname}{Syntax} 
+
+\makeatother%
+\providecommand{\example}{\stepcounter{example}%
+\section*{Example~\arabic{example}}} 
+
+%
+\providecommand{\precdata}{\hyperlink{precdata}{{\tt psb\_prec\_type}}}%
+\providecommand{\descdata}{\hyperlink{descdata}{{\tt psb\_desc\_type}}}%
+\providecommand{\spdata}{\hyperlink{spdata}{{\tt psb\_Tspmat\_type}}}%
+\providecommand{\vdata}{\hyperlink{vdata}{{\tt psb\_T\_vect\_type}}}%
+\providecommand{\spbasedata}{\hypertarget{spbasedata}{{\tt psb\_T\_base\_sparse\_mat}}}%
+\providecommand{\vbasedata}{\hypertarget{vbasedata}{{\tt psb\_T\_base\_vect\_type}}} 
+
+
+
+
+\usepackage[latin1]{inputenc}
+
+
+
+\makeatletter
+
+\makeatletter
+\count@=\the\catcode`\_ \catcode`\_=8 
+\newenvironment{tex2html_wrap}{}{}%
+\catcode`\<=12\catcode`\_=\count@
+\newcommand{\providedcommand}[1]{\expandafter\providecommand\csname #1\endcsname}%
+\newcommand{\renewedcommand}[1]{\expandafter\providecommand\csname #1\endcsname{}%
+  \expandafter\renewcommand\csname #1\endcsname}%
+\newcommand{\newedenvironment}[1]{\newenvironment{#1}{}{}\renewenvironment{#1}}%
+\let\newedcommand\renewedcommand
+\let\renewedenvironment\newedenvironment
+\makeatother
+\let\mathon=$
+\let\mathoff=$
+\ifx\AtBeginDocument\undefined \newcommand{\AtBeginDocument}[1]{}\fi
+\newbox\sizebox
+\setlength{\hoffset}{0pt}\setlength{\voffset}{0pt}
+\addtolength{\textheight}{\footskip}\setlength{\footskip}{0pt}
+\addtolength{\textheight}{\topmargin}\setlength{\topmargin}{0pt}
+\addtolength{\textheight}{\headheight}\setlength{\headheight}{0pt}
+\addtolength{\textheight}{\headsep}\setlength{\headsep}{0pt}
+\setlength{\textwidth}{349pt}
+\newwrite\lthtmlwrite
+\makeatletter
+\let\realnormalsize=\normalsize
+\global\topskip=2sp
+\def\preveqno{}\let\real@float=\@float \let\realend@float=\end@float
+\def\@float{\let\@savefreelist\@freelist\real@float}
+\def\liih@math{\ifmmode$\else\bad@math\fi}
+\def\end@float{\realend@float\global\let\@freelist\@savefreelist}
+\let\real@dbflt=\@dbflt \let\end@dblfloat=\end@float
+\let\@largefloatcheck=\relax
+\let\if@boxedmulticols=\iftrue
+\def\@dbflt{\let\@savefreelist\@freelist\real@dbflt}
+\def\adjustnormalsize{\def\normalsize{\mathsurround=0pt \realnormalsize
+ \parindent=0pt\abovedisplayskip=0pt\belowdisplayskip=0pt}%
+ \def\phantompar{\csname par\endcsname}\normalsize}%
+\def\lthtmltypeout#1{{\let\protect\string \immediate\write\lthtmlwrite{#1}}}%
+\newcommand\lthtmlhboxmathA{\adjustnormalsize\setbox\sizebox=\hbox\bgroup\kern.05em }%
+\newcommand\lthtmlhboxmathB{\adjustnormalsize\setbox\sizebox=\hbox to\hsize\bgroup\hfill }%
+\newcommand\lthtmlvboxmathA{\adjustnormalsize\setbox\sizebox=\vbox\bgroup %
+ \let\ifinner=\iffalse \let\)\liih@math }%
+\newcommand\lthtmlboxmathZ{\@next\next\@currlist{}{\def\next{\voidb@x}}%
+ \expandafter\box\next\egroup}%
+\newcommand\lthtmlmathtype[1]{\gdef\lthtmlmathenv{#1}}%
+\newcommand\lthtmllogmath{\dimen0\ht\sizebox \advance\dimen0\dp\sizebox
+  \ifdim\dimen0>.95\vsize
+   \lthtmltypeout{%
+*** image for \lthtmlmathenv\space is too tall at \the\dimen0, reducing to .95 vsize ***}%
+   \ht\sizebox.95\vsize \dp\sizebox\z@ \fi
+  \lthtmltypeout{l2hSize %
+:\lthtmlmathenv:\the\ht\sizebox::\the\dp\sizebox::\the\wd\sizebox.\preveqno}}%
+\newcommand\lthtmlfigureA[1]{\let\@savefreelist\@freelist
+       \lthtmlmathtype{#1}\lthtmlvboxmathA}%
+\newcommand\lthtmlpictureA{\bgroup\catcode`\_=8 \lthtmlpictureB}%
+\newcommand\lthtmlpictureB[1]{\lthtmlmathtype{#1}\egroup
+       \let\@savefreelist\@freelist \lthtmlhboxmathB}%
+\newcommand\lthtmlpictureZ[1]{\hfill\lthtmlfigureZ}%
+\newcommand\lthtmlfigureZ{\lthtmlboxmathZ\lthtmllogmath\copy\sizebox
+       \global\let\@freelist\@savefreelist}%
+\newcommand\lthtmldisplayA{\bgroup\catcode`\_=8 \lthtmldisplayAi}%
+\newcommand\lthtmldisplayAi[1]{\lthtmlmathtype{#1}\egroup\lthtmlvboxmathA}%
+\newcommand\lthtmldisplayB[1]{\edef\preveqno{(\theequation)}%
+  \lthtmldisplayA{#1}\let\@eqnnum\relax}%
+\newcommand\lthtmldisplayZ{\lthtmlboxmathZ\lthtmllogmath\lthtmlsetmath}%
+\newcommand\lthtmlinlinemathA{\bgroup\catcode`\_=8 \lthtmlinlinemathB}
+\newcommand\lthtmlinlinemathB[1]{\lthtmlmathtype{#1}\egroup\lthtmlhboxmathA
+  \vrule height1.5ex width0pt }%
+\newcommand\lthtmlinlineA{\bgroup\catcode`\_=8 \lthtmlinlineB}%
+\newcommand\lthtmlinlineB[1]{\lthtmlmathtype{#1}\egroup\lthtmlhboxmathA}%
+\newcommand\lthtmlinlineZ{\egroup\expandafter\ifdim\dp\sizebox>0pt %
+  \expandafter\centerinlinemath\fi\lthtmllogmath\lthtmlsetinline}
+\newcommand\lthtmlinlinemathZ{\egroup\expandafter\ifdim\dp\sizebox>0pt %
+  \expandafter\centerinlinemath\fi\lthtmllogmath\lthtmlsetmath}
+\newcommand\lthtmlindisplaymathZ{\egroup %
+  \centerinlinemath\lthtmllogmath\lthtmlsetmath}
+\def\lthtmlsetinline{\hbox{\vrule width.1em \vtop{\vbox{%
+  \kern.1em\copy\sizebox}\ifdim\dp\sizebox>0pt\kern.1em\else\kern.3pt\fi
+  \ifdim\hsize>\wd\sizebox \hrule depth1pt\fi}}}
+\def\lthtmlsetmath{\hbox{\vrule width.1em\kern-.05em\vtop{\vbox{%
+  \kern.1em\kern0.8 pt\hbox{\hglue.17em\copy\sizebox\hglue0.8 pt}}\kern.3pt%
+  \ifdim\dp\sizebox>0pt\kern.1em\fi \kern0.8 pt%
+  \ifdim\hsize>\wd\sizebox \hrule depth1pt\fi}}}
+\def\centerinlinemath{%
+  \dimen1=\ifdim\ht\sizebox<\dp\sizebox \dp\sizebox\else\ht\sizebox\fi
+  \advance\dimen1by.5pt \vrule width0pt height\dimen1 depth\dimen1 
+ \dp\sizebox=\dimen1\ht\sizebox=\dimen1\relax}
+
+\def\lthtmlcheckvsize{\ifdim\ht\sizebox<\vsize 
+  \ifdim\wd\sizebox<\hsize\expandafter\hfill\fi \expandafter\vfill
+  \else\expandafter\vss\fi}%
+\providecommand{\selectlanguage}[1]{}%
+\makeatletter \tracingstats = 1 
+
+
+\begin{document}
+\pagestyle{empty}\thispagestyle{empty}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength hsize=\the\hsize}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength vsize=\the\vsize}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength hoffset=\the\hoffset}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength voffset=\the\voffset}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength topmargin=\the\topmargin}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength topskip=\the\topskip}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength headheight=\the\headheight}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength headsep=\the\headsep}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength parskip=\the\parskip}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength oddsidemargin=\the\oddsidemargin}\lthtmltypeout{}%
+\makeatletter
+\if@twoside\lthtmltypeout{latex2htmlLength evensidemargin=\the\evensidemargin}%
+\else\lthtmltypeout{latex2htmlLength evensidemargin=\the\oddsidemargin}\fi%
+\lthtmltypeout{}%
+\makeatother
+\setcounter{page}{1}
+\onecolumn
+
+% !!! IMAGES START HERE !!!
+
+\begingroup 
+\renewcommand{\thepage}{toc}
+\endgroup
+\stepcounter{section}
+\stepcounter{section}
+\stepcounter{subsection}
+\stepcounter{subsection}
+\stepcounter{subsection}
+\stepcounter{subsubsection}
+\stepcounter{subsection}
+\stepcounter{section}
+\stepcounter{subsection}
+\stepcounter{subsubsection}
+\stepcounter{subsubsection}
+\stepcounter{subsection}
+\stepcounter{subsubsection}
+\stepcounter{subsubsection}
+\stepcounter{subsection}
+\stepcounter{subsubsection}
+\stepcounter{subsection}
+\stepcounter{subsection}
+\stepcounter{section}
+\stepcounter{section}
+\stepcounter{section}
+\stepcounter{section}
+\stepcounter{section}
+{\newpage\clearpage
+\lthtmlfigureA{Sbox7771}%
+\begin{Sbox}
+    \begin{minipage}[tl]{0.95\textwidth}
+\small
+\begin{lstlisting}
+subroutine psb_foo(some args, info)
+   ...
+   if(error detected) then
+      info=errcode1
+      call psb_errpush('psb_foo', errcode1)
+      goto 9999
+   end if
+   ...
+   call psb_bar(some args, info)
+   if(info .ne. zero) then
+      info=errcode2
+      call psb_errpush('psb_foo', errcode2)
+      goto 9999
+   end if
+   ...
+9999 continue
+   if (err_act .eq. act_abort) then
+     call psb_error(icontxt)
+     return
+   else
+     return
+   end if
+\par
+end subroutine psb_foo
+\end{lstlisting}
+    \end{minipage}
+  \end{Sbox}%
+\lthtmlfigureZ
+\lthtmlcheckvsize\clearpage}
+
+
+
+\setlength{\fboxsep}{8pt}%
+
+\setlength{\fboxsep}{8pt}
+{\newpage\clearpage
+\lthtmlfigureA{Sbox7788}%
+\begin{Sbox}
+    \begin{minipage}[tl]{0.95\textwidth}
+\begin{verbatim}
+
+==========================================================
+Process: 0.  PSBLAS Error (4010) in subroutine: df_sample           
+Error from call to subroutine mat dist            
+==========================================================
+Process: 0.  PSBLAS Error (4010) in subroutine: mat_distv           
+Error from call to subroutine psb_spasb           
+==========================================================
+Process: 0.  PSBLAS Error (4010) in subroutine: psb_spasb           
+Error from call to subroutine psb_cest            
+==========================================================
+Process: 0.  PSBLAS Error (136) in subroutine: psb_cest            
+Format FOO is unknown
+==========================================================
+Aborting...\end{verbatim}
+
+    \end{minipage}
+  \end{Sbox}%
+\lthtmlfigureZ
+\lthtmlcheckvsize\clearpage}
+
+
+
+\setlength{\fboxsep}{8pt}%
+
+\setlength{\fboxsep}{8pt}
+\stepcounter{section}
+\stepcounter{section}
+\stepcounter{section}
+
+\end{document}
diff --git a/docs/html/img1.png b/docs/html/img1.png
index 2ac27f9619e5eb27f3ca81d3b0f77011c78ffb37..e7280f00d36d73c160acac44123814715d0282a7 100644
GIT binary patch
delta 195
zcmV;!06hQ50n!1G7k>`~0{{R4Xj)>50000gP)t-s|NsA)nVDr}WkW+l?(Xi)%*?8)
zs)&e)c6N3E001&FGTq(X5D*Z%ySuRzb9?{*00DGTPE!Ct=GbNc0034=L_t&tnPXsJ
z;ATJt2N)O@FfcU0xRF52af^Y0cLH+*iaKu)kqg9(96*BYGCYuI;9+23YLL8uX5t1Y
x%{~{(XqW+^Js6C@G;8f$WiX?ffgzKD0RVRK4J4odCXxUE002ovPDHLkV1mBTN)-SA

delta 185
zcmcb_c!F_)cs(BrGXn$TVz!O?3=9nF0X`wF|NsA=Idf)tdHK6{?~IL&1qB6HtyFtfSD&~Skfqwowyp#V3-YkZ=3uOXf}hVtDnm{r-UW|^y)#_

diff --git a/docs/html/img10.png b/docs/html/img10.png
index 41dbbad67f5d00bdffd4d5a0ef6ab3537fd89bbd..e94e2a07b561799143695201bb1d6f20cbd23ffc 100644
GIT binary patch
literal 447
zcmV;w0YLtVP)N0}~h+Hh{?_mU`XI(n83+U05mUvlV6`R;Q^4vAPE%nXPiKUIp|($XCGNdH^B{<}(2qofptd>H?-R1(+zqTDw-S;u>5*UT2UD3nw$
pfHE#12_i({K1U4#Y@$OA0003oRdzkQ%@F_q002ovPDHLkV1n(5r*!}T

literal 404
zcmV;F0c-w=P)Hh-PMH0000)L`2=)-6A3)ySuv-E6N)H
z0004WQchCOO@Ms1W0EQBMt(p4&z~a7%9W0CXEc3}oOwfIcdgAd3JDD|t
z8TF|h<9Dg}C5JT8iioCH)uh}?{otLT21
zTj)s|f>-OIXC4AD9^&PFC0HAS*_$-VmuYZ4dJBoAM}&2Ev*ER45JzwRUHSqS!Qf3A
yw0V0sM@=_)&qhoMZcb|Dy$*UU&2#Sue-RIimk8_{iK!?60000S

diff --git a/docs/html/img100.png b/docs/html/img100.png
index 89a17445a1029668b2dc5d19d19653f60ae4a6e7..f6badca21146f4a33fb163270ec8b2d12afb96e0 100644
GIT binary patch
literal 603
zcmV-h0;K(kP)vdLMKHOk)R@>qDYTRO2bvhLpr5LT9k^UxO}@lC&rv8P}1>9o|&E5*`3!K
z7-QNHWyr9J&$x>qXOX2@#ptyQ=}?d)!(#h`p`Zo*KK
zeu7Lu#`G8_p38=t0Ju90!z^?ot|adaj$3@+S9_xoTyqkeSHx*+
z|Al=+EZX4#9zI7PFTB
pMue^wuUl2zhJ8x${d*o^@Ea(lbhv=4ECB!j002ovPDHLkV1oaQ9QgnM

literal 178
zcmeAS@N?(olHy`uVBq!ia0vp^JV4CH!py+HIB&`YPasDh($

diff --git a/docs/html/img101.png b/docs/html/img101.png
index f539ffeb3309da75bba063bf2f46ca8d6c155676..991e37cee66b74720e38c0af525b746a8ec341ef 100644
GIT binary patch
literal 318
zcmV-E0m1%>P)~5D>e&yC0vO-~a#s0d!JM
zQvg8b*k%9#0KZ8@K~yM_V_*OQ4h9S$#epWs%)r2Mm4RUa7PaVri{k+wm~nuCi?C|!
zfCof0Ffi~)1j=&UqJhh337#vVi!gUSfU=svWKOri6TYVkj0?cL
zMGKIm81681Ft8ke#q-MsgcQ2~--d!m3~!J%L8XAPYs|n93}SM@tQsN!0PWT$5ZvYQ
QU;qFB07*qoM6N<$f>23+6aWAK

literal 363
zcmV-x0hIoUP)SV1R;83=9_-@PQ2iAToe~ft7(t39m{91}1hWgEIug
zn*d@qFzIt!fEW)5XvPLqI1%gvKx26r7!tsoOKc!=5rYB`)Mn;y3&=2^0N}Zx184Jt
z>@Pr)1O?jy0VqfC69tfX?E`~!
z1_OgTip~=ZlNr3gETB#%U?N0Gf&2jsds|d4B8hAv-A_Xp001=)B*xBXU4j4r002ov
JPDHLkV1ixrha~_2

diff --git a/docs/html/img102.png b/docs/html/img102.png
index bbb0a1c0638813184dbf7efea93ec2d3bef9b505..c8269e63edae8d233ef80b3eee9596c55103d787 100644
GIT binary patch
literal 487
zcmV@RJ%^YFcdv)Q#THzsaQH81&O^LkeHCl7XW|2!b~M5
zwn$8Du0Sw>%Ea1%oqPcbW1#~p1Ckepiow`@t*AOg|mD&jTF
z!;hv85TF=TXxnrpxL6>`p)qBq8f)n-z4!!?;i9XCVJ{oC1VNQ#JPv~{nTxoB^8@F)
z6*3M_Sw?C~z#UZAJ;vexYdO6oL)TOOq&bfR7xom{X~-n$2;t&
zw4NN|D^TVr6aO+~KFH3SdI|R`*GD*6Eqhm3j~m^YeDcx<_Ch);Ztx`Mq49s`uJ}L>
d-jcdi!Y}RxPPit&Uj6_8002ovPDHLkV1oAg()s`Z

literal 533
zcmV+w0_y#VP)@QY}xzP!v7umUe63_Lg}nA16e{zCv(_{3}wcXA#_(I
z&%r7ppw=G<)NJ^O)TY2TdTD%_msC@;81BET_`4~DBi1&Wutb3;Y
zK>cJ?tr8rvousJzD#0W5lXfbuqn>tcM+pW8$(cl5rdcdA3q1${WK$nM`4U@X
zxxh?#M$CxA_R3_|Xv2!>{^dHrAv)u?9}J#;%W!8ft7GLOatnJ6Txf=O^TBQb8_gwL
z0rN3rkFH@C%M_n8AcJSFh0hSN-KS5waXKD1R_8de$;sfPf4jt6kev&-30>PP1l)V(
zuQafz87dHTGEwHJb%0}FB}Aq@R<1Cu_4Eqeh+*op%=7kJTl+jO6Jo9L6v7`AohkbO
XvC&&dV>9~m00000NkvXXu0mjfjvnZ4

diff --git a/docs/html/img103.png b/docs/html/img103.png
index b6226f3cb58570dcd90e8ddd8732b6904a4be507..61f04c6da1ed8d22886f6315bc88d87c5accc519 100644
GIT binary patch
literal 397
zcmV;80doF{P)~5D>e&yC0vO-~a#s0d!JM
zQvg8b*k%9#0S-w-K~y-6V_?7sHZd?TF$gd)9731iU;>dm^YH3sU|@q#1!%%IU<~F9
z1Ps6c2iO&mcn^TMfdML#VaKB&0J2H}2p=#s@G&rQmvaH-85sBwTAncQkZLC>0K@Qx
zM@SqFH~|9&K)1mJPP4qQ0y>uiF2KXV%Lo);1qn2O)D=8nVq!>OU=*riTDs8(R0DPUK@JOM~3~m4b2E#CD2rR8B00000NkvXXu0mjfOT?4B

literal 359
zcmeAS@N?(olHy`uVBq!ia0vp^DnP8j!py+H_;_2w
zg{O;Sh{nX^1O{eS1-^s>EIJNniW?ptVA3gaIKZVO<&f1SCd06iKOwxGA;;lQ18>S2
zX?=0&!^UkaY;Aj(74Ps^@<=OasTmju8nLKnBvde{Bug~7Z7_Cjv5=6Ekd(N=-1o!a
zLu2iZ1jY*oxgFNbVCDWP!4#?ZYKNqRg`$oaJDc35SO=+$#t4hn#)VTH*&`pB%y`0L
z9g)Z69I%k@upL`lIU7&Sf`CVl=NzzY{K|Ae+(GP$v2kR)rNL*@_HXP6~!
zYrmGTl8|`DX<(qGAbI`^gG<%o9Y>i{47Qm#6f-b*UROVw#=5{9=w}8`S3j3^P6==xZb-KV>#z
z;fp9Z>2#Fi)gcy{`>J9EUCn1X1sVxsM=XFw-1c)I$ztaD0e0sw!mWH|r;

literal 368
zcmV-$0gwKPP)SU;qOFAYQ-#2MR#^fdK_@GhhcC{4f^NGlmTe44gRB
zAp@2K5ZPb=Bvcqa2yFNUv4M{-;Q*TeP>vO3KO+Of1tQGC33wUUfFwH*A7E#JiZy_}
z#?8vg!0?@+0O({UAnPv3*%$ad5)x_|4lpo)Tm@8=z`zA^`pTOiYFzMLDz@pgMz;KL#|1$%_ACM65g;oYV2KEa;pL|#akE{0#I~ZoM0mZl$
zTmT0I(24^LNsU4c3>pkv9~l^gKtf`EP^)-A1j_+bH}wMXH!Ay+6aWBqO)Pn?2Tg+j
O0000luya47hY9Uhram4j4GgT
zV><(90Z@Q*0*0Co3mIw{SQ8in7~V4QgDhjmRKpg)aGYT#8*>4t0s{xwK?fN4=ez_u
zdLB^i12DxUz<+?jzJYh4^aTdy3m`Q&aXGh;VI~8^d?0wP*4dWH_+TiD8#8Gw9eT%UGCayn)MLgASv2gwd7iO>+`1rZO;G
Xnjxg1Sth6fw2i^j)z4*}Q$iB}$i+)j

diff --git a/docs/html/img106.png b/docs/html/img106.png
index bd84d15a13c55f0d1ca4f209b9dbf12f7d15f537..6b570c4f67dfc5ff0f8a36803f454da9e48a7838 100644
GIT binary patch
literal 190
zcmeAS@N?(olHy`uVBq!ia0vp^JV4CP!py+H7EF>fZsKm&~=|7_S}I3Cl4Ip6@AK(q{hZ}?JZSSu0aI+X{iEF?hQAxvX+9_=LFr|NnpH%$eoo<)NXW
z@7}#LHa0$U=8T}A;Hp)tIyySi($atmU0hu5-o2}&q_lhYZh2Y7sX!sdk|4ie28U-i
zK=PM7T^vI+CMG8^F!>1_Jj}q()pJLqhK-fYPFbOFCZlx%dlDlXpC6lBox*Fb!|WS0
zE=$Us+W7K1dk`PD#1CE}nFbw4wz@W69vYZWLWL!%?)O-uOd4!^Uh$HDi-T*T^jsN)2=qZfF;{
kh~4C4)Y~EJEXTl*HA%(dr`P=!pzjzwUHx3vIVCg!07F`EA^-pY

diff --git a/docs/html/img107.png b/docs/html/img107.png
index 6c716f7e4178c36efee52549aad19407b2ea3fb7..55ae005a6ccec481c4e7e3f252eb7159b44c9134 100644
GIT binary patch
literal 387
zcmV-}0et?6P)SU;qI|28IF#h6xPFfR}*-h5r#uZeU-?;5TSM2rw5QOJ87M
habWNz-giR|004}KFBO;P>kj|`002ovPDHLkV1i-Hl>h($

literal 259
zcmeAS@N?(olHy`uVBq!ia0vp^3LrKMGXn#oZ=&N)AjcrUC&cyt|Nk>*&MYr44-E}{
z_wJpsvGJKRX9NWWSFKvr(b18XmIhSl;^K1m?p-A%rQN%C%gZWG1qv~i1o;IsI6S)n
zl5g~MaSY*@nVjIjUc)UBIbp{iK~5$fov1Ls$^`kUt+I9b||$o%*%OCB2=>vB$o
ziMM&yF!9XdnJg(G!Fs?;NAi_zB$vdud+9N!*B@YDSY;#m{CfG!zd*+@c)I$ztaD0e
F0sx<5TcrR1

diff --git a/docs/html/img108.png b/docs/html/img108.png
new file mode 100644
index 0000000000000000000000000000000000000000..452a9c87f5ccd95eca5fee9cff47340be799eed9
GIT binary patch
literal 520
zcmV+j0{8uiP)0000mP)t-s|NsA)
znVDr}WkW+l?(Xg(AtB7n%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001
zbW%=J06^y0W&i*IhDk(0R5*>*l0QoWF&M_5_S(Bk={0pK1;K8v_Yvyipa|{i6wt*%
zj1CsTp@@THT*MAi2S0$5gVSwYGZh>P{Q^Qj+#Gz9w6%p!9SXif^5e<9e;)1yCecIz
z2(dH-e&$}HDOBDuR`dw9JZ(uN?#%uKO65CB+W{Ihz^R>LwTNu>h!GWS-7*mu$C7bj
zn*`+|$CssA+73{IRFJ}ic!Bi!1`K9MZqNl=b%+&0Q$HWlQ3h(CaiRm~h|j(Z{8e_u
z)2wB98UwL(E{QN~Ru#0($X=fr#zduE4pC|{!qho;-h>Wq6#-K~9%53NO6UZK77g?o
zyss%D;jWw^N~X(t>#r@~GFe#Q2Y2o*RA6GJ)x^9lH;YUDD>p{cvaBt@5blHE*)NVCxC)r`uOEv#O`szmH$~hF5vio1uUJ0000<
KMNUMnLSTYI*ymjU

literal 0
HcmV?d00001

diff --git a/docs/html/img109.png b/docs/html/img109.png
index 660cca8c7ec796eebb489d2e672e35a6881cb687..0d45d2e5571a321c21e3009f9df80b97837cf0fc 100644
GIT binary patch
literal 350
zcmV-k0iphhP)GYCvO;GfH3rcWXgc+zHB*
z&Jd`BkyfZ-%7r3-wB#T_i{}c9?2E@|++P}i!{}$WO5LPMtdOq9F>Y#P#G<}{iely@
zDx>w|yPQVS_zRfwp<;=h3YC?gd*`cdgv$v+=@`~7Wj7dL2Cf~$)mxcSf{S9Bn8L!P
w_#EBwA*JsihTf~aZ^mt*<(AI$#|yr}4Tx+iw$jiQi~s-t07*qoM6N<$f;iQj?f?J)

literal 194
zcmeAS@N?(olHy`uVBq!ia0vp^JRmj;GXn#o1jC}|K#p#JPl)UP|Nm#soLOF89vT|@
z?%lgHXU+%;3a(nUs-vSLEiDbG%EiUy?%lgeN=mzT?_M^AZw^q1u_VYZn8D%M4UoLE
zr;B3<$IRq}ga;`J2>}dAY<=uJ1qaxdK2|gMU@4Q}z$nGTb4P}UCnkrHr>9@uAc1{N
o_zmHPD=XR0Fe!9BlvHMBm|@1HdBjz1InX!;Pgg&ebxsLQ09B|yy#N3J

diff --git a/docs/html/img11.png b/docs/html/img11.png
index 31bd2fc6ebcfb2228566927602896b510cc08d62..5af308a8d1d779b827b769262d525b0672dfa850 100644
GIT binary patch
delta 564
zcmV-40?Yl51i%E47k?iF0{{R4w{;XI0000mP)t-s|NsA)nVDr}WkW+l?(Xg(AtB7n
z%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001bW%=J06^y0W&i*IzDYzu
zR5*?8RKH6?K^*_6;d_TZpR~0Z4G|3n(hx0gX^@DT`Y}Y(*nf1ixH`Dh;tfF<2yU&?
z(2x+?9yqu)P*1e6c9A?63fPLfQEb=oW<6P9>PQ>iVCo*#p8oZkHK
zsn$vvC_w)USQb$VonQ@nDcyormkMauR#CE@u
zZcmCaik+HIHP(y86LITlFJB8+jjXP!7wyV`TF2<^}UY?41p9-@K
za=IKY4=rluSfz?IhQuFK1hXSv-`AL~&fiV-xA+F}1B&SwjU3Vd00007f@n}3Vw=Fr(G6bG?O5%EDB
zVwZw03c8AaKA>K+JwU;iPLFh*z(g?FZ@59^F70%|mG5zT+9FN_+p
zOtS)*mVa&rmE}*Go+K@yq(e!22Tv)gZ1~MIvq+X5xV7x6Nej-H7E-Sp!}`g>#uybY
zQfs;-v0>vlrh0Cp1?-1jAYV=JUR1UcRP_=$
zE$WrLt2)C~WldzSVyakb=?(IM2i|F*Vslj!Pf*R6iZ5Uh;t3mf!*Q;AIeQSg{5}s>fpRD61%DdD)uI2dG5!?a0<==xxAHdnEn`;*ZCw&1SAUJyoQW5_q{UCRjQ27;sHKh!!5FdHI5Py
zz~4{{*g23xND7Cn4tX)vOC_fqTY?HY3))g4`K{1rgz&U;XvqNTei3W6z=?21Un_Mi
zpU9dZxMElu;f#g46XNc4Lw#cW8D3(XrQq`L@h>LEHjHgg!NxtX7*>VmBa#p8x;=

literal 737
zcmV<70v`Q|P)TxS)sImALl7Zi!9wy^O)Tu~v77%apt1E#Q0%s+4;ML@;)W_HZod1!HkAmn4`
z&6{uD%zN|Z?Ernmuu4V1!JlAEV2_wo28;qAkdV0^`SwfNdrUBDwOW6i_MOC4^3u&E
z?B~#)N_VoH4yg%yT(^IRORaF#ft7=d$*km$fa|=>H9Qx4=m7KVEO1kY#oKY>Rk+eu
zz`IJ#w50|c
zEYL%Yi~Cwu9;shv%5aNicb-av*ZGk7`y4CMjSOzw|4!?l)75J{V+Ql8rHoKUYc#G;Ta81!+J@YfRLlsAwDMA*u
z@doRl(kpsU9WB2H+up$pPAa4A+lEGuedEq?PESXV3a_I%KM7x8SFoGtv52N%U{uzD(t24;wLQ
z?gmC_W@hQbtt~8UdiR9#*wU(YiqPx#=R?L5Yk5|(ez84b;ije_TX
z9$3Os$|mh1krH+|OT0tDUO+fkPcVU*kFmwVTD_TDtXF=;3yvZO#u+I}VV3ob&66hC
zZ8{N}=O)L-7T0s&NoraI!xvMZIh~G;jt!lSGaVbJv)?qUlM(y)Xu4ccgEHgHbcb1K
zJy%-Ue%K3#oLh0xzOylLYX{SWzloxbPvv~$3I`pe8*%-sC9b!VmihTm<>{P`je7#MEc(eUPo
R+zbj}22WQ%mvv4FO#m8@hr9p)

diff --git a/docs/html/img112.png b/docs/html/img112.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a753508dfddc82d642d405520d858ad161c7cff
GIT binary patch
literal 358
zcmV-s0h#`ZP)SU;qM6H~|3)jNB-Eh6@a=PZ%aJa5G>B%s?!_0Mx|D
z4^~{j3le3Yi9$!E+Fyhyu)RR6QFy^^2qg=(ltqDo
zffeXtj_(2vK!GJd|9t>jYA^xLVPm+k7p#n%*MWhHx4<5(lg$g}?wLe;kshEJh`T;O
z*z5{S32=$?U{Y8BL}oKEYyncWa~!@hup2-XOa3~XbDDWR>
z_{@Q12Xg}00AOUhFtDJ+kpBl%m)-yW|Nl2?c#(Dh0OK7md3N$d=>Px#07*qoM6N<$
Ef=wZe2><{9

literal 0
HcmV?d00001

diff --git a/docs/html/img113.png b/docs/html/img113.png
new file mode 100644
index 0000000000000000000000000000000000000000..709c989869cc2b00b70894b8276c3419b72cb984
GIT binary patch
literal 279
zcmeAS@N?(olHy`uVBq!ia0vp^@<7bT!py+H7{vQ(5s+gL;1lBd|NsA)GiRozraC)2
zzkByiQBm>CnKP?at?KCLC@U)q2?+rzG%_-}d-tw@fWYqEyZgHHKLdprOM?7@862M7
zNCR@Fdb&7eZBy|b@;+C9OlaRnsG5f&j
zfCCNu1vTOUa}LzYoeud<9nv(ENpEh9cQ`zuuIL7_*Y<%61Rg>=s{{iLE?@B2Ob?@Dq&`3
ZX1H)nsda~XSp?9544$rjF6*2UngBF;XXXF^

literal 0
HcmV?d00001

diff --git a/docs/html/img114.png b/docs/html/img114.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7a30bbdf0311a231a9fbfda4cb09f2c41fd08b7
GIT binary patch
literal 303
zcmV+~0nq-5P)~5D>e&yC0vO-~a#s0d!JM
zQvg8b*k%9#0I*3!K~yM_V_*ORjsgZ0Ai&3f4p=TQU%f!II{%k?r0vLy3fdWweo!kQu
zhn3+#09+X-Pr?KUr*{F&fCJQY7nJ}Hn0&5;A@Kr2HGznnZi6QbIZf;e=n@Qf7&<@%
z5WIU=`0m{Sm;}23--ZHq0ZgNS_8CJhg-Z-t003sKDuEe9k0$^C002ovPDHLkV1g8C
BY6AcO

literal 0
HcmV?d00001

diff --git a/docs/html/img115.png b/docs/html/img115.png
new file mode 100644
index 0000000000000000000000000000000000000000..3ee61bda66d209d8071a342cae4b733c713915a7
GIT binary patch
literal 199
zcmeAS@N?(olHy`uVBq!ia0vp^JV4CH!py+HIB&`YPawx2z$e7@|Ns9pXU4G0e$3jGJffG7xp{(g5!YACHj7l(cyW
z(V9z|aB6pgoKjwJu1uE-TcWN7&#KY*SmxJA(=YRp2s$NJyc02Q*{aw%Df>R2>SPMF
zZI&8xahK;a*UW%N@i61~io^Icz_0A}#(+tEm|?5M{(G$X
zh}=Tg@ePv&9s^HA%S4Wn;dx2UElKj;+)UXX4$dJa|=Jt
zT8yiICgOs8Yd<}Ed7HB7*&uw2Wix-91
ez}#}om65^j1moX;7{hR&Y6eeNKbLh*2~7abRwP&e

diff --git a/docs/html/img117.png b/docs/html/img117.png
index 74f211e1e3c6cc60031f040e98a014fb4b6367f3..f17fc72aba4f194b93d54ff61ecbc9242a516bd8 100644
GIT binary patch
literal 411
zcmV;M0c8G(P)=W
zoDUcn<}rXNAdgFc*Zj)_?IYNI!-0o43UC1&B?XQI3;?elmM?%~FOL8K002ovPDHLk
FV1kP@nH~TD

literal 257
zcmeAS@N?(olHy`uVBq!ia0vp^l0eMI!py+H7%x2QDUf3j;1lBd|NsA)GiR2UmxqRi
zzI*r1*x2~YnKOcdf~!`o>gec5OG^VPba8RHd-txAlG5(oyX9pSrvil-OM?7@862M7
z0Lj;Tx;Tb#%uG%If?EtK67Mt(8W?}GinD1vNcq9AXq}_xiHyu<45rT*
zng6rJPUm)DX4zvI*}(MY&K)Q54X+p)*RxNkv{7jNGhdQPa*|Z3C@R7(8A5T-G@yGywoy
Ccv`6pHR5*=eU;u*&6Py{)K*9uebRh!}!3a{$z=0&Z8wwC2K%M+x
z#s|)s3=Euq8$coq{7fex(!A&f<1z;wOn|caII9!0=fMMp$`Cx%Ntd-0_kqdAYyqtVM2A2a=fRmx&0~4|#{0tXZ7*GXh2+(}L
z0aJhoz@C82b0nmEGKL7FBo+l6`r;EAntn)u*dJzMQSf0QLoq*>0K^FgfNtP21_FD8
z0=58#w--_&S~xq94fuI(BE#$i1}*_!bD$|W00%CKAq>!yJ9=~j0FRe#j3nV`00000
M07*qoM6N<$f{k&6MF0Q*

literal 390
zcmV;10eSw3P)SU?2ia_`tvmq__zxYaaR57oN`Qrd0c24wn8VLd-~gAI0CEun
zM}qi--y9AF`~@IKZs1^GT)?n__W~#&az6kC6b`Uo;DPJ8z`%fTC>H~R0`(k90hofs
z_HqDviRl7{8r}n7Y8jZ6U%)s~(17C?gCfTRo(~NCpBWhbfW-N^7F^L{VE8bZ;{k&L
zFbF=Zf+dMnYz$j~)E4#&{0YE-;#zP48mSfuoC-inaAm(51Lp(=u8#~1LYOYp2N5g>
kFeO+(3F#X-o~8=`0F-GlG@kMKk^lez07*qoM6N<$f~2gJ7ytkO

diff --git a/docs/html/img119.png b/docs/html/img119.png
index fdfd3db7a7accefb6aa96c9dfe408ed99ccfa6f5..89de8dc3246d22b8b3d9421a55cbe8a7f745865e 100644
GIT binary patch
literal 857
zcmV-f1E&0mP)0000mP)t-s|NsA)
znVDr}WkW+l?(Xg(AtB7n%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001
zbW%=J06^y0W&i*J*GWV{R7i>KR?TV@K@k2nv(r1h*-5V`k${kW0KvIM5Xt5gFa-AE
zC8q%~;K|9wD0qk>sJ9M+8YH-a58%o3Jb?@d3pp(83kZWh!5pNm{+Z2evL-nQVo1Ss
zSAYFgZB128_X3CHg&tD3@Q{hs>@aCx95ZbL5n4uPmk~Ciql}zr#~k8UIJntVkU753
z&^lY#gE)cpiKRBwg3@Y(oB|4uR_W=@BQh@eC7
z=sll1FyZhGEO*U&h&eeQcL!!qnmj~lM^ddN**DWpl#_1YN}~Dob_0x+pyjSi+@Jiu5p%(M}X;Qg>7kd8rjmWeS
z^^c)5dfm*m2&&X9f+CHPdo;AsuF~<6S5eATNvOB{uHIXresh>uIhc_%IXzOLb0{vY
z?~P?G06T^Lq_873lq0n88Zc`pj{UOO**hu*x+|;Q5yaWu80Bq&+fXf=MX1b_yq}Z7
zl}BBI)`HHccf2whn@MozVvFpI$`flfm20&60k7A@NR#;&!yiCT4bkH2y>KkDRPHyS=_Q~616nmkNqKI6f^4tEfyb${kc__@B>r5
znlvf`lla?o6>D@U!~=^vb_)Kil$qBX^(IYoYxC13=X;+vf$Mk^o77IMUs^X;AjRor
z{3DI)i9tWlqG54jYZf3{7Pbdw}-J!L8jMqY}ldw4Iu&vc#
jOcebb{N?+

literal 263
zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)i!py+HD3-|}4dmzs_=LFr|NnpH%$eoo<)NXW
z@7}#TbLNbopx~-it2#P5($dm^s$5)L?%uttq@=Wa_wHp=_~rnG7)yfuf*Bm1-2lmV
zc)B=-NK8#m0D_bQOd<(9-%8lpSlJ~k%oUzY5ph%zXI7taoL5jJfjxNjfds})fjwRV
zha)NuT(NFrGdO!>0>dH;g=GdZm)b7y?+Cclc+`gFLy193qh$#{GxKZK87;r9*x1q-
zHQL`FRAaMSX&w;A-E4Y@L5+<~*W&q8B{ny0+cjcqo!A(*$SDb2eRfm;=q3hFS3j3^
HP6KR=;o4KotHGr*_V&b16&2RwNdtT4I0&)%g$7|G*5)
z&4fT=FmwPW4iy0&ic+Z(urYPcUw}@kKw^Q29m%4iQYLf1{3~%%BoG7Sll<=d-uv#|
zdp%9$ZjS|WuxB1cVFmW3Vxqr#AYxxprU-){^Jhvl5LQNHjSS!bTr
zO%85^e6QYb*5DropVQP8YfTT16a-^dSk%*J>x$O)iB|5-uh6PlReJjf)Z9`RiQ|NZ
zC(%hWq1j>rXWn(s-;!rbQ&>(hk9gw2a~XI+>4?nuTd^zpJ=K&nO%!FQ9eNR>Zs-P%
zIc5}%J7_m-9A#04d6coHgdE>wX9^G+h3%ok)g7rO`7z99bRateGgVc?5150W@m5$t
zygots?sh(FByhq{wUimBlBEw+DgASzKbN94`UNM6sUG%cDdw|(^F>*?!P;B*N90oP
zvhAaB5vW)fIaQ)mDLRVB

literal 244
zcmeAS@N?(olHy`uVBq!ia0vp^vOp}y!py+H7^-K%0_3O%_=LFr|NnpH%$eoo<)NXW
z@7}!=6ck*wYE@cV8c^QF#pUkZyGlw*yLa#2SC>8sD8yJ2FVdQ&MBb@0D2=%7XSbN

diff --git a/docs/html/img121.png b/docs/html/img121.png
index 4c5591100d17b9afb1b86907d6640487850c0b0e..61df3677072db8097bfa090839e9e06db779847c 100644
GIT binary patch
literal 423
zcmV;Y0a*TtP)!L4YtAkD?DKJWdetfZ>1tUj|-223A%^hW!5@AfgFy
zwHF9mO+46*1#BR!4FL{-9mI|hXogUz0mRI}z;6H&;RkyHv!;LvYe02C_Z2*6PJVI~788k+w9zreuHIpM=Xu+Upj$mjnD0)$HT0|^K-
zYuMO;X0ZiuD6l19n913JWc!Q;E>M)37ut&<`{CR~Bpxq5AB}i`ErDUp#Q+MdpoIs+
R9ZCQI002ovPDHLkV1mBSqeuV%

literal 276
zcmeAS@N?(olHy`uVBq!ia0vp^@*p+`GXn#oU}h;VkYg6$6XN>+|Nq5{7tfqIv%I`K
zG&JG5=N43U^RH{dqkQ3a0IE_X_*=KTM^Svzi$?VHr)#~cK5xD6(x9%1Td
zm+I$;+u*!FIn;4=zU_pF2T?uqBK28}BsWg3V#rwZhnEShP`q5dZMO*oNZcj4b9{Zx0Kgafm@4WNo
Y{fC%acO7u30J@98)78&qol`;+0I?%-J^%m!

diff --git a/docs/html/img122.png b/docs/html/img122.png
index 8e8e8c7b617ef9d65016d9de0d80b87d8db2f0da..401353f2dbf4ca549c251ae333a911143e4d8228 100644
GIT binary patch
literal 151
zcmeAS@N?(olHy`uVBq!ia0vp^JRmj;GXn#o1jC}|K#p{PPl)UP|Notxo!`BC*U`~Y
zR#rB1=1e0aBLM+{-Me?cJwGD?sEn~B$S;_|;n|HeAV=)kjc;Yff1ORy%KnP7(N&>q$5=EGYha4fMh_N$qZB3
z7`z<#8BSbbd%$3L0by1i1G6kx1_+)ptQX+C_O5}!{sS|RKvHGF!2B01GYVh;05K>y
ULaoNwV*mgE07*qoM6N<$f^M#jssI20

diff --git a/docs/html/img123.png b/docs/html/img123.png
index 56826b8bf01bdaa32853861434dfdbb451e4b900..01f60011ca74ec47c17bf08763c162d6e33b66fe 100644
GIT binary patch
literal 272
zcmeAS@N?(olHy`uVBq!ia0vp^l0eMQ!py+HIK|)70mv~3@CkAK|NsBYnKM&UQ=Ofi
z-@SXMsHk}6%$ZfIR&{iAl$Di*goFSU8W|bgy?a+cKw$Uo-F@BppMgS*B|(0{3=Yq3
zqyag7o-U3d95a&>fPjlZh{uwZC*eR%<4i`b8IpDlD{A=IL=NyDVNBv4J?aQ4p+DN
z6tc4APq@%NljnaVtA&U}T2n<1BM)!9h+`1o6XN>+|NogYXO@?jhlYl}
zd-u-R*!awuGlGJGt5&V*=;%mGO9Lu&adEkO_pXwX((c{6)?;<3R}H
zMD8CKM2w>5Keyc{cjigefhi24w(Q9pI-S=h1wXjUk@jcR&I1x_&mUl5_z=MR*{!O%
Q0%#9|r>mdKI;Vst061<=9{>OV

diff --git a/docs/html/img124.png b/docs/html/img124.png
index e205726f752de2f3b9c3206e5602974187753a72..c0d01a751711f11606e26c2164ad44fcc36ff6f9 100644
GIT binary patch
literal 390
zcmV;10eSw3P)~5D>e&yC0vO-~a#s0d!JM
zQvg8b*k%9#0S8G$K~yM_#gRWs13?tVe;9V1U9(G$u$7g_9wA2BP@a_p29a{SfdFTMDQ!#-;eLTHv@BY`3k)dJ3~gKzEf7A5VnIx
z!pF#GKO+uSQRk5Bd-If*O2R(gkJF1NTLC%dQ|%uSFMi}59PqGAQi0T&dYfJ|db#1&
z#?_cTB!DyDXeN15kt>@y#l#2j8b;K5Aa1~jeU9Kbg3};-!iBhv!^=0#7MvT{SsLE8
kf!nND%ZV|+yZi6(4x7g{X4lUHHUIzs07*qoM6N<$f*HZ9f&c&j

literal 259
zcmeAS@N?(olHy`uVBq!ia0vp^(m>3|!py+H82!xa29RSA;1lBd|NsA)GiR2UmxqRi
zzI*r1*x2~YnKOcdf~!`o>gec5OG^VPba8RHd-txAlG5(oyX9pSrvil-OM?7@862M7
z0LeFcx;Tb#%uG&jVB_X;P?4W={`7$ZXEro8Hg*jQrHM=o!5;L<}LRvy#
zK*Ndm3?Cb3U3DnYW0tn=FiY@waA;9)qvO^UjgA%P+pR<855$x)Ds1FiB+l`ykz-!E
z!O>O)rHx#t9@j9aOp?gsZm8^e)h_X4`utRZyDTQ047NdHNi(DOcmf^6;OXk;vd$@?
F2>^0?UMK(n

diff --git a/docs/html/img125.png b/docs/html/img125.png
index 0df61bc18ca942c85295b2217fa35a9a6dce5cb4..ee72c1c30a9efee573c80897adb80221fb706be9 100644
GIT binary patch
literal 260
zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)o!py+H=(c3y3LwWIz$e7@|Ns9pXU6dAc};NK8#m0D@$PhPejE*d>}%RhbX7F|wUwb}(dCnaWecvnJse-(eqvvnLyv
z3yhjH@
zc%4F6gXV08FRb@jHI7d{$dSkp{l7kyW&QNVg;J+j7;Z<4^|~A1)&aVP!PC{xWt~$(
F69Br+TY3Nh

literal 808
zcmV+@1K0eCP)+0000mP)t-s|NsA)
znVENYcU4tY?(Xh0Gc(N0%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0BD=f09~~i;00001
zbW%=J06^y0W&i*Jrb$FWR7i>KRnKeGKotHmn`E=eCbR6RJ!r?pL#tq0Z=N>AA5@CE
z1rLe`b5IZub_;s)V9;WVtrGhWn4>p?l%fQoO3|Ve*Mf&qgr#`!*0hMWJ+w{|Thi?h
zD^(EbcbI(h-kWdUOlIByNf6kXN!llgr
z_r^oV%=r^Nnm>PRP6o04r#T@&U7-1|yXyNMYyRI_-am(2eoZ%JZ4hH&DJIz(2U#Ja
znKTRWXK#*?KCwRH^pVw|%>oU`D~lf)$hSKJRRt(5ZO)miu~wDoQvCOI*DDeYC>mIX
z1TgI=U63fmk!p(-L=m{}If@EW;AgthNO@`sr7CYL@Q4mAycf1TE=2dkhJB@u^hDa3
zL1i|>{AaVIhevn#T`Xe>O*!8S8uvd5G!N297{=Tvy5=HlBo2#`brA>pyp=57>7rP2Bq7%mhiOb9tICuhW-_0eA%H;>97FI~k
zR7bq-45w`)s+g@9XrDq}IOR>5VHIfafaDOC!K<|WQ<}eAw_z~3glSw$&e@7X7`W+v
zL4PR4*)-@2!Y3UJy$0j%m$<}Nbp)S6OMwgU3$3qK@sN$~F@n=~tr?t4D9au_YcSod
z>YpPe-5tYaQ!{~~u-s&Ap@gzt;SZW8MrjV&GdL{tsyy)+B=J_$CGv
m=6wl=evs`@dKbIc3O@i+C!Uu>O7X-10000*&P+{Bb#``s
z_wJpdqT-n|XI8CR)zQ&WR#p}g5&~3cWMp*r?%mzHcTcL9)dTVwOM?7@862M7NCR?u
zJzX3_B&H@OBqTgYc3_egIK$1u!*oYn!hk`UnOU9rF!KVPX69u&TnsPyDj2S*9N55^
z5@;>3Tt{I6FZT|PZQ>b^7}?m=C(L%_OKrR4Em6^E(#

v-{}55O!CdEQPMrYs?1I zbD5d9GrPD&FnD}m{K>z-E8f@PS@Tj!i8B&ijv~rFf~T!#SSV896kK!gFBU;+a#ABbketq%-1QFsaryda8~VFOI$ z0s;MKfE|bzFd^x6XHjSXv4LU-Hh^U78xAmh01Gg)JMchNI>7WVAk8|`KmwEo`#Bfn zKy6fOnHadC0>CikNDw&A4iXSxm<18s!0>?^qJoKVfp-HhI5{EApUg0oje(&6#I#80`DpQlfk}XY zNn7ax#C(Ql4C@6L7$+dRW-W%tZlUnl6wstO6EJiPIRF5Fuq@>wuw2#v0000CnKP?at?KCLC@U)q2?+rzG%_-}d-tw@fWYqEyZgHHKLdprOM?7@862M7 zNCR?uJY5_^IA$g%Ff{E{NIJ;EW{~hC{r`am26-NbCnd*NR1AArjV07Q7$h0j{K=Ea z;rYRE+&#|Gtt?EzyJ6x_b$NAWX6eK1c42A@^z_*JIL{nqs@VFNW$R>1o+6owPx~bc zIDa&{-ZR>eoA^LGVef=f2RODxHa6-u9Gvjb_^=P#2Gu*QoTyVKoI`&!zIS7i@k8?8(3P}h&Dcguv%SnkT=jq zK@_yGvv3Qmt5RyWrA5F6JDuJKM7i$1?9A@Ye8cR_1n?NJw&+IB@5>=< zxmNwbZbu9nLupZ&@E^H;MM{B*@V5w%NQR$Dthazy23Layu5tInIc%MuSx5XIeXm%)BR%V1;0fq!NJF;6#(BBn)MN}57;3Q0blvBZ zV^0vf6p(3)m5HF~je9&q#M7zfr^I-}C`JRnzm9R2O66 Z@dbcGIFt8jJ&ynY002ovPDHLkV1j5w#Kiyr diff --git a/docs/html/img128.png b/docs/html/img128.png index 8ae7e6e58190234b3da209af2c9c766da4ef7f6f..7dcbbf599d85eb878bea2c112b35b2439735754c 100644 GIT binary patch literal 420 zcmV;V0bBlwP)z* O0000SU;u*&KpemT2LeEBz<>mJ`515jPA0e-1_lLOs!#zt z5HH{at9EBmXkh3Di`F+BVEDko@BymGfq{iM({O+Uu>M>izQD>45dt}N0s}{az;Sk< z@dXSF8yG%t1D&w}sIHKchhYc90hmu1E4UO$|IB814gw|A2(}xfZZ7EMj2bW?;B+089bFDmDh*4ZNVh=IM0+hdBd-MMBR< zi!TgJ0u0Rm85m}wSh5yuk^+ht8;GkyH6M}=0La`V>GPR%*Z=?k07*qoM6N<$g0rE4 AxBvhE diff --git a/docs/html/img129.png b/docs/html/img129.png index 03e5d0350d226cb15e264056ef036bcc9af17008..5971190f09b2db6396bea509fef1483fba22397c 100644 GIT binary patch literal 221 zcmeAS@N?(olHy`uVBq!ia0vp^LO{&V!py+Hn6rMMd%8G=aLi0jNJw~)*ubF5Ch_1&N`gSbgF6i393Bi4r#hVZKdqFBSxexYDf1+s zHv&@?n%**Y`0U^iic|R8$SD3HFCn0L!;Njz53=mmcaW5v!>`bz!q#T$z{SA1kgxRP Tf!m@$YZyFT{an^LB{Ts5dJIj` literal 310 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 Y*AzJ~84tE1e|A8+_YLorY1xJRA45?rYXATM literal 3167 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 diff --git a/docs/html/img130.png b/docs/html/img130.png index 84c60af3d463eec8d2269eeaa0d79d4921123fa1..c39e7eb240ec2b712d3e96298c2bf3249a02f729 100644 GIT binary patch literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^Qb5el!py+HSYPqU8OSjR@CkAK|NsBYnKM&UQ=Ofi z-@SXMsHk}6%$ZfIR&{iAl$Di*goFSU8W|bgy?a+cKw$Uo-F@BppMgS*B|(0{3=Yq3 zqyagto-U3d95a&>7@C-Q0t_5G8yk6#J$&*c9Tqxx6 zasHF~(^id)!W`xt&u2AWHQw0#Bh#T)p^B0DHnYIqM#YCpC;B3mv0jqj@WP$7*5S?F z0}I$5?qx{Y_BK_3kNw7tciaMU^BE?bcu>Rea4S=x5c6Rv1y%;uDWdN<+5gTe~DWM4fS-xV- literal 839 zcmV-N1GxN&P)KRY7ReP#FG_rs->vCQ(5q2#piQ@UnUFCPa|UA?OZc zHzhmh4)w5s$S%UOR@76=4#Nq;5D^B-!WhB~LI;AoS$a@d!Id$@n{RW2;gI=~tZPfV z(aS(&-y!dN|NGyUKmYsx7oZjzu?*EX7we(O`|}uDKnIL9JQhz5Jq1SgcXL=ccGo=3 z&?K4d7P1=Id1F9g5EXW<(8`-zMtdcOJxg5V4{?(aK1`TQ5R7%$bd4!@vVcM68Q)V3 zJmrLIB!DZND!|P;-Inrmm~f5yxm6*whVyTz5GN|4V3h;Dq(+$KBErfB^N+h5uX0}s zrVB-h?w*VSL4H6d!@ZMM)*M&8tl4Sjk@02~)@64pY1O+Be?pR~cL<;NkE2tqnCo59wTkx zE~>}0@SqbpI$Gq7G+M;FGOuvOQ3PH5O<+vr9VZ{C;|5Vu5g6^f^+x)s$7`E<$kQmV z>gy#Qv(Dpq?OsICwgP6vm)B(|)SD;rjWoQ2`wJgA8-!(aOC3Xbqs-&%8A)&n znQiy=SJbcapO1wV+(L=Qr|MoSmdU60Iwiik&n#>g+5>kE{j7yp*9KBa2YNx|>L?Ys z1Ydkv6&VNAKKzt^+%Dm(U8A1DroDnC9p8K_XBw3UFvs143;zV>G8#p$*G{n02)g~= zpAu4+qAy&sm-~T+gzn;e^Sn00_kHYSx*G0cn$@fnXImEkwbFVZM>xU(_zTU#wQo4? R-u(ao002ovPDHLkV1nmUhj#z~ diff --git a/docs/html/img131.png b/docs/html/img131.png index 8aa2fd479620438432151766fa114d58be561f87..8d05ac1ef143b2bee86f9d9525fee445c2caa5a9 100644 GIT binary patch literal 943 zcmV;g15o^lP)N@K1X2Pi0hjRH z4ZljczXQw7gt1sL&ZYG0xA|f8bANX z9vv+)T3Rd+Eef~n4*?A5NbrH|Wt}(U3(-Nah)8tcEC$dH5pfoD03Eak5pndP3oi5y z5owT@vv=d;d*A;VpPk0f!S`hSAR?!OJl)bc?rx2)Fo?+Rb@>E3us08n_@UqoxAX*j z8xXJoaBih#eJEImcLu;Zu#VoDpzI{@mgp_s0eDODEyX82Zy5{IK2o)4%0=D4=K)fgaFWYYimu9)(5#k3tcP0zv{5u_Pej>UkW9 zkil0|47um_UX_`g^(=7oAZ_|0X3jZ}^ebn8`{Qda8yYXk~6+SVIpNDfi zUj9cGcVZ^JKZIwI;buX&iT%whQpH`Dh3!z=mkYC&g9M=a=MyB$$2#_QA-e+O--#w$ z-T(v*q^=MYfCi zG8eciS*SSB7Bye~C(=4X4Rn$+d1oxdtCgV5m1*dtD>cyFT&}AuNdekGnl7^`8U;;(G&rOBX;5DgDUdX z8S@yadN^`~A9}pU0@`v08eqI+!`b{QyA6Sa0n!MPBY>HeR7hg)v%#gWLdx(LaP0@u zI58;SoE-Ow)CGLjo#P0MfGbJG20GY3|2!fRxk0Otw7Ug!(iw;LTBGM4cFOGqeU8ju h!c6U1{%Eo9a0ivDAa8ELk(B@d002ovPDHLkV1j-ji^>21 diff --git a/docs/html/img132.png b/docs/html/img132.png index 8c725ced5f339779b92535fa7c293ced7f241be0..eb2ae848e47a07f6055577d98369dc19addfc2ac 100644 GIT binary patch literal 423 zcmV;Y0a*TtP)I$w9{hkk0Yb|&FgT(}@S?;JCs5gBRGnTRf>DyeLn_^tA(;Ux zF9pOL`r;FTT0pVzVJ1TYD==JUG9c;yu#lk`80;Vm*bgKy2s2z@s6>`$3t)JAfq?@g z&)LDTT85V;M0085#HDt4+ RLtg*@002ovPDHLkV1hhhoge@J literal 500 zcmV@QoTw8K@k3Om)z-XjyUTYXBMUDc~&Ew#}S-KVy&j z+|$z?o{#c0^EG`nRUKe>FjQGo`@7+^ckh6$=8uBxkkNW2dgOh+jGQ`0)qpPn+CFIq zY~ke22T)1bSkX35#q?sdyb<^P3ib|9os&I;1L6Rm@P_otGs3W8y}um-N3efUQiUR) qW=gh!ll*vIv^xq5A@ySWy5SEfJ4ppc=T$=h0000R5*>*QoTyVKoI`oYBsAEms2EYqmOVeAf!`#3AfVrs;h)c zX}OJ}g$Q!sYvd8q+TA0pTw@n!HX9AH2o@Ii!R*d_JHMF#0VPR}7_J7o4EHXHJ#M4^ zanyYs+hFdv(#hr@!UqlH7^z^50Bx!}g%vEenOTt(FG^s6DKs;S;On3w`ThqDs)1F5 zN=qFq`Na!#Jrndqq)wZx+k-ZoV~1v1Qq*PJIxNZeOu?X_DH0AT_$ZOWh_E@+<;uAJ z8bca?B@US7_Q&IFpx^uRB9bCG#QD+nX*vPM7HZ1ed;d7*obC~3i+%|U&BD~dyk)>M z)JAQvk4BPylOkh^^K~GGmU^4L?tPTJ--imqfAo#sgP3o;`Sba=sh{9Cx4!rU_V_#9 TRYuDq00000NkvXXu0mjfDxkpW literal 402 zcmV;D0d4+?P)~?fQqlGPdAw#UQ}U;u_pO09c-dAf~YJ z5h{_*1iBtXzX44U2m}cs(-VLs-21kaVwO3=N#5z{>3iqhQ&2PplX-M;F3bM5D8Nsv z4_06Vk)CV~Ki?{yunblmY!OVY(FcuiMOJ$+*&TCvDL3pSNq%VOAumAu6 diff --git a/docs/html/img134.png b/docs/html/img134.png index 8fbf5a93f28c83e320f6f831c0f8d0dd99f4e1a4..afdff9bdb362158d18aeedf78c01c2bd14af3fb8 100644 GIT binary patch literal 359 zcmV-t0hs=YP)SU;qOL23`hakd}a8^8xV$25bOHkHdruV44N1LIhw3 z8OFoOz`&o-FqNO-GstA|MVxF5OBf0uDjFC#37CN!6aaNIFdP86jGZ4M#KXYA47AOF znT?Y_fdeRTfg5PS1E4IIJ10;|9Bi8d0~136Gt`t13>V0D0ZD*80Yb|&FqHA41TiOA z#tTF+N-}szrQ0$jGcX8FVBiFW(ubK039KI&7-ll?b53C32kB%#kiZ}ebay2KLk$}P z2S|vsgJZeS4+l^P%xGX>M)niLviT^E;RGt+pouq8005>wB+FCSx|jd}002ovPDHLk FV1k_af4l$y literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^Vn8g%!py+Hxc1!P&p?iDfKQ0)|NsAI&YW3ZULG16 z`tIF3V`JkpXU+%;3U+jKq@|?+Rk^sh+`W5ONl9t=emnH^3fvX>y&hzTrW0<&3@!XV9g@%VlZyH=*Jm6;CcKp3mV~*WD z_8!KXojh^;4Rg}k!pzv5*>Wc=%I5jZazoG7t06NU_?hSp%!yPVxMML>5k Nc)I$ztaD0e0sutOU(x^o diff --git a/docs/html/img135.png b/docs/html/img135.png index ae2386e3facd4cfc362d95639b6267d781020766..59f6cf6c4ef275cc267545e0b9e79b4c1562dab0 100644 GIT binary patch literal 330 zcmV-Q0k!^#P)D+)22Y?jFc%PV1aDx#3q%A#u!vxz z)plxUGb(-Z9=$bQjHlY~9fly51=Gtpfzyg*EHa6Z)2W#4}&tUi*8aN$Nysfd{ cnf*)D9Z9esid<9@8~^|S07*qoM6N<$f=>v86aWAK literal 533 zcmV+w0_y#VP)Dd0CbyfCkP0!69@(kn2Da3Q!I^jz|~KRZVCUK@|RGvwyRjxN9jbR+QY-o)&WIsq3W_R2mOn z+ej4;R#|^4T3T2{sP(kk9@;}O1*M1xIrLKEPYG|1_@5C9Uc@E z1VmDHMX|OstFUa(CJ@+3R>(PWj{VrD6xivUc&&^lVM>!=WHOTa>E3+0xaeQ-<~|n-FqTA2Am~cd zz01bzRBab_@VD_N4>4&Xz@?uN4mEh9s#tFDCp|XRc*($Q%Bv$)*y^F895tsY-LT`M z4#698hhcb0_79z5xC?xnbX#zb$fYcj3M#NMC}ebW zDY>e6H{*rs0_N}lU*d25h)#??c2|+~*@#(ZU3_3(cB^uX-f`7u8{m(i@(3XV`Nvw- zHQz*}B^kTkvE%*?Gfs&iw|b(lIx4RcUPETfXOEzQ-x6FV<<{!&?bUiJrY2(A m)_uQe!kXYWs5{s}b9@JnVX&FT=dLLL00002A27sa7C zxE5L`b#itp2pxn%aMCTa1Pl%iqR^iZagd^=UM@|0t+o{kI_R_9z0dpH`*nAK4?=qs z2~357fP<26B}JD+L8I=b$W02V0UD5(4MsecFekKrdcc7mRoKps*&YE@+KknxuNXj` zH|t~=4$u_rJ<*xy3tDWOl3|#qp1{_eE-cHOGUd4k^~0#KHbWXB1A-2HqyZ>sLv9EM z#G!E!yE6CEUc+HUYa3W+`@>?OG`L7V!jlwc=`=poNDL)IvMf)bdNowZR$0b9uOXgL zm-OkClUc2$oLP#$2dO^tr=t3|PlmjgeSj0bD(4fX`%st^fxif1;LTlbY|fDvgtEuA zSo3J5mv)KwmM2ahb*Pfr&CUwoTwo0mTfapPJ3;^wRONj+QQUUM1E7kG*TSOfi#O~m zoXNywt!>EMamQPzAh>{4j=euGjv8Z{Og zV&gY>0M{aZ>_DRSbioL*qNj%^V=H^waH=TOb^Rj6I4GkEj~16*N-Gln4$73%9=eS4eGB z&rov03SGU%bcMH2CBT~%Sz=Ma}=^{B^=b=z0aNzf5#OF>+;r2 inTF+sPW+>Xwcrh`bR(^r9}Up}0000Hv;xD2kNONu z3LrKko9YH4wUY`qJV@Z?;e@bt&K#hTEyREVRIWCr3T_4l{(^vj%Y57nOiD^0phCPC z6apAHm?28eoH+m#V!!aEO(B6d0ZHRf2OJ4_rJ0E`1QHJXpBY#bI~zEcb!hw-!l~-R zDh54ZKqj0Art5T^s<;+h*ugN1jsE~c34#6l&l}U{qkR|A1i> hleW?YqTD|+000GBC+GJL+JpcA002ovPDHLkV1mfGe98a- diff --git a/docs/html/img138.png b/docs/html/img138.png index 28bf892de4cf98b516cc966a4577fdf9982cedd6..74b25797d542b8914a15ac102a04cbe6a88773d3 100644 GIT binary patch literal 532 zcmV+v0_**WP)*Q^88ZKoEUxk|t@p-5`P@Li+~>Jm@h>PlDJ_2#SJ& z5b#iXGI%O@i6BBx+8+?XqlXs!frzJqVy`_2ksbwgHi1wMzIlxOI{B;CW4=If-t49!>l>b!Ep%amONRiF=WvfHSllW3r9a--5OVz zqM)%A7I~$>);M^Ht<$EWt44G!`s5$1c<;X;fST~a8fJ5r5J~!>fCVtSaV%8b1PWB8 zM@N#XMQ-Csfh%GXypj&dlQIsNF81o!gGtAfstW1q2I1LWfC_}nzLSS9i+lpHc56N0 zR|iZn_RBLiP>vjaKeo!E%U-0h3f+#Q!|@~=!eqN-mazkzyfqBL>ebJ&z0j;cTber~ zwH+e7lTkZpf#(gCq#b5VC{71AbeU}&Q4Qjk1!8^JXaKt?JrheKmeHKIfLsl)KD4l~ z)@F;^p$N3`cnp5+9n>#ydN-g}HP}i3De5j2q7{Qwym_D1Tbh+`1o6XN>+|NogYXO@?jhlYl} zd-u-R*!awuGlGJGt5&V*=;%mGO9Lu&adEkO_pXwX((c{62JW`%-V7Q4g+mu@O1TaS?83{1OUK-RL=ka diff --git a/docs/html/img139.png b/docs/html/img139.png index 69fa8cc71517b3ae30beee0dc4c9c72c2e81369f..50b5104b51dfddbaf54a443e2fc62311bb4e85dd 100644 GIT binary patch literal 412 zcmV;N0b~A&P)qBjpxqF#Z4h=;SKkwYRXsGhCR=8~A*3q>X zE@W;{C#V9>S+sw^rRVf*gNtg^{wA2yekcVij^sqDc-1iJS7l>iv5}Ar% zA##|6U|a48w1iP|d!SoobYOwZor!g(!Qjhhk>Y`&fxWr~C+)`Vt^#h&21*V2Dg@u^ zG#%axknIS@8{dyO9W;^U^2AO9PyEj0pPK{sRurXGJxORkQZKA z@y?&rP0htS@W92Hvgx%ZO4#5mAC3CKhiAeqsq#aaBRw^;iBF&GDaR9!xQ0`7cu*k> z)pIb%-P1g>S(@CzJ)I(2wHzHLkDi#~S?GN|bQq~uHaqAabHgX-8%~r0KRljQ#K^T3Pz4P{)b(51wKqQdD zMuaeOM2sMwMpIvk2*G9%Ei8ol6NF$t-g)P(C|r~33b(mJ=6^g=h=qlSVqt3`iUb$5 z5C!8md%u^gNg;~pYj(c(-oBmPnb{9WLRKDy_)mAJ01svCgy+|c02TX2skh%>xX+W$!1bt;^F`kxDapt$f z+L@+tQ`TOwvVT0d>gZ76X3jxCia)EpLdF`>l$ac*k?)PC`L*F#pyB`d*ZvD2M~m3b zSBb?C<4ahdm8w3=tk|EyR)zRHJeEO&AEOA9uMs$6;&YT{Efp27qewd%D!sr)NXe5~ zDn@G^SeAX=7;D>dxwZ|Y=QvSWX)na)rZLLpi7Q=Wc7J4k*7SodE~5@qq=e92rR;sS1A3z-mAK4C0iikrn-WW0O$6d5AY z9F?l6zJCEm_=qzYRf=Y^GCUPStQ2K`>15$2!u{wK8BDp}2r zvKLythP+YW*L#n{x&e;Tk?oGst~B{^~Y07w|2(-D6QHw*v(002ovPDHLkV1jB{J4FBh delta 607 zcmV-l0-*i21%m~UFMoG;cU4tY?(Xh0Gc(N0%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0 zBD=f09~~i;00001bW%=J06^y0W&i*J0ZBwbR7i>KRX=DGQ5^nyz2>g>YmVCk5=tRM zP`X$LmjiWk2o70X0;PzHgdmm*LKpY9xM$MAWvar>NSK32WuPUJGo&2@MW4>H2J34G?AfVnL~i8+$rn^d`P4VLr=bqx3jA#+;g5=XCi tCyOuV$xh=7I^t*~5D>e&yC0vO-~a#s0d!JM zQvg8b*k%9#0DMVAK~xx(V_;xl;8?%_2LcQXtZ)v?1qKYj#Ryb#!~s(R1@KKsc*zc= z7wB;=CZH4@us>VSl?>FWz{Lb~%7Fkb22P%YX#yZALbj3%a=HzkFuZ9pSP0_WVdwx6 zk|3uD@NFnySKv|rvUwO7j2U>(9DwQJn^HibtpKnt7W}6z>W=^b002ovPDHLkV1hyc BTf_hW literal 613 zcmV-r0-F7aP)(g4E0z{t$Rz;oshl41c=y(|h4 znvr;C4H3}r0hNy>;-ncEco`lrFz_IWxd5>~sxod+qTj&4>cF6+q`)wnBgJKbivma$ zlakU0&IJtOd@yAo(?Vd@ZTPG3_W%PE)EOHB82K2^oH+oFMFF57ByF)U6g+4M*v0@; zH{oZ(7no@fV1V5lXu>!EFaGQ>!~mAuL{SDK5->Fi5LQGOFhi&khAyapFm`njP})fW zpJ|Zv!M}mwH<%%cUHqxQKeJyAmuamk$QH5v z17;8fhW&aB4EvctsgB7WS(=~k17pD5Sq$A6rZLn)d?*Ss?vs)dDDyBdoL~Uj!E|6h z1J?n*4+$`*F@dB(*={n!R5qZ-AWYNXu^@x+D%$~I$)%yo;PgXRS|(8>kU0Q&_>bdQ3e0*EVWhyxn{|LV&&1@zjv00000NkvXXu0mjfZxj16 diff --git a/docs/html/img141.png b/docs/html/img141.png index f659c90c4a84c34f67d4316091e38ae9a7bea1cd..2c6ef8d9201b9eb7017f0ea8cc333213752bce07 100644 GIT binary patch literal 619 zcmV-x0+juUP)KRZU16K^T4c+w5#Indre>V<~u&21@a|y%Yq&bjzLa!UzLklhFNqY0%OK#p|@vP|8gRmAVMuc@{Hp$LrHySaA7Wzo$=gpfp z^L;bS0wGkfENhqlbc_LEE0t^lHb7k|4Wosmtf?$h{W%7T?>MEu=IvP5U!ypPU%dk4 zrQ=|uoT5l=IGiS)8K}~4K58Jz?r;Y>4;*Q%Q1eCpf<8YrW_3F6~E?bVhSC~IRZ_W z%dC8+x!Q20lFPrHJ+{UUk&RjC6qUwRp_;g?Z74IvvwY}C+ZMlsvPnquSb z;k_t!hVx=~GYD#1V^v&Qb>thwwt}EE&N{rPjR}foJ1=_*XE&S7d^R;vO#l6Du7{UJ(EQ002ovPDHLk FV1jo^9v%Py literal 581 zcmV-L0=oT)P)KRliHaKoowtUZo|rQN*po^|UI~(zv)95cdw z1YO;NC^$G22XV7FIR=8ckktU-+PY>?*Ia@ z*06%AbDXCSaX)>Y*m^51!mRNW3?V^N zaQE>Woj#CcO4&bdha&YLQ{;)15_oUPYE5NVT?a%d2z@P^^O(pmz?Z;4DkdS2RvcTE z%}@I(IZZ6PdDXhoW_Oexm=g5#S|~f;x=t zs$d#P&Uin-Lae43upCXi#EpY&@mz}IF+|@^lglXNof4zZ(!sJHZrtt-E`8Z TgYZ0q00000NkvXXu0mjfZL$Dy diff --git a/docs/html/img142.png b/docs/html/img142.png index eb9a94fb926a6fcc8ca8348505ab4eac0c49df0a..cbc74cec0a796ef25f325fa01f4012dfaa2ab5f9 100644 GIT binary patch literal 626 zcmV-&0*(ENP)(EFH-73RKLGTBVt`Z<JMi@u zqOPN8wf9V4i;)k2z~|Gp;_Z~pfmeY{2DW)`5s%NK69n5}WrO%+dL1uSB~UBP=OCP_ z78EQTmx+{qFUAA4O#$w2Q#gEJ%1?sZbw9ojvB)HqQQu5JP-70VYAo`wVTq9I=qj|p z_56%?r|aW2SC7L%npVn&Ku0)!mnc{Se%mdGCi7aY1YO?cYOG7#P3F^F=dkEz6YVSX zR4H&m)g$mBQUzgVLZu83QmQC8`@5F>GsHaY?RdcxV7Is9xbW~_zR@-heb;JY?1tB3{d=dye2R9U*we|A4sHcii9k8U#iN!`Pm>;Q#;t M07*qoM6N<$f*kH15&!@I literal 312 zcmeAS@N?(olHy`uVBq!ia0vp^3P3E!!py+HctY8*2gor9@CkAK|NsBYnKR4F%R@s$ z-@SWhY;1hy%o#yJ!BwkPb#!#3rKJHCy12O9y?a+lNon`)-SV=EQ-MN^B|(0{3=Yq3 zfaJG%x;TbNOifNmNO&NU(!k8l%Esnq@S0hmc#fGzk^?(`!;Fb9%_i(AsAuwUV07kW zVmO<`nr&n;;lP=M0|yo?RN6SN`7mR@*ct_fV-^f0q8-=xPXt7;ESV`GC1w-wAT{B^ zv*+akl?+poe_JHF9X2YP!NwP~R*Ba@mmzra1Eza?3X@W~r%0b%aHQb;!QV`mnK|bB zHzqQ_=UY%Uk29c={|whA=^NWP3O3)J8suPH`%pY;=WGE6hQ4!3+cde@K|WycboFyt I=akR{0F%vco&W#< diff --git a/docs/html/img143.png b/docs/html/img143.png index 3df4bd77545b396fa90496a94c5ac61a0b34bf41..6bb04de64e04c3c658be961e1f919e3950313112 100644 GIT binary patch literal 395 zcmV;60d)R}P)9rVMPD61!nw1Ck&+ zlr~`a;4q(oa{>dy1O|3S?EsM21ROSC7)U@J1c3eVV8a4FPN>`R|9=3BC9p6sun=Vg zQD8R)*g#kl1ROx+He;$_W?gec5OG^VPba8RHd-txAlG5(oyX9pSrvil-OM?7@862M7 z0Lf4Gba4#fn3b(mcR%?GGd^DRuoo*FiW>e8A|yGLSW~1UTDp;WmbYZEP{+n#e*0ANN%|!&hze0QNb6SF6q`+7zg&-7 zC1L%eum)QPrv*Thn5V`}GTHpqY&ILMIC2ZN#DFVXV=h@y_ocpLUC7k1KVlV&*W23w z3Uj*SL7`CecPz0lpJ|)0A5laGDdhWTK$ZxP*}Lv&#iGuOz;j2496(14NNf~mlZF3V zjJZ(hZ=P+vZ8morv1E6VHKr{lzlX?_;H_1GU=dmxB3I!C?^X6yFjXEplCu}Mq&$YH zx*{JY8#e(h?a*tz$Yn`sqVySMHY3u^!?IOpp-4eEt;4==xdr7iKcNJ3-Va|@EHw)D z+A_IUb{wb$^~$1f8ZaYV4bf&51^K0QBWzWM<F;xoSRGO2YreStd@TxQgGqLp-HXnW1 znOF`>)cdde@x>73yHOk79>y~JE_@EI+~O@O_nI}18D9iiBd|?#c~=0V#aCC4Y8A62 zQ{BFT%ZPsMqS%~$-ka{)i!Ei1PD*A_?X5{?w?eo7NXNDdk1Ax)WT?9`c*%c>&&~VLkx<0A^&SwUSx>$N&HU07*qoM6N<$g6o`#h5!Hn diff --git a/docs/html/img145.png b/docs/html/img145.png index d3d1573f6c148aed7e57479b5406f9dafa8692fa..16435531c24bc8957a03b8064b5d72985fb7fd6d 100644 GIT binary patch literal 568 zcmV-80>}M{P)VIlelglqhWAHqU)h~5V1II;?z2~e}rO9V4~@G%bnt{8%%?wnh9b>Ur5RV-Tv;rdnvZ5k5? zWuVg@#!{yhh)ULrQcRl)A4`sO^2)Pa+>fTzkp{fl53KY$tgwv0000*&MYr44-E}{ z_wJpsvGJKRX9NWWSFKvr(b18XmIhSl;^K1m?p-A%rQN%C%gZWG1qv~i1o;IsI6S)n zk`MKCaSY*@nVbLwOi69Y3Qdi^Ga0#r8fM5Ji(IJBpu#UAVUWN$NAfS1!>eW|MvwMp z31((~<-_bbT7eGhjSlbUzLW5btxcF`vLlZg>o$hAz4s*;to`^h8*H={ffg`$y85}S Ib4q9e0L_C#S^xk5 diff --git a/docs/html/img146.png b/docs/html/img146.png index 7ecedb71d1a3be936e0e89f4bed1fe19071d05ed..d25261ef14396212690115dd486abc9fbc268932 100644 GIT binary patch literal 614 zcmV-s0-61ZP)KRljT7KotHY*^1>vxq}X!3d)wHprQ_4if`zYr5f8! zYe^uQvIPvy&`dQLS_Dm_l0fK|!F&8CDBV01I&}*bO+$V{@=mfVD{3uswtE9-Fcesknk`<1$b>d7%;tx^4XuYtxuxzi&M%hA=Z zMja6m6hTuZEubA};$ThNw%gW@gWkRPq#qgkc}Msd)k0u#Ffjoiz)6MZ@ZK zobd3R)~QBPQ?TuC`_D-GmJoSk&q|c52`;x}JQ`1-s;DyLlNyuM@-$5rJyna9Snv5E zKYaLlkjmOAU$BN~{nS%zZgabfx=3x_2%EU3t&lWR;2dxq8y>?i{8$6+pyoKx5xMRl zn!bd=28Gz9=MQO*rCB%qFKOJ*yl{p3_#{m6Uom5;UNOThcBeRVl4cp`B#Ie~j%xJF zvG<`cTswJR0teLSfvoI6f=+yUkzH3VH-ge;oo&DgSK$>jQ|SKRJ}^WP!#@h+a_sib7Q68U@-;<6~sJ3HaAVh&B2O` zllTawR0pR%LVW-+IEZ6)cE}3|;@~C(-4w<9(>7_fwW1aWKgd1z%RTqYIp>~SAOZ#Q z7H9>Z!#9yjAuMM48vltf=;Lbk}fk&w};Q45LL+x4aX^9U9xQrrr+_>nT{f~NS@YorZpzk zLYk4g$?0#UF*3|V(*XzMHqfr4Cc8;_??idgJTWDQ>dQjdDjufIbhXQ?Rc$Motpw05 z$tvY1JrWBXq+Hmx1;6f=n*s8moOzC6bVo1GWM^`Q(%gZ>|fvh#gvwjy$+|^dBKRXt0?P!v6BOGs+d1QA?=V?lV5#mx-4pjQh-W*SkB zJSOirjCt!7QHVksNcJ022p4Bt8PKFDO(QU5yy7{}o{Vc6cr*26~u|ivl^& zQwFmoeKdWof8eL6FOO)_gTxL>PxI|`sOk&&I?{P+W+^mXVnYV>n@BOPPjt$DOi;mR zvB3;=E+j2C3IgGRJ29l`qdoB0KPX}Jj1Nt3BmLA2mzf^&U18Re3;Y9q0gwT8u&>&O Qp#T5?07*qoM6N<$g3~nmkN^Mx literal 732 zcmV<20wev2P)KRnKb^K^T2I`yN_qgmb{87JiJm1_HY8Mv?&hg{|RS6mnkR47+FhIbjU(Y=ji-_ zt7kl~=>&O3JF$1nsL4f?H_V%(;z@k`+?ldN!*tQS?(j zjljT~j2P#pihp^aSdezSF^#xECx_!|GGM z=|p(HN1ud*lbk*PJ2)0cvhWdKoW5;AvrAdZ^1JX5u8)QIhh6ACkyuDRvDeb6btUt$ z@@;C<*xK)6d)Zr~|DHJt>in2gOpKR9y(}sbp4Qe0MhreXt?L>7A$$idD|PSU|?Y2Q(=IEvv%i>00mn&-@0000mP)t-s|NsA) znVENYcU4tY?(Xh0Gc(N0%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0BD=f09~~i;00001 zbW%=J06^y0W&i*IiAh93R5*?0QNK&WKp1_wCTU9BG&ov>1d2G^4yhY15y$6w7pI*N^@(Z43BArY>;J|VZ&09Ots5xxnngG0507q#Hs$JT6Q?e9`tI|qv! z(CU2<1Mbe4=k~^rNQ;tf;IV1}Cu#4R`nDQ$revmBr7%UTq&fc`J^f!(Z diff --git a/docs/html/img149.png b/docs/html/img149.png index 18cdc9576d9ad2f63c7000b0d840983cc72eba54..cb788d91113476458c199366ef3e0ab0ac72e4ef 100644 GIT binary patch literal 271 zcmeAS@N?(olHy`uVBq!ia0vp^Qb5el!py+HSYPqU8OSjR@CkAK|NsBYnKM&UQ=Ofi z-@SXMsHk}6%$ZfIR&{iAl$Di*goFSU8W|bgy?a+cKw$Uo-F@BppMgS*B|(0{3=Yq3 zqyag-o-U3d95a&>fPj}lh$p?lg7HYggR};wFom?l6X(+%n7Ab*EF>jv$Q+SjQEMoP z@z`;oftST0laY;Wft6XgS$P|;!{VJgb~@Cgg(ZeDx-ZzmETEQf@!W2yqc_wHPS!KH zq;>6QO=A7FQd_pcPvk)WLt>k~!pikLHP;gec5OG^VPba8RHd-txAlG5(oyX9pSrvil-OM?7@862M7 z0LgcGx;Tb#%uG&5NO+*lAjFg3@PyS&p*fS0nQO=S1C2+Rz1R#4KGX?h#4k9|z$j;6 zAj1&E#KXhOlOxBI_lJk)&KaKNI~zoH%jj=sUd9*qmit7Erol=UwaIn+Qg{6L-+V!B zf~yVJ9BzrOr}_m=XVQPXJy6%XxUru3bvuhff8oF9|7HG5%kGeplwfGHl5c%%{;wG5 ODh5wiKbLh*2~7aSonVLn diff --git a/docs/html/img15.png b/docs/html/img15.png index d9af05b2e66ad2ffa69a7427acf290cbb042556a..557ff9028d2fc6c44114ea3129fe8528e0de4957 100644 GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^x^2^Tk!w@ literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^dLT9nGXn!-@QOl^gl>ROi0l9V|7XseSzcZq8XEfU z-8*Ar<1=T@2nq^zbabSpr2$pBxVYTCdsj(GY4`5kWh*vo0EHM!g8YIR9G=|($)|g| zIEF|}O-?w#Cm|{#QK5dIB8H<&pTT3Jks*hHfq`;%gI3~%%9bOU83z(=@(wKOSknH! ziDA+dM~MjmRR>NTI3jRh!Uu-=noisW9s=s;4(?>sYFhSBgn2bX%pA@WAuR!7Jf(6x Z47W}A-u?G$zX!CE!PC{xWt~$(69B#sP_qC4 diff --git a/docs/html/img150.png b/docs/html/img150.png index a83c2523b21ff3cb104a1130ccd33536aaea03da..59c6a079e6fad840a0fa98a520136106ac2bd736 100644 GIT binary patch literal 889 zcmV-<1BU#GP)naZB zIB$?!>L0x2gbd;!$OTR~RFI0diO@mhuy}O1O~v5g;^4Ws96}aBIU&CHC25niU(#Ac z{K5Ap@Atiz_rC9YF98^ey)JaY1t>snh6(Jh>oZnmxJCjZfaCx)geqr&Ig*(GE}B!w zACNbhAP2Cz>Z$?V2G27h%M0V!9tEw$^HOp_n>q;>&f4sGI*@CY8!pkby5!Gtf!}gS zDHYF4d%X?P;M*c-rYZk1a_O{M)OEd+^6G7WcupPeif~stq*@_ag&d1wac^<%!Y7>O z@p!ccJk?K<74i)$e&dubFGfQZ#|Cl`Oh5*x^=RK|scZ(wqv7lk6I6S&c=PPid zo=P|VZy}`98Cf%0-t*w>==zBcm$r+BUoZ%_-6UO=>9UwmqQS9~v;}X2bpTyTu60ed z<|Btxq(g;GXH(tUx9Da!>`O+U7RhX0$t!-0CMMV^7j&Jj3S~iq=<;%TiETm)j%q(b z)k1LQ!rHa9>(;$^YEFSl&h=nMABdJfA~%A7=HgLNAa%UR&ywK=PP;CaJ&#*C>?()w zvDbpMGi|$p2gAXVh<{;bsgt>MMwVpIN;>`jpx8-4mNNfrM!=Oxl+@K&cC(b%v6c3#5y=zQKLDx8 zzOlD9lp30`3&s%=6M7Ypl?Gua3{TpX8`R)M&)7GB70(6v&4444UsqN_V#O$E)Kru& zFo}X*odxmESJ)Z|*`Qv0A3iU^_Z+pN!D{JGjETlGIGQmGN*`+e{W=|(ufOIk9fC?5MBJA`F9EeNl;H~~10SuC zvC;oBi(^|kFeXUmvK1z?d@eJCl2B`{a5^{EW)Ujell-(^oIn@z?(gC^J*K>@64{k}@P)OW;0000mP)t-s|NsA) znVENYcU4tY?(Xh0Gc(N0%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0BD=f09~~i;00001 zbW%=J06^y0W&i*Ix=BPqR7i>KRJ%^YFcdv;(^Tmz5vUu32@fGaO1mSq5@KgyWT;r! zfPob$MPh)Zz!!AvhIfSM2XqJndp@D+PzfOfcHKwPv@~iLK%Bvk>*M3&>jyA|0SXY6 z4I?flfZ6ocupBmil+cktlE-R_Xr)1TsdOd@<1vH@i;SWr3X@pasZdI6qW1^*y0JQ3 zgWF)G@VrDc`MLe^q;ZRi>5q`sSk`5)c^HQW*gc;*YK%0SK59Tq9G-xVzXE4Wb^;(g z^%;?(bRfJtLSy1;GsH`66D zxv%|hyyiCGI8gK59?c}OgB2z6ejh58b#ltKBsL?legVQSW{x)$4WwdDCr!bgtj=-M z3oK6Ns@Atsscva7ymuQpzd6k|Umg}5+_l9uR9Ad=UfHPLT^g67jk1cq1Co5@hG5~8WW$mq)Ss`$l?vnL&1%iq!E@Hqh+`1o6XN>+|NogYXQrm6Iy*bR zd-qOJQSr=~Gpkmu>gebwD=P~L2>~iJGBUb*_pX3|!0z3<`?~W#1BDn%g8YIR9G=}s z19B2PT^vI=W+o>90eey#t3p%bM+0V&nuO$p2MvWH%S9PZHZTiIY+&enFQjmmiJeJ8 z;)Vp*GDCxckH$3zmI<+5Ial~2>HtsJ_i2f0&RRD#Sf}aoBxX8@=`%MoUoc@~V2Bi4 U(IIHz477{E)78&qol`;+0PIOiX#fBK literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^QXn=9GXn#o(S~3TAjcrUC&cyt|Nk>*&MYr44-E}{ z_wJpsvGJKRX9NWWSFKvr(b18XmIhSl;^K1m?p-A%rQN%C%gZWG1qv~i1o;IsI6S)n zlF##WaSY*@nVbLwi42XkJOT&!TM7h9(8Z4;VjN)@}U5 zaw+?#JP)KRZU16K@|RWH|}OPjT3_4sSr<*p^UwD3sm;ONj?H65mV`GqEbt^zYyY zd2im#$9r$yd$R$$$N<9}Rt|SS0k)0+M%y%d4zr4s(CD|Fay*6!B!(y12Ks>}Wu$H; zBBJ?i5i!8>1+f()GRAR~pk%oC;P(~r*AefN2;?#iJRp_2!f+{LY-6KkY5G7t0V}mF z<1`J{Y)TfM(&hA6>|4VuctZM6vZ7DUkX+bb|KwHv0v>jkpRXlQ@dg+!i>Qmv%gU;- z#W>SM6k676`^|Kxa2P4QT~J7!Li>SDopQJ|STwI0m}@4Il;t=9JkN#yJ?Fmyb;|L) z1b(fkbv&7q=rrTeL3zGTdQ4im@vT-CjnZxR{#Vm^4}w+Di`VVHkn&EgVJqT&Vg}fe zb~fzsxGsdF8-2EWJAJ^l+^0FHZeq6DfL Qg#Z8m07*qoM6N<$g4;JGp8x;= literal 0 HcmV?d00001 diff --git a/docs/html/img153.png b/docs/html/img153.png index 2c8c4c5960ec02422feddee783e7699c003578f1..986f62fdb4eec3565fee5fde2fff31560300ab89 100644 GIT binary patch literal 750 zcmVKRn2P?K@|TryE~i7hZ|6=qSD}B5YVf*0iozAryjgG zqE>PcEFN^UBI_C~#fM&CW zcNQh9xd(Gb$@4iG!ms$14iDl3P$l4=9@{u2RLnQp(^9%=B^=?PEFqKIH5%!t;SCGM zS?K=`d$5<v6?A;~{VemBbT z^|u1Yk4$D`beyg1ka~he&A&&cJLKMG@(pzNdDf$eSr0itQOTpQPSC^PKG~imE6Z)Pc{~^P0t|seag-OvLdw!O&{& z(_R@}4B1=Vnq0=|)H8SL);0b~rWOt_uozueKBYw0ZUZMq9>kv`KUn{bsFC5AVfi08 gjK;W8ckwUq3k30$YdvprWdHyG07*qoM6N<$g5Kt39RL6T literal 8603 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 diff --git a/docs/html/img154.png b/docs/html/img154.png index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f358d2063c7f1afcf65391b9ade0aca72bd30f48 100644 GIT binary patch literal 534 zcmV+x0_pvUP)@Q@u;WKoox=$xG6&L|g#&>(F5d_8;JlE@cJM;D+hzHprp|mk1{d`3*j2RB=iCN5Biby0H~j z0fu?ZgF|V7lA&90HiM31%j&c`3n5vxK^QXd(O$%$4_(Kjf>>5y!DpKT25ppTXW2aD~b8th&V!%YlE-FZ~axqJv z$Yc+4RU;7&*Z5zt8*37u!qe^0o?<~Z>3TFc)8{xhePJjweWceJy%)AuyQNpE}>4T_E)l(EURG8_u}fHGjqVAYR~5E+2Q%*$e=G~z_a3L^W4Lg^ynMDm4#qor99i}5BeaqR)=aSJ3AVqF YF93*I(ktoO`~Uy|07*qoM6N<$f(|n5eEfFPDZMZzyPA;E*e@J5V8fI}UVvJn4@GNypuW{0iJ6Vg0(6fiF0 z7G-G=Y-aE(R7i=nRy~LtM-={c@2sDl)2(vBaNrnC#32quIAPMI**4(9 zoEw+hxHwlTQn=I^0)`a1gkTa6j2o@L{j9o0}(iqN-acAWUhu~oOy*In7 z-IY#~?c}>#?aZ6^y`PykGYiZ>K>x~3^{G7sTsN)c=2<>$KoL3U;w`@{CJlorsvn48 zima5hI-h8L43!sD=P@W_msxIu8`SD^@7`F!QvH!MMv=Zdq`94DsyokD;e;UbSemC0 zMKS{(I(y|x>?+X9HoO+F*HHykK&X}EEM`gw{E`OrQKam1t+bDdt3_11iABpnUB(!D zA^lXlWxeX7Nb9H4t{ixp7ge#$)5W40DR9K55NKEy-Sh@MMd4^IVhPDMV~!YPS2W1R zR?;a}{>;sXPMU>TQzHm-eJih^^MVsFLHuBh_g1n?rc{UqmOnk9)`G6|Lat__ib1=$ z8oLTxtx$1jx@BuyD_-Fx2kkZuQ)T^(mpry-sC9s9?<^lzc4-`@rs5?{gZ5FXbg5pg zACjzs^KHck*B?W}q*vhu0y@ty8X2whc}BIjCGXML)xBYAUe*H{jHYbRwUv%sd3pfJ zY9JHFS@|nV>}rq{F?81yvbds+0@=FdB&%o%BvIW%vP=9~vzrQUrruPP@`7%xECU(!CA4qjZQjE;SruJ7*rLwERQVWQU^#>Oj5baHV&OB&UbuCM@e~EwK!rgZs)%QP0&+R+OTfXH`(W-%MBd% zLNvEx%Kom#(yxDcaB9ay>G!En8?bs>9;o#-Qu=K7et4=@gVj9Sq*}1~L(r}_VE3wU zS<)w-eXhX=G`P)KR6R=rK@ffS8Sf<7Lv1XC*rhx;Tgg=-HeP9Yy`s@t z@JI^VfK{qoA=p}23R?IBR*Ogq5r2Sig^e1ByPI50a{1Dzl@E4j-^}dn%(Anc|Ad5go;3@-+>3)U8#<^-bSks^?j?NW>w@wNvsfzfy>XE?(SuAiBMX2P}2u#?h zCAVl(6fbbJ1mWJP}$H(d(o@zf&u=d*{jI5XpjqU3o%uCImgn)~Utu~<1n*hXIVy#@%%9C&c2AZtse^XkMH9HE?#S*&Hl}n00000NkvXX Hu0mjf&IkdD literal 758 zcmV{WTwx<@BOHRbXlY>#7J?RIIOHIRse}WI#RCfuC0NLn%US4&5Z~-(Hp%YZT|PF+ z%s1crG4H)BFo7Qb2>F;o$i-!(Q2-1v)hX~fQHhQi5_cIaIHDxCBB7>+?K01V}Tb>SEo(ZFj&?=WnQj7d{;DK{1 zF*6XG#X&t;W=R=U_$|(%`RohUf#F>E54l&WXP9dK-RBWx7+)>&+7rW&y`I2I1v}hI zpIJ*)Nsi30Qwx-p+tvW5MRXNU@DrBBOOe|1sj#M0eT&0|U||v~WbdNocpOn-sLD$% zh*iay7|%d7m#d1@c0dO5cf>Hk$iAC3KddOCPr`Be;{_f~e~~qfZJnAck9n` z%(0DS;(vSQr@L+F=S~C9n)itRNS|M1{LuD*CPn_YeNacKVFx&WzqW>3{fne9huFg% z&?D0K5-5!D=6MheMl|+Iaze0)Sakzt8{A1QE>QDIK6Zika-)1bIF(dJP%OeWM35J& zj;AxRHkD(k+Jiot$dg#~v+HQnSQc<|4eE8-L7}$-oIKd~@wp$M(NwXvHfVY2F{Sll zOg4kT0L)$i>(^m6s3v-kYJAp~(pA~BK5)i%q1m=W8`clWvx5uW??323HldKb0Wvst oBBn4FQhi_Ar15V*mgE07*qoM6N<$g13`hJpcdz diff --git a/docs/html/img157.png b/docs/html/img157.png index f241006d2a5a78e572d8af0521ca02d9e6f961d4..a32e3e378968206beef795ac65f289f73d0bf70b 100644 GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^Qb5ed!py+HxJ5CnKP?at?KCLC@U)q2?+rzG%_-}d-tw@fWYqEyZgHHKLdprOM?7@862M7 zNCR>zJY5_^IA$g%06`){qXQeq19m5i2k9G9A4C`kDn5w&IFa#4>Ca;aPBpNfNqF^0 zl>Jh1y`jM;BLjm?n~Z80iY)gV8x@E=xZJ@x%|LH|=7lp89ves=S$*^If%3-2TFVdQ&MBb@0L<}Vvj6}9 literal 875 zcmV-x1C;!UP)%oI3!y$~hq09AK;6}pqe{E#oicR-IVdKn>VoRPsj^jtdZbql>bL_$JE!_I z!yvpy*ly__-5LQbCPex)9J5}yUYY1$Zbl!k`qX}M4J15TsX^7C4CbV#MqL?WwO}nw zQ6E0MxQ~PT{slFf(V=0aHXZ6RGrs`4HV&&4HR05>!eZe*)>bB9+z58$o(e15eS~B8#(+d91)#m;_FBZcpONatozPF^4lJ=^6?JI(}h` zmW_s=s%cxr3UmyyTH$Pa_zO8yuT}3$O&$OM002ovPDHLkV1g*` BgzEqR diff --git a/docs/html/img158.old b/docs/html/img158.old new file mode 100644 index 000000000..e69de29bb diff --git a/docs/html/img158.png b/docs/html/img158.png index 55f17c1aee09cd30d3ce1806fb928af2541d464a..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 867 zcmV-p1DyPcP)@S7f?rKqQcOtyfDRg4viMIB z-I^&whmMM&5W2)!N|urzYnIncp{C#|P{<&fF%*(5TZOlFsC)P1XW5dPDA2R@^zQC^ z-`#t6l7JkM{I5zx23_>)v1M8wsL=qbK;)_wcD(LRaUhZ?w}@YW3zi~Gr8T~bDcm}P z9EU>62pGXBb8wnUmpxH*uT-2oP>$$yyp&yK7WC|fW|9`lD4S~D3*xm0ws8FU2H_ZB zT5wfh@!avzCDSL==Ho&Iv@?+~K{FB2D~=|3AwiTbOUhXT26{~$wJP3{VJ6AX1viOa z#$p#;nv!f4LOn@(WuPZ!3TsX*r7ZQtltYv*XQCS^PlY>fu-OPTk>8=?lvL+Zl`F$p zSdhLe?2vG*2PUpI>26a2MZ*VlNqM_wG|4EcTvIbrh->Ues#{0OWApRJx}@%vu{}<) zyrefXIB-2p6n1JQl@Z+rV%}5d6nhBAI%Pye74_^OelFtHsAP|=fK;=lnaUWVAW=?u zcWQn?n>fyaoEM}|$(%?<&$e-n?9XU2|5Z@SnsPewPXEST$sF)NEo2?7055<0sf_F| zTZeS~qZVy;uN&K}=6iDNEyHTJ#;}#HhvViuT%0}uwuZ#Qe9Hfb=(a~a)L-oEGW3jx zUBWZgJ>TezIiJ$_p%viu$tuk%1Ki*Z=r22)qg7&v;@4opVEZ&{1YA-%j(fwmZ;)YLMi%}|Wu!EP*Pp6O4@lyjF-zi? z6bb9$Oh$p8=|DB#scW-2j(bGMw(x7%!}pUA?KPdz={8O0noWALnnPmf_odP-#v4Z- z`u#r8YWZkC2Cb!6$ipGA7}~!;Z|-hOpx$0xA_VxN^7sntwy8wSVC<|t0~X1Q#bw^L tz`vx(SN&d6@(Q8;ci7vcSpZWH@E03t#6CexT*CkW002ovPDHLkV1mtao74aR diff --git a/docs/html/img159.png b/docs/html/img159.png index 4aecd5d283cb72148bb2125599a47321e8fe435f..c857d6ca2e9a22b4492aba2fc02f58d62922fe94 100644 GIT binary patch literal 9773 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 diff --git a/docs/html/img160.old b/docs/html/img160.old new file mode 100644 index 000000000..e69de29bb diff --git a/docs/html/img160.png b/docs/html/img160.png index bf808fd4154de2d91cf919c351d6f18d11a973a4..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 1348 zcmV-K1-tr*P))9!N!xK z=o&8`8^MD)%^?R55!yNVbJz)p(bFyqlEYpq1D+PyK81)YjPao8WsZxNbVd+k0_%JA z(|)#f}}rjtej$&R*b{BZGikc!W-mqz6Lq zL~T2I7Rez1Q>$_~i-Ogmi%&KyE~6$rhRt-YLeJ*@q(o??btz9w(`yQ&F~LVH6XCm3 zX6x#mQmL#Me^%@YY*%Q}_oxIrTq=W4T5R78Y_q{4hl9{zO@J1GARIqOse^qjIA~1s%h1(nnL3saZ4CVl3uBt);+ZzY>ns zB)AZ4o2fiF7kSh_4#WysNF|C!um{qqZNfFxT^x7aCbw5XsZnN9pYt&Rp{Xnu!`UR= zp>|Eq$#(_g_9b3aRXI!4rQF6{ARnu-xjYs(H49+e2it4;jqIUQSH_jRu-lphJOy$zRcaC>&;O3oP z#HQVuzKbsK6{6;*ZIJGn4S4H8oRv>U=IDXP#0sV(%x?o1#nfV&`HgvUs`+~M zW|>)7g;V|6Tn^ayJS+>e63>_Csa9=LLF@k-;eSJ&5dHyYHaU-iHZvXo00007MSL z#C5); zma{Bz2^}fmh(8kw*vS?WRpim*{in!PP{raLj9%tJ4vM{6b?7#Cs#{JF@7pfvb8Tk3 z|6M-UXlDbR)gGFfBd-1Rd2`%Ohpf42lI@(zZDCMVP^V<9#9+yqf~ujP*i=V;(?hQh zbk}i6f4x{iZ|iy;KHNl4`(5t5W?XsP>oq$nisSJhE0bKO{b}FKn_S{}(ADZOn&e60 zY%1;eE=C)~cgZWjC|0i41IM9dH`&m_;#9He6#?xgxd-ErBx_T-VEvkXm%Sc`4$u5T zk3TN7+?$VeVWl_|Bn$J>mM;=c#VZqE24`NUDzECr?oY$|vc>onQ>_4`g0a(0Q}yD8 zQX!?^RO&JPg|Xw1CZBnp7FqL6Rx6fF|O5qORes`0!yZZ);O*OX8 z?*Sjq4xoNHZ_o4UjTqP7e#<^PG1L}*((e9q`WbTJCXqb$_U`YH_iKhKNjO6e)_%+` zoLFsL-}~gVNW$lkiiXV`Ph#d_iq02iDR=NWybz6uzv~MpHG%gC$Ga|@p2|gOj<6>L z`+S-Z$3nk$51k3c9gpE?J9=>2#v{^O@jJs zkBX%oh4#l;j=+mNB-+##=?Ur-GfQbZqpclXd$OJDkwGgbY2+l?#4=_QbID$%Y-|A{ z5my~#aSe^8TZuUWRWCXvpmeH)m*(UH)uxd>wN=bdM^Ik!R#8HIqplL%AMWKn4DUJs~Ip#1Mjw;z7!MG-kL6LttDUq1b zb#&sVV&;H(3>&MbSYZQ&44Fb|Rf%aqOb(S-6h<#pMwvAiQ*;XZ_0lP;pd*6jjpxA# z;VHlM64y3JT|crej&kOPV?-{ZG#XYylm3XKQW*FxQuZL8WI4EsC9`;g-YY&djm2Rc zcaY-Xuqh7KYq4bgNx9#0q{?$hscx7;RRygM_MyV0Ve`&#R7+mOu^Hd&bU}Kp=cS7L z$#*sc{F5HS@;JMRzB9nhbL7yR;u_;Kwdu`_oOyibCU57&&aEjv7gARzRNms=9=1?f zpHA(jiq{h!zd4MdGv3A4bicXjYVZ?!9Mhk&T0?pF60rIBDpFNc)(@{7_Ig6!ygT}&sR~dt)$4kbv}HuIJq}i zHgoVOR4I#vuqQs5tlY&_h^PY2`DWfonI1+W9TCMTWW6Je_2+s5nPg-5S>9#ixBR-Asfzi4EVUC? z!3ln(cjK^%C{!vB_U}eP)2$v;MdmXgsiK=C^?D=9Rmc1+7rS&orw4bcI0!qatwr9I z+SR4ye)u(7I_-9Q;oU)a5c*koNz!}=03{?Zp`e|X2eJ1=P#9z|?AAG@Y;GOi}qW(zb00000NkvXXu0mjf2Q%i2 diff --git a/docs/html/img162.png b/docs/html/img162.png index 28c318222068b8358d8b7087834c94a6b6304c49..36856d84dabca459b1e4bb22cc091e5a045b6320 100644 GIT binary patch literal 801 zcmV++1K#|JP)A>$tDsFC}xd? zvAaYo3PVHWV!)2+FQ*Y>QP^BZGYI9ymG65CKlxFD&21%xaogJ?dhwZECy6e$xl(Md244BE3 zUoAC86%ebGmy4q9ev+@3Q4}-x_vV8c&T*>4;Y0)t!KT(oRGu`2aH(^q1o^iOuOq&3 z!;xuZ-*1CdS0$-xG%;Q#Do24YZx1g469?}hJ`Tr6nx2z{ z4@n-dpObF(;s}|{8a8C|?6U~o9c@WeK2w6BvA$KDyUPiz89ajF!feu?K=xicFgCE; z)*1Q{T3rjU#CSAL0e2$0C8OJ$Yq%f79`^&Y@Ze06R7k2takHs)3$^SGdNW=ybUmqs zwAN$bRzx?`S}7dXqUSgXc%*M90^X?_u6;nxLVeSIC% z4}FMt%i)0Wrqv`mpMuZ8!h7>FfvukkH|BuTL4B*EfANW-9sO6lbL37TzMqJ-a`J@7 f#qtR_^uqlEtg^T#cqLxv00000NkvXXu0mjfYQuAD literal 1121 zcmV-n1fKheP)Z zY(9u1GcT0te6_tef+WbH&Jka~t!cx1X@Np=vKe^&_yC&Su5u7^Ayx8SSmai^dKr}k zQo=A3p`Tf{Ug1Sjv5aRPKCHJ4(BNpm)$kiQp6v~eR_a8e%2sMExUw?g>L}*1mDdy~ z#;WCWa|p5@4Jb~~O1XPv48XakfrJn#P&1_%VM_)zSc7|kz(@ia-VKH;dOJnUQMvIh zuxEhCE(GJAg!ep(EtOtjrdDjp7KQWG_424GX`afvAh8+D?%k}6%pg5V<`9_9aLoy0 zeQ!E6+s~8W1jT7<+Fo*^ZHxx3*x)1ys;mZ3r#!|V^(JJ8F)s|Pm{p{Mzoiq3ei-Bq z1XuAqn~{V8?PVAvJQ^@rc>LIVnx;mmgFxAQj2}?{*W@!(Sa-0L1Ri>scp3rc# z=lIh&TsEZOO|0tm67dSv(}(ZXP1*odxNc;PQ}c6oQ=n+Y5{E6k=ZrXonOE+NEd8u3 zxP*z%)@ z_tB)L84ib5M9`nL`_>1ftaOgQCpGmjzMYVs4Rk`M>tS6s5qT1*>bEmn+BlAYbCdNw z!lxmN67o<4Z)gXLK-V5AKN&CC#fk)rCf!ZRx=m`>Q_FNJ`NUalYh~qm n4WZdv&i%M|F@?V3 z=FK;6zW2?0vvWYgdl!G*_2&8GzC!EeI zGyxe?05oqDaXHab$NFk6gyPLCP4w@~!peQ!2jLB7}OC?)%rZ57z?-eAK zza+RZp5Zh-m#a_RQ*E(fzEl)4iwpb%%)0B6DXfD)a>{Wm?bF;A7HqxD6q)c0<6&o= zY(Xjt-7>gw<@JLVn6InAsXH+;Ipb60S)?aM zeVkkom%0%4j#v4Z)6XLsDzWx)0opm)rp+cLisCVkS(pyeZchH8fxP>HxGf#_Hlp`! zt7hOSEWZ<$Y0?uPPTD-Zo3Hdi`88-ZQWZrLMy2Efu81GU13RRF?3Sxg4JKzkRNc#PWXQs;B94trhyliiEQ#d!4a8yorTX~h&VLI3~&07*qo IM6N<$f|QJ`fB*mh literal 1209 zcmV;q1V;ObP){I?apLFz$gS-i>w$XVtovlz#bz4 zws8KyUtvPJuwci+nL5!8+;^JlPnGbJP9$DGI-$iV01;rG z{Bj-Yde_d|bxd1sZ4{coMZm*M_)O|qc80bIL?a@x&*5SSEF}gZ7}NVI;(8C@<{jdw z@gu$ljB&>ReSyn6~S`>))6NJ4WSAR-yel)NduONO2H7uu- zU7GhBvJ6M+wGr_S^$I%k%rV1jTonz2ej-RZdY{an-QDxNFzK}vElH(TLli<^%Ty9zfe zPLiF88Mjnf2IZx+#(rPuMmNMFBEB$&%Z0h}ScKb!#=#}*jl0{BPx$cu_{KdC-s#-F z^;#Z3?yvVhcs};v<9`CU5tBLiANl;7ffK(9e-kyolfZ+$9>5dS+#UxRlIE4?(v{p+ z1vLDQByzsp%*FDz0Kx+M?j{a4ayoi*hh(w(c(Nf2aWBsANjpwfMT%=(zw|(-r87~% z!RK%aw*Y@xAz=pUrWfYIR|m5|Q(=zv#_m=A4B(M;MP(~7y07yGzjoE1O_BuvUKC%4 zkXTKjtsxJQVyI!sLKy59%7W>%bS5e|oSl;KL;3_+F5zG33qq&@?sy-1CJj6aTOlpd zHTJXo%qS;pYZ6Wir-g`h$jwJ`T)2WO61JW^o_w|i$MFdK zu6FmkvO-`j-mZ}9Kre~42MHl!5^@&w$Rl&@Zif%0Pr1pUl^ki zysxpE{`R{YV?;+cJI0&vpoeJKOk1QiRxpkw7T6tJUsomlsn(Ibwg1x;G&^{{iNkl4tNQ Xa|$OU_OVe100000NkvXXu0mjfJ-;_% diff --git a/docs/html/img164.png b/docs/html/img164.png index 73fe83b67b58ea611fa9a759900c012d770a0b81..0e6a371eec594323f07f8742068ebb3a9823c047 100644 GIT binary patch literal 966 zcmV;%13CPOP)DCFU+Y@b3TQv%I@5M>%q-`X)>e+Yq zzWd(g?p_UykU&7d3=moY0#c`G#iT5sR{%{I!XecaSwOfwfHR6#iUt?9&Dx<253mjC zF45bLFd=E~=z&Q+>OrwEDTVO-ej23}hh``aDSmK-#O0?|0YkELe zKVkUDQBqegJL%7Jn3IAZc9{;Xj6o05%3{vp+UcRl(Vvzh9NBK##vcQO*sJG+^OF#M zn9XsKe2EZUCZSn68>H3eQcR_XdET3(Ft**C?NP@FvFB;BO%$BgF+*LCCHduo9~P70 z3Jm?=F(tgs3f={z(P;)pk zH-Wa__A@r)DB@8Tg#v-8r)@t+K~Yz!;x3F25tHkf-{?Ww9qh;+W;=54N{4XF6wu{y zDaz`ELMBPU0TffgqZW6WT7ffx7L6GV1GSlaIbAYQ=L=+0PHAQ;@pLGrXg=s_+v);H zxyw4=P(6&=s=8z&W*Y-tFR_oP;*|QwAy3AWYsrmKunuM$&?YhGcJQ*(*1L!||Mm#uo&PL4h ozsc_95E5&w8~LAPeH@UFzu{^L01(`M&j0`b07*qoM6N<$f?5^Jv;Y7A literal 1156 zcmV-~1bh35P)!pL*Va_^+_U#_oYZ9<_3wmhoI%tMm$g=lREQ6qyXEx**81}q|cP?8|tAH!d@jcdRlDXGTR)~Y1a zWa$4oqRiz9T2k7f;1?s~bBe*R){MmNkqh6~3*j`K+7wP780`#A_H1&F)>;5nn8O|& zJ5q`^LM%^Iar*X%+Tm9S@;)4(LM00kb(T^gbmDQxQ6k?H(_GiGZIe5xR1bEAfl`)a z)V{9Lo8uy=TZfXI;O{!r0BGcITir?Wr7R@V$JPp8qx?{5Di=dm(edyWjg8bNZ!K|l z?0?xL_7eVGw(&=&4MnG_T_$mE3Y1s1jfvZwMxm(tDoyrz7A;wo?opF#89Go7-AqQE zT&rkQghL$}YdBOYamPY;?2$|DT{bI_m)Jc_KUS6CenC&KpHZb}>GA4Mq@_@cMevM# ziA5rmNDPwD6R%WhLo){)V=`*>)1gGrMashwJzjZ>LsVdzm~d62(3go=Zlzy5;RI{R!=~BM>YKpJ(pPdk8#%NXc{n+{rZQ`wh)QV_b#+c`U zn=+~2J*_Rwoh;&|4{;uNqF`FyOK|EmH+&&2XV;>`;hrc2uB5cFN<3E4+7#8pP2jmd z9VCl-w6k~RfemAK^Ra^)foL&zaOd;$`0K0pQ9XA7t;@1;PiOb(%&WbDo4wcRq)Xin z4eHxZ(nU_~AwHhRd#J8pUA{(Vuz9VofpMZPxvvP(y3G;qD{Onc1YqV#>sF8_*;`NV z6RfoV0rl7y^KTYyx@F&`uxL$i7gs=El`4uyHV}wN_zv?SuIBK7j>5b8&C<^nz4ZFQ z4MAt5!Ug}Xr}mn~Kk_Qw6(WopMpW4&Q4uJ#C#F1%%;TlFz>(SL`dcLJYbUKa(5T~3MZt?8c(h;-aTjD7JnlvZ za>{Ky>M0{140@Px=~kVPrIi$c<>TrM;7szzN!c3B*aTSw6s=KQv zJrfoD3_V@--+!-O)$g7Jpd3MQkSI_?ffqQVp#*5bsEc<3l$t7aV}W3!rBCoGK_Xg+ zKqScF0sLw(hGVH^#$E-NomX_*ZWouk&}J4rN7uf{vuTivOtUxUI4DF+X1pSq8-nS} zNy#5_j-`UOVBt(-6`V8T8Yok$u7v_bswEU{*!7&w2XdX}%zf*aUD`tnvaE#)ZCXKL zQvilJRa1X;%y8g*0n|4JPG!NFjT&=UnHt2Y5&bg|Q37xtj|Yo*NJB_4XI6C{uZoOB zdLDv7S|yJ*Wjv_YL5@W~Nmfmw7wc-A@~8vB^HYUKBWi*w^b!Q~Di}vf`00>X6)JPf z!fFk=<_u+PiHaoRIjuz_T*~kWp%S4iJL=eK=_zV^6xCBRLg?KnMq0*HbW*!A-JY8H zXL%d`C2>xe=9cb5r1FhuI`F3bs+oy&V{p;K?KW2v`;cV9IifR3p!B+!EvlHGDI*w- zy=5!f>(v+W>j+y+jy<3HYuU0NVRwp*3{$rA3u(aB|wAM~+3u5ucnePcn<5NEe-A&uvhH_6u9D z@7wg&N@>*3(;BJly<1`DQhUp4exA0k!E|n`$1wHSl)J0ysS=gx(1AS$_{+ZN#2Q{2 zYZZ(?Kf+6G`nlh%z*96fsz*9rxQ+z0ic7`&vN~thk-7QF$xirpJ|CFNML|A4owJZR zFWAy9XWEsTr4SW9lbk$*_yh3o-;O}+yaZ*Ro4dFnSGIZ3Si73QyIY9{`ggCO&j6vi zE|-3+k--BjdvV=0iko{Pn~$(lm{~&Yhg}D7yxyV1#8r^e$;xf4KRxbn!Q1ckHETia z`{#=S7Dcj1!{q436nzGFAc&yRZ>f^c6ME(+(Ed)l23Q=yt_I%W^9)f%*X1$M$MG>G z%lnOE{B#X7WhYYrO~6W`N7xVGKo^8kvpVo!iodW1#j<7{A}czhMFYIq_x_mbTlVP} zeH!40?6Z;Bx(j@=i2GxteI6KQZAz5@nNQGr;{OKShzr})>-v6sNpL(8(4eDyV)?p%#ve}7->-NSC$j5RQLW$PPM7@0Z@HYqSj@)lM0{;L2 N002ovPDHLkV1g-mUU2{b literal 373 zcmV-*0gC>KP)SU;qMs5g?Jo00+`63=9eh49I{dfCY)S8w56>C`e%V z_dke%fstctCxZdQ2L%*Khz15UfKc;5L4k*rnThEG*dPXm21azXq=N!Xi`Wi4VQ}XV z=W_$HFFayUn83(a?*Mc%H$y=|!j}UK416F}1_mJV9}sKuqWY0Eup17@(A)i T@r?7`00000NkvXXu0mjf(5!a*+pazd5*7j?9@9q^#5oDs%a%JPBq2k5 zud2Gc`e!Ctb{{k8davI5-dC^c)pP(#;uj5(0KO4J)RG!wWIDbi;KTC(oJ@b0LCP{k z&hu~(01Uw8G8;$!ipu4j2Wu+va3@O2I25{SDF)Kuoc*kO;Ax z25~4zed5Y0r9o7QtEh&Qw3(q-uaaquW={w{0*@5FEvJOdC58S*5fd!1&o z*B!CvHgsufHBYWyfN){~A@V@Pq#lTliJa9gBVaLWp}O%1$*4pf2WCL-9P)4k?uww3 zDpDSVh158Y&{c-n4II6s$LQ`ks^+$hJTR{i$fGN#CkiW?9dT{0j)8Nb)r!?%Z&E0Vb2Ag@xb#r=wl1<0SlsNR(lE@ z)%0>lVXs%$_C3#&S&;{|7Pck0-=y`B*}?ieP%X7B5aA7xB!ab3jt6x{j>k5&(8pVd z!`DX2zVEM%8tM8uuiw{WW+yya$Hb%OPj^Jhqec5Y-BPVB2EI#1mhiy7Oxv_It$2v6 zCt=_tkBvvf16y9T8kfz_5+1Cn4uj-@d1tU5*y8il5P`90G#DifaENKBZ=%1- zXP~XZv}+P3gHnhfJ4ea&A7{S^V4FHhBy-fhb#WIXX# z!z<`RBl{_2lH)k?Qlcz<>gV*qxp%_{w)A4L8W(S1z|nJyN*$|d*x$6X^0&0l--6@aVPBk5=g?m2GR4+3@x9$l?pSMsZS`L=Z85}(a2;It%% z0n5){P^h_T{CSUT)~jM@P7s431;2m1Zu%!ML=5xD^jHnK7=SO~GjM&V2l%#^uSSnv zGKSE8Al3FyQ@o+dI8DYu@F{GY3H5wq3sy>7NBWT7(-Zj82C8WMNc>&$Rpcn( zjzTp7FGR{#6Q2|l$>80k+^wWx(zWUZ-BK$#z-pj;5ZM2fIz`fTR5jpi_p8vT215Xp zI$}8gz>Hs64dqy_hN^s0jr`4HR0DM75^}m41;8(q&3Q1Nx9i|8+%4F3HJJ7hsv1%j z!M%6@@b1#$_i(ra@+;+V$9pJXf9Z@5o12^XpIFd}f&I9O-w2%FLOfj8(G7_>Z|~m? z!MmU2!}-G$~e9kpJ2fE;oF0000@h%<6GBNeh_iJS$ zqOSL!@R`dJJVF$p?fzqwEGejCt*z&=1xv*&N?AZifXNJ%4ynFkLhQ3mK+@JuhNzh- z%6{sJ8;J~z#?(pQeV+&)L*x2$B2jPlP$$-oDMYQIQK`R{c?^2Zoj|&o68-?AvpIvi zebnucofW+jeQCI9$-qc|N;w?3ieBNID|F+?Ygtq2p#K0b@Jzbk9lvtqX&c10L}$o+ z9ckw*jbBR8Jrq%ck_0ojV9=6k?}>P{$`2>KJh%T0af13;m-w)Do7Y|1u{H7hH{JOU Zd;ne6G@J;|9@_u_002ovPDHLkV1g(i!o&ao diff --git a/docs/html/img167.png b/docs/html/img167.png index 0c441a4406839785dbd542469ff4d22966008c43..e06c9ae88e5088ede7216fd59860f6c7643af045 100644 GIT binary patch literal 1126 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 Ai~s-t literal 678 zcmV;X0$KfuP)cfv2Kb~QDEuH!2%LXD|KVZ zR0*M$RO;5{#6%?|QY54fMcl~H;kv*;2O}|LV2GgV)T$X68Lq0-c7i@T+;L|(2NE*y zN%7hK-tYPBvtxjSIE^YFMHz-nJmy7l5XXQju2f7x?RuhGyb_E$RFfPsKk6XoA1<@K z8x5m+9n$GAo?Vyw4)mf~j_U@o0X#6rWQ!)lC{IyDX_rpZZ8iR8;u6XxIk)P1KPdWI zUrbN><58dS@)a0r;8XmyM;qSj7MNiz4n~r8Rt3vS*mVE7>HJWpsZ~?QFOl!mYGwN( ze_oSd@Zy8A^MR+O8Ps&POY~!#di!BZ+VO`ry*0n85(b`xrKPP}1==jMRF{Zz^6iHo zOhSNz;TCZmmheXa@bt8*HmrplqN7Zcel@>Nex;I9E7=-WUt7DI&@L6UHbJ{y&$Qty zmgQ_4m1}72doLbu8`^De4}!K=&$oN0t+Rf{hGsvsh16!dpH+J>duMBI?5k1s39!b_ z@XFEn28e@-3e}i2`x~aG{<>#yfLF|7r6#ZSf}4yi?4^ZW0wX0000mP)t-s|NsA) znVDr}WkW+l?(Xg(AtB7n%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001 zbW%=J06^y0W&i*H{z*hZR5*=eV1NQnD1Cqd6)1p7uA&PJSOM#Mh7#;DsDKf{WJYj7 zOoj^vml|M>$b<-y1F&g?it#Tf2%KBV_3IYM6Y~W47$yLrfc*z%1_6TxMlAZUiBSq1 zu!v2-EynR(08^cSxe;fHl;kHQF*acM39xd5eae3lDEffm0T*w9K?5tJWCIJb!TfKz z$`}$ZBw(?#jd*ViBEa8lK$JR8vXs@%arjD%X>S>3GW@&W62fqYp^HJ0p#e!5KQNAd zGJr9M0{?-A&md9e30$(J*Ap19W++|;1{a3U3@lF=t~#*n^ivz+Axp{Q-)C-Ee>`%8kn8*#KoS zF*0~FFbWW`6vf;PI23T>6THC4ouHsFApt|$z#yZI2-~R!6i8Ffxd4mch5&vIhAvi4 z2#*OECkhM`egZwS;TpP94u*yY0oV*?BF!D-g58*a6zv8?s>78g@T+4Hy7*Ip2zC5? z9~c8J?@(oE{MevvtF1770SPdT>udy!0h$OAIdhz3;u5 z-T7lSH9z*v&iD8CeQ&;byTAl>6c8&ci5B(|vX}sYgg~<37d`WsBS#hLggq!J0YM8= zDOv3=$|^-Gn27CmMHuNqd+V9A{RTs-qfh3`mF;qK*;>I!*YfHB6wAzq*M^(~&ihVJNsO z4LwF=zwc44iaC0RY+;;wrgm#!@bzM+DfbcKR6RGaIZ zMk!-9R9!uWN(iEI%5$EF-z_L~)%nRSP2+zIHf`X8A(`#M=$ABh>_c9CqR`a6#f#S-ejf77%JsM230bwj+r@=bCwXzeiCc0> z8=S9pzWn{OMC)l6A6t%bZj}o5biVH%nJ!&^kNTMtF}%+&gB_=nZqQ&WUDLUFgy zRABt}vZmZW(Ceo@9Dvim7-#2{e+iSOBsE2-o2E`zHpLYASKlP)#Z+B%(Gn*?X#WFawW5=qTwF3M zqB!YRMI6MTD!7Q)!BxoMro-VRh*$@9R(z6I{u;y|Xv-qAg>?>~vJa`RTGEgXk4oK6e8xZsL`AlQofZP--+f1|P zg%RjIRhji{vA{rOTNLI@+@{0zePwh^ zV4$ZjmVi>I#_T}WV+!oEJ-86}CYI>0J_T{uKgmS{rDS7m{AH#D^{uUGxo}ZCy;wnl zRFP|vJ_4&BI%q6*?IACMX0q_8Rlc6|1aCEAp0LCeoU{LL*LF3 t0%J`9*lsi5Ubwx4n+x(Y0iW9m`vlU(itmRtOxged002ovPDHLkV1j)~CPx4O diff --git a/docs/html/img171.png b/docs/html/img171.png index cbcd172629a6c66045b415b0ecdd4109eef8c923..341e3e5713ef5dc8d6007168e95458db7530e4dc 100644 GIT binary patch literal 356 zcmV-q0h|7bP)k7R49>SU;qLp5OIwG4pbQh7#JonAOqHL28Is|cmQLim{J-8 z16xce149B35&_`m@h@mN@RRu$2V*Xfv(VuSvpAOsM*&oh7?TKq15lb%+;fQ}=fo1u z1_lNJdj?K+M&^JC3~UU-3<)0+7&kC5a1}8(_y;UkkQZQJ1*+dLApmBC3l*F}3Sh-5 zIul*s?_>udhAj;LlNn}$m~2NN(e{=>ixbF*1xf*#+5f>I&0)Z3!0jNwZ@@VL#Pnuh zX#k4y-Ms*cFkUu42QbqOq?CVY1K4=a8xvqmdIJE3Ff&JR=CcU^0000`D+oZ3}+V&0`{hdF0|#IUe2=uVYfxSKz1 Q63`w7Pgg&ebxsLQ0NXE3yZ`_I diff --git a/docs/html/img172.png b/docs/html/img172.png index 881b68af772a0f2aaeeb0d9e4260ed08bfe17371..7054de7420ff505ab67b2a279c340b55d7248cd4 100644 GIT binary patch literal 440 zcmV;p0Z0CcP)sd#O3liEREdp+3@mJ!nRtZmW$4O8 z9>Ee4q7oI%OdSwwyL1m@>C#8YiWuPRR8XMmK;gIUZ0Bs>|K9~Xv=V3dib*E!kngCY zOa0^PDjH(#HkuX$afF)%8CkaR-YQ}lj2aX*<&s6T2~gOwg@v44H)WBkkpAZ-QLvfW zuaUT%qRP`S*nY<>Nk%R_s)u-1B6Y_wGD4mOi$G(wY~A5g*#>pdkoG@Fme4hXD~Tja z@jnu_M{s#9Hpn`ghXIgqU{Yc@z`&rubqiTB2T4Zb1x!$y5lZtiK)lYx4HZ!EW#9r* z4;U1{Tuumekg0a&2TtlagKTgcO0%Mgb3y6f5Q=wU1BBr@0YZB-2!ce|HZVX06#T&y z6FVg#{U~vZ?U`T;9I6%Wb!vRDx7O?6FB`AP(e!y_sTJpR!tUx*% zUmL&jgQ#4_-^iiL$)ivKW_(go0>upj#}kIVNbxB2b4RasB#JDo>`vweHJ%~^=3Wx&$ XLsc#;=ziLL00000NkvXXu0mjf(;1&5 diff --git a/docs/html/img173.png b/docs/html/img173.png index e803c83496e7973d6cae4b1d447a187c73fcbd6d..076f48e56c0de68839a331de4a49c664cb166e93 100644 GIT binary patch literal 302 zcmV+}0nz@6P)~5D>e&yC0vO-~a#s0d!JM zQvg8b*k%9#0Ix|zK~yM_V_*OQjsymDAOXZIXksi^F_d8d0|qWG0|tf$28II*z!VvP z1Bm%1Byce?#Jzg}<}obLn5p@q_|~cR*(VIjjr^ z92{UWoIDA$48WY;1q>j$K@OfP;go6ulR4c6PxwwKa|vL`Fx+A2VBkH#IDr8eAwYnT zVHe=rP*B9M2-7qk1_on>J7;j%_|lymFVGqQ05iWP*Ko_$lmGw#07*qoM6N<$g2y&% Ang9R* literal 2452 zcmV;F32XL=P)yK(0000mP)t-s|NsA) znVENYcU4tY?(Xh0Gc(N0%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0BD=f09~~i;00001 zbW%=J06^y0W&i*Q5=lfsRA_cXF%2J;Dx^^W zsVRlJp%i{lrxE?A_^692Bpx5Lu7D^!)*wWw5M+t^5mYKJR)yLwD;rc$140b&fz%bj zL;^*8z{HSHx(^;qpm)uZ6FJ!^R z2p1R{A#Su>qG^y4C2~SSDQj9tUf{wc%jCRI(V#5@+%8T}N90(}1QXCjlri&Yj$@LI z$VwJ{^u-H<)6pLIa9MQ8`cR>cqO}rG8LaU za5X_zFu@kZ`Wq)7DAydkf1A)$NF_Z_6(#8ExUGt$x7U{pbr<)8+-7(+)* zGKXpvQ=(2(NqY=rwTUsCAOoz!RvyKK=xkuk#F#f=)l(5k(V_0az?e~yk9E{`^?^s0 zk;BYGO^nOgFj!-$;~Nt{p1-T=TiAdf@eD!ge2$=`Z;J^*r7>=$>~X7YpwlW{jaUDx zpibGL@;cfW!kC^=%#y$i1bcOBvZ=X1jx3fmlvoE>6BFB4da&!=Op#fVQBnD^3Z!AR ztQH|V(1P1)wt$LTQa)7epTIg)LM35@DDyJBo*IV7qn*HUpEsr9 zXkS%7rpWY5YK(3Luw1X3#PstRTL_7xrVEhM40D{9$5z(_?40ha7+J1w6>3@|n`HS( zvP&nxvyAlt4%rH zp`#!69mk6)RL@{a9!_;`1KIp<=gH3g?HHmi$yy}cR9V54CksGHE0vtWD3WE`w-@Wb(z;aIjKh^U! zP3C`x^uPJ+lfmOnVl|fc0o?pH_6R=zq2?#**4#f#m437>n99sDA|N+p1`i%|gP2jS93-~v1Z_~Anl3zV&vDDagPoi%AwL^ zZJB4o=%llrAx5%ep8W@uor3N+9!jl36^nk)kq_aLCSHFY?f|rg@NIf*9}}@}cT*8} zzTxVnZT~q?tQWxO0=((-5WO;qB6ev|M0hS0vH2*qjDr!=3|>gA_9HI5HcD~XS9EJD z1Epx|sA*Dmh*pm4@!3TCK*Xp(2f)M9eICl3#%I9S>^^t^e%T6OC3y?`>0d^xE33E~apmgw! zd=)YuxO@yvzBf{Dku_F1pnU*_y|lTEyMS2P$E`mJ&3dxp0pGU>*{@!tv=iyb`qB@8 z>?qn}l_qR%Zo=Z)p{kRj6h*?|tcc$a{x^c$F3YAFeeN-2b!(dj;Fun_OMQ*#2qHE%eYj zd32a{`WDQj6{Y&&_`!G{JMY5p+voFV7}|cym8p*c(?LaAN?5OudVs0}j z$Q?^wBS?L?d7NIw6rFPb=Ym9M)VP#{fk(oH<1v{z#s=`qLVf$Js^Yeh>k+F<&r2VR z1R=3h{nmjtMS1g`^P!9 z4f}VHbU5ve8a=feroG(R#ortTP8FUsX1Gw7rG8zb1^bqWx%v?Ep+w}@m%1~ zPoKn^z@(ZsmLBJDf>zU;Wo?gOPk4bf=8vdJtbLgDs-iiDM&0lPLkd=>oBAg_{7vN_ S(1}<80000SB!r*WZG zk+{Up`Oe>c@6Pw$a{vw$mH+;9EUxMN*Vg3rZ4H3L)u5tVv07p0nI@iyun{+Z$fQV% zi)o_)?x=|CLYW|&l_ZU&M2J_923X2PTZKZF%gU~j_2v7ZsCz-si*=>mpo)B@+hvzk zsmAqoBmx$#Ls49t%vH3(1TtlH1W;uS&r@%yYo^nc4)}LP?&KH{vmock6yQm248TM; zMiYwkPy%U?FuILpCs480K&yM;akD|Y$j2UKMXg3gY*XG`=Rx|WKO( zj6uzI20Nk7r&Wqk7{=TUeIVr_86fj~sI7bEK#)D46LeoI{(u(L@B`D+ z)&Uq3M;bt}sN90_N`>!OB7-WQq0v6V<|tMXXK@uLwLWS#l93FWx)xYq35*e~K;W9< z9;b_ah?UDtUO5aqYBPrwJfh*g%OuOt5(((MMN8E=?T%S$s9(d@he>C!r<(OwSk+N#&1 zXsaucQO>)Y(^iQaD%k>s`PgB^PT;w(=VZZZ`RxTo$4Gjj(>hif;Xq^No7Qp3Z+$58 UY+D1Ud;kCd07*qoM6N<$f*p+2&j0`b literal 449 zcmV;y0Y3hTP)^vp^FF(eT3lP zpi4#{!7)Pz7a@y_Q|J?jgOgx!aOmXf))x>w=a!-!3awD^59i*S^PiJ@{y(5F2}_|u zDr?!RE>{i>Q^a0ahPV@LEX!#+wcl9<{i?}b`gM{R9o9LZ4>#b-Q

y-bp<&PZHi- zZw}##*Zlz#eC!*(cA=Y`G}lw`Anv}G0cO<-W& zDMzCCozRNWdIYTnFM<$uqjn3%QKyH=t>EsIZweWjYw#brm-kmLv1U1`<##xRSQKw0 zCk3kgdCE(@;!}V1&>rK2x2S84o&{Uh<70^dSE)VCIA#39C%vZe&>6_K9o>Gx9z??~ rm2iQgT4J}eg_2vk`00`c{bPIs@KQOWgNMoi00000NkvXXu0mjfO{B&g diff --git a/docs/html/img175.png b/docs/html/img175.png new file mode 100644 index 0000000000000000000000000000000000000000..ff19444e706cf2eb24757dc49f2f107c7b71c313 GIT binary patch literal 719 zcmV;=0xsC8_$pbjaBG{5 zjd1wEDi$IZ*}cLxaD{Fm=HM*swh@FAyu!jp3>Jcj;y)k+1V0Kn=OvqLHf~E2i{bLup$fK6i`gL}0jxt0MZuwoQLb%SnD@Uv{-(#A3NfS-N4 zh_?B;9Su9qLrl@9AJ*6Nd;TOBO5<>YCZmJSeDB#nz6I`?H;wOw)bjJ%SW=i^oMFhs z@0G)Ahv4rO>zKm|u{Bl-gTZ$@<*+cd|3tD+0R3UDUd@5o`l(S+pB-(JzEGE~_2X4d zwn>9=>-9mpCf}&V4ziw`8QYq;1uyL-?!R|7n{?6BgiC~_qD{hBUuDLxEp`MuQh+P_ z5n5z!g?Z1l-9;f&yUUUwFZO{iIElN@8O}rX#$+5<7t@Y6SEuOdj^tc-O$v98KEz0_ zyinJqi}{g@3+EkBU9>)u`#Zr#oHi)3(0LlU)@>Gt`?#-BH1U^Q{U8Kf5nH8 zl!ZwhwsG5!Gv8R5oEA*#)9$mC*|SLv>UHg}G)5G<7Y2ZVHj7eT|p#k1iaKToI;{Clma!XrmERjxcpi z4%_IT?xlfqGTa7srUsY?M)A~*mEXmN8fyVvC>N5xPETFVCUv@Lw*`ewN@?w^`1GYY z1bo>PGCp`^43Fk#Gl1TR;iY5j_7AW;bx2S5dEi}jp!OJo(XcI=T4L8ioU%5Z{Yl4o zOJ}YF$DX1oh>BAs4MkOG#s4jA*%W}wrZS=B^Ad$UM6(ID8kXeHEK9Q1O9=AtYu*!U zIml5B8@RT5!g-3W&&>S1DfaYuXz^#*qMOqN+U?2E--$%|9Bt6q31Fq+;x;)DyTD`p zp7w3RZJZ#`$VSc*a?p%(EQH@FCLnYp_&fQkQi2Mf2u-Ir1VXxBu2o2g-%K;F=zj-A z)}vIc?9V9l_fIaSVCuAQmlw+6y0oe)Yy$V+ExMAmyOkAm>8Fn=7y~!MYrcj5a9ut7 zi9e#=Kw!!@gk%qrFO6G{_H*4ih9L`Z^MD+_0!!fpbvq9lHJ6=4=*@v}TETbr(yY$>rmWV1){4GB3Q6bjeLU zvlbL8l!M$NI!{CTpC+?Ye_utR*#+}WE=&W1DhhP1n4KtKb#8&Q_>Emhm|wPE&8-k< c)6BnuU)`gWXAS~8UjP6A07*qoM6N<$f-<#MyZ`_I literal 0 HcmV?d00001 diff --git a/docs/html/img177.png b/docs/html/img177.png new file mode 100644 index 0000000000000000000000000000000000000000..4c5ed5a3b67076a96708ce4d093493416de2bd38 GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9b!py+HsI*Z~9mvrQ@CkAK|NsBYnKM&UQ=Ofi z-@SXMsHk}6%$ZfIR&{iAl$Di*goFSU8W|bgy?b}}?%k8>W%Yo3#*!evUo;8U@udIO1Q;zObRvZ#md}!M<`!n0hnUsWDzp}F$ACr0~FZ) z{|9>SGaElB1lSlj85oR>4HyhIfTbt!F$i3k07?{G5cM;_B+~@xU-AxMBeBE>j>I#p zzy-Xrny6fk{rD8~Zb0Qv*onlcoy=jt0!o@QK>)~LTEHoQB=5;!1k5y+tO;O63~$lQ zzRkeXzyOS4P?`qDZvTH}1_l^{gIxy&#ViPy`(P|Z-qG=USM2$%^O)RC=b kNWt`q0~@-cQ9u>|04C%+zVV!Z07*qoM6N<$g0ID|aR2}S literal 0 HcmV?d00001 diff --git a/docs/html/img179.png b/docs/html/img179.png new file mode 100644 index 0000000000000000000000000000000000000000..1c7be3b530da9843ffb23e52ee93b39777e31ced GIT binary patch literal 2571 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 T(xjOU00000NkvXXu0mjfQtsI5 literal 0 HcmV?d00001 diff --git a/docs/html/img181.png b/docs/html/img181.png new file mode 100644 index 0000000000000000000000000000000000000000..8ed7190c36909f2a0472946d7c53af2810264194 GIT binary patch literal 480 zcmV<60U!Q}P)G7LLK}`IBPm|=zILT`~ThJ-#{`6aE$DDPp-Cx8%R9U*lr|1#I@Jt366sYR z0-ZUV+JABZ0000mP)t-s|NsA) znVDr}WkW+l?(Xg(AtB7n%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001 zbW%=J06^y0W&i*IPf0{UR5*=eV1R(b#SogG0R<$4u|XIgP{sKfI2afhH?Sm!Pe9Yb zup0(8Ad9jGfXD_0W}s2N3@kwQ1R#^0!y!QcA_@Wb(d;2;E)w8GFc}3Hz-B&}z;Izg zz=j138xUd%47@;s1?&bYfZdpYc+Ce8OfDeiHvq9FAOx8qTz-QMmHq`E4g@qz1q!f2 zlw6p=$H~U#Ai#o9$K~M2#Lb$<&#;ISY#zj@1dvw~E?h{!>IDA(--vfFg#cSvQ51gc z3Haq%1fUH51K4CI6+jrA;BaS@WS_dyq3L6#So;D7wuwayERD;GFMt(Di6E4Hn91;m zfuBo&{QyH4Lm)#F0~<1Fe*%(q8cnUZtV?M(x(fAMkle^W=cNDxZcsTB2=Ir&umo6A4Hf_Z&i|QLrow*J00000NkvXX Hu0mjf&*it# literal 0 HcmV?d00001 diff --git a/docs/html/img183.png b/docs/html/img183.png new file mode 100644 index 0000000000000000000000000000000000000000..045d4f07c0b632cb0b2f4474dbe1a7560870d9b4 GIT binary patch literal 345 zcmV-f0jB zLkeRG!+r(^E(b>@hJ+6Z92*=U?q=g28U6!U1Q{jSr>=Bp`XR-@HnE6- zccM5$rUb}@4>KA5Fz|B;Ffar%G%*-5++`KWyZ|!(K!Q0NLn_d;0EV~uz~K4~F^98* r!M=rIA&{kBc)Vc7cLB!!LIwr^M3F5CnKP?attu-k3keAUsxmS%x_kHT?%lilTf=REe8!R>zhDN3XE)M-oHS1t z#}JO0$q5b3tPW?Y7(F)lCO9xE7>a4k{>b2Csz1TN%q$_IfF;!Qu%kw80`rVVtkOIS zEqijKE0@6Gj2-~`5f_%iId@w XsAxZD{K?fo8yP%Z{an^LB{Ts5U8hUu literal 0 HcmV?d00001 diff --git a/docs/html/img185.png b/docs/html/img185.png new file mode 100644 index 0000000000000000000000000000000000000000..0cd52618141d931f1091509d53abed697a4b824d GIT binary patch literal 452 zcmV;#0XzPQP)2Tq0w3|K(|11=dbFkoQZz`)1?W}~XxjQ}X( z>;X^)KLf)D-?p+j6J~-nvU4zpIyB(13Ju^g9|dq?h=A;RFoEF$Hy1ZU{s*uS+yDPy z;RFU=1_lR)1Qy~QL55?AayNEx07Hbs07PO&5Kx%kU_&J{4=WFI3IoH;ne$=73>PNw zF{Ci2Fzkn@{}QX0$J*X#|vhB u7hvo!#B{~aa}x>sYZTxH*fT%&BnklV*P{`#<)yv=0000R49>SU;qJL24-#sG>{>HE&>Eh2@H%4uQo6+uo)l(cSFDi zga|tWLjaiZ!N9=*NP0h|mh3xF0g0OcR>GVmOj02Je5;0N&&E&#>zdX$^Nfq~zAg293XKzA_;0Qo?{3lA8o9YF5= z3FdP-D6l0sI5IE@0t1B|qWc0v0?;oE;J~6aK=tkh3_d}?o`7BaqAZ#K{{bKY6J)&r z<}yk$H2sibV42>|K6Rx7P{30kEd85-VLy=iFq5APnDkiZUt#zI)yQawkY+!SkP4(k zSmGJX*&wnDL5AFB;N1eGI6D{?0;%~w3K;BLfD8|Hh!Jciw=NL&*N_Ff@qrBh*Clx= T>N8p~00000NkvXXu0mjfy^){r literal 0 HcmV?d00001 diff --git a/docs/html/img187.png b/docs/html/img187.png new file mode 100644 index 0000000000000000000000000000000000000000..45adb542d7c0e9bfd7bd5202624569ebca8357a7 GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^vOp}r!py+Hn6DC90^}G3_=LFr|NnpH%$cdFsm{*M z@7}#rR8%~3=FF;9t2#P5%F4<@LPCHFjf{-$-n}azAh3J)?!NB)&p;u@k|4ie28U-i z(tw<)o-U3d5>t~C7@8s^7M?C?Y@EBWfsv_#d!6wC24!X;fy5aME<8McSRIc1XVfs- z-;!8m$t-ptG7}`q$iwS!g7X4f5)C94ua8*Q!B zN-QJ;rmzvySqWPxVxwuTvPud&$I8UUwekIUB*ZDQ^)GT=mv4hFGlQ`UbYXk~JHsl&IL zXVVxFmO#|N0yzpa9;*DnJlHAmJ(FeuQXWbf>KfMbOkfxlSmpe+5}0er=gVN)9*f61 z*53m*u!UFZk7A*sJn42k^{4TR5ccKhGw<+^s?;~j&2`|`YxMoE9&}5^=3FsqtIWe- dc_OUQgYU-_T(3DLa7q9G002ovPDHLkV1g%r>3#qJ delta 449 zcmV;y0Y3hW1m**fFMoG;cU4tY?(Xh0Gc(N0%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0 zBD=f09~~i;00001bW%=J06^y0W&i*IWJyFpR5*>@Q@>BbKp1_cEw;4fIvF;R3Ac`p zH#q2E!s=jx{ssOC)x<#;5En;uGjSjeZYG48;lg5!1BnwOk$=eIpx<3BX(cwqgvFQZ zeLwp8?(X}pKnmk-!G{AbeG5NP4`CuCCqMTp#p$V`ma8JPzMl{z# zDg2GxAGH^T?Qxp*BD8+LPbKL<1KuhXSrxl9d`?FK?nP^w(7#%1 racHF;@Kj&VE{uX&ea~tyKuzNdD)&d3?neko00000NkvXXu0mjfcXiMV diff --git a/docs/html/img2.png b/docs/html/img2.png index ce374483e615394e990dec773625273263dfca43..bc1204e6210e28cc94f1e112ba88f8e8296a9bfa 100644 GIT binary patch literal 3875 zcmV+;58UvHP)$?IkNdMN(k6$jzR0nACr$hGtQ zkYjxvtIk#*oMhS~xz0dxk}W+_uQ#59V3MCK# zKyCtvWR=Hv1m(im!yBb;^Ko4pT#M5tMMJ61kh?a5Nf0eXxb zdiLFEh*QsW7|v_(D@iFwAy*FI?l=c={HuN0oPMpM-oYHp^%7}3nRtEc>Wq)3syf3k zb>&2=^milfSTwq&XkxwoZj4g-1_(}d-%hlhrO4rjGh>v(KM*7r!B_aOC4Ao?5e-6Z(u2i~;p1_g z*f~WDC3?>J{UNHyKtB@am9{d#EJ3q8YLMwMmPCtD?G)+BoU1|qUH(0I5@+;SESJT0`Mh@Zd`qTH+x;9}q8tDQ2;oF6X%N5`xvTiSDMfd^`+Ux? z6sjhsHZ&UM!gul=-9qk@LOH57o_8))-3q^LUDfQXn@QYbz>&r+NRXu73}v@JF~uzn z(VSvuES)U892fMy07vuCqJ{v*fwDe~gN5~>s_8OG7F7ju0!U<(JE<1yVyoBjWL|8U z#uL3x^?Y7$CFRHIx8{n!u;K2fsBs>ib5cQ_FkY{#+*R)7x)f%M7NlF3sujAo#G5Hv zXE#hP{n5RqeqIvCIhH|LJ>>g`VMweJ0S8WHD_R3U;Tx=ig;Dns57cNzO4%AOBknhe z?j)Qxc5pq#Ptc-#ScCz5;gr5m0o{B| zJ#3xMc(|ezfP+SCR9FKvS_euXstl?!_g6rDUh^|l)K5U7Lr=aQ^^;}MSsQgHF%Vji zuu36U5keI~?G5EzHBRaqaYOy=!`7R$KtU-%k0j$IS)gdE#afU^r{r8q&gGm_DK%K2 zm}}XV#H|)JP-}aFxZgTzEE2z_1p@dcnZXUpXa)abvj=$G0wFzWNl?zI8*}?9D$1Uk z9Z`b~@;C|CA_?FaIIv|F`Ua}}$LUyezWm%B)|%Xw)Bh9Oq(qKC+|mY-*d8PN6tcLB zuV_6+cV2Ve#p_p5T~aw;x~QCET>pxR>^Huyy5NM|F6m9QmTP*|i@BG|HN8o(Wwpn0 z=)B-mYI-ESG@BHe$F=mTp3Wlk=%v|&np$!#_aro#Rti9SnqKt+TzZXd5{l4>FQXjRdy+Xno1yjyqgrR%6k$SN>=q9Cw zbpa$Rz@}}=>8ikD<(40|Xm;hOS6(`i@?b6fbF-`kUXg{~6kKo8DLHT0=DjJ4OP>45 zV)PN?)`Ih$lr7`kQy_h`*F_$Kn6ytYjBnt^V9`%IcA+p3-V}Z!3guzn$49t-44dQj zqp(>ZjAn3s3#14Yk|Z%HB2`xFf49*%2%f2FEekRu2#=m5nR=v0Nnp1%cO#oNJOqB| zRts`V03T(ds(~y9_OJy-V`3BFwp2X%t~Yb zak{yro0Fk+V=;9jA6R6PS*^dOJo5Rf^N|ggh(lFnK z`3%YG@r4v13lC(KF)IKn)R_GbX8FulotMqd6G(DOZ~yF3OERX;xXrjFsYmN^r9dfQ z-6!;E)NA0n|JRkjwE6XoYV9lsk0j^S^O6l1pvNTv{;XF0N?fk`4bi8C05%|80SMqj z{H>jl%&Vq8pD!gdUts3GK!i6 zY6awh1^^^U0I1cVJWw;$^f;#^DfP5^(T;}}T4R>D)})E`11yvuCBjws-K6Iyv99Gb z+KN9b7lG zrOG1!u6q$W1cg7X3e74I&6^%WP^j>&cFg{WU!lj<*EL!#X0(cR%(NzlR{8TR;>JDs z8lD!U!sC)Id>n2NSX~}AA4CogLV?JZPF}*oH<(5CxS=zQqzeG9zzmq>*dm8};!<+o zs=Q-7&SPXtuDvBuOw)KdDJEO*WToj>=nroSZP4CpttR0P$Fsh|VRxITeS_kKpVVCv z-CJvi1jncffNI$3wdy!(AEuJM`m|g!ZcHgJ`~0pg&9J+VDFmt;9QH4oVNn8+EmdLw z-$1}dwgk#B^$n`Gl}5BX?JZ1>2!NX+!K!)@icOxNgc~D_5Y#B-D*O((`0kc|D1aZy z%DMoAfUYR^w~Ay@0x%7x3>wCVkX5d!F%bM{MIl!K0KeHXKCh*@oKw%`M5mOp zH~DL4&JtthmNemdTE5nf+O59Qx_o5rBc@PX`l*U}jMsAs1A z`oq97*rU_3-w{ukv5$^753hkY53hj%dAMAuG=T+H7q|XgzIhD89Rdr}^5ViF|Ht_m zp3=X?K)=!qCWmB}hyZ|Np=O5<0KPE_<*c+mj1TcA;2W3~pnNz9g7(|c*Dw?hc`D3z zqX4)F|NHm>0NW3UT+GCYZLR@?e*glac$|0}^Zf!BsWeiukdOsrye_I)b&*bGkxpgq zO_p26SjtJv>H2R|Sx~OEEHpORd|BMcw-p9I6uAo;|FGo|gX>n-KAwX2`0yHd^Y9w@ z>+;ZZ!gUWl=b{fBs~uW>_Akma75PYbf*0`U6h`O48J~&2u3qW@j&C{*=he~=HU`k@ zn6cg9_Z5(DzlqiEKkTObz8d19o;$ch!ILCUuk1vW2V37l6@^3j{CO#09-#4G$meT1oC0Wf)8Dm>;y4EqaMKyOlOjlz7 zSd&|+m&N}7bQ{Od*vtAAcFV@cr}LnWev&q%n)n9;fU0 z78_ynLrIl2rNu{JMIuZsq=rwI!vOgF{_r^7JiG?pJiG=T(XGzV%iBFOe7zqac*ZZu z>?n;kP42#i_=5eRGZQ^|c&X*V7nDP1ym@#Hym{EeSIAw3nT4GJP(Bd2fPZkMFGc0c zv5zq*29v|gPau5b?kB~Iygd0WqK#eT0BSJ?!$3Tg#)LU+SqgV|v_t&wi5JakkxRD( zYB7exAPZlfBuTv?iL_dEEGBZdmMXa}NXqF+j0aZLE-~mfUMY;*c!PY07*{hNF8*W5 z#>xDxTVDfj9$o`Ic^Jvrp&$CnVLT?f&k!F_lH(kK=rPBAupk3V;{^w+CsBC&YrF>D z{u+b8nqtxX6B{k@0&U4H>_aTP0uKPNKSkgq2tpIVIwc&Nx0~_33J-g?3;|JW0GHzE zyKxUMz=Jh5F|fJG%j)Cru~c(z^|V zm^!TPYH53`T1$}4^*xG~rGqac>Fc-rs8hP_#EL``g)(v zxA+jX``K1MDx=cG-`(aI?IH9cn;{4n0*Ig&LAm*sh2`d37DD}|7b_%b2@yuni#>^% zpM>f+y;vRNn$-1;`k{>#Nm@eS?DEr;*RJpK^t~8YHaCwCl3NtA&>+`qDP@*T)&;Z4 zx*(ZKk3>N)t-?ssTWif-*hySZlhBm1ihm}DV)e%|g2@B>TOpiO2;u(_%9xF*$AFW% zDoLskCl$i#Fj?)=-H=33eq;jJTXx8W!Xg(6u%@(t1k9<`Cw%P9zWfmPWKJOggSs3v z$rRe#9xKq(#WK_0UJkn$1WD{dK$4j^Nxf46HOS$v?6Pg4^}3CePvh5lNaq{9lq`04 z7;FosQ~4iQ%1N9~WpRvAU3pNQ6p67dsMmU(Rp}n#VeNUX8fq>+x_3po^hFxh73p;R+YN2%@;35jw6VPxd5KG3q+wl= zgkI!85bns#{N#k<9kk)0=8AOiMH<)@$=`k}_dnxOc|)~EoBrTV(%sFNmD8sZlN#`G3#xa}8M<;amU!002ovPDHLkV1gL*aee>* literal 3108 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 N@O1TaS?83{1OVF`Ov(TN literal 231 zcmeAS@N?(olHy`uVBq!ia0vp@KrF|?%)r1{)UfjnkYf+|NogYXO@?jhlYl} zd-u-R*!awuGlGJGt5&V*=;%mGO9Lu&adEkO_pXwX((c{6ef%(D=}S zfti{6f(aiR+qV20SKqcpck`ame;~pT^rwbtyR5^X?>ue^g$I}EDs(MwP;Xq|z2O!o bi!=k1y_jR{v$iQf3mH6J{an^LB{Ts5kk(LK diff --git a/docs/html/img22.png b/docs/html/img22.png index 6a7336dd74bd2b9988e0067617cb07afa1f14f3b..19b9986cb72d46b8b616c27a4cd22e33c3cfb9af 100644 GIT binary patch delta 190 zcmX@fc$RU3cs(BrGXn$TtVD(q1_lPL0G|-o|NsBboH^6k+4bW$Y(4G@(X5gcy=QV$O-gxaSY*@nVgXDAR!?^ zfFX(P8v~n$M?!*dgAqTI8W4$S;_|;n@w4ysxK=V+hC0}(nZ2@iZ5jLu3qXst6yU@%Q)W7BK9$-^^;$5>cG;>Npq$3mFc&v;8{-Dvo7 mj+@7vwPDLjMrT!KW`?(RTzNY$N=E=qX7F_Nb6Mw<&;$UZFG7+4 diff --git a/docs/html/img23.png b/docs/html/img23.png index 8820cddeaedb8247cf2defa7392439ca2c3372c6..fa052e10ea7440384e5b93e542e7d532ff8de777 100644 GIT binary patch literal 225 zcmeAS@N?(olHy`uVBq!ia0vp@KrF|?%)r1{)UfjnkfR>p6XN>+|Nqp~RA*=BckkXQ zDk`2ib7s}5RUI82Wo2a{At5to&b)i~?(W^Y@A%%|4b;L|666=m;PC858jzFW>Eak7 zF*P|M;Xz760|Q5CLt{H5V}!KCj)p62GjxO!(inwU-#9E<#^5Z(w?n9*tKkbLqr$}l z2TnaWaA4lSh9q`70p5+P8XP5EHX9e1HoRbBTgEFeOEAUkH&Ywe1{33mDUAKa9~c;{ Xzwq3zP~UbCXeWcGtDnm{r-UW|Vun*5 literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^d_XM6!py+HICDGGdmu+Ez$e7@|NsBx<>jHFq3_x+&MmUI+Gd8o_P~|zprBJ2M+^pYmEiFNdA+jdX_{hSPn~V$% XzTC=BpB>TxTFBt(>gTe~DWM4f!B9%f diff --git a/docs/html/img24.png b/docs/html/img24.png index 87dfb3617e0beb11fe0895d44d446b3ed411cad2..35196adf1468f8338f5aa73dbd49c93d69720142 100644 GIT binary patch delta 439 zcmV;o0Z9JU1Kb0UFMnlaWkW+l?(Xg(AtB7n%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn z5WBm(j*D;e00001bW%=J06^y0W&i*IT1iAfR5*=eV1NNm6bbB2ySs z_<&;Z|Nnnr;06f?xG+MTfq@lHvBJd|;S@r{OfZ>J zkiy0S4pRmW&Hx4meuD`N8y0K;hA3nG|Nl_GU2tG92n;X)hB+|68MqXH!OhPJidi<8 zVZ0y~Zyu&=IDZ=`@E_fP;755uf{NH3_%5)+IJ~QIC1-{v4E7%^s@}p`nc{C5Zb}GL zMoj^7_ywS%ERD;GAyzO-GGsEa3UDYe3ouyn9{`Dj{|A8&phO!FRsUfogE_-j2EJ=w z8Tg+t7bF0MlHpb`8t_6GYym(6n960!Is2zGF#m7>i7+WZ6?GNrw?OT-7cIc$I|R6$ hFq5z%29_@j3;?P_L`@3CQ{Vsq002ovPDHLkV1g&-s{{Z5 delta 432 zcmV;h0Z;zi1JwhNFMoG;cU4tY?(Xh0Gc(N0%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0 zBD=f09~~i;00001bW%=J06^y0W&i*IQ%OWYR5*=eV1NOp1Q7Xwn*j~*0Wk}M!v-+t z1G+2}+;?CEk`ovh9B?Rr0bU3NwCi2O1{MZ}uM7Y zlPL{uJPr&D2Y^gAZeSenvN$koFxbGSz`%Is%o&J!W+1VluwcRlNF1_WXkcLA#)xYm zz~UNC1(H2A0Ds_;l9JK|f~o{K7jVGXyxKU`vm?n!fyq`d>42hY7Mzvz^DTpCzuKoN zT_A@|0Vdor@y7u$4 z`XK=*94Jl8f@P)000{V0{{R4vFTs90000mP)t-s|NsA) znVDr}WkW+l?(Xg(AtB7n%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001 zbW%=J06^y0W&i*IWJyFpR5*=eV1NSw2AqI}f#Cy~F#(5y`~*fY&5ug~6o91JAk0}n zeDur)AZf

0T{U}RuN(awS2EZl(mBbef1VBiFkATTo1%Q(aQ;hv9m|_JZD3|~VXhyK#Ab@wnOc0e)kirIxs0BbK z2WJ2WHjJ~vQk0rVJep?=j@-(!2H7jB&GnB>nhZ5fij&xhT{wh1mNAqNgxkH cfIrY00PC4dV72QgE&u=k07*qoM6N<$g6$8)NdN!< literal 482 zcmV<80UiE{P)m_n1t z@z($Vmg!$^ohL$_5(Cc%7@I#1r)m5D&q44GLUn?G1F|wE1qKV44#l4V440Y&gf=Mv zd29+WB@+5g4G`9S1BPV`dJN1BJPHi^IS&9uI3i%G*ccYUm^TeL0vL8M{Ner0z;uB1 zLjq996K)~z23U&azQEVOkn}@n3ZsTD16Lzh%m6Ca^U>l9l*uTu6qg^7fimwAVw8aZ Y0I_XGENs)f8~^|S07*qoM6N<$f&@pt?*IS* diff --git a/docs/html/img26.png b/docs/html/img26.png index 7bb6f1e1499f9158c58e068883f892658149b069..8c581355e69cf351eb90b36b0cf7887aab9be31e 100644 GIT binary patch literal 273 zcmeAS@N?(olHy`uVBq!ia0vp^Qb5el!py+HSYPqU8OSjR@CkAK|NsBYnKM&UQ=Ofi z-@SXMsHk}6%$ZfIR&{iAl$Di*goFSU8W|bgy?a+cKw$Uo-F@BppMgS*B|(0{3=Yq3 zqyahoo-U3d95a&>fWVePMdDmeLV^c_p@fS>fI}UVvQR!F^I;Y?HZyj^c6NtZiVvHZ zL&T*x7?j!A7(1%U&DvSm+1T>*^4h!>Xc({7FgEv)YR_Z4cU64CPTz!2{4>so)SoU0 zc3NPR#dYE>lML4xCZ1`366|YIAME}%wede^G2@AlWkoZK&i#AIbH-jqf+62PW*Mu_ SmBm1(F?hQAxvXgec5OG^VPba8RHd-txAlG5(oyX9pSrvil-OM?7@862M7 z0LgcHx;Tb#%uG&5NO+LVAjIQuZeS3@U>G50u%O{LUyp~)f+bAM%B0$u%ymtde( diff --git a/docs/html/img27.png b/docs/html/img27.png index e3b06a48c325a65e036275e6611472e0b371f081..54f4af4404af1f15fbb234cca74c4e72386c3675 100644 GIT binary patch literal 4602 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 literal 4180 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 delta 781 zcmV+o1M>WV2A2kq7k?ZC0{{R41_NvP0000mP)t-s|NsA)nVENYcU4tY?(Xh0Gc(N0 z%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0BD=f09~~i;00001bW%=J06^y0W&i*Jl}SWF zR7i>KRlSSUP!Rtm8N*1#qB;aDB%7RZ%DiG`#aznlEILzNr_@^X=fc6MD0Ne*YOh`JBgyeF4 z7%+kLGl9!nJ%0k9Bv10zWmt96MVK|&tzk<4SaO?#uh!hZ-N_DQ0AV4>yl$3RV_eHE zGzh(L^CkDri4voZxv<{rIq4L%e!tJl^vEzJ%}J}oOsPth3nEKdRa9*hh7WBLV@J(7@#WcQ^20000< LMFvhpu0mjf=Voy> diff --git a/docs/html/img29.png b/docs/html/img29.png index a39cee90cac107b421587a79c88a0aeedfda1d1f..79cf88911b5ca3a564e04c9e86b841862e251813 100644 GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^Qb5ed!py+HxJ5CnKP?at?KCLC@U)q2?+rzG%_-}d-tw@fWYqEyZgHHKLdprOM?7@862M7 zNCR?eJY5_^IA$g%G&HgbE0`$T+sE`gbXL)4ZhlbG(r~OvlE=8Agu$FyS)1AKz{iQc zJxgUy2qc_I{d?%Zfny&U8;{O!Z0v4a+_0ZCGY?zo#|k{;y|a z`*zvg;hKiQhMa^C3Dw6ou$*AFn%bz!=)r8ru-Z}7>9S197oa;BJYD@<);T3K0RS<5 BUfKWv literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^(jYbqGXn$T-6D%JAV)XAC&cyt|Nk>*&MYr4fA{X4 zv9a-)GiL+^1y`+F)zQ(BmX-!o<>KOU_wHRKC8gcFcXLY45CjS_mIV0)GdMiE0g^BC zba4#fn3wX=Ms0(;HP(mM16*ls7awHa=uD)@JrQV7xIw zu33qh`8AWDTbrc=BdZ=8pPoYQfzN&GCAQnWX=sjCoO_cwW4W>Ljh+4y5;wlc85?x0 pVe`&UPk5l0utG4=;^YAa2FY?k1+H@OI-m;}JYD@<);T3K0RZ2qQGoye diff --git a/docs/html/img3.png b/docs/html/img3.png index 869e09eb2d53a8c79295a6821ce0df639fcc5bfa..61ee834b5f1524034cb5e7da8d5808c76c084ae0 100644 GIT binary patch literal 3855 zcmV+q5Ag7bP)pXJ)cT^KqNlGFqN=NrxeWlWacr+T1Mx)Vy9HN9%ePZ`u z`=y3&=K>Bx9Qc_7wflKnZU^P7g%E%b0NDf%*o=g=5~w#{;kV#Y*}m7QS8;Ex9T&zP z{2a7)ZqDuYkc0B6@0;>E0-Uc{ZaXrID?V~gSfje2Jupi1ET*}g_@%j!yi+nI)sQUKjrsxSrs z1z3Co0w@$!&Y1}&B3@+Cm4=!I^YYIBetRdEEjLuT{GsZ`+6b^jX8YqSTLJ-%(Ya(q)5_3&@WTbU1 zyiq3R-UT7~__}H#L{D4r`V`e;qQ4X8rL;1@Bu4Xmegv89BT2NF)ee!6$u`BgdGk1c zPTo)-J^90+tml37(m?v|O^T+k8$7?ce`tIk*lC2yM52lkVG|IZjT;-a2 zU>~{rc+Srh>bxD}4DO)me?|)BsH6G3FCPvZ2XLI`*Y@Ku1wo=oyCO)p`c~n(T$3P4 z&7t)6`=n@Aa4w~2niv8&9oPYk17&>}2Q%wK0RhU|%_TgN903xe zrL1O%e3`HHG8%dLnn^U$%S2D7$GxO@JN(sL@iiUpdWxgkT{Md*b-?&ZdwiftL``Nb zNVhIkD|GLP7gMy(ZkSy9qkB#Lv?PjsPcvclB||YJ39E}z#5#b60if^>t6*WyE!Fnu z(rJ2jjaQF)k+=k>jUIfQ;wR`)J}kljzHt6+V^sh*C;%*=;3zo2rj6=y86Fu?69h?5 z6O?2^j=3CjNy;9&PG{U)Q3}9TA};Pj0&t)NHh_ZyMdpXV<~aN(sHmTSMCXy*okW+0 zI$NAeB)aj?W8-!(oLVdzU?YUt`rVE2L#W@X{W$e@T`#E6f(y5Jv*KSDZd_Pc7eKrK zY;rZ-7HzmN8@PJ)TOqWcDa>Z{oxjZ5lejdx2O9YgXzrJcx)+JBseu5#i6?M_VzYo> z+w1{u*FZ>*S`w5~>c-rDii)y_@^I529B(J#TEqby0|&N9L*E!o%;8+qLJVGkwI;L0 z`2WN@E|B5R?%#>f73+P3pQ0_U;yYT;(Y^TXz0mEF%4xRuor}Hu<{z20aPYk8aXAD> zV_Dity(Aswske$s%c)1^sYfqKN7U4kOSvVX z$z)0mdh|5C@&P#aG{Ic1^5lfX2_)Bz!bLJYw~btK9iK?GT@!R_i&Ht6NSP;+Bv&Nm z>L~CG7s-m$Q6eQ*^^H{4#)TUf)&+oA1#Pt@R|OUew|KL8lPkw530nwlj1p!7q3o<7 zMI9y#-6*t1xu#(Q`C?ntBll{HW*>kn6gr{zl+?ChyjHRyq}MPi?E@6!3%D>@^plQV zC=7%bg`bGRezx%UHu$hHY8|ZmF@tY2ya~ipnPUR>Z0_8^rKhr0%?L);Vt5z7)rZnnKeYX);2owU=eZZJLWcs`l>6sUSQ=uY z#ajyh%gpmu#fSYAAS`I*Bb72%f?WB z>3lwe>3rSKD5B%;a<9$hZtR^a&sXTJzX%1TEL4b4ZK{o|5XjW#TCyFk&zl}46H+qQ znMGA`s1+9z#$l@qTp7evhv(;*RF; z7RHR$CXXGC+M!Ki=k&qKJ@^?OmZik)EuH(=-5{`N*k&1`9UO!L8(TP80SjLh#m4TB z&J5FAa{w+d0VWyV#Qx4248enmk!1*?1yE$xD61EU4z${@FdkkM+MvDH+EEL4IG*(# z4qL`P$hCckqSM9w$6=?;D>R>JJyV|DHw8d7oT;;FKWpy>-Su@`!*Wf|88xPq_2pdE zmnNw0V=93128Zo~W>^%!#uh3z7woBs|r`a~>eD*OOke7J=l3LpqdX(to}%BKL3|A-e`rlRRmN|Kt1M@=%Ck|`69 zOqX2B^r)7`xlECJb1s)!r;yRqqcUjT0uLhS1OTb$C&z;CyRsh}%#KTgl^6#gX!`juv=c8Djj2mrvbP?PE%0DJ?ZP)rKz!}t)tmyZ^J^5Mh? z+IrWY$3Q$}i7+4Kg*Yz4|JlBmSieDJVj>Q7a}6N;Gaw-H+o`uv-)lHcrIC=igv<#U zEw}HAICDMTxywXtkUT`Kc8i+B72i%ZwcRaug`0f<$Z-u)*6Thxp>Hywf zcN)&Cr5|hrpw%&ByTWe^AX~qSMfDE5Dn1rNT-0*~S15RrJo@99eA*aqUB+E|q@I@V z%t<2ex$5YGYdm;TjdY*6J$LlD1#9r1{*e$z1KAi`(ch@@FSKX-A_d0w!4-hbJ983zt@21#n z78`8*jrjL0x60`Pa& zofN_V*hUx_gSErNk0E^HR*T|UR^Z_J!|F%S=hF<}N<6v8c!c8LEy^rBhJ zGU*mLj4&hyF?@NFB=w3U5=xKEM{;XRm0ac|<#-pNTjp0W=r&#g4BHydx3+&6g_pm^ zbKvE#F$k>5XH9>x(Hc+Cm)zXm#KJT1007%l1Wt?~G#gl_fMc_EOTK5}Ve6J5Ao3O9 zQtW&;uHp%Ju*Sv)HZxgKe*7sCiw$CITCTibbKG;_#ltYT)$QaNc(~Q=of(Ax3-y91NT_n=i_^ z)1@2^zCG71>TRaqu4+Sp2ATN)vs!jWIev z=vg{J5Y7a!fu04$>OBpM)q5I3{Xx$baZ*5pWmuJF;>V%-gPtw+aZTd-M*Yynia04C zaB}%+!gJSmdHPz6Gn9%LFGp-t% z=af?Clu~-s9%W8$!^rKHaT&Icd%%OtNgnf{NhZ+VdPm&T%;)Kzhbjg^5>*IDrrs#= zj@qYzhigrju5+!I*J9NY9P^M&S9&hFy~ALgCu5nH=RuOO%=aaIuw`yvTF%YY!P=uG_h@Xuc_qYV#7zDQeFq@jJ0{PlaG zDsxil4b>WL#)CUb%9}BZRTyjpe7G5mRf~m_wQcX~2#U9~s(I0EKcc_ddc_y1E=lhu zTkoTK>Q%z15A2xi)5bAHJNePvW4BaqWVs0pWna{{vddeX@|3 R?tlOQ002ovPDHLkV1l%$aU1{u literal 3149 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 diff --git a/docs/html/img31.png b/docs/html/img31.png index b0759f28c537a74501498c37eea35679c0b9351c..ac17f63f507fb1f5ead7a1c34e3b59f0d23f1af9 100644 GIT binary patch literal 1060 zcmV+<1l#+GP)1Z%40000mP)t-s|NsA) znVDr}WkW+l?(Xg(AtB7n%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001 zbW%=J06^y0W&i*KqDe$SR9J=WSIuh_NfiIhbWe5HB%K;p*hmm|#Dky*2Sj%-G7T#z zf)K%tmjwqBKQBAW!iGo=Z4j62snnSGks%Wgdd+{ZbCJF2oP@w0B8aeiYK53lg!aAe zo=i^?i4KE-B@e3ly{h->SN-a}*VVu#WQ|iN;0eHimeHV3tq$0m8E-)5GWX8qB2chb z7w|h+X(Mu?M=zkEi1~%K4&sLAN|0@njA-Vgf(i zeyO!V3_P0mpA>P16%GuoXnGuauv9Cs>}r~=nitZu>lar^Alc&0uD{0Dr|A4F?!2}M zKIHYWSxxZ0(WAzlfp#|$ky~Air23=~ZmtK&1VI49kYbkNN;1G-#4Ln%su9o$)*YFV zp;vv5J>f84s=H`~R*71gMS;ADbgqTVL#2AjBHZquOFGx}CAX>DRQI@#s+XPU;~4k6 zPg+WFEr`1?G!a!cC!STGG>xr7G9@b`st{3jxZ1!-`Jap-j@xn&Ssr^UrR`)K3i26U zsLjE^~nC1D5!t!*q+DJ6Qclt}0g0xDn1NC%X08hS|tQLd1wdJ{nQVM&)H zdU#8;;lgR}m>A9s2AElcx5JlW3cRho6L7SH3AE~mmsneoDLTI3TMq|_< zmpWz{f*dvq_#kVX(IDUD_HJr{%c8}|gWNEN~gKHPMQDln?~3PsnvMTi!o z;yg_(L;@R363*nBcO4g`)mxUjG)D4H)a^>FWNV~HcaLUss)nM+?4Q3LydIk6W7PNm z%Ku&;p8BD2|Ju)ZS_$ut67w{(Yb8fQXmEwZqiay_dZhIMMuR@9_Tz6FuBgUJMh72` zwqRY19{b9W&CqsY)E31-n;wmo<~|!swf;#e$t5dI##@&;389`;`hq{j$u0R6yRsFa ed~(~=5q$(~73u=sM)Ift0000#~Z5 zt`>y42XZzM5yTIjJWFRTN>|9( zKJ!37QG4h!QfMrhG@~0=BCIJBskoKhJqB^8f2FFuRQS}h_=?|y?}T6bXdMREuG_eA z-T)dEZ`{{i4ZxZstozryrfex1Y}IcRJu**<94e)A)X}jhjErTaq)Cyi9QlpNqz@B; z^5AJO0-#Jm6vL2-vN;L8r?^}MT$?d%|3u5GA1!UH+@$u(@*jx)a9%!m@ZfET>j&I@ z-&1&r8XtN2HmTzhc#g4pX1-A1{y={#Hc>R3wC*VMQ~=IfdV?KD?QFaYlAUO_xhUj~ zBt8Sr7#9gb*J%)K1bdJ-F&n5kv@=6p;z1Z^6|0KMX&`H)G2G6Fj3OHw@_GsR!Q1JW zT<1Ipf;J_wkjbB=(Wy{!!Gm}heKvy~Y@N2voCj2*h9Viw7Jf3~_{ zWaMAF62CFcW{Ek(Y#9J)#)%-z9Jl1&1PRy6-LOb98+)1vwHZ;{L7aL;x_WljCx>W1D zls8MzB*ZXZLvB6FcA{!&s<9TA-za3s_zDryBDxvsf!!?|NA{8K+K$+@HuAXfs&S2GjT+ehsY5I9A2MHWj<}3j^;}X^PlILKswxntN-ggfK5_maHFn<3;Y!7@ zFN$Cd0`E5T7$r^gjRe2Em^r^3|2^PmU#!0l>97|cJop~`2JAl@?CarSo&W#<07*qo IM6N<$g49C&9RL6T diff --git a/docs/html/img32.png b/docs/html/img32.png index ed749deb990c719fc90a94603bc7719606b71773..b5d11a44cbf4fbeba3822b6b7c9ccc16aa5f36c3 100644 GIT binary patch literal 321 zcmV-H0lxl;P){0tWY4ovvK%OG$8T|ag(o#VU20?q=CE1OzlN1TZkL z@})5pObd9%U;uPsO%*@G2leCa8pIh%7_c2-52&5v@U?*X1Bl7cz&s%gD4gxUCBX2O zVJ1T=gvsCyR-Mf7m61b%WeY=C8i>ihK$BqtNIZq%0xtuD0|OhF$#8`sfq?-4bU-ZI TW?Mn^00000NkvXXu0mjfIM#Mk literal 311 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 literal 3994 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 AA^-pY diff --git a/docs/html/img34.png b/docs/html/img34.png index 75e66a30e60b99898f2d4900a6ec10e6240938d6..8fdb928396ffe57f3505bf9fbb65c91e524f9605 100644 GIT binary patch literal 808 zcmV+@1K0eCP)fb&D0000mP)t-s|NsA) znVDr}WkW+l?(Xg(AtB7n%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001 zbW%=J06^y0W&i*Jrb$FWR7i>KRy~LlQ4s!;>~8X6_BP@Vc1EnU$rd6ua$DKh1gr$% z)}JPo2?rjc;06TI#z7Cy2zqN{saIL*wl=z;jbNdTsMYGBL`34em)-nbylfE!#V=%c z-^@4j=1pcM3rs}AvVCy?-CVpb1JPvWFql>UNG16g@|R#vw?Po!g?y9?=acKm-PWI! z1l$5S!)z~w$5bF|@CfkY<}=4CK%LXYLAY{JDWE8n%tD?@q!vjK=7e}M$O&A#bLA7Epd!I#lV>VDM+ym!W()FicZs zZhV&*PMVYGKhv=OQRFw37UFw|25n@8sy7=X;&mW@DEMQnpyx~zcSLM_k9wH1ewbC5ww^ zxq)JZY>S(WHG(5F_**e#A%y*?8K!{>2jQ|NiQbB9Qz46iRQ6l{j3dw|CT|?sG}8#$ ztyIqbX30000mP)t-s|NsA) znVENYcU4tY?(Xh0Gc(N0%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0BD=f09~~i;00001 zbW%=J06^y0W&i*Jok>JNR7i>KRn3djKotM=D@~fD4XZBbibiy6VJYod5a+7mVQ(HI zA`2qegV%-F#RXAl{R_4zsCWwEp*Q12Jro*5P!J{h7sL;C7ZK{4Nk7~)Ym2Oc;_oo? z=FNM*dGqGY3=oSofE5nl5tq~PCNVg{o2<;J^@O4@*~eTN$yFSt_R6tf76u;|vDZyw zb?Wth2`-pu+YA!lt3$CraT6qp8Hw9Cs^>jJ>WoS{0uzpT?$s2&LnMB0tm9C|a;y!* z(1pxFQ5rnGTdho3T(mVL@faBwDvk1;PDcn8q{ylOCr^G!47psOH8|f97iS8HQbP<< zQ*Fg#Q_^1BRZOqYQE_&VFR`BP?dZ(o7Z2^ zO*d_5OTZ1f1Tdvp%&B-w^8QZ81ynULCu+#2dN6rSkd>2W`*aPRJuuLLog`G7TCr6X(1Hlq$P-1o;&l-c{{xnwe_Ecp5@z>%MgKQMTeuiqGc1PF4B!@4wV(I-|T+1rP3;-ilGH4dz4VTXj7j#IWLgBO5 zc8jR2oXOR=V+n(oH-(Q2%|?OLk|8-+ilOBp%jZuDB)cT z^+?)z^60VJs@pE@DJHu9FIkOJrTLMpBMyF)3I~6feT^v9_E5^7rnH=h%Q02EL7zz-B>7w2zamh$3f z_yAMC@Cz5VKmePwfL^X98$evniBp`jfU`l8lSwk2fq@Ys-c<_{4`|@Lz{&oLogslC z9uz(X46F?NAb;^^0s#phSb2aZCP36PGxP$*)sN3F@b6&cVQyex0*iALH6-A$R~?J^ z0vzrf1sH${Deo!}4l!mV4`<4`;9kO0XJnJ|daUzCe>82N)Q6AWR-KDF&tum|_^<0K;PjULXX50w9MRFn{UzZiwydAf6V(K^A@> zEtx=;VT8Z|oZ=5yII0+#_!&MJFvy%a16KC|mwMI@xXc+m;J^V8i5Y`f#F>%B0~A;i zF1XBLa$sO^frvYCfW#Fx@N6(xz{<+W!0-kXJ_io)fz^Ldd~jjIMh+hC1_nm3`V%}1 zvrx_FCDA>j0Dn8+K?c*%1P6d!m60&l}rXLzm z<$4Uv4GhKd7j7DG1h8>CFe$JV03})*kd-HJ0gYeKRy}OfKotILCw4BxwIwJO6P=(;y-F-hmI9RGm zAdJ+d6CD_l$WRF}AbCQ{#Kwjc)D{&aWZs>BVv^D_w4M5t+?~IB-}`)b&(8+7GuK7U zSOz9sJ40-TfdksMv=Jx5voMB0b6F@vwlR@kZp+Jz6(gQscPqDXR}O;}!9xl0HkeUk zTSwRj>)M9u1AjQQGT_?z#re>Y6Qb5ir}PEP%if+uU>X_EkUp6DC|mw_NJH<9{XM+( zeK(Oek&$2X-b|!gO|Pyq3vS!TNRo7EN`o&1ZA90Q8IX*3!5#6-LZCp1!+sRTC^>$}z6dTe3Rh&x zaVlF!I|wMZWOg~5NlZFIYgCy6DShC7b$$O+wZW9O)bSly&}_*uG98L&u^9z&O3jlW zUbQBcWPcJuPdTnE46oOza1wz4n1~`#w?cAx%v3v6e zc3^vBdbx7Wsy3wmX#Y#Q4=6nK|E#=5$*+@kjGiFg3!6SK5@@srJ&o;kikCv!ubuU$ z%Q}uIbg+eI&No*rA4}SsADjuRv+7*NSwbsONq@)c@Q1kRF^X8jnQDN?X;`aICuw5# zg}2c%x+PDgL+iZZ)m_|w=MBY&JPgH5nDVP)_(38qThCAo^L+wFjLHgOKU1AGsgi7t zC%?1xe3QRLOqD$)-=V_P#D;b&sC#R8u3-)rz3Oy84&TfBHm6t@OpbfHpm+;Co$`9> zM_5|5(aKv~nl5?fI=D^;`I-8__GnbeO0Zqlktbat_ylavq#@s0hnPh3V3s`#ogJ*4 p2eq_RcLt7q0O)z{kZ-$fe*hl#&tqr5jOhRX002ovPDHLkV1j_;k+T2* delta 865 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�GL?6E^#T#6lKZCIcV!40i^G{of5 z*K&H0oI{;A!TzJ0L(G+-ehkE1a1ieNL4YE9re?}_YT4VC5awvkTo-|m*RVTMNaT=Y zZ0)f~F^hLSjt~g)H%0Yiia4mjkh&+<2Tl#dT&#@>*df^6=|sVVJj(x@_83QfGcNP% zHLkWk)RBX5HJn0wjxrmfNdS<#;cHp33`dpbmYVHIJp=>}N3Ls!h>Wq@U=k~wZG5uRs)9`QHWkd?6JhK*g_Q1rHs`Bbk> zgPe;^`Gc}$@ z-S{uiuQyTF=NAu6IqUO_hvKU9GV7CV(7(1!G3%ohhIC$Lec&^#>1KUcA=7!9^`SF< zs#zaa$b)u%W_>j$6=pr&&U@>vusKYU^mv@k?)2qztjJSV;B|Cz2UdlOJ@~e-TTs@8(=Q=pCy&uj z>t+HBbjl7&FTI6C8I&kV(xr5Er$3()=Y~i@{J%%x&vZDu6aR;i+X{7cg}A!oV002ovPDHLkV1jUfC5!+7 literal 3960 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 a%pjkkbYDf+AhAIJ0000A+0I#F&){KEdq|5D8YK zfCPex3Uy*314G5sKfvsjuv8|b{(~n}l>zMAs7=~bDner7#JaJ4j<0>MA3z3CDdY%| zk9P8pbJ??LEjZy45^(O9ILd|4#?@wLFEC5Gai@%bh?4GgLou7&{fXmwSO80^SwB8d zm?J7^vNhhTiVBQ=zpn|AU2`=xV&gZ<`UBYNn_vP55>0BwIM{{;~0iUY7WA*fV^Q11Nes;`uT8}LV`-1dEHPYC<#n(-MI`~0{{R4v*F070000dP)t-s|Ns9(LqqQF?##^0s;a7ph=_J} zc2rbUnVFd~GBVxW-4GBEySuw~xZ=0~0004WQchC)HJAaS-(1_l5QF9ur; Sj9)GQ0000|F}@-mA{QAk6pt_(}Up{EW33=GddaOVH|74ZgW O9D}E;pUXO@geCyUfI8&> diff --git a/docs/html/img40.png b/docs/html/img40.png index e7b8816aa53b682551145982cab79469dfa7e3dc..18cdf16577ce02b283e30a84b96e1acc6100e655 100644 GIT binary patch literal 881 zcmV-%1CIQOP)KR=aN0KomXRhwZU;u?rFrB$QMXG`OIl!V-vw(ribG zQKTRQNEQV`ND)gYcr+PAkx(TCEmHn~Eg~8kxBCNhkqiwcb^UpWPN}oA0OJ-5fCx3VTw3oBJJ`~)K`nFz?I;BeCruz7z&iA@m}=f)^z9? zqM63b1B4Z5VLH8chxR!`JI^`KI2)x+NyaIId}W_Rf-b?h24foOjo(NpL2Ny|Ha4jm zq}1-0k&-qYeOZAUc!M2ajni;Wi8zJf%|=~Av}Sdh{Xq?ubIi9sE7}hZU4Jd;8gE4|Cn;W@xo%C=fFr)`I!TKoJG>Ai8 zh-?JaeTG7*wRPo0W@!W6bHv~3z?j5AQC=}oUsi!C>)-%$>7yGyjs(2uJSp-8T03rN zZ5V-^VffnKf+T{AtL+%?v^*ILlrK2LE&ndA(TjPIxefa(y|B*rEg`w4g;VtG^6jT* zbSA~4JOdM2n}qEu)aU2Z&v!28`^Aj5i7BMr!zUbIx^s-&wtwKW9l|@CK&XNKG?#7} zm`AHmgcl7-9j?}a%o&k-8S_zlF{XtXXY#w!im9aEMfGM}*V}0Z;_bc(CUhgZv0LHf zK%`F5;-V2xVpitzb=)0G5;GZGeP0hTA(uvy0V_D1`G4&Xf!@P=X+60k00000NkvXX Hu0mjfEfbT} literal 909 zcmV;819JR{P)KR=;o4KotJ$I(8Daimgi z#yg!3Yj|p6id0#YI`wRoS`%Tk!6v2uwJHI>!tK$r$Xl4jFG{d&uu+p!) zUSWnRQEeI-qc4~JdK5XI8d51i4JTxUp6qmDQD<`=FG?IvRI4>I`Y@(>Zp7D;C6R-> zHhhh&9f_nOwsoTwS{bA}M%nPCm)--KQ}g*ULbDQK4Kl`PKku|-^5aY;d2dHOBD_t7}cHs+_6o-8fH z@=;uvTx4IVrvD0fsZGFq)}@EWUWEARD9$2-qgyV@8y7;F(eaUFrm+6HF@%%6u-EID z#Swl2eI*vYSo2I1Dh2+U?#fV)7@++QXwv*l76+fnbs{5BVtODA8D%ttQ*Lz)zt|`> z5`JpO6Ptadn&Xs+w>v+yodpl4f$0P#aT(XMIMZ}_)poi#gZoRX0Wh%(&L)o2mQka+ zXdhbfp;U63DUEr|w{o&vCel>fEg{`nOEP-7I>0&ET$1+HwY<+s`c!Xs96S{K@u+Ie j<0v8o#~)eO|B!wH`Y6Ogq}q=%00000NkvXXu0mjfq)wwV diff --git a/docs/html/img41.png b/docs/html/img41.png index ef7452395bbbdbcbcdb1ab162eb358781f9b8529..61ae82f89f5038bba4c08a2edbe62c433be399f7 100644 GIT binary patch delta 564 zcmV-40?Ylh1i%E47k?Q90{{R4T)viF0000mP)t-s|NsA)nVDr}WkW+l?(Xg(AtB7n z%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001bW%=J06^y0W&i*IzDYzu zR5*>@Q@u;WP!RvcwrLVglPV~<=&A_qpy(nviQ-@;9Sw-+W`9JNZfz+DPH}K>&{hXs z3xZ1*!GGZW0S@j`NKwQ=i1%JvO>3;s!NDKAOYZL7$GZ=p1I`Q(Q{_&vfJSHe-hydm zBlS(3hyIIL+=U4l6UcS5`4JUZK-pnH99U3X7nnjx_INs4PaeZqsR>jgR1_|*sbNX= zg{K23f|CSIsegC`b1mW$zVFi|%2HeoTbu&!6Q&-c!)mpRhA7 z4B@B>hgyzH>I94H?P;@sV{PgDU!3(~r1DLHG?s3d(SH|=Q}$h07W4phIFUy2>9#Eo zAbG)88E;9H%*Zj3LZ#Tq4Ifr$ZiJQ5N+n6tkOr1Ux95@KD_*$TXYekt&xxU#$vdpk z8~6lB>plmMp=KrWU?-aKWNdJ1q0We43j>bo+L9>-X!9$-$uy@!tzDF|G)|hS&w3hp zyTChQZ!P*$?M5g+pMV%CmFvN`1;HKdWlE71`5hmY0BWh47OMFG0000@Qol>XP!Rr_#HLLf8c;#SAryxy)V3hvW_Brb6kMW97k|OJIER8FSZMGsDC#Cc z2DdKRT!hBKK^$6lhYAi-2fde6+tgUGIQc>D?%mJt-U~1QqYOxih|kB-w`SQ;O6p)b z!+f7TflQNB7}KZ(h}~l zPmjSN>4n57aep$c7G25g^|cLLdX;F6z~=8!AHLsrphYF$>TpV*7JafWrdr^c-b9V0 z>H2PCDCYI7MXo$Mi!ucDU=PX_Rr4HpK~reLBfB%X)4i@X^^#){B~fdb2)T_c7&fWh zsBfg7z(2y$C`G)+WFnbNs=*1|!tz(=oGY8i!3eH;z<(NhOySc(VtczC{;bi zOQT~PrmJUU0!Q?Y*!qYk7J&;&E5D?`E998Ulnu0VC}O7t`6i2XOajpwh4y<)IGc^q zrS3*yoOn}nPMnfNJyM7k+F=#cQ80U)Pt#1^qf1k^=uhDdtUB9tnn7Hbp0H7`voPPQ qiWB2VVo10000&(Q9|ZL5+g$~V zp7FCX+?iy51G{Q*m{u@44;Kdd+lI776^q1sz64T0$=ngThi_OlLe@m0Dxc4-Fi}@X za8X4Ft97S#$A6LlGqwVaIVW%d8I;LLM^Qu{kx+JIRSFyM*pw=TZ7`SqRrX(_-u`@l z0v}tQuZerN)jDaljHQ}-$so^hRenED+ryPfKco?edzhoAIJZ?ZMH#k$%n1Wjpf`#_ z*tc=p;=U|}Ccb3TULjCpL=Hb-Mfm_SWxtj!m8F{cUw>fdQ&A#}m$@V7tDF3Vvn}6m z?x{uhag`jE`rf?qEzndkJVrP9#+F&=-5^@7u3T4o)~a+P;xMNvCbJ220%Lu@MlggN z{jAFe3liZz7ML8%&75M2&cTzQO-Br_B8nQN@Y0Qn^k*~6T*j3o!cTPgBJeafo}?cy z5(he&yFZ(k5?YZ4%X00Z(4u_%c!d67U)GOfXZ|@%C#QMX^-xmg`tQPOa$i2i6B)H` UF;084yZ`_I07*qoM6N<$f>|64O#lD@ delta 560 zcmV-00?+-@1iS>07k?N80{{R4n*24t0000mP)t-s|NsA)nVENYcU4tY?(Xh0Gc(N0 z%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0BD=f09~~i;00001bW%=J06^y0W&i*Ix=BPq zR5*>*R69$T>RkPbMAM~^WK{P?_jLM7sYr37o{=pxKLMv_vQ@4 zb$S*PS5T2e7ldZEU!a^gA4#A@Myl>gJXFU1O)Y$-HSd_7}Q zzdFeTSe|%-aetBk6Si|rhHakb0Y?>2h>g*HT-o2C_<4V=z%JI0)ieIen?^%xaMqlP zTtb0n$6|VK3WE!l?hqxhH76skZRjV-lnp+nAQm@NI-(xWb0I$i*J0W~o(Cs##;F|^ z=pf^gNcfrW_Wa*5^((KKQ5MSK#rA!3i|EMoM{=Mdcz+lDEdt+Q&Sui65~PUXb587( z!n;SLuaw8xL3<`UmfOqaiP>a7g`^hlE91aEnXNw!;Q<2C*{vrR7yVd{eRqdTennU*Z*+&uXEyC1rO20000CnKP?at?KCLC@U)q2?+rzG%_-}d-tw@fWYqEyZgHHKLdprOM?7@862M7 zNCR>%c)B=-NK8#mU|=d^_KXM19wsL|_@TF8qeEd7BlCo_3JLog>Kz%SnFDyG z54SS3H82ZH{FIc~QNhh3!NM1D=U&fUpPU4{+s-UBAhIz_ovP{d7!+JvBOe*1FL}nN0Y0i$Pa!K6Glm2o_l<2GC4i}*Eh9PHrgdH iXt5=Uv9+;u@G|uO*Vp@;{oxtVZw#KUelF{r5}E)F=y!_% literal 320 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 diff --git a/docs/html/img46.png b/docs/html/img46.png index dfafa7c95afe8b26bacc5b3694058e50946bb020..8a05f9b875776a34d96118727817aa2c3825f325 100644 GIT binary patch literal 501 zcmVES{SeTXevHZc&Oj&WA~UC9^^(XQ|qY2mdP$LLn$o3Y-ZY0zwAdr_F>$pBfdA7 z&-|_-mAVjul&e68CFh|>4xC`sdIDVK`M{bER^7Cjg};DWN;qm^;fAemr4cEme_+0t zZ;QTESfV&wDVh$N&X!abgosEv^1$bSj%~>M?Vej|%;d4;U&ST&hfOpYqR+G_Z)pRi zRG?Py`S2%Yiu3<#xbYo_87qUGlwJu>tuqHHtHO#Me$m12GDq*S{fge1=@IGbQR3Jv z*4V&G%o;Lz#s!6#>?Jj{9YKf^htU^HF&oJST^1ahE|J?ce&-erC00000NkvXXu0mjf4ldxS literal 476 zcmV<20VDp2P)2T;GDq?Ry%-|y4L~(Mn zmrw);p+j-jdkA$D@i+<{oJ6+{jvbPS(9!dg9}^R_LO0*x<2&ccbMkRQfKoi0mua%F z%am*bkE&&5CPJk|IrBp}>WHB7$=U>>2=(@rFVYDd`k)6cZ-%huI_`I2SxI8$L}!vT z2z(b|hm+QL%mir%U{%wo(-tx3V#2bLgyvwS{Gmw#1`<5u%(&8gv3HOFO#(W!U>FUt zHx<{#(A<)scc)?5w)(tXQbtz~OYd+hr>Y(IKlSMpm$te%%}cxQkv|~xlF_1>5$#44 zmumxO{UtuVps8_OG!8YE87CdHXWAZ2%h#ycON{e=!EnPyAiLQFFuKI+esI*r5yp)nji`mmw323a}ihnfRG|Z6d~r4Yf0Kvs7`_p?#sJ--^=B``vQ#O z3a|vV#zbIdNryHN8fHO;oH!*;A1n8=l*~%3AahF8cvz;yF*vF6upN(p69%=N&1J#w z_nQuJO%6oGJ`~;8eOG=5X+;s2*r$+)6dEvs1|7KcYss@TJdeN7ABH~!MLgr{-azr4 z$Ez(Nbq;BdzRmk}z(^&+ghV9pLTxfsB3?rVxQV3DVCB@Q*Caw2BWyR)ngXn_5XGy&JH}P)9u8ZPwH5 z+I=+7sKtpZh0#vDSoZUtb*$v}dBG(QDcMcwT>KL!J(y<7ooF%Zp{5?RsmV$C23vdT zEI&^#x6dhXoG^lZ9TXa{#seQVZ(|4PBzGRc6tJ#MzAwe7=jZqW&r?v|a;+8X00000 LNkvXXu0mjfycXsm literal 498 zcmVh9Lt`mn_4HD?qj?19b+U|7h&{FlN014yX>k{-t60t~7}7l15a8hpgS@Bx2N oAp0D|YEoiZr9nswnjZ220MaE-Rasl8^#A|>07*qoM6N<$f?^ZNq5uE@ diff --git a/docs/html/img48.png b/docs/html/img48.png index ffc914618dbf09bee8680bcf88cbe53c88d8d5b2..cf61ecd875a2aca57b28bcfba2aa653ff318f094 100644 GIT binary patch delta 517 zcmV+g0{Z=!1gZp(FMnlaWkW+l?(Xg(AtB7n%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn z5WBm(j*D;e00001bW%=J06^y0W&i*Is7XXYR5*?8R6R?>Kp1|~CTY$#q$m{>`~k(m zIEjOJgM*XgCqxj$Mco~GqTuK`+2T@NTwUG#37K3R>`#av(0>X_ypKd{TUr#|d?1(S z?tR{m`viIrH|;tQf~sEBYZjnYxEx$kHoz?4$>u;s19-71+2Ua75U@1;miWRlEO5uu zaRL`raD#oR&*b0EFbsCzh>A}#W))%7k_1I?JMm31>Bj^PSa1cbq#hv^O%!Uc2qyj2 z3jZGN0G6Vd5q~p1DL^y*pQ%>tykki6M1)45RH9}cd0Ux~_k0f5gq4Uj+#qG=QHD&8 z-+&w&#S}4&iPC^}+KX>}T`;2e8)v1gy7*Up0F# z{@|XLIuwB-#+16xc*q3q$-dmfnG(n9^yX5R&(73^mVU<#EQo$ZTsL`IfO(Kp3Q~LZ z5n3{rmvrV5adgC+L70-;fp;TI@v}Mt5MSP0(gG&*yP@;gF|0_*&E?9j9LZ(1)!UQj z_p=-m*PYAp4*m3Tj$W9S--V4)E114gJF-!7^LeyO7o_|hfOl-A;sFTK00000NkvXX Hu0mjfPk;IW delta 499 zcmViUfwH${OBH9%l|Uv`-(T7zsjV}C%8D&Fvl2!S1?BC*C;5@Q#5RUk0y&{z$dx>1^COIodYghih6TsP^i zWeJYZR+0s6QI?ZHA+n&ZcYv-xlb@_){(i&%6@}qDzWM6(*+W-*((I~AA~>k`iSmX$ zCO5j|$~GauS|I>eZC5fJ!)l>v;}Fq`6pHR5*>@RIyInKoEU^?epH9@f|1$L_%Dj0#hN1h?Pi@Dse~a z2v9`D^(k5;)4n9%Mn~7%@h+pukr-e7Zg3HYl`)Q6(^SHcV26xXaHSV8a3;%JzzL zFJh5QNHw}9tXC*p#5XB)C7i;IGTY4w_1aL}3GS0!gRQkj4a(605fadI31ZiysXxl* z7|B%RIY#N>@c5t2_I6-ZMd_FayLjnc8m#3fh9Ip=gYVEuEgzMbwiQ1Gs!Y`D(i&qY zh|)nUMGDlxds-)06AkwVlLzqonhLhU10>1>MpeWWvTc>7b)f=v(OxS%(Uz&{N>~#6 zrE5MaUGjg0=E-dHCc26o?^UiZdqO+5eFgvQbm;E{&Wi;2K0x>;o^~-zosns5Fx|)l zyf-g-!)NMQ;>Y)&KO7KlPJcjCISNS!3nX9B3@UpU>R$Y$2p{W<-coETzH zsIfMj(Emd3s~0m0Ap-uS#c{?=nh(NMbQ0LTb)3`DTDsF_rj;xAPw&3}_CR6sbCRy< z<3wK;LU;Ep#`4Ju@HOfTZBl`>?k0EPlb|HlufNm{;3-Yv57n`8TQ4bsvH$=807*qo IM6N<$f?b^!EdT%j literal 572 zcmV-C0>k}@P)@Q@u*VP!#?W(>C@dG3X*FcpE2CG~f#a6r@{6$Lb5% z7ZAERI2b!RxmX03AZ{)h#3{pFozy4r>QpMI_vS~_S__rB_(9G+=R5cOTyhTZg|ZYj zgI~fd>M^C{+@HoNz*E15ftbn^4Ys&UQ1*d>IrwrvdUJAD%3a`1@NH4GCGBhILLP}a zjUSI2NLOc*&UXf$~b=6@C0+*uE zNCqw>u;o}ZX`Hs8u^`C(uP?~7b->5ckG;2sJoz7C+HoqsiPOCj(?<_8#0s1Y;NM@o z9^32lYlmWd_VbC7LxFOdC|w+jqe!z0>Oxy)c{fs~+TAAVebGAR@ zY9P;IFTIH{A?g;-RWvzDxO4RyEIuJqSF=FEL8x42HAtEHWZ{jpQ_O%cG26=Qa{Rn( zE{kiO=gQOt#mr?~Nk8v)aus*hrkRL20}gPD5#UR)Xx@wx(~A!mk63^w4#^_`0000< KMNUMnLSTYHy8spd diff --git a/docs/html/img5.png b/docs/html/img5.png index 8960898839f77c9c621f4c715850fef1cedf1c2e..ad004662323b3bf16443f68bccdf2f4b936f1a5e 100644 GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^+(0bP!py+HxaE)(ACRLJ;1lBd|NsA)GiN$GJHLDP zPEk?u%$YN*R;}vj=qM{I3keAUsxmS%x_kHT?%lhSc{nEk`HUq&e!&b5&u*jvIT@ZV zjv*W~lM@=6nc6rNUNKDBoyFLZl9rH=oRE-|P>|pt*v^or@GRAVadp^Qr-FzDCc+`H zOal1{2^LZZ8bsGH&DzU#vxcpVS;a3wy5ouE1;%HF&Q}Ue8cxhpPB<6&=2_BaP7W~! ZhLe}YifsS7F9O=h;OXk;vd$@?2>@iNPkaCX literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eV!py+HD1B`~4UnT7;1lBd|NsA)GiR2Um%n@W z&e+)a%$YNSf`Y47t?KCLNJ~ots&a90xqJ7nl9JNy-Mcv@X9xm?7)yfuf*Bm1-2lmZ zdb&7C6F^BXe%3G&IP1?QdF@%$Br(H7A1CiQR_R vL*|;7f#?U8LwETES$2PB`Ociw)6B?lr-xJe^3|etprH(&u6{1-oD!Mq$gGR5*>@RKHK#KotIhor^Dtaa2SFNR?XF z4mDH7fO-Q%yHx%YjD&;`5@GMaAys1Rbt(=E?b4N%jsKvYx_@+N{sAO6Z3Rf6<9^tQ z8wiamy6{Q9`+VVv+V9fK5L8Ag1$Xlb0}k?e z-#<(YQT5^(zn@g+4rn%+>uBN-V}%oh0=|o?RC!*dEw5*{hkSRb$^j`uCTvB=b?};+ zYt-({X`tBGt}T~-6wF%R!ruh;M&F%}zWaRx>4@Hwe}9uc$7K3-QCWEtulfg=01s+3WNM+Xa4)lLy|NV~s=8u}i&M)WImP*R@>?bSA5_KD3TK&RhMKS&z?zDe5z$qZbT#sj&*Q_Ul4(Yx<$}#5yh14S@uklp_&?z z`(k=auR=@|etV}6KYo8IFm;sKdwqUz#s*4n_nceNw>Y^qQze*_+j=k}_t&_>613@R6R?>U=V)VruwEynt&n>4j~0U z5&H*(AcD9#x|zk<4*r1BMG(RI0|XItatJ7{77?d_K?f0$R(~hQ;2spT4`NH`4m4&5|0ZlT z+}s=&-UNzJB%uKG7QuW;1QKQ7LV*|O^nNeVw;;8tGS9z4<>@lgDWHcyP9y6$4z!!^n9iNvQw6ILP`6 zP_B`V6^MH0>i!#)J#TUFchm()zhEUbu!Z;SR>RV>)qij|n;iyp$VDvI6?_O2P->y@ zf(`m~>5+plylPUI*<^()5~Zi%7*jLuP|af(-mP*#(=-1W`WWh=3)K^CuCOwCJf{ZP zy2{h$%X%r_FdGq7o0z~R)T2ms9j*eIKNgpe+-wnv{;{CM&mk?nKi=OAP2yocT*&OK zXWgtb#VU!CN2DEK1*gru`4axVLQXmP5vdU$+1p%LwMbg)00000NkvXXu0mjfFYN#V diff --git a/docs/html/img51.png b/docs/html/img51.png index f6335409c72526e4b20d54dac87e20171a8e8aaa..57fa3dfb6bb4184b3f32d923a4f18ab91b956765 100644 GIT binary patch delta 228 zcmVfg5AX9z{bFEgy9H}1CkO( e6vG@CC;$NF9u0QkS^VAr0000cGIr)>dHAo+{1Eci})mQ!$gCr^18m0EWw5oC&WOQ@dna7?Yiuk4SAO3$x>6Gh<_W zrk-G^$LGgarf|NYv0ug5llgsFVdQ&MBb@0M)8h1^@s6 delta 241 zcmV0GBwP rpvb_Uke!f@P|HZPg?Pbk1lRxoeh47@CQr#I00000NkvXXu0mjfU>#r0 diff --git a/docs/html/img53.png b/docs/html/img53.png index be2cba0ea04111fc3d37f3d1edd410c14338073d..c56945fb3dc283e3cf837bfffd4f42c643119841 100644 GIT binary patch literal 429 zcmV;e0aE^nP)SV1NT&C>>Eafk6N+$}hmc&Jf3Nfx-AgLIDF7Fkt~h zrPc&Z4j}Uj0|Q$CTbwADF#{Jir6BMDmCLaKL>~CX5YX_8onbCil(hk58Y6@HaYp8! z-yyDhi_1jffG~pw$Rboh{tG~hIG6MbBr5b5vXnyv6CMEl$_GKWEqLn%Y;9EYzATnltk70000mP)t-s|NsA) znVENYcU4tY?(Xh0Gc(N0%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0BD=f09~~i;00001 zbW%=J06^y0W&i*I9Z5t%R49>SV1NR4B^c`)+W`dzIN)Po;AXhSaA^UM9l(GDcwh{m zV)oY;7#NfoW-~CbY+$Kozy~-`xonOgfdxzqH<*|>8QK?s1^F2h@S1@R&{Q)iFrYgY zXyyi>6B!C-b6oM2=4NnXU{X^0z`&3{0ptNDh7A)qnHf$)P2+9=xs!!q!$t?*f4mUE z2}~rph!D`(%fM74fN(5Mz^U%Q0CFP(qqY)%&;Jz+NsYSvLjQ#r7%u+*fUIx=R{)~} zm^Fui?H@3D7O*{FYi3AiU?`TqfTED$6eolg&&F_qf#J6Uv#diHgCQG71OEmFP`D^5 z>4R(rMr#N};R*q^13(wd=<4S;U|27}@xRdlVIKc-1qNP_Cjh9SII64@nJxeT002ov JPDHLkV1jhipVwQ)A-ZX%c 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 DQkSrp diff --git a/docs/html/img55.png b/docs/html/img55.png index 0b94ce1bb965ee459976ac7201259b944a088dd9..80ca5a952f3e902c0aa48fe67b04f0c2ae1dd19f 100644 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^{2g??N z?%g{@Ma45`&a7Iss-vT$tgI{~Bm}6?$jIpK-Maz;0=swb?(5F~3>0E43GxeOaCmkj z4af=cba4#fn3;Wu`+j>uC1miPV!umx}mFfg<%=d4LzW)KK8pTX1B K&t;ucLK6UH$VssP literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!py+HxR`CDK9Hjl;1lBd|NsA)GiR2UmxqRi zzI*r1*w}d0s#R%eX+U`w7ni$t@9y5c`vHgkJs_X4B*-tA!Qt5rkffKVi(?4K%;bcG zgd_&WbCEnJ8br@!F(jFZSgvE`V&%!n;o}TQl~HKobmeq@>Z8DLsfSM|m!~H|aT&vk nIqpnT7IH4!F?H6~MiGWz=Q+;qIsK{_XexuJtDnm{r-UW|DilA8 diff --git a/docs/html/img56.png b/docs/html/img56.png index 38055651c907a81af1dd2df94e83cb4d7434cd85..a2d8c23cf4b43a65f0f31bcf5248dcd38053efa5 100644 GIT binary patch delta 218 zcmV<0044wB0qFsd7k>`~0{{R4hnNYp0000mP)t-s|NsA)nVDr}WkW+l?(Xg(AtB7n z%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001bW%=J06^y0W&i*HXGugs zR0x@4U_gMG3=C|1U>4^D25x2sUbqYw0|$^~Vz|!0z5k?%V5C3 zuz+C$1H%Tk1P0DX6$V_Om4QLV0nB;`G~58h;0Rz~U{wII_yiaj=D?JFO<-UE0RPes U04_G8tpET307*qoM6N<$g8rRTFaQ7m delta 214 zcmaFK_>^&ics(BrGXn#o&yib#3=9mq0X`wF|NsA=Idf)td3k7P=(~6CjE#-YoH-*X zD7b3Xs8P+e;2AjRPFn`eKJrmP## ON(N6?KbLh*2~7YqJx0d> diff --git a/docs/html/img57.png b/docs/html/img57.png index bbdf4b88347d61afdcb9aacff51854eb80f9813f..e49a3dc80e403d2f6165ea59a7512229410caaec 100644 GIT binary patch delta 431 zcmV;g0Z{&>1H1!}7k>`~0{{R4%W?!v0000mP)t-s|NsA)nVDr}WkW+l?(Xg(AtB7n z%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001bW%=J06^y0W&i*II!Q!9 zR49>SU;qP7W`+q2P>{ z-DRj@V=hSe%D{IG7@5XEU=Nht&%p2>tc=B8Vuiy(hA7MR3^N*-e>gCe%akLTmQybY Zq5#;4LwK!LkC^}f002ovPDHLkV1l=}s+s@* delta 408 zcmV;J0cZZa1Em9y7k>@}0{{R404~?*0000mP)t-s|NsA)nVENYcU4tY?(Xh0Gc(N0 z%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0BD=f09~~i;00001bW%=J06^y0W&i*IBS}O- zR49>^Q87!zFc^JJORptY6Mw1KIqz2CxQ@7k?iF0{{R4?2$`S0000mP)t-s|NsA)nVDr}WkW+l?(Xg(AtB7n z%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001bW%=J06^y0W&i*Ju1Q2e zR7i>KR7-2rP!#^AdCg5HO$1?lQRg2RaiQWSvr*KA=`ZMA)PI745D_c|!LfpMXNr%` zfYK>;=VliEfGk}}pdu7naN(w4;fmD9Lhzp4%yeEB1%)p9B{}zT&UbQh&ba})V0UH# z91;W*yCTWtG+9;7b7w$r4eaRSJfAV>pTLm<@$N7AOZ2}pi332(=b7ZFK8@p;b~kyc zRTWMnr2QMHQ-0d8RQyan$s{isc8MXo8Vw=8C7!*4 zB&nJgONQq9>rySfm@dj(SXE8h<(bjokCYx@+%|MBgdNnR8d3g^l^CL{B5q%RD>3^Y z-@Rv$qS%=awsVa{n2=<$G$Pw{{q6?VR3@{$d7V99O@DeC-EAvjUU2=X$SP0~YgA2X z>0;e5gX?xln~I{Z))QeBWMrc@(pIx6VreOIp9~Hg#mws|w3^8nKEzESU2DdXz@KP_ zoEjsyG*J_VHm&obKXIlIRo*m1s%DTid`O4bZwJRy9r8Tu@(N5c3AMJWPAS^SO|36S z_3n<{$A2D%^D4D?XC=E2RXDx>V%<}UA>?zw?VVMdHrH+QOg@i+OFcy9E5#5rdRB^d zt-Mt@OhX0i-n{86mn`bGlrE*Bc%r-jtR3?7#d$ajW#Z^99EdUZdDbJgq8VPXA{yCH z2(iUt<5TGIMN(JaaGvJiY9Gn){RF3lhZv kMjx*DJ%~MwwvRo9Ul~EMBUUD9G5`Po07*qoM6N<$f|_4?rT_o{ delta 814 zcmV+}1JV4j2Dk>07k?lG0{{R48NL200000mP)t-s|NsA)nVENYcU4tY?(Xh0Gc(N0 z%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0BD=f09~~i;00001bW%=J06^y0W&i*Jwn;=m zR7i>KRXu1FK@|RWZ~yn!InERk0ylRcM2_U{Y73X3A}Y9*^?!1WV3k%uSQRvaA%~_A z8?Ug@#wFD?!K=j1MKpztTSzK}HBpI#aL(@D?d@idfQ?AV2Q%-@oA=(ld2jYDkb;(Q zbSxwu4nij;0vr8F`yA|j5>ocZi?7(k`wrX#&-h!YBSwk|bt$07ycNwJgu3gxq4b8Y zQ_O*ngA(jqynp`|9v>024l@?iGsVDSNDMaoFQ&?iyw0v5gRj+s@P>Cxl=|m2k#I6u z+<+)DeS@IqHwj;43dPusjzH6AxMPMQ`I~|4Ev^$KDc=eWi<%sIc3*&vl7_>KfF*eZ zGq)Q(cfT3V1(u_T0qHWU1R|V}L|H0D5-#CVZ*wS*iGOrKaV@G0Gs~*UW*Hy#f>M-K z-m;uuoaubEb$ufpln$f7^U6&h)UtGRn!X)M<&qgxt!DTU*h9@CsG*3w)+ayi z^`t3$_O0=4-SGJCaFID6f>juCr_9i2(igh>6l+m8IKuxAqwYygvXa>2W)FHUqav_| zdC{C`e196aH(ov;(&@C$bv9U+)$EL=3!^_dpju{Ch@M#c_cvu5LUo5?p|XWHu}hNm z;G!6Sn_YPXRJUxSGJslH7OD>%VI6}eDG$oP!igubS&^#U4-YYqg2UQ=EBgD4M%pE7 zs6h+Ya1z9oTYF4*bsn`3o5M7o4sor!yRDqY&cO9NNYV%BOmHshXc5Ae=z?@X^sjTr}3=4ovX98JYYYHKC6 z!|s7IUi&-6%FdL~SPI&=%g(uFyeg3i?C@woE7dkmn4r<=)2!|ej0Ab&rxNb0!&j0`b07*qoM6N<$g7biY+5i9m diff --git a/docs/html/img59.png b/docs/html/img59.png index 0896a6f55ed36a52122c64b4067d251836e9bf66..c06940f9d161f2559b72f781839e41adc6781049 100644 GIT binary patch literal 620 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 bQ($0NA;_$#rX6|#XdHv5tDnm{r-UW|(sw$a literal 3748 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 KMNUMnLSTZ$47+~- literal 3122 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 diff --git a/docs/html/img64.png b/docs/html/img64.png index 63497b0632474f618af81724b6460373bcf449ac..1653a0fb91fc0e56465b47e37259ce09db649418 100644 GIT binary patch literal 416 zcmV;R0bl-!P)#7ig1wye6M1%-ZunM}USWWFIli5}`O^edo9gD2_i zL+$+~9hp~_!2NP;-Av66sN^lWvC)ljDA{5s1!A!ry!DpFoB!1F_t*u_ z@bcm4d9d12;%xi2!fq8RcW2Z4(_#elS?_g)eg~f5zRxj`K@rn$UuiV7!~{4Oz$J%w z`wSl89P*LFtCPJ8Yy&qba9GI}2eZ|8k$%u*zY|98X8M!-O~L}_T{c2eh4#(>0000< KMNUMnLSTZFEak7F*P}Xfk{r_U;&4Z(F>yu6$S?w-!lo!d~o2vf&&d~(+ngG3}O>*0C|6| zF~$mU8fY?iGAu~4V_T4v$0o+gmRDD{AVTCnKP?at?KCLC@U)q2?+rzynFZV?%liBe)h8hau`d3{DK)Ap4|W$(dX&n z7@{#TIiZ2cjGfKGAi;rss)SMmV=>bN0fjJAj)H>{(h?F$@9*tBaNz8L158goH5`#C zc)3U}W5%fi8yGx_3)mXoq^{XpEuQmU$&am#Tj9H=PlCk+hQQN@-KxI_@I**W7nNtY zw1-K9DTimH0$=ivSOJD#JZcFHd@oaW)NODGUzo=|V>yFpD|Z4T!=g}GJB#I441g|U N@O1TaS?83{1ORn)UuFOR literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^Vn8g%!py+Hxc1!P&p?hrfKQ0)|NsAI&YW3ZULG16 z`tIF3V`JkpXU+%;3a(nUs-vSLEiDbG(8a~&?%lgeN=mzT@0OQUoC*|TED7=pW^j0R z10-MS>Eak7F*P}%fq_xu>3Yg62JssXYuNuG6V)9k|s;CJ1mk;K+VR7Dcxl!J0?yGfz3v6`$ZuPi!DAFU)*}g5Bb9p zC6K_7o9WDEcAd<4&b?LL)z#HMyR#tZ8M@~Fob#P??z#7zTLlcIK*BARBoY*+d9`xR8iENH~(vl3a-rKLXS(p1%WV0sn++ z(-5$gTLfuR(s_F9!$EGZT07hBfXc#1FJdwbZHtlVwu`~g3lf{A%cxf|oN$AUA?-_zZEow8F2z#?s0GyX-7q{iMIwd9@+OQx$~pw` z>@SFtCuplq8$nPfh!+YEUnSm!DRPYZ9&2$*?7k^;%KcTws_H1OP+LifyX+^6{($al_+ry=82)| zY8hkv$k^K9h~9sXhQ~aykFxVqdQ=QFJk(A2aXj1~)$GviEyCP?wE(LP| z1-$lG)(Y$Rp1HlkO+tCSkF4oV{pKhJsL zvc(C;^k{E!s$ddjGn94NUImKL0t(JKlDNi2&4u+$tOG5hW^hvqd|4Vc7s#l1BPiQD z;R(LHU}`7UK{u>{anlrN$oQX`YM#buMU7eHM^zE*Da#@FpQxp3G@j;{`KZ9>J zr)Q}3QGh3id(pFybDK)Uz8TMBS?(vX;vS9C!M6kPEoWZ$K0UMU%;#r}H+1(GE%8C_ z2*Hq|mQUrNdj{#+)3P*I_BK!@uGTBcquBKW@7BF8Kdn@oK4CQ;XZauIrru3gbO zwg}fH7=mu0Vt8F0)xa>74wG~gQKKclv!{dn<`p=Q(xGFPn`s#MER061gK%Afq3u5x zP{}!u^Q_}ZZ!svYW2JR|Nfj=tKFGD#RLz+>5uU@cKNpl+UwcZg_BPHhi8YJX>Wm6q zXw8>`jk1p17cLU+O9ay&v8?zKNSwft&Q%S z_;cLKWfpbnT&Go8sT0*WapwDs$mv*6qneI zoXf8^HrsFg!%yH9S`>|98)vbxU}|(GC6*vov_UsiZfGpv%C6iXy3aR09B|{!klqcO zWU_fN9-4*u4rbZ4BB`#Tz;2koOa`N{s@>o;u%ywMM~S7}=tOR4Ea2oW+^}w?MYwC> z=G*o#+uY%bj7p}ev}bM|}E+_$;Z5WfrX;4wZIWNz-e_}jCv{}2P- zf9&U9qS*${K6XZqsl zoW346+F6RPsfrI+IhG-Y?@bsUre&o{7t>0ZsvC!>fED@E?}k^@bwM1)VgAs&#t7yi zyan}@5_kK3=X@65kmedL;AeP9qcbV7e&aMAHSYGDc5?11+(PG_N5$GEI_Bv#ytcQ~ zg(U+|@tn1HYp{xw*GGTvGxs0kA*$l{FRLnUyL|CiRUFSG)z~a(U)uQ?h1(BnbS5R1 zazo)!gP3kh&Xqp%$ZNhDRki*nUK(E8+v&p6YUZU`#lKP6Nx9J`99zg4X7cexB2n;?)c?y>upQVdJO7>ePZ#azkZ6C zx)7fFQW1-$1Qoop*N`Zp7|2|@FB*aL;0RI6oGFnKUH02`z O0000%b{shWZKjt6R}`TSdvFe7$qwT-bE(~# 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 QX#fBK07*qoM6N<$g6MpRoB#j- diff --git a/docs/html/img68.png b/docs/html/img68.png index 5fc286046de65c9e8b31ebb08b1ae4882b8d51ea..364c435c1b45086c8877717e33c533a839d84864 100644 GIT binary patch literal 3213 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 A;s5{u literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^d?3ui%)r1nE0LiD$T0};332`Z|NqRHGt0}%LqkK~ zy?bYDY<%X-89_n8RjXEYbabSpr2!SXxVYTCdsj(GY4`5k^0JCkfkKQWL4Lsu4$p3Y zR|h2t(?=m#F3uJ`x$K4)fTSZK^W(f#XFb)cCHp00i_>zopr0QvhvMgRZ+ diff --git a/docs/html/img70.png b/docs/html/img70.png index 2539460aa3a028e10010860d8eb06ca22e135e5c..1e347c622a4aca6e42765a09e936100617422ba1 100644 GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRs!py+HxZuL(EkKSzfKQ0)|NsAI&YYQ=n(FNA z{O;X5MMcFkXU?ozwW_0|qpYkfBqRi=(8$Q>?%lfr0s^~t@9yi){|ppjED7=pW^j0R zBMr!D@N{tuk(ipCz`&FyaB#!SMsXkG56(XX3K(5#7`TiUFsrq(^Y92ev@Fu-h;LrV z#MQ7%(&dJXM1{S9gh4^`mjY%};{u~4jH>T`H&4kqxKv#H#FXh?3>S^~czDDVj>|9z z9dr02ogsa@PNDgC^L}T!h_g$geA(GM%vMJ(i2{0QhOnr`LIZ^rK({b>y85}Sb4q9e E0P$m3b^rhX literal 773 zcmV+g1N!`lP)KRZU0~Q5^rh+1c6Iea^mNAux%0J9sKcgKk|`DJX>4 zQ*_*d%&17BQy`48o&p&=Nf*}w*;|uX2%9u@>ehnLAt?tB(j|7y8j;HF&A8V1v2CXy z@ppLd|NZsm%>zQvmWL!ohc12D;LG?kmeGbBBG=Rk5Nl#v2d!@d^purDR*(`Wj@bG} z{w_dM*dcne0rhg~9zzG=CUA>&!-Vc@d70Uui^pJa^gg9l$TQOIubuuv!t#HIq!^9A zOWPGZL^G>EsFUMbOM(DaT*c}24F~4hGYM6AFSw=~^l{{5k+(kXYgM%xElrSN>XBMt zsu;=|%a@)Fnkl5slD$3Q-a@*8JhD@it52VAlW#c^wUdwWKBvnvDzEd_wwBvQ1KmTapzQhueW$Dul z?qd;Gkl?so%lMjyzzG=mif?b9cv~A{vpDb^6&x3w?<6^>Cb`J80h>7bAq;D_GObtS zkG)hjUqkgD6ZN~~6C5=`iJY=-gaAcCjb{@oo z2F5*^-}K6210yotj>B(u-MxEPKtN#k?%gY0DtLiHj3q&S!3+-1ZlnP@ z)t)YnAre!Q6B-&AG|rwqaNu|Y{|6>R>lt4eR@+z~W)V1g^&!I|E{O`M4^r)X5t1Sf zBFfE-9jjh2aK|My1hKIuuw}YEV(U38E30d8PKB*aPh)Z}FY|p{+a6?zl6{gbBq1cSjIzsCmNAo3Lq$?Zmcd|brR+_J8L|&!WGTyFEM-fU zu_fDBqA-RT$-cxp{r~Sd-}j#Hd;j16J>Pwv^E~G{_kEw=eO=e@cm1NRElrMcp5O!k z07uPCjlci^vmgM#)W*TWc(X2cxiS*r)>k0L2L}h3&zJ)j7Yqh-P*(@7g8KXW8QIGvr=5xwBZ-3SiqR3MzQC2 zL&yOkQ*+VW$XDHEwj(9nup$&n+nIfIiGU z@+wX_{Amr7xYRf6m(!6=99)yU=cVa2O~HlZ#1(&yPJSG)wkuvzaGhzMFt9g1|x9=VbSXoFqqznL#uDK19tC=a-v%#;7}vG2Qlk>ANpDE}JgPwZwndHf&Bc`q3wtCU!f+ z0suI7%=w6m!T1L>sD`=iOpMBUq}C+|8H5|{<{h%}P-Fc-qXhw(?i!@PbabAU5?qZ* z$&}%D_mMXrZb8YDhXk)XJg*lcWc-xZ;=+*-C+!FgUbp%?fzS=n=K4o&$&=F*gv-jx zQcU&eE;o5}ByUmf=zS~PHS(>X3bU7n*GE%K){?_Gr=ky6ldMNBH&r7P2^{Xr@ps8d zrZM>U15pGZ3!ZVJ0030HXH5GgT}oxXX#Ab*ictC3CHglt2Z!yWEGNSD?R3L1pB+>aNF0L zKd9MClhLMO#kG_g!koyDJ|cSiVpV#q4k`XPp-Py^r=oujKf61jFrk~RmMpaE=Y+zd zcNFqRd)l3L>92rG=bjG;fPu=a9|ze6joAl{S*W>;hbc7s-R}>4#d2`G`xC|%JR;sp zqH7EUMiaIPa!nhBNgnA?iF1Th6-r{UUTvRGryuRe3-Q21wjH-7s{5xlQHn_fZD2 zRxsKzmTI!HJD9+cy|wjTckx#JPr+7&wpn&6^C_tZmY9pcwu|fU6o2=3+qSs>dL`u{ z$s;apevIL-jLalxC_wjlj7QW=#f5DH=kRw3`{pkRJf}gI4@t-a06bB3!yT$P zxmxK}4{zGL?Z+3BRl{4wM`(J8%7k{D&bYHZU&TtIin=y4`9YEk7fwxfeqZrYU5KMD z>+qctPULi8aq05OLU-BW#xnQX#p%vxjB*h)H1+K!OdRYf9n=CoWNvO4RR9JmmW zw(@0;)87Vut5oe8p^~Nig=}7a*_!#LWEyTGy!7hOL{$5=0~@sLsI$no7y>~Nw$Ni< z@%Zo?WaX6BUa5P&!ul(cef#B#^SZ>$me+`l!vH{BJXRKUbqAsvwCR&TcbS zT@S@9?t*=m^-x$E-~jE5-I74Z2Z@NBJW8hp(^?9UoQ~N{m5L zZy7}hTyB4i9X^piua!>X)40zfQ9EDzBRp8y6ZjFnfiS>OGK=x-3z3)o5B~nB%&5 z1JaBT&66472mLNv;dLq4KxJct8VrhF5Iea@4Xv#WD8J~p(G;lo6aA|8_#!}S?Cjpc zsrG@_$}a{3%H;g{2RtU=MH)T0B(xcutz%FyL5JRyyqhMsTQzk26s`4vRlV^aGJ;MD z>N94C>OWizgN*CRM=)e9iWnSX!gCn>p==2YH%i3Rn1_KAiW*~-Yw(p}PCMd~ow?d3 zf5p8Mh7y7@Yh9>@;QH{|Z1XlA1KY>5N`fL47j`wP_)4`#(N~4eXrW0dof#?tgo_Cu z1C%(XBu?I|vArABX&F*`X6frb0MC}Wl*Ua)h&?n&r&(WfT5R+THKN{@$9sxCV3wj1 z&vdL0Drv4XhC>cXc6dNo@g*!^FP1+>EM)M^j+Ns0Q*&;T^!d^QQ0!2p;(nVAT;U-s z;8|uTLFj*zVrF7a#S%dp?Ea{J;S(zu0MA6~9*?*Q?@)sWUZTenOOZp*-g(%V zjzw#(oc=fRz87d4){WcVskkrJJSQ`H#RfgIy8PwXl({p>q8tWZ(fGYlgMW>GZ>i?H zv6|=(7mCw|4yxg|q9AJ0pG=FFf1oCnv1IB_nNu-_m1JeJ;409h^Uu&<}p^qF!? zkuzy{_J6K9h8p*@?(0%N-~|c0Ts&VOhI9 zvEY!}=rl=c!jTc;Ti>Jos+|Jl`$oqiwd@x=qHk7{Q!)1)xxLKA zPZKhmu)WhL=wjBJOYj)#1tsE^+&F)32 z$7(O!%fFd2t6p^E&8-ag=KP#krAGNuP*PjGSk)Xv5R8ag%uphFOV243*)|06Sl3+9`C3~us92~ucmV(^}J&NExYPPS3L8GQ?Q z22#8j+8UYSbQokAXnZ1IpX_**QlsrJ#%tfx52rRq;z9CDAGE;}9&m~%vBPa99-^C_ zl#{1#vDW96D-%f3?B~1W``R^H9AsH(bWBXvKKFS7zhb{(dvppV=bO=gSXL9Td!dOk zB~(8F#1zE}7_>iQfB=@cm33z4Ws`#owaW^)1icqcDb-?gM}5ChTkVWzkT30hYkJpI z>=R@tnq~mzKuiMy?qCD{r`f z-iw8AS(aV$>q;_k9uIr~gwRpuUZoZVcIta#v+Q%72xk zx=s@!*em!d(}@|xZe{m@haq?m(+(%4Sr1xY!;NJ1W%*jqOw^$$WOK1VS7tzQC;N_m zEs1&6OVOJ^7K}46rH2{LPfb*tN0)Lg-bjlqt$NrR0?y$oj=BEd5Z1lC7~$NtI*D%c zPDhM!ud)%Xr>_%(VZXGOIvbo=CNcQ;7FuFyYzdF<4~{FR71;)6Eu1b(>BT(+mM-gx zf2+^E`1(y2&KpTCPjUM31s*%cLRPI`rpq?AbspPPW}2))4Y%|-*dgB*#yGu%9|eBQ zz!YID;&Qow)IQb?!NXH_BjNtda2o@^4BGp=0UM;F*SfUdXz2|84YH5_K27wm&IAy|Epj~$pYUcBY~9w1i8(ku%rJ=VDLtcTsD;J?~o5}}SO zYR!4i>AZ{rI_G5`$_`J+w~P>pg2*0RtUv+v#K%izZ!=~1U~bUB3``w8-lkXK4@$*K zl&rVL5p5xLFo-g{+p&_~U61Do7Fgk9QCOx}?-%awrCN97{+h-lVUps#`9b)?W^4g9 zdGh|lZaI;?E%Pys#95LB!W~&OdpsBcb5L3gdP>sqM2c=HrsT=1-$UN?S)Z$nTKyPa zDZat#yH0AVy9&QG6?#12#J1EX<{8&~iN&u#s*2xNu_PsP%^(J&B8TU8ujKe}-tdJ; ze-goeIXr;{5qYut0c(9npA>~D3CEpO&Tsk6+_?z7_5_BRSTIR{vRGj72$OhirLV+V6>gROrDZZWf=e3MofVyrHk>YMu#>MZw z=!(`M_h}6oKu>Yx#;-P?7q^Idv=sPJnX#B*Xqu4F06?@=bLN0p+`DW8}uiKV9} wIWMGgfIBtb`1Q+m^q-YeSg#>o;pP4rYIq2{(+pXz<3Gs4AhJbtL(=?|VxU79JYD@<);T3K0RS1l BRvrKV literal 5450 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 diff --git a/docs/html/img73.png b/docs/html/img73.png index 6cc3ae5c543f5728efc2e11ffa2622bae2cc0a60..ec9322e9321b69118a78d7f0782dbd6da88ec5ff 100644 GIT binary patch literal 2512 zcmV;>2`~1EP)R#1#k?UNR4bl)|cu z;H3{yZ`dT--EOm-`!n{8?e#i|6D3lQ*4M{p&fh)v+;h*J1key;5JVh2pzktD?_wO> zaR#!l2DN#o8UdxLYKXfRkjKWq;uRkeyA$m79E)>x!Nsp$vEPq42H4zS3xFe(vTOJI z5OAEE`O8&A^7lFv*8xU-M&72`$8ZzjYb4&r1< z-Qo0f9LYQr4pJ>+rNmN+ox18@PTG}!GhX+^c^H? zrSrjDN#=$@IqiH-4C(Ai(l?1!_fD#*(ZMgrM2xD8G}ND`!Dx`SqH{44iNNwvP3&*B zr?6a&LJC+kb-}UWupdW6FTP}dbCJe>&`3!wgH35zkUtPfY>pNNN>P8aLWWor`CBp?bH*lh85<4R1tj!E?C{f?x@yG{##v`RMuL(MaOfB$N2yu1&z|99IFs2z1y(SqVpA zDFa3-oxK#@OGl`;324wKFHftR=TK{qLrN6A+wFRwHEUE7hiXy5LM?iNEr13*kwJbS);9v)rf&??^z) z8V1olXQWG3^Gg-39co36i58Wfit87B=@2boOV*VT^4n$Hl-E$;A%!BtW`~yQ9sa6tG$!THB#4!~=f44>tkkI`zg*)gk7k_D`{A z;bawevQ4Ag-52x_y5K+-*NeY$VN99pUl_Zo!hY1B(6`?;vUm~qM(l!i$le;6i+Gjf z+)12Tus2o+5z7mTf5ZC!xs&U1lMV?6 zs$+)xhF+iC`q02e7$LC|9twv-I)wH|)IwcRUH;jIGl{A3(lmwK20PDYDcNg(k!fHZ z8s8rtiws_xCIN`9jT*ZO-z=6#wp_9!+jRQDBY4d^BnaPVP|v3b)U!=DU&9!Ph1xgS z^98XrS&S}~6khz6#Iq&VLl4NT?|m`U1^O1+Q?R=-zOZ^tU-eWR?KQ_=l_N~y?2o`w zZ;kC<%Ju%`>aJhJy)`JF3fpJJL5!Hw5NnZSF^2iCtYddSI9c^-=%O)rj3Z zFn=-WgH7FqY=rDxA39DCPb_jQtvRe{?lEHBaEjeSPuE6rYWwK3c4933YQX&InlrFY z9#+B+eefAcRTerx8OU}WBopjoPb(QZ({4@Atk);$p|Hql@@3t{Z4a{H2wYj6xhd~(~4o-UU!9+>T?!4=TB}BTL%U; z4kw0FahriNx^*Ar8;kehHUj&)bI1%v;Kq%DuDrg6jY-q%-9UR1ml5P@K zu5i_sYNOr_-&vu0%E-f_)!5}J++gW-%-K- z?DBFfgq=j6vXG6C3G@MCLgHSA z=<{`zO%fi6We%BDDZCf=N~*HZxmctlr1Yj#EQ!1j4wzpij5YBN1&nc_R7NsYfA7AkW~02=nx>oo#ozo6UECF2u`Yi{H_Xv>4W=82^-qE< zSu^ic#)1T6ZOn}W$*P2BG*w%;++(P%H>G06)ed0BqQ{aRwE3h&OtF<$z6?j(T%c`f zEm_;XoP(R$_8t06nsi@3f0eht8t#%bl^|~o#qRchx7JBXK8Ti;)6J)gvw7mk* aS^a-u&;;%i(i?XG0000KRnKeGKotHmn`X0{-6V?8DnbVlY!B^v^cYG#NVjDV z9=y4V2fax2=AkfzDhP$9(2HJnDIy*U=Aa^0+~CDa!JrFz5O)6n#cZjtv=p7mc7NGM zr1hfs!OXn(=6i2mX68+RI4tpIfj|X<5OAWIMa7R7HmQ&^@a*O_>(*QA4?=)j5qfKCQ+tp6!v9 zgM7umjc$2F8%B0-mfyPXgcnL1r+L$XOiN32%uMt&B@Sl?47zTlblauKFQ`7=JwcYwb_;piq$KU{m*4b2PQG_Zz++=*b z++j^LTxoa&qaZGn;X7O}omvjwLb$ziOe{7<=%Jh=+!UVqYutyAaiDSnQ(_5x6>)B} zcEk)-oI13PI%a?`${5$#JopcXyJaXU<49S;ZJBcm!frgltZEi3Nc$dEL7{Na j`@y-rj9GS&ka73{Ft4wU+K(q900000NkvXXu0mjf<&<*O diff --git a/docs/html/img74.png b/docs/html/img74.png index 90e36a4d75b43c20cd37a67b86b8d25fece54d58..810b69c986d264816c1145ebcbeb1d91f3af1563 100644 GIT binary patch literal 255 zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)o!py+H=(c3y3LwWIz$e7@|Ns9pXUXz<3Gs4AhJbtL(=?|VxU79JYD@<);T3K0RS1l BRvrKV literal 368 zcmV-$0gwKPP)SU;qM67DfhS;Q9%P!^Cg_NOG*$u$AEh19rgAumMOi zGEAGm(E!!~1X?)MVgnzbdVnCHAm9M^f(C|!13-?3gFya-AKtqUP9woEJOJoQ12_k0 zfdZ7N(eS}TVSfTc=O2(mZZItPps;}f6eQf7toIon0M+sFGBB{UbA3=`n8dxi5#(M@ z>NtsNfE!G51fYv6fl1Z|Bq5e~hCr4L46X?r2l^cT0R{5;w@d|6dSU;qIwAYRFU0yr527>->)74w<^A{Q{=2V5Y{5Ho?` zCIb%v^=S6a1X?n4CPM&_&CT$Dfnft5C&=0~295@{1ehv*6Os(Y4<-lz3E`Oz42+gj z*gyhI3>z326u7}Y$mLI9V7u_G8)WqY2DrC?Dm)svp-zrvIFK+E9#$(FsOUB_0i(R& zM*&RX5{9=71z=Vy1H&Q&gF^wT;2{IUVFZH@>L-q!Gl8Ll%m4$v26P4(^Z_yRg&7bA jD)`9|@PQ293_1V+dS@(WW*K8i00000NkvXXu0mjf7?E|K literal 502 zcmV;x1(D zqGad?h<~6JL5iDBegn@X0I{QdSJ<7_(1vKY_Quy)SSPpN%dC`NJe0j7C@OV$29$JbUm(I&pO32K;gBf7q za{SVxB~s=-Q_p6^V4J`N4I)tJ^HO!2u$tBGtcYG!RuL#aky6!7VZS5M!crP%(Unw< zal$$UWM32RpyHW~!)8i!9;7y{>5wycpcHV*O@Qlru6S^!x+VYAXx|-*gC{wt;M!DN zkuZmm!p@Z*&i^#x-;`OEcis8UH;@+nVfn%s)?I7eZ$R&=^%KhwGpAUK8F!?cUgI2F zcnrQ{WJi$eMfsZLud}Uwll@;(Z%KRY7RfKootG&15&(#tF4qXi_A57-Yd;ib;{7Ghj49w{}>rC;hk z91!HrKrE+?PPSR>Us1`}>3e_-uTX;Wcn|^)3%v*s%DgQ9dMr{Y;)&xQIZf-CNR7&; zCm;ECW%xf(04Dp6okEhFBhKU@jt zefC&=%zos~B7dnzS30#)q9~o}bVmTKlkj*ZkPN>!A6m9$$5d?6YdybNAh#0N%>vzE zI*0aqD zS0PyqMi&e7y!Nsi)8^4)O;TDm^$Pd5P5(Db^d{9g+q7mZYDynqub?F-R^|is+5{-= z4>zN6iq371^>!hjTJT#}F~?R;5c{Tk8?vDaZ7I2Bif%@f-`|`>jD#`VUL3=WU}cbS z?8747q?4|RNe)HI(<;iEXfnGSTXCB3<|0`HHNC{ TV<4uX00000NkvXXu0mjfk_c}T literal 326 zcmV-M0lEH(P)SU;qOFAZB5JflUo?CId5s;@|Xv;R6GHpdi2j)aU?G z4H4iXpaG%_iEVIz|G@-?gaaVgG)P>~_`Un!G$vvU!3}sfV7H6q!VQ7>7Z^JK0NG3o z3Y&oLW@KPxVBo&ba2hDY$NPzaf%SqC%Mb3|jUPCW%;2QVJ(Pg2*o6bJigFY%n+a diff --git a/docs/html/img77.png b/docs/html/img77.png index 650cef038e8ae6a036b12d2bfd68e2438bb9b9a8..2a05686fb7f65bf41e7c0826bfeb56324d8656fd 100644 GIT binary patch literal 5441 zcmbVPXH-+$whki2P!ED2RYXA$K~WGwl_Et562Kr3IwD<204YIGsS1ap2!zlfBtS%^ zCNzmO1*AytqO?c?QYAuOJomlv&N%Phd)|9{tg-fwwf35Gesg}`Tsz?=*pLe-3A3bR3U@RowG_^9I)9G1RS;3@WIv!6a65WaJbY5P%`>#i- zL`f1Y$ynCY)1y!*fZqYr>(g`!g|4U9v)m&oDcRH0lQo!y!{O*XJ#TLN?z$L;_C{O-p3*R1a6tf9Fcp;Y){zfR4dC!^94Vlr`NUK0~$SLf;U zCgz{rac;&&B+kgZQnGuTU@zyR$4@Vrpw)yORAOJm6=PnM%%8m&Gtbg>{jm9n)6IL zDyovq=5b4+WsS3smr_z`-8ycA#98EQN9*mQDY`qm5({;|wekRRQ@?M>HIuqgBi|<` z+zxNmW=z!Dd#CIFhV;Y*`_B4#RYLV0kF;`$#{qd1ulo$pqF@_)neTv9gJaR11#Kh_ zhuo+HXC*00{WbgiQNN#y*K^auQoX10?-Gf{A&>a$FR`0nEtRm?sdmt)ms3J&EjtG) zMNm7uO7L{$>JtkS(l??6G=R_I1RFI%uh-hupeNX@dAuH!n_H?EL>oq{kolo57skVM z>yJhq*8n1B*uI(CRA)eXZMh5&Amg@5eqT+zg@^jq-k$P)AOyNvT~obY88iGAD4Lm%tHP3sW?dr}XUYwnx zerVhtXc5g@PCr(}pSirrQ?j?*(l>Joy7ncdGfPeYDs71o`tfb*}1~lJP^qYKqn8 zvwcf@#!^O4_dW^}K`lBAHG&)C@FRDd>~9$lBdMFOf!6+(s8hS|vcE&|>Rf4QW2E? z5K~myl2()i0LL-2S~Ca>0F0!36v6sln?vv=g|6O3apWu(@-1R>OlCgpv<%1jx8U;1 zS6a$qna*$99qcK7(S?cEN7?`S5RqAW|Bgsr!`+lnuYs_W)meydzT8f^peiv|_(1m( zw$#zM;?Zc8{~z+?CEYji5$Gf@Cr= zM*vYW6Eg0rd2_eZg?(b#8nVSHo{{TI7T(4hxf!6Rk?I7Q`&xqn28A_Qh#T(xC(S74 z18bHU!`fzT=k0LbMYR_YBGZVx2jQI?Wgpu&%4SQ)@5n=LWSiZEqzZc}R+4Y0W85o; zw3DI42b+rys!d=)KVOcUC&?7&Yh|OD}7`2ViX`gCrnJ?j8lIdinJsM97lr*6#OaL|mfA_ck}R zbfR`dOEC1db!^|QQbSmYb!}mPar0|21k%8rLnRgfXq8e$zEOYV|3qS@U({!Z9}OJ> zrTKD(j_~Kp<4*}(I@PFhrCQC)E(D#TBBII_vEZ|S1%s=XWTa7PF7Rkes!G7`-QB*$ zr*RCd{iFmee7WxhieTft;8E$5Mg~?W=A5bPa)lG3b6->-zYQ+}Wa?5A%T(A@8{tO1eD8%cX@!=vfIkWI&%Dwd6vJL z{`X$zstDxZ{Xb`~v7R*_Fvs`NXtvH`2Fpvcs∨r-oIEpMj-Dg^*VWdKU>io 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 literal 366 zcmV-!0g?WRP)`6pHR2Y?GU;qKuQbsV%u=2`vAj!kPz{bG9k>KdV?!bTqK0qi= z79er#z=aDO3|N3c1BeU&Vg){i9SjQf4jUL0uqi|V9}a*>Fu}mVU;v_k=1kCHab>s= zpzvTn0|Ore6aOU+27TTSTp$dLO)U9q=>Px# M07*qoM6N<$g7UYPdjJ3c diff --git a/docs/html/img78.png b/docs/html/img78.png index c3fd2d55f938f626fca0e4773cd6af70e59006c3..089b17f68aa07803d55581f1f6ab05a4bf24c073 100644 GIT binary patch literal 6161 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 hG002ovPDHLkV1i9mY_b3V literal 2461 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 bo4bDksZCi=<1hS#00000NkvXXu0mjfKtiG0 diff --git a/docs/html/img8.png b/docs/html/img8.png index d7424dc1e6e7b1be704d0810d1c77cd23d9a6cf2..1b047adf84c55634bbbb57add608cdef62494032 100644 GIT binary patch delta 227 zcmV<9038440rCNm7k>~00{{R4On(TW0000mP)t-s|NsA)nVDr}WkW+l?(Xg(AtB7n z%&MxYh=_=Gc6L-$Q~&?~GBPsV-Q5rn5WBm(j*D;e00001bW%=J06^y0W&i*Ha7jc# zR0x@4U|?WkU|^WQz&@XWiva{U0vH%BfJ7i5k0F79;Q=cH16;4x6b57vVh1F)03{gS z9{>^sK0vJ?vv_tkpr~WG!14u5-)?g71Djecz%m^yV&pmXIf!Q4!oV;O#9&ru;9UY@ dTw(hUq5uT973%Tuo7(^Y002ovPDHLkV1gxER|^0D delta 216 zcmV;}04M+Q0p|gb7k>@}0{{R4b)#!a0000mP)t-s|NsA)nVENYcU4tY?(Xh0Gc(N0 z%n=b0s;a7ph=^upW&i*HL_|d0-Q6N0BD=f09~~i;00001bW%=J06^y0W&i*HWl2Oq zR0x@4U|`^6U|=}F!2gMX$pOe>;QYYAyMcj4fdK-V7=gqFeo+Qwu$3Jo29j8Dkb!}X z0m$W>FabqL@)W&&2_VMpG6vQUAcngCQm_C+1p|XQ*rEjt43j_%A-(PEffN9`RT9o( SJhGMm0000SU;qLRMm7dyz}@A5;4m`?07-U*cxwjSU;)S!h6xRf z1`G@iEDVen7%K6oMh6oZ82F*gfCm!{I0FWT^002ovPDHLkV1k=tj=ul^ literal 373 zcmV-*0gC>KP)Hh-PMH0000)L`2=)-6A3)ySuxWH7^|i z0004WQchC zVCEa$82rnoIsx`pI8tDq+00000NkvXXu0mjfm6M*e diff --git a/docs/html/img81.png b/docs/html/img81.png index 6619889af70f094701afe63977363ddf4e29e57e..94fe3652d8537d68dd79897452c2449d2bd395ad 100644 GIT binary patch literal 523 zcmV+m0`&cfP)@Q$0w-Kp1`bF+WYy21QU@Ite<(*(D&N;F8JJEIK*F z+NDDwqjtK2sGI4cxOH&rq9EvIgo27lom>r67bh=CjZH1u4laFg$M@d7`|i8%5+H)a z2<>S9-9-{g*=R>D$;B!MEsn+9+B_g1Lmx%|h|iHg97b;wg9p>(Cm`A=2AstQb3Z`V z-XK8sr)oYET{d&Dd^zM_MO2@(Bl}RPSKsI+_YTluom1WK+TYFp4Qh=R+iQXJ)GGzt zYF9wHl#m%bK+}DK5sZaGbZc<3(!{Ik(KqF=m7k=o+N*l>)G5y2MNz5e9S#B~2Q74| z&d71faj(pZDVDe!4(+g)EJMJsV>_H#(x3Y#oFDsep5Q{%v1z2OSyU)@II;?{(_w#y zDUvnQzHo+2sfO!7S)rrVVb1CuZhKK{NrH(vRhMbuqB}#sBI+*KFEUw(+~QKkI*9!1 z;63mbeN7{v4On6BhU8>0?W+cLtHzFc8T<>U%YSr2`+YeHeh~9e;1dE*Ry2KGnsNXD N002ovPDHLkV1f}C?6Lp= literal 539 zcmV+$0_6RPP)ZgKpw7+iJK+C0jP@iC^j>Q2N=%UK!RoMw(LwDbNNH3!ofOgmR%vf&-6X2~5ld zsKfzD4L6($08+C#Qd}0eC@`=B*^C=D dWdadk0|0fDyK1(&+^YZp002ovPDHLkV1nG6$Rq#& diff --git a/docs/html/img82.png b/docs/html/img82.png index 44cbaea8f64168b21eed31eebc65797d5587e2e9..e58c5e69115e601b611398f60657d85c85417cd0 100644 GIT binary patch literal 334 zcmV-U0kQsxP)SU;u*z24t{91i@y8((wTdgusLej0Ox04lE3eHz5M- z1hs&4A+rrQ4K6SweBftb;1!r(FkgE2!Y^FJ7=jz{ZoqCA3&TZ$iv|>UFd4{c zV4e`h;13e!`M|b?fv;=}M3Fa4^=A&Y00u)K_5kW!pvf?yi_@%07*qoM6N<$f*{>~BLDyZ literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^5P%wJ9C;s zSz%$qv0M{H?u88(kG6&wPiQohcrYQv;hDsQbAl!!OAlnWG#UyqFuZ)u!QOJWb3f2H N22WQ%mvv4FO#pLPH7@`F diff --git a/docs/html/img83.png b/docs/html/img83.png index 2f1e81d34fe3199e8948fd35c3c87a2d6ba2a515..ba4e52685df24da3b09109bf393ba8c705e6f841 100644 GIT binary patch literal 363 zcmV-x0hIoUP)u&B700001 zbW%=J06^y0W&i*H=}AOER2Y?ok1Pyd-YrAI3rL~3BvIMK!+{#7Z_mux(-toIbchK`@^s@_FBXqMX$>W;`xyBTJxs91u zBo)W*Uh}&SyvXDcABUa;pVwVxM_VP=XWYHTr#`~1*Fy9DlrKH?GF(SRD8T>#002ov JPDHLkV1ntPp#%T` literal 800 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 V|CEWBkb(dJ002ovPDHLkV1j@!@ml}@ literal 1401 zcmV-<1%~>GP)RG%l!+koHajol;;UDylfwP=sP)MbQxpu~j6x)kQ)yAcKT-qCk5Gh#ZZ1 zZ)V5#?%I1xM8orWcjnFe`R1E9<2iuSh0|X>0*5-TR2@Mi22eM`&s6NCQ8a)$2WP~= zvSd&&-~Jxq z)KWea)bE=O<BQ1zjyf0}jl$syNoD0M~J}iOp#YUpFY`4=nClz+9L4eM}Xq zELafaDCJlO9|Oj{?zrpgmLbykSj23KqYeTGzJdV{;eDXB!qKV-S1Jh{`gZ_*g#%FG zjb$NXf`A1sHPKm=w1`ZO@j@UDmpuni6MD{L96^Gw`^)%76xvZj5iK<>W|LSNFbhNz zvaqWDI|)@|R(?e$DkWQ#UPdFPo!!C-DMKk2Ms*s1QRj3R1*MZ#7`Q1Kp@PwAW7^Oq ze1?goEKHgMo#AlV!y+`mb7y-4w}xNGf`f4!&Gk$JeSQSAh}uK==?FOzu!7g1W3iK{h*b3l2g_5FATwnOGv6Vo8iHzO}KKA5_ z=x>I9#lirrx+8;fiTn{vTi@biK^d!cXmoPXa=SGB&U(bdTB`s1XRa9JE#A4b~7Sq!$KGR{KSG#R~xTWqJrBvgPmV#k&H2g8G5lQ3WmN`@&JER%nA zgeeKc-J`VJ;PgAKUno)DO|_gim00002bW%=J0RLN& zBDDYj0dGk}K~zYI?N!lj!Y~khAO;}a07fAF=)c_oDv=SI5gbNHx`8tS9l;&}kI;+| zMtJ=&307mkLRHmDeLrWNpWj{1=gW*3Fh|jzmb1`1;_RK5T~z>p418xIzd{pSkxTaE zRtS=$U=Sr1E)w?|ZH@*ln(7$%NW+y8q!7kulB$*BisgUvU>>1JU=CXVXdxv~Sr=|w zYpwN5Qj@F|mDy9&lR{H1b+oQYA9OeCXCodbEE{3f02XNSu0-`vbrxAwG;u*vlY&&5 zf}60M2V;yO70Cr$33RYeFL2no9FV8j;hl0zQkgw#MVfwcL1v?(U3ga|{yrn=gTI^(*zXXu{7<~O9G(02; gjrg5?^)HoHoSo3_yNyS;espx~4-T@s}p2oDA zp`V1Vu+C9{y1k`|D&JzwGI12l)Bzm*WemC`Xv4Hi!c|Tqr{1(l8nfZLEBC{mWGenX zOhfo!A%egW`!V6PTAgkc$Kq9nkj+Gf-WrGJKZPHvswg;V@Py5hiMJuc3SzUIg!3t$ z)48RrAKS&-;FUD(Yv#Mgkn3C@6Jd}Dr5S9eJGyRj=m#5N#2DTSQM03T)ygn*!`8U& z;ssa0MMy<=LRQpWn46ty4^0#{dyhB*zGT~Pl9%3es!?MXC~@E{QUe^K@PqAk3yI${ seYHH4Jk!Zdzi-W>5N@3RvMbEu4`Kd9_iPEVw*UYD07*qoM6N<$f|$SKNdN!< diff --git a/docs/html/img87.png b/docs/html/img87.png index d280160a6ff8a74211c90e54066367fd400fa936..0e932c939803fba4d723ac371fb57a190667f3e4 100644 GIT binary patch literal 554 zcmV+_0@eMAP)KRKH8ZP!PT(P101;7f{e{annJF;O?88GdkuEaL6Qd zD|YG@+yY`F6#NJJ2Xt_8OWit%gR|JdA6SI=?j_MA7#oldLO*)V-TS_KclY`lfDGtn zCwS+c$38NYp$;}|prd+RS^>Huzr2A6x>HI13yfSO;Fr|^qG@fQb$1;=;!9w%c@9}! zl<+0cc&n=a*A6NJ%ZgzVOquN#$S9h!M}y)VmS$-qfB{=JEI~pp=^HNMnFHv%efOFB z4c)ymv*dpStw7>$cAKt^*hMlk8t?0Y*LFJ?8{^gh2#duQY?&#kL{Xw40Xtmd0JvtR zlAwcJW*@9&6L^9L;I-stXxo`uYxpC#5J+WWM43gne4ven<4GS z=lW&{$`G0-%-UX_U@yI9C`6pHR49?HkUee!F%X5n{n27z1Ka>3(WF6J=0h8TLi3Z{P4Vm zzV@_6#L6i?E73yu*;A>r1l9HBN0os3gU;2ZeidT0si}k}2&1(uV;VM78CjMgZC^IB zYR}VSlgi=2F|l_&#ck`{fH!zye4a}Rf4utGFP6lEgG_TiGx&13Zf7nS5%sLGZAI;G z#+G-!-7Q@x?;m#ioXKuO*dsc?`ZOcRnpW+}tI6~6f&0(ly^a1GKOG|}7$Hr9wEzGB M07*qoM6N<$f~td|0RR91 diff --git a/docs/html/img88.png b/docs/html/img88.png index 89a30141f4e44021229186d55eba774c3587d7cd..00cb49e66f50d6f6633a448d1ee4f6467e554977 100644 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^5gec5OG^VPba8RHd-txAlG5(oyX9pSrvil-OM?7@862M7 z0Lj;Rx;TbNOifMzf}n(k#??H30>pmTcD#6ZSNg#w`Gg*|9Rgi85;8LuFo-1e;N{;?}8d&19VRy&hzMO9+kNtGWB4ZjaCFepw^5f(qK^b+V222WQ%mvv4FO#nb_ BVHW@Z diff --git a/docs/html/img89.png b/docs/html/img89.png index 168fcb95157e5a8d71ac20bd4b63beb7f0166f74..3a49b4c5406abe6810896658914b9d4f420b6d07 100644 GIT binary patch literal 939 zcmV;c162HpP)ND00002bW%=J0RLN& zBDDYj17t}=K~z|U?U*fh+(s0J-%U~2rvE@HG?NR>X8R9hTDA!c8anUR&DVsf~ zq;Lca$7L>?g*BTPmOTaf*tNZJyovYZ^fWIR9nIYLe(7rFN;7l-FAh!Wg_=eib&|BX zT&<<;N*i$(9)Q_VdZm>lHS0~I)ncW!RuaH+Qk(1}dOxW4qqvl$tukZ)S}*_via8Mx zv5;ZTu?{@9ug8ln9$W3Cg|r@TX>m}eG2w0UmcnLB09xT(4Rx}j2nApmWL*J7Z-(c; zBwz%Fc2^so#}Q7G*Qeu%w0?1=%@NX_bUxiQcP`yd>hgu8h14vxl_ZtJ`g+rKUDruc zv(;MLQY)!ZccoIzSU#m*Nzz)2a`AfNzxn3J+w<$$)!XaY)%Wk-y}Z$17graO&dVE(A?>|?X^?bd)zuz2# zzLp=LJ?5=`I{r%~_5W77oqZ~`um6Ex?&cc_dqibc`;{5TY6U2E^BHAG&XJr4vWvr} zi<@M;$2y{0V(VWDOLUQCTSve;p8?xac_zM>1&6_rfJmTsrU)T~5P%|NL&C8nKm{(Q zP=f{6AI%1Az>a*Zlmg7dfRAB_)`P*KL_zqCltw;QCeT`FJ(6k{ zGBvQ*CxjLo9Nu|MOUSf-Oipsb1Z?nlJMl>eHk6N@RwFF#;8V7rwV`acWqEMnB)il} zl%4`7dG$|$uZ})9zB>9iHrr#QSCRx{!~X0jrr{paoxSpo{pG>K(gp<8!KUqlsGllm z?Ks>=b@y)1{-M(Xz-09S#VSJ;iB-mq5w>6~MT9)*$_Mp@0fn^PL>JKC~aKf}tfAfN}jb4}!jCX~E)iHGQ!XrY>keoJXkhK#c}M zfdge+KV%JB+rEY98>-rq3r8@tj1DBTS1gl#zC@2$YMa}qw!_ID^_S(#;$PjL98JHyIoJRI N002ovPDHLkV1lIc$g}_e literal 243 zcmeAS@N?(olHy`uVBq!ia0vp^(m*W7!py+H7-8Vy4CJT>_=LFr|NnpH%$eoo<)NXW z@7}!=6ck*wYE@cV8c^QF#pUkZyGlw*yLa#2SC>8sD8yJ2zopr04vf{qyPW_ diff --git a/docs/html/img9.png b/docs/html/img9.png index 2a67babe3b406cb9e514810e31e3e786e3357838..67fce13f6e07538f34052ccc7723aa4a5879ac8a 100644 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^fCnKP?at?KCLC@U)q2?+rzG%_-}d-tw@fWYqEyZgHHKLdprOM?7@862M7 zNCR?8JY5_^IA$g%G%)3{#j#l=JWEeVN=Wc&D7yJmQmP^3>lsdmO^u(Gn2jzloiZ#m z)-W(A_+({Zkm1MLCHsI)h&w`5Vgu8$X<2M-)ec*EIC&;ZO7u0e{#5?|--Kbag_uD> rJ;UZaYl9PpF$^24Bqh4ON=h&sej)T=p2#O(p#2Pd-XuCO>hw#nNJv!d zIJhb9y-0%!yR^rmhRN(pre-p&syeoUmq$mz*n)e8nSlX!18XI>gv&vmzP(;vuNAni m8x-U;>{!;=c>6#fBZIKP)rg=aFKR+XfK>-5_H~b!u!M0zj>BZOBkTbT+zvp*c7$O+7Kei>})k* h*0BQ34V`NmG zP%-Y4G!^KeF4*7zlo2QTt}=7Q@97{&&6$F^+D3ezuO1MZ8xs0k^7Yit*b6QVqgu_X(xI$dCdpTJGcJex0G0>z6IGjX2 zMoHq-iP?w}O$zRxu@L#fq(m9&SS8UTi|I;Ng#ME96aO{iZ z-x#ulR$_6K1!mMLuXsjvR-AF(l9-aXLImI{RM`hx-B(i_r0A?roL!LPs+FZyL@7bR zwo17S<%S(Iy+Wgjy4`}fDn!|r2&O5&ED^UB2km6FqE^>8!}ccJ26s)m_3b_BHK1O|1)7=&AGyOd zDMrYQ#g7U*=t~TfDz^O+W)%Z{yurITuNwI@k>3M1245MK{X@|WNJ;fmZ63Qpp`!R- zZLqeY%=Sv382KzLhz85W{CtKk_}gnhxD8}T?a|R^~SI(xPC%d-i zFnzo{_yPO{>(pDqE~Dd%hMNi8KfCzin~}!QwZ$N2a0Fh6N>o<`I%xD-BA=%Z$1ePD zjf!TKHeLbV#(6_3`yYphO`wQ1%{8`_0+eU^vECn1Zn5OAJxo59H}1$ekfElk9V}vP z-Zdy$bmfdN<|ZAsJlIiqoiZk^)0e{bS)=b-5oiouQ;Y&)Dn#;3^)9Zr9zEfoF?!Xq~=v^Ji*T)1fhRO)-K_TYb+p;EDOUvyflMxPG~p>!qPD!;*0Yz7QV%`8eyWA14-vc{ThuHxxPF1KV`N(Mk zayZJ@NQ_Qj7;Y}`({noxFb2+{i@_QG!8yuVHz1ejZvnV#xJP5S$w+A{hpoLftFdX| qnUQMWg76NQUj47L{!c>xF8l*aGrj%_{9RK30000*Qn60MFc5u7TDNIh$ljqYYlW!z0&lE{iP0nKl&Lcd zE6OJnsUKjmbwG4t?t~Cu;lRkk8QTd_J2Wg6Pm1sE<@ug3G2jtm4+LgmB;HH?3n5p| zLn*}P2_@3-gNA*81Y+V+wV~xgh=fRR43ic*#AJNcw~QEk<$Wj4%MOdio=u^B61y1D zVQTI?@O6k3=;}-LQ>Az{M<=Yc-@~S+?nISDR#~ZFUbwyi7 zsU#AasfrJY2aPds@_6c8KG7=-8C3U;e!ti;<9n?dZ3|+#W7j{%H^AgMgfU{iXaE2J M07*qoM6N<$f;^nE!vFvP diff --git a/docs/html/img92.png b/docs/html/img92.png index 7a1571bee715c24a2bc9cbc0d98ab1ce0dcc993e..bde637725c080a15c177e5c0e8449c00187d447b 100644 GIT binary patch literal 508 zcmVBbKotH8mU0c!n)r*2$vAdng~;E)+{HmARyU%F zzosf0WzcBCj{g7&e}U<29QYGzG*J?hdiUBh2eb@^jjy@)dhfgM-Mx1$AYo7W1TeS` z;4?MmMNR{X2y=08B|XPn*ra9323A0`)tf#Aorucm|J+~(23dxWi6}41a*4}89_CHY zqGgM6w_uWn!Qu}?yPj+6vJo74H5F^aS=3<{0B!PmskmYMdOSfz^_ae3veS&^&|T#v zV_bh(W`Q(5`eBv7NzKS}nT{Qvs){Ci~X$pB2 z;Nl>}4sHeY7Zk@X9_~UW=O7M(OD5-1P*EuLa!nILG8A+W{NTNJ@4I*R?%sPqf=!{v z$iwBbFIE-`kV8<$plun&y)yW*a=3UY_2@2lbQz3m0F9r;=Dtq2>V2rHq`3?XGNg#v z=z-vj>>WpbAV`9z9R%quQo5@D-qV&wR%M%utD(Y8@U`G%h%c@nDQ1jF2Q=al$vG9i zghNO4Q3Z><^k=57#K!Qu(W^TZEs&rZ{g7nY?R2GPWHu7cPk#1CVQm8!+^!FWODL55 zNWKNie5*P4YoRa`E-V*lhEU@@G;t&7; diff --git a/docs/html/img93.png b/docs/html/img93.png index 79cf58a608ac4cb053e96d889a83c89e734a4a70..ae65520d2645270a59acd5ffa737595d02c76086 100644 GIT binary patch literal 370 zcmV-&0ge8NP)SV1NS$1oHq8D=;7dR>?>P?0_9v_k#%xENl!3IFzD* z3k(Gl7#R2y6c!wq@Qr~JC}MD-M8JTt0Bj(aCj&nN!vtas!VP#CIAF{PJPaQY5(Yqv z4Fn4089p;KfSkg`&k0lvRKU;A#mdI81Z;5v11rcU1|SWb4M2swl(~j%!1#fIJ%JZB zET(};FR-*E!+QqK#&$LX5R-wk04VlhCc}Tm0EV}m6F^J`evoFi0EPzU0!{_?2@LE9 z5*RqZ2AY>M@Gg|T0E}?X4h9D13sB<=8GyQOf|>JSR`UM^k#m6<9;!430DV&~O-h-R QW&i*H07*qoM6N<$f>)Y?{{R30 literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^LO{&N!py+HxcqY>h@%_e6XN>+|NogYXO@?jzkB!2 z*x2~YnKOcdf~!`o>gec5OG^W)a&d9Fd-txAlG5(oyE!Fi2m*x|OM?7@862M70LjOA zx;Tb#%uG%I0=6W!WPyVRma#6A*dcMFL4}=J#(;4nlRy%?L*X}eKJJD!y!;ATJO-kM zYnwOzFl+GG$+?wBhut~C5)vL{Cp0iJT6AxXZDeFFaCqtEqbc!V{s+YejLglJhYxWpykozk zHIeag3%@Y8goIj6%8mmEjvY9|DWdg!D%P!v5$(+|_82_lG#1QF56=q?tWbaHZzlZ!(B zfFKoII_M-F1Y4&fi1`D>;w<QXg$IbLqnnG>*9?DX8O+l4wzuG6ePmY_=wCrggO&^iu)^;7%UrNlLQ^x zdOT&)e%8p2=1VFvoN<|+TWpw7o!bI4u}u+;8tBz?$#%KnL-elQzWKk>{0~TVwNzE; zW!Sya&E;k_+u#UNu(Ucd;bVoOi z%ac$}T&NZj`@k3?iKc@KORp7U9l9o5k=+Rc=R$C$yLp@4flj1&*N(oPGr-UB4wMpJ UIE(2>82|tP07*qoM6N<$f(PFN>Hq)$ diff --git a/docs/html/img95.png b/docs/html/img95.png index 48aa78e3f8d4cf21d250e237bfc08d657a632e96..93115ef1d0fb20231d9c077757919f70fb875ecb 100644 GIT binary patch literal 264 zcmeAS@N?(olHy`uVBq!ia0vp^(m*WB!py+HcyEc-TOh|Ez$e7@|Ns9pXU4Tq4II^!V8W2R2^^@;!`qa2quL*ufC? z*C2t(u=^pCGJnVEGYtlvCmC1sbus>DvhZefD%MMQk>*}t&SGH1w9;STUd#Li7k;$l zFbU_%u(9o)$k1nSm_35&g6kBS1f30qI!@yCS|94tUN9H_=#`nUDDji<&I~Z(dW}eN?EVDt| yK$T&o4_lk2!z&f$!!j&K=N!mm2ztzHBE?W!#8dd&F18nFID@CFpUXO@geCy=z(Ah> literal 457 zcmV;)0XF`LP)0#w0(@&sjJVPr?@#s*#4 zqV5R9#>OM~4VsB5gBSKZLR29n1VjCk1~*A5AhsSUz9;v7wtO8cfFVzZ4J<0wp~O-J zYV=vY9BFB*c0@cMW=X!>fEcUY|6<{9MMxtNJ*oa!q>a0~&=p{hOtNcieb3U}ai1+eb=EZ3Z zOA1QFhm1pad%jLq-yA8wc6{L~9kzirQbe&cUP+w-XWC6+r%thomsj~hxn~3=CT7j* z-#y@Z@J<{2r*f>tmkBQMRydOeA5^?e!;#5v7D%{FN!H+9<@(V5o{PUs4D3Vng8{!f zJ}~g<(Jt_)Y_Ge)q?L(c9dElQw6ym_Zk;s)(N#XhwM&2O00000NkvXXu0mjf{|d=v diff --git a/docs/html/img97.png b/docs/html/img97.png index c4a1e7addb4aaced38e2b20c67297361c6e97cc5..e7744ab3c0a3a94f8c79eadd4b06a4b76a9b513f 100644 GIT binary patch literal 440 zcmV;p0Z0CcP)zQn5uMCVouYH3%wJOTky>Q4V=&_u?Bthx|}BBZf2pfF>+_x$ov@{_zt(NLzmWzqjN z;4RDlMYzUg(RYFU>Xgj{P7p{S_NvkSEjJnb5Qu=|b@6Sh0AY$QjdG6Yr2qf`07*qoM6N<$f*HDxivR!s diff --git a/docs/html/img98.png b/docs/html/img98.png index df9999c45dc7ea3e7673d9a791d4d58d363d4803..eb7686778c8f2e113b105457a0790007de39cbca 100644 GIT binary patch literal 520 zcmV+j0{8uiP)*Q9Vn;P!v5iX+BC`U(`Y9VmH_4CWz2Yv4im+WKbN9 zi&zjX{R75D6e?B_T=NHnfP-tGlZw#QL5Os5^uDC@gJkHShzIiSz2}|#l?M#)D34kd zHH;&)0Tq$FLI#{zUx2mE>|GwbOgdgWqnNpLM0t&-EN=l0RWL*vD{?H+*VYZw@gYzG z3mp$WHNI1dl`4%cV8Y;785@lcy(zc)QLv%cq)+J3$oTyM=gHw>&?Xp-7b<|xU8@MO zFG(AXEeHd!(Ay~>FjHmOL`>;QbHR;0Uz22v8S6|sDqM}JfSXpN2UjpLNQ&q;HvVI< zRp5~9%R>?tVyO0npc^nhajw$Xs3zuu9zaY8O&^=mssUzwXy+%QD`Rf)c|30000< KMNUMnLSTYELgOR= literal 285 zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)n!py+Hxc!rIEs$dn;1lBd|NsA)GiR2UmxqRi zzI*r1*x2~YnKOcdf~!`o>gec5OG^VPba8RHd-txAlG5(oyX9pSrvil-OM?7@862M7 z0Ljnxba4!kn3|lBknn&#iIt6m;UW`{!2uE8CnKP?at?KCLC@U)isxmS%x_kGofPld6-MhcXoAv{R7)yfuf*Bm1-ADs+ z(mY)pLpWw8CjbFcQd!anV@H<7Du->Su_nAVmb_Q!$FT7RlZ4csiUV0^PD}EgHZ)*h Y*y<$6>&|~=2GB+ZPgg&ebxsLQ01K;3t^fc4 literal 415 zcmV;Q0bu@#P)T#y?J;5>x`8&Z5hi~~T-2z0Li4?RR#qH;kt zDllz876OIF1O^l#h$g7e93}^b2OHRtg;-fRc^ejRgEeme`H+c$gNM79*MWxt;%zu! zV&DamE=VFg{R|7p^~_)aEK3*|Tye^JL8v=G%#GWOSTK1WLlLjkjZgWV3Jh!-LKhhR zfQ2?-C}QJwU{YW!U^v8(2a_tmv`&e^n}J#6{uTy91_ns{&17Ksq^$^yKm`VdAPDt@ zL6d>`2ZLm109YCbm_9II2doWz2@L!S5RNBquQ4#F;FBB{002@YFn@UT8g>8x002ov JPDHLkV1j~;mXQDe diff --git a/docs/html/index.html b/docs/html/index.html index e3200a830..cccebd92f 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -20,18 +20,18 @@ @@ -61,345 +61,351 @@ Dec 1st, 2018

+

+

Notes

    -
  1. For processes in the virtual parallel machine the identifier - will satisfy $0 \le iam \le np-1$; + WIDTH="180" HEIGHT="30" ALIGN="MIDDLE" BORDER="0" + SRC="img131.png" + ALT="$flag = psb\_sort\_ovw\_idx\_$"> then the entries in $ix(1:n)$ + where $n$ is the size of $x$ are initialized to +$ix(i) \leftarrow
+i$; thus, upon return from the subroutine, for each + index $i$ we have in $ix(i)$ the position that the item $x(i)$ + occupied in the original data sequence;
  2. -
  3. If the user has requested on psb_init a number of - processes less than the total available in the parallel execution - environment, the remaining processes will have on return If +$flag = psb\_sort\_keep\_idx\_$ the routine will assume that + the entries in $iam=-1$; - the only call involving icontxt that any such process may - execute is to psb_exit. + ALT="$ix(:)$"> have already been initialized by the user; +
  4. +
  5. The three sorting algorithms have a similar $O(n \log n)$ expected + running time; in the average case quicksort will be the + fastest and merge-sort the slowest. However note that: + +
      +
    1. The worst case running time for quicksort is $O(n^2)$; the algorithm + implemented here follows the well-known median-of-three heuristics, + but the worst case may still apply; +
    2. +
    3. The worst case running time for merge-sort and heap-sort is + $O(n \log n)$ as the average case; +
    4. +
    5. The merge-sort algorithm is implemented to take advantage of + subsequences that may be already in the desired ordering prior to + the subroutine call; this situation is relatively common when + dealing with groups of indices of sparse matrix entries, thus + merge-sort is the preferred choice when a sorting is needed + by other routines in the library. +
    6. +

-


+ +

+ +

+ diff --git a/docs/html/node102.html b/docs/html/node102.html index ef55917cb..10f2e3675 100644 --- a/docs/html/node102.html +++ b/docs/html/node102.html @@ -3,8 +3,8 @@ -psb_exit -- Exit from PSBLAS parallel environment - +Parallel environment routines + @@ -14,136 +14,93 @@ - - - + + + -

-psb_exit -- Exit from PSBLAS parallel +

+ +
+Parallel environment routines +

+ +

+


+ +Subsections + +

- -

-

-call psb_exit(icontxt)
-call psb_exit(icontxt,close)
-
- -

-This subroutine exits from the PSBLAS parallel virtual machine. -

-
Type:
-
Synchronous. -
-
On Entry
-
-
-
icontxt
-
the communication context identifying the virtual - parallel machine. -
-Scope: global. -
-Type: required. -
-Intent: in. -
-Specified as: an integer variable. -
-
close
-
Whether to close all data structures related to the - virtual parallel machine, besides those associated with icontxt. -
-Scope: global. -
-Type: optional. -
-Intent: in. -
-Specified as: a logical variable, default value: true. -
-
- -

-Notes - -

    -
  1. This routine may be called even if a previous call to - psb_info has returned with $iam=-1$; indeed, it it is the only - routine that may be called with argument icontxt in this - situation. -
  2. -
  3. A call to this routine with close=.true. implies a call - to MPI_Finalize, after which no parallel routine may be called. -
  4. -
  5. If the user whishes to use multiple communication contexts in the - same program, or to enter and exit multiple times into the parallel - environment, this routine may be called to - selectively close the contexts with close=.false., while on - the last call it should be called with close=.true. to - shutdown in a clean way the entire parallel environment. -
  6. -
- -

- -

- +
  • psb_info -- Return information about PSBLAS parallel + environment +
  • psb_exit -- Exit from PSBLAS parallel + environment +
  • psb_get_mpicomm -- Get the MPI communicator +
  • psb_get_rank -- Get the MPI rank +
  • psb_wtime -- Wall clock timing +
  • psb_barrier -- Sinchronization point parallel + environment +
  • psb_abort -- Abort a computation +
  • psb_bcast -- Broadcast data +
  • psb_sum -- Global sum +
  • psb_max -- Global maximum +
  • psb_min -- Global minimum +
  • psb_amx -- Global maximum absolute value +
  • psb_amn -- Global minimum absolute value +
  • psb_nrm2 -- Global 2-norm reduction +
  • psb_snd -- Send data +
  • psb_rcv -- Receive data + + +

    diff --git a/docs/html/node103.html b/docs/html/node103.html index 86979e32c..419c426d2 100644 --- a/docs/html/node103.html +++ b/docs/html/node103.html @@ -3,8 +3,8 @@ -psb_get_mpicomm -- Get the MPI communicator - +psb_init -- Initializes PSBLAS parallel environment + @@ -16,67 +16,97 @@ - + -

    -psb_get_mpicomm -- Get the MPI communicator +

    +psb_init -- Initializes PSBLAS parallel + environment

    -call psb_get_mpicomm(icontxt, icomm)
    +call psb_init(icontxt, np, basectxt, ids)
     

    -This subroutine returns the MPI communicator associated with a PSBLAS context +This subroutine initializes the PSBLAS parallel environment, defining +a virtual parallel machine.

    Type:
    -
    Asynchronous. +
    Synchronous.
    On Entry
    -
    icontxt
    -
    the communication context identifying the virtual - parallel machine. +
    np
    +
    Number of processes in the PSBLAS virtual parallel machine.
    Scope: global.
    -Type: required. +Type: optional.
    Intent: in.
    -Specified as: an integer variable. +Specified as: an integer value. Default: use all available processes. +
    +
    basectxt
    +
    the initial communication context. The new context + will be defined from the processes participating in the initial one. +
    +Scope: global. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: an integer value. Default: use MPI_COMM_WORLD. +
    +
    ids
    +
    Identities of the processes to use for the new context; the + argument is ignored when np is not specified. This allows the + processes in the new environment to be in an order different from the + original one. +
    +Scope: global. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: an integer array. Default: use the indices $(0\dots np-1)$.
    @@ -85,19 +115,63 @@ Specified as: an integer variable.
    On Return
    -
    icomm
    -
    The MPI communicator associated with the PSBLAS virtual parallel machine. +
    icontxt
    +
    the communication context identifying the virtual + parallel machine. Note that this is always a duplicate of + basectxt, so that library communications are completely + separated from other communication operations.
    Scope: global.
    Type: required.
    Intent: out. -
    +
    +Specified as: an integer variable. +

    -


    +Notes + +
      +
    1. A call to this routine must precede any other PSBLAS call. +
    2. +
    3. It is an error to specify a value for $np$ greater than the + number of processes available in the underlying base parallel + environment. +
    4. +
    + +

    + +

    + diff --git a/docs/html/node104.html b/docs/html/node104.html index 2c8cd368b..6eda8e7e9 100644 --- a/docs/html/node104.html +++ b/docs/html/node104.html @@ -3,8 +3,8 @@ -psb_get_rank -- Get the MPI rank - +psb_info -- Return information about PSBLAS parallel environment + @@ -16,52 +16,51 @@ - + -

    -psb_get_rank -- Get the MPI rank +

    +psb_info -- Return information about PSBLAS parallel + environment

    -call psb_get_rank(rank, icontxt, id)
    +call psb_info(icontxt, iam, np)
     

    -This subroutine returns the MPI rank of the PSBLAS process $id$ +This subroutine returns information about the PSBLAS parallel environment, defining +a virtual parallel machine.

    Type:
    Asynchronous. @@ -81,22 +80,6 @@ Intent: in.
    Specified as: an integer variable.
    -
    id
    -
    Identifier of a process in the PSBLAS virtual parallel machine. -
    -Scope: local. -
    -Type: required. -
    -Intent: in. -
    -Specified as: an integer value. -$0 \le id \le np-1$

    @@ -104,20 +87,58 @@ Specified as: an integer value. +$-1 \le iam \le np-1$ +

    np
    +
    Number of processes in the PSBLAS virtual parallel machine. +
    +Scope: global. +
    +Type: required. +
    +Intent: out. +
    +Specified as: an integer variable.
    +

    +Notes + +

      +
    1. For processes in the virtual parallel machine the identifier + will satisfy +$0 \le iam \le np-1$; +
    2. +
    3. If the user has requested on psb_init a number of + processes less than the total available in the parallel execution + environment, the remaining processes will have on return $iam=-1$; + the only call involving icontxt that any such process may + execute is to psb_exit. +
    4. +
    +



    diff --git a/docs/html/node105.html b/docs/html/node105.html index a93ed5422..a9efb2cb1 100644 --- a/docs/html/node105.html +++ b/docs/html/node105.html @@ -3,8 +3,8 @@ -psb_wtime -- Wall clock timing - +psb_exit -- Exit from PSBLAS parallel environment + @@ -16,66 +16,134 @@ - + -

    -psb_wtime -- Wall clock timing +

    +psb_exit -- Exit from PSBLAS parallel + environment

    -time = psb_wtime()
    +call psb_exit(icontxt)
    +call psb_exit(icontxt,close)
     

    -This function returns a wall clock timer. The resolution of the timer -is dependent on the underlying parallel environment implementation. +This subroutine exits from the PSBLAS parallel virtual machine.

    Type:
    -
    Asynchronous. +
    Synchronous.
    -
    On Exit
    +
    On Entry
    -
    Function value
    -
    the elapsed time in seconds. +
    icontxt
    +
    the communication context identifying the virtual + parallel machine.
    -Returned as: a real(psb_dpk_) variable. +Scope: global. +
    +Type: required. +
    +Intent: in. +
    +Specified as: an integer variable. +
    +
    close
    +
    Whether to close all data structures related to the + virtual parallel machine, besides those associated with icontxt. +
    +Scope: global. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: a logical variable, default value: true.

    -


    +Notes + +
      +
    1. This routine may be called even if a previous call to + psb_info has returned with $iam=-1$; indeed, it it is the only + routine that may be called with argument icontxt in this + situation. +
    2. +
    3. A call to this routine with close=.true. implies a call + to MPI_Finalize, after which no parallel routine may be called. +
    4. +
    5. If the user whishes to use multiple communication contexts in the + same program, or to enter and exit multiple times into the parallel + environment, this routine may be called to + selectively close the contexts with close=.false., while on + the last call it should be called with close=.true. to + shutdown in a clean way the entire parallel environment. +
    6. +
    + +

    + +

    + diff --git a/docs/html/node106.html b/docs/html/node106.html index 74bd3f515..047d0ff4f 100644 --- a/docs/html/node106.html +++ b/docs/html/node106.html @@ -3,8 +3,8 @@ -psb_barrier -- Sinchronization point parallel environment - +psb_get_mpicomm -- Get the MPI communicator + @@ -16,54 +16,52 @@ - + -

    -psb_barrier -- Sinchronization point parallel - environment +

    +psb_get_mpicomm -- Get the MPI communicator

    -call psb_barrier(icontxt)
    +call psb_get_mpicomm(icontxt, icomm)
     

    -This subroutine acts as an explicit synchronization point for the PSBLAS -parallel virtual machine. +This subroutine returns the MPI communicator associated with a PSBLAS context

    Type:
    -
    Synchronous. +
    Asynchronous.
    On Entry
    @@ -82,6 +80,22 @@ Specified as: an integer variable.
    +

    +

    +
    On Return
    +
    +
    +
    icomm
    +
    The MPI communicator associated with the PSBLAS virtual parallel machine. +
    +Scope: global. +
    +Type: required. +
    +Intent: out. +
    +
    +



    diff --git a/docs/html/node107.html b/docs/html/node107.html index 0f37acf31..a7b9c7202 100644 --- a/docs/html/node107.html +++ b/docs/html/node107.html @@ -3,8 +3,8 @@ -psb_abort -- Abort a computation - +psb_get_rank -- Get the MPI rank + @@ -16,49 +16,52 @@ - + -

    -psb_abort -- Abort a computation +

    +psb_get_rank -- Get the MPI rank

    -call psb_abort(icontxt)
    +call psb_get_rank(rank, icontxt, id)
     

    -This subroutine aborts computation on the parallel virtual machine. +This subroutine returns the MPI rank of the PSBLAS process $id$

    Type:
    Asynchronous. @@ -78,6 +81,41 @@ Intent: in.
    Specified as: an integer variable.
    +
    id
    +
    Identifier of a process in the PSBLAS virtual parallel machine. +
    +Scope: local. +
    +Type: required. +
    +Intent: in. +
    +Specified as: an integer value. +$0 \le id \le np-1$
    +
    + +

    +

    +
    On Return
    +
    +
    +
    rank
    +
    The MPI rank associated with the PSBLAS process $id$. +
    +Scope: local. +
    +Type: required. +
    +Intent: out. +

    diff --git a/docs/html/node108.html b/docs/html/node108.html index cada5b117..813dd87f9 100644 --- a/docs/html/node108.html +++ b/docs/html/node108.html @@ -3,8 +3,8 @@ -psb_bcast -- Broadcast data - +psb_wtime -- Wall clock timing + @@ -16,116 +16,61 @@ - +

    -

    -psb_bcast -- Broadcast data +

    +psb_wtime -- Wall clock timing

    -call psb_bcast(icontxt, dat, root)
    +time = psb_wtime()
     

    -This subroutine implements a broadcast operation based on the -underlying communication library. +This function returns a wall clock timer. The resolution of the timer +is dependent on the underlying parallel environment implementation.

    Type:
    -
    Synchronous. +
    Asynchronous.
    -
    On Entry
    +
    On Exit
    -
    icontxt
    -
    the communication context identifying the virtual - parallel machine. +
    Function value
    +
    the elapsed time in seconds.
    -Scope: global. -
    -Type: required. -
    -Intent: in. -
    -Specified as: an integer variable. -
    -
    dat
    -
    On the root process, the data to be broadcast. -
    -Scope: global. -
    -Type: required. -
    -Intent: inout. -
    -Specified as: an integer, real or complex variable, which may be a -scalar, or a rank 1 or 2 array, or a character or logical variable, -which may be a scalar or rank 1 array. Type, kind, rank and size must agree on all processes. -
    -
    root
    -
    Root process holding data to be broadcast. -
    -Scope: global. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: an integer value -$0<= root <= np-1$, default 0
    -
    - -

    -

    -
    On Return
    -
    -
    -
    dat
    -
    On processes other than root, the data to be broadcast. -
    -Scope: global. -
    -Type: required. -
    -Intent: inout. -
    -Specified as: an integer, real or complex variable, which may be a -scalar, or a rank 1 or 2 array, or a character or logical scalar. Type, kind, rank and size must agree on all processes. +Returned as: a real(psb_dpk_) variable.
    diff --git a/docs/html/node109.html b/docs/html/node109.html index c023b27af..e97259523 100644 --- a/docs/html/node109.html +++ b/docs/html/node109.html @@ -3,8 +3,8 @@ -psb_sum -- Global sum - +psb_barrier -- Sinchronization point parallel environment + @@ -16,50 +16,51 @@ - + -

    -psb_sum -- Global sum +

    +psb_barrier -- Sinchronization point parallel + environment

    -call psb_sum(icontxt, dat, root)
    +call psb_barrier(icontxt)
     

    -This subroutine implements a sum reduction operation based on the -underlying communication library. +This subroutine acts as an explicit synchronization point for the PSBLAS +parallel virtual machine.

    Type:
    Synchronous. @@ -79,99 +80,10 @@ Intent: in.
    Specified as: an integer variable.
    -
    dat
    -
    The local contribution to the global sum. -
    -Scope: global. -
    -Type: required. -
    -Intent: inout. -
    -Specified as: an integer, real or complex variable, which may be a -scalar, or a rank 1 or 2 array. Type, kind, rank and size must agree on all processes. -
    -
    root
    -
    Process to hold the final sum, or $-1$ to make it available - on all processes. -
    -Scope: global. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: an integer value -$-1<= root <= np-1$, default -1.

    -

    -
    On Return
    -
    -
    -
    dat
    -
    On destination process(es), the result of the sum operation. -
    -Scope: global. -
    -Type: required. -
    -Intent: inout. -
    -Specified as: an integer, real or complex variable, which may be a -scalar, or a rank 1 or 2 array. -
    -Type, kind, rank and size must agree on all processes. -
    -
    - -

    -Notes - -

      -
    1. The dat argument is both input and output, and its - value may be changed even on processes different from the final - result destination. -
    2. -
    3. The dat argument may also be a long integer scalar. -
    4. -
    - -

    - -

    - +

    diff --git a/docs/html/node11.html b/docs/html/node11.html index c3adba33d..4952cd9bd 100644 --- a/docs/html/node11.html +++ b/docs/html/node11.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node110.html b/docs/html/node110.html index 06883b02c..df63b41ce 100644 --- a/docs/html/node110.html +++ b/docs/html/node110.html @@ -3,8 +3,8 @@ -psb_max -- Global maximum - +psb_abort -- Abort a computation + @@ -16,53 +16,52 @@ - + -

    -psb_max -- Global maximum +

    +psb_abort -- Abort a computation

    -call psb_max(icontxt, dat, root)
    +call psb_abort(icontxt)
     

    -This subroutine implements a maximum valuereduction -operation based on the underlying communication library. +This subroutine aborts computation on the parallel virtual machine.

    Type:
    -
    Synchronous. +
    Asynchronous.
    On Entry
    @@ -79,98 +78,10 @@ Intent: in.
    Specified as: an integer variable.
    -
    dat
    -
    The local contribution to the global maximum. -
    -Scope: local. -
    -Type: required. -
    -Intent: inout. -
    -Specified as: an integer or real variable, which may be a -scalar, or a rank 1 or 2 array. Type, kind, rank and size must agree on all processes. -
    -
    root
    -
    Process to hold the final maximum, or $-1$ to make it available - on all processes. -
    -Scope: global. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: an integer value -$-1<= root <= np-1$, default -1. -

    -

    -
    On Return
    -
    -
    -
    dat
    -
    On destination process(es), the result of the maximum operation. -
    -Scope: global. -
    -Type: required. -
    -Intent: in. -
    -Specified as: an integer or real variable, which may be a -scalar, or a rank 1 or 2 array. Type, kind, rank and size must agree on all processes. -
    -
    - -

    -Notes - -

      -
    1. The dat argument is both input and output, and its - value may be changed even on processes different from the final - result destination. -
    2. -
    3. The dat argument may also be a long integer scalar. -
    4. -
    - -

    - -

    - +

    diff --git a/docs/html/node111.html b/docs/html/node111.html index 76e40bd5a..febe6db20 100644 --- a/docs/html/node111.html +++ b/docs/html/node111.html @@ -3,8 +3,8 @@ -psb_min -- Global minimum - +psb_bcast -- Broadcast data + @@ -16,50 +16,50 @@ - + -

    -psb_min -- Global minimum +

    +psb_bcast -- Broadcast data

    -call psb_min(icontxt, dat, root)
    +call psb_bcast(icontxt, dat, root)
     

    -This subroutine implements a minimum value reduction -operation based on the underlying communication library. +This subroutine implements a broadcast operation based on the +underlying communication library.

    Type:
    Synchronous. @@ -80,23 +80,20 @@ Intent: in. Specified as: an integer variable.
    dat
    -
    The local contribution to the global minimum. +
    On the root process, the data to be broadcast.
    -Scope: local. +Scope: global.
    Type: required.
    Intent: inout.
    -Specified as: an integer or real variable, which may be a -scalar, or a rank 1 or 2 array. Type, kind, rank and size must agree on all processes. +Specified as: an integer, real or complex variable, which may be a +scalar, or a rank 1 or 2 array, or a character or logical variable, +which may be a scalar or rank 1 array. Type, kind, rank and size must agree on all processes.
    root
    -
    Process to hold the final value, or $-1$ to make it available - on all processes. +
    Root process holding data to be broadcast.
    Scope: global.
    @@ -105,13 +102,12 @@ Type: optional. Intent: in.
    Specified as: an integer value $-1<= root <= np-1$, default -1. -
    + WIDTH="153" HEIGHT="29" ALIGN="MIDDLE" BORDER="0" + SRC="img146.png" + ALT="$0<= root <= np-1$">, default 0

    @@ -120,7 +116,7 @@ Specified as: an integer value - -next - -up - -previous - -contents -
    - Next: psb_amx Global - Up: Parallel environment routines - Previous: psb_max Global -   Contents - +


    diff --git a/docs/html/node112.html b/docs/html/node112.html index 36e57ef87..7038a6b64 100644 --- a/docs/html/node112.html +++ b/docs/html/node112.html @@ -3,8 +3,8 @@ -psb_amx -- Global maximum absolute value - +psb_sum -- Global sum + @@ -16,50 +16,50 @@ - + -

    -psb_amx -- Global maximum absolute value +

    +psb_sum -- Global sum

    -call psb_amx(icontxt, dat, root)
    +call psb_sum(icontxt, dat, root)
     

    -This subroutine implements a maximum absolute value reduction -operation based on the underlying communication library. +This subroutine implements a sum reduction operation based on the +underlying communication library.

    Type:
    Synchronous. @@ -80,9 +80,9 @@ Intent: in. Specified as: an integer variable.
    dat
    -
    The local contribution to the global maximum. +
    The local contribution to the global sum.
    -Scope: local. +Scope: global.
    Type: required.
    @@ -92,9 +92,9 @@ Specified as: an integer, real or complex variable, which may be a scalar, or a rank 1 or 2 array. Type, kind, rank and size must agree on all processes.
    root
    -
    Process to hold the final value, or Process to hold the final sum, or $-1$ to make it available on all processes.
    @@ -108,10 +108,9 @@ Specified as: an integer value $-1<= root <= np-1$, default -1. -
    + WIDTH="165" HEIGHT="29" ALIGN="MIDDLE" BORDER="0" + SRC="img147.png" + ALT="$-1<= root <= np-1$">, default -1.

    @@ -120,7 +119,7 @@ Specified as: an integer value - next - + up - previous - contents
    - Next: psb_amn Global - Up: Parallel environment routines - Previous: psb_min Global -   Next: psb_max Global + Up: Parallel environment routines + Previous: psb_bcast Broadcast +   Contents diff --git a/docs/html/node113.html b/docs/html/node113.html index 587b7431d..f1e003d07 100644 --- a/docs/html/node113.html +++ b/docs/html/node113.html @@ -3,8 +3,8 @@ -psb_amn -- Global minimum absolute value - +psb_max -- Global maximum + @@ -16,49 +16,49 @@ - +

    -

    -psb_amn -- Global minimum absolute value +

    +psb_max -- Global maximum

    -call psb_amn(icontxt, dat, root)
    +call psb_max(icontxt, dat, root)
     

    -This subroutine implements a minimum absolute value reduction +This subroutine implements a maximum valuereduction operation based on the underlying communication library.

    Type:
    @@ -80,7 +80,7 @@ Intent: in. Specified as: an integer variable.
    dat
    -
    The local contribution to the global minimum. +
    The local contribution to the global maximum.
    Scope: local.
    @@ -88,13 +88,13 @@ Type: required.
    Intent: inout.
    -Specified as: an integer, real or complex variable, which may be a +Specified as: an integer or real variable, which may be a scalar, or a rank 1 or 2 array. Type, kind, rank and size must agree on all processes.
    root
    -
    Process to hold the final value, or Process to hold the final maximum, or $-1$ to make it available on all processes.
    @@ -108,8 +108,8 @@ Specified as: an integer value $-1<= root <= np-1$, default -1.
    @@ -120,18 +120,16 @@ Specified as: an integer value - next - + up - previous - contents
    - Next: psb_nrm2 Global - Up: Parallel environment routines - Previous: psb_amx Global -   Next: psb_min Global + Up: Parallel environment routines + Previous: psb_sum Global +   Contents diff --git a/docs/html/node114.html b/docs/html/node114.html index 0f1bd1841..15ca157e8 100644 --- a/docs/html/node114.html +++ b/docs/html/node114.html @@ -3,8 +3,8 @@ -psb_nrm2 -- Global 2-norm reduction - +psb_min -- Global minimum + @@ -16,49 +16,49 @@ - + -

    -psb_nrm2 -- Global 2-norm reduction +

    +psb_min -- Global minimum

    -call psb_nrm2(icontxt, dat, root)
    +call psb_min(icontxt, dat, root)
     

    -This subroutine implements a 2-norm value reduction +This subroutine implements a minimum value reduction operation based on the underlying communication library.

    Type:
    @@ -88,13 +88,13 @@ Type: required.
    Intent: inout.
    -Specified as: a real variable, which may be a -scalar, or a rank 1 array. Kind, rank and size must agree on all processes. +Specified as: an integer or real variable, which may be a +scalar, or a rank 1 or 2 array. Type, kind, rank and size must agree on all processes.
    root
    Process to hold the final value, or $-1$ to make it available on all processes.
    @@ -108,8 +108,8 @@ Specified as: an integer value $-1<= root <= np-1$, default -1.
    @@ -120,7 +120,7 @@ Specified as: an integer value - -\begin{displaymath}res = \sqrt{\sum_i dat_i^2},\end{displaymath} - -
    -

    -with care taken to avoid unnecessary overflow. -
  • The dat argument is both input and output, and its value may be changed even on processes different from the final result destination.
  • +
  • The dat argument may also be a long integer scalar. +
  • diff --git a/docs/html/node115.html b/docs/html/node115.html index 2da350d64..afa24b62e 100644 --- a/docs/html/node115.html +++ b/docs/html/node115.html @@ -3,8 +3,8 @@ -psb_snd -- Send data - +psb_amx -- Global maximum absolute value + @@ -16,52 +16,53 @@ - + -

    -psb_snd -- Send data +

    +psb_amx -- Global maximum absolute value

    -call psb_snd(icontxt, dat, dst, m)
    +call psb_amx(icontxt, dat, root)
     

    -This subroutine sends a packet of data to a destination. +This subroutine implements a maximum absolute value reduction +operation based on the underlying communication library.

    Type:
    -
    Synchronous: see usage notes. +
    Synchronous.
    On Entry
    @@ -79,65 +80,38 @@ Intent: in. Specified as: an integer variable.
    dat
    -
    The data to be sent. +
    The local contribution to the global maximum.
    Scope: local.
    Type: required.
    -Intent: in. +Intent: inout.
    Specified as: an integer, real or complex variable, which may be a -scalar, or a rank 1 or 2 array, or a character or logical scalar. Type, kind and rank must agree on sender and receiver process; if $m$ is -not specified, size must agree as well. +scalar, or a rank 1 or 2 array. Type, kind, rank and size must agree on all processes.
    -
    dst
    -
    Destination process. +
    root
    +
    Process to hold the final value, or $-1$ to make it available + on all processes.
    Scope: global.
    -Type: required. +Type: optional.
    Intent: in.
    Specified as: an integer value $0<= dst <= np-1$. -
    -
    m
    -
    Number of rows. -
    -Scope: global. -
    -Type: Optional. -
    -Intent: in. -
    -Specified as: an integer value -$0<= m <= size(dat,1)$. -
    -When $dat$ is a rank 2 array, specifies the number of rows to be sent -independently of the leading dimension $size(dat,1)$; must have the -same value on sending and receiving processes. -
    + ALT="$-1<= root <= np-1$">, default -1. +

    @@ -145,17 +119,29 @@ same value on sending and receiving processes.

    On Return
    +
    dat
    +
    On destination process(es), the result of the maximum operation. +
    +Scope: global. +
    +Type: required. +
    +Intent: inout. +
    +Specified as: an integer, real or complex variable, which may be a +scalar, or a rank 1 or 2 array. Type, kind, rank and size must agree on all processes. +

    Notes

      -
    1. This subroutine implies a synchronization, but only between the - calling process and the destination process $dst$. +
    2. The dat argument is both input and output, and its + value may be changed even on processes different from the final + result destination. +
    3. +
    4. The dat argument may also be a long integer scalar.
    @@ -163,26 +149,26 @@ same value on sending and receiving processes. diff --git a/docs/html/node116.html b/docs/html/node116.html index 6f0eaa1e7..6ed398342 100644 --- a/docs/html/node116.html +++ b/docs/html/node116.html @@ -3,8 +3,8 @@ -psb_rcv -- Receive data - +psb_amn -- Global minimum absolute value + @@ -14,53 +14,55 @@ + - + -

    -psb_rcv -- Receive data +

    +psb_amn -- Global minimum absolute value

    -call psb_rcv(icontxt, dat, src, m)
    +call psb_amn(icontxt, dat, root)
     

    -This subroutine receives a packet of data to a destination. +This subroutine implements a minimum absolute value reduction +operation based on the underlying communication library.

    Type:
    -
    Synchronous: see usage notes. +
    Synchronous.
    On Entry
    @@ -77,59 +79,8 @@ Intent: in.
    Specified as: an integer variable.
    -
    src
    -
    Source process. -
    -Scope: global. -
    -Type: required. -
    -Intent: in. -
    -Specified as: an integer value -$0<= src <= np-1$. -
    -
    m
    -
    Number of rows. -
    -Scope: global. -
    -Type: Optional. -
    -Intent: in. -
    -Specified as: an integer value -$0<= m <= size(dat,1)$. -
    -When $dat$ is a rank 2 array, specifies the number of rows to be sent -independently of the leading dimension $size(dat,1)$; must have the -same value on sending and receiving processes. -
    -
    - -

    -

    -
    On Return
    -
    -
    dat
    -
    The data to be received. +
    The local contribution to the global minimum.
    Scope: local.
    @@ -138,11 +89,49 @@ Type: required. Intent: inout.
    Specified as: an integer, real or complex variable, which may be a -scalar, or a rank 1 or 2 array, or a character or logical scalar. Type, kind and rank must agree on sender and receiver process; if $m$ is -not specified, size must agree as well. +scalar, or a rank 1 or 2 array. Type, kind, rank and size must agree on all processes. +
    +
    root
    +
    Process to hold the final value, or $-1$ to make it available + on all processes. +
    +Scope: global. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: an integer value +$-1<= root <= np-1$, default -1. +
    +
    + +

    +

    +
    On Return
    +
    +
    +
    dat
    +
    On destination process(es), the result of the minimum operation. +
    +Scope: global. +
    +Type: required. +
    +Intent: inout. +
    +Specified as: an integer, real or complex variable, which may be a +scalar, or a rank 1 or 2 array. +
    +Type, kind, rank and size must agree on all processes.
    @@ -150,11 +139,11 @@ not specified, size must agree as well. Notes
      -
    1. This subroutine implies a synchronization, but only between the - calling process and the source process $src$. +
    2. The dat argument is both input and output, and its + value may be changed even on processes different from the final + result destination. +
    3. +
    4. The dat argument may also be a long integer scalar.
    @@ -162,26 +151,26 @@ not specified, size must agree as well. diff --git a/docs/html/node117.html b/docs/html/node117.html index 3f350078a..765c68358 100644 --- a/docs/html/node117.html +++ b/docs/html/node117.html @@ -3,8 +3,8 @@ -Error handling - +psb_nrm2 -- Global 2-norm reduction + @@ -15,326 +15,194 @@ - - + + -

    -Error handling -

    +

    +psb_nrm2 -- Global 2-norm reduction +

    -The PSBLAS library error handling policy has been completely rewritten -in version 2.0. The idea behind the design of this new error handling -strategy is to keep error messages on a stack allowing the user to -trace back up to the point where the first error message has been -generated. Every routine in the PSBLAS-2.0 library has, as last -non-optional argument, an integer info variable; whenever, -inside the routine, an error is detected, this variable is set to a -value corresponding to a specific error code. Then this error code is -also pushed on the error stack and then either control is returned to -the caller routine or the execution is aborted, depending on the users -choice. At the time when the execution is aborted, an error message is -printed on standard output with a level of verbosity than can be -chosen by the user. If the execution is not aborted, then, the caller -routine checks the value returned in the info variable and, if -not zero, an error condition is raised. This process continues on all the -levels of nested calls until the level where the user decides to abort -the program execution. - -

    -Figure 9 shows the layout of a generic psb_foo -routine with respect to the PSBLAS-2.0 error handling policy. It is -possible to see how, whenever an error condition is detected, the -info variable is set to the corresponding error code which is, -then, pushed on top of the stack by means of the -psb_errpush. An error condition may be directly detected inside -a routine or indirectly checking the error code returned returned by a -called routine. Whenever an error is encountered, after it has been -pushed on stack, the program execution skips to a point where the -error condition is handled; the error condition is handled either by -returning control to the caller routine or by calling the -psb\_error routine which prints the content of the error stack -and aborts the program execution, according to the choice made by the -user with psb_set_erraction. The default is to print the error -and terminate the program, but the user may choose to handle the error -explicitly. - -

    - -

    - - - -
    Figure 9: -The layout of a generic psb_foo - routine with respect to PSBLAS-2.0 error handling policy.
    -
    - -
    - -\fbox{\TheSbox} -
    -
    - -

    -Figure 10 reports a sample error message generated by -the PSBLAS-2.0 library. This error has been generated by the fact that -the user has chosen the invalid “FOO” storage format to represent -the sparse matrix. From this error message it is possible to see that -the error has been detected inside the psb_cest subroutine -called by psb_spasb ... by process 0 (i.e. the root process). - -

    - -

    - - - -
    Figure 10: -A sample PSBLAS-2.0 error - message. Process 0 detected an error condition inside the psb_cest subroutine
    -
    - -
    - -\fbox{\TheSbox} -
    -
    - -

    -ifstarsubroutinesubroutinepsb_errpushPushes an error code onto the error - stack - -

    -
    -\begin{lstlisting}
-call psb_errpush(err_c, r_name, i_err, a_err)
-\end{lstlisting} -
    +

    +call psb_nrm2(icontxt, dat, root)
    +

    +This subroutine implements a 2-norm value reduction +operation based on the underlying communication library.

    Type:
    -
    Asynchronous. +
    Synchronous.
    -
    On Entry
    -
    -
    -
    err_c
    -
    the error code -
    -Scope: local -
    -Type: required -
    -Intent: in. -
    -Specified as: an integer. -
    -
    r_name
    -
    the soutine where the error has been caught. -
    -Scope: local -
    -Type: required -
    -Intent: in. -
    -Specified as: a string. -
    -
    i_err
    -
    addional info for error code -
    -Scope: local -
    -Type: optional -
    -Specified as: an integer array -
    -
    a_err
    -
    addional info for error code -
    -Scope: local -
    -Type: optional -
    -Specified as: a string. -
    -
    - -

    -ifstarsubroutinesubroutinepsb_errorPrints the error stack content and aborts - execution - -

    -
    -\begin{lstlisting}
-call psb_error(icontxt)
-\end{lstlisting} -
    - -

    -

    -
    Type:
    -
    Asynchronous. -
    -
    On Entry
    +
    On Entry
    icontxt
    -
    the communication context. +
    the communication context identifying the virtual + parallel machine.
    -Scope: global +Scope: global.
    -Type: optional +Type: required.
    Intent: in.
    -Specified as: an integer. +Specified as: an integer variable.
    +
    dat
    +
    The local contribution to the global minimum. +
    +Scope: local. +
    +Type: required. +
    +Intent: inout. +
    +Specified as: a real variable, which may be a +scalar, or a rank 1 array. Kind, rank and size must agree on all processes. +
    +
    root
    +
    Process to hold the final value, or $-1$ to make it available + on all processes. +
    +Scope: global. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: an integer value +$-1<= root <= np-1$, default -1. +
    -

    -ifstarsubroutinesubroutinepsb_set_errverbositySets the verbosity of error - messages. - -

    -
    -\begin{lstlisting}
-call psb_set_errverbosity(v)
-\end{lstlisting} -
    -

    -
    Type:
    -
    Asynchronous. -
    -
    On Entry
    +
    On Return
    -
    v
    -
    the verbosity level +
    dat
    +
    On destination process(es), the result of the 2-norm reduction.
    -Scope: global +Scope: global.
    -Type: required +Type: required.
    -Intent: in. +Intent: inout.
    -Specified as: an integer. +Specified as: a real variable, which may be a +scalar, or a rank 1 array. +
    +Kind, rank and size must agree on all processes.

    -ifstarsubroutinesubroutinepsb_set_erractionSet the type of action to be - taken upon error condition. +Notes + +

      +
    1. This reduction is appropriate to compute the results of multiple + (local) NRM2 operations at the same time. +
    2. +
    3. Denoting by $dat_i$ the value of the variable $dat$ on process + $i$, the output $res$ is equivalent to the computation of +

      +
      + -

      -
      \begin{lstlisting}
-call psb_set_erraction(err_act)
-\end{lstlisting} -
      - -

      -

      -
      Type:
      -
      Asynchronous. -
      -
      On Entry
      -
      -
      -
      err_act
      -
      the type of action. -
      -Scope: global -
      -Type: required -
      -Intent: in. -
      -Specified as: an integer. Possible values: psb_act_ret, -psb_act_abort. -
      -
      + WIDTH="119" HEIGHT="55" BORDER="0" + SRC="img150.png" + ALT="\begin{displaymath}res = \sqrt{\sum_i dat_i^2},\end{displaymath}"> +
      +
      +

      +with care taken to avoid unnecessary overflow. +
    4. +
    5. The dat argument is both input and output, and its + value may be changed even on processes different from the final + result destination. +
    6. +

    diff --git a/docs/html/node118.html b/docs/html/node118.html index 9e19b0097..43baeea3b 100644 --- a/docs/html/node118.html +++ b/docs/html/node118.html @@ -3,8 +3,8 @@ -Utilities - +psb_snd -- Send data + @@ -14,78 +14,177 @@ - + - + -

    - +

    +psb_snd -- Send data +

    + +

    +

    +call psb_snd(icontxt, dat, dst, m)
    +
    + +

    +This subroutine sends a packet of data to a destination. +

    +
    Type:
    +
    Synchronous: see usage notes. +
    +
    On Entry
    +
    +
    +
    icontxt
    +
    the communication context identifying the virtual + parallel machine.
    -Utilities - +Scope: global. +
    +Type: required. +
    +Intent: in. +
    +Specified as: an integer variable. +
    +
    dat
    +
    The data to be sent. +
    +Scope: local. +
    +Type: required. +
    +Intent: in. +
    +Specified as: an integer, real or complex variable, which may be a +scalar, or a rank 1 or 2 array, or a character or logical scalar. Type, kind and rank must agree on sender and receiver process; if $m$ is +not specified, size must agree as well. +
    +
    dst
    +
    Destination process. +
    +Scope: global. +
    +Type: required. +
    +Intent: in. +
    +Specified as: an integer value +$0<= dst <= np-1$. +
    +
    m
    +
    Number of rows. +
    +Scope: global. +
    +Type: Optional. +
    +Intent: in. +
    +Specified as: an integer value +$0<= m <= size(dat,1)$. +
    +When $dat$ is a rank 2 array, specifies the number of rows to be sent +independently of the leading dimension $size(dat,1)$; must have the +same value on sending and receiving processes. +
    +

    -We have some utilities available for input and output of -sparse matrices; the interfaces to these routines are available in the -module psb_util_mod. +

    +
    On Return
    +
    +
    +

    -


    - -Subsections +Notes - - -

    +
      +
    1. This subroutine implies a synchronization, but only between the + calling process and the destination process $dst$. +
    2. +
    + +

    + +

    + diff --git a/docs/html/node119.html b/docs/html/node119.html index 31f1fbaf5..2d94be946 100644 --- a/docs/html/node119.html +++ b/docs/html/node119.html @@ -3,8 +3,8 @@ -hb_read -- Read a sparse matrix from a file in the Harwell-Boeing format - +psb_rcv -- Receive data + @@ -14,78 +14,112 @@ - - + -

    - hb_read -- Read a sparse matrix from a file in the - Harwell-Boeing format +

    +psb_rcv -- Receive data

    -
    -\begin{lstlisting}
-call hb_read(a, iret, iunit, filename, b, mtitle)
-\end{lstlisting} -
    +

    +call psb_rcv(icontxt, dat, src, m)
    +

    +This subroutine receives a packet of data to a destination.

    Type:
    -
    Asynchronous. +
    Synchronous: see usage notes.
    On Entry
    -
    filename
    -
    The name of the file to be read. +
    icontxt
    +
    the communication context identifying the virtual + parallel machine.
    -Type:optional. +Scope: global.
    -Specified as: a character variable containing a valid file name, or --, in which case the default input unit 5 (i.e. standard input -in Unix jargon) is used. Default: -. +Type: required. +
    +Intent: in. +
    +Specified as: an integer variable.
    -
    iunit
    -
    The Fortran file unit number. +
    src
    +
    Source process.
    -Type:optional. +Scope: global.
    -Specified as: an integer value. Only meaningful if filename is not -. +Type: required. +
    +Intent: in. +
    +Specified as: an integer value +$0<= src <= np-1$. +
    +
    m
    +
    Number of rows. +
    +Scope: global. +
    +Type: Optional. +
    +Intent: in. +
    +Specified as: an integer value +$0<= m <= size(dat,1)$. +
    +When $dat$ is a rank 2 array, specifies the number of rows to be sent +independently of the leading dimension $size(dat,1)$; must have the +same value on sending and receiving processes.
    @@ -94,64 +128,60 @@ Specified as: an integer value. Only meaningful if filename is not -On Return
    -
    a
    -
    the sparse matrix read from file. +
    dat
    +
    The data to be received.
    -Type:required. +Scope: local.
    -Specified as: a structured data of type spdatapsb_Tspmat_type. -
    -
    b
    -
    Rigth hand side(s). +Type: required.
    -Type: Optional +Intent: inout.
    -An array of type real or complex, rank 2 and having the ALLOCATABLE -attribute; will be allocated and filled in if the input file contains -a right hand side, otherwise will be left in the UNALLOCATED state. -
    -
    mtitle
    -
    Matrix title. -
    -Type: Optional -
    -A charachter variable of length 72 holding a copy of the -matrix title as specified by the Harwell-Boeing format and contained -in the input file. -
    -
    iret
    -
    Error code. -
    -Type: required -
    -An integer value; 0 means no error has been detected. +Specified as: an integer, real or complex variable, which may be a +scalar, or a rank 1 or 2 array, or a character or logical scalar. Type, kind and rank must agree on sender and receiver process; if $m$ is +not specified, size must agree as well.
    +

    +Notes + +

      +
    1. This subroutine implies a synchronization, but only between the + calling process and the source process $src$. +
    2. +
    +

    diff --git a/docs/html/node12.html b/docs/html/node12.html index 165f326db..019a46a12 100644 --- a/docs/html/node12.html +++ b/docs/html/node12.html @@ -23,26 +23,26 @@ @@ -84,7 +84,7 @@ Scope: local. $|{\cal I}_i| + |{\cal B}_i|$ --> $\vert{\cal I}_i\vert + \vert{\cal B}_i\vert$. The returned value is specific to the calling process. diff --git a/docs/html/node120.html b/docs/html/node120.html index 11e1a5b6c..21a186b79 100644 --- a/docs/html/node120.html +++ b/docs/html/node120.html @@ -3,8 +3,8 @@ -hb_write -- Write a sparse matrix to a file in the Harwell-Boeing format - +Error handling + @@ -15,51 +15,143 @@ - - + + -

    -hb_write -- Write a sparse matrix to a file - in the Harwell-Boeing format -

    +

    +Error handling +

    + +

    +The PSBLAS library error handling policy has been completely rewritten +in version 2.0. The idea behind the design of this new error handling +strategy is to keep error messages on a stack allowing the user to +trace back up to the point where the first error message has been +generated. Every routine in the PSBLAS-2.0 library has, as last +non-optional argument, an integer info variable; whenever, +inside the routine, an error is detected, this variable is set to a +value corresponding to a specific error code. Then this error code is +also pushed on the error stack and then either control is returned to +the caller routine or the execution is aborted, depending on the users +choice. At the time when the execution is aborted, an error message is +printed on standard output with a level of verbosity than can be +chosen by the user. If the execution is not aborted, then, the caller +routine checks the value returned in the info variable and, if +not zero, an error condition is raised. This process continues on all the +levels of nested calls until the level where the user decides to abort +the program execution. + +

    +Figure 9 shows the layout of a generic psb_foo +routine with respect to the PSBLAS-2.0 error handling policy. It is +possible to see how, whenever an error condition is detected, the +info variable is set to the corresponding error code which is, +then, pushed on top of the stack by means of the +psb_errpush. An error condition may be directly detected inside +a routine or indirectly checking the error code returned returned by a +called routine. Whenever an error is encountered, after it has been +pushed on stack, the program execution skips to a point where the +error condition is handled; the error condition is handled either by +returning control to the caller routine or by calling the +psb\_error routine which prints the content of the error stack +and aborts the program execution, according to the choice made by the +user with psb_set_erraction. The default is to print the error +and terminate the program, but the user may choose to handle the error +explicitly. + +

    + +

    + + + +
    Figure 9: +The layout of a generic psb_foo + routine with respect to PSBLAS-2.0 error handling policy.
    +
    + +
    + +\fbox{\TheSbox} +
    +
    + +

    +Figure 10 reports a sample error message generated by +the PSBLAS-2.0 library. This error has been generated by the fact that +the user has chosen the invalid “FOO” storage format to represent +the sparse matrix. From this error message it is possible to see that +the error has been detected inside the psb_cest subroutine +called by psb_spasb ... by process 0 (i.e. the root process). + +

    + +

    + + + +
    Figure 10: +A sample PSBLAS-2.0 error + message. Process 0 detected an error condition inside the psb_cest subroutine
    +
    + +
    + +\fbox{\TheSbox} +
    +
    + +

    +ifstarsubroutinesubroutinepsb_errpushPushes an error code onto the error + stack


    \begin{lstlisting}
-call hb_write(a, iret, iunit, filename, key, rhs, mtitle)
+call psb_errpush(err_c, r_name, i_err, a_err)
 \end{lstlisting}
    @@ -68,72 +160,154 @@ call hb_write(a, iret, iunit, filename, key, rhs, mtitle)

    Type:
    Asynchronous.
    -
    On Entry
    +
    On Entry
    -
    a
    -
    the sparse matrix to be written. +
    err_c
    +
    the error code
    -Type:required. +Scope: local
    -Specified as: a structured data of type spdatapsb_Tspmat_type. +Type: required +
    +Intent: in. +
    +Specified as: an integer.
    -
    b
    -
    Rigth hand side. +
    r_name
    +
    the soutine where the error has been caught.
    -Type: Optional +Scope: local
    -An array of type real or complex, rank 1 and having the ALLOCATABLE -attribute; will be allocated and filled in if the input file contains -a right hand side. +Type: required +
    +Intent: in. +
    +Specified as: a string. +
    +
    i_err
    +
    addional info for error code +
    +Scope: local +
    +Type: optional +
    +Specified as: an integer array +
    +
    a_err
    +
    addional info for error code +
    +Scope: local +
    +Type: optional +
    +Specified as: a string. +
    + + +

    +ifstarsubroutinesubroutinepsb_errorPrints the error stack content and aborts + execution + +

    +
    +\begin{lstlisting}
+call psb_error(icontxt)
+\end{lstlisting} +
    + +

    +

    +
    Type:
    +
    Asynchronous.
    -
    filename
    -
    The name of the file to be written to. -
    -Type:optional. -
    -Specified as: a character variable containing a valid file name, or --, in which case the default output unit 6 (i.e. standard output -in Unix jargon) is used. Default: -. +
    On Entry
    +
    -
    iunit
    -
    The Fortran file unit number. +
    icontxt
    +
    the communication context.
    -Type:optional. +Scope: global
    -Specified as: an integer value. Only meaningful if filename is not -. -
    -
    key
    -
    Matrix key. +Type: optional
    -Type: Optional +Intent: in.
    -A charachter variable of length 8 holding the -matrix key as specified by the Harwell-Boeing format and to be -written to file. -
    -
    mtitle
    -
    Matrix title. -
    -Type: Optional -
    -A charachter variable of length 72 holding the -matrix title as specified by the Harwell-Boeing format and to be -written to file. +Specified as: an integer.
    +

    +ifstarsubroutinesubroutinepsb_set_errverbositySets the verbosity of error + messages. + +

    +
    +\begin{lstlisting}
+call psb_set_errverbosity(v)
+\end{lstlisting} +
    +

    -
    On Return
    +
    Type:
    +
    Asynchronous. +
    +
    On Entry
    -
    iret
    -
    Error code. +
    v
    +
    the verbosity level
    -Type: required +Scope: global
    -An integer value; 0 means no error has been detected. +Type: required +
    +Intent: in. +
    +Specified as: an integer. +
    +
    + +

    +ifstarsubroutinesubroutinepsb_set_erractionSet the type of action to be + taken upon error condition. + +

    +
    +\begin{lstlisting}
+call psb_set_erraction(err_act)
+\end{lstlisting} +
    + +

    +

    +
    Type:
    +
    Asynchronous. +
    +
    On Entry
    +
    +
    +
    err_act
    +
    the type of action. +
    +Scope: global +
    +Type: required +
    +Intent: in. +
    +Specified as: an integer. Possible values: psb_act_ret, +psb_act_abort.
    @@ -141,26 +315,26 @@ An integer value; 0 means no error has been detected. diff --git a/docs/html/node121.html b/docs/html/node121.html index 2854dbbec..384e43c76 100644 --- a/docs/html/node121.html +++ b/docs/html/node121.html @@ -3,8 +3,8 @@ -mm_mat_read -- Read a sparse matrix from a file in the MatrixMarket format - +Utilities + @@ -14,103 +14,77 @@ - + - + -

    -mm_mat_read -- Read a sparse matrix from a +

    + +
    +Utilities +

    + +

    +We have some utilities available for input and output of +sparse matrices; the interfaces to these routines are available in the +module psb_util_mod. + +

    +


    + +Subsections + +

    - -

    -
    -\begin{lstlisting}
-call mm_mat_read(a, iret, iunit, filename)
-\end{lstlisting} -
    - -

    -

    -
    Type:
    -
    Asynchronous. -
    -
    On Entry
    -
    -
    -
    filename
    -
    The name of the file to be read. -
    -Type:optional. -
    -Specified as: a character variable containing a valid file name, or --, in which case the default input unit 5 (i.e. standard input -in Unix jargon) is used. Default: -. -
    -
    iunit
    -
    The Fortran file unit number. -
    -Type:optional. -
    -Specified as: an integer value. Only meaningful if filename is not -. -
    -
    - -

    -

    -
    On Return
    -
    -
    -
    a
    -
    the sparse matrix read from file. -
    -Type:required. -
    -Specified as: a structured data of type spdatapsb_Tspmat_type. -
    -
    iret
    -
    Error code. -
    -Type: required -
    -An integer value; 0 means no error has been detected. -
    -
    - -

    +

  • mm_array_read -- Read a dense array from a + file in the MatrixMarket format +
  • mm_mat_write -- Write a sparse matrix to a + file in the MatrixMarket format +
  • mm_array_write -- Write a dense array from a + file in the MatrixMarket format + +

    diff --git a/docs/html/node122.html b/docs/html/node122.html index 5a57cd340..b3438b339 100644 --- a/docs/html/node122.html +++ b/docs/html/node122.html @@ -3,8 +3,8 @@ -mm_array_read -- Read a dense array from a file in the MatrixMarket format - +hb_read -- Read a sparse matrix from a file in the Harwell-Boeing format + @@ -16,50 +16,50 @@ - + -

    -mm_array_read -- Read a dense array from a - file in the MatrixMarket format +

    + hb_read -- Read a sparse matrix from a file in the + Harwell-Boeing format


    \begin{lstlisting}
-call mm_array_read(b, iret, iunit, filename)
+call hb_read(a, iret, iunit, filename, b, mtitle)
 \end{lstlisting}
    @@ -94,15 +94,31 @@ Specified as: an integer value. Only meaningful if filename is not -On Return

    +
    a
    +
    the sparse matrix read from file. +
    +Type:required. +
    +Specified as: a structured data of type spdatapsb_Tspmat_type. +
    b
    Rigth hand side(s).
    -Type: required +Type: Optional
    -An array of type real or complex, rank 1 or 2 and having the ALLOCATABLE +An array of type real or complex, rank 2 and having the ALLOCATABLE attribute; will be allocated and filled in if the input file contains a right hand side, otherwise will be left in the UNALLOCATED state.
    +
    mtitle
    +
    Matrix title. +
    +Type: Optional +
    +A charachter variable of length 72 holding a copy of the +matrix title as specified by the Harwell-Boeing format and contained +in the input file. +
    iret
    Error code.
    @@ -113,7 +129,31 @@ An integer value; 0 means no error has been detected.

    -


    + + + diff --git a/docs/html/node123.html b/docs/html/node123.html index 4dd5f34e4..f8e65c336 100644 --- a/docs/html/node123.html +++ b/docs/html/node123.html @@ -3,8 +3,8 @@ -mm_mat_write -- Write a sparse matrix to a file in the MatrixMarket format - +hb_write -- Write a sparse matrix to a file in the Harwell-Boeing format + @@ -16,52 +16,54 @@ - + -

    -mm_mat_write -- Write a sparse matrix to a - file in the MatrixMarket format +

    +hb_write -- Write a sparse matrix to a file + in the Harwell-Boeing format


    \begin{lstlisting}
-call mm_mat_write(a, mtitle, iret, iunit, filename)
+call hb_write(a, iret, iunit, filename, key, rhs, mtitle)
 \end{lstlisting}
    + +

    Type:
    Asynchronous. @@ -76,13 +78,14 @@ Type:required.
    Specified as: a structured data of type spdatapsb_Tspmat_type.
    -
    mtitle
    -
    Matrix title. +
    b
    +
    Rigth hand side.
    -Type: required +Type: Optional
    -A charachter variable holding a descriptive title for the matrix to be - written to file. +An array of type real or complex, rank 1 and having the ALLOCATABLE +attribute; will be allocated and filled in if the input file contains +a right hand side.
    filename
    The name of the file to be written to. @@ -100,6 +103,24 @@ Type:optional.
    Specified as: an integer value. Only meaningful if filename is not -.
    +
    key
    +
    Matrix key. +
    +Type: Optional +
    +A charachter variable of length 8 holding the +matrix key as specified by the Harwell-Boeing format and to be +written to file. +
    +
    mtitle
    +
    Matrix title. +
    +Type: Optional +
    +A charachter variable of length 72 holding the +matrix title as specified by the Harwell-Boeing format and to be +written to file. +

    @@ -117,7 +138,31 @@ An integer value; 0 means no error has been detected.

    -


    + + + diff --git a/docs/html/node124.html b/docs/html/node124.html index e7e3f85f6..f1307a9d2 100644 --- a/docs/html/node124.html +++ b/docs/html/node124.html @@ -3,8 +3,8 @@ -mm_array_write -- Write a dense array from a file in the MatrixMarket format - +mm_mat_read -- Read a sparse matrix from a file in the MatrixMarket format + @@ -14,51 +14,52 @@ + - + -

    -mm_array_write -- Write a dense array from a +

    +mm_mat_read -- Read a sparse matrix from a file in the MatrixMarket format


    \begin{lstlisting}
-call mm_array_write(b, iret, iunit, filename)
+call mm_mat_read(a, iret, iunit, filename)
 \end{lstlisting}
    @@ -70,14 +71,8 @@ call mm_array_write(b, iret, iunit, filename)

    On Entry
    -
    b
    -
    Rigth hand side(s). -
    -Type: required -
    -An array of type real or complex, rank 1 or 2; will be written..
    filename
    -
    The name of the file to be written. +
    The name of the file to be read.
    Type:optional.
    @@ -99,6 +94,13 @@ Specified as: an integer value. Only meaningful if filename is not -On Return
    +
    a
    +
    the sparse matrix read from file. +
    +Type:required. +
    +Specified as: a structured data of type spdatapsb_Tspmat_type. +
    iret
    Error code.
    diff --git a/docs/html/node125.html b/docs/html/node125.html index 0b67b7104..07ecfc91b 100644 --- a/docs/html/node125.html +++ b/docs/html/node125.html @@ -3,8 +3,8 @@ -Preconditioner routines - +mm_array_read -- Read a dense array from a file in the MatrixMarket format + @@ -14,84 +14,105 @@ - - - + + + -

    - +

    +mm_array_read -- Read a dense array from a + file in the MatrixMarket format +

    + +

    +
    +\begin{lstlisting}
+call mm_array_read(b, iret, iunit, filename)
+\end{lstlisting}
    -Preconditioner routines -

    -The base PSBLAS library contains the implementation of two simple -preconditioning techniques: - -

      -
    • Diagonal Scaling -
    • -
    • Block Jacobi with ILU(0) factorization -
    • -
    -The supporting data type and subroutine interfaces are defined in the -module psb_prec_mod. -The old interfaces psb_precinit and psb_precbld are still supported for -backward compatibility +
    +
    Type:
    +
    Asynchronous. +
    +
    On Entry
    +
    +
    +
    filename
    +
    The name of the file to be read. +
    +Type:optional. +
    +Specified as: a character variable containing a valid file name, or +-, in which case the default input unit 5 (i.e. standard input +in Unix jargon) is used. Default: -. +
    +
    iunit
    +
    The Fortran file unit number. +
    +Type:optional. +
    +Specified as: an integer value. Only meaningful if filename is not -. +
    +

    -


    - -Subsections +
    +
    On Return
    +
    +
    +
    b
    +
    Rigth hand side(s). +
    +Type: required +
    +An array of type real or complex, rank 1 or 2 and having the ALLOCATABLE +attribute; will be allocated and filled in if the input file contains +a right hand side, otherwise will be left in the UNALLOCATED state. +
    +
    iret
    +
    Error code. +
    +Type: required +
    +An integer value; 0 means no error has been detected. +
    +
    - - +



    diff --git a/docs/html/node126.html b/docs/html/node126.html index aa0d47e77..6f5c409c4 100644 --- a/docs/html/node126.html +++ b/docs/html/node126.html @@ -3,8 +3,8 @@ -init -- Initialize a preconditioner - +mm_mat_write -- Write a sparse matrix to a file in the MatrixMarket format + @@ -16,130 +16,103 @@ - + -

    -init -- Initialize a preconditioner +

    +mm_mat_write -- Write a sparse matrix to a + file in the MatrixMarket format

    -

    -call prec%init(icontxt,ptype, info)
    -
    - -

    +
    +\begin{lstlisting}
+call mm_mat_write(a, mtitle, iret, iunit, filename)
+\end{lstlisting} +

    Type:
    Asynchronous.
    -
    On Entry
    +
    On Entry
    -
    icontxt
    -
    the communication context. -
    -Scope:global. +
    a
    +
    the sparse matrix to be written.
    Type:required.
    -Intent: in. -
    -Specified as: an integer value. +Specified as: a structured data of type spdatapsb_Tspmat_type.
    -
    ptype
    -
    the type of preconditioner. -Scope: global +
    mtitle
    +
    Matrix title.
    -Type: required +Type: required
    -Intent: in. -
    -Specified as: a character string, see usage notes. +A charachter variable holding a descriptive title for the matrix to be + written to file.
    -
    On Exit
    -

    +

    filename
    +
    The name of the file to be written to. +
    +Type:optional. +
    +Specified as: a character variable containing a valid file name, or +-, in which case the default output unit 6 (i.e. standard output +in Unix jargon) is used. Default: -.
    -
    prec
    -
    Scope: local +
    iunit
    +
    The Fortran file unit number.
    -Type: required +Type:optional.
    -Intent: inout. -
    -Specified as: a preconditioner data structure precdatapsb_prec_type. -
    -
    info
    -
    Scope: global -
    -Type: required -
    -Intent: out. -
    -Error code: if no error, 0 is returned. +Specified as: an integer value. Only meaningful if filename is not -.
    -Notes -Legal inputs to this subroutine are interpreted depending on the -$ptype$ string as follows4: + +

    -
    NONE
    -
    No preconditioning, i.e. the preconditioner is just a copy - operator. +
    On Return
    +
    -
    DIAG
    -
    Diagonal scaling; each entry of the input vector is - multiplied by the reciprocal of the sum of the absolute values of - the coefficients in the corresponding row of matrix $A$; -
    -
    BJAC
    -
    Precondition by a factorization of the - block-diagonal of matrix $A$, where block boundaries are determined - by the data allocation boundaries for each process; requires no - communication. Only the incomplete factorization $ILU(0)$ is - currently implemented. +
    iret
    +
    Error code. +
    +Type: required +
    +An integer value; 0 means no error has been detected.
    diff --git a/docs/html/node127.html b/docs/html/node127.html index e6a559015..2f598cdfc 100644 --- a/docs/html/node127.html +++ b/docs/html/node127.html @@ -3,8 +3,8 @@ -build -- Builds a preconditioner - +mm_array_write -- Write a dense array from a file in the MatrixMarket format + @@ -14,120 +14,83 @@ - - + -

    -build -- Builds a preconditioner +

    +mm_array_write -- Write a dense array from a + file in the MatrixMarket format

    -

    -call prec%build(a, desc_a, info[,amold,vmold,imold])
    -
    +
    +\begin{lstlisting}
+call mm_array_write(b, iret, iunit, filename)
+\end{lstlisting} +

    Type:
    -
    Synchronous. +
    Asynchronous.
    -
    On Entry
    +
    On Entry
    -
    a
    -
    the system sparse matrix. -Scope: local +
    b
    +
    Rigth hand side(s).
    -Type: required +Type: required
    -Intent: in, target. +An array of type real or complex, rank 1 or 2; will be written..
    +
    filename
    +
    The name of the file to be written.
    -Specified as: a sparse matrix data structure spdatapsb_Tspmat_type. +Type:optional. +
    +Specified as: a character variable containing a valid file name, or +-, in which case the default input unit 5 (i.e. standard input +in Unix jargon) is used. Default: -.
    -
    prec
    -
    the preconditioner. +
    iunit
    +
    The Fortran file unit number.
    -Scope: local +Type:optional.
    -Type: required -
    -Intent: inout. -
    -Specified as: an already initialized precondtioner data structure precdatapsb_prec_type -
    -
    desc_a
    -
    the problem communication descriptor. -Scope: local -
    -Type: required -
    -Intent: in, target. -
    -Specified as: a communication descriptor data structure descdatapsb_desc_type. -
    -
    amold
    -
    The desired dynamic type for the internal matrix storage. -
    -Scope: local. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: an object of a class derived from spbasedatapsb_T_base_sparse_mat. -
    -
    vmold
    -
    The desired dynamic type for the internal vector storage. -
    -Scope: local. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: an object of a class derived from vbasedatapsb_T_base_vect_type. -
    -
    imold
    -
    The desired dynamic type for the internal integer vector storage. -
    -Scope: local. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: an object of a class derived from (integer) vbasedatapsb_T_base_vect_type. +Specified as: an integer value. Only meaningful if filename is not -.
    @@ -136,59 +99,17 @@ Specified as: an object of a class derived from (integer) vbasedatapsb_T_bas
    On Return
    -
    prec
    -
    the preconditioner. -
    -Scope: local -
    -Type: required -
    -Intent: inout. -
    -Specified as: a precondtioner data structure precdatapsb_prec_type -
    -
    info
    +
    iret
    Error code.
    -Scope: local -
    Type: required
    -Intent: out. -
    An integer value; 0 means no error has been detected.
    -The amold, vmold and imold arguments may be -employed to interface with special devices, such as GPUs and other -accelerators.

    - -

    - +

    diff --git a/docs/html/node128.html b/docs/html/node128.html index d6071c087..06233ef98 100644 --- a/docs/html/node128.html +++ b/docs/html/node128.html @@ -3,8 +3,8 @@ -apply -- Preconditioner application routine - +Preconditioner routines + @@ -14,139 +14,84 @@ - - - + + + -

    -apply -- Preconditioner application +

    + +
    +Preconditioner routines +

    + +

    +The base PSBLAS library contains the implementation of two simple +preconditioning techniques: + +

      +
    • Diagonal Scaling +
    • +
    • Block Jacobi with ILU(0) factorization +
    • +
    +The supporting data type and subroutine interfaces are defined in the +module psb_prec_mod. +The old interfaces psb_precinit and psb_precbld are still supported for +backward compatibility + +

    +


    + +Subsections + +

    - -

    -

    -call prec%apply(x,y,desc_a,info,trans,work)
    -call prec%apply(x,desc_a,info,trans)
    -
    - -

    -

    -
    Type:
    -
    Synchronous. -
    -
    On Entry
    -
    -
    -
    prec
    -
    the preconditioner. -Scope: local -
    -Type: required -
    -Intent: in. -
    -Specified as: a preconditioner data structure precdatapsb_prec_type. -
    -
    x
    -
    the source vector. -Scope: local -
    -Type: required -
    -Intent: inout. -
    -Specified as: a rank one array or an object of type vdatapsb_T_vect_type. -
    -
    desc_a
    -
    the problem communication descriptor. -Scope: local -
    -Type: required -
    -Intent: in. -
    -Specified as: a communication data structure descdatapsb_desc_type. -
    -
    trans
    -
    Scope: -
    -Type: optional -
    -Intent: in. -
    -Specified as: a character. -
    -
    work
    -
    an optional work space -Scope: local -
    -Type: optional -
    -Intent: inout. -
    -Specified as: a double precision array. -
    -
    - -

    -

    -
    On Return
    -
    -
    -
    y
    -
    the destination vector. -Scope: local -
    -Type: required -
    -Intent: inout. -
    -Specified as: a rank one array or an object of type vdatapsb_T_vect_type. -
    -
    info
    -
    Error code. -
    -Scope: local -
    -Type: required -
    -Intent: out. -
    -An integer value; 0 means no error has been detected. -
    -
    - -

    +

  • descr -- Prints a description of current + preconditioner +
  • clone -- clone current + preconditioner +
  • free -- Free a preconditioner + +

    diff --git a/docs/html/node129.html b/docs/html/node129.html index de6f38eae..0ff25da70 100644 --- a/docs/html/node129.html +++ b/docs/html/node129.html @@ -3,8 +3,8 @@ -descr -- Prints a description of current preconditioner - +init -- Initialize a preconditioner + @@ -16,47 +16,45 @@ - + -

    -descr -- Prints a description of current - preconditioner +

    +init -- Initialize a preconditioner

    -call prec%descr()
    -call prec%descr(iout, root)
    +call prec%init(icontxt,ptype, info)
     

    @@ -67,43 +65,81 @@ call prec%descr(iout, root)

    On Entry
    -
    prec
    -
    the preconditioner. -Scope: local +
    icontxt
    +
    the communication context. +
    +Scope:global. +
    +Type:required. +
    +Intent: in. +
    +Specified as: an integer value. +
    +
    ptype
    +
    the type of preconditioner. +Scope: global
    Type: required
    Intent: in.
    +Specified as: a character string, see usage notes. +
    +
    On Exit
    +

    +

    +
    prec
    +
    Scope: local +
    +Type: required +
    +Intent: inout. +
    Specified as: a preconditioner data structure precdatapsb_prec_type.
    -
    iout
    -
    output unit. -Scope: local +
    info
    +
    Scope: global
    -Type: optional +Type: required
    -Intent: in. +Intent: out.
    -Specified as: an integer number. Default: default output unit. +Error code: if no error, 0 is returned.
    -
    root
    -
    Process from which to print -Scope: local -
    -Type: optional -
    -Intent: in. -
    -Specified as: an integer number between 0 and $np-1$, in which case -the specified process will print the description, or $-1$, in which case -all processes will print. Default: 0. + +Notes +Legal inputs to this subroutine are interpreted depending on the +$ptype$ string as follows4: +
    +
    NONE
    +
    No preconditioning, i.e. the preconditioner is just a copy + operator. +
    +
    DIAG
    +
    Diagonal scaling; each entry of the input vector is + multiplied by the reciprocal of the sum of the absolute values of + the coefficients in the corresponding row of matrix $A$; +
    +
    BJAC
    +
    Precondition by a factorization of the + block-diagonal of matrix $A$, where block boundaries are determined + by the data allocation boundaries for each process; requires no + communication. Only the incomplete factorization $ILU(0)$ is + currently implemented.
    diff --git a/docs/html/node13.html b/docs/html/node13.html index 0fdc4242b..bbbcaa1b3 100644 --- a/docs/html/node13.html +++ b/docs/html/node13.html @@ -23,26 +23,26 @@ @@ -85,7 +85,7 @@ Scope: local. $|{\cal I}_i| + |{\cal B}_i| +|{\cal H}_i|$ --> $\vert{\cal I}_i\vert + \vert{\cal B}_i\vert +\vert{\cal H}_i\vert$. The returned value is specific to the calling process. diff --git a/docs/html/node130.html b/docs/html/node130.html index 8cad168ce..532b6c53f 100644 --- a/docs/html/node130.html +++ b/docs/html/node130.html @@ -3,8 +3,8 @@ -clone -- clone current preconditioner - +build -- Builds a preconditioner + @@ -16,60 +16,119 @@ - + -

    -clone -- clone current - preconditioner +

    +build -- Builds a preconditioner

    +

    -call  prec%clone(precout,info)
    +call prec%build(a, desc_a, info[,amold,vmold,imold])
     

    Type:
    -
    Asynchronous. +
    Synchronous.
    On Entry
    +
    a
    +
    the system sparse matrix. +Scope: local +
    +Type: required +
    +Intent: in, target. +
    +Specified as: a sparse matrix data structure spdatapsb_Tspmat_type. +
    prec
    the preconditioner.
    -Scope: local. +Scope: local +
    +Type: required +
    +Intent: inout. +
    +Specified as: an already initialized precondtioner data structure precdatapsb_prec_type
    +
    desc_a
    +
    the problem communication descriptor. +Scope: local +
    +Type: required +
    +Intent: in, target. +
    +Specified as: a communication descriptor data structure descdatapsb_desc_type. +
    +
    amold
    +
    The desired dynamic type for the internal matrix storage. +
    +Scope: local. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: an object of a class derived from spbasedatapsb_T_base_sparse_mat. +
    +
    vmold
    +
    The desired dynamic type for the internal vector storage. +
    +Scope: local. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: an object of a class derived from vbasedatapsb_T_base_vect_type. +
    +
    imold
    +
    The desired dynamic type for the internal integer vector storage. +
    +Scope: local. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: an object of a class derived from (integer) vbasedatapsb_T_base_vect_type. +

    @@ -77,16 +136,59 @@ Scope: local.

    On Return
    -
    precout
    -
    A copy of the input object. -
    +
    prec
    +
    the preconditioner. +
    +Scope: local +
    +Type: required +
    +Intent: inout. +
    +Specified as: a precondtioner data structure precdatapsb_prec_type +
    info
    -
    Return code. +
    Error code. +
    +Scope: local +
    +Type: required +
    +Intent: out. +
    +An integer value; 0 means no error has been detected.
    +The amold, vmold and imold arguments may be +employed to interface with special devices, such as GPUs and other +accelerators.

    -


    + + + diff --git a/docs/html/node131.html b/docs/html/node131.html index 2c00d6de4..289b69abd 100644 --- a/docs/html/node131.html +++ b/docs/html/node131.html @@ -3,8 +3,8 @@ -free -- Free a preconditioner - +apply -- Preconditioner application routine + @@ -14,91 +14,137 @@ + - + -

    -free -- Free a preconditioner +

    +apply -- Preconditioner application + routine

    -call prec%free(info)
    +call prec%apply(x,y,desc_a,info,trans,work)
    +call prec%apply(x,desc_a,info,trans)
     

    Type:
    -
    Asynchronous. +
    Synchronous.
    On Entry
    prec
    the preconditioner. +Scope: local
    -Scope: local. +Type: required +
    +Intent: in. +
    +Specified as: a preconditioner data structure precdatapsb_prec_type. +
    +
    x
    +
    the source vector. +Scope: local
    Type: required
    Intent: inout.
    -Specified as: a preconditioner data structure precdatapsb_prec_type. +Specified as: a rank one array or an object of type vdatapsb_T_vect_type.
    -
    On Exit
    -

    +

    desc_a
    +
    the problem communication descriptor. +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: a communication data structure descdatapsb_desc_type.
    -
    prec
    -
    Scope: local +
    trans
    +
    Scope: +
    +Type: optional +
    +Intent: in. +
    +Specified as: a character. +
    +
    work
    +
    an optional work space +Scope: local +
    +Type: optional +
    +Intent: inout. +
    +Specified as: a double precision array. +
    +
    + +

    +

    +
    On Return
    +
    +
    +
    y
    +
    the destination vector. +Scope: local
    Type: required
    Intent: inout.
    -Specified as: a preconditioner data structure precdatapsb_prec_type. +Specified as: a rank one array or an object of type vdatapsb_T_vect_type.
    info
    -
    Scope: global +
    Error code.
    -Type: required +Scope: local +
    +Type: required
    Intent: out.
    -Error code: if no error, 0 is returned. +An integer value; 0 means no error has been detected.
    -Notes -Releases all internal storage.



    diff --git a/docs/html/node132.html b/docs/html/node132.html index 9c42bbe23..6244d986c 100644 --- a/docs/html/node132.html +++ b/docs/html/node132.html @@ -3,8 +3,8 @@ -Iterative Methods - +descr -- Prints a description of current preconditioner + @@ -14,62 +14,100 @@ - - - + + + -

    - +

    +descr -- Prints a description of current + preconditioner +

    + +

    +

    +call prec%descr()
    +call prec%descr(iout, root)
    +
    + +

    +

    +
    Type:
    +
    Asynchronous. +
    +
    On Entry
    +
    +
    +
    prec
    +
    the preconditioner. +Scope: local
    -Iterative Methods - +Type: required +
    +Intent: in. +
    +Specified as: a preconditioner data structure precdatapsb_prec_type. +
    +
    iout
    +
    output unit. +Scope: local +
    +Type: optional +
    +Intent: in. +
    +Specified as: an integer number. Default: default output unit. +
    +
    root
    +
    Process from which to print +Scope: local +
    +Type: optional +
    +Intent: in. +
    +Specified as: an integer number between 0 and $np-1$, in which case +the specified process will print the description, or $-1$, in which case +all processes will print. Default: 0. +
    +

    -In this chapter we provide routines for preconditioners and iterative -methods. The interfaces for Krylov subspace methods are available in -the module psb_krylov_mod. - -

    -


    - -Subsections - - -

    diff --git a/docs/html/node133.html b/docs/html/node133.html index ba43c36fd..fadd4e4bb 100644 --- a/docs/html/node133.html +++ b/docs/html/node133.html @@ -3,8 +3,8 @@ -psb_krylov -- Krylov Methods Driver Routine - +clone -- clone current preconditioner + @@ -14,427 +14,79 @@ + - + -

    -
    -psb_krylov -- Krylov Methods Driver - Routine +

    +clone -- clone current + preconditioner

    -

    -This subroutine is a driver that provides a general interface for all -the Krylov-Subspace family methods implemented in PSBLAS version 2. - -

    -The stopping criterion can take the following values: -

    -
    1
    -
    normwise backward error in the infinity -norm; the iteration is stopped when -

    -
    - - -\begin{displaymath}err = \frac{\Vert r_i\Vert}{(\Vert A\Vert\Vert x_i\Vert+\Vert b\Vert)} < eps \end{displaymath} -
    -
    -

    -
    -
    2
    -
    Relative residual in the 2-norm; the iteration is stopped -when -

    -
    - - -\begin{displaymath}err = \frac{\Vert r_i\Vert}{\Vert b\Vert _2} < eps \end{displaymath} -
    -
    -

    -
    -
    3
    -
    Relative residual reduction in the 2-norm; the iteration is stopped -when -

    -
    - - -\begin{displaymath}err = \frac{\Vert r_i\Vert}{\Vert r_0\Vert _2} < eps \end{displaymath} -
    -
    -

    -
    -
    -The behaviour is controlled by the istop argument (see -later). In the above formulae, $x_i$ is the tentative solution and -$r_i=b-Ax_i$ the corresponding residual at the $i$-th iteration. - -

    -
    -\begin{lstlisting}
-call psb_krylov(method,a,prec,b,x,eps,desc_a,info,&
-& itmax,iter,err,itrace,irst,istop,cond)
-\end{lstlisting} -
    +

    +call  prec%clone(precout,info)
    +

    Type:
    -
    Synchronous. +
    Asynchronous.
    On Entry
    -
    method
    -
    a string that defines the iterative method to be - used. Supported values are: -
    -
    CG:
    -
    the Conjugate Gradient method; - -
    -
    CGS:
    -
    the Conjugate Gradient Stabilized method; - -

    -

    -
    GCR:
    -
    the Generalized Conjugate Residual method; - -
    -
    FCG:
    -
    the Flexible Conjugate Gradient method5; - -

    -

    -
    BICG:
    -
    the Bi-Conjugate Gradient method; - -
    -
    BICGSTAB:
    -
    the Bi-Conjugate Gradient Stabilized method; - -
    -
    BICGSTABL:
    -
    the Bi-Conjugate Gradient Stabilized method with restarting; - -
    -
    RGMRES:
    -
    the Generalized Minimal Residual method with restarting. - -
    -
    -
    -
    a
    -
    the local portion of global sparse matrix -$A$. -
    -Scope: local -
    -Type: required -
    -Intent: in. -
    -Specified as: a structured data of type spdatapsb_Tspmat_type. -
    prec
    -
    The data structure containing the preconditioner. +
    the preconditioner.
    -Scope: local -
    -Type: required -
    -Intent: in. -
    -Specified as: a structured data of type precdatapsb_prec_type. -
    -
    b
    -
    The RHS vector. -
    -Scope: local -
    -Type: required -
    -Intent: in. -
    -Specified as: a rank one array or an object of type vdatapsb_T_vect_type. -
    -
    x
    -
    The initial guess. -
    -Scope: local -
    -Type: required -
    -Intent: inout. -
    -Specified as: a rank one array or an object of type vdatapsb_T_vect_type. -
    -
    eps
    -
    The stopping tolerance. -
    -Scope: global -
    -Type: required -
    -Intent: in. -
    -Specified as: a real number. -
    -
    desc_a
    -
    contains data structures for communications. -
    -Scope: local -
    -Type: required -
    -Intent: in. -
    -Specified as: a structured data of type descdatapsb_desc_type. -
    -
    itmax
    -
    The maximum number of iterations to perform. -
    -Scope: global -
    -Type: optional -
    -Intent: in. -
    -Default: $itmax = 1000$. -
    -Specified as: an integer variable $itmax \ge 1$. -
    -
    itrace
    -
    If $>0$ print out an informational message about - convergence every $itrace$ iterations. If $=0$ print a message in - case of convergence failure. -
    -Scope: global -
    -Type: optional -
    -Intent: in. -
    -Default: $itrace = -1$. +Scope: local.
    -
    irst
    -
    An integer specifying the restart parameter. -
    -Scope: global -
    -Type: optional. -
    -Intent: in. -
    -Values: $irst>0$. This is employed for the BiCGSTABL or RGMRES -methods, otherwise it is ignored. +

    - -

    istop
    -
    An integer specifying the stopping criterion. -
    -Scope: global -
    -Type: optional. -
    -Intent: in. -
    -Values: 1: use the normwise backward error, 2: use the scaled 2-norm -of the residual, 3: use the residual reduction in the 2-norm. Default: 2. -
    +
    On Return
    -
    x
    -
    The computed solution. -
    -Scope: local -
    -Type: required -
    -Intent: inout. -
    -Specified as: a rank one array or an object of type vdatapsb_T_vect_type. -
    -
    iter
    -
    The number of iterations performed. -
    -Scope: global -
    -Type: optional -
    -Intent: out. -
    -Returned as: an integer variable. -
    -
    err
    -
    The convergence estimate on exit. -
    -Scope: global -
    -Type: optional -
    -Intent: out. -
    -Returned as: a real number. -
    -
    cond
    -
    An estimate of the condition number of matrix $A$; only - available with the $CG$ method on real data. -
    -Scope: global -
    -Type: optional -
    -Intent: out. -
    -Returned as: a real number. A correct result will be greater than or -equal to one; if specified for non-real data, or an error occurred, -zero is returned. +
    precout
    +
    A copy of the input object.
    info
    -
    Error code. -
    -Scope: local -
    -Type: required -
    -Intent: out. -
    -An integer value; 0 means no error has been detected. +
    Return code.

    - -

    - -

    - -

    - -

    - +

    diff --git a/docs/html/node134.html b/docs/html/node134.html index fa6197a58..c98f860ce 100644 --- a/docs/html/node134.html +++ b/docs/html/node134.html @@ -3,8 +3,8 @@ -Bibliography - +free -- Free a preconditioner + @@ -14,164 +14,91 @@ - - - + + +
    +
    - -

    -Bibliography -

    1 -
    - D. Barbieri, V. Cardellini, S. Filippone and D. Rouson -Design Patterns for Scientific Computations on Sparse Matrices, - HPSS 2011, Algorithms and Programming Tools for Next-Generation High-Performance Scientific Software, Bordeaux, Sep. 2011 + +

    +free -- Free a preconditioner +

    -

    2 +
    +call prec%free(info)
    +
    + +

    +

    +
    Type:
    +
    Asynchronous. +
    +
    On Entry
    -G. Bella, S. Filippone, A. De Maio and M. Testa, -A Simulation Model for Forest Fires, -in J. Dongarra, K. Madsen, J. Wasniewski, editors, -Proceedings of PARA 04 Workshop on State of the Art -in Scientific Computing, pp. 546-553, Lecture Notes in Computer Science, -Springer, 2005. -

    3 -
    A. Buttari, D. di Serafino, P. D'Ambra, S. Filippone,
    -2LEV-D2P4: a package of high-performance preconditioners,
    -Applicable Algebra in Engineering, Communications and Computing, -Volume 18, Number 3, May, 2007, pp. 223-239 -

    4 -
    P. D'Ambra, S. Filippone, D. Di Serafino
    -On the Development of PSBLAS-based Parallel Two-level Schwarz Preconditioners +
    +
    prec
    +
    the preconditioner.
    -Applied Numerical Mathematics, Elsevier Science, -Volume 57, Issues 11-12, November-December 2007, Pages 1181-1196. - -

    -

    5 -
    - Dongarra, J. J., DuCroz, J., Hammarling, S. and Hanson, R., -An Extended Set of Fortran Basic Linear Algebra Subprograms, -ACM Trans. Math. Softw. vol. 14, 1-17, 1988. -

    6 -
    - Dongarra, J., DuCroz, J., Hammarling, S. and Duff, I., -A Set of level 3 Basic Linear Algebra Subprograms, -ACM Trans. Math. Softw. vol. 16, 1-17, 1990. -

    7 -
    -J. J. Dongarra and R. C. Whaley, -A User's Guide to the BLACS v. 1.1, -Lapack Working Note 94, Tech. Rep. UT-CS-95-281, University of -Tennessee, March 1995 (updated May 1997). -

    8 -
    -I. Duff, M. Marrone, G. Radicati and C. Vittoli, -Level 3 Basic Linear Algebra Subprograms for Sparse Matrices: -a User Level Interface, -ACM Transactions on Mathematical Software, 23(3), pp. 379-401, 1997. -

    9 -
    -I. Duff, M. Heroux and R. Pozo, -An Overview of the Sparse Basic Linear -Algebra Subprograms: the New Standard from the BLAS Technical Forum, -ACM Transactions on Mathematical Software, 28(2), pp. 239-267, 2002. -

    10 -
    -S. Filippone and M. Colajanni, -PSBLAS: A Library for Parallel Linear Algebra -Computation on Sparse Matrices, +Scope: local.
    -ACM Transactions on Mathematical Software, 26(4), pp. 527-550, 2000. -

    11 -
    -S. Filippone and A. Buttari, -Object-Oriented Techniques for Sparse Matrix Computations in Fortran 2003, +Type: required
    -ACM Transactions on Mathematical Software, 38(4), 2012. -

    12 -
    -S. Filippone, P. D'Ambra, M. Colajanni, -Using a Parallel Library of Sparse Linear Algebra in a Fluid Dynamics -Applications Code on Linux Clusters, -in G. Joubert, A. Murli, F. Peters, M. Vanneschi, editors, -Parallel Computing - Advances & Current Issues, -pp. 441-448, Imperial College Press, 2002. -

    13 -
    - Gamma, E., Helm, R., Johnson, R., and Vlissides, - J. 1995. - Design Patterns: Elements of Reusable Object-Oriented Software. - Addison-Wesley. - -

    -

    14 -
    -Karypis, G. and Kumar, V., -METIS: Unstructured Graph Partitioning and Sparse Matrix - Ordering System. -Minneapolis, MN 55455: University of Minnesota, Department of - Computer Science, 1995. -Internet Address: http://www.cs.umn.edu/~karypis. -

    15 -
    -Lawson, C., Hanson, R., Kincaid, D. and Krogh, F., - Basic Linear Algebra Subprograms for Fortran usage, -ACM Trans. Math. Softw. vol. 5, 38-329, 1979. - -

    -

    16 -
    -Machiels, L. and Deville, M. -Fortran 90: An entry to object-oriented programming for the solution - of partial differential equations. -ACM Trans. Math. Softw. vol. 23, 32-49. -

    17 -
    -Metcalf, M., Reid, J. and Cohen, M. -Fortran 95/2003 explained. -Oxford University Press, 2004. -

    18 -
    -Rouson, D.W.I., Xia, J., Xu, X.: Scientific Software Design: The - Object-Oriented Way. Cambridge University Press (2011) - -

    -

    19 -
    -M. Snir, S. Otto, S. Huss-Lederman, D. Walker and J. Dongarra, -MPI: The Complete Reference. Volume 1 - The MPI Core, second edition, -MIT Press, 1998. +Intent: inout. +
    +Specified as: a preconditioner data structure precdatapsb_prec_type. +
    +
    On Exit
    +

    +

    +
    prec
    +
    Scope: local +
    +Type: required +
    +Intent: inout. +
    +Specified as: a preconditioner data structure precdatapsb_prec_type. +
    +
    info
    +
    Scope: global +
    +Type: required +
    +Intent: out. +
    +Error code: if no error, 0 is returned. +
    +Notes +Releases all internal storage.



    diff --git a/docs/html/node135.html b/docs/html/node135.html index 29fee5d55..9dda94793 100644 --- a/docs/html/node135.html +++ b/docs/html/node135.html @@ -3,8 +3,8 @@ -About this document ... - +Iterative Methods + @@ -14,53 +14,62 @@ - + + + -

    -About this document ... -

    -

    -This document was generated using the -LaTeX2HTML translator Version 2018 (Released Feb 1, 2018) -

    -Copyright © 1993, 1994, 1995, 1996, -Nikos Drakos, -Computer Based Learning Unit, University of Leeds. +

    +
    -Copyright © 1997, 1998, 1999, -Ross Moore, -Mathematics Department, Macquarie University, Sydney. +Iterative Methods +

    +

    -The command line arguments were:
    - latex2html -local_icons -noaddress -dir ../../html userhtml.tex +In this chapter we provide routines for preconditioners and iterative +methods. The interfaces for Krylov subspace methods are available in +the module psb_krylov_mod. +

    -The translation was initiated on 2019-05-28 +


    + +Subsections + + +

    diff --git a/docs/html/node136.html b/docs/html/node136.html new file mode 100644 index 000000000..1899d05d4 --- /dev/null +++ b/docs/html/node136.html @@ -0,0 +1,440 @@ + + + + + +psb_krylov -- Krylov Methods Driver Routine + + + + + + + + + + + + + + + + + + + + +

    +
    +psb_krylov -- Krylov Methods Driver + Routine +

    + +

    +This subroutine is a driver that provides a general interface for all +the Krylov-Subspace family methods implemented in PSBLAS version 2. + +

    +The stopping criterion can take the following values: +

    +
    1
    +
    normwise backward error in the infinity +norm; the iteration is stopped when +

    +
    + + +\begin{displaymath}err = \frac{\Vert r_i\Vert}{(\Vert A\Vert\Vert x_i\Vert+\Vert b\Vert)} < eps \end{displaymath} +
    +
    +

    +
    +
    2
    +
    Relative residual in the 2-norm; the iteration is stopped +when +

    +
    + + +\begin{displaymath}err = \frac{\Vert r_i\Vert}{\Vert b\Vert _2} < eps \end{displaymath} +
    +
    +

    +
    +
    3
    +
    Relative residual reduction in the 2-norm; the iteration is stopped +when +

    +
    + + +\begin{displaymath}err = \frac{\Vert r_i\Vert}{\Vert r_0\Vert _2} < eps \end{displaymath} +
    +
    +

    +
    +
    +The behaviour is controlled by the istop argument (see +later). In the above formulae, $x_i$ is the tentative solution and +$r_i=b-Ax_i$ the corresponding residual at the $i$-th iteration. + +

    +
    +\begin{lstlisting}
+call psb_krylov(method,a,prec,b,x,eps,desc_a,info,&
+& itmax,iter,err,itrace,irst,istop,cond)
+\end{lstlisting} +
    + +

    +

    +
    Type:
    +
    Synchronous. +
    +
    On Entry
    +
    +
    +
    method
    +
    a string that defines the iterative method to be + used. Supported values are: +
    +
    CG:
    +
    the Conjugate Gradient method; + +
    +
    CGS:
    +
    the Conjugate Gradient Stabilized method; + +

    +

    +
    GCR:
    +
    the Generalized Conjugate Residual method; + +
    +
    FCG:
    +
    the Flexible Conjugate Gradient method5; + +

    +

    +
    BICG:
    +
    the Bi-Conjugate Gradient method; + +
    +
    BICGSTAB:
    +
    the Bi-Conjugate Gradient Stabilized method; + +
    +
    BICGSTABL:
    +
    the Bi-Conjugate Gradient Stabilized method with restarting; + +
    +
    RGMRES:
    +
    the Generalized Minimal Residual method with restarting. + +
    +
    +
    +
    a
    +
    the local portion of global sparse matrix +$A$. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: a structured data of type spdatapsb_Tspmat_type. +
    +
    prec
    +
    The data structure containing the preconditioner. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: a structured data of type precdatapsb_prec_type. +
    +
    b
    +
    The RHS vector. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: a rank one array or an object of type vdatapsb_T_vect_type. +
    +
    x
    +
    The initial guess. +
    +Scope: local +
    +Type: required +
    +Intent: inout. +
    +Specified as: a rank one array or an object of type vdatapsb_T_vect_type. +
    +
    eps
    +
    The stopping tolerance. +
    +Scope: global +
    +Type: required +
    +Intent: in. +
    +Specified as: a real number. +
    +
    desc_a
    +
    contains data structures for communications. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: a structured data of type descdatapsb_desc_type. +
    +
    itmax
    +
    The maximum number of iterations to perform. +
    +Scope: global +
    +Type: optional +
    +Intent: in. +
    +Default: $itmax = 1000$. +
    +Specified as: an integer variable $itmax \ge 1$. +
    +
    itrace
    +
    If $>0$ print out an informational message about + convergence every $itrace$ iterations. If $=0$ print a message in + case of convergence failure. +
    +Scope: global +
    +Type: optional +
    +Intent: in. +
    +Default: $itrace = -1$. +
    +
    irst
    +
    An integer specifying the restart parameter. +
    +Scope: global +
    +Type: optional. +
    +Intent: in. +
    +Values: $irst>0$. This is employed for the BiCGSTABL or RGMRES +methods, otherwise it is ignored. + +

    +

    +
    istop
    +
    An integer specifying the stopping criterion. +
    +Scope: global +
    +Type: optional. +
    +Intent: in. +
    +Values: 1: use the normwise backward error, 2: use the scaled 2-norm +of the residual, 3: use the residual reduction in the 2-norm. Default: 2. +
    +
    On Return
    +
    +
    +
    x
    +
    The computed solution. +
    +Scope: local +
    +Type: required +
    +Intent: inout. +
    +Specified as: a rank one array or an object of type vdatapsb_T_vect_type. +
    +
    iter
    +
    The number of iterations performed. +
    +Scope: global +
    +Type: optional +
    +Intent: out. +
    +Returned as: an integer variable. +
    +
    err
    +
    The convergence estimate on exit. +
    +Scope: global +
    +Type: optional +
    +Intent: out. +
    +Returned as: a real number. +
    +
    cond
    +
    An estimate of the condition number of matrix $A$; only + available with the $CG$ method on real data. +
    +Scope: global +
    +Type: optional +
    +Intent: out. +
    +Returned as: a real number. A correct result will be greater than or +equal to one; if specified for non-real data, or an error occurred, +zero is returned. +
    +
    info
    +
    Error code. +
    +Scope: local +
    +Type: required +
    +Intent: out. +
    +An integer value; 0 means no error has been detected. +
    +
    + +

    + +

    + +

    + +

    + +

    + + + + diff --git a/docs/html/node137.html b/docs/html/node137.html new file mode 100644 index 000000000..4717ee2dd --- /dev/null +++ b/docs/html/node137.html @@ -0,0 +1,180 @@ + + + + + +Bibliography + + + + + + + + + + + + + + + + + + + + + +

    +Bibliography +

    1 +
    + D. Barbieri, V. Cardellini, S. Filippone and D. Rouson +Design Patterns for Scientific Computations on Sparse Matrices, + HPSS 2011, Algorithms and Programming Tools for Next-Generation High-Performance Scientific Software, Bordeaux, Sep. 2011 + +

    +

    2 +
    +G. Bella, S. Filippone, A. De Maio and M. Testa, +A Simulation Model for Forest Fires, +in J. Dongarra, K. Madsen, J. Wasniewski, editors, +Proceedings of PARA 04 Workshop on State of the Art +in Scientific Computing, pp. 546-553, Lecture Notes in Computer Science, +Springer, 2005. +

    3 +
    A. Buttari, D. di Serafino, P. D'Ambra, S. Filippone,
    +2LEV-D2P4: a package of high-performance preconditioners,
    +Applicable Algebra in Engineering, Communications and Computing, +Volume 18, Number 3, May, 2007, pp. 223-239 +

    4 +
    P. D'Ambra, S. Filippone, D. Di Serafino
    +On the Development of PSBLAS-based Parallel Two-level Schwarz Preconditioners +
    +Applied Numerical Mathematics, Elsevier Science, +Volume 57, Issues 11-12, November-December 2007, Pages 1181-1196. + +

    +

    5 +
    + Dongarra, J. J., DuCroz, J., Hammarling, S. and Hanson, R., +An Extended Set of Fortran Basic Linear Algebra Subprograms, +ACM Trans. Math. Softw. vol. 14, 1-17, 1988. +

    6 +
    + Dongarra, J., DuCroz, J., Hammarling, S. and Duff, I., +A Set of level 3 Basic Linear Algebra Subprograms, +ACM Trans. Math. Softw. vol. 16, 1-17, 1990. +

    7 +
    +J. J. Dongarra and R. C. Whaley, +A User's Guide to the BLACS v. 1.1, +Lapack Working Note 94, Tech. Rep. UT-CS-95-281, University of +Tennessee, March 1995 (updated May 1997). +

    8 +
    +I. Duff, M. Marrone, G. Radicati and C. Vittoli, +Level 3 Basic Linear Algebra Subprograms for Sparse Matrices: +a User Level Interface, +ACM Transactions on Mathematical Software, 23(3), pp. 379-401, 1997. +

    9 +
    +I. Duff, M. Heroux and R. Pozo, +An Overview of the Sparse Basic Linear +Algebra Subprograms: the New Standard from the BLAS Technical Forum, +ACM Transactions on Mathematical Software, 28(2), pp. 239-267, 2002. +

    10 +
    +S. Filippone and M. Colajanni, +PSBLAS: A Library for Parallel Linear Algebra +Computation on Sparse Matrices, +
    +ACM Transactions on Mathematical Software, 26(4), pp. 527-550, 2000. +

    11 +
    +S. Filippone and A. Buttari, +Object-Oriented Techniques for Sparse Matrix Computations in Fortran 2003, +
    +ACM Transactions on Mathematical Software, 38(4), 2012. +

    12 +
    +S. Filippone, P. D'Ambra, M. Colajanni, +Using a Parallel Library of Sparse Linear Algebra in a Fluid Dynamics +Applications Code on Linux Clusters, +in G. Joubert, A. Murli, F. Peters, M. Vanneschi, editors, +Parallel Computing - Advances & Current Issues, +pp. 441-448, Imperial College Press, 2002. +

    13 +
    + Gamma, E., Helm, R., Johnson, R., and Vlissides, + J. 1995. + Design Patterns: Elements of Reusable Object-Oriented Software. + Addison-Wesley. + +

    +

    14 +
    +Karypis, G. and Kumar, V., +METIS: Unstructured Graph Partitioning and Sparse Matrix + Ordering System. +Minneapolis, MN 55455: University of Minnesota, Department of + Computer Science, 1995. +Internet Address: http://www.cs.umn.edu/~karypis. +

    15 +
    +Lawson, C., Hanson, R., Kincaid, D. and Krogh, F., + Basic Linear Algebra Subprograms for Fortran usage, +ACM Trans. Math. Softw. vol. 5, 38-329, 1979. + +

    +

    16 +
    +Machiels, L. and Deville, M. +Fortran 90: An entry to object-oriented programming for the solution + of partial differential equations. +ACM Trans. Math. Softw. vol. 23, 32-49. +

    17 +
    +Metcalf, M., Reid, J. and Cohen, M. +Fortran 95/2003 explained. +Oxford University Press, 2004. +

    18 +
    +Rouson, D.W.I., Xia, J., Xu, X.: Scientific Software Design: The + Object-Oriented Way. Cambridge University Press (2011) + +

    +

    19 +
    +M. Snir, S. Otto, S. Huss-Lederman, D. Walker and J. Dongarra, +MPI: The Complete Reference. Volume 1 - The MPI Core, second edition, +MIT Press, 1998. +
    + +

    +


    + + + diff --git a/docs/html/node138.html b/docs/html/node138.html new file mode 100644 index 000000000..6fd05bf82 --- /dev/null +++ b/docs/html/node138.html @@ -0,0 +1,67 @@ + + + + + +About this document ... + + + + + + + + + + + + + + + + + + + +

    +About this document ... +

    +

    +This document was generated using the +LaTeX2HTML translator Version 2018 (Released Feb 1, 2018) +

    +Copyright © 1993, 1994, 1995, 1996, +Nikos Drakos, +Computer Based Learning Unit, University of Leeds. +
    +Copyright © 1997, 1998, 1999, +Ross Moore, +Mathematics Department, Macquarie University, Sydney. +

    +The command line arguments were:
    + latex2html -local_icons -noaddress -dir ../../html userhtml.tex +

    +The translation was initiated on 2019-11-21 +


    + + + diff --git a/docs/html/node14.html b/docs/html/node14.html index df52c1c46..914b0e58c 100644 --- a/docs/html/node14.html +++ b/docs/html/node14.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node15.html b/docs/html/node15.html index 32983a8e6..0f9aa78af 100644 --- a/docs/html/node15.html +++ b/docs/html/node15.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node16.html b/docs/html/node16.html index d7a1001d0..e938a3c29 100644 --- a/docs/html/node16.html +++ b/docs/html/node16.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node17.html b/docs/html/node17.html index c432cd85d..80c4cf41d 100644 --- a/docs/html/node17.html +++ b/docs/html/node17.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node18.html b/docs/html/node18.html index 42ebe8813..422ddc253 100644 --- a/docs/html/node18.html +++ b/docs/html/node18.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node19.html b/docs/html/node19.html index 35a0d5cb0..af94fa1c1 100644 --- a/docs/html/node19.html +++ b/docs/html/node19.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node2.html b/docs/html/node2.html index 3f09ef740..cc966d25f 100644 --- a/docs/html/node2.html +++ b/docs/html/node2.html @@ -23,26 +23,26 @@ @@ -68,7 +68,7 @@ passing.

    The PSBLAS library version 3 is implemented in the Fortran 2003 [17] programming language, with reuse and/or + HREF="node137.html#metcalf">17] programming language, with reuse and/or adaptation of existing Fortran 77 and Fortran 95 software, plus a handful of C routines. @@ -78,11 +78,11 @@ mostly in the handling of requirements for evolution and adaptation of the library to new computing architectures and integration of new algorithms. For a detailed discussion of our design see [11]; other + HREF="node137.html#Sparse03">11]; other works discussing advanced programming in Fortran 2003 include [1,18]; sufficient support for + HREF="node137.html#DesPat:11">1,18]; sufficient support for Fortran 2003 is now available from many compilers, including the GNU Fortran compiler from the Free Software Foundation (as of version 4.8). @@ -91,7 +91,7 @@ Previous approaches have been based on mixing Fortran 95, with its support for object-based design, with other languages; these have been advocated by a number of authors, e.g. [16]. Moreover, the Fortran 95 facilities for dynamic + HREF="node137.html#machiels">16]. Moreover, the Fortran 95 facilities for dynamic memory management and interface overloading greatly enhance the usability of the PSBLAS subroutines. In this way, the library can take care of runtime memory @@ -102,12 +102,12 @@ implementation or compilation time. The presentation of the PSBLAS library follows the general structure of the proposal for serial Sparse BLAS [8,9], which in its turn is based on the + HREF="node137.html#sblas97">8,9], which in its turn is based on the proposal for BLAS on dense matrices [15,5,6]. + HREF="node137.html#BLAS1">15,5,6].

    The applicability of sparse iterative solvers to many different areas @@ -142,26 +142,26 @@ computational fluid dynamics applications.

    diff --git a/docs/html/node20.html b/docs/html/node20.html index 905f54a5f..f5816c702 100644 --- a/docs/html/node20.html +++ b/docs/html/node20.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node21.html b/docs/html/node21.html index 3478b03a8..2e6a31b63 100644 --- a/docs/html/node21.html +++ b/docs/html/node21.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node22.html b/docs/html/node22.html index b733e044a..2f9f2a6ac 100644 --- a/docs/html/node22.html +++ b/docs/html/node22.html @@ -22,26 +22,26 @@ diff --git a/docs/html/node23.html b/docs/html/node23.html index ecc0e565c..1105c101c 100644 --- a/docs/html/node23.html +++ b/docs/html/node23.html @@ -23,26 +23,26 @@ @@ -57,9 +57,9 @@ The spdatapsb_Tspmat_type class contains all information about the local portion of the sparse matrix and its storage mode. Its design is based on the STATE design pattern [13] as detailed + HREF="node137.html#DesignPatterns">13] as detailed in [11]; the type declaration is shown in + HREF="node137.html#Sparse03">11]; the type declaration is shown in figure 4 where T is a placeholder for the data type and precision variants
    @@ -141,74 +141,74 @@ variants are obtained by conversion to/from it. Subsections diff --git a/docs/html/node24.html b/docs/html/node24.html index 660dda429..95bed484d 100644 --- a/docs/html/node24.html +++ b/docs/html/node24.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node25.html b/docs/html/node25.html index 4e11b66d2..892822632 100644 --- a/docs/html/node25.html +++ b/docs/html/node25.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node26.html b/docs/html/node26.html index c22ddd4c6..b354b89f4 100644 --- a/docs/html/node26.html +++ b/docs/html/node26.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node27.html b/docs/html/node27.html index a7b464d09..79142d1ed 100644 --- a/docs/html/node27.html +++ b/docs/html/node27.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node28.html b/docs/html/node28.html index c7f4130fb..93fa1562f 100644 --- a/docs/html/node28.html +++ b/docs/html/node28.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node29.html b/docs/html/node29.html index bd2a7410b..6543ee2dd 100644 --- a/docs/html/node29.html +++ b/docs/html/node29.html @@ -25,26 +25,26 @@ of a sparse matrix"> diff --git a/docs/html/node3.html b/docs/html/node3.html index 9d55ff44f..0d4479c1f 100644 --- a/docs/html/node3.html +++ b/docs/html/node3.html @@ -23,26 +23,26 @@ @@ -56,7 +56,7 @@ General overview The PSBLAS library is designed to handle the implementation of iterative solvers for sparse linear systems on distributed memory parallel computers. The system coefficient matrix $A$ must be square; it may be real or complex, nonsymmetric, and its sparsity pattern @@ -75,10 +75,10 @@ calls to the serial sparse BLAS subroutines. In a similar way, the inter-process message exchanges are encapsulated in an applicaiton layer that has been strongly inspired by the Basic Linear Algebra Communication Subroutines (BLACS) library [7]. + HREF="node137.html#BLACS">7]. Usually there is no need to deal directly with MPI; however, in some cases, MPI routines are used directly to improve efficiency. For -further details on our communication layer see Sec. 7. +further details on our communication layer see Sec. 7.

    @@ -131,7 +131,7 @@ equation indices to processes. In particular it is consistent with the usage of graph partitioning tools commonly available in the literature, e.g. METIS [14]. + HREF="node137.html#METIS">14]. Dense vectors conform to sparse matrices, that is, the entries of a vector follow the same distribution of the matrix rows. @@ -151,44 +151,44 @@ bottleneck would make this option unattractive in most cases. Subsections

    diff --git a/docs/html/node30.html b/docs/html/node30.html index abfd6eca7..6bb1780dc 100644 --- a/docs/html/node30.html +++ b/docs/html/node30.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node31.html b/docs/html/node31.html index d12946dd8..1b942045c 100644 --- a/docs/html/node31.html +++ b/docs/html/node31.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node32.html b/docs/html/node32.html index e799406e3..a515bd961 100644 --- a/docs/html/node32.html +++ b/docs/html/node32.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node33.html b/docs/html/node33.html index 09fdf1042..7d7e9b278 100644 --- a/docs/html/node33.html +++ b/docs/html/node33.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node34.html b/docs/html/node34.html index c5b9402dc..79ac9113e 100644 --- a/docs/html/node34.html +++ b/docs/html/node34.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node35.html b/docs/html/node35.html index 027817f2f..87018a14c 100644 --- a/docs/html/node35.html +++ b/docs/html/node35.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node36.html b/docs/html/node36.html index 4768938d7..542aa3f78 100644 --- a/docs/html/node36.html +++ b/docs/html/node36.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node37.html b/docs/html/node37.html index 6cc088c91..1fc5b6e4e 100644 --- a/docs/html/node37.html +++ b/docs/html/node37.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node38.html b/docs/html/node38.html index a718ea45d..7a7e8e5d0 100644 --- a/docs/html/node38.html +++ b/docs/html/node38.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node39.html b/docs/html/node39.html index 685de000e..30ece33f7 100644 --- a/docs/html/node39.html +++ b/docs/html/node39.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node4.html b/docs/html/node4.html index 1fd13393a..81bbea421 100644 --- a/docs/html/node4.html +++ b/docs/html/node4.html @@ -23,26 +23,26 @@ @@ -62,21 +62,21 @@ PDE. Each point of the discretization mesh will have (at least) one associated equation/variable, and therefore one index. We say that point $i$ depends on point $j$ if the equation for a variable associated with $i$ contains a term in $j$, or equivalently if $a_{ij} \ne0$. After the partition of the discretization mesh into sub-domains @@ -123,25 +123,25 @@ Overlap points do not usually exist in the basic data distributions; however they are a feature of Domain Decomposition Schwarz preconditioners which are the subject of related research work [4,3]. + HREF="node137.html#2007c">4,3].

    We denote the sets of internal, boundary and halo points for a given subdomain by $\cal I$, $\cal B$ and $\cal H$. Each subdomain is assigned to one process; each process usually owns one subdomain, although the user may choose to assign more than one subdomain to a process. If each process $i$ owns one subdomain, the number of rows in the local sparse matrix is @@ -149,7 +149,7 @@ subdomain, the number of rows in the local sparse matrix is $|{\cal I}_i| + |{\cal B}_i|$ --> $\vert{\cal I}_i\vert + \vert{\cal B}_i\vert$, and the number of local columns (i.e. those for which there exists at least one non-zero entry in the @@ -157,7 +157,7 @@ local rows) is $\vert{\cal I}_i\vert + \vert{\cal B}_i\vert +\vert{\cal H}_i\vert$. @@ -170,7 +170,7 @@ Point classfication.

    diff --git a/docs/html/node40.html b/docs/html/node40.html index 33021ee91..aef8c0c1d 100644 --- a/docs/html/node40.html +++ b/docs/html/node40.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node41.html b/docs/html/node41.html index b76f447cd..83caf8851 100644 --- a/docs/html/node41.html +++ b/docs/html/node41.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node42.html b/docs/html/node42.html index 0810e2ecc..34e452e09 100644 --- a/docs/html/node42.html +++ b/docs/html/node42.html @@ -22,26 +22,26 @@ diff --git a/docs/html/node43.html b/docs/html/node43.html index 74f930ba1..096acda1a 100644 --- a/docs/html/node43.html +++ b/docs/html/node43.html @@ -23,26 +23,26 @@ @@ -57,7 +57,7 @@ The vdatapsb_T_vect_type data structure encapsulates the dense vectors in a way similar to sparse matrices, i.e. including a base type vbasedata psb_T_base_vect_type. The user will not, in general, access the vector components directly, -but rather via the routines of sec. 6. Among other +but rather via the routines of sec. 6. Among other simple things, we define here an extraction method that can be used to get a full copy of the part of the vector stored on the local process. @@ -119,44 +119,44 @@ private memory. Subsections diff --git a/docs/html/node44.html b/docs/html/node44.html index d7ea4154e..59a5574b7 100644 --- a/docs/html/node44.html +++ b/docs/html/node44.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node45.html b/docs/html/node45.html index 967d15c69..41ef895e2 100644 --- a/docs/html/node45.html +++ b/docs/html/node45.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node46.html b/docs/html/node46.html index 85e388673..18fa65e1d 100644 --- a/docs/html/node46.html +++ b/docs/html/node46.html @@ -25,26 +25,26 @@ of a dense vector"> diff --git a/docs/html/node47.html b/docs/html/node47.html index b14e02f91..2feec7f95 100644 --- a/docs/html/node47.html +++ b/docs/html/node47.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node48.html b/docs/html/node48.html index e8c5cf980..4bc79826d 100644 --- a/docs/html/node48.html +++ b/docs/html/node48.html @@ -23,26 +23,26 @@ @@ -89,15 +89,15 @@ Type: optional; default: entire vector.
    Function value
    An allocatable array holding a copy of the dense vector contents. If the argument $n$ is specified, the size of the returned array equals the minimum between $n$ and the internal size of the vector, or 0 if $n$ is negative; otherwise, the size of the array is the same as the internal size of the vector. diff --git a/docs/html/node49.html b/docs/html/node49.html index 08d0b52ca..8344bc75f 100644 --- a/docs/html/node49.html +++ b/docs/html/node49.html @@ -22,26 +22,26 @@ diff --git a/docs/html/node5.html b/docs/html/node5.html index a2f0e2b83..f2b0e0341 100644 --- a/docs/html/node5.html +++ b/docs/html/node5.html @@ -23,26 +23,26 @@ @@ -125,7 +125,7 @@ internally defined in the PSBLAS software package:
  • For example the psb_geins, psb_spins and - psb_cdins perform the same action (see 6) on + psb_cdins perform the same action (see 6) on dense matrices, sparse matrices and communication descriptors respectively. Interface overloading allows the usage of the same subroutine @@ -167,26 +167,26 @@ whose current value is 3.4.0 diff --git a/docs/html/node50.html b/docs/html/node50.html index 3b2fcc2e7..e61abc77d 100644 --- a/docs/html/node50.html +++ b/docs/html/node50.html @@ -23,26 +23,26 @@ diff --git a/docs/html/node51.html b/docs/html/node51.html index d7f55d82e..41816dcff 100644 --- a/docs/html/node51.html +++ b/docs/html/node51.html @@ -22,26 +22,26 @@ @@ -52,7 +52,7 @@ Heap data structure

    -Among the tools routines of sec. 6, we have a number +Among the tools routines of sec. 6, we have a number of sorting utilities; the heap sort is implemented in terms of heaps having the following signatures:

    diff --git a/docs/html/node52.html b/docs/html/node52.html index deb3c842a..1d9cf8ca3 100644 --- a/docs/html/node52.html +++ b/docs/html/node52.html @@ -14,7 +14,7 @@ - + @@ -23,26 +23,26 @@ @@ -58,33 +58,39 @@ Computational routines Subsections

    diff --git a/docs/html/node53.html b/docs/html/node53.html index 6df5a1876..b3c9a66e6 100644 --- a/docs/html/node53.html +++ b/docs/html/node53.html @@ -23,26 +23,26 @@ @@ -78,7 +78,7 @@ call psb_geaxpby(alpha, x, beta, y, desc_a, info)


    -
    +
    @@ -86,16 +86,16 @@ Data types
    Table 1: Data types
    @@ -129,7 +129,7 @@ Data types
    alpha
    the scalar $\alpha$.
    @@ -145,7 +145,7 @@ type indicated in Table 1.
    x
    the local portion of global dense matrix $x$.
    @@ -158,16 +158,16 @@ Intent: in. Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type containing numbers of type specified in Table 1. The rank of $x$ must be the same of $y$.
    beta
    the scalar $\beta$.
    @@ -182,7 +182,7 @@ Specified as: a number of the data type indicated in Table $y$.
    @@ -194,10 +194,10 @@ Intent: inout.
    Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type containing numbers of the type indicated in Table 
    1. The rank of $y$ must be the same of $x$.
    @@ -223,7 +223,7 @@ Specified as: an object of type descdatapsb_desc_type.
    y
    the local portion of result submatrix $y$.
    @@ -253,26 +253,26 @@ An integer value; 0 means no error has been detected. diff --git a/docs/html/node54.html b/docs/html/node54.html index 1cfefa4ff..9ab3fd9c3 100644 --- a/docs/html/node54.html +++ b/docs/html/node54.html @@ -23,26 +23,26 @@ @@ -54,19 +54,19 @@ psb_gedot -- Dot Product

    This function computes dot product between two vectors $x$ and $y$.
    If $x$ and $y$ are real vectors it computes dot-product as: @@ -86,10 +86,10 @@ dot \leftarrow x^T y

    Else if $x$ and $y$ are complex vectors then it computes dot-product as:

    @@ -101,7 +101,7 @@ dot \leftarrow x^H y --> \begin{displaymath}dot \leftarrow x^H y\end{displaymath} @@ -113,7 +113,7 @@ dot \leftarrow x^H y psb_gedot(x, y, desc_a, info [,global])

    -
    +
    $x$, $y$, $\alpha$, $\beta$ Subroutine
    @@ -121,13 +121,13 @@ Data types
    Table 2: Data types
    @@ -162,7 +162,7 @@ Data types
    x
    the local portion of global dense matrix $x$.
    @@ -175,17 +175,17 @@ Intent: in. Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type containing numbers of type specified in Table 2. The rank of $x$ must be the same of $y$.
    y
    the local portion of global dense matrix $y$.
    @@ -198,10 +198,10 @@ Intent: in. Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type containing numbers of type specified in Table 2. The rank of $y$ must be the same of $x$.
    @@ -236,10 +236,10 @@ Default: global=.true.
    Function value
    is the dot product of vectors $x$ and $y$.
    @@ -272,7 +272,7 @@ An integer value; 0 means no error has been detected. by using the following scheme:
    \begin{lstlisting}
 vres(1) = psb_gedot(x1,y1,desc_a,info,global=.false.)
@@ -290,26 +290,26 @@ In this way the global communication, which for small sizes is a
 
 <DIV CLASS=
    - next - up - previous - contents
    - Next: Next: psb_gedots Generalized - Up: Up: Computational routines - Previous: Previous: psb_geaxpby General -   Contents diff --git a/docs/html/node55.html b/docs/html/node55.html index f14e7e64d..1244a8d8c 100644 --- a/docs/html/node55.html +++ b/docs/html/node55.html @@ -23,26 +23,26 @@ @@ -55,10 +55,10 @@ psb_gedots -- Generalized Dot Product

    This subroutine computes a series of dot products among the columns of two dense matrices $x$ and $y$:

    @@ -70,7 +70,7 @@ res(i) \leftarrow x(:,i)^T y(:,i) --> \begin{displaymath}res(i) \leftarrow x(:,i)^T y(:,i)\end{displaymath} @@ -78,17 +78,17 @@ res(i) \leftarrow x(:,i)^T y(:,i)

    If the matrices are complex, then the usual convention applies, i.e. the conjugate transpose of $x$ is used. If $x$ and $y$ are of rank one, then $res$ is a scalar, else it is a rank one array. @@ -98,7 +98,7 @@ is a rank one array. call psb_gedots(res, x, y, desc_a, info)

    -
    +
    $dot$, $x$, $y$ Function
    @@ -106,13 +106,13 @@ Data types
    Table 3: Data types
    @@ -147,7 +147,7 @@ Data types
    x
    the local portion of global dense matrix $x$.
    @@ -160,17 +160,17 @@ Intent: in. Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type containing numbers of type specified in Table 3. The rank of $x$ must be the same of $y$.
    y
    the local portion of global dense matrix $y$.
    @@ -183,10 +183,10 @@ Intent: in. Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type containing numbers of type specified in Table 3. The rank of $y$ must be the same of $x$.
    @@ -206,10 +206,10 @@ Specified as: an object of type descdatapsb_desc_type.
    res
    is the dot product of vectors $x$ and $y$.
    @@ -237,26 +237,26 @@ An integer value; 0 means no error has been detected. diff --git a/docs/html/node56.html b/docs/html/node56.html index d626f7f67..7f1ecd2b2 100644 --- a/docs/html/node56.html +++ b/docs/html/node56.html @@ -23,26 +23,26 @@ @@ -55,12 +55,12 @@ psb_normi -- Infinity-Norm of Vector

    This function computes the infinity-norm of a vector $x$.
    If $x$ is a real vector it computes infinity norm as: @@ -73,14 +73,14 @@ amax \leftarrow \max_i |x_i| --> \begin{displaymath}amax \leftarrow \max_i \vert x_i\vert\end{displaymath}

    else if $x$ is a complex vector then it computes the infinity-norm as:

    @@ -92,7 +92,7 @@ amax \leftarrow \max_i {(|re(x_i)| + |im(x_i)|)} --> \begin{displaymath}amax \leftarrow \max_i {(\vert re(x_i)\vert + \vert im(x_i)\vert)}\end{displaymath} @@ -107,7 +107,7 @@ psb_normi(x, desc_a, info [,global])


    -
    +
    $res$, $x$, $y$ Subroutine
    @@ -115,11 +115,11 @@ Data types
    Table 4: Data types
    @@ -158,7 +158,7 @@ Data types
    x
    the local portion of global dense matrix $x$. @@ -205,7 +205,7 @@ Default: global=.true.
    Function value
    is the infinity norm of vector $x$.
    @@ -238,7 +238,7 @@ An integer value; 0 means no error has been detected. by using the following scheme:
    \begin{lstlisting}
 vres(1) = psb_geamax(x1,desc_a,info,global=.false.)
@@ -256,26 +256,26 @@ In this way the global communication, which for small sizes is a
 
 <DIV CLASS=
    - next - up - previous - contents
    - Next: Next: psb_geamaxs Generalized - Up: Up: Computational routines - Previous: Previous: psb_gedots Generalized -   Contents diff --git a/docs/html/node57.html b/docs/html/node57.html index fdd2f842a..60bc14e4e 100644 --- a/docs/html/node57.html +++ b/docs/html/node57.html @@ -23,26 +23,26 @@ @@ -55,7 +55,7 @@ psb_geamaxs -- Generalized Infinity Norm

    This subroutine computes a series of infinity norms on the columns of a dense matrix $x$:

    @@ -67,7 +67,7 @@ res(i) \leftarrow \max_k |x(k,i)| --> \begin{displaymath}res(i) \leftarrow \max_k \vert x(k,i)\vert \end{displaymath} @@ -81,7 +81,7 @@ call psb_geamaxs(res, x, desc_a, info)


    -
    +
    $amax$ $x$ Function
    @@ -89,11 +89,11 @@ Data types
    Table 5: Data types
    @@ -132,7 +132,7 @@ Data types
    x
    the local portion of global dense matrix $x$.
    @@ -162,7 +162,7 @@ Specified as: an object of type descdatapsb_desc_type.
    res
    is the infinity norm of the columns of $x$.
    @@ -189,26 +189,26 @@ An integer value; 0 means no error has been detected. diff --git a/docs/html/node58.html b/docs/html/node58.html index c4fd28f7d..489a80f31 100644 --- a/docs/html/node58.html +++ b/docs/html/node58.html @@ -23,26 +23,26 @@ @@ -54,12 +54,12 @@ psb_norm1 -- 1-Norm of Vector

    This function computes the 1-norm of a vector $x$.
    If $x$ is a real vector it computes 1-norm as: @@ -72,14 +72,14 @@ asum \leftarrow \|x_i\| --> \begin{displaymath}asum \leftarrow \Vert x_i\Vert\end{displaymath}

    else if $x$ is a complex vector then it computes 1-norm as:

    @@ -91,7 +91,7 @@ asum \leftarrow \|re(x)\|_1 + \|im(x)\|_1 --> \begin{displaymath}asum \leftarrow \Vert re(x)\Vert _1 + \Vert im(x)\Vert _1\end{displaymath} @@ -106,7 +106,7 @@ psb_norm1(x, desc_a, info [,global])


    -
    +
    $res$ $x$ Subroutine
    @@ -114,11 +114,11 @@ Data types
    Table 6: Data types
    @@ -157,7 +157,7 @@ Data types
    x
    the local portion of global dense matrix $x$. @@ -203,7 +203,7 @@ Default: global=.true.
    Function value
    is the 1-norm of vector $x$.
    @@ -236,7 +236,7 @@ An integer value; 0 means no error has been detected. by using the following scheme:
    \begin{lstlisting}
 vres(1) = psb_geasum(x1,desc_a,info,global=.false.)
@@ -254,26 +254,26 @@ In this way the global communication, which for small sizes is a
 
 <DIV CLASS=
    - next - up - previous - contents
    - Next: Next: psb_geasums Generalized - Up: Up: Computational routines - Previous: Previous: psb_geamaxs Generalized -   Contents diff --git a/docs/html/node59.html b/docs/html/node59.html index 4ab320ea4..bed7c2508 100644 --- a/docs/html/node59.html +++ b/docs/html/node59.html @@ -23,26 +23,26 @@ @@ -55,7 +55,7 @@ psb_geasums -- Generalized 1-Norm of Vector

    This subroutine computes a series of 1-norms on the columns of a dense matrix $x$:

    @@ -67,19 +67,19 @@ res(i) \leftarrow \max_k |x(k,i)| --> \begin{displaymath}res(i) \leftarrow \max_k \vert x(k,i)\vert \end{displaymath}

    This function computes the 1-norm of a vector $x$.
    If $x$ is a real vector it computes 1-norm as: @@ -92,14 +92,14 @@ res(i) \leftarrow \|x_i\| --> \begin{displaymath}res(i) \leftarrow \Vert x_i\Vert\end{displaymath}

    else if $x$ is a complex vector then it computes 1-norm as:

    @@ -111,7 +111,7 @@ res(i) \leftarrow \|re(x)\|_1 + \|im(x)\|_1 --> \begin{displaymath}res(i) \leftarrow \Vert re(x)\Vert _1 + \Vert im(x)\Vert _1\end{displaymath} @@ -125,7 +125,7 @@ call psb_geasums(res, x, desc_a, info)


    -
    +
    $asum$ $x$ Function
    @@ -133,11 +133,11 @@ Data types
    Table 7: Data types
    @@ -176,7 +176,7 @@ Data types
    x
    the local portion of global dense matrix $x$. @@ -209,7 +209,7 @@ Specified as: an object of type descdatapsb_desc_type.
    res
    contains the 1-norm of (the columns of) $x$.
    @@ -237,26 +237,26 @@ An integer value; 0 means no error has been detected. diff --git a/docs/html/node6.html b/docs/html/node6.html index 91707813f..15321ca34 100644 --- a/docs/html/node6.html +++ b/docs/html/node6.html @@ -23,26 +23,26 @@ @@ -61,7 +61,7 @@ space to which there corresponds an index space and a matrix sparsity pattern. As an example, consider a cell-centered finite-volume discretization of the Navier-Stokes equations on a simulation domain; the index space $1\dots n$ is isomorphic to the set of cell centers, whereas the pattern of the associated linear system matrix is @@ -72,7 +72,7 @@ by the discretization stencil. Thus the first order of business is to establish an index space, and this is done with a call to psb_cdall in which we specify the size of the index space $n$ and the allocation of the elements of the index space to the various processes making up the MPI (virtual) @@ -81,22 +81,22 @@ parallel machine.

    The index space is partitioned among processes, and this creates a mapping from the “global” numbering $1\dots n$ to a numbering “local” to each process; each process $i$ will own a certain subset $1\dots n_{\hbox{row}_i}$, each element of which corresponds to a certain element of $1\dots n$. The user does not set explicitly this mapping; when the application needs to indicate to which element of the index @@ -106,7 +106,7 @@ library will translate into the appropriate “local” numbering.

    For a given index space $1\dots n$ there are many possible associated topologies, i.e. many different discretization stencils; thus the @@ -115,7 +115,7 @@ defined a sparsity pattern, either explicitly through psb_cdins or implicitly through psb_spins. The descriptor is finalized with a call to psb_cdasb and a sparse matrix with a call to psb_spasb. After psb_cdasb each process $i$ will have defined a set of “halo” (or “ghost”) indices @@ -123,16 +123,16 @@ defined a set of “halo” (or “ghost”) indices $n_{\hbox{row}_i}+1\dots n_{\hbox{col}_i}$ --> $n_{\hbox{row}_i}+1\dots n_{\hbox{col}_i}$, denoting elements of the index space that are not assigned to process $i$; however the variables associated with them are needed to complete computations associated with the sparse matrix $A$, and thus they have to be fetched from (neighbouring) processes. The descriptor of the index @@ -247,33 +247,33 @@ from optimal. Subsections

    diff --git a/docs/html/node60.html b/docs/html/node60.html index f663ca4c1..231ca72d5 100644 --- a/docs/html/node60.html +++ b/docs/html/node60.html @@ -23,26 +23,26 @@ @@ -54,12 +54,12 @@ psb_norm2 -- 2-Norm of Vector

    This function computes the 2-norm of a vector $x$.
    If $x$ is a real vector it computes 2-norm as: @@ -72,14 +72,14 @@ nrm2 \leftarrow \sqrt{x^T x} --> \begin{displaymath}nrm2 \leftarrow \sqrt{x^T x}\end{displaymath}

    else if $x$ is a complex vector then it computes 2-norm as:

    @@ -91,7 +91,7 @@ nrm2 \leftarrow \sqrt{x^H x} --> \begin{displaymath}nrm2 \leftarrow \sqrt{x^H x}\end{displaymath} @@ -100,7 +100,7 @@ nrm2 \leftarrow \sqrt{x^H x}


    -
    +
    $res$ $x$ Subroutine
    @@ -108,11 +108,11 @@ Data types
    Table 8: Data types
    @@ -157,7 +157,7 @@ psb_norm2(x, desc_a, info [,global])
    x
    the local portion of global dense matrix $x$.
    @@ -203,7 +203,7 @@ Default: global=.true.
    Function Value
    is the 2-norm of vector $x$.
    @@ -238,7 +238,7 @@ An integer value; 0 means no error has been detected. by using the following scheme:
    \begin{lstlisting}
 vres(1) = psb_genrm2(x1,desc_a,info,global=.false.)
@@ -256,26 +256,26 @@ In this way the global communication, which for small sizes is a
 
 <DIV CLASS=
    - next - up - previous - contents
    - Next: Next: psb_genrm2s Generalized - Up: Up: Computational routines - Previous: Previous: psb_geasums Generalized -   Contents diff --git a/docs/html/node61.html b/docs/html/node61.html index 867d4545d..bdbc1061f 100644 --- a/docs/html/node61.html +++ b/docs/html/node61.html @@ -23,26 +23,26 @@ @@ -55,7 +55,7 @@ psb_genrm2s -- Generalized 2-Norm of Vector

    This subroutine computes a series of 2-norms on the columns of a dense matrix $x$:

    @@ -67,7 +67,7 @@ res(i) \leftarrow \|x(:,i)\|_2 --> \begin{displaymath}res(i) \leftarrow \Vert x(:,i)\Vert _2 \end{displaymath} @@ -81,7 +81,7 @@ call psb_genrm2s(res, x, desc_a, info)


    -
    +
    $nrm2$ $x$ Function
    @@ -89,11 +89,11 @@ Data types
    Table 9: Data types
    @@ -132,7 +132,7 @@ Data types
    x
    the local portion of global dense matrix $x$. @@ -165,7 +165,7 @@ Specified as: an object of type descdatapsb_desc_type.
    res
    contains the 1-norm of (the columns of) $x$.
    @@ -192,26 +192,26 @@ An integer value; 0 means no error has been detected. diff --git a/docs/html/node62.html b/docs/html/node62.html index 6ef4e36db..497fbdd5f 100644 --- a/docs/html/node62.html +++ b/docs/html/node62.html @@ -23,26 +23,26 @@ @@ -54,7 +54,7 @@ psb_norm1 -- 1-Norm of Sparse Matrix

    This function computes the 1-norm of a matrix $A$:
    @@ -68,7 +68,7 @@ nrm1 \leftarrow \|A\|_1 --> \begin{displaymath}nrm1 \leftarrow \Vert A\Vert _1 \end{displaymath} @@ -77,11 +77,11 @@ nrm1 \leftarrow \|A\|_1 where:

    $A$
    represents the global matrix $A$
    @@ -89,7 +89,7 @@ where:


    -
    +
    $res$ $x$ Subroutine
    @@ -97,7 +97,7 @@ Data types
    Table 10: Data types
    @@ -138,7 +138,7 @@ psb_norm1(A, desc_a, info)
    a
    the local portion of the global sparse matrix $A$.
    @@ -166,7 +166,7 @@ Specified as: an object of type descdatapsb_desc_type.
    Function value
    is the 1-norm of sparse submatrix $A$.
    diff --git a/docs/html/node63.html b/docs/html/node63.html index d084adad1..a4d426808 100644 --- a/docs/html/node63.html +++ b/docs/html/node63.html @@ -23,26 +23,26 @@ @@ -54,7 +54,7 @@ psb_normi -- Infinity Norm of Sparse Matrix

    This function computes the infinity-norm of a matrix $A$:
    @@ -68,7 +68,7 @@ nrmi \leftarrow \|A\|_\infty --> \begin{displaymath}nrmi \leftarrow \Vert A\Vert _\infty \end{displaymath} @@ -77,11 +77,11 @@ nrmi \leftarrow \|A\|_\infty where:

    $A$
    represents the global matrix $A$
    @@ -89,7 +89,7 @@ where:


    -
    +
    $A$ Function
    @@ -97,7 +97,7 @@ Data types
    Table 11: Data types
    @@ -138,7 +138,7 @@ psb_normi(A, desc_a, info)
    a
    the local portion of the global sparse matrix $A$.
    @@ -166,7 +166,7 @@ Specified as: an object of type descdatapsb_desc_type.
    Function value
    is the infinity-norm of sparse submatrix $A$.
    diff --git a/docs/html/node64.html b/docs/html/node64.html index 9f15d14c7..12cdf45b1 100644 --- a/docs/html/node64.html +++ b/docs/html/node64.html @@ -23,26 +23,26 @@ @@ -88,7 +88,7 @@ y \leftarrow \alpha A^T x + \beta y
    $A$ Function
    \begin{displaymath}
 y \leftarrow \alpha A^T x + \beta y
@@ -122,29 +122,29 @@ y \leftarrow \alpha A^H x + \beta y
 where:
 <DL>
 <DT><STRONG><SPAN CLASS=$x$
    is the global dense matrix $x_{:, :}$
    $y$
    is the global dense matrix $y_{:, :}$
    $A$
    is the global sparse matrix $A$
    @@ -152,7 +152,7 @@ where:


    -
    +
    @@ -160,19 +160,19 @@ Data types
    Table 12: Data types
    @@ -213,7 +213,7 @@ call psb_spmm(alpha, a, x, beta, y,desc_a, info, &
    alpha
    the scalar $\alpha$.
    @@ -229,7 +229,7 @@ Table 12.
    a
    the local portion of the sparse matrix $A$.
    @@ -244,7 +244,7 @@ Specified as: an object of type spdatapsb_Tspmat_type.
    x
    the local portion of global dense matrix $x$. @@ -258,16 +258,16 @@ Intent: in. Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type containing numbers of type specified in Table 12. The rank of $x$ must be the same of $y$.
    beta
    the scalar $\beta$.
    @@ -282,7 +282,7 @@ Specified as: a number of the data type indicated in Table $y$. @@ -296,10 +296,10 @@ Intent: inout. Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type containing numbers of type specified in Table 12. The rank of $y$ must be the same of $x$.
    @@ -336,7 +336,7 @@ Type: optional Intent: in.
    Default: $trans = N$
    @@ -354,10 +354,10 @@ Type: optional Intent: inout.
    Specified as: a rank one array of the same type of $x$ and $y$ with the TARGET attribute. @@ -369,7 +369,7 @@ the TARGET attribute.
    y
    the local portion of result matrix $y$.
    @@ -400,26 +400,26 @@ An integer value; 0 means no error has been detected. diff --git a/docs/html/node65.html b/docs/html/node65.html index 7617d650b..0283a958e 100644 --- a/docs/html/node65.html +++ b/docs/html/node65.html @@ -14,6 +14,7 @@ + @@ -22,26 +23,26 @@ @@ -86,34 +87,34 @@ y &\leftarrow& \alpha T^{-H} D x + \beta y\\ where:
    $x$
    is the global dense matrix $x_{:, :}$
    $y$
    is the global dense matrix $y_{:, :}$
    $T$
    is the global sparse block triangular submatrix $T$
    $D$
    is the scaling diagonal matrix. @@ -129,7 +130,7 @@ call psb_spsm(alpha, t, x, beta, y, desc_a, info,&


    -
    +
    $A$, $x$, $y$, $\alpha$, $\beta$ Subroutine
    @@ -137,22 +138,22 @@ Data types
    Table 13: Data types
    @@ -186,7 +187,7 @@ Data types
    alpha
    the scalar $\alpha$.
    @@ -202,7 +203,7 @@ Table 13.
    t
    the global portion of the sparse matrix $T$.
    @@ -218,7 +219,7 @@ Specified as: an object type specified in
    x
    the local portion of global dense matrix $x$. @@ -232,16 +233,16 @@ Intent: in. Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type containing numbers of type specified in Table 13. The rank of $x$ must be the same of $y$.
    beta
    the scalar $\beta$.
    @@ -256,7 +257,7 @@ Specified as: a number of the data type indicated in Table $y$. @@ -270,10 +271,10 @@ Intent: inout. Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type containing numbers of type specified in Table 13. The rank of $y$ must be the same of $x$.
    @@ -308,7 +309,7 @@ Type: optional Intent: in.
    Default: $trans = N$
    @@ -334,7 +335,7 @@ Type: optional Intent: in.
    Default: $unitd = U$
    @@ -380,7 +381,7 @@ Default: $diag(1) = 1 (no scaling)$
    @@ -397,7 +398,7 @@ Type: optional Intent: inout.
    Specified as: a rank one array of the same type of $x$ with the TARGET attribute. @@ -410,7 +411,7 @@ TARGET attribute.
    y
    the local portion of global dense matrix $y$. @@ -442,26 +443,26 @@ An integer value; 0 means no error has been detected. diff --git a/docs/html/node66.html b/docs/html/node66.html index e73a47eba..7112a9500 100644 --- a/docs/html/node66.html +++ b/docs/html/node66.html @@ -3,8 +3,8 @@ -Communication routines - +psb_gemlt -- Entrywise Product + @@ -14,64 +14,226 @@ - - - + + + -

    -Communication routines -

    -The routines in this chapter implement various global communication operators -on vectors associated with a discretization mesh. For auxiliary communication -routines not tied to a discretization space see 6. +

    +psb_gemlt -- Entrywise Product +

    -


    - -Subsections +This function computes the entrywise product between two vectors $x$ and +$y$ +

    + +
    +

    + +

    +

    +psb_gemlt(x, y, desc_a, info)
    +
    +

    +
    +
    $T$, $x$, $y$, $D$, $\alpha$, $\beta$ Subroutine
    + + +
    Table 14: +Data types
    + + + + + + + + + + + + + + + + +
    $dot$, $x$, $y$Function
    Short Precision Realpsb_gemlt
    Long Precision Realpsb_gemlt
    Short Precision Complexpsb_gemlt
    Long Precision Complexpsb_gemlt
    +
    +
    +

    +
    + +

    +

    +
    Type:
    +
    Synchronous. + +
    +
    On Entry
    +
    +
    +
    x
    +
    the local portion of global dense vector + $x$. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: an object of type vdatapsb_T_vect_type + containing numbers of type specified in + Table 2. + +
    +
    y
    +
    the local portion of global dense vector + $y$. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: an object of type vdatapsb_T_vect_type + containing numbers of type specified in + Table 2. + +
    +
    desc_a
    +
    contains data structures for communications. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: an object of type descdatapsb_desc_type. + +
    +
    On Return
    +
    +
    +
    y
    +
    the local portion of result submatrix $y$. +
    +Scope: local +
    +Type: required +
    +Intent: inout. +
    +Specified as: an object of type vdatapsb_T_vect_type containing numbers of the type + indicated in Table 14. + +
    +
    info
    +
    Error code. +
    +Scope: local +
    +Type: required +
    +Intent: out. +
    +An integer value; 0 means no error has been detected. +
    +
    + +

    + +

    + diff --git a/docs/html/node67.html b/docs/html/node67.html index 1ab4ea308..ff68685c8 100644 --- a/docs/html/node67.html +++ b/docs/html/node67.html @@ -3,8 +3,8 @@ -psb_halo -- Halo Data Communication - +psb_gediv -- Entrywise Division + @@ -16,146 +16,153 @@ - + -

    -psb_halo -- Halo Data Communication +

    +psb_gediv -- Entrywise Division

    -These subroutines gathers the values of the halo -elements: - -

    +This function computes the entrywise division between two vectors $x$ and +$y$

    \begin{displaymath}x \leftarrow x \end{displaymath} + WIDTH="96" HEIGHT="29" BORDER="0" + SRC="img60.png" + ALT="\begin{displaymath}/ \leftarrow x(i)/y(i).\end{displaymath}">

    -where: -
    -
    $x$
    -
    is a global dense submatrix. -
    -

    +

    +psb_gediv(x, y, desc_a, info, [flag)
    +

    -
    +
    - - +
    Table 14: +Table 15: Data types
    -
    +
    - - - - + ALT="$x$">, $y$ + - + - + - + - +
    $\alpha$, $/$, $x$Subroutine
    Integerpsb_haloFunction
    Short Precision Realpsb_halopsb_gediv
    Long Precision Realpsb_halopsb_gediv
    Short Precision Complexpsb_halopsb_gediv
    Long Precision Complexpsb_halopsb_gediv
    -


    -

    -
    -\begin{lstlisting}
-call psb_halo(x, desc_a, info)
-call psb_halo(x, desc_a, info, work, data)
-\end{lstlisting} -
    -

    Type:
    Synchronous. +
    On Entry
    x
    -
    global dense matrix the local portion of global dense vector + $x$. -
    +
    Scope: local
    Type: required
    -Intent: inout. +Intent: in.
    -Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type -containing numbers of type specified in -Table 14. +Specified as: an object of type vdatapsb_T_vect_type + containing numbers of type specified in + Table 2. + +
    +
    y
    +
    the local portion of global dense vector + $y$. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: an object of type vdatapsb_T_vect_type + containing numbers of type specified in + Table 2. +
    desc_a
    contains data structures for communications. @@ -166,41 +173,29 @@ Type: required
    Intent: in.
    -Specified as: a structured data of type descdatapsb_desc_type. +Specified as: an object of type descdatapsb_desc_type. +
    -
    work
    -
    the work array. +
    flag
    +
    check if any of the $y(i) = 0$, and in case returns error halting the computation.
    Scope: local
    Type: optional + Intent: in.
    -Intent: inout. -
    -Specified as: a rank one array of the same type of $x$. -
    -
    data
    -
    index list selector. -
    -Scope: global -
    -Type: optional -
    -Specified as: an integer. Values:psb_comm_halo_,psb_comm_mov_, -psb_comm_ext_, default: psb_comm_halo_. Chooses the -index list on which to base the data exchange. - -

    +Specified as: the logical value flag=.true. +

    On Return
    x
    -
    global dense result matrix the local portion of result submatrix $x$.
    @@ -210,15 +205,12 @@ Type: required
    Intent: inout.
    -Returned as: a rank one or two array -containing numbers of type specified in -Table 14. +Specified as: an object of type vdatapsb_T_vect_type containing numbers of the type + indicated in Table 14. +
    info
    -
    the local portion of result submatrix $y$. +
    Error code.
    Scope: local
    @@ -226,406 +218,34 @@ Type: required
    Intent: out.
    -An integer value that contains an error code. +An integer value; 0 means no error has been detected.
    -
    - - - -
    Figure 7: -Sample discretization mesh.
    -
    -\includegraphics[scale=0.45]{figures/try8x8.eps} - -\includegraphics[scale=0.45]{figures/try8x8} - -
    -
    - -

    -Usage Example -Consider the discretization mesh depicted in fig. 7, -partitioned among two processes as shown by the dashed line; the data -distribution is such that each process will own 32 entries in the -index space, with a halo made of 8 entries placed at local indices 33 -through 40. If process 0 assigns an initial value of 1 to its entries -in the $x$ vector, and process 1 assigns a value of 2, then after a -call to psb_halo the contents of the local vectors will be the -following: -
    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -Process 0  -Process 1
    - I GLOB(I) X(I)   I GLOB(I) X(I)
    - 1 1 1.0   1 33 2.0
    - 2 2 1.0   2 34 2.0
    - 3 3 1.0   3 35 2.0
    - 4 4 1.0   4 36 2.0
    - 5 5 1.0   5 37 2.0
    - 6 6 1.0   6 38 2.0
    - 7 7 1.0   7 39 2.0
    - 8 8 1.0   8 40 2.0
    - 9 9 1.0   9 41 2.0
    - 10 10 1.0   10 42 2.0
    - 11 11 1.0   11 43 2.0
    - 12 12 1.0   12 44 2.0
    - 13 13 1.0   13 45 2.0
    - 14 14 1.0   14 46 2.0
    - 15 15 1.0   15 47 2.0
    - 16 16 1.0   16 48 2.0
    - 17 17 1.0   17 49 2.0
    - 18 18 1.0   18 50 2.0
    - 19 19 1.0   19 51 2.0
    - 20 20 1.0   20 52 2.0
    -21 21 1.0   21 53 2.0
    -22 22 1.0   22 54 2.0
    -23 23 1.0   23 55 2.0
    -24 24 1.0   24 56 2.0
    -25 25 1.0   25 57 2.0
    -26 26 1.0   26 58 2.0
    -27 27 1.0   27 59 2.0
    -28 28 1.0   28 60 2.0
    -29 29 1.0   29 61 2.0
    -30 30 1.0   30 62 2.0
    -31 31 1.0   31 63 2.0
    -32 32 1.0   32 64 2.0
    -33 33 2.0   33 25 1.0
    -34 34 2.0   34 26 1.0
    -35 35 2.0   35 27 1.0
    -36 36 2.0   36 28 1.0
    -37 37 2.0   37 29 1.0
    -38 38 2.0   38 30 1.0
    -39 39 2.0   39 31 1.0
    -40 40 2.0   40 32 1.0
    -
    -

    diff --git a/docs/html/node68.html b/docs/html/node68.html index eff574f40..56b7396a1 100644 --- a/docs/html/node68.html +++ b/docs/html/node68.html @@ -3,8 +3,8 @@ -psb_ovrl -- Overlap Update - +psb_geinv -- Entrywise Inversion + @@ -14,157 +14,136 @@ - - + -

    -psb_ovrl -- Overlap Update +

    +psb_geinv -- Entrywise Inversion

    -These subroutines applies an overlap operator to the input vector: - -

    +This function computes the entrywise inverse of a vector $x$ and puts it into +$y$

    \begin{displaymath}x \leftarrow Q x \end{displaymath} + ALT="\begin{displaymath}/ \leftarrow 1/x(i).\end{displaymath}">

    -where: -
    -
    $x$
    -
    is the global dense submatrix $x$ -
    -
    $Q$
    -
    is the overlap operator; it is the composition of two -operators $P_a$ and $P^{T}$. -
    -

    +

    +psb_geinv(x, y, desc_a, info, [flag)
    +

    -
    +
    - - +
    Table 15: +Table 16: Data types
    -
    +
    - + ALT="$x$">, $y$ + - + - + - + - +
    $/$, $x$SubroutineFunction
    Short Precision Realpsb_ovrlpsb_geinv
    Long Precision Realpsb_ovrlpsb_geinv
    Short Precision Complexpsb_ovrlpsb_geinv
    Long Precision Complexpsb_ovrlpsb_geinv
    -


    -

    -
    -\begin{lstlisting}
-call psb_ovrl(x, desc_a, info)
-call psb_ovrl(x, desc_a, info, update=update_type, work=work)
-\end{lstlisting} -
    -

    Type:
    Synchronous. +
    On Entry
    x
    -
    global dense matrix the local portion of global dense vector + $x$. -
    +
    Scope: local
    Type: required
    -Intent: inout. +Intent: in.
    -Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type -containing numbers of type specified in -Table 15. +Specified as: an object of type vdatapsb_T_vect_type + containing numbers of type specified in + Table 2. +
    desc_a
    contains data structures for communications. @@ -175,65 +154,29 @@ Type: required
    Intent: in.
    -Specified as: a structured data of type descdatapsb_desc_type. +Specified as: an object of type descdatapsb_desc_type. +
    -
    update
    -
    Update operator. -
    -
    update = psb_none_
    -
    Do nothing; -
    -
    update = psb_add_
    -
    Sum overlap entries, i.e. apply $P^T$; -
    -
    update = psb_avg_
    -
    Average overlap entries, i.e. apply $P_aP^T$; -
    -
    -Scope: global -
    -Intent: in. -
    -Default: -$update\_type = psb\_avg\_ $ -
    -Scope: global -
    -Specified as: a integer variable. -
    -
    work
    -
    the work array. +
    flag
    +
    check if any of the $x(i) = 0$, and in case returns error halting the computation.
    Scope: local
    Type: optional + Intent: in.
    -Intent: inout. -
    -Specified as: a one dimensional array of the same type of $x$. - -

    +Specified as: the logical value flag=.true. +

    On Return
    -
    x
    -
    global dense result matrix y +
    the local portion of result submatrix $x$.
    @@ -241,11 +184,11 @@ Scope: local
    Type: required
    -Intent: inout. +Intent: out.
    -Specified as: an array of rank one or two -containing numbers of type specified in -Table 15. +Specified as: an object of type vdatapsb_T_vect_type containing numbers of the type + indicated in Table 16. +
    info
    Error code. @@ -260,500 +203,30 @@ An integer value; 0 means no error has been detected.
    -

    -Notes - -

      -
    1. If there is no overlap in the data distribution associated with - the descriptor, no operations are performed; -
    2. -
    3. The operator $P^{T}$ performs the reduction sum of overlap -elements; it is a “prolongation” operator $P^T$ that -replicates overlap elements, accounting for the physical replication -of data; -
    4. -
    5. The operator $P_a$ performs a scaling on the overlap elements by -the amount of replication; thus, when combined with the reduction -operator, it implements the average of replicated elements over all of -their instances. -
    6. -
    - -

    - -

    - - - -
    Figure 8: -Sample discretization mesh.
    -
    -\includegraphics[scale=0.65]{figures/try8x8_ov.eps} - -\includegraphics[scale=0.65]{figures/try8x8_ov} - -
    -
    - -Example of use -Consider the discretization mesh depicted in fig. 8, -partitioned among two processes as shown by the dashed lines, with an -overlap of 1 extra layer with respect to the partition of -fig. 7; the data -distribution is such that each process will own 40 entries in the -index space, with an overlap of 16 entries placed at local indices 25 -through 40; the halo will run from local index 41 through local index 48.. If process 0 assigns an initial value of 1 to its entries -in the $x$ vector, and process 1 assigns a value of 2, then after a -call to psb_ovrl with psb_avg_ and a call to -psb_halo_ the contents of the local vectors will be the -following (showing a transition among the two subdomains) - -

    -
    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -Process 0  -Process 1
    - I GLOB(I) X(I)   I GLOB(I) X(I)
    - 1 1 1.0   1 33 1.5
    - 2 2 1.0   2 34 1.5
    - 3 3 1.0   3 35 1.5
    - 4 4 1.0   4 36 1.5
    - 5 5 1.0   5 37 1.5
    - 6 6 1.0   6 38 1.5
    - 7 7 1.0   7 39 1.5
    - 8 8 1.0   8 40 1.5
    - 9 9 1.0   9 41 2.0
    - 10 10 1.0   10 42 2.0
    - 11 11 1.0   11 43 2.0
    - 12 12 1.0   12 44 2.0
    - 13 13 1.0   13 45 2.0
    - 14 14 1.0   14 46 2.0
    - 15 15 1.0   15 47 2.0
    - 16 16 1.0   16 48 2.0
    - 17 17 1.0   17 49 2.0
    - 18 18 1.0   18 50 2.0
    - 19 19 1.0   19 51 2.0
    - 20 20 1.0   20 52 2.0
    - 21 21 1.0   21 53 2.0
    - 22 22 1.0   22 54 2.0
    - 23 23 1.0   23 55 2.0
    - 24 24 1.0   24 56 2.0
    - 25 25 1.5   25 57 2.0
    - 26 26 1.5   26 58 2.0
    - 27 27 1.5   27 59 2.0
    - 28 28 1.5   28 60 2.0
    - 29 29 1.5   29 61 2.0
    - 30 30 1.5   30 62 2.0
    - 31 31 1.5   31 63 2.0
    - 32 32 1.5   32 64 2.0
    - 33 33 1.5   33 25 1.5
    - 34 34 1.5   34 26 1.5
    - 35 35 1.5   35 27 1.5
    - 36 36 1.5   36 28 1.5
    - 37 37 1.5   37 29 1.5
    - 38 38 1.5   38 30 1.5
    - 39 39 1.5   39 31 1.5
    - 40 40 1.5   40 32 1.5
    - 41 41 2.0   41 17 1.0
    - 42 42 2.0   42 18 1.0
    - 43 43 2.0   43 19 1.0
    - 44 44 2.0   44 20 1.0
    - 45 45 2.0   45 21 1.0
    - 46 46 2.0   46 22 1.0
    - 47 47 2.0   47 23 1.0
    - 48 48 2.0   48 24 1.0
    -
    -

    diff --git a/docs/html/node69.html b/docs/html/node69.html index 79a9d84cf..dd04cb65d 100644 --- a/docs/html/node69.html +++ b/docs/html/node69.html @@ -3,8 +3,8 @@ -psb_gather -- Gather Global Dense Matrix - +Communication routines + @@ -14,257 +14,64 @@ - - - + + + -

    -psb_gather -- Gather Global Dense Matrix -

    +

    +Communication routines +

    +The routines in this chapter implement various global communication operators +on vectors associated with a discretization mesh. For auxiliary communication +routines not tied to a discretization space see 6.

    -These subroutines collect the portions of global dense matrix -distributed over all process into one single array stored on one -process. +


    + +Subsections -

    -

    -
    - - -\begin{displaymath}glob\_x \leftarrow collect(loc\_x_i) \end{displaymath} -
    -
    -

    -where: -
    -
    $glob\_x$
    -
    is the global submatrix -$glob\_x_{1:m,1:n}$ -
    -
    $loc\_x_i$
    -
    is the local portion of global dense matrix on -process $i$. -
    -
    $collect$
    -
    is the collect function. -
    -
    - -

    -

    -
    - - - -
    Table 16: -Data types
    -
    - - - - - - - - - - - - - - - - - - - -
    $x_i, y$Subroutine
    Integerpsb_gather
    Short Precision Realpsb_gather
    Long Precision Realpsb_gather
    Short Precision Complexpsb_gather
    Long Precision Complexpsb_gather
    -
    -
    -

    -
    - -

    -
    -\begin{lstlisting}
-call psb_gather(glob_x, loc_x, desc_a, info, root)
-call psb_gather(glob_x, loc_x, desc_a, info, root)
-\end{lstlisting} -
    - -

    -

    -
    Type:
    -
    Synchronous. -
    -
    On Entry
    -
    -
    -
    loc_x
    -
    the local portion of global dense matrix -$glob\_x$. -
    -Scope: local -
    -Type: required -
    -Intent: in. -
    -Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type -indicated in Table 16. -
    -
    desc_a
    -
    contains data structures for communications. -
    -Scope: local -
    -Type: required -
    -Intent: in. -
    -Specified as: a structured data of type descdatapsb_desc_type. -
    -
    root
    -
    The process that holds the global copy. If $root=-1$ all - the processes will have a copy of the global vector. -
    -Scope: global -
    -Type: optional -
    -Intent: in. -
    -Specified as: an integer variable -$-1\le root\le np-1$, default $-1$. -
    -
    On Return
    -
    -
    -
    glob_x
    -
    The array where the local parts must be gathered. -
    -Scope: global -
    -Type: required -
    -Intent: out. -
    -Specified as: a rank one or two array with the ALLOCATABLE attribute. -
    -
    info
    -
    Error code. -
    -Scope: local -
    -Type: required -
    -Intent: out. -
    -An integer value; 0 means no error has been detected. -
    -
    - -

    - -

    - + + +

    diff --git a/docs/html/node7.html b/docs/html/node7.html index 155a14f7a..2823bee49 100644 --- a/docs/html/node7.html +++ b/docs/html/node7.html @@ -22,26 +22,26 @@ @@ -61,7 +61,7 @@ to the constraints outlined in sec. 2.3< $1\dots n_{\hbox{row}_i}$ --> $1\dots n_{\hbox{row}_i}$; @@ -70,7 +70,7 @@ to the constraints outlined in sec. 2.3< $n_{\hbox{row}_i}+1\dots n_{\hbox{col}_i}$ --> $n_{\hbox{row}_i}+1\dots n_{\hbox{col}_i}$; diff --git a/docs/html/node70.html b/docs/html/node70.html index d16ab5109..cca8cb371 100644 --- a/docs/html/node70.html +++ b/docs/html/node70.html @@ -3,8 +3,8 @@ -psb_scatter -- Scatter Global Dense Matrix - +psb_halo -- Halo Data Communication + @@ -14,98 +14,77 @@ + - + -

    -psb_scatter -- Scatter Global Dense Matrix +

    +psb_halo -- Halo Data Communication

    -These subroutines scatters the portions of global dense matrix owned -by a process to all the processes in the processes grid. +These subroutines gathers the values of the halo +elements:


    \begin{displaymath}loc\_x_i \leftarrow scatter(glob\_x) \end{displaymath} + WIDTH="43" HEIGHT="24" BORDER="0" + SRC="img65.png" + ALT="\begin{displaymath}x \leftarrow x \end{displaymath}">

    where:
    $glob\_x$
    -
    is the global matrix -$glob\_x_{1:m,1:n}$ -
    -
    $loc\_x_i$
    -
    is the local portion of global dense matrix on -process $i$. -
    -
    $scatter$
    -
    is the scatter function. + WIDTH="13" HEIGHT="14" ALIGN="BOTTOM" BORDER="0" + SRC="img20.png" + ALT="$x$"> +
    is a global dense submatrix.


    -
    +
    @@ -113,25 +92,28 @@ Data types
    Table 17: Data types
    + WIDTH="14" HEIGHT="14" ALIGN="BOTTOM" BORDER="0" + SRC="img22.png" + ALT="$\alpha$">, $x$ - + - + - + - + - +
    $x_i, y$ Subroutine
    Integerpsb_scatterpsb_halo
    Short Precision Realpsb_scatterpsb_halo
    Long Precision Realpsb_scatterpsb_halo
    Short Precision Complexpsb_scatterpsb_halo
    Long Precision Complexpsb_scatterpsb_halo
    @@ -143,10 +125,11 @@ Data types


    \begin{lstlisting}
-call psb_scatter(glob_x, loc_x, desc_a, info, root, mold)
+call psb_halo(x, desc_a, info)
+call psb_halo(x, desc_a, info, work, data)
 \end{lstlisting}
    @@ -158,16 +141,21 @@ call psb_scatter(glob_x, loc_x, desc_a, info, root, mold)

    On Entry
    -
    glob_x
    -
    The array that must be scattered into local pieces. +
    x
    +
    global dense matrix $x$.
    -Scope: global +Scope: local
    -Type: required +Type: required
    -Intent: in. +Intent: inout.
    -Specified as: a rank one or two array. +Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type +containing numbers of type specified in +Table 17.
    desc_a
    contains data structures for communications. @@ -180,61 +168,57 @@ Intent: in.
    Specified as: a structured data of type descdatapsb_desc_type.
    -
    root
    -
    The process that holds the global copy. If $root=-1$ all - the processes have a copy of the global vector. +
    work
    +
    the work array.
    -Scope: global +Scope: local
    Type: optional
    -Intent: in. +Intent: inout.
    -Specified as: an integer variable -$-1\le root\le np-1$, default -psb_root_, i.e. process 0. +Specified as: a rank one array of the same type of $x$.
    -
    mold
    -
    The desired dynamic type for the internal vector storage. +
    data
    +
    index list selector.
    -Scope: local. +Scope: global
    -Type: optional. +Type: optional
    -Intent: in. -
    -Specified as: an object of a class derived from vbasedatapsb_T_base_vect_type; this is -only allowed when loc_x is of type vdatapsb_T_vect_type. +Specified as: an integer. Values:psb_comm_halo_,psb_comm_mov_, +psb_comm_ext_, default: psb_comm_halo_. Chooses the +index list on which to base the data exchange. + +

    On Return
    -
    loc_x
    -
    the local portion of global dense matrix -$glob\_x$. +
    x
    +
    global dense result matrix $x$.
    Scope: local
    -Type: required +Type: required
    -Intent: out. +Intent: inout.
    -Specified as: a rank one or two ALLOCATABLE array or an object of type vdatapsb_T_vect_type containing numbers of the type -indicated in Table 17. +Returned as: a rank one or two array +containing numbers of type specified in +Table 17.
    info
    -
    Error code. +
    the local portion of result submatrix $y$.
    Scope: local
    @@ -242,34 +226,406 @@ Type: required
    Intent: out.
    -An integer value; 0 means no error has been detected. +An integer value that contains an error code.
    +
    + + + +
    Figure 7: +Sample discretization mesh.
    +
    +\includegraphics[scale=0.45]{figures/try8x8.eps} + +\includegraphics[scale=0.45]{figures/try8x8} + +
    +
    + +

    +Usage Example +Consider the discretization mesh depicted in fig. 7, +partitioned among two processes as shown by the dashed line; the data +distribution is such that each process will own 32 entries in the +index space, with a halo made of 8 entries placed at local indices 33 +through 40. If process 0 assigns an initial value of 1 to its entries +in the $x$ vector, and process 1 assigns a value of 2, then after a +call to psb_halo the contents of the local vectors will be the +following: +
    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +Process 0  +Process 1
    + I GLOB(I) X(I)   I GLOB(I) X(I)
    + 1 1 1.0   1 33 2.0
    + 2 2 1.0   2 34 2.0
    + 3 3 1.0   3 35 2.0
    + 4 4 1.0   4 36 2.0
    + 5 5 1.0   5 37 2.0
    + 6 6 1.0   6 38 2.0
    + 7 7 1.0   7 39 2.0
    + 8 8 1.0   8 40 2.0
    + 9 9 1.0   9 41 2.0
    + 10 10 1.0   10 42 2.0
    + 11 11 1.0   11 43 2.0
    + 12 12 1.0   12 44 2.0
    + 13 13 1.0   13 45 2.0
    + 14 14 1.0   14 46 2.0
    + 15 15 1.0   15 47 2.0
    + 16 16 1.0   16 48 2.0
    + 17 17 1.0   17 49 2.0
    + 18 18 1.0   18 50 2.0
    + 19 19 1.0   19 51 2.0
    + 20 20 1.0   20 52 2.0
    +21 21 1.0   21 53 2.0
    +22 22 1.0   22 54 2.0
    +23 23 1.0   23 55 2.0
    +24 24 1.0   24 56 2.0
    +25 25 1.0   25 57 2.0
    +26 26 1.0   26 58 2.0
    +27 27 1.0   27 59 2.0
    +28 28 1.0   28 60 2.0
    +29 29 1.0   29 61 2.0
    +30 30 1.0   30 62 2.0
    +31 31 1.0   31 63 2.0
    +32 32 1.0   32 64 2.0
    +33 33 2.0   33 25 1.0
    +34 34 2.0   34 26 1.0
    +35 35 2.0   35 27 1.0
    +36 36 2.0   36 28 1.0
    +37 37 2.0   37 29 1.0
    +38 38 2.0   38 30 1.0
    +39 39 2.0   39 31 1.0
    +40 40 2.0   40 32 1.0
    +
    +

    diff --git a/docs/html/node71.html b/docs/html/node71.html index ae405046e..1947ee48f 100644 --- a/docs/html/node71.html +++ b/docs/html/node71.html @@ -3,8 +3,8 @@ -Data management routines - +psb_ovrl -- Overlap Update + @@ -14,120 +14,748 @@ - - - + + + -

    - -
    -Data management routines -

    +

    +psb_ovrl -- Overlap Update +

    -


    - -Subsections +These subroutines applies an overlap operator to the input vector: - - -

    +

    +

    +
    + + +\begin{displaymath}x \leftarrow Q x \end{displaymath} +
    +
    +

    +where: +
    +
    $x$
    +
    is the global dense submatrix $x$ +
    +
    $Q$
    +
    is the overlap operator; it is the composition of two +operators $P_a$ and $P^{T}$. +
    +
    + +

    +

    +
    + + + +
    Table 18: +Data types
    +
    + + + + + + + + + + + + + + + + +
    $x$Subroutine
    Short Precision Realpsb_ovrl
    Long Precision Realpsb_ovrl
    Short Precision Complexpsb_ovrl
    Long Precision Complexpsb_ovrl
    +
    +
    +

    +
    + +

    +
    +\begin{lstlisting}
+call psb_ovrl(x, desc_a, info)
+call psb_ovrl(x, desc_a, info, update=update_type, work=work)
+\end{lstlisting} +
    + +

    +

    +
    Type:
    +
    Synchronous. +
    +
    On Entry
    +
    +
    +
    x
    +
    global dense matrix $x$. +
    +Scope: local +
    +Type: required +
    +Intent: inout. +
    +Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type +containing numbers of type specified in +Table 18. +
    +
    desc_a
    +
    contains data structures for communications. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: a structured data of type descdatapsb_desc_type. +
    +
    update
    +
    Update operator. +
    +
    update = psb_none_
    +
    Do nothing; +
    +
    update = psb_add_
    +
    Sum overlap entries, i.e. apply $P^T$; +
    +
    update = psb_avg_
    +
    Average overlap entries, i.e. apply $P_aP^T$; +
    +
    +Scope: global +
    +Intent: in. +
    +Default: +$update\_type = psb\_avg\_ $ +
    +Scope: global +
    +Specified as: a integer variable. +
    +
    work
    +
    the work array. +
    +Scope: local +
    +Type: optional +
    +Intent: inout. +
    +Specified as: a one dimensional array of the same type of $x$. + +

    +

    +
    On Return
    +
    +
    +
    x
    +
    global dense result matrix $x$. +
    +Scope: local +
    +Type: required +
    +Intent: inout. +
    +Specified as: an array of rank one or two +containing numbers of type specified in +Table 18. +
    +
    info
    +
    Error code. +
    +Scope: local +
    +Type: required +
    +Intent: out. +
    +An integer value; 0 means no error has been detected. +
    +
    + +

    +Notes + +

      +
    1. If there is no overlap in the data distribution associated with + the descriptor, no operations are performed; +
    2. +
    3. The operator $P^{T}$ performs the reduction sum of overlap +elements; it is a “prolongation” operator $P^T$ that +replicates overlap elements, accounting for the physical replication +of data; +
    4. +
    5. The operator $P_a$ performs a scaling on the overlap elements by +the amount of replication; thus, when combined with the reduction +operator, it implements the average of replicated elements over all of +their instances. +
    6. +
    + +

    + +

    + + + +
    Figure 8: +Sample discretization mesh.
    +
    +\includegraphics[scale=0.65]{figures/try8x8_ov.eps} + +\includegraphics[scale=0.65]{figures/try8x8_ov} + +
    +
    + +Example of use +Consider the discretization mesh depicted in fig. 8, +partitioned among two processes as shown by the dashed lines, with an +overlap of 1 extra layer with respect to the partition of +fig. 7; the data +distribution is such that each process will own 40 entries in the +index space, with an overlap of 16 entries placed at local indices 25 +through 40; the halo will run from local index 41 through local index 48.. If process 0 assigns an initial value of 1 to its entries +in the $x$ vector, and process 1 assigns a value of 2, then after a +call to psb_ovrl with psb_avg_ and a call to +psb_halo_ the contents of the local vectors will be the +following (showing a transition among the two subdomains) + +

    +
    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +Process 0  +Process 1
    + I GLOB(I) X(I)   I GLOB(I) X(I)
    + 1 1 1.0   1 33 1.5
    + 2 2 1.0   2 34 1.5
    + 3 3 1.0   3 35 1.5
    + 4 4 1.0   4 36 1.5
    + 5 5 1.0   5 37 1.5
    + 6 6 1.0   6 38 1.5
    + 7 7 1.0   7 39 1.5
    + 8 8 1.0   8 40 1.5
    + 9 9 1.0   9 41 2.0
    + 10 10 1.0   10 42 2.0
    + 11 11 1.0   11 43 2.0
    + 12 12 1.0   12 44 2.0
    + 13 13 1.0   13 45 2.0
    + 14 14 1.0   14 46 2.0
    + 15 15 1.0   15 47 2.0
    + 16 16 1.0   16 48 2.0
    + 17 17 1.0   17 49 2.0
    + 18 18 1.0   18 50 2.0
    + 19 19 1.0   19 51 2.0
    + 20 20 1.0   20 52 2.0
    + 21 21 1.0   21 53 2.0
    + 22 22 1.0   22 54 2.0
    + 23 23 1.0   23 55 2.0
    + 24 24 1.0   24 56 2.0
    + 25 25 1.5   25 57 2.0
    + 26 26 1.5   26 58 2.0
    + 27 27 1.5   27 59 2.0
    + 28 28 1.5   28 60 2.0
    + 29 29 1.5   29 61 2.0
    + 30 30 1.5   30 62 2.0
    + 31 31 1.5   31 63 2.0
    + 32 32 1.5   32 64 2.0
    + 33 33 1.5   33 25 1.5
    + 34 34 1.5   34 26 1.5
    + 35 35 1.5   35 27 1.5
    + 36 36 1.5   36 28 1.5
    + 37 37 1.5   37 29 1.5
    + 38 38 1.5   38 30 1.5
    + 39 39 1.5   39 31 1.5
    + 40 40 1.5   40 32 1.5
    + 41 41 2.0   41 17 1.0
    + 42 42 2.0   42 18 1.0
    + 43 43 2.0   43 19 1.0
    + 44 44 2.0   44 20 1.0
    + 45 45 2.0   45 21 1.0
    + 46 46 2.0   46 22 1.0
    + 47 47 2.0   47 23 1.0
    + 48 48 2.0   48 24 1.0
    +
    + +

    + +

    + diff --git a/docs/html/node72.html b/docs/html/node72.html index 6277372ec..dbff365ae 100644 --- a/docs/html/node72.html +++ b/docs/html/node72.html @@ -3,8 +3,8 @@ -psb_cdall -- Allocates a communication descriptor - +psb_gather -- Gather Global Dense Matrix + @@ -16,226 +16,215 @@ - + -

    -psb_cdall -- Allocates a communication descriptor +

    +psb_gather -- Gather Global Dense Matrix

    -

    -call psb_cdall(icontxt, desc_a, info,mg=mg,parts=parts)
    -call psb_cdall(icontxt, desc_a, info,vg=vg,[mg=mg,flag=flag])
    -call psb_cdall(icontxt, desc_a, info,vl=vl,[nl=nl,globalcheck=.false.,lidx=lidx])
    -call psb_cdall(icontxt, desc_a, info,nl=nl)
    -call psb_cdall(icontxt, desc_a, info,mg=mg,repl=.true.)
    -
    +These subroutines collect the portions of global dense matrix +distributed over all process into one single array stored on one +process.

    -This subroutine initializes the communication descriptor associated -with an index space. One of the optional arguments -parts, vg, vl, nl or repl -must be specified, thereby choosing -the specific initialization strategy. +

    +
    + + +\begin{displaymath}glob\_x \leftarrow collect(loc\_x_i) \end{displaymath} +
    +
    +

    +where:
    -
    On Entry
    -
    -
    -
    Type:
    -
    Synchronous. -
    -
    icontxt
    -
    the communication context. -
    -Scope:global. -
    -Type:required. -
    -Intent: in. -
    -Specified as: an integer value. -
    -
    vg
    -
    Data allocation: each index $i\in \{1\dots mg\}$ is allocated - to process $vg(i)$. -
    -Scope:global. -
    -Type:optional. -
    -Intent: in. -
    -Specified as: an integer array. + WIDTH="90" HEIGHT="30" ALIGN="MIDDLE" BORDER="0" + SRC="img81.png" + ALT="$glob\_x_{1:m,1:n}$">
    -
    flag
    -
    Specifies whether entries in $vg$ are zero- or one-based. -
    -Scope:global. -
    -Type:optional. -
    -Intent: in. -
    -Specified as: an integer value $0,1$, default $0$. - -

    +

    $loc\_x_i$
    +
    is the local portion of global dense matrix on +process $i$.
    -
    mg
    -
    the (global) number of rows of the problem. -
    -Scope:global. -
    -Type:optional. -
    -Intent: in. -
    -Specified as: an integer value. It is required if parts or -repl is specified, it is optional if vg is specified. -
    -
    parts
    -
    the subroutine that defines the partitioning scheme. -
    -Scope:global. -
    -Type:required. -
    -Specified as: a subroutine. -
    -
    vl
    -
    Data allocation: the set of global indices - $vl(1:nl)$ belonging to the calling process. -
    -Scope:local. -
    -Type:optional. -
    -Intent: in. -
    -Specified as: an integer array. -
    -
    nl
    -
    Data allocation: in a generalized block-row distribution the - number of indices belonging to the current process. -
    -Scope:local. -
    -Type:optional. -
    -Intent: in. -
    -Specified as: an integer value. May be specified together with -vl. -
    -
    repl
    -
    Data allocation: build a replicated index space - (i.e. all processes own all indices). -
    -Scope:global. -
    -Type:optional. -
    -Intent: in. -
    -Specified as: the logical value .true. -
    -
    globalcheck
    -
    Data allocation: do global checks on the local - index lists vl -
    -Scope:global. -
    -Type:optional. -
    -Intent: in. -
    -Specified as: a logical value, default: .false. -
    -
    lidx
    -
    Data allocation: the set of local indices - $lidx(1:nl)$ to be assigned to the global indices $vl$. -
    -Scope:local. -
    -Type:optional. -
    -Intent: in. -
    -Specified as: an integer array. +
    $collect$
    +
    is the collect function.
    +

    +

    +
    + + + +
    Table 19: +Data types
    +
    + + + + + + + + + + + + + + + + + + + +
    $x_i, y$Subroutine
    Integerpsb_gather
    Short Precision Realpsb_gather
    Long Precision Realpsb_gather
    Short Precision Complexpsb_gather
    Long Precision Complexpsb_gather
    +
    +
    +

    +
    + +

    +
    +\begin{lstlisting}
+call psb_gather(glob_x, loc_x, desc_a, info, root)
+call psb_gather(glob_x, loc_x, desc_a, info, root)
+\end{lstlisting} +
    +

    +
    Type:
    +
    Synchronous. +
    +
    On Entry
    +
    +
    +
    loc_x
    +
    the local portion of global dense matrix +$glob\_x$. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type +indicated in Table 19. +
    +
    desc_a
    +
    contains data structures for communications. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: a structured data of type descdatapsb_desc_type. +
    +
    root
    +
    The process that holds the global copy. If $root=-1$ all + the processes will have a copy of the global vector. +
    +Scope: global +
    +Type: optional +
    +Intent: in. +
    +Specified as: an integer variable +$-1\le root\le np-1$, default $-1$. +
    On Return
    -
    desc_a
    -
    the communication descriptor. +
    glob_x
    +
    The array where the local parts must be gathered.
    -Scope:local. +Scope: global
    -Type:required. +Type: required
    Intent: out.
    -Specified as: a structured data of type descdatapsb_desc_type. +Specified as: a rank one or two array with the ALLOCATABLE attribute.
    info
    Error code. @@ -250,199 +239,30 @@ An integer value; 0 means no error has been detected.
    -

    -Notes - -

      -
    1. One of the optional arguments parts, vg, - vl, nl or repl must be specified, thereby choosing the - initialization strategy as follows: -
      -
      parts
      -
      In this case we have a subroutine specifying the mapping - between global indices and process/local index pairs. If this - optional argument is specified, then it is mandatory to - specify the argument mg as well. - The subroutine must conform to the following interface: -
      -  interface 
      -     subroutine psb_parts(glob_index,mg,np,pv,nv)
      -       integer, intent (in)  :: glob_index,np,mg
      -       integer, intent (out) :: nv, pv(*)
      -     end subroutine psb_parts
      -  end interface
      -
      - The input arguments are: -
      -
      glob_index
      -
      The global index to be mapped; - -
      -
      np
      -
      The number of processes in the mapping; - -
      -
      mg
      -
      The total number of global rows in the mapping; - -
      -
      - The output arguments are: -
      -
      nv
      -
      The number of entries in pv; - -
      -
      pv
      -
      A vector containing the indices of the processes to - which the global index should be assigend; each entry must satisfy - -$0\le pv(i) < np$; if $nv>1$ we have an index assigned to multiple - processes, i.e. we have an overlap among the subdomains. - -
      -
      -
      -
      vg
      -
      In this case the association between an index and a process - is specified via an integer vector vg(1:mg); - each index -$i\in \{1\dots mg\}$ is assigned to process $vg(i)$. - The vector vg must be identical on all - calling processes; its entries may have the ranges $(0\dots np-1)$ - or $(1\dots np)$ according to the value of flag. - The size $mg$ may be specified via the optional argument mg; - the default is to use the entire vector vg, thus having - mg=size(vg). -
      -
      vl
      -
      In this case we are specifying the list of indices - vl(1:nl) assigned to the current process; thus, the global - problem size $mg$ is given by - the range of the aggregate of the individual vectors vl specified - in the calling processes. The size may be specified via the optional - argument nl; the default is to use the entire vector - vl, thus having nl=size(vl). - If globalcheck=.true. the subroutine will check how many - times each entry in the global index space $(1\dots mg)$ is - specified in the input lists vl, thus allowing for the - presence of overlap in the input, and checking for “orphan” - indices. If globalcheck=.false., the subroutine will not - check for overlap, and may be significantly faster, but the user - is implicitly guaranteeing that there are neither orphan nor - overlap indices. -
      -
      lidx
      -
      The optional argument lidx is available for - those cases in which the user has already established a - global-to-local mapping; if it is specified, each index in - vl(i) will be mapped to the corresponding local index - lidx(i). When specifying the argument lidx the user - would also likely employ lidx in calls to psb_cdins - and local in calls to psb_spins and psb_geins; - see also sec. 2.3.1. -
      -
      nl
      -
      If this argument is specified alone (i.e. without vl) - the result is a generalized row-block distribution in which each - process $I$ gets assigned a consecutive chunk of $N_I=nl$ global - indices. -
      -
      repl
      -
      This arguments specifies to replicate all indices on - all processes. This is a special purpose data allocation that is - useful in the construction of some multilevel preconditioners. -
      -
      -
    2. -
    3. On exit from this routine the descriptor is in the build - state. -
    4. -
    5. Calling the routine with vg or parts implies that - every process will scan the entire index space to figure out the - local indices. -
    6. -
    7. Overlapped indices are possible with both parts and - vl invocations. -
    8. -
    9. When the subroutine is invoked with vl in - conjunction with globalcheck=.true., it will perform a scan - of the index space to search for overlap or orphan indices. -
    10. -
    11. When the subroutine is invoked with vl in - conjunction with globalcheck=.false., no index space scan - will take place. Thus it is the responsibility of the user to make - sure that the indices specified in vl have neither orphans nor - overlaps; if this assumption fails, results will be - unpredictable. -
    12. -
    13. Orphan and overlap indices are - impossible by construction when the subroutine is invoked with - nl (alone), or vg. -
    14. -
    -

    diff --git a/docs/html/node73.html b/docs/html/node73.html index 364e18a04..924e3506b 100644 --- a/docs/html/node73.html +++ b/docs/html/node73.html @@ -3,8 +3,8 @@ -psb_cdins -- Communication descriptor insert routine - +psb_scatter -- Scatter Global Dense Matrix + @@ -14,162 +14,224 @@ - - + -

    -psb_cdins -- Communication descriptor insert - routine +

    +psb_scatter -- Scatter Global Dense Matrix

    -

    -call psb_cdins(nz, ia, ja, desc_a, info [,ila,jla])
    -call psb_cdins(nz,ja,desc,info[,jla,mask,lidx])
    -
    +These subroutines scatters the portions of global dense matrix owned +by a process to all the processes in the processes grid.

    -This subroutine examines the edges of the graph associated with the -discretization mesh (and isomorphic to the sparsity pattern of a -linear system coefficient matrix), storing them as necessary into the -communication descriptor. In the first form the edges are specified as -pairs of indices $ia(i),ja(i)$; the starting index $ia(i)$ should -belong to the current process. -In the second form only the remote indices $ja(i)$ are specified. +

    +
    + -

    +\begin{displaymath}loc\_x_i \leftarrow scatter(glob\_x) \end{displaymath} +

    +
    +

    +where:
    -
    Type:
    -
    Asynchronous. +
    $glob\_x$
    +
    is the global matrix +$glob\_x_{1:m,1:n}$
    -
    On Entry
    -
    +
    $loc\_x_i$
    +
    is the local portion of global dense matrix on +process $i$.
    -
    nz
    -
    the number of points being inserted. -
    -Scope: local. -
    -Type: required. -
    -Intent: in. -
    -Specified as: an integer value. -
    -
    ia
    -
    the indices of the starting vertex of the edges being inserted. -
    -Scope: local. -
    -Type: required. -
    -Intent: in. -
    -Specified as: an integer array of length $nz$. -
    -
    ja
    -
    the indices of the end vertex of the edges being inserted. -
    -Scope: local. -
    -Type: required. -
    -Intent: in. -
    -Specified as: an integer array of length $nz$. -
    -
    mask
    -
    Mask entries in ja, they are inserted only when the - corresponding mask entries are .true. -
    -Scope: local. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: a logical array of length $nz$, default .true.. -
    -
    lidx
    -
    User defined local indices for ja. -
    -Scope: local. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: an integer array of length $nz$. +
    $scatter$
    +
    is the scatter function.
    +

    +

    +
    + + + +
    Table 20: +Data types
    +
    + + + + + + + + + + + + + + + + + + + +
    $x_i, y$Subroutine
    Integerpsb_scatter
    Short Precision Realpsb_scatter
    Long Precision Realpsb_scatter
    Short Precision Complexpsb_scatter
    Long Precision Complexpsb_scatter
    +
    +
    +

    +
    + +

    +
    +\begin{lstlisting}
+call psb_scatter(glob_x, loc_x, desc_a, info, root, mold)
+\end{lstlisting} +
    +

    +
    Type:
    +
    Synchronous. +
    +
    On Entry
    +
    +
    +
    glob_x
    +
    The array that must be scattered into local pieces. +
    +Scope: global +
    +Type: required +
    +Intent: in. +
    +Specified as: a rank one or two array. +
    +
    desc_a
    +
    contains data structures for communications. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: a structured data of type descdatapsb_desc_type. +
    +
    root
    +
    The process that holds the global copy. If $root=-1$ all + the processes have a copy of the global vector. +
    +Scope: global +
    +Type: optional +
    +Intent: in. +
    +Specified as: an integer variable +$-1\le root\le np-1$, default +psb_root_, i.e. process 0. +
    +
    mold
    +
    The desired dynamic type for the internal vector storage. +
    +Scope: local. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: an object of a class derived from vbasedatapsb_T_base_vect_type; this is +only allowed when loc_x is of type vdatapsb_T_vect_type. +
    On Return
    -
    desc_a
    -
    the updated communication descriptor. +
    loc_x
    +
    the local portion of global dense matrix +$glob\_x$.
    -Scope:local. +Scope: local
    -Type:required. +Type: required
    -Intent: inout. +Intent: out.
    -Specified as: a structured data of type descdatapsb_desc_type. +Specified as: a rank one or two ALLOCATABLE array or an object of type vdatapsb_T_vect_type containing numbers of the type +indicated in Table 20.
    info
    Error code. @@ -182,76 +244,32 @@ Intent: out.
    An integer value; 0 means no error has been detected.
    -
    ila
    -
    the local indices of the starting vertex of the edges being inserted. -
    -Scope: local. -
    -Type: optional. -
    -Intent: out. -
    -Specified as: an integer array of length $nz$. -
    -
    jla
    -
    the local indices of the end vertex of the edges being inserted. -
    -Scope: local. -
    -Type: optional. -
    -Intent: out. -
    -Specified as: an integer array of length $nz$. - -

    -

    -Notes - -
      -
    1. This routine may only be called if the descriptor is in the - build state; -
    2. -
    3. This routine automatically ignores edges that do not -insist on the current process, i.e. edges for which neither the starting -nor the end vertex belong to the current process. -
    4. -
    5. The second form of this routine will be useful when dealing with - user-specified index mappings; see also 2.3.1. -
    6. -

    diff --git a/docs/html/node74.html b/docs/html/node74.html index dce0fc24f..4d97a7eb7 100644 --- a/docs/html/node74.html +++ b/docs/html/node74.html @@ -3,8 +3,8 @@ -psb_cdasb -- Communication descriptor assembly routine - +Data management routines + @@ -14,119 +14,119 @@ - - - + + + -

    -psb_cdasb -- Communication descriptor assembly +

    + +
    +Data management routines +

    + +

    +


    + +Subsections + +

    - -

    -

    -call psb_cdasb(desc_a, info [, mold])
    -
    - -

    -

    -
    Type:
    -
    Synchronous. -
    -
    On Entry
    -
    -
    -
    desc_a
    -
    the communication descriptor. -
    -Scope:local. -
    -Type:required. -
    -Intent: inout. -
    -Specified as: a structured data of type descdatapsb_desc_type. -
    -
    mold
    -
    The desired dynamic type for the internal index storage. -
    -Scope: local. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: a object of type derived from (integer) vbasedatapsb_T_base_vect_type. -
    -
    - -

    -

    -
    On Return
    -
    -
    -
    desc_a
    -
    the communication descriptor. -
    -Scope:local. -
    -Type:required. -
    -Intent: inout. -
    -Specified as: a structured data of type descdatapsb_desc_type. -
    -
    info
    -
    Error code. -
    -Scope: local -
    -Type: required -
    -Intent: out. -
    -An integer value; 0 means no error has been detected. -
    -
    -Notes - -
      -
    1. On exit from this routine the descriptor is in the assembled - state. -
    2. -
    - -

    +

  • psb_cdasb -- Communication descriptor assembly + routine +
  • psb_cdcpy -- Copies a communication descriptor +
  • psb_cdfree -- Frees a communication descriptor +
  • psb_cdbldext -- Build an extended communication + descriptor +
  • psb_spall -- Allocates a sparse matrix +
  • psb_spins -- Insert a set of coefficients into a sparse + matrix +
  • psb_spasb -- Sparse matrix assembly routine +
  • psb_spfree -- Frees a sparse matrix +
  • psb_sprn -- Reinit sparse matrix structure for psblas + routines. +
  • psb_geall -- Allocates a dense matrix +
  • psb_geins -- Dense matrix insertion routine +
  • psb_geasb -- Assembly a dense matrix +
  • psb_gefree -- Frees a dense matrix +
  • psb_gelp -- Applies a left permutation to a dense + matrix +
  • psb_glob_to_loc -- Global to local indices + convertion +
  • psb_loc_to_glob -- Local to global indices + conversion +
  • psb_is_owned -- +
  • psb_owned_index -- +
  • psb_is_local -- +
  • psb_local_index -- +
  • psb_get_boundary -- Extract list of boundary + elements +
  • psb_get_overlap -- Extract list of overlap + elements +
  • psb_sp_getrow -- Extract row(s) from a sparse + matrix +
  • psb_sizeof -- Memory occupation +
  • Sorting utilities -- + +

    diff --git a/docs/html/node75.html b/docs/html/node75.html index 508603a4a..dc27405d4 100644 --- a/docs/html/node75.html +++ b/docs/html/node75.html @@ -3,8 +3,8 @@ -psb_cdcpy -- Copies a communication descriptor - +psb_cdall -- Allocates a communication descriptor + @@ -16,68 +16,209 @@ - + -

    -psb_cdcpy -- Copies a communication descriptor +

    +psb_cdall -- Allocates a communication descriptor

    -call psb_cdcpy(desc_in, desc_out, info)
    +call psb_cdall(icontxt, desc_a, info,mg=mg,parts=parts)
    +call psb_cdall(icontxt, desc_a, info,vg=vg,[mg=mg,flag=flag])
    +call psb_cdall(icontxt, desc_a, info,vl=vl,[nl=nl,globalcheck=.false.,lidx=lidx])
    +call psb_cdall(icontxt, desc_a, info,nl=nl)
    +call psb_cdall(icontxt, desc_a, info,mg=mg,repl=.true.)
     

    +This subroutine initializes the communication descriptor associated +with an index space. One of the optional arguments +parts, vg, vl, nl or repl +must be specified, thereby choosing +the specific initialization strategy.

    -
    Type:
    -
    Asynchronous. -
    -
    On Entry
    +
    On Entry
    -
    desc_in
    -
    the communication descriptor. +
    Type:
    +
    Synchronous. +
    +
    icontxt
    +
    the communication context.
    -Scope:local. +Scope:global.
    Type:required.
    Intent: in.
    -Specified as: a structured data of type descdatapsb_desc_type. +Specified as: an integer value. +
    +
    vg
    +
    Data allocation: each index +$i\in \{1\dots mg\}$ is allocated + to process $vg(i)$. +
    +Scope:global. +
    +Type:optional. +
    +Intent: in. +
    +Specified as: an integer array. +
    +
    flag
    +
    Specifies whether entries in $vg$ are zero- or one-based. +
    +Scope:global. +
    +Type:optional. +
    +Intent: in. +
    +Specified as: an integer value $0,1$, default $0$.

    +
    mg
    +
    the (global) number of rows of the problem. +
    +Scope:global. +
    +Type:optional. +
    +Intent: in. +
    +Specified as: an integer value. It is required if parts or +repl is specified, it is optional if vg is specified. +
    +
    parts
    +
    the subroutine that defines the partitioning scheme. +
    +Scope:global. +
    +Type:required. +
    +Specified as: a subroutine. +
    +
    vl
    +
    Data allocation: the set of global indices + $vl(1:nl)$ belonging to the calling process. +
    +Scope:local. +
    +Type:optional. +
    +Intent: in. +
    +Specified as: an integer array. +
    +
    nl
    +
    Data allocation: in a generalized block-row distribution the + number of indices belonging to the current process. +
    +Scope:local. +
    +Type:optional. +
    +Intent: in. +
    +Specified as: an integer value. May be specified together with +vl. +
    +
    repl
    +
    Data allocation: build a replicated index space + (i.e. all processes own all indices). +
    +Scope:global. +
    +Type:optional. +
    +Intent: in. +
    +Specified as: the logical value .true. +
    +
    globalcheck
    +
    Data allocation: do global checks on the local + index lists vl +
    +Scope:global. +
    +Type:optional. +
    +Intent: in. +
    +Specified as: a logical value, default: .false. +
    +
    lidx
    +
    Data allocation: the set of local indices + $lidx(1:nl)$ to be assigned to the global indices $vl$. +
    +Scope:local. +
    +Type:optional. +
    +Intent: in. +
    +Specified as: an integer array. +

    @@ -85,8 +226,8 @@ Specified as: a structured data of type descdatapsb_desc_type.

    On Return
    -
    desc_out
    -
    the communication descriptor copy. +
    desc_a
    +
    the communication descriptor.
    Scope:local.
    @@ -110,7 +251,200 @@ An integer value; 0 means no error has been detected.

    -


    +Notes + +
      +
    1. One of the optional arguments parts, vg, + vl, nl or repl must be specified, thereby choosing the + initialization strategy as follows: +
      +
      parts
      +
      In this case we have a subroutine specifying the mapping + between global indices and process/local index pairs. If this + optional argument is specified, then it is mandatory to + specify the argument mg as well. + The subroutine must conform to the following interface: +
      +  interface 
      +     subroutine psb_parts(glob_index,mg,np,pv,nv)
      +       integer, intent (in)  :: glob_index,np,mg
      +       integer, intent (out) :: nv, pv(*)
      +     end subroutine psb_parts
      +  end interface
      +
      + The input arguments are: +
      +
      glob_index
      +
      The global index to be mapped; + +
      +
      np
      +
      The number of processes in the mapping; + +
      +
      mg
      +
      The total number of global rows in the mapping; + +
      +
      + The output arguments are: +
      +
      nv
      +
      The number of entries in pv; + +
      +
      pv
      +
      A vector containing the indices of the processes to + which the global index should be assigend; each entry must satisfy + +$0\le pv(i) < np$; if $nv>1$ we have an index assigned to multiple + processes, i.e. we have an overlap among the subdomains. + +
      +
      +
      +
      vg
      +
      In this case the association between an index and a process + is specified via an integer vector vg(1:mg); + each index +$i\in \{1\dots mg\}$ is assigned to process $vg(i)$. + The vector vg must be identical on all + calling processes; its entries may have the ranges $(0\dots np-1)$ + or $(1\dots np)$ according to the value of flag. + The size $mg$ may be specified via the optional argument mg; + the default is to use the entire vector vg, thus having + mg=size(vg). +
      +
      vl
      +
      In this case we are specifying the list of indices + vl(1:nl) assigned to the current process; thus, the global + problem size $mg$ is given by + the range of the aggregate of the individual vectors vl specified + in the calling processes. The size may be specified via the optional + argument nl; the default is to use the entire vector + vl, thus having nl=size(vl). + If globalcheck=.true. the subroutine will check how many + times each entry in the global index space $(1\dots mg)$ is + specified in the input lists vl, thus allowing for the + presence of overlap in the input, and checking for “orphan” + indices. If globalcheck=.false., the subroutine will not + check for overlap, and may be significantly faster, but the user + is implicitly guaranteeing that there are neither orphan nor + overlap indices. +
      +
      lidx
      +
      The optional argument lidx is available for + those cases in which the user has already established a + global-to-local mapping; if it is specified, each index in + vl(i) will be mapped to the corresponding local index + lidx(i). When specifying the argument lidx the user + would also likely employ lidx in calls to psb_cdins + and local in calls to psb_spins and psb_geins; + see also sec. 2.3.1. +
      +
      nl
      +
      If this argument is specified alone (i.e. without vl) + the result is a generalized row-block distribution in which each + process $I$ gets assigned a consecutive chunk of $N_I=nl$ global + indices. +
      +
      repl
      +
      This arguments specifies to replicate all indices on + all processes. This is a special purpose data allocation that is + useful in the construction of some multilevel preconditioners. +
      +
      +
    2. +
    3. On exit from this routine the descriptor is in the build + state. +
    4. +
    5. Calling the routine with vg or parts implies that + every process will scan the entire index space to figure out the + local indices. +
    6. +
    7. Overlapped indices are possible with both parts and + vl invocations. +
    8. +
    9. When the subroutine is invoked with vl in + conjunction with globalcheck=.true., it will perform a scan + of the index space to search for overlap or orphan indices. +
    10. +
    11. When the subroutine is invoked with vl in + conjunction with globalcheck=.false., no index space scan + will take place. Thus it is the responsibility of the user to make + sure that the indices specified in vl have neither orphans nor + overlaps; if this assumption fails, results will be + unpredictable. +
    12. +
    13. Orphan and overlap indices are + impossible by construction when the subroutine is invoked with + nl (alone), or vg. +
    14. +
    + +

    + +

    + diff --git a/docs/html/node76.html b/docs/html/node76.html index 6a43fb9f1..46ac92530 100644 --- a/docs/html/node76.html +++ b/docs/html/node76.html @@ -3,8 +3,8 @@ -psb_cdfree -- Frees a communication descriptor - +psb_cdins -- Communication descriptor insert routine + @@ -16,57 +16,152 @@ - + -

    -psb_cdfree -- Frees a communication descriptor +

    +psb_cdins -- Communication descriptor insert + routine

    -call psb_cdfree(desc_a, info)
    +call psb_cdins(nz, ia, ja, desc_a, info [,ila,jla])
    +call psb_cdins(nz,ja,desc,info[,jla,mask,lidx])
     
    +

    +This subroutine examines the edges of the graph associated with the +discretization mesh (and isomorphic to the sparsity pattern of a +linear system coefficient matrix), storing them as necessary into the +communication descriptor. In the first form the edges are specified as +pairs of indices $ia(i),ja(i)$; the starting index $ia(i)$ should +belong to the current process. +In the second form only the remote indices $ja(i)$ are specified. +

    Type:
    -
    Synchronous. +
    Asynchronous.
    On Entry
    +
    nz
    +
    the number of points being inserted. +
    +Scope: local. +
    +Type: required. +
    +Intent: in. +
    +Specified as: an integer value. +
    +
    ia
    +
    the indices of the starting vertex of the edges being inserted. +
    +Scope: local. +
    +Type: required. +
    +Intent: in. +
    +Specified as: an integer array of length $nz$. +
    +
    ja
    +
    the indices of the end vertex of the edges being inserted. +
    +Scope: local. +
    +Type: required. +
    +Intent: in. +
    +Specified as: an integer array of length $nz$. +
    +
    mask
    +
    Mask entries in ja, they are inserted only when the + corresponding mask entries are .true. +
    +Scope: local. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: a logical array of length $nz$, default .true.. +
    +
    lidx
    +
    User defined local indices for ja. +
    +Scope: local. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: an integer array of length $nz$. +
    +
    + +

    +

    +
    On Return
    +
    +
    desc_a
    -
    the communication descriptor to be freed. +
    the updated communication descriptor.
    Scope:local.
    @@ -76,13 +171,6 @@ Intent: inout.
    Specified as: a structured data of type descdatapsb_desc_type.
    -
    - -

    -

    -
    On Return
    -
    -
    info
    Error code.
    @@ -94,10 +182,78 @@ Intent: out.
    An integer value; 0 means no error has been detected.
    -
    +
    ila
    +
    the local indices of the starting vertex of the edges being inserted. +
    +Scope: local. +
    +Type: optional. +
    +Intent: out. +
    +Specified as: an integer array of length $nz$. +
    +
    jla
    +
    the local indices of the end vertex of the edges being inserted. +
    +Scope: local. +
    +Type: optional. +
    +Intent: out. +
    +Specified as: an integer array of length $nz$.

    -


    +
    + +Notes + +
      +
    1. This routine may only be called if the descriptor is in the + build state; +
    2. +
    3. This routine automatically ignores edges that do not +insist on the current process, i.e. edges for which neither the starting +nor the end vertex belong to the current process. +
    4. +
    5. The second form of this routine will be useful when dealing with + user-specified index mappings; see also 2.3.1. +
    6. +
    + +

    + +

    + diff --git a/docs/html/node77.html b/docs/html/node77.html index 9716704ac..507c1f1c2 100644 --- a/docs/html/node77.html +++ b/docs/html/node77.html @@ -3,8 +3,8 @@ -psb_cdbldext -- Build an extended communication descriptor - +psb_cdasb -- Communication descriptor assembly routine + @@ -16,52 +16,49 @@ - + -

    -psb_cdbldext -- Build an extended communication - descriptor +

    +psb_cdasb -- Communication descriptor assembly + routine

    -call psb_cdbldext(a,desc_a,nl,desc_out, info, extype)
    +call psb_cdasb(desc_a, info [, mold])
     

    -This subroutine builds an extended communication descriptor, based on -the input descriptor desc_a and on the stencil specified -through the input sparse matrix a.

    Type:
    Synchronous. @@ -69,16 +66,6 @@ through the input sparse matrix a.
    On Entry
    -
    a
    -
    A sparse matrix -Scope:local. -
    -Type:required. -
    -Intent: in. -
    -Specified as: a structured data type. -
    desc_a
    the communication descriptor.
    @@ -86,37 +73,20 @@ Scope:local.
    Type:required.
    -Intent: in. +Intent: inout.
    -Specified as: a structured data of type spdatapsb_Tspmat_type. +Specified as: a structured data of type descdatapsb_desc_type.
    -
    nl
    -
    the number of additional layers desired. +
    mold
    +
    The desired dynamic type for the internal index storage.
    -Scope:global. +Scope: local.
    -Type:required. +Type: optional.
    Intent: in.
    -Specified as: an integer value $nl\ge 0$. -
    -
    extype
    -
    the kind of estension required. -
    -Scope:global. -
    -Type:optional . -
    -Intent: in. -
    -Specified as: an integer value -psb_ovt_xhal_, psb_ovt_asov_, default: psb_ovt_xhal_ - -

    +Specified as: a object of type derived from (integer) vbasedatapsb_T_base_vect_type.

    @@ -125,8 +95,8 @@ Specified as: an integer value
    On Return
    -
    desc_out
    -
    the extended communication descriptor. +
    desc_a
    +
    the communication descriptor.
    Scope:local.
    @@ -148,51 +118,16 @@ Intent: out. An integer value; 0 means no error has been detected.
    - -

    Notes

      -
    1. Specifying psb_ovt_xhal_ for the extype argument - the user will obtain a descriptor for a domain partition in which - the additional layers are fetched as part of an (extended) halo; - however the index-to-process mapping is identical to that of the - base descriptor; -
    2. -
    3. Specifying psb_ovt_asov_ for the extype argument - the user will obtain a descriptor with an overlapped decomposition: - the additional layer is aggregated to the local subdomain (and thus - is an overlap), and a new halo extending beyond the last additional - layer is formed. +
    4. On exit from this routine the descriptor is in the assembled + state.

    - -

    - +

    diff --git a/docs/html/node78.html b/docs/html/node78.html index 42ebd8018..4319c0670 100644 --- a/docs/html/node78.html +++ b/docs/html/node78.html @@ -3,8 +3,8 @@ -psb_spall -- Allocates a sparse matrix - +psb_cdcpy -- Copies a communication descriptor + @@ -16,56 +16,56 @@ - + -

    -psb_spall -- Allocates a sparse matrix +

    +psb_cdcpy -- Copies a communication descriptor

    -call psb_spall(a, desc_a, info, nnz)
    +call psb_cdcpy(desc_in, desc_out, info)
     

    Type:
    -
    Synchronous. +
    Asynchronous.
    On Entry
    -
    desc_a
    +
    desc_in
    the communication descriptor.
    Scope:local. @@ -75,18 +75,8 @@ Type:required. Intent: in.
    Specified as: a structured data of type descdatapsb_desc_type. -
    -
    nnz
    -
    An estimate of the number of nonzeroes in the local - part of the assembled matrix. -
    -Scope: global. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: an integer value. + +

    @@ -95,16 +85,16 @@ Specified as: an integer value.
    On Return
    -
    a
    -
    the matrix to be allocated. +
    desc_out
    +
    the communication descriptor copy.
    -Scope:local +Scope:local.
    -Type:required +Type:required.
    Intent: out.
    -Specified as: a structured data of type spdatapsb_Tspmat_type. +Specified as: a structured data of type descdatapsb_desc_type.
    info
    Error code. @@ -118,23 +108,6 @@ Intent: out. An integer value; 0 means no error has been detected.
    -Notes - -
      -
    1. On exit from this routine the sparse matrix is in the build - state. -
    2. -
    3. The descriptor may be in either the build or assembled state. -
    4. -
    5. Providing a good estimate for the number of nonzeroes $nnz$ in - the assembled matrix may substantially improve performance in the - matrix build phase, as it will reduce or eliminate the need for - (potentially multiple) data reallocations. -
    6. -



    diff --git a/docs/html/node79.html b/docs/html/node79.html index 562a80b04..17081ee52 100644 --- a/docs/html/node79.html +++ b/docs/html/node79.html @@ -3,8 +3,8 @@ -psb_spins -- Insert a set of coefficients into a sparse matrix - +psb_cdfree -- Frees a communication descriptor + @@ -16,169 +16,65 @@ - + -

    -psb_spins -- Insert a set of coefficients into a sparse - matrix +

    +psb_cdfree -- Frees a communication descriptor

    -call psb_spins(nz, ia, ja, val, a, desc_a, info [,local])
    -call psb_spins(nr, irw, irp, ja, val, a, desc_a, info [,local])
    +call psb_cdfree(desc_a, info)
     

    Type:
    -
    Asynchronous. +
    Synchronous.
    On Entry
    -
    nz
    -
    the number of coefficients to be inserted. -
    -Scope:local. -
    -Type:required. -
    -Intent: in. -
    -Specified as: an integer scalar. -
    -
    nr
    -
    the number of rows to be inserted. -
    -Scope:local. -
    -Type:required. -
    -Intent: in. -
    -Specified as: an integer scalar. -
    -
    irw
    -
    the first row to be inserted. -
    -Scope:local. -
    -Type:required. -
    -Intent: in. -
    -Specified as: an integer scalar. -
    -
    ia
    -
    the row indices of the coefficients to be inserted. -
    -Scope:local. -
    -Type:required. -
    -Intent: in. -
    -Specified as: an integer array of size $nz$. -
    -
    irp
    -
    the row pointers of the coefficients to be inserted. -
    -Scope:local. -
    -Type:required. -
    -Intent: in. -
    -Specified as: an integer array of size . -
    -
    ja
    -
    the column indices of the coefficients to be inserted. -
    -Scope:local. -
    -Type:required. -
    -Intent: in. -
    -Specified as: an integer array of size $nz$. -
    -
    val
    -
    the coefficients to be inserted. -
    -Scope:local. -
    -Type:required. -
    -Intent: in. -
    -Specified as: an array of size $nz$. Must be of the same type and kind -of the coefficients of the sparse matrix $a$. -
    desc_a
    -
    The communication descriptor. +
    the communication descriptor to be freed.
    -Scope: local. +Scope:local.
    -Type: required. +Type:required.
    Intent: inout.
    -Specified as: a variable of type descdatapsb_desc_type. -
    -
    local
    -
    Whether the entries in the indices vectors ia, - ja are already in local numbering. -
    -Scope:local. -
    -Type:optional. -
    -Specified as: a logical value; default: .false.. - -

    +Specified as: a structured data of type descdatapsb_desc_type.

    @@ -187,28 +83,6 @@ Specified as: a logical value; default: .false..
    On Return
    -
    a
    -
    the matrix into which coefficients will be inserted. -
    -Scope:local -
    -Type:required -
    -Intent: inout. -
    -Specified as: a structured data of type spdatapsb_Tspmat_type. -
    -
    desc_a
    -
    The communication descriptor. -
    -Scope: local. -
    -Type: required. -
    -Intent: inout. -
    -Specified as: a variable of type descdatapsb_desc_type. -
    info
    Error code.
    @@ -223,98 +97,7 @@ An integer value; 0 means no error has been detected.

    -Notes - -

      -
    1. On entry to this routine the descriptor may be in either the - build or assembled state. -
    2. -
    3. On entry to this routine the sparse matrix may be in either the - build or update state. -
    4. -
    5. If the descriptor is in the build state, then the sparse matrix - must also be in the build state; the action of the routine is to - (implicitly) call psb_cdins to add entries to the sparsity - pattern; each sparse matrix entry implicitly defines a graph edge, - that is passed to the descriptor routine for the appropriate - processing; -
    6. -
    7. The input data can be passed in either COO or CSR formats; -
    8. -
    9. In COO format the coefficients to be inserted are represented by - the ordered triples -$ia(i),ja(i),val(i)$, for $i=1,\dots,nz$; - these triples should belong to the current process, i.e. $ia(i)$ - should be one of the local indices, but are otherwise arbitrary; -
    10. -
    11. In CSR format the coefficients to be inserted for each input row - are represented by the ordered triples -, for - -; - these triples should belong to the current process, i.e. - should be one of the local indices, but are otherwise arbitrary; -
    12. -
    13. There is no requirement that a given row must be passed in its - entirety to a single call to this routine: the buildup of a row - may be split into as many calls as desired (even in the CSR format); -
    14. -
    15. Coefficients from different rows may also be mixed up freely - in a single call, according to the application needs; -
    16. -
    17. Any coefficients from matrix rows not owned by the calling - process are silently ignored; -
    18. -
    19. If the descriptor is in the assembled state, then any entries in - the sparse matrix that would generate additional communication - requirements are ignored; -
    20. -
    21. If the matrix is in the update state, any entries in positions - that were not present in the original matrix are ignored. -
    22. -
    - -

    - -

    - +

    diff --git a/docs/html/node8.html b/docs/html/node8.html index df750f2ad..6501ef055 100644 --- a/docs/html/node8.html +++ b/docs/html/node8.html @@ -22,26 +22,26 @@ @@ -94,26 +94,26 @@ as: diff --git a/docs/html/node80.html b/docs/html/node80.html index 295e944c8..346afbdd8 100644 --- a/docs/html/node80.html +++ b/docs/html/node80.html @@ -3,8 +3,8 @@ -psb_spasb -- Sparse matrix assembly routine - +psb_cdbldext -- Build an extended communication descriptor + @@ -16,48 +16,52 @@ - + -

    -psb_spasb -- Sparse matrix assembly routine +

    +psb_cdbldext -- Build an extended communication + descriptor

    -call psb_spasb(a, desc_a, info, afmt, upd, dupl, mold)
    +call psb_cdbldext(a,desc_a,nl,desc_out, info, extype)
     

    +This subroutine builds an extended communication descriptor, based on +the input descriptor desc_a and on the stencil specified +through the input sparse matrix a.

    Type:
    Synchronous. @@ -65,6 +69,16 @@ call psb_spasb(a, desc_a, info, afmt, upd, dupl, mold)
    On Entry
    +
    a
    +
    A sparse matrix +Scope:local. +
    +Type:required. +
    +Intent: in. +
    +Specified as: a structured data type. +
    desc_a
    the communication descriptor.
    @@ -74,52 +88,35 @@ Type:required.
    Intent: in.
    -Specified as: a structured data of type descdatapsb_desc_type. +Specified as: a structured data of type spdatapsb_Tspmat_type.
    -
    afmt
    -
    the storage format for the sparse matrix. +
    nl
    +
    the number of additional layers desired.
    -Scope: local. +Scope:global.
    -Type: optional. +Type:required.
    Intent: in.
    -Specified as: an array of characters. Defalt: 'CSR'. +Specified as: an integer value $nl\ge 0$.
    -
    upd
    -
    Provide for updates to the matrix coefficients. +
    extype
    +
    the kind of estension required.
    -Scope: global. +Scope:global.
    -Type: optional. +Type:optional .
    Intent: in.
    -Specified as: integer, possible values: psb_upd_srch_, psb_upd_perm_ -
    -
    dupl
    -
    How to handle duplicate coefficients. -
    -Scope: global. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: integer, possible values: psb_dupl_ovwrt_, -psb_dupl_add_, psb_dupl_err_. -
    -
    mold
    -
    The desired dynamic type for the internal matrix storage. -
    -Scope: local. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: an object of a class derived from spbasedatapsb_T_base_sparse_mat. +Specified as: an integer value +psb_ovt_xhal_, psb_ovt_asov_, default: psb_ovt_xhal_ + +

    @@ -128,16 +125,16 @@ Specified as: an object of a class derived from spbasedatapsb_T_base_sparse_
    On Return
    -
    a
    -
    the matrix to be assembled. +
    desc_out
    +
    the extended communication descriptor.
    -Scope:local +Scope:local.
    -Type:required +Type:required.
    Intent: inout.
    -Specified as: a structured data of type spdatapsb_Tspmat_type. +Specified as: a structured data of type descdatapsb_desc_type.
    info
    Error code. @@ -156,25 +153,17 @@ An integer value; 0 means no error has been detected. Notes
      -
    1. On entry to this routine the descriptor must be in the - assembled state, i.e. psb_cdasb must already have been called. +
    2. Specifying psb_ovt_xhal_ for the extype argument + the user will obtain a descriptor for a domain partition in which + the additional layers are fetched as part of an (extended) halo; + however the index-to-process mapping is identical to that of the + base descriptor;
    3. -
    4. The sparse matrix may be in either the build or update state; -
    5. -
    6. Duplicate entries are detected and handled in both build and - update state, with the exception of the error action that is only - taken in the build state, i.e. on the first assembly; -
    7. -
    8. If the update choice is psb_upd_perm_, then subsequent - calls to psb_spins to update the matrix must be arranged in - such a way as to produce exactly the same sequence of coefficient - values as encountered at the first assembly; -
    9. -
    10. The output storage format need not be the same on all - processes; -
    11. -
    12. On exit from this routine the matrix is in the assembled state, - and thus is suitable for the computational routines. +
    13. Specifying psb_ovt_asov_ for the extype argument + the user will obtain a descriptor with an overlapped decomposition: + the additional layer is aggregated to the local subdomain (and thus + is an overlap), and a new halo extending beyond the last additional + layer is formed.
    @@ -182,26 +171,26 @@ An integer value; 0 means no error has been detected. diff --git a/docs/html/node81.html b/docs/html/node81.html index 7320ea14f..8480c728e 100644 --- a/docs/html/node81.html +++ b/docs/html/node81.html @@ -3,8 +3,8 @@ -psb_spfree -- Frees a sparse matrix - +psb_spall -- Allocates a sparse matrix + @@ -16,45 +16,45 @@ - + -

    -psb_spfree -- Frees a sparse matrix +

    +psb_spall -- Allocates a sparse matrix

    -call psb_spfree(a, desc_a, info)
    +call psb_spall(a, desc_a, info, nnz)
     

    @@ -65,17 +65,6 @@ call psb_spfree(a, desc_a, info)

    On Entry
    -
    a
    -
    the matrix to be freed. -
    -Scope:local -
    -Type:required -
    -Intent: inout. -
    -Specified as: a structured data of type spdatapsb_Tspmat_type. -
    desc_a
    the communication descriptor.
    @@ -87,6 +76,18 @@ Intent: in.
    Specified as: a structured data of type descdatapsb_desc_type.
    +
    nnz
    +
    An estimate of the number of nonzeroes in the local + part of the assembled matrix. +
    +Scope: global. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: an integer value. +

    @@ -94,6 +95,17 @@ Specified as: a structured data of type descdatapsb_desc_type.

    On Return
    +
    a
    +
    the matrix to be allocated. +
    +Scope:local +
    +Type:required +
    +Intent: out. +
    +Specified as: a structured data of type spdatapsb_Tspmat_type. +
    info
    Error code.
    @@ -106,6 +118,23 @@ Intent: out. An integer value; 0 means no error has been detected.
    +Notes + +
      +
    1. On exit from this routine the sparse matrix is in the build + state. +
    2. +
    3. The descriptor may be in either the build or assembled state. +
    4. +
    5. Providing a good estimate for the number of nonzeroes $nnz$ in + the assembled matrix may substantially improve performance in the + matrix build phase, as it will reduce or eliminate the need for + (potentially multiple) data reallocations. +
    6. +



    diff --git a/docs/html/node82.html b/docs/html/node82.html index e966ada42..fb0084f45 100644 --- a/docs/html/node82.html +++ b/docs/html/node82.html @@ -3,8 +3,8 @@ -psb_sprn -- Reinit sparse matrix structure for psblas routines. - +psb_spins -- Insert a set of coefficients into a sparse matrix + @@ -16,58 +16,182 @@ - + -

    -psb_sprn -- Reinit sparse matrix structure for psblas - routines. +

    +psb_spins -- Insert a set of coefficients into a sparse + matrix

    -call psb_sprn(a, decsc_a, info, clear)
    +call psb_spins(nz, ia, ja, val, a, desc_a, info [,local])
    +call psb_spins(nr, irw, irp, ja, val, a, desc_a, info [,local])
     

    Type:
    -
    Synchronous. +
    Asynchronous.
    On Entry
    +
    nz
    +
    the number of coefficients to be inserted. +
    +Scope:local. +
    +Type:required. +
    +Intent: in. +
    +Specified as: an integer scalar. +
    +
    nr
    +
    the number of rows to be inserted. +
    +Scope:local. +
    +Type:required. +
    +Intent: in. +
    +Specified as: an integer scalar. +
    +
    irw
    +
    the first row to be inserted. +
    +Scope:local. +
    +Type:required. +
    +Intent: in. +
    +Specified as: an integer scalar. +
    +
    ia
    +
    the row indices of the coefficients to be inserted. +
    +Scope:local. +
    +Type:required. +
    +Intent: in. +
    +Specified as: an integer array of size $nz$. +
    +
    irp
    +
    the row pointers of the coefficients to be inserted. +
    +Scope:local. +
    +Type:required. +
    +Intent: in. +
    +Specified as: an integer array of size $nr+1$. +
    +
    ja
    +
    the column indices of the coefficients to be inserted. +
    +Scope:local. +
    +Type:required. +
    +Intent: in. +
    +Specified as: an integer array of size $nz$. +
    +
    val
    +
    the coefficients to be inserted. +
    +Scope:local. +
    +Type:required. +
    +Intent: in. +
    +Specified as: an array of size $nz$. Must be of the same type and kind +of the coefficients of the sparse matrix $a$. +
    +
    desc_a
    +
    The communication descriptor. +
    +Scope: local. +
    +Type: required. +
    +Intent: inout. +
    +Specified as: a variable of type descdatapsb_desc_type. +
    +
    local
    +
    Whether the entries in the indices vectors ia, + ja are already in local numbering. +
    +Scope:local. +
    +Type:optional. +
    +Specified as: a logical value; default: .false.. + +

    +

    +
    + +

    +

    +
    On Return
    +
    +
    a
    -
    the matrix to be reinitialized. +
    the matrix into which coefficients will be inserted.
    Scope:local
    @@ -78,34 +202,16 @@ Intent: inout. Specified as: a structured data of type spdatapsb_Tspmat_type.
    desc_a
    -
    the communication descriptor. +
    The communication descriptor.
    -Scope:local. +Scope: local.
    -Type:required. +Type: required.
    -Intent: in. +Intent: inout.
    -Specified as: a structured data of type descdatapsb_desc_type. -
    -
    clear
    -
    Choose whether to zero out matrix coefficients -
    -Scope:local. -
    -Type:optional. -
    -Intent: in. -
    -Default: true. -
    -
    - -

    -

    -
    On Return
    -
    -
    +Specified as: a variable of type descdatapsb_desc_type. +
    info
    Error code.
    @@ -118,16 +224,112 @@ Intent: out. An integer value; 0 means no error has been detected.
    + +

    Notes

      -
    1. On exit from this routine the sparse matrix is in the update - state. +
    2. On entry to this routine the descriptor may be in either the + build or assembled state. +
    3. +
    4. On entry to this routine the sparse matrix may be in either the + build or update state. +
    5. +
    6. If the descriptor is in the build state, then the sparse matrix + must also be in the build state; the action of the routine is to + (implicitly) call psb_cdins to add entries to the sparsity + pattern; each sparse matrix entry implicitly defines a graph edge, + that is passed to the descriptor routine for the appropriate + processing; +
    7. +
    8. The input data can be passed in either COO or CSR formats; +
    9. +
    10. In COO format the coefficients to be inserted are represented by + the ordered triples +$ia(i),ja(i),val(i)$, for $i=1,\dots,nz$; + these triples should belong to the current process, i.e. $ia(i)$ + should be one of the local indices, but are otherwise arbitrary; +
    11. +
    12. In CSR format the coefficients to be inserted for each input row $i=1,nr$ + are represented by the ordered triples +$(i+irw-1),ja(j),val(j)$, for + +$j=irp(i),\dots,irp(i+1)-1$; + these triples should belong to the current process, i.e. $i+irw-1$ + should be one of the local indices, but are otherwise arbitrary; +
    13. +
    14. There is no requirement that a given row must be passed in its + entirety to a single call to this routine: the buildup of a row + may be split into as many calls as desired (even in the CSR format); +
    15. +
    16. Coefficients from different rows may also be mixed up freely + in a single call, according to the application needs; +
    17. +
    18. Any coefficients from matrix rows not owned by the calling + process are silently ignored; +
    19. +
    20. If the descriptor is in the assembled state, then any entries in + the sparse matrix that would generate additional communication + requirements are ignored; +
    21. +
    22. If the matrix is in the update state, any entries in positions + that were not present in the original matrix are ignored.

    -


    + + + diff --git a/docs/html/node83.html b/docs/html/node83.html index 65e4c10ef..b44e36758 100644 --- a/docs/html/node83.html +++ b/docs/html/node83.html @@ -3,8 +3,8 @@ -psb_geall -- Allocates a dense matrix - +psb_spasb -- Sparse matrix assembly routine + @@ -16,45 +16,45 @@ - + -

    -psb_geall -- Allocates a dense matrix +

    +psb_spasb -- Sparse matrix assembly routine

    -call psb_geall(x, desc_a, info, n, lb)
    +call psb_spasb(a, desc_a, info, afmt, upd, dupl, mold)
     

    @@ -66,51 +66,60 @@ call psb_geall(x, desc_a, info, n, lb)

    desc_a
    -
    The communication descriptor. +
    the communication descriptor.
    -Scope: local +Scope:local.
    -Type: required +Type:required.
    Intent: in.
    -Specified as: a variable of type descdatapsb_desc_type. -
    -
    n
    -
    The number of columns of the dense matrix to be allocated. -
    -Scope: local -
    -Type: optional -
    -Intent: in. -
    -Specified as: Integer scalar, default $1$. It is not a valid argument if $x$ is a -rank-1 array. +Specified as: a structured data of type descdatapsb_desc_type.
    -
    lb
    -
    The lower bound for the column index range of the dense matrix to be allocated. +
    afmt
    +
    the storage format for the sparse matrix.
    -Scope: local +Scope: local.
    -Type: optional +Type: optional.
    Intent: in.
    -Specified as: Integer scalar, default $1$. It is not a valid argument if $x$ is a -rank-1 array. +Specified as: an array of characters. Defalt: 'CSR'. +
    +
    upd
    +
    Provide for updates to the matrix coefficients. +
    +Scope: global. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: integer, possible values: psb_upd_srch_, psb_upd_perm_ +
    +
    dupl
    +
    How to handle duplicate coefficients. +
    +Scope: global. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: integer, possible values: psb_dupl_ovwrt_, +psb_dupl_add_, psb_dupl_err_. +
    +
    mold
    +
    The desired dynamic type for the internal matrix storage. +
    +Scope: local. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: an object of a class derived from spbasedatapsb_T_base_sparse_mat.
    @@ -119,18 +128,17 @@ rank-1 array.
    On Return
    -
    x
    -
    The dense matrix to be allocated. +
    a
    +
    the matrix to be assembled.
    -Scope: local +Scope:local
    -Type: required +Type:required
    -Intent: out. +Intent: inout.
    -Specified as: a rank one or two array with the ALLOCATABLE attribute -or an object of type vdatapsb_T_vect_type, of type real, complex or integer. -
    +Specified as: a structured data of type spdatapsb_Tspmat_type. +
    info
    Error code.
    @@ -145,7 +153,57 @@ An integer value; 0 means no error has been detected.

    -


    +Notes + +
      +
    1. On entry to this routine the descriptor must be in the + assembled state, i.e. psb_cdasb must already have been called. +
    2. +
    3. The sparse matrix may be in either the build or update state; +
    4. +
    5. Duplicate entries are detected and handled in both build and + update state, with the exception of the error action that is only + taken in the build state, i.e. on the first assembly; +
    6. +
    7. If the update choice is psb_upd_perm_, then subsequent + calls to psb_spins to update the matrix must be arranged in + such a way as to produce exactly the same sequence of coefficient + values as encountered at the first assembly; +
    8. +
    9. The output storage format need not be the same on all + processes; +
    10. +
    11. On exit from this routine the matrix is in the assembled state, + and thus is suitable for the computational routines. +
    12. +
    + +

    + +

    + diff --git a/docs/html/node84.html b/docs/html/node84.html index 26821fdaf..2ae76326e 100644 --- a/docs/html/node84.html +++ b/docs/html/node84.html @@ -3,8 +3,8 @@ -psb_geins -- Dense matrix insertion routine - +psb_spfree -- Frees a sparse matrix + @@ -16,101 +16,65 @@ - + -

    -psb_geins -- Dense matrix insertion routine +

    +psb_spfree -- Frees a sparse matrix

    -call psb_geins(m, irw, val, x, desc_a, info [,dupl,local])
    +call psb_spfree(a, desc_a, info)
     

    Type:
    -
    Asynchronous. +
    Synchronous.
    On Entry
    -
    m
    -
    Number of rows in $val$ to be inserted. +
    a
    +
    the matrix to be freed.
    -Scope:local. +Scope:local
    -Type:required. +Type:required
    -Intent: in. +Intent: inout.
    -Specified as: an integer value. -
    -
    irw
    -
    Indices of the rows to be inserted. Specifically, row $i$ - of $val$ will be inserted into the local row corresponding to the - global row index $irw(i)$. -Scope:local. -
    -Type:required. -
    -Intent: in. -
    -Specified as: an integer array. -
    -
    val
    -
    the dense submatrix to be inserted. -
    -Scope:local. -
    -Type:required. -
    -Intent: in. -
    -Specified as: a rank 1 or 2 array. -Specified as: an integer value. +Specified as: a structured data of type spdatapsb_Tspmat_type.
    desc_a
    the communication descriptor. @@ -123,30 +87,6 @@ Intent: in.
    Specified as: a structured data of type descdatapsb_desc_type.
    -
    dupl
    -
    How to handle duplicate coefficients. -
    -Scope: global. -
    -Type: optional. -
    -Intent: in. -
    -Specified as: integer, possible values: psb_dupl_ovwrt_, -psb_dupl_add_. -
    -
    local
    -
    Whether the entries in the index vector irw, - are already in local numbering. -
    -Scope:local. -
    -Type:optional. -
    -Specified as: a logical value; default: .false.. - -

    -

    @@ -154,18 +94,6 @@ Specified as: a logical value; default: .false..

    On Return
    -
    x
    -
    the output dense matrix. -
    -Scope: local -
    -Type: required -
    -Intent: inout. -
    -Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type, of -type real, complex or integer. -
    info
    Error code.
    @@ -180,42 +108,7 @@ An integer value; 0 means no error has been detected.

    -Notes - -

      -
    1. Dense vectors/matrices do not have an associated state; -
    2. -
    3. Duplicate entries are either overwritten or added, there is no - provision for raising an error condition. -
    4. -
    - -

    - -

    - +

    diff --git a/docs/html/node85.html b/docs/html/node85.html index 3a23b931b..199f1af90 100644 --- a/docs/html/node85.html +++ b/docs/html/node85.html @@ -3,8 +3,8 @@ -psb_geasb -- Assembly a dense matrix - +psb_sprn -- Reinit sparse matrix structure for psblas routines. + @@ -16,45 +16,46 @@ - + -

    -psb_geasb -- Assembly a dense matrix +

    +psb_sprn -- Reinit sparse matrix structure for psblas + routines.

    -call psb_geasb(x, desc_a, info, mold)
    +call psb_sprn(a, decsc_a, info, clear)
     

    @@ -65,31 +66,38 @@ call psb_geasb(x, desc_a, info, mold)

    On Entry
    +
    a
    +
    the matrix to be reinitialized. +
    +Scope:local +
    +Type:required +
    +Intent: inout. +
    +Specified as: a structured data of type spdatapsb_Tspmat_type. +
    desc_a
    -
    The communication descriptor. +
    the communication descriptor.
    -Scope: local +Scope:local.
    -Type: required +Type:required.
    Intent: in.
    -Specified as: a variable of type descdatapsb_desc_type. -
    -
    mold
    -
    The desired dynamic type for the internal vector storage. +Specified as: a structured data of type descdatapsb_desc_type. +
    +
    clear
    +
    Choose whether to zero out matrix coefficients
    -Scope: local. +Scope:local.
    -Type: optional. +Type:optional.
    Intent: in.
    -Specified as: an object of a class derived from vbasedatapsb_T_base_vect_type; this is -only allowed when $x$ is of type vdatapsb_T_vect_type. +Default: true.
    @@ -98,18 +106,6 @@ only allowed when On Return
    -
    x
    -
    The dense matrix to be assembled. -
    -Scope: local -
    -Type: required -
    -Intent: inout. -
    -Specified as: a rank one or two array with the ALLOCATABLE or an -object of type vdatapsb_T_vect_type, of type real, complex or integer. -
    info
    Error code.
    @@ -122,6 +118,15 @@ Intent: out. An integer value; 0 means no error has been detected.
    +Notes + +
      +
    1. On exit from this routine the sparse matrix is in the update + state. +
    2. +
    + +



    diff --git a/docs/html/node86.html b/docs/html/node86.html index e1744ccb3..72ad8bf66 100644 --- a/docs/html/node86.html +++ b/docs/html/node86.html @@ -3,8 +3,8 @@ -psb_gefree -- Frees a dense matrix - +psb_geall -- Allocates a dense matrix + @@ -16,45 +16,45 @@ - + -

    -psb_gefree -- Frees a dense matrix +

    +psb_geall -- Allocates a dense matrix

    -call psb_gefree(x, desc_a, info)
    +call psb_geall(x, desc_a, info, n, lb)
     

    @@ -65,21 +65,6 @@ call psb_gefree(x, desc_a, info)

    On Entry
    -
    x
    -
    The dense matrix to - be freed. -
    -Scope: local -
    -Type: required -
    -Intent: inout. -
    -Specified as: a rank one or two array with the ALLOCATABLE or an -object of type vdatapsb_T_vect_type, of type real, complex or integer. -
    -

    -

    desc_a
    The communication descriptor.
    @@ -91,6 +76,42 @@ Intent: in.
    Specified as: a variable of type descdatapsb_desc_type.
    +
    n
    +
    The number of columns of the dense matrix to be allocated. +
    +Scope: local +
    +Type: optional +
    +Intent: in. +
    +Specified as: Integer scalar, default $1$. It is not a valid argument if $x$ is a +rank-1 array. +
    +
    lb
    +
    The lower bound for the column index range of the dense matrix to be allocated. +
    +Scope: local +
    +Type: optional +
    +Intent: in. +
    +Specified as: Integer scalar, default $1$. It is not a valid argument if $x$ is a +rank-1 array. +

    @@ -98,6 +119,18 @@ Specified as: a variable of type descdatapsb_desc_type.

    On Return
    +
    x
    +
    The dense matrix to be allocated. +
    +Scope: local +
    +Type: required +
    +Intent: out. +
    +Specified as: a rank one or two array with the ALLOCATABLE attribute +or an object of type vdatapsb_T_vect_type, of type real, complex or integer. +
    info
    Error code.
    diff --git a/docs/html/node87.html b/docs/html/node87.html index dbb80998a..7e7dff181 100644 --- a/docs/html/node87.html +++ b/docs/html/node87.html @@ -3,8 +3,8 @@ -psb_gelp -- Applies a left permutation to a dense matrix - +psb_geins -- Dense matrix insertion routine + @@ -16,46 +16,45 @@ - + -

    -psb_gelp -- Applies a left permutation to a dense - matrix +

    +psb_geins -- Dense matrix insertion routine

    -call psb_gelp(trans, iperm, x, info)
    +call psb_geins(m, irw, val, x, desc_a, info [,dupl,local])
     

    @@ -66,51 +65,88 @@ call psb_gelp(trans, iperm, x, info)

    On Entry
    -
    trans
    -
    A character that specifies whether to permute $A$ or $A^T$. +
    m
    +
    Number of rows in $val$ to be inserted.
    -Scope: local +Scope:local.
    -Type: required +Type:required.
    Intent: in.
    -Specified as: a single character with value 'N' for $A$ or 'T' for $A^T$. -
    -
    iperm
    -
    An integer array containing permutation information. +Specified as: an integer value. +
    +
    irw
    +
    Indices of the rows to be inserted. Specifically, row $i$ + of $val$ will be inserted into the local row corresponding to the + global row index $irw(i)$. +Scope:local.
    -Scope: local -
    -Type: required +Type:required.
    Intent: in.
    -Specified as: an integer one-dimensional array. -
    -
    x
    -
    The dense matrix to be permuted. +Specified as: an integer array. +
    +
    val
    +
    the dense submatrix to be inserted.
    -Scope: local +Scope:local.
    -Type: required +Type:required.
    -Intent: inout. +Intent: in.
    -Specified as: a one or two dimensional array. -
    +Specified as: a rank 1 or 2 array. +Specified as: an integer value. + +
    desc_a
    +
    the communication descriptor. +
    +Scope:local. +
    +Type:required. +
    +Intent: in. +
    +Specified as: a structured data of type descdatapsb_desc_type. +
    +
    dupl
    +
    How to handle duplicate coefficients. +
    +Scope: global. +
    +Type: optional. +
    +Intent: in. +
    +Specified as: integer, possible values: psb_dupl_ovwrt_, +psb_dupl_add_. +
    +
    local
    +
    Whether the entries in the index vector irw, + are already in local numbering. +
    +Scope:local. +
    +Type:optional. +
    +Specified as: a logical value; default: .false.. + +

    +

    @@ -118,6 +154,18 @@ Specified as: a one or two dimensional array.

    On Return
    +
    x
    +
    the output dense matrix. +
    +Scope: local +
    +Type: required +
    +Intent: inout. +
    +Specified as: a rank one or two array or an object of type vdatapsb_T_vect_type, of +type real, complex or integer. +
    info
    Error code.
    @@ -132,7 +180,42 @@ An integer value; 0 means no error has been detected.

    -


    +Notes + +
      +
    1. Dense vectors/matrices do not have an associated state; +
    2. +
    3. Duplicate entries are either overwritten or added, there is no + provision for raising an error condition. +
    4. +
    + +

    + +

    + diff --git a/docs/html/node88.html b/docs/html/node88.html index 562054789..705998d9c 100644 --- a/docs/html/node88.html +++ b/docs/html/node88.html @@ -3,8 +3,8 @@ -psb_glob_to_loc -- Global to local indices convertion - +psb_geasb -- Assembly a dense matrix + @@ -16,101 +16,80 @@ - + -

    -psb_glob_to_loc -- Global to local indices - convertion +

    +psb_geasb -- Assembly a dense matrix

    -call psb_glob_to_loc(x, y, desc_a, info, iact,owned)
    -call psb_glob_to_loc(x, desc_a, info, iact,owned)
    +call psb_geasb(x, desc_a, info, mold)
     

    Type:
    -
    Asynchronous. +
    Synchronous.
    On Entry
    -
    x
    -
    An integer vector of indices to be converted. +
    desc_a
    +
    The communication descriptor.
    Scope: local
    Type: required
    -Intent: in, inout. +Intent: in.
    -Specified as: a rank one integer array. +Specified as: a variable of type descdatapsb_desc_type.
    -
    desc_a
    -
    the communication descriptor. +
    mold
    +
    The desired dynamic type for the internal vector storage.
    -Scope:local. +Scope: local.
    -Type:required. +Type: optional.
    Intent: in.
    -Specified as: a structured data of type descdatapsb_desc_type. -
    -
    iact
    -
    specifies action to be taken in case of range errors. -Scope: global -
    -Type: optional -
    -Intent: in. -
    -Specified as: a character variable Ignore, Warning or -Abort, default Ignore. -
    -
    owned
    -
    Specfies valid range of input -Scope: global -
    -Type: optional -
    -Intent: in. -
    -If true, then only indices strictly owned by the current process are -considered valid, if false then halo indices are also -accepted. Default: false. +Specified as: an object of a class derived from vbasedatapsb_T_base_vect_type; this is +only allowed when $x$ is of type vdatapsb_T_vect_type.
    @@ -120,43 +99,17 @@ accepted. Default: false.
    x
    -
    If $y$ is not present, - then $x$ is overwritten with the translated integer indices. -Scope: global +
    The dense matrix to be assembled. +
    +Scope: local
    Type: required
    Intent: inout.
    -Specified as: a rank one integer array. -
    -
    y
    -
    If $y$ is present, - then $y$ is overwritten with the translated integer indices, and $x$ - is left unchanged. -Scope: global -
    -Type: optional -
    -Intent: out. -
    -Specified as: a rank one integer array. -
    +Specified as: a rank one or two array with the ALLOCATABLE or an +object of type vdatapsb_T_vect_type, of type real, complex or integer. +
    info
    Error code.
    @@ -169,45 +122,7 @@ Intent: out. An integer value; 0 means no error has been detected.
    - -

    -Notes - -

      -
    1. If an input index is out of range, then the corresponding output - index is set to a negative number; -
    2. -
    3. The default Ignore means that the negative output is the - only action taken on an out-of-range input. -
    4. -
    - -

    - -

    - +

    diff --git a/docs/html/node89.html b/docs/html/node89.html index ac2750955..48f987c13 100644 --- a/docs/html/node89.html +++ b/docs/html/node89.html @@ -3,8 +3,8 @@ -psb_loc_to_glob -- Local to global indices conversion - +psb_gefree -- Frees a dense matrix + @@ -16,90 +16,81 @@ - + -

    -psb_loc_to_glob -- Local to global indices - conversion +

    +psb_gefree -- Frees a dense matrix

    -call psb_loc_to_glob(x, y, desc_a, info, iact)
    -call psb_loc_to_glob(x, desc_a, info, iact)
    +call psb_gefree(x, desc_a, info)
     

    Type:
    -
    Asynchronous. +
    Synchronous.
    On Entry
    x
    -
    An integer vector of indices to be converted. +
    The dense matrix to + be freed.
    Scope: local
    Type: required
    -Intent: in, inout. +Intent: inout.
    -Specified as: a rank one integer array. -
    +Specified as: a rank one or two array with the ALLOCATABLE or an +object of type vdatapsb_T_vect_type, of type real, complex or integer. +
    +

    +

    desc_a
    -
    the communication descriptor. +
    The communication descriptor.
    -Scope:local. +Scope: local
    -Type:required. +Type: required
    Intent: in.
    -Specified as: a structured data of type descdatapsb_desc_type. -
    -
    iact
    -
    specifies action to be taken in case of range errors. -Scope: global -
    -Type: optional -
    -Intent: in. -
    -Specified as: a character variable Ignore, Warning or -Abort, default Ignore. -
    +Specified as: a variable of type descdatapsb_desc_type. +

    @@ -107,44 +98,6 @@ Specified as: a character variable Ignore, Warning or

    On Return
    -
    x
    -
    If $y$ is not present, - then $x$ is overwritten with the translated integer indices. -Scope: global -
    -Type: required -
    -Intent: inout. -
    -Specified as: a rank one integer array. -
    -
    y
    -
    If $y$ is not present, - then $y$ is overwritten with the translated integer indices, and $x$ - is left unchanged. -Scope: global -
    -Type: optional -
    -Intent: out. -
    -Specified as: a rank one integer array. -
    info
    Error code.
    diff --git a/docs/html/node9.html b/docs/html/node9.html index b60f74d37..7e75eada3 100644 --- a/docs/html/node9.html +++ b/docs/html/node9.html @@ -23,26 +23,26 @@ @@ -114,132 +114,132 @@ developer's documentation. Subsections diff --git a/docs/html/node90.html b/docs/html/node90.html index aaf6d3e32..9de2f117a 100644 --- a/docs/html/node90.html +++ b/docs/html/node90.html @@ -3,8 +3,8 @@ -psb_is_owned -- - +psb_gelp -- Applies a left permutation to a dense matrix + @@ -16,45 +16,46 @@ - + -

    -psb_is_owned -- +

    +psb_gelp -- Applies a left permutation to a dense + matrix

    -call psb_is_owned(x, desc_a)
    +call psb_gelp(trans, iperm, x, info)
     

    @@ -65,8 +66,14 @@ call psb_is_owned(x, desc_a)

    On Entry
    -
    x
    -
    Integer index. +
    trans
    +
    A character that specifies whether to permute $A$ or $A^T$.
    Scope: local
    @@ -74,19 +81,36 @@ Type: required
    Intent: in.
    -Specified as: a scalar integer. +Specified as: a single character with value 'N' for $A$ or 'T' for $A^T$.
    -
    desc_a
    -
    the communication descriptor. +
    iperm
    +
    An integer array containing permutation information.
    -Scope:local. +Scope: local
    -Type:required. +Type: required
    Intent: in.
    -Specified as: a structured data of type descdatapsb_desc_type. -
    +Specified as: an integer one-dimensional array. +
    +
    x
    +
    The dense matrix to be permuted. +
    +Scope: local +
    +Type: required +
    +Intent: inout. +
    +Specified as: a one or two dimensional array. +

    @@ -94,30 +118,19 @@ Specified as: a structured data of type descdatapsb_desc_type.

    On Return
    -
    Function value
    -
    A logical mask which is true if - $x$ is owned by the current process +
    info
    +
    Error code. +
    Scope: local
    -Type: required +Type: required
    Intent: out. -
    +
    +An integer value; 0 means no error has been detected. + -

    -Notes - -

      -
    1. This routine returns a .true. value for an index - that is strictly owned by the current process, excluding the halo - indices -
    2. -
    -



    diff --git a/docs/html/node91.html b/docs/html/node91.html index d2bd979c5..053654184 100644 --- a/docs/html/node91.html +++ b/docs/html/node91.html @@ -3,8 +3,8 @@ -psb_owned_index -- - +psb_glob_to_loc -- Global to local indices convertion + @@ -16,45 +16,47 @@ - + -

    -psb_owned_index -- +

    +psb_glob_to_loc -- Global to local indices + convertion

    -call psb_owned_index(y, x, desc_a, info)
    +call psb_glob_to_loc(x, y, desc_a, info, iact,owned)
    +call psb_glob_to_loc(x, desc_a, info, iact,owned)
     

    @@ -66,7 +68,7 @@ call psb_owned_index(y, x, desc_a, info)

    x
    -
    Integer indices. +
    An integer vector of indices to be converted.
    Scope: local
    @@ -74,7 +76,7 @@ Type: required
    Intent: in, inout.
    -Specified as: a scalar or a rank one integer array. +Specified as: a rank one integer array.
    desc_a
    the communication descriptor. @@ -98,6 +100,18 @@ Intent: in. Specified as: a character variable Ignore, Warning or Abort, default Ignore.
    +
    owned
    +
    Specfies valid range of input +Scope: global +
    +Type: optional +
    +Intent: in. +
    +If true, then only indices strictly owned by the current process are +considered valid, if false then halo indices are also +accepted. Default: false. +

    @@ -105,19 +119,43 @@ Specified as: a character variable Ignore, Warning or

    On Return
    -
    y
    -
    A logical mask which is true for all corresponding entries of - x +
    If $y$ is not present, + then $x$ that are owned by the current process -Scope: local + ALT="$x$"> is overwritten with the translated integer indices. +Scope: global
    Type: required
    +Intent: inout. +
    +Specified as: a rank one integer array. +
    +
    y
    +
    If $y$ is present, + then $y$ is overwritten with the translated integer indices, and $x$ + is left unchanged. +Scope: global +
    +Type: optional +
    Intent: out.
    -Specified as: a scalar or rank one logical array. +Specified as: a rank one integer array.
    info
    Error code. @@ -136,14 +174,40 @@ An integer value; 0 means no error has been detected. Notes
      -
    1. This routine returns a .true. value for those indices - that are strictly owned by the current process, excluding the halo - indices +
    2. If an input index is out of range, then the corresponding output + index is set to a negative number; +
    3. +
    4. The default Ignore means that the negative output is the + only action taken on an out-of-range input.

    -


    + + + diff --git a/docs/html/node92.html b/docs/html/node92.html index a3c4d4b6f..666b0bf51 100644 --- a/docs/html/node92.html +++ b/docs/html/node92.html @@ -3,8 +3,8 @@ -psb_is_local -- - +psb_loc_to_glob -- Local to global indices conversion + @@ -16,45 +16,47 @@ - + -

    -psb_is_local -- +

    +psb_loc_to_glob -- Local to global indices + conversion

    -call psb_is_local(x, desc_a)
    +call psb_loc_to_glob(x, y, desc_a, info, iact)
    +call psb_loc_to_glob(x, desc_a, info, iact)
     

    @@ -66,15 +68,15 @@ call psb_is_local(x, desc_a)

    x
    -
    Integer index. +
    An integer vector of indices to be converted.
    Scope: local
    Type: required
    -Intent: in. +Intent: in, inout.
    -Specified as: a scalar integer. +Specified as: a rank one integer array.
    desc_a
    the communication descriptor. @@ -87,6 +89,17 @@ Intent: in.
    Specified as: a structured data of type descdatapsb_desc_type.
    +
    iact
    +
    specifies action to be taken in case of range errors. +Scope: global +
    +Type: optional +
    +Intent: in. +
    +Specified as: a character variable Ignore, Warning or +Abort, default Ignore. +

    @@ -94,30 +107,57 @@ Specified as: a structured data of type descdatapsb_desc_type.

    On Return
    -
    Function value
    -
    A logical mask which is true if - x +
    If $y$ is not present, + then $x$ is local to the current process -Scope: local + ALT="$x$"> is overwritten with the translated integer indices. +Scope: global
    Type: required
    +Intent: inout. +
    +Specified as: a rank one integer array. +
    +
    y
    +
    If $y$ is not present, + then $y$ is overwritten with the translated integer indices, and $x$ + is left unchanged. +Scope: global +
    +Type: optional +
    Intent: out. -
    +
    +Specified as: a rank one integer array. + +
    info
    +
    Error code. +
    +Scope: local +
    +Type: required +
    +Intent: out. +
    +An integer value; 0 means no error has been detected. +
    -

    -Notes - -

      -
    1. This routine returns a .true. value for an index - that is local to the current process, including the halo - indices -
    2. -
    -



    diff --git a/docs/html/node93.html b/docs/html/node93.html index 3a12cab90..133899aa9 100644 --- a/docs/html/node93.html +++ b/docs/html/node93.html @@ -3,8 +3,8 @@ -psb_local_index -- - +psb_is_owned -- + @@ -16,45 +16,45 @@ - + -

    -psb_local_index -- +

    +psb_is_owned --

    -call psb_local_index(y, x, desc_a, info)
    +call psb_is_owned(x, desc_a)
     

    @@ -66,15 +66,15 @@ call psb_local_index(y, x, desc_a, info)

    x
    -
    Integer indices. +
    Integer index.
    Scope: local
    Type: required
    -Intent: in, inout. +Intent: in.
    -Specified as: a scalar or a rank one integer array. +Specified as: a scalar integer.
    desc_a
    the communication descriptor. @@ -87,17 +87,6 @@ Intent: in.
    Specified as: a structured data of type descdatapsb_desc_type.
    -
    iact
    -
    specifies action to be taken in case of range errors. -Scope: global -
    -Type: optional -
    -Intent: in. -
    -Specified as: a character variable Ignore, Warning or -Abort, default Ignore. -

    @@ -105,40 +94,27 @@ Specified as: a character variable Ignore, Warning or

    On Return
    -
    y
    -
    A logical mask which is true for all corresponding entries of +
    Function value
    +
    A logical mask which is true if $x$ that are local to the current process + ALT="$x$"> is owned by the current process Scope: local
    Type: required
    Intent: out. -
    -Specified as: a scalar or rank one logical array. -
    -
    info
    -
    Error code. -
    -Scope: local -
    -Type: required -
    -Intent: out. -
    -An integer value; 0 means no error has been detected. -
    +

    Notes

      -
    1. This routine returns a .true. value for those indices - that are local to the current process, including the halo - indices. +
    2. This routine returns a .true. value for an index + that is strictly owned by the current process, excluding the halo + indices
    diff --git a/docs/html/node94.html b/docs/html/node94.html index 41a1b8588..56bfb76ff 100644 --- a/docs/html/node94.html +++ b/docs/html/node94.html @@ -3,8 +3,8 @@ -psb_get_boundary -- Extract list of boundary elements - +psb_owned_index -- + @@ -16,46 +16,45 @@ - + -

    -psb_get_boundary -- Extract list of boundary - elements +

    +psb_owned_index --

    -call psb_get_boundary(bndel, desc, info)
    +call psb_owned_index(y, x, desc_a, info)
     

    @@ -66,7 +65,18 @@ call psb_get_boundary(bndel, desc, info)

    On Entry
    -
    desc
    +
    x
    +
    Integer indices. +
    +Scope: local +
    +Type: required +
    +Intent: in, inout. +
    +Specified as: a scalar or a rank one integer array. +
    +
    desc_a
    the communication descriptor.
    Scope:local. @@ -77,6 +87,17 @@ Intent: in.
    Specified as: a structured data of type descdatapsb_desc_type.
    +
    iact
    +
    specifies action to be taken in case of range errors. +Scope: global +
    +Type: optional +
    +Intent: in. +
    +Specified as: a character variable Ignore, Warning or +Abort, default Ignore. +

    @@ -84,19 +105,20 @@ Specified as: a structured data of type descdatapsb_desc_type.

    On Return
    -
    bndel
    -
    The list of boundary elements on the calling process, in - local numbering. -
    +
    y
    +
    A logical mask which is true for all corresponding entries of + $x$ that are owned by the current process Scope: local
    Type: required
    Intent: out.
    -Specified as: a rank one array with the ALLOCATABLE -attribute, of type integer. -
    +Specified as: a scalar or rank one logical array. +
    info
    Error code.
    @@ -114,12 +136,9 @@ An integer value; 0 means no error has been detected. Notes
      -
    1. If there are no boundary elements (i.e., if the local part of - the connectivity graph is self-contained) the output vector is set - to the “not allocated” state. -
    2. -
    3. Otherwise the size of bndel will be exactly equal to the - number of boundary elements. +
    4. This routine returns a .true. value for those indices + that are strictly owned by the current process, excluding the halo + indices
    diff --git a/docs/html/node95.html b/docs/html/node95.html index 07d579819..79dba935f 100644 --- a/docs/html/node95.html +++ b/docs/html/node95.html @@ -3,8 +3,8 @@ -psb_get_overlap -- Extract list of overlap elements - +psb_is_local -- + @@ -16,46 +16,45 @@ - + -

    -psb_get_overlap -- Extract list of overlap - elements +

    +psb_is_local --

    -call psb_get_overlap(ovrel, desc, info)
    +call psb_is_local(x, desc_a)
     

    @@ -66,7 +65,18 @@ call psb_get_overlap(ovrel, desc, info)

    On Entry
    -
    desc
    +
    x
    +
    Integer index. +
    +Scope: local +
    +Type: required +
    +Intent: in. +
    +Specified as: a scalar integer. +
    +
    desc_a
    the communication descriptor.
    Scope:local. @@ -84,41 +94,27 @@ Specified as: a structured data of type descdatapsb_desc_type.
    On Return
    -
    ovrel
    -
    The list of overlap elements on the calling process, in - local numbering. -
    +
    Function value
    +
    A logical mask which is true if + $x$ is local to the current process Scope: local
    Type: required
    Intent: out. -
    -Specified as: a rank one array with the ALLOCATABLE -attribute, of type integer.
    -
    info
    -
    Error code. -
    -Scope: local -
    -Type: required -
    -Intent: out. -
    -An integer value; 0 means no error has been detected. -

    Notes

      -
    1. If there are no overlap elements the output vector is set - to the “not allocated” state. -
    2. -
    3. Otherwise the size of ovrel will be exactly equal to the - number of overlap elements. +
    4. This routine returns a .true. value for an index + that is local to the current process, including the halo + indices
    diff --git a/docs/html/node96.html b/docs/html/node96.html index 2736fbfb9..d7e2ac978 100644 --- a/docs/html/node96.html +++ b/docs/html/node96.html @@ -3,8 +3,8 @@ -psb_sp_getrow -- Extract row(s) from a sparse matrix - +psb_local_index -- + @@ -16,47 +16,45 @@ - + -

    -psb_sp_getrow -- Extract row(s) from a sparse - matrix +

    +psb_local_index --

    -call psb_sp_getrow(row, a, nz, ia, ja, val, info, &
    -              & append, nzin, lrw)
    +call psb_local_index(y, x, desc_a, info)
     

    @@ -67,75 +65,38 @@ call psb_sp_getrow(row, a, nz, ia, ja, val, info, &

    On Entry
    -
    row
    -
    The (first) row to be extracted. +
    x
    +
    Integer indices.
    -Scope:local +Scope: local
    -Type:required +Type: required +
    +Intent: in, inout. +
    +Specified as: a scalar or a rank one integer array. +
    +
    desc_a
    +
    the communication descriptor. +
    +Scope:local. +
    +Type:required.
    Intent: in.
    -Specified as: an integer $>0$. +Specified as: a structured data of type descdatapsb_desc_type.
    -
    a
    -
    the matrix from which to get rows. +
    iact
    +
    specifies action to be taken in case of range errors. +Scope: global
    -Scope:local -
    -Type:required +Type: optional
    Intent: in.
    -Specified as: a structured data of type spdatapsb_Tspmat_type. -
    -
    append
    -
    Whether to append or overwrite existing output. -
    -Scope:local -
    -Type:optional -
    -Intent: in. -
    -Specified as: a logical value default: false (overwrite). -
    -
    nzin
    -
    Input size to be appended to. -
    -Scope:local -
    -Type:optional -
    -Intent: in. -
    -Specified as: an integer $>0$. When append is true, specifies how many -entries in the output vectors are already filled. -
    -
    lrw
    -
    The last row to be extracted. -
    -Scope:local -
    -Type:optional -
    -Intent: in. -
    -Specified as: an integer $>0$, default: $row$. - -

    +Specified as: a character variable Ignore, Warning or +Abort, default Ignore.

    @@ -144,49 +105,19 @@ Specified as: an integer On Return
    -
    nz
    -
    the number of elements returned by this call. +
    y
    +
    A logical mask which is true for all corresponding entries of + $x$ that are local to the current process +Scope: local
    -Scope:local. -
    -Type:required. +Type: required
    Intent: out.
    -Returned as: an integer scalar. -
    -
    ia
    -
    the row indices. -
    -Scope:local. -
    -Type:required. -
    -Intent: inout. -
    -Specified as: an integer array with the ALLOCATABLE attribute. -
    -
    ja
    -
    the column indices of the elements to be inserted. -
    -Scope:local. -
    -Type:required. -
    -Intent: inout. -
    -Specified as: an integer array with the ALLOCATABLE attribute. -
    -
    val
    -
    the elements to be inserted. -
    -Scope:local. -
    -Type:required. -
    -Intent: inout. -
    -Specified as: a real array with the ALLOCATABLE attribute. +Specified as: a scalar or rank one logical array.
    info
    Error code. @@ -205,52 +136,14 @@ An integer value; 0 means no error has been detected. Notes
      -
    1. The output $nz$ is always the size of the output generated by - the current call; thus, if append=.true., the total output - size will be $nzin+nz$, with the newly extracted coefficients stored in - entries nzin+1:nzin+nz of the array arguments; -
    2. -
    3. When append=.true. the output arrays are reallocated as - necessary; -
    4. -
    5. The row and column indices are returned in the local numbering - scheme; if the global numbering is desired, the user may employ the - psb_loc_to_glob routine on the output. +
    6. This routine returns a .true. value for those indices + that are local to the current process, including the halo + indices.

    - -

    - +

    diff --git a/docs/html/node97.html b/docs/html/node97.html index 9a4468313..184f952e2 100644 --- a/docs/html/node97.html +++ b/docs/html/node97.html @@ -3,8 +3,8 @@ -psb_sizeof -- Memory occupation - +psb_get_boundary -- Extract list of boundary elements + @@ -16,50 +16,46 @@ - + -

    -psb_sizeof -- Memory occupation +

    +psb_get_boundary -- Extract list of boundary + elements

    -

    -This function computes the memory occupation of a PSBLAS object. -

    -isz = psb_sizeof(a)
    -isz = psb_sizeof(desc_a)
    -isz = psb_sizeof(prec)
    +call psb_get_boundary(bndel, desc, info)
     

    @@ -70,54 +66,63 @@ isz = psb_sizeof(prec)

    On Entry
    -
    a
    -
    A sparse matrix -$A$. +
    desc
    +
    the communication descriptor.
    -Scope: local +Scope:local.
    -Type: required -
    -Intent: in. -
    -Specified as: a structured data of type spdatapsb_Tspmat_type. -
    -
    desc_a
    -
    Communication descriptor. -
    -Scope: local -
    -Type: required +Type:required.
    Intent: in.
    Specified as: a structured data of type descdatapsb_desc_type.
    -
    prec
    -
    Scope: local -
    -Type: required -
    -Intent: in. -
    -Specified as: a preconditioner data structure precdatapsb_prec_type. -
    + + +

    +

    On Return
    -
    Function value
    -
    The memory occupation of the object specified in - the calling sequence, in bytes. +
    bndel
    +
    The list of boundary elements on the calling process, in + local numbering.
    Scope: local
    -Returned as: an integer(psb_long_int_k_) number. +Type: required +
    +Intent: out. +
    +Specified as: a rank one array with the ALLOCATABLE +attribute, of type integer. +
    +
    info
    +
    Error code. +
    +Scope: local +
    +Type: required +
    +Intent: out. +
    +An integer value; 0 means no error has been detected.
    +

    +Notes + +

      +
    1. If there are no boundary elements (i.e., if the local part of + the connectivity graph is self-contained) the output vector is set + to the “not allocated” state. +
    2. +
    3. Otherwise the size of bndel will be exactly equal to the + number of boundary elements. +
    4. +
    +



    diff --git a/docs/html/node98.html b/docs/html/node98.html index 5625baef1..4f8e69381 100644 --- a/docs/html/node98.html +++ b/docs/html/node98.html @@ -3,8 +3,8 @@ -Sorting utilities -- - +psb_get_overlap -- Extract list of overlap elements + @@ -14,121 +14,68 @@ + - + -

    -Sorting utilities -- +

    +psb_get_overlap -- Extract list of overlap + elements

    -psb_msort -- Sorting by the Merge-sort - algorithm - -

    -psb_qsort -- Sorting by the Quicksort - algorithm - -

    -psb_hsort -- Sorting by the Heapsort algorithm

    -call psb_msort(x,ix,dir,flag)
    -call psb_qsort(x,ix,dir,flag)
    -call psb_hsort(x,ix,dir,flag)
    +call psb_get_overlap(ovrel, desc, info)
     

    -These serial routines sort a sequence $X$ into ascending or -descending order. The argument meaning is identical for the three -calls; the only difference is the algorithm used to accomplish the -task (see Usage Notes below).

    Type:
    Asynchronous.
    -
    On Entry
    +
    On Entry
    -
    x
    -
    The sequence to be sorted. +
    desc
    +
    the communication descriptor. +
    +Scope:local.
    Type:required.
    -Specified as: an integer, real or complex array of rank 1. -
    -
    ix
    -
    A vector of indices. +Intent: in.
    -Type:optional. -
    -Specified as: an integer array of (at least) the same size as $X$. -
    -
    dir
    -
    The desired ordering. -
    -Type:optional. -
    -Specified as: an integer value:
    -
    Integer and real data:
    -
    psb_sort_up_, -psb_sort_down_, psb_asort_up_, psb_asort_down_; -default psb_sort_up_. -
    -
    Complex data:
    -
    psb_lsort_up_, -psb_lsort_down_, psb_asort_up_, psb_asort_down_; -default psb_lsort_up_. -
    -
    -
    -
    flag
    -
    Whether to keep the original values in $IX$. -
    -Type:optional. -
    -Specified as: an integer value psb_sort_ovw_idx_ or -psb_sort_keep_idx_; default psb_sort_ovw_idx_. - -

    +Specified as: a structured data of type descdatapsb_desc_type.

    @@ -137,155 +84,46 @@ Specified as: an integer value psb_sort_ovw_idx_ or
    On Return
    -
    x
    -
    The sequence of values, in the chosen ordering. +
    ovrel
    +
    The list of overlap elements on the calling process, in + local numbering.
    -Type:required. +Scope: local
    -Specified as: an integer, real or complex array of rank 1. -
    -
    ix
    -
    A vector of indices. +Type: required
    -Type: Optional +Intent: out.
    -An integer array of rank 1, whose entries are moved to the same -position as the corresponding entries in $x$. +Specified as: a rank one array with the ALLOCATABLE +attribute, of type integer. +
    +
    info
    +
    Error code. +
    +Scope: local +
    +Type: required +
    +Intent: out. +
    +An integer value; 0 means no error has been detected.
    -

    -

    Notes

      -
    1. For integer or real data the sorting can be performed in the up/down direction, on the - natural or absolute values; +
    2. If there are no overlap elements the output vector is set + to the “not allocated” state.
    3. -
    4. For complex data the sorting can be done in a lexicographic - order (i.e.: sort on the real part with ties broken according to - the imaginary part) or on the absolute values; -
    5. -
    6. The routines return the items in the chosen ordering; the - output difference is the handling of ties (i.e. items with an - equal value) in the original input. With the merge-sort algorithm - ties are preserved in the same relative order as they had in the - original sequence, while this is not guaranteed for quicksort or - heapsort; -
    7. -
    8. If -$flag = psb\_sort\_ovw\_idx\_$ then the entries in $ix(1:n)$ - where $n$ is the size of $x$ are initialized to -$ix(i) \leftarrow
-i$; thus, upon return from the subroutine, for each - index $i$ we have in $ix(i)$ the position that the item $x(i)$ - occupied in the original data sequence; -
    9. -
    10. If -$flag = psb\_sort\_keep\_idx\_$ the routine will assume that - the entries in $ix(:)$ have already been initialized by the user; -
    11. -
    12. The three sorting algorithms have a similar $O(n \log n)$ expected - running time; in the average case quicksort will be the - fastest and merge-sort the slowest. However note that: - -
        -
      1. The worst case running time for quicksort is $O(n^2)$; the algorithm - implemented here follows the well-known median-of-three heuristics, - but the worst case may still apply; -
      2. -
      3. The worst case running time for merge-sort and heap-sort is - $O(n \log n)$ as the average case; -
      4. -
      5. The merge-sort algorithm is implemented to take advantage of - subsequences that may be already in the desired ordering prior to - the subroutine call; this situation is relatively common when - dealing with groups of indices of sparse matrix entries, thus - merge-sort is the preferred choice when a sorting is needed - by other routines in the library. -
      6. -
      +
    13. Otherwise the size of ovrel will be exactly equal to the + number of overlap elements.

    - -

    - -

    - +

    diff --git a/docs/html/node99.html b/docs/html/node99.html index 24fa37b80..57f6c73e4 100644 --- a/docs/html/node99.html +++ b/docs/html/node99.html @@ -3,8 +3,8 @@ -Parallel environment routines - +psb_sp_getrow -- Extract row(s) from a sparse matrix + @@ -14,93 +14,243 @@ - - - + + + -

    - -
    -Parallel environment routines -

    +

    +psb_sp_getrow -- Extract row(s) from a sparse + matrix +

    -


    - -Subsections +
    +call psb_sp_getrow(row, a, nz, ia, ja, val, info, &
    +              & append, nzin, lrw)
    +
    - - -

    +

    +

    +
    Type:
    +
    Asynchronous. +
    +
    On Entry
    +
    +
    +
    row
    +
    The (first) row to be extracted. +
    +Scope:local +
    +Type:required +
    +Intent: in. +
    +Specified as: an integer $>0$. +
    +
    a
    +
    the matrix from which to get rows. +
    +Scope:local +
    +Type:required +
    +Intent: in. +
    +Specified as: a structured data of type spdatapsb_Tspmat_type. +
    +
    append
    +
    Whether to append or overwrite existing output. +
    +Scope:local +
    +Type:optional +
    +Intent: in. +
    +Specified as: a logical value default: false (overwrite). +
    +
    nzin
    +
    Input size to be appended to. +
    +Scope:local +
    +Type:optional +
    +Intent: in. +
    +Specified as: an integer $>0$. When append is true, specifies how many +entries in the output vectors are already filled. +
    +
    lrw
    +
    The last row to be extracted. +
    +Scope:local +
    +Type:optional +
    +Intent: in. +
    +Specified as: an integer $>0$, default: $row$. + +

    +

    +
    + +

    +

    +
    On Return
    +
    +
    +
    nz
    +
    the number of elements returned by this call. +
    +Scope:local. +
    +Type:required. +
    +Intent: out. +
    +Returned as: an integer scalar. +
    +
    ia
    +
    the row indices. +
    +Scope:local. +
    +Type:required. +
    +Intent: inout. +
    +Specified as: an integer array with the ALLOCATABLE attribute. +
    +
    ja
    +
    the column indices of the elements to be inserted. +
    +Scope:local. +
    +Type:required. +
    +Intent: inout. +
    +Specified as: an integer array with the ALLOCATABLE attribute. +
    +
    val
    +
    the elements to be inserted. +
    +Scope:local. +
    +Type:required. +
    +Intent: inout. +
    +Specified as: a real array with the ALLOCATABLE attribute. +
    +
    info
    +
    Error code. +
    +Scope: local +
    +Type: required +
    +Intent: out. +
    +An integer value; 0 means no error has been detected. +
    +
    + +

    +Notes + +

      +
    1. The output $nz$ is always the size of the output generated by + the current call; thus, if append=.true., the total output + size will be $nzin+nz$, with the newly extracted coefficients stored in + entries nzin+1:nzin+nz of the array arguments; +
    2. +
    3. When append=.true. the output arrays are reallocated as + necessary; +
    4. +
    5. The row and column indices are returned in the local numbering + scheme; if the global numbering is desired, the user may employ the + psb_loc_to_glob routine on the output. +
    6. +
    + +

    + +

    + diff --git a/docs/html/userhtml.html b/docs/html/userhtml.html index e3200a830..cccebd92f 100644 --- a/docs/html/userhtml.html +++ b/docs/html/userhtml.html @@ -20,18 +20,18 @@ @@ -61,345 +61,351 @@ Dec 1st, 2018