diff --git a/CHANGELOG b/CHANGELOG index 82ae1c06e6..b1586ef5b2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,22 @@ # This file chronicles user-level changes, beginning with the most recent. # ============================================================================= +Version 2.30.0 released 2023/11/06 + +- Added FSAI support with CUDA and HIP +- Added MAGMA option to FSAI +- Added Binary I/O functions for IJ matrices and vectors +- Added a convergent l1-hybrid symmetric Gauss-Seidel smoother to BoomerAMG +- Added CUDA support to dense direct solver options in BoomerAMG and MGR +- Added SYCL support for triangular solves (enabling Gauss-Seidel, ILU, etc.) + and Chebyshev relaxation +- Improved MGR statistics and data printing +- Added CG options to ignore errors, and added a flexible CG version +- Added superlu_dist support on GPUs +- Various bug fixes + +#==================================== + Version 2.29.0 released 2023/06/22 - Added ILU support for AMD GPUs diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 00322ba6bd..8ab89c2e3c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,9 +12,9 @@ else () endif () # The version number. -set(HYPRE_VERSION 2.29.0) -set(HYPRE_NUMBER 22900) -set(HYPRE_DATE 2023/06/22) +set(HYPRE_VERSION 2.30.0) +set(HYPRE_NUMBER 23000) +set(HYPRE_DATE 2023/11/06) set(HYPRE_TIME 00:00:00) set(HYPRE_BUGS https://github.com/hypre-space/hypre/issues) set(HYPRE_SRCDIR "${PROJECT_SOURCE_DIR}") diff --git a/src/config/configure.in b/src/config/configure.in index ee518795eb..1719f9b85e 100644 --- a/src/config/configure.in +++ b/src/config/configure.in @@ -48,9 +48,9 @@ dnl * Set package information so it only has to be modified in one place dnl ********************************************************************* m4_define([M4_HYPRE_NAME], [hypre]) -m4_define([M4_HYPRE_VERSION], [2.29.0]) -m4_define([M4_HYPRE_NUMBER], [22900]) -m4_define([M4_HYPRE_DATE], [2023/06/22]) +m4_define([M4_HYPRE_VERSION], [2.30.0]) +m4_define([M4_HYPRE_NUMBER], [23000]) +m4_define([M4_HYPRE_DATE], [2023/11/06]) m4_define([M4_HYPRE_TIME], [00:00:00]) m4_define([M4_HYPRE_BUGS], [https://github.com/hypre-space/hypre/issues]) m4_define([M4_HYPRE_SRCDIR], [`pwd`]) diff --git a/src/config/version.sh b/src/config/version.sh index 40ceea3b31..28cedd003a 100755 --- a/src/config/version.sh +++ b/src/config/version.sh @@ -4,8 +4,8 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) -hypre_version="2.29.0" -hypre_reldate="2023/06/22" +hypre_version="2.30.0" +hypre_reldate="2023/11/06" hypre_major=`echo $hypre_version | cut -d. -f 1` hypre_minor=`echo $hypre_version | cut -d. -f 2` diff --git a/src/configure b/src/configure index 6293b1d92c..c3948cc2e2 100755 --- a/src/configure +++ b/src/configure @@ -1,7 +1,7 @@ #! /bin/sh # From configure.in Id. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for hypre 2.29.0. +# Generated by GNU Autoconf 2.71 for hypre 2.30.0. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, @@ -612,8 +612,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='hypre' PACKAGE_TARNAME='hypre' -PACKAGE_VERSION='2.29.0' -PACKAGE_STRING='hypre 2.29.0' +PACKAGE_VERSION='2.30.0' +PACKAGE_STRING='hypre 2.30.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1474,7 +1474,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures hypre 2.29.0 to adapt to many kinds of systems. +\`configure' configures hypre 2.30.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1540,7 +1540,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of hypre 2.29.0:";; + short | recursive ) echo "Configuration of hypre 2.30.0:";; esac cat <<\_ACEOF @@ -1907,7 +1907,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -hypre configure 2.29.0 +hypre configure 2.30.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2252,7 +2252,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by hypre $as_me 2.29.0, which was +It was created by hypre $as_me 2.30.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3233,9 +3233,9 @@ ac_config_headers="$ac_config_headers HYPRE_config.h:config/HYPRE_config.h.in" HYPRE_NAME="hypre" -HYPRE_VERSION="2.29.0" -HYPRE_NUMBER=22900 -HYPRE_DATE="2023/06/22" +HYPRE_VERSION="2.30.0" +HYPRE_NUMBER=23000 +HYPRE_DATE="2023/11/06" HYPRE_TIME="00:00:00" HYPRE_BUGS="https://github.com/hypre-space/hypre/issues" HYPRE_SRCDIR="`pwd`" @@ -11892,7 +11892,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by hypre $as_me 2.29.0, which was +This file was extended by hypre $as_me 2.30.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -11956,7 +11956,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -hypre config.status 2.29.0 +hypre config.status 2.30.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/src/docs/ref-manual/conf.doxygen b/src/docs/ref-manual/conf.doxygen index ba8409eb88..761dc19969 100644 --- a/src/docs/ref-manual/conf.doxygen +++ b/src/docs/ref-manual/conf.doxygen @@ -48,7 +48,7 @@ PROJECT_NAME = hypre # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 2.29.0 +PROJECT_NUMBER = 2.30.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/src/docs/usr-manual/conf.py b/src/docs/usr-manual/conf.py index 08084e6841..5e58314ca4 100644 --- a/src/docs/usr-manual/conf.py +++ b/src/docs/usr-manual/conf.py @@ -70,9 +70,9 @@ # built documents. # # The short X.Y version. -version = '2.29.0' +version = '2.30.0' # The full version, including alpha/beta/rc tags. -release = '2.29.0' +release = '2.30.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -80,7 +80,7 @@ # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -today = 'June 22, 2023' +today = 'November 06, 2023' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' diff --git a/src/krylov/HYPRE_krylov.h b/src/krylov/HYPRE_krylov.h index 9a026e2d23..6cc13190ee 100644 --- a/src/krylov/HYPRE_krylov.h +++ b/src/krylov/HYPRE_krylov.h @@ -279,7 +279,7 @@ HYPRE_Int HYPRE_PCGGetRelChange(HYPRE_Solver solver, /** **/ HYPRE_Int HYPRE_PCGGetSkipBreak(HYPRE_Solver solver, - HYPRE_Int *skip_break); + HYPRE_Int *skip_break); /** **/ diff --git a/src/krylov/HYPRE_pcg.c b/src/krylov/HYPRE_pcg.c index 36757fdab2..6756b8e461 100644 --- a/src/krylov/HYPRE_pcg.c +++ b/src/krylov/HYPRE_pcg.c @@ -252,14 +252,14 @@ HYPRE_PCGGetRecomputeResidualP( HYPRE_Solver solver, HYPRE_Int HYPRE_PCGSetSkipBreak( HYPRE_Solver solver, - HYPRE_Int skip_break ) + HYPRE_Int skip_break ) { return ( hypre_PCGSetSkipBreak( (void *) solver, skip_break ) ); } HYPRE_Int HYPRE_PCGGetSkipBreak( HYPRE_Solver solver, - HYPRE_Int *skip_break ) + HYPRE_Int *skip_break ) { return ( hypre_PCGGetSkipBreak( (void *) solver, skip_break ) ); } diff --git a/src/krylov/pcg.c b/src/krylov/pcg.c index e04612003f..1b4f93b332 100644 --- a/src/krylov/pcg.c +++ b/src/krylov/pcg.c @@ -588,44 +588,44 @@ hypre_PCGSolve( void *pcg_vdata, /* alpha should always be greater zero for spd A, spd precond. and nonzero p, r*/ /* alpha = / */ /* for alpha close to 0 x and r will not change much unless x and/or r are close to 0 */ - if (alpha <=0.0) + if (alpha <= 0.0) { if (print_level > 1 && my_id == 0) - { + { hypre_printf("alpha %e", alpha); - } + } hypre_error_w_msg(HYPRE_ERROR_CONV, "Negative or zero alpha value in PCG"); if (skip_break < 3) - { - if (i == 1) { i_prod = i_prod_0; } + { + if (i == 1) { i_prod = i_prod_0; } break; - } + } } else if (! (alpha >= HYPRE_REAL_TRUE_MIN)) { hypre_error_w_msg(HYPRE_ERROR_CONV, "alpha value less than TRUE_MIN in PCG"); if (print_level > 1 && my_id == 0) - { + { hypre_printf("alpha %e", alpha); - } + } if (skip_break < 2) - { - if (i == 1) { i_prod = i_prod_0; } + { + if (i == 1) { i_prod = i_prod_0; } break; - } + } } else if (! (alpha >= HYPRE_REAL_MIN)) { hypre_error_w_msg(HYPRE_ERROR_CONV, "Subnormal alpha value in PCG"); if (print_level > 1 && my_id == 0) - { + { hypre_printf("alpha %e", alpha); - } + } if (skip_break < 1) - { - if (i == 1) { i_prod = i_prod_0; } + { + if (i == 1) { i_prod = i_prod_0; } break; - } + } } gamma_old = gamma; @@ -633,9 +633,9 @@ hypre_PCGSolve( void *pcg_vdata, /* x = x + alpha*p */ (*(pcg_functions->Axpy))(alpha, p, x); - if (flex) + if (flex) { - (*(pcg_functions->CopyVector))(r, r_old); /*save old residual */ + (*(pcg_functions->CopyVector))(r, r_old); /*save old residual */ } /* r = r - alpha*s */ @@ -650,9 +650,9 @@ hypre_PCGSolve( void *pcg_vdata, hypre_printf("Recomputing the residual...\n"); } (*(pcg_functions->CopyVector))(r, s); /*save old residual */ - if (flex) + if (flex) { - (*(pcg_functions->CopyVector))(r, r_old); /*save old residual */ + (*(pcg_functions->CopyVector))(r, r_old); /*save old residual */ } (*(pcg_functions->CopyVector))(b, r); (*(pcg_functions->Matvec))(matvec_data, -1.0, A, x, 1.0, r); @@ -661,7 +661,7 @@ hypre_PCGSolve( void *pcg_vdata, /* compute s = r_old-r_new */ (*(pcg_functions->Axpy))(-1.0, s, r); if (two_norm) - /* residual-based stopping criteria: ||r_new-r_old|| < rtol ||b|| */ + /* residual-based stopping criteria: ||r_new-r_old|| < rtol ||b|| */ { HYPRE_Real drob2 = (*(pcg_functions->InnerProd))(s, s) / bi_prod; if ( drob2 < rtol * rtol ) @@ -673,8 +673,8 @@ hypre_PCGSolve( void *pcg_vdata, break; } } - else - /* residual-based stopping criteria: ||r_new-r_old||_C < rtol ||b||_C */ + else + /* residual-based stopping criteria: ||r_new-r_old||_C < rtol ||b||_C */ { HYPRE_Real r2ob2; /* v = C*s = C*(r_old-r_new) */ @@ -801,7 +801,7 @@ hypre_PCGSolve( void *pcg_vdata, } if ( tentatively_converged && recompute_residual ) /* At user request, don't trust the convergence test until we've recomputed - the residual from scratch. This is expensive in the usual case where + the residual from scratch. This is expensive in the usual case where the norm is the energy norm. This calculation is coded on the assumption that r's accuracy is only a concern for problems where CG takes many iterations. */ @@ -842,44 +842,44 @@ hypre_PCGSolve( void *pcg_vdata, break; } /* gamma should generally be greater than 0 for spd prec and nonzero r */ - if (gamma <=0.0) + if (gamma <= 0.0) { if (print_level > 1 && my_id == 0) - { + { hypre_printf("gamma %e", gamma); - } + } hypre_error_w_msg(HYPRE_ERROR_CONV, "Negative or zero gamma value in PCG"); if (skip_break < 3) - { - if (i == 1) { i_prod = i_prod_0; } + { + if (i == 1) { i_prod = i_prod_0; } break; - } + } } else if (! (gamma >= HYPRE_REAL_TRUE_MIN)) { hypre_error_w_msg(HYPRE_ERROR_CONV, "gamma value less than TRUE_MIN in PCG"); if (print_level > 1 && my_id == 0) - { + { hypre_printf("gamma %e", gamma); - } + } if (skip_break < 2) - { - if (i == 1) { i_prod = i_prod_0; } + { + if (i == 1) { i_prod = i_prod_0; } break; - } + } } else if (! (gamma >= HYPRE_REAL_MIN)) { hypre_error_w_msg(HYPRE_ERROR_CONV, "Subnormal gamma value in PCG"); if (print_level > 1 && my_id == 0) - { + { hypre_printf("gamma %e", gamma); - } + } if (skip_break < 1) - { - if (i == 1) { i_prod = i_prod_0; } + { + if (i == 1) { i_prod = i_prod_0; } break; - } + } } /* ... gamma should be >=0. IEEE subnormal numbers are < 2**(-1022)=2.2e-308 (and >= 2**(-1074)=4.9e-324). So a gamma this small means we're getting @@ -902,41 +902,41 @@ hypre_PCGSolve( void *pcg_vdata, enough to pass the convergence test. Therefore initial guess was good, and we're just calculating garbage - time to bail out before the next step, which will be a divide by zero (or close to it). */ - if (i_prod_0 <=0.0) + if (i_prod_0 <= 0.0) { if (print_level > 1 && my_id == 0) - { + { hypre_printf("i_prod_0 %e", i_prod_0); - } + } hypre_error_w_msg(HYPRE_ERROR_CONV, "Negative or zero i_prod_0 value in PCG"); if (skip_break < 3) - { + { break; - } + } } else if (! (i_prod_0 >= HYPRE_REAL_TRUE_MIN)) { hypre_error_w_msg(HYPRE_ERROR_CONV, "i_prod_0 value less than TRUE_MIN in PCG"); if (print_level > 1 && my_id == 0) - { + { hypre_printf("i_prod_0 %e", i_prod_0); - } + } if (skip_break < 2) - { + { break; - } + } } else if (! (i_prod_0 >= HYPRE_REAL_MIN)) { hypre_error_w_msg(HYPRE_ERROR_CONV, "Subnormal i_prod_0 value in PCG"); if (print_level > 1 && my_id == 0) - { + { hypre_printf("i_prod_0 %e", i_prod_0); - } + } if (skip_break < 1) - { + { break; - } + } } cf_ave_1 = hypre_pow( i_prod / i_prod_0, 1.0 / (2.0 * i) ); @@ -956,13 +956,13 @@ hypre_PCGSolve( void *pcg_vdata, /* beta = gamma / gamma_old */ if (!flex) - { + { beta = gamma / gamma_old; - } + } else - { + { beta = delta / gamma_old; - } + } /* p = s + beta p */ if ( !recompute_true_residual ) @@ -1307,7 +1307,7 @@ hypre_PCGGetStopCrit( void *pcg_vdata, HYPRE_Int hypre_PCGSetSkipBreak( void *pcg_vdata, - HYPRE_Int skip_break ) + HYPRE_Int skip_break ) { hypre_PCGData *pcg_data = (hypre_PCGData *)pcg_vdata; @@ -1319,7 +1319,7 @@ hypre_PCGSetSkipBreak( void *pcg_vdata, HYPRE_Int hypre_PCGGetSkipBreak( void *pcg_vdata, - HYPRE_Int * skip_break ) + HYPRE_Int * skip_break ) { hypre_PCGData *pcg_data = (hypre_PCGData *)pcg_vdata; @@ -1335,7 +1335,7 @@ hypre_PCGGetSkipBreak( void *pcg_vdata, HYPRE_Int hypre_PCGSetFlex( void *pcg_vdata, - HYPRE_Int flex ) + HYPRE_Int flex ) { hypre_PCGData *pcg_data = (hypre_PCGData *)pcg_vdata; @@ -1347,7 +1347,7 @@ hypre_PCGSetFlex( void *pcg_vdata, HYPRE_Int hypre_PCGGetFlex( void *pcg_vdata, - HYPRE_Int * flex ) + HYPRE_Int * flex ) { hypre_PCGData *pcg_data = (hypre_PCGData *)pcg_vdata; diff --git a/src/parcsr_ls/par_ilu_solve.c b/src/parcsr_ls/par_ilu_solve.c index abcf1f372d..200162afb4 100644 --- a/src/parcsr_ls/par_ilu_solve.c +++ b/src/parcsr_ls/par_ilu_solve.c @@ -815,11 +815,11 @@ hypre_ILUSolveSchurNSH(hypre_ParCSRMatrix *A, * L, D and U factors only have local scope (no off-diagterms) * so apart from the residual calculation (which uses A), * the solves with the L and U factors are local. - * - * Note: perm contains the permutation of indexes corresponding to - * user-prescribed reordering strategy. In the block Jacobi case, perm - * may be NULL if no reordering is done (for performance, (perm == NULL) - * assumes identity mapping of indexes). Hence we need to check the local + * + * Note: perm contains the permutation of indexes corresponding to + * user-prescribed reordering strategy. In the block Jacobi case, perm + * may be NULL if no reordering is done (for performance, (perm == NULL) + * assumes identity mapping of indexes). Hence we need to check the local * solves for this case and avoid segfaults. - DOK *--------------------------------------------------------------------*/ @@ -864,7 +864,7 @@ hypre_ILUSolveLU(hypre_ParCSRMatrix *A, /* L solve - Forward solve */ /* copy rhs to account for diagonal of L (which is identity) */ - if(perm) + if (perm) { for (i = 0; i < nLU; i++) { @@ -880,7 +880,7 @@ hypre_ILUSolveLU(hypre_ParCSRMatrix *A, } /* Update with remaining (off-diagonal) entries of L */ - if(perm) + if (perm) { for ( i = 0; i < nLU; i++ ) { @@ -900,10 +900,10 @@ hypre_ILUSolveLU(hypre_ParCSRMatrix *A, { utemp_data[i] -= L_diag_data[j] * utemp_data[L_diag_j[j]]; } - } + } } /*-------------------- U solve - Backward substitution */ - if(perm) + if (perm) { for ( i = nLU - 1; i >= 0; i-- ) { @@ -931,7 +931,7 @@ hypre_ILUSolveLU(hypre_ParCSRMatrix *A, /* diagonal scaling (contribution from D. Note: D is stored as its inverse) */ utemp_data[i] *= D[i]; - } + } } /* Update solution */ hypre_ParVectorAxpy(beta, utemp, u); @@ -947,11 +947,11 @@ hypre_ILUSolveLU(hypre_ParCSRMatrix *A, * L, D and U factors only have local scope (no off-diag terms) * so apart from the residual calculation (which uses A), the solves * with the L and U factors are local. - * - * Note: perm contains the permutation of indexes corresponding to - * user-prescribed reordering strategy. In the block Jacobi case, perm - * may be NULL if no reordering is done (for performance, (perm == NULL) - * assumes identity mapping of indexes). Hence we need to check the local + * + * Note: perm contains the permutation of indexes corresponding to + * user-prescribed reordering strategy. In the block Jacobi case, perm + * may be NULL if no reordering is done (for performance, (perm == NULL) + * assumes identity mapping of indexes). Hence we need to check the local * solves for this case and avoid segfaults. - DOK *--------------------------------------------------------------------*/ @@ -1004,7 +1004,7 @@ hypre_ILUSolveLUIter(hypre_ParCSRMatrix *A, /* copy rhs to account for diagonal of L (which is identity) */ /* Initialize iteration to 0 */ - if(perm) + if (perm) { for ( i = 0; i < nLU; i++ ) { @@ -1016,7 +1016,7 @@ hypre_ILUSolveLUIter(hypre_ParCSRMatrix *A, for ( i = 0; i < nLU; i++ ) { utemp_data[i] = 0.0; - } + } } /* Jacobi iteration loop */ for ( kk = 0; kk < lower_jacobi_iters; kk++ ) @@ -1024,9 +1024,9 @@ hypre_ILUSolveLUIter(hypre_ParCSRMatrix *A, /* u^{k+1} = f - Lu^k */ /* Do a SpMV with L and save the results in xtemp */ - if(perm) + if (perm) { - for ( i = nLU-1; i >= 0; i-- ) + for ( i = nLU - 1; i >= 0; i-- ) { sum = 0.0; k1 = L_diag_i[i] ; k2 = L_diag_i[i + 1]; @@ -1039,7 +1039,7 @@ hypre_ILUSolveLUIter(hypre_ParCSRMatrix *A, } else { - for ( i = nLU-1; i >= 0; i-- ) + for ( i = nLU - 1; i >= 0; i-- ) { sum = 0.0; k1 = L_diag_i[i] ; k2 = L_diag_i[i + 1]; @@ -1048,12 +1048,12 @@ hypre_ILUSolveLUIter(hypre_ParCSRMatrix *A, sum += L_diag_data[j] * utemp_data[L_diag_j[j]]; } utemp_data[i] = ftemp_data[i] - sum; - } + } } } /* end jacobi loop */ /* Initialize iteration to 0 */ - if(perm) + if (perm) { for ( i = 0; i < nLU; i++ ) { @@ -1074,7 +1074,7 @@ hypre_ILUSolveLUIter(hypre_ParCSRMatrix *A, /* u^{k+1} = f - Uu^k */ /* Do a SpMV with U and save the results in xtemp */ - if(perm) + if (perm) { for ( i = 0; i < nLU; ++i ) { @@ -1098,7 +1098,7 @@ hypre_ILUSolveLUIter(hypre_ParCSRMatrix *A, sum += U_diag_data[j] * ftemp_data[U_diag_j[j]]; } ftemp_data[i] = D[i] * (utemp_data[i] - sum); - } + } } } /* end jacobi loop */