From 492ae602f2399c550645b8b30eb59fe9b14e0996 Mon Sep 17 00:00:00 2001 From: Fabio Durastante Date: Fri, 23 Jan 2026 14:29:21 +0100 Subject: [PATCH] Added interface for smoother build. Improved options for preconditioner. There is still a memory error. --- cbind/amgprec/amg_c_dprec.h | 1 + cbind/amgprec/amg_c_zprec.h | 28 ++++--- cbind/amgprec/amg_dprec_cbind_mod.F90 | 114 ++++++++++++++++++++++++++ cbind/amgprec/amg_zprec_cbind_mod.F90 | 108 ++++++++++++++++++++++++ cbind/test/pargen/amgecgpu.c | 48 +++++++---- 5 files changed, 272 insertions(+), 27 deletions(-) diff --git a/cbind/amgprec/amg_c_dprec.h b/cbind/amgprec/amg_c_dprec.h index d1297a80..14126228 100644 --- a/cbind/amgprec/amg_c_dprec.h +++ b/cbind/amgprec/amg_c_dprec.h @@ -26,6 +26,7 @@ extern "C" { psb_i_t amg_c_dprecbld(psb_c_dspmat *ah, psb_c_descriptor *cdh, amg_c_dprec *ph); psb_i_t amg_c_dhierarchy_build(psb_c_dspmat *ah, psb_c_descriptor *cdh, amg_c_dprec *ph); psb_i_t amg_c_dsmoothers_build(psb_c_dspmat *ah, psb_c_descriptor *cdh, amg_c_dprec *ph); + psb_i_t amg_c_dsmoothers_build_opt(psb_c_dspmat *ah, psb_c_descriptor *cdh, amg_c_dprec *ph, const char *afmt, const char *chfmt); psb_i_t amg_c_dprecapply(amg_c_dprec *ph, psb_c_dvector *x, psb_c_dvector *b, psb_c_descriptor *cdh); psb_i_t amg_c_dprecapply_opt(amg_c_dprec *ph, psb_c_dvector *x, psb_c_dvector *b, psb_c_descriptor *cdh, const char *ctrans); psb_i_t amg_c_dprecfree(amg_c_dprec *ph); diff --git a/cbind/amgprec/amg_c_zprec.h b/cbind/amgprec/amg_c_zprec.h index d3882484..38c36035 100644 --- a/cbind/amgprec/amg_c_zprec.h +++ b/cbind/amgprec/amg_c_zprec.h @@ -10,15 +10,17 @@ /* Note: amg_get_XXX_handle returns: <= 0 unsuccessful */ /* >0 valid handle */ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - typedef struct AMG_C_ZPREC { + typedef struct AMG_C_ZPREC + { void *dprec; - } amg_c_zprec; - - amg_c_zprec* amg_c_zprec_new(); - psb_i_t amg_c_zprec_delete(amg_c_zprec* p); - + } amg_c_zprec; + + amg_c_zprec *amg_c_zprec_new(); + psb_i_t amg_c_zprec_delete(amg_c_zprec *p); + psb_i_t amg_c_zprecinit(psb_c_ctxt cctxt, amg_c_zprec *ph, const char *ptype); psb_i_t amg_c_zprecseti(amg_c_zprec *ph, const char *what, psb_i_t val); psb_i_t amg_c_zprecsetc(amg_c_zprec *ph, const char *what, const char *val); @@ -26,19 +28,19 @@ extern "C" { psb_i_t amg_c_zprecbld(psb_c_zspmat *ah, psb_c_descriptor *cdh, amg_c_zprec *ph); psb_i_t amg_c_zhierarchy_build(psb_c_zspmat *ah, psb_c_descriptor *cdh, amg_c_zprec *ph); psb_i_t amg_c_zsmoothers_build(psb_c_zspmat *ah, psb_c_descriptor *cdh, amg_c_zprec *ph); + psb_i_t amg_c_zsmoothers_build_opt(psb_c_zspmat *ah, psb_c_descriptor *cdh, amg_c_zprec *ph, const char *afmt, const char *chfmt); psb_i_t amg_c_zprecapply(amg_c_zprec *ph, psb_c_zvector *x, psb_c_zvector *b, psb_c_descriptor *cdh); psb_i_t amg_c_zprecapply_opt(amg_c_zprec *ph, psb_c_zvector *x, psb_c_zvector *b, psb_c_descriptor *cdh, const char *ctrans); psb_i_t amg_c_zprecfree(amg_c_zprec *ph); - psb_i_t amg_c_zprecbld_opt(psb_c_zspmat *ah, psb_c_descriptor *cdh, - amg_c_zprec *ph, const char *afmt); + psb_i_t amg_c_zprecbld_opt(psb_c_zspmat *ah, psb_c_descriptor *cdh, + amg_c_zprec *ph, const char *afmt); psb_i_t amg_c_zdescr(amg_c_zprec *ph); psb_i_t amg_c_zallocate_wrk(amg_c_zprec *ph, const char *chfmt); - psb_i_t amg_c_zkrylov(const char *method, psb_c_zspmat *ah, amg_c_zprec *ph, - psb_c_zvector *bh, psb_c_zvector *xh, - psb_c_descriptor *cdh, psb_c_SolverOptions *opt); - + psb_i_t amg_c_zkrylov(const char *method, psb_c_zspmat *ah, amg_c_zprec *ph, + psb_c_zvector *bh, psb_c_zvector *xh, + psb_c_descriptor *cdh, psb_c_SolverOptions *opt); #ifdef __cplusplus } diff --git a/cbind/amgprec/amg_dprec_cbind_mod.F90 b/cbind/amgprec/amg_dprec_cbind_mod.F90 index b2fe6a0a..29a66067 100644 --- a/cbind/amgprec/amg_dprec_cbind_mod.F90 +++ b/cbind/amgprec/amg_dprec_cbind_mod.F90 @@ -245,6 +245,120 @@ contains return end function amg_c_dsmoothers_build + function amg_c_dsmoothers_build_format(ah,cdh,ph,afmt,cdfmt) bind(c) result(res) +#if defined (PSB_HAVE_CUDA) + use psb_cuda_mod +#endif + implicit none + + integer(psb_c_ipk_) :: res + type(psb_c_object_type) :: ph,ah,cdh + type(amg_dprec_type), pointer :: precp + type(psb_dspmat_type), pointer :: ap + type(psb_desc_type), pointer :: descp + character(c_char) :: afmt(*), cdfmt(*) + character(len=80) :: fptype + integer(psb_ipk_) :: iret + ! Local variables for formats + character(len=10) :: fafmt, fcdfmt +#if defined (PSB_HAVE_CUDA) + type(psb_d_vect_cuda), target :: dvgpu + type(psb_i_vect_cuda), target :: ivgpu + ! GPU matrix molds + type(psb_d_cuda_hlg_sparse_mat), target :: ahlg + type(psb_d_cuda_hdiag_sparse_mat), target :: ahdiag + type(psb_d_cuda_csrg_sparse_mat), target :: acsrg + type(psb_d_cuda_elg_sparse_mat), target :: aelg +#endif + type(psb_d_base_vect_type), target :: dvhost + type(psb_i_base_vect_type), target :: ivhost + ! CPU matrix molds + type(psb_d_ell_sparse_mat), target :: aell + type(psb_d_csr_sparse_mat), target :: acsr + type(psb_d_coo_sparse_mat), target :: acoo + type(psb_d_hll_sparse_mat), target :: ahll + type(psb_d_hdia_sparse_mat), target :: ahdia + type(psb_d_dns_sparse_mat), target :: adns + + ! molding variables + class(psb_d_base_vect_type), pointer :: vmold + class(psb_d_base_sparse_mat), pointer :: amold + class(psb_i_base_vect_type), pointer :: imold + + + res = -1 + + if (c_associated(cdh%item)) then + call c_f_pointer(cdh%item,descp) + else + return + end if + if (c_associated(ah%item)) then + call c_f_pointer(ah%item,ap) + else + return + end if + if (c_associated(ph%item)) then + call c_f_pointer(ph%item,precp) + else + return + end if + ! Convert formats + call psb_stringc2f(afmt,fafmt) + call psb_stringc2f(cdfmt,fcdfmt) + ! Select matrix mold + select case (psb_toupper(fafmt)) +#if defined (PSB_HAVE_CUDA) + case('CSRG') + amold => acsrg + case('ELG') + amold => aelg + case('HLG') + amold => ahlg + case('HDIAG') + amold => ahdiag +#endif + case('CSR') + amold => acsr + case('ELL') + amold => aell + case('COO') + amold => acoo + case('HLL') + amold => ahll + case('HDIA') + amold => ahdia + case('DNS') + amold => adns + case default + write(psb_err_unit,'(A)') 'amg_c_dsmoothers_build_format: Unknown format ', fafmt, ' defaulting to CSR' + amold => acsr + end select + ! Select vector mold + select case (psb_toupper(fcdfmt)) +#if defined (PSB_HAVE_CUDA) + case('GPU','DEVICE') + vmold => dvgpu + imold => ivgpu +#endif + case('HOST','CPU') + vmold => dvhost + imold => ivhost + case default + write(psb_err_unit,'(A)') 'amg_c_dsmoothers_build_format: Unknown format ', fcdfmt, ' defaulting to HOST/CPU' + vmold => dvhost + imold => ivhost + end select + + + call precp%smoothers_build(ap,descp,iret,amold=amold,vmold=vmold,imold=imold) + + res = MLDC_ERR_FILTER(iret) + MLDC_ERR_HANDLE(res) + + return + end function amg_c_dsmoothers_build_format + function amg_c_dkrylov(methd,& & ah,ph,bh,xh,cdh,options) bind(c) result(res) use psb_base_mod diff --git a/cbind/amgprec/amg_zprec_cbind_mod.F90 b/cbind/amgprec/amg_zprec_cbind_mod.F90 index 33edca8d..607bed6d 100644 --- a/cbind/amgprec/amg_zprec_cbind_mod.F90 +++ b/cbind/amgprec/amg_zprec_cbind_mod.F90 @@ -246,6 +246,114 @@ contains return end function amg_c_zsmoothers_build + function amg_c_zsmoothers_build_format(ah,cdh,ph,afmt,cdfmt) bind(c) result(res) +#if defined (PSB_HAVE_CUDA) + use psb_cuda_mod +#endif + implicit none + + integer(psb_c_ipk_) :: res + type(psb_c_object_type) :: ph,ah,cdh + type(amg_zprec_type), pointer :: precp + type(psb_zspmat_type), pointer :: ap + type(psb_desc_type), pointer :: descp + character(c_char) :: afmt(*), cdfmt(*) + character(len=80) :: fptype + integer(psb_ipk_) :: iret + ! Local variables for formats + character(len=10) :: fafmt, fcdfmt +#if defined (PSB_HAVE_CUDA) + type(psb_z_vect_cuda), target :: dvgpu + type(psb_i_vect_cuda), target :: ivgpu + ! GPU matrix molds + type(psb_z_cuda_hlg_sparse_mat), target :: ahlg + type(psb_z_cuda_csrg_sparse_mat), target :: acsrg + type(psb_z_cuda_elg_sparse_mat), target :: aelg +#endif + type(psb_z_base_vect_type), target :: dvhost + type(psb_i_base_vect_type), target :: ivhost + ! CPU matrix molds + type(psb_z_ell_sparse_mat), target :: aell + type(psb_z_csr_sparse_mat), target :: acsr + type(psb_z_coo_sparse_mat), target :: acoo + type(psb_z_hll_sparse_mat), target :: ahll + type(psb_z_dns_sparse_mat), target :: adns + + ! molding variables + class(psb_z_base_vect_type), pointer :: vmold + class(psb_z_base_sparse_mat), pointer :: amold + class(psb_i_base_vect_type), pointer :: imold + + + res = -1 + + if (c_associated(cdh%item)) then + call c_f_pointer(cdh%item,descp) + else + return + end if + if (c_associated(ah%item)) then + call c_f_pointer(ah%item,ap) + else + return + end if + if (c_associated(ph%item)) then + call c_f_pointer(ph%item,precp) + else + return + end if + ! Convert formats + call psb_stringc2f(afmt,fafmt) + call psb_stringc2f(cdfmt,fcdfmt) + ! Select matrix mold + select case (psb_toupper(fafmt)) +#if defined (PSB_HAVE_CUDA) + case('CSRG') + amold => acsrg + case('ELG') + amold => aelg + case('HLG') + amold => ahlg +#endif + case('CSR') + amold => acsr + case('ELL') + amold => aell + case('COO') + amold => acoo + case('HLL') + amold => ahll + case('DNS') + amold => adns + case default + write(psb_err_unit,'(A)') 'amg_c_dsmoothers_build_format: Unknown format ', fafmt, ' defaulting to CSR' + amold => acsr + end select + ! Select vector mold + select case (psb_toupper(fcdfmt)) +#if defined (PSB_HAVE_CUDA) + case('GPU','DEVICE') + vmold => dvgpu + imold => ivgpu +#endif + case('HOST','CPU') + vmold => dvhost + imold => ivhost + case default + write(psb_err_unit,'(A)') 'amg_c_dsmoothers_build_format: Unknown format ', fcdfmt, ' defaulting to HOST/CPU' + vmold => dvhost + imold => ivhost + end select + + + call precp%smoothers_build(ap,descp,iret,amold=amold,vmold=vmold,imold=imold) + + res = MLDC_ERR_FILTER(iret) + MLDC_ERR_HANDLE(res) + + return + end function amg_c_zsmoothers_build_format + function amg_c_zkrylov(methd,& & ah,ph,bh,xh,cdh,options) bind(c) result(res) use psb_linsolve_mod diff --git a/cbind/test/pargen/amgecgpu.c b/cbind/test/pargen/amgecgpu.c index 708d0be3..5f7389f5 100644 --- a/cbind/test/pargen/amgecgpu.c +++ b/cbind/test/pargen/amgecgpu.c @@ -496,10 +496,26 @@ int main(int argc, char *argv[]) amg_c_dprecseti(ph, "SMOOTHER_SWEEPS", 2); amg_c_dprecsetc(ph, "COARSE_SOLVE", "BJAC"); amg_c_dprecsetc(ph, "COARSE_SUBSOLVE", "L1-JACOBI"); - if ((ret = amg_c_dhierarchy_build(ah, cdh, ph)) != 0) + amg_c_dprecsetc(ph, "AGGR_FILTER", "FILTER"); + if ((ret = amg_c_dhierarchy_build(ah, cdh, ph)) != 0){ fprintf(stderr, "From hierarchy_build: %d\n", ret); + }{ + if (iam == 0) { + fprintf(stdout, "Hierarchy built\n"); + } + } +#if defined (PSB_HAVE_CUDA) + if ((ret = amg_c_dsmoothers_build_format(ah, cdh, ph, afmt, cdfmt)) != 0) + fprintf(stderr, "From smoothers_build_format: %d\n", ret); +#else if ((ret = amg_c_dsmoothers_build(ah, cdh, ph)) != 0) fprintf(stderr, "From smoothers_build: %d\n", ret); +#endif + if ( ret == 0){ + if (iam == 0) { + fprintf(stdout, "Smoothers built\n"); + } + } #ifdef PSB_HAVE_CUDA /* Allocate work vectors for the preconditioner on the GPU */ @@ -508,24 +524,28 @@ int main(int argc, char *argv[]) { fprintf(stderr, "From dallocate_wrk: %d\nBailing out\n", info); psb_c_abort(*cctxt); + } else { + if (iam == 0) { + fprintf(stdout, "Preconditioner work vectors allocated\n"); + } } #endif psb_c_barrier(*cctxt); /* Do a dry run of the preconditioner */ - info = amg_c_dprecapply(ph, bh, xh, cdh); - if (info != 0) - { - fprintf(stderr, "From dprec_apply: %d\nBailing out\n", info); - psb_c_abort(*cctxt); - } - /* Do a dry run of the preconditioner with the option routine */ - info = amg_c_dprecapply_opt(ph, bh, xh, cdh, "N"); - if (info != 0) - { - fprintf(stderr, "From dprec_apply_opt: %d\nBailing out\n", info); - psb_c_abort(*cctxt); - } + // info = amg_c_dprecapply(ph, bh, xh, cdh); + // if (info != 0) + // { + // fprintf(stderr, "From dprec_apply: %d\nBailing out\n", info); + // psb_c_abort(*cctxt); + // } + // /* Do a dry run of the preconditioner with the option routine */ + // info = amg_c_dprecapply_opt(ph, bh, xh, cdh, "N"); + // if (info != 0) + // { + // fprintf(stderr, "From dprec_apply_opt: %d\nBailing out\n", info); + // psb_c_abort(*cctxt); + // } /* info = amg_c_dprecapply_opt(ph,bh,xh,cdh,"T"); if (info != 0) {