diff --git a/src/parcsr_ls/HYPRE_parcsr_ls.h b/src/parcsr_ls/HYPRE_parcsr_ls.h index 7da26a8c07..67d42b6ada 100644 --- a/src/parcsr_ls/HYPRE_parcsr_ls.h +++ b/src/parcsr_ls/HYPRE_parcsr_ls.h @@ -4279,13 +4279,13 @@ HYPRE_Int HYPRE_MGRSetFSolver(HYPRE_Solver solver, /** * (Optional) Set the F-relaxation solver at a given level. * - * @param level [IN] MGR solver level * @param solver [IN] MGR solver/preconditioner object * @param fsolver [IN] F-relaxation solver object + * @param level [IN] MGR solver level **/ -HYPRE_Int HYPRE_MGRSetFSolverAtLevel(HYPRE_Int level, - HYPRE_Solver solver, - HYPRE_Solver fsolver ); +HYPRE_Int HYPRE_MGRSetFSolverAtLevel(HYPRE_Solver solver, + HYPRE_Solver fsolver, + HYPRE_Int level ); /** * (Optional) Extract A_FF block from matrix A. @@ -4436,12 +4436,59 @@ HYPRE_MGRSetGlobalSmoothType( HYPRE_Solver solver, HYPRE_Int smooth_type ); /** - * (Optional) Determines type of global smoother for each level. - * See \e HYPRE_MGRSetGlobalSmoothType for global smoother options. - **/ + * @brief Sets the type of global smoother for each level in the multigrid reduction (MGR) solver. + * + * This function allows the user to specify the type of global smoother to be used at each level + * of the multigrid reduction process. The types of smoothers available can be found in the + * documentation for \e HYPRE_MGRSetGlobalSmoothType. The smoother type for each level is indicated + * by the \e smooth_type array, which should have a size equal to \e max_num_coarse_levels. + * + * @note This function does not take ownership of the \e smooth_type array. + * @note If \e smooth_type is a NULL pointer, a default global smoother (Jacobi) is used for all levels. + * @note This call is optional. It is intended for advanced users who need specific control over the + * smoothing process at different levels of the solver. If not called, the solver will proceed + * with default smoothing parameters. + * + * @param[in] \e solver The HYPRE solver object to configure. + * @param[in] \e smooth_type An array of integers where each value specifies the type of smoother to + * be used at the corresponding level. + * + * @return HYPRE_Int Error code (0 for success, non-zero for failure). + * + * @see HYPRE_MGRSetGlobalSmoothType for details on global smoother options. + */ + +HYPRE_Int +HYPRE_MGRSetLevelSmoothType(HYPRE_Solver solver, + HYPRE_Int *smooth_type); + +/** + * @brief Sets the global smoother method for a specified MGR level using a HYPRE solver object. + * + * This function enables solvers within hypre to be used as complex smoothers for a specific level + * within the multigrid reduction (MGR) scheme. Users can configure the solver options and pass the + * solver in as the smoother. Currently supported solver options via this interface are ILU and AMG. + * + * @note Unlike some other setup functions that might require an array to set options across multiple + * levels, this function focuses on a single level, identified by the \e level parameter. + * + * @warning The smoother passed to function takes precedence over the smoother type set for that level + * in the MGR hierarchy. + * + * @param[in,out] \e solver A pointer to the MGR solver object. This object is modified to include the + * specified smoother for the given level. + * @param[in] \e smoother The HYPRE solver object that specifies the global relaxation method to be used + * at the specified level. Currently available choices are BoomerAMG and ILU. + * @param[in] \e level The level identifier for which the global relaxation method is to be set. + * Must be within the range of the number of levels in the MGR solver. + * + * @return HYPRE_Int Returns an error code. Success is indicated by 0, while any non-zero value signifies an error. + */ + HYPRE_Int -HYPRE_MGRSetLevelSmoothType( HYPRE_Solver solver, - HYPRE_Int *smooth_type ); +HYPRE_MGRSetGlobalSmootherAtLevel( HYPRE_Solver solver, + HYPRE_Solver smoother, + HYPRE_Int level ); /** * (Optional) Return the number of MGR iterations. diff --git a/src/parcsr_ls/HYPRE_parcsr_mgr.c b/src/parcsr_ls/HYPRE_parcsr_mgr.c index f74e9e10f6..c6d9af426d 100644 --- a/src/parcsr_ls/HYPRE_parcsr_mgr.c +++ b/src/parcsr_ls/HYPRE_parcsr_mgr.c @@ -16,7 +16,7 @@ HYPRE_MGRCreate( HYPRE_Solver *solver ) { if (!solver) { - hypre_error_in_arg(2); + hypre_error_in_arg(1); return hypre_error_flag; } *solver = ( (HYPRE_Solver) hypre_MGRCreate( ) ); @@ -99,7 +99,7 @@ HYPRE_MGRDirectSolverCreate( HYPRE_Solver *solver ) { if (!solver) { - hypre_error_in_arg(2); + hypre_error_in_arg(1); return hypre_error_flag; } *solver = ( (HYPRE_Solver) hypre_MGRDirectSolverCreate( ) ); @@ -211,11 +211,23 @@ HYPRE_MGRSetNonCpointsToFpoints( HYPRE_Solver solver, HYPRE_Int nonCptToFptFlag) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetFSolver(HYPRE_Solver solver, +HYPRE_MGRSetFSolver(HYPRE_Solver solver, HYPRE_PtrToParSolverFcn fine_grid_solver_solve, HYPRE_PtrToParSolverFcn fine_grid_solver_setup, - HYPRE_Solver fsolver ) + HYPRE_Solver fsolver ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + else if (!fsolver) + { + hypre_error_in_arg(4); + return hypre_error_flag; + } + + return ( hypre_MGRSetFSolver( (void *) solver, (HYPRE_Int (*)(void*, void*, void*, void*)) fine_grid_solver_solve, (HYPRE_Int (*)(void*, void*, void*, void*)) fine_grid_solver_setup, @@ -227,13 +239,24 @@ HYPRE_MGRSetFSolver(HYPRE_Solver solver, *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetFSolverAtLevel(HYPRE_Int level, - HYPRE_Solver solver, - HYPRE_Solver fsolver ) +HYPRE_MGRSetFSolverAtLevel(HYPRE_Solver solver, + HYPRE_Solver fsolver, + HYPRE_Int level ) { - return ( hypre_MGRSetFSolverAtLevel( level, - (void *) solver, - (void *) fsolver ) ); + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + else if (!fsolver) + { + hypre_error_in_arg(2); + return hypre_error_flag; + } + + return ( hypre_MGRSetFSolverAtLevel( (void *) solver, + (void *) fsolver, + level ) ); } /*-------------------------------------------------------------------------- @@ -254,11 +277,22 @@ HYPRE_MGRBuildAff(HYPRE_ParCSRMatrix A, *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetCoarseSolver(HYPRE_Solver solver, +HYPRE_MGRSetCoarseSolver(HYPRE_Solver solver, HYPRE_PtrToParSolverFcn coarse_grid_solver_solve, HYPRE_PtrToParSolverFcn coarse_grid_solver_setup, - HYPRE_Solver coarse_grid_solver ) + HYPRE_Solver coarse_grid_solver ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + else if (!coarse_grid_solver) + { + hypre_error_in_arg(4); + return hypre_error_flag; + } + return ( hypre_MGRSetCoarseSolver( (void *) solver, (HYPRE_Int (*)(void*, void*, void*, void*)) coarse_grid_solver_solve, (HYPRE_Int (*)(void*, void*, void*, void*)) coarse_grid_solver_setup, @@ -270,8 +304,15 @@ HYPRE_MGRSetCoarseSolver(HYPRE_Solver solver, *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetMaxCoarseLevels( HYPRE_Solver solver, HYPRE_Int maxlev ) +HYPRE_MGRSetMaxCoarseLevels( HYPRE_Solver solver, + HYPRE_Int maxlev ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetMaxCoarseLevels(solver, maxlev); } @@ -280,8 +321,15 @@ HYPRE_MGRSetMaxCoarseLevels( HYPRE_Solver solver, HYPRE_Int maxlev ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetBlockSize( HYPRE_Solver solver, HYPRE_Int bsize ) +HYPRE_MGRSetBlockSize( HYPRE_Solver solver, + HYPRE_Int bsize ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetBlockSize(solver, bsize ); } @@ -290,10 +338,27 @@ HYPRE_MGRSetBlockSize( HYPRE_Solver solver, HYPRE_Int bsize ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetReservedCoarseNodes( HYPRE_Solver solver, HYPRE_Int reserved_coarse_size, - HYPRE_BigInt *reserved_coarse_indexes ) +HYPRE_MGRSetReservedCoarseNodes( HYPRE_Solver solver, + HYPRE_Int reserved_coarse_size, + HYPRE_BigInt *reserved_coarse_indices ) { - return hypre_MGRSetReservedCoarseNodes(solver, reserved_coarse_size, reserved_coarse_indexes ); + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + else if (reserved_coarse_size < 0) + { + hypre_error_in_arg(2); + return hypre_error_flag; + } + else if (!reserved_coarse_indices) + { + hypre_error_in_arg(3); + return hypre_error_flag; + } + + return hypre_MGRSetReservedCoarseNodes(solver, reserved_coarse_size, reserved_coarse_indices); } /*-------------------------------------------------------------------------- @@ -301,8 +366,15 @@ HYPRE_MGRSetReservedCoarseNodes( HYPRE_Solver solver, HYPRE_Int reserved_coarse_ *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetReservedCpointsLevelToKeep( HYPRE_Solver solver, HYPRE_Int level) +HYPRE_MGRSetReservedCpointsLevelToKeep( HYPRE_Solver solver, + HYPRE_Int level) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetReservedCpointsLevelToKeep((void *) solver, level); } @@ -311,8 +383,15 @@ HYPRE_MGRSetReservedCpointsLevelToKeep( HYPRE_Solver solver, HYPRE_Int level) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetRestrictType(HYPRE_Solver solver, HYPRE_Int restrict_type ) +HYPRE_MGRSetRestrictType(HYPRE_Solver solver, + HYPRE_Int restrict_type ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetRestrictType(solver, restrict_type ); } @@ -321,8 +400,15 @@ HYPRE_MGRSetRestrictType(HYPRE_Solver solver, HYPRE_Int restrict_type ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetLevelRestrictType( HYPRE_Solver solver, HYPRE_Int *restrict_type ) +HYPRE_MGRSetLevelRestrictType( HYPRE_Solver solver, + HYPRE_Int *restrict_type ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetLevelRestrictType( solver, restrict_type ); } @@ -331,8 +417,15 @@ HYPRE_MGRSetLevelRestrictType( HYPRE_Solver solver, HYPRE_Int *restrict_type ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetFRelaxMethod(HYPRE_Solver solver, HYPRE_Int relax_method ) +HYPRE_MGRSetFRelaxMethod( HYPRE_Solver solver, + HYPRE_Int relax_method ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetFRelaxMethod(solver, relax_method ); } @@ -341,8 +434,15 @@ HYPRE_MGRSetFRelaxMethod(HYPRE_Solver solver, HYPRE_Int relax_method ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetLevelFRelaxMethod( HYPRE_Solver solver, HYPRE_Int *relax_method ) +HYPRE_MGRSetLevelFRelaxMethod( HYPRE_Solver solver, + HYPRE_Int *relax_method ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetLevelFRelaxMethod( solver, relax_method ); } @@ -351,8 +451,15 @@ HYPRE_MGRSetLevelFRelaxMethod( HYPRE_Solver solver, HYPRE_Int *relax_method ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetLevelFRelaxType( HYPRE_Solver solver, HYPRE_Int *relax_type ) +HYPRE_MGRSetLevelFRelaxType( HYPRE_Solver solver, + HYPRE_Int *relax_type ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetLevelFRelaxType( solver, relax_type ); } @@ -363,6 +470,12 @@ HYPRE_MGRSetLevelFRelaxType( HYPRE_Solver solver, HYPRE_Int *relax_type ) HYPRE_Int HYPRE_MGRSetCoarseGridMethod( HYPRE_Solver solver, HYPRE_Int *cg_method ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetCoarseGridMethod( solver, cg_method ); } @@ -371,8 +484,15 @@ HYPRE_MGRSetCoarseGridMethod( HYPRE_Solver solver, HYPRE_Int *cg_method ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetLevelFRelaxNumFunctions( HYPRE_Solver solver, HYPRE_Int *num_functions ) +HYPRE_MGRSetLevelFRelaxNumFunctions( HYPRE_Solver solver, + HYPRE_Int *num_functions ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetLevelFRelaxNumFunctions( solver, num_functions ); } @@ -381,8 +501,15 @@ HYPRE_MGRSetLevelFRelaxNumFunctions( HYPRE_Solver solver, HYPRE_Int *num_functio *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetRelaxType(HYPRE_Solver solver, HYPRE_Int relax_type ) +HYPRE_MGRSetRelaxType( HYPRE_Solver solver, + HYPRE_Int relax_type ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetRelaxType(solver, relax_type ); } @@ -391,17 +518,32 @@ HYPRE_MGRSetRelaxType(HYPRE_Solver solver, HYPRE_Int relax_type ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetNumRelaxSweeps( HYPRE_Solver solver, HYPRE_Int nsweeps ) +HYPRE_MGRSetNumRelaxSweeps( HYPRE_Solver solver, + HYPRE_Int nsweeps ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetNumRelaxSweeps(solver, nsweeps); } /*-------------------------------------------------------------------------- * HYPRE_MGRSetLevelNumRelaxSweeps *--------------------------------------------------------------------------*/ + HYPRE_Int -HYPRE_MGRSetLevelNumRelaxSweeps( HYPRE_Solver solver, HYPRE_Int *nsweeps ) +HYPRE_MGRSetLevelNumRelaxSweeps( HYPRE_Solver solver, + HYPRE_Int *nsweeps ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetLevelNumRelaxSweeps(solver, nsweeps); } @@ -410,8 +552,15 @@ HYPRE_MGRSetLevelNumRelaxSweeps( HYPRE_Solver solver, HYPRE_Int *nsweeps ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetInterpType( HYPRE_Solver solver, HYPRE_Int interpType ) +HYPRE_MGRSetInterpType( HYPRE_Solver solver, + HYPRE_Int interpType ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetInterpType(solver, interpType); } @@ -420,8 +569,15 @@ HYPRE_MGRSetInterpType( HYPRE_Solver solver, HYPRE_Int interpType ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetLevelInterpType( HYPRE_Solver solver, HYPRE_Int *interpType ) +HYPRE_MGRSetLevelInterpType( HYPRE_Solver solver, + HYPRE_Int *interpType ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetLevelInterpType(solver, interpType); } @@ -430,8 +586,15 @@ HYPRE_MGRSetLevelInterpType( HYPRE_Solver solver, HYPRE_Int *interpType ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetNumInterpSweeps( HYPRE_Solver solver, HYPRE_Int nsweeps ) +HYPRE_MGRSetNumInterpSweeps( HYPRE_Solver solver, + HYPRE_Int nsweeps ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetNumInterpSweeps(solver, nsweeps); } @@ -440,8 +603,15 @@ HYPRE_MGRSetNumInterpSweeps( HYPRE_Solver solver, HYPRE_Int nsweeps ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetNumRestrictSweeps( HYPRE_Solver solver, HYPRE_Int nsweeps ) +HYPRE_MGRSetNumRestrictSweeps( HYPRE_Solver solver, + HYPRE_Int nsweeps ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetNumRestrictSweeps(solver, nsweeps); } @@ -450,17 +620,37 @@ HYPRE_MGRSetNumRestrictSweeps( HYPRE_Solver solver, HYPRE_Int nsweeps ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetTruncateCoarseGridThreshold( HYPRE_Solver solver, HYPRE_Real threshold) +HYPRE_MGRSetTruncateCoarseGridThreshold( HYPRE_Solver solver, + HYPRE_Real threshold) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetTruncateCoarseGridThreshold( solver, threshold ); } /*-------------------------------------------------------------------------- * HYPRE_MGRSetBlockJacobiBlockSize *--------------------------------------------------------------------------*/ + HYPRE_Int -HYPRE_MGRSetBlockJacobiBlockSize( HYPRE_Solver solver, HYPRE_Int blk_size ) +HYPRE_MGRSetBlockJacobiBlockSize( HYPRE_Solver solver, + HYPRE_Int blk_size ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + else if (blk_size < 1) + { + hypre_error_in_arg(2); + return hypre_error_flag; + } + return hypre_MGRSetBlockJacobiBlockSize(solver, blk_size); } @@ -469,8 +659,15 @@ HYPRE_MGRSetBlockJacobiBlockSize( HYPRE_Solver solver, HYPRE_Int blk_size ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetFrelaxPrintLevel( HYPRE_Solver solver, HYPRE_Int print_level ) +HYPRE_MGRSetFrelaxPrintLevel( HYPRE_Solver solver, + HYPRE_Int print_level ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetFrelaxPrintLevel( solver, print_level ); } @@ -479,8 +676,15 @@ HYPRE_MGRSetFrelaxPrintLevel( HYPRE_Solver solver, HYPRE_Int print_level ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetCoarseGridPrintLevel( HYPRE_Solver solver, HYPRE_Int print_level ) +HYPRE_MGRSetCoarseGridPrintLevel( HYPRE_Solver solver, + HYPRE_Int print_level ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetCoarseGridPrintLevel( solver, print_level ); } @@ -489,8 +693,15 @@ HYPRE_MGRSetCoarseGridPrintLevel( HYPRE_Solver solver, HYPRE_Int print_level ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetPrintLevel( HYPRE_Solver solver, HYPRE_Int print_level ) +HYPRE_MGRSetPrintLevel( HYPRE_Solver solver, + HYPRE_Int print_level ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetPrintLevel( solver, print_level ); } @@ -499,8 +710,15 @@ HYPRE_MGRSetPrintLevel( HYPRE_Solver solver, HYPRE_Int print_level ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetLogging( HYPRE_Solver solver, HYPRE_Int logging ) +HYPRE_MGRSetLogging( HYPRE_Solver solver, + HYPRE_Int logging ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetLogging(solver, logging ); } @@ -509,8 +727,20 @@ HYPRE_MGRSetLogging( HYPRE_Solver solver, HYPRE_Int logging ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetMaxIter( HYPRE_Solver solver, HYPRE_Int max_iter ) +HYPRE_MGRSetMaxIter( HYPRE_Solver solver, + HYPRE_Int max_iter ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + else if (max_iter < 0) + { + hypre_error_in_arg(2); + return hypre_error_flag; + } + return hypre_MGRSetMaxIter( solver, max_iter ); } @@ -519,8 +749,20 @@ HYPRE_MGRSetMaxIter( HYPRE_Solver solver, HYPRE_Int max_iter ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetTol( HYPRE_Solver solver, HYPRE_Real tol ) +HYPRE_MGRSetTol( HYPRE_Solver solver, + HYPRE_Real tol ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + else if (tol < 0.0) + { + hypre_error_in_arg(2); + return hypre_error_flag; + } + return hypre_MGRSetTol( solver, tol ); } @@ -529,54 +771,128 @@ HYPRE_MGRSetTol( HYPRE_Solver solver, HYPRE_Real tol ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetMaxGlobalSmoothIters( HYPRE_Solver solver, HYPRE_Int max_iter ) +HYPRE_MGRSetMaxGlobalSmoothIters( HYPRE_Solver solver, + HYPRE_Int max_iter ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + else if (max_iter < 0) + { + hypre_error_in_arg(2); + return hypre_error_flag; + } + return hypre_MGRSetMaxGlobalSmoothIters(solver, max_iter); } + /*-------------------------------------------------------------------------- * HYPRE_MGRSetLevelsmoothIters *--------------------------------------------------------------------------*/ + HYPRE_Int -HYPRE_MGRSetLevelSmoothIters( HYPRE_Solver solver, - HYPRE_Int *smooth_iters ) +HYPRE_MGRSetLevelSmoothIters( HYPRE_Solver solver, + HYPRE_Int *smooth_iters ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetLevelSmoothIters(solver, smooth_iters); } /*-------------------------------------------------------------------------- * HYPRE_MGRSetGlobalsmoothType *--------------------------------------------------------------------------*/ + HYPRE_Int -HYPRE_MGRSetGlobalSmoothType( HYPRE_Solver solver, HYPRE_Int smooth_type ) +HYPRE_MGRSetGlobalSmoothType( HYPRE_Solver solver, + HYPRE_Int smooth_type ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetGlobalSmoothType(solver, smooth_type); } + /*-------------------------------------------------------------------------- * HYPRE_MGRSetLevelsmoothType *--------------------------------------------------------------------------*/ + HYPRE_Int -HYPRE_MGRSetLevelSmoothType( HYPRE_Solver solver, - HYPRE_Int *smooth_type ) +HYPRE_MGRSetLevelSmoothType( HYPRE_Solver solver, + HYPRE_Int *smooth_type ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetLevelSmoothType(solver, smooth_type); } + /*-------------------------------------------------------------------------- * HYPRE_MGRSetGlobalSmoothCycle *--------------------------------------------------------------------------*/ + HYPRE_Int HYPRE_MGRSetGlobalSmoothCycle( HYPRE_Solver solver, - HYPRE_Int global_smooth_cycle ) + HYPRE_Int global_smooth_cycle ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetGlobalSmoothCycle(solver, global_smooth_cycle); } +/*-------------------------------------------------------------------------- + * HYPRE_MGRSetGlobalSmootherAtLevel + *--------------------------------------------------------------------------*/ + +HYPRE_Int +HYPRE_MGRSetGlobalSmootherAtLevel( HYPRE_Solver solver, + HYPRE_Solver smoother, + HYPRE_Int level ) +{ + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + else if (!smoother) + { + hypre_error_in_arg(2); + return hypre_error_flag; + } + + return hypre_MGRSetGlobalSmootherAtLevel((void*) solver, smoother, level); +} + /*-------------------------------------------------------------------------- * HYPRE_MGRSetPMaxElmts *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetPMaxElmts( HYPRE_Solver solver, HYPRE_Int P_max_elmts ) +HYPRE_MGRSetPMaxElmts( HYPRE_Solver solver, + HYPRE_Int P_max_elmts ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetPMaxElmts(solver, P_max_elmts); } @@ -585,8 +901,15 @@ HYPRE_MGRSetPMaxElmts( HYPRE_Solver solver, HYPRE_Int P_max_elmts ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRSetLevelPMaxElmts( HYPRE_Solver solver, HYPRE_Int *P_max_elmts ) +HYPRE_MGRSetLevelPMaxElmts( HYPRE_Solver solver, + HYPRE_Int *P_max_elmts ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRSetLevelPMaxElmts(solver, P_max_elmts); } @@ -595,8 +918,15 @@ HYPRE_MGRSetLevelPMaxElmts( HYPRE_Solver solver, HYPRE_Int *P_max_elmts ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRGetCoarseGridConvergenceFactor( HYPRE_Solver solver, HYPRE_Real *conv_factor ) +HYPRE_MGRGetCoarseGridConvergenceFactor( HYPRE_Solver solver, + HYPRE_Real *conv_factor ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRGetCoarseGridConvergenceFactor( solver, conv_factor ); } @@ -605,8 +935,15 @@ HYPRE_MGRGetCoarseGridConvergenceFactor( HYPRE_Solver solver, HYPRE_Real *conv_f *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRGetNumIterations( HYPRE_Solver solver, HYPRE_Int *num_iterations ) +HYPRE_MGRGetNumIterations( HYPRE_Solver solver, + HYPRE_Int *num_iterations ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRGetNumIterations( solver, num_iterations ); } @@ -615,7 +952,14 @@ HYPRE_MGRGetNumIterations( HYPRE_Solver solver, HYPRE_Int *num_iterations ) *--------------------------------------------------------------------------*/ HYPRE_Int -HYPRE_MGRGetFinalRelativeResidualNorm( HYPRE_Solver solver, HYPRE_Real *res_norm ) +HYPRE_MGRGetFinalRelativeResidualNorm( HYPRE_Solver solver, + HYPRE_Real *res_norm ) { + if (!solver) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + return hypre_MGRGetFinalRelativeResidualNorm(solver, res_norm); } diff --git a/src/parcsr_ls/_hypre_parcsr_ls.h b/src/parcsr_ls/_hypre_parcsr_ls.h index 70bcfb5d6c..50acd25345 100644 --- a/src/parcsr_ls/_hypre_parcsr_ls.h +++ b/src/parcsr_ls/_hypre_parcsr_ls.h @@ -3606,7 +3606,7 @@ HYPRE_Int hypre_MGRSetFSolver( void *mgr_vdata, HYPRE_Int (*fine_grid_solver_solve)(void*, void*, void*, void*), HYPRE_Int (*fine_grid_solver_setup)(void*, void*, void*, void*), void *fsolver ); -HYPRE_Int hypre_MGRSetFSolverAtLevel( HYPRE_Int level, void *mgr_vdata, void *fsolver ); +HYPRE_Int hypre_MGRSetFSolverAtLevel( void *mgr_vdata, void *fsolver, HYPRE_Int level ); HYPRE_Int hypre_MGRSetup( void *mgr_vdata, hypre_ParCSRMatrix *A, hypre_ParVector *f, hypre_ParVector *u ); HYPRE_Int hypre_MGRSolve( void *mgr_vdata, hypre_ParCSRMatrix *A, @@ -3680,6 +3680,8 @@ HYPRE_Int hypre_MGRSetNumRestrictSweeps( void *mgr_vdata, HYPRE_Int nsweeps ); HYPRE_Int hypre_MGRSetLevelSmoothType( void *mgr_vdata, HYPRE_Int *level_smooth_type ); HYPRE_Int hypre_MGRSetLevelSmoothIters( void *mgr_vdata, HYPRE_Int *level_smooth_iters ); HYPRE_Int hypre_MGRSetGlobalSmoothCycle( void *mgr_vdata, HYPRE_Int global_smooth_cycle ); +HYPRE_Int hypre_MGRSetGlobalSmootherAtLevel( void *mgr_vdata, HYPRE_Solver smoother, + HYPRE_Int level ); HYPRE_Int hypre_MGRSetPrintLevel( void *mgr_vdata, HYPRE_Int print_level ); HYPRE_Int hypre_MGRSetFrelaxPrintLevel( void *mgr_vdata, HYPRE_Int print_level ); HYPRE_Int hypre_MGRSetCoarseGridPrintLevel( void *mgr_vdata, HYPRE_Int print_level ); @@ -3740,7 +3742,7 @@ HYPRE_Int hypre_MGRBuildInterpApproximateInverse( hypre_ParCSRMatrix *A, HYPRE_I HYPRE_BigInt *num_cpts_global, hypre_ParCSRMatrix **P_ptr ); HYPRE_Int hypre_MGRTruncateAcfCPR( hypre_ParCSRMatrix *A_CF, hypre_ParCSRMatrix **A_CF_new_ptr ); -HYPRE_Int hypre_MGRBuildRFromW( HYPRE_Int *C_map, HYPRE_Int *F_map, +HYPRE_Int hypre_MGRBuildRFromW( hypre_IntArray *C_map, hypre_IntArray *F_map, HYPRE_BigInt global_num_rows_R, HYPRE_BigInt global_num_cols_R, HYPRE_BigInt *row_starts_R, HYPRE_BigInt *col_starts_R, hypre_ParCSRMatrix *W, hypre_ParCSRMatrix **R_ptr ); @@ -4350,4 +4352,3 @@ HYPRE_Int hypre_FSAISetupDevice( void *fsai_vdata, hypre_ParCSRMatrix *A, #endif #endif - diff --git a/src/parcsr_ls/par_gauss_elim.c b/src/parcsr_ls/par_gauss_elim.c index 3eb87f3f6c..c3a9ec6e4c 100644 --- a/src/parcsr_ls/par_gauss_elim.c +++ b/src/parcsr_ls/par_gauss_elim.c @@ -96,7 +96,13 @@ hypre_GaussElimSetup(hypre_ParAMGData *amg_data, } else { + /* Fallback to host execution when dependency libraries are not met (cuSOLVER/MAGMA) */ +#if defined(HYPRE_USING_CUDA) && !defined(HYPRE_USING_CUSOLVER) && !defined(HYPRE_USING_MAGMA) ||\ + (defined(HYPRE_USING_HIP) && !defined(HYPRE_USING_MAGMA)) + ge_memory_location = HYPRE_MEMORY_HOST; +#else ge_memory_location = memory_location; +#endif } hypre_ParAMGDataGEMemoryLocation(amg_data) = ge_memory_location; diff --git a/src/parcsr_ls/par_mgr.c b/src/parcsr_ls/par_mgr.c index 85b446fd16..574273627a 100644 --- a/src/parcsr_ls/par_mgr.c +++ b/src/parcsr_ls/par_mgr.c @@ -444,6 +444,11 @@ hypre_MGRDestroy( void *data ) { HYPRE_ILUDestroy((mgr_data -> level_smoother)[i]); } + else if ((mgr_data -> level_smoother)[i]) + { + hypre_Solver *smoother_base = (hypre_Solver*) (mgr_data -> level_smoother)[i]; + hypre_SolverDestroy(smoother_base)((mgr_data -> level_smoother)[i]); + } } } hypre_TFree(mgr_data -> level_smoother, HYPRE_MEMORY_HOST); @@ -852,17 +857,6 @@ hypre_MGRSetReservedCoarseNodes(void *mgr_vdata, HYPRE_BigInt *reserved_coarse_indexes = NULL; HYPRE_Int i; - if (!mgr_data) - { - hypre_error_w_msg(HYPRE_ERROR_GENERIC, "Warning! MGR object empty!\n"); - return hypre_error_flag; - } - - if (reserved_coarse_size < 0) - { - hypre_error_in_arg(2); - return hypre_error_flag; - } /* free data not previously destroyed */ if ((mgr_data -> reserved_coarse_indexes)) { @@ -2908,14 +2902,8 @@ hypre_MGRSetFSolver( void *mgr_vdata, void *fsolver ) { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; - - if (!mgr_data) - { - hypre_error_in_arg(1); - return hypre_error_flag; - } - HYPRE_Int max_num_coarse_levels = (mgr_data -> max_num_coarse_levels); - HYPRE_Solver **aff_solver = (mgr_data -> aff_solver); + HYPRE_Int max_num_coarse_levels = (mgr_data -> max_num_coarse_levels); + HYPRE_Solver **aff_solver = (mgr_data -> aff_solver); if (aff_solver == NULL) { @@ -2943,24 +2931,18 @@ hypre_MGRSetFSolver( void *mgr_vdata, *--------------------------------------------------------------------------*/ HYPRE_Int -hypre_MGRSetFSolverAtLevel( HYPRE_Int level, - void *mgr_vdata, - void *fsolver ) +hypre_MGRSetFSolverAtLevel( void *mgr_vdata, + void *fsolver, + HYPRE_Int level ) { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; - - if (!mgr_data) - { - hypre_error_in_arg(1); - return hypre_error_flag; - } - HYPRE_Int max_num_coarse_levels = (mgr_data -> max_num_coarse_levels); - HYPRE_Solver **aff_solver = (mgr_data -> aff_solver); + HYPRE_Int max_num_coarse_levels = (mgr_data -> max_num_coarse_levels); + HYPRE_Solver **aff_solver = (mgr_data -> aff_solver); /* Check if the requested level makes sense */ if (level < 0 || level >= max_num_coarse_levels) { - hypre_error_in_arg(2); + hypre_error_in_arg(1); return hypre_error_flag; } @@ -2980,19 +2962,13 @@ hypre_MGRSetFSolverAtLevel( HYPRE_Int level, /* set coarse grid solver */ HYPRE_Int -hypre_MGRSetCoarseSolver( void *mgr_vdata, +hypre_MGRSetCoarseSolver( void *mgr_vdata, HYPRE_Int (*coarse_grid_solver_solve)(void*, void*, void*, void*), HYPRE_Int (*coarse_grid_solver_setup)(void*, void*, void*, void*), - void *coarse_grid_solver ) + void *coarse_grid_solver ) { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; - if (!mgr_data) - { - hypre_error_in_arg(1); - return hypre_error_flag; - } - (mgr_data -> coarse_grid_solver_solve) = coarse_grid_solver_solve; (mgr_data -> coarse_grid_solver_setup) = coarse_grid_solver_setup; (mgr_data -> coarse_grid_solver) = (HYPRE_Solver) coarse_grid_solver; @@ -3010,6 +2986,7 @@ hypre_MGRSetMaxCoarseLevels( void *mgr_vdata, HYPRE_Int maxcoarselevs ) { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; (mgr_data -> max_num_coarse_levels) = maxcoarselevs; + return hypre_error_flag; } @@ -3019,6 +2996,7 @@ hypre_MGRSetBlockSize( void *mgr_vdata, HYPRE_Int bsize ) { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; (mgr_data -> block_size) = bsize; + return hypre_error_flag; } @@ -3461,7 +3439,12 @@ hypre_MGRSetMaxGlobalSmoothIters( void *mgr_vdata, HYPRE_Int max_iter ) return hypre_error_flag; } -/* Set global smoothing type for mgr solver */ +/*-------------------------------------------------------------------------- + * hypre_MGRSetGlobalSmoothType + * + * Set global smoothing type at the first (finest) MGR level + *--------------------------------------------------------------------------*/ + HYPRE_Int hypre_MGRSetGlobalSmoothType( void *mgr_vdata, HYPRE_Int gsmooth_type ) { @@ -3482,43 +3465,74 @@ hypre_MGRSetGlobalSmoothType( void *mgr_vdata, HYPRE_Int gsmooth_type ) return hypre_error_flag; } -/* Set global smoothing type for mgr solver */ +/*-------------------------------------------------------------------------- + * hypre_MGRSetLevelSmoothType + * + * Set global smoothing type at each MGR level. + *--------------------------------------------------------------------------*/ + HYPRE_Int -hypre_MGRSetLevelSmoothType( void *mgr_vdata, HYPRE_Int *gsmooth_type ) +hypre_MGRSetLevelSmoothType( void *mgr_vdata, + HYPRE_Int *gsmooth_type ) { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; - HYPRE_Int i; - HYPRE_Int max_num_coarse_levels = (mgr_data -> max_num_coarse_levels); - hypre_TFree((mgr_data -> level_smooth_type), HYPRE_MEMORY_HOST); + HYPRE_Int max_num_coarse_levels = (mgr_data -> max_num_coarse_levels); + HYPRE_Int *level_smooth_type, i; + char msg[1024]; - HYPRE_Int *level_smooth_type = hypre_CTAlloc(HYPRE_Int, max_num_coarse_levels, HYPRE_MEMORY_HOST); + /* Set level_smooth_type array */ + level_smooth_type = hypre_CTAlloc(HYPRE_Int, max_num_coarse_levels, HYPRE_MEMORY_HOST); + hypre_TFree((mgr_data -> level_smooth_type), HYPRE_MEMORY_HOST); if (gsmooth_type != NULL) { for (i = 0; i < max_num_coarse_levels; i++) { - level_smooth_type[i] = gsmooth_type[i]; + /* For meaningful values of global smoothing type, the option set via + hypre_MGRSetGlobalSmootherAtLevel has precedence over the option set + via this function. */ + if ((mgr_data -> level_smoother) && (mgr_data -> level_smoother)[i] && + (gsmooth_type[i] >= 0)) + { + hypre_sprintf(msg, "hypre_MGRSetLevelSmoothType does not take effect at level %d since\n\ + hypre_MGRSetGlobalSmootherAtLevel has been called at the same level", + i); + hypre_error_w_msg(HYPRE_ERROR_GENERIC, msg); + } + else + { + level_smooth_type[i] = gsmooth_type[i]; + } } } else { for (i = 0; i < max_num_coarse_levels; i++) { - level_smooth_type[i] = 0; + level_smooth_type[i] = 0; // Jacobi } } (mgr_data -> level_smooth_type) = level_smooth_type; + return hypre_error_flag; } +/*-------------------------------------------------------------------------- + * hypre_MGRSetLevelSmoothIters + * + * Set the number of global smoothing iterations at each MGR level. + *--------------------------------------------------------------------------*/ + HYPRE_Int -hypre_MGRSetLevelSmoothIters( void *mgr_vdata, HYPRE_Int *gsmooth_iters ) +hypre_MGRSetLevelSmoothIters( void *mgr_vdata, + HYPRE_Int *gsmooth_iters ) { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; - HYPRE_Int i; - HYPRE_Int max_num_coarse_levels = (mgr_data -> max_num_coarse_levels); - hypre_TFree((mgr_data -> level_smooth_iters), HYPRE_MEMORY_HOST); + HYPRE_Int max_num_coarse_levels = (mgr_data -> max_num_coarse_levels); + HYPRE_Int *level_smooth_iters; + HYPRE_Int i; - HYPRE_Int *level_smooth_iters = hypre_CTAlloc(HYPRE_Int, max_num_coarse_levels, HYPRE_MEMORY_HOST); + level_smooth_iters = hypre_CTAlloc(HYPRE_Int, max_num_coarse_levels, HYPRE_MEMORY_HOST); + hypre_TFree((mgr_data -> level_smooth_iters), HYPRE_MEMORY_HOST); if (gsmooth_iters != NULL) { for (i = 0; i < max_num_coarse_levels; i++) @@ -3534,6 +3548,75 @@ hypre_MGRSetLevelSmoothIters( void *mgr_vdata, HYPRE_Int *gsmooth_iters ) } } (mgr_data -> level_smooth_iters) = level_smooth_iters; + + return hypre_error_flag; +} + +/*-------------------------------------------------------------------------- + * hypre_MGRSetGlobalSmootherAtLevel + * + * Set global relaxation method for a given MGR level via a HYPRE solver object. + * + * Note this function asks for a level identifier and doesn't expect an array + * of function pointers for each level (as done by SetLevel functions). + *--------------------------------------------------------------------------*/ + +HYPRE_Int +hypre_MGRSetGlobalSmootherAtLevel( void *mgr_vdata, + HYPRE_Solver smoother, + HYPRE_Int level ) +{ + hypre_Solver *base = (hypre_Solver*) smoother; + HYPRE_PtrToSolverFcn setup = hypre_SolverSetup(base); + hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; + HYPRE_Int max_num_coarse_levels = (mgr_data -> max_num_coarse_levels); + HYPRE_Int smoother_type; + char msg[1024]; + + /* Check if the requested level makes sense */ + if (level < 0 || level >= max_num_coarse_levels) + { + hypre_error_in_arg(1); + return hypre_error_flag; + } + + /* Allocate level_smoother if needed */ + if (!(mgr_data -> level_smoother)) + { + (mgr_data -> level_smoother) = hypre_CTAlloc(HYPRE_Solver, + max_num_coarse_levels, + HYPRE_MEMORY_HOST); + } + + /* Allocate level_smooth_type if needed */ + if (!(mgr_data -> level_smooth_type)) + { + (mgr_data -> level_smooth_type) = hypre_CTAlloc(HYPRE_Int, + max_num_coarse_levels, + HYPRE_MEMORY_HOST); + } + + (mgr_data -> level_smoother)[level] = smoother; + + /* Obtain corresponding smoother type */ + if (setup == (HYPRE_PtrToSolverFcn) HYPRE_ILUSetup) + { + smoother_type = 16; + } + else + { + smoother_type = -1; /* Unknown smoother */ + } + + /* Check if level_smooth_type[level] corresponds to the right smoother type */ + if ((mgr_data -> level_smooth_type)[level] > 0 && + (mgr_data -> level_smooth_type)[level] != smoother_type) + { + hypre_sprintf(msg, "Reseting global relaxation type at level %d to user's smoother", level); + hypre_error_w_msg(HYPRE_ERROR_GENERIC, msg); + } + (mgr_data -> level_smooth_type)[level] = smoother_type; + return hypre_error_flag; } @@ -3589,11 +3672,6 @@ hypre_MGRGetNumIterations( void *mgr_vdata, HYPRE_Int *num_iterations ) { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; - if (!mgr_data) - { - hypre_error_in_arg(1); - return hypre_error_flag; - } *num_iterations = mgr_data->num_iterations; return hypre_error_flag; @@ -3605,11 +3683,6 @@ hypre_MGRGetFinalRelativeResidualNorm( void *mgr_vdata, HYPRE_Real *res_norm ) { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; - if (!mgr_data) - { - hypre_error_in_arg(1); - return hypre_error_flag; - } *res_norm = mgr_data->final_rel_residual_norm; return hypre_error_flag; @@ -3620,11 +3693,6 @@ hypre_MGRGetCoarseGridConvergenceFactor( void *mgr_vdata, HYPRE_Real *conv_facto { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; - if (!mgr_data) - { - hypre_error_in_arg(1); - return hypre_error_flag; - } *conv_factor = (mgr_data -> cg_convergence_factor); return hypre_error_flag; @@ -4239,11 +4307,6 @@ hypre_MGRGetCoarseGridMatrix( void *mgr_vdata, hypre_ParCSRMatrix **RAP ) { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; - if (!mgr_data) - { - hypre_error_in_arg(1); - return hypre_error_flag; - } if (mgr_data -> RAP == NULL) { hypre_error_w_msg(HYPRE_ERROR_GENERIC, @@ -4261,11 +4324,6 @@ hypre_MGRGetCoarseGridSolution( void *mgr_vdata, hypre_ParVector **sol ) { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; - if (!mgr_data) - { - hypre_error_in_arg(1); - return hypre_error_flag; - } if (mgr_data -> U_array == NULL) { hypre_error_w_msg(HYPRE_ERROR_GENERIC, @@ -4283,11 +4341,6 @@ hypre_MGRGetCoarseGridRHS( void *mgr_vdata, hypre_ParVector **rhs ) { hypre_ParMGRData *mgr_data = (hypre_ParMGRData*) mgr_vdata; - if (!mgr_data) - { - hypre_error_in_arg(1); - return hypre_error_flag; - } if (mgr_data -> F_array == NULL) { hypre_error_w_msg(HYPRE_ERROR_GENERIC, diff --git a/src/parcsr_ls/par_mgr_interp.c b/src/parcsr_ls/par_mgr_interp.c index 6355693528..344949bd46 100644 --- a/src/parcsr_ls/par_mgr_interp.c +++ b/src/parcsr_ls/par_mgr_interp.c @@ -2248,8 +2248,8 @@ hypre_MGRTruncateAcfCPR(hypre_ParCSRMatrix *A_CF, *--------------------------------------------------------------------------*/ HYPRE_Int -hypre_MGRBuildRFromWHost(HYPRE_Int *C_map, - HYPRE_Int *F_map, +hypre_MGRBuildRFromWHost(hypre_IntArray *C_map, + hypre_IntArray *F_map, hypre_ParCSRMatrix *W, hypre_ParCSRMatrix *R) { @@ -2259,6 +2259,8 @@ hypre_MGRBuildRFromWHost(HYPRE_Int *C_map, HYPRE_Int *W_diag_j = hypre_CSRMatrixJ(W_diag); HYPRE_Complex *W_diag_a = hypre_CSRMatrixData(W_diag); HYPRE_Int W_diag_num_rows = hypre_CSRMatrixNumRows(W_diag); + HYPRE_Int *C_map_data = hypre_IntArrayData(C_map); + HYPRE_Int *F_map_data = hypre_IntArrayData(F_map); /* Output matrix */ hypre_CSRMatrix *R_diag = hypre_ParCSRMatrixDiag(R); @@ -2276,13 +2278,13 @@ hypre_MGRBuildRFromWHost(HYPRE_Int *C_map, /* Set CF connections */ for (j = W_diag_i[i]; j < W_diag_i[i + 1]; j++) { - R_diag_j[nnz_diag] = F_map[W_diag_j[j]]; + R_diag_j[nnz_diag] = F_map_data[W_diag_j[j]]; R_diag_a[nnz_diag] = - W_diag_a[j]; nnz_diag++; } /* Set CC connection */ - R_diag_j[nnz_diag] = C_map[i]; + R_diag_j[nnz_diag] = C_map_data[i]; R_diag_a[nnz_diag] = one; nnz_diag++; @@ -2300,8 +2302,8 @@ hypre_MGRBuildRFromWHost(HYPRE_Int *C_map, *--------------------------------------------------------------------------*/ HYPRE_Int -hypre_MGRBuildRFromW(HYPRE_Int *C_map, - HYPRE_Int *F_map, +hypre_MGRBuildRFromW(hypre_IntArray *C_map, + hypre_IntArray *F_map, HYPRE_BigInt global_num_rows_R, HYPRE_BigInt global_num_cols_R, HYPRE_BigInt *row_starts_R, @@ -2358,6 +2360,8 @@ hypre_MGRBuildRFromW(HYPRE_Int *C_map, /* TODO (VPM): Implement hypre_MGRBuildRFromWDevice */ hypre_ParCSRMatrixMigrate(W, HYPRE_MEMORY_HOST); hypre_ParCSRMatrixMigrate(R, HYPRE_MEMORY_HOST); + hypre_IntArrayMigrate(C_map, HYPRE_MEMORY_HOST); + hypre_IntArrayMigrate(F_map, HYPRE_MEMORY_HOST); hypre_MGRBuildRFromWHost(C_map, F_map, W, R); hypre_ParCSRMatrixMigrate(W, HYPRE_MEMORY_DEVICE); hypre_ParCSRMatrixMigrate(R, HYPRE_MEMORY_DEVICE); @@ -2446,8 +2450,8 @@ hypre_MGRColLumpedRestrict(hypre_ParCSRMatrix *A, hypre_IntArraySeparateByValue(num_points, points, sizes, CF_marker, &CF_maps); /* Build restriction from W (R = [-W I]) */ - hypre_MGRBuildRFromW(hypre_IntArrayArrayEntryIData(CF_maps, 0), - hypre_IntArrayArrayEntryIData(CF_maps, 1), + hypre_MGRBuildRFromW(hypre_IntArrayArrayEntryI(CF_maps, 0), + hypre_IntArrayArrayEntryI(CF_maps, 1), hypre_ParCSRMatrixGlobalNumRows(A_CF), hypre_ParCSRMatrixGlobalNumCols(A), hypre_ParCSRMatrixRowStarts(A_CF), @@ -2561,8 +2565,8 @@ hypre_MGRBlockColLumpedRestrict(hypre_ParCSRMatrix *A, hypre_IntArraySeparateByValue(num_points, points, sizes, CF_marker, &CF_maps); /* Build restriction from W (R = [-W I]) */ - hypre_MGRBuildRFromW(hypre_IntArrayArrayEntryIData(CF_maps, 0), - hypre_IntArrayArrayEntryIData(CF_maps, 1), + hypre_MGRBuildRFromW(hypre_IntArrayArrayEntryI(CF_maps, 0), + hypre_IntArrayArrayEntryI(CF_maps, 1), hypre_ParCSRMatrixGlobalNumRows(A_CF), hypre_ParCSRMatrixGlobalNumCols(A), hypre_ParCSRMatrixRowStarts(A_CF), diff --git a/src/parcsr_ls/par_mgr_setup.c b/src/parcsr_ls/par_mgr_setup.c index 619c53a250..0f9edd15fa 100644 --- a/src/parcsr_ls/par_mgr_setup.c +++ b/src/parcsr_ls/par_mgr_setup.c @@ -1020,11 +1020,21 @@ hypre_MGRSetup( void *mgr_vdata, hypre_sprintf(region_name, "Global-Relax"); hypre_GpuProfilingPushRange(region_name); HYPRE_ANNOTATE_REGION_BEGIN("%s", region_name); + + /* TODO (VPM): Change option types for block-Jacobi and block-GS to 30 and 31 and + make them accessible through hypre_BoomerAMGRelax? */ if (level_smooth_iters[lev] > 0) { - /* TODO (VPM): Change option types for block-Jacobi and block-GS to 30 and 31 and - make them accessible through hypre_BoomerAMGRelax? */ - if (level_smooth_type[lev] == 0 || level_smooth_type[lev] == 1) + if (level_smoother[lev]) + { + hypre_Solver *smoother_base = (hypre_Solver*) level_smoother[lev]; + + /* Call setup function */ + hypre_SolverSetup(smoother_base)((HYPRE_Solver) level_smoother[lev], + (HYPRE_Matrix) A_array[lev], + NULL, NULL); + } + else if (level_smooth_type[lev] == 0 || level_smooth_type[lev] == 1) { /* TODO (VPM): move this to hypre_MGRBlockRelaxSetup and change its declaration */ #if defined (HYPRE_USING_GPU) @@ -1499,17 +1509,23 @@ hypre_MGRSetup( void *mgr_vdata, } /* TODO: Check use of A_ff_array[lev], vectors at (lev + 1) are correct? (VPM) */ - F_fine_array[lev + 1] = - hypre_ParVectorCreate(hypre_ParCSRMatrixComm(A_ff_array[lev]), - hypre_ParCSRMatrixGlobalNumRows(A_ff_array[lev]), - hypre_ParCSRMatrixRowStarts(A_ff_array[lev])); - hypre_ParVectorInitialize(F_fine_array[lev + 1]); + if (!F_fine_array[lev + 1]) + { + F_fine_array[lev + 1] = + hypre_ParVectorCreate(hypre_ParCSRMatrixComm(A_ff_array[lev]), + hypre_ParCSRMatrixGlobalNumRows(A_ff_array[lev]), + hypre_ParCSRMatrixRowStarts(A_ff_array[lev])); + hypre_ParVectorInitialize(F_fine_array[lev + 1]); + } - U_fine_array[lev + 1] = - hypre_ParVectorCreate(hypre_ParCSRMatrixComm(A_ff_array[lev]), - hypre_ParCSRMatrixGlobalNumRows(A_ff_array[lev]), - hypre_ParCSRMatrixRowStarts(A_ff_array[lev])); - hypre_ParVectorInitialize(U_fine_array[lev + 1]); + if (!U_fine_array[lev + 1]) + { + U_fine_array[lev + 1] = + hypre_ParVectorCreate(hypre_ParCSRMatrixComm(A_ff_array[lev]), + hypre_ParCSRMatrixGlobalNumRows(A_ff_array[lev]), + hypre_ParCSRMatrixRowStarts(A_ff_array[lev])); + hypre_ParVectorInitialize(U_fine_array[lev + 1]); + } } /* TODO: refactor this block (VPM) */ diff --git a/src/parcsr_ls/par_mgr_solve.c b/src/parcsr_ls/par_mgr_solve.c index 244ff14726..e9762cc835 100644 --- a/src/parcsr_ls/par_mgr_solve.c +++ b/src/parcsr_ls/par_mgr_solve.c @@ -78,6 +78,7 @@ hypre_MGRSolve( void *mgr_vdata, return hypre_error_flag; } + A_array[0] = A; U_array[0] = u; F_array[0] = f; @@ -705,7 +706,6 @@ hypre_MGRCycle( void *mgr_vdata, level_diaginv, Vtemp); } } - hypre_ParVectorAllZeros(U_array[fine_grid]) = 0; } else if ((level_smooth_type[fine_grid] > 1) && (level_smooth_type[fine_grid] < 7)) @@ -733,16 +733,17 @@ hypre_MGRCycle( void *mgr_vdata, /* Update solution */ hypre_ParVectorAxpy(fp_one, Utemp, U_array[fine_grid]); - hypre_ParVectorAllZeros(U_array[fine_grid]) = 0; } } - else if (level_smooth_type[fine_grid] == 16) + else if ((mgr_data -> level_smoother)[fine_grid]) { - /* hypre_ILU smoother */ - HYPRE_ILUSolve((mgr_data -> level_smoother)[fine_grid], - A_array[fine_grid], F_array[fine_grid], - U_array[fine_grid]); - hypre_ParVectorAllZeros(U_array[fine_grid]) = 0; + /* Generic smoother object */ + hypre_Solver *base = (hypre_Solver*) (mgr_data -> level_smoother)[fine_grid]; + + hypre_SolverSolve(base)((mgr_data -> level_smoother)[fine_grid], + (HYPRE_Matrix) A_array[fine_grid], + (HYPRE_Vector) F_array[fine_grid], + (HYPRE_Vector) U_array[fine_grid]); } else { @@ -755,6 +756,7 @@ hypre_MGRCycle( void *mgr_vdata, U_array[fine_grid], Vtemp, Ztemp); } } + hypre_ParVectorAllZeros(U_array[fine_grid]) = 0; /* Error checking */ if (HYPRE_GetError()) @@ -813,8 +815,8 @@ hypre_MGRCycle( void *mgr_vdata, { hypre_MGRBlockRelaxSolveDevice(B_FF_array[fine_grid], A_ff_array[fine_grid], - F_fine_array[fine_grid], - U_fine_array[fine_grid], + F_fine_array[coarse_grid], + U_fine_array[coarse_grid], Vtemp, fp_one); } else @@ -848,20 +850,25 @@ hypre_MGRCycle( void *mgr_vdata, if (relax_type == 18) { #if defined(HYPRE_USING_GPU) - for (i = 0; i < nsweeps[fine_grid]; i++) + if (exec == HYPRE_EXEC_DEVICE) { - hypre_MGRRelaxL1JacobiDevice(A_array[fine_grid], F_array[fine_grid], - CF_marker_data, relax_points, relax_weight, - l1_norms, U_array[fine_grid], Vtemp); + for (i = 0; i < nsweeps[fine_grid]; i++) + { + hypre_MGRRelaxL1JacobiDevice(A_array[fine_grid], F_array[fine_grid], + CF_marker_data, relax_points, relax_weight, + l1_norms, U_array[fine_grid], Vtemp); + } } -#else - for (i = 0; i < nsweeps[fine_grid]; i++) + else +#endif { - hypre_ParCSRRelax_L1_Jacobi(A_array[fine_grid], F_array[fine_grid], - CF_marker_data, relax_points, relax_weight, - l1_norms, U_array[fine_grid], Vtemp); + for (i = 0; i < nsweeps[fine_grid]; i++) + { + hypre_ParCSRRelax_L1_Jacobi(A_array[fine_grid], F_array[fine_grid], + CF_marker_data, relax_points, relax_weight, + l1_norms, U_array[fine_grid], Vtemp); + } } -#endif } else { @@ -971,13 +978,18 @@ hypre_MGRCycle( void *mgr_vdata, F_array[fine_grid], Vtemp); /* Restrict to F points */ -#if defined (HYPRE_USING_GPU) - hypre_ParCSRMatrixMatvecT(fp_one, P_FF_array[fine_grid], Vtemp, - fp_zero, F_fine_array[coarse_grid]); -#else - hypre_MGRAddVectorR(CF_marker[fine_grid], FMRK, fp_one, Vtemp, - fp_zero, &(F_fine_array[coarse_grid])); +#if defined(HYPRE_USING_GPU) + if (exec == HYPRE_EXEC_DEVICE) + { + hypre_ParCSRMatrixMatvecT(fp_one, P_FF_array[fine_grid], Vtemp, + fp_zero, F_fine_array[coarse_grid]); + } + else #endif + { + hypre_MGRAddVectorR(CF_marker[fine_grid], FMRK, fp_one, Vtemp, + fp_zero, &(F_fine_array[coarse_grid])); + } /* Set initial guess to zeros */ hypre_ParVectorSetZeros(U_fine_array[coarse_grid]); @@ -1011,15 +1023,20 @@ hypre_MGRCycle( void *mgr_vdata, } /* Interpolate the solution back to the fine grid level */ -#if defined (HYPRE_USING_GPU) - hypre_ParCSRMatrixMatvec(fp_one, P_FF_array[fine_grid], - U_fine_array[coarse_grid], fp_one, - U_array[fine_grid]); -#else - hypre_MGRAddVectorP(CF_marker[fine_grid], FMRK, fp_one, - U_fine_array[coarse_grid], fp_one, - &(U_array[fine_grid])); +#if defined(HYPRE_USING_GPU) + if (exec == HYPRE_EXEC_DEVICE) + { + hypre_ParCSRMatrixMatvec(fp_one, P_FF_array[fine_grid], + U_fine_array[coarse_grid], fp_one, + U_array[fine_grid]); + } + else #endif + { + hypre_MGRAddVectorP(CF_marker[fine_grid], FMRK, fp_one, + U_fine_array[coarse_grid], fp_one, + &(U_array[fine_grid])); + } } else { @@ -1214,6 +1231,16 @@ hypre_MGRCycle( void *mgr_vdata, A_array[fine_grid], F_array[fine_grid], U_array[fine_grid]); } + else if ((mgr_data -> level_smoother)[fine_grid]) + { + /* User smoother */ + hypre_Solver *base = (hypre_Solver*) (mgr_data -> level_smoother)[fine_grid]; + + hypre_SolverSolve(base)((mgr_data -> level_smoother)[fine_grid], + (HYPRE_Matrix) A_array[fine_grid], + (HYPRE_Vector) F_array[fine_grid], + (HYPRE_Vector) U_array[fine_grid]); + } else { /* Generic relaxation interface */ diff --git a/src/parcsr_ls/par_mgr_stats.c b/src/parcsr_ls/par_mgr_stats.c index b58bc4e7d8..739bded6e9 100644 --- a/src/parcsr_ls/par_mgr_stats.c +++ b/src/parcsr_ls/par_mgr_stats.c @@ -26,9 +26,6 @@ hypre_MGRGetGlobalRelaxName(hypre_ParMGRData *mgr_data, switch (smoother_type) { - case -1: - return "--"; - case 0: return "Blk-Jacobi"; diff --git a/src/parcsr_ls/protos.h b/src/parcsr_ls/protos.h index dcfd4b5635..a0b9cb240b 100644 --- a/src/parcsr_ls/protos.h +++ b/src/parcsr_ls/protos.h @@ -2153,7 +2153,7 @@ HYPRE_Int hypre_MGRSetFSolver( void *mgr_vdata, HYPRE_Int (*fine_grid_solver_solve)(void*, void*, void*, void*), HYPRE_Int (*fine_grid_solver_setup)(void*, void*, void*, void*), void *fsolver ); -HYPRE_Int hypre_MGRSetFSolverAtLevel( HYPRE_Int level, void *mgr_vdata, void *fsolver ); +HYPRE_Int hypre_MGRSetFSolverAtLevel( void *mgr_vdata, void *fsolver, HYPRE_Int level ); HYPRE_Int hypre_MGRSetup( void *mgr_vdata, hypre_ParCSRMatrix *A, hypre_ParVector *f, hypre_ParVector *u ); HYPRE_Int hypre_MGRSolve( void *mgr_vdata, hypre_ParCSRMatrix *A, @@ -2227,6 +2227,8 @@ HYPRE_Int hypre_MGRSetNumRestrictSweeps( void *mgr_vdata, HYPRE_Int nsweeps ); HYPRE_Int hypre_MGRSetLevelSmoothType( void *mgr_vdata, HYPRE_Int *level_smooth_type ); HYPRE_Int hypre_MGRSetLevelSmoothIters( void *mgr_vdata, HYPRE_Int *level_smooth_iters ); HYPRE_Int hypre_MGRSetGlobalSmoothCycle( void *mgr_vdata, HYPRE_Int global_smooth_cycle ); +HYPRE_Int hypre_MGRSetGlobalSmootherAtLevel( void *mgr_vdata, HYPRE_Solver smoother, + HYPRE_Int level ); HYPRE_Int hypre_MGRSetPrintLevel( void *mgr_vdata, HYPRE_Int print_level ); HYPRE_Int hypre_MGRSetFrelaxPrintLevel( void *mgr_vdata, HYPRE_Int print_level ); HYPRE_Int hypre_MGRSetCoarseGridPrintLevel( void *mgr_vdata, HYPRE_Int print_level ); @@ -2287,7 +2289,7 @@ HYPRE_Int hypre_MGRBuildInterpApproximateInverse( hypre_ParCSRMatrix *A, HYPRE_I HYPRE_BigInt *num_cpts_global, hypre_ParCSRMatrix **P_ptr ); HYPRE_Int hypre_MGRTruncateAcfCPR( hypre_ParCSRMatrix *A_CF, hypre_ParCSRMatrix **A_CF_new_ptr ); -HYPRE_Int hypre_MGRBuildRFromW( HYPRE_Int *C_map, HYPRE_Int *F_map, +HYPRE_Int hypre_MGRBuildRFromW( hypre_IntArray *C_map, hypre_IntArray *F_map, HYPRE_BigInt global_num_rows_R, HYPRE_BigInt global_num_cols_R, HYPRE_BigInt *row_starts_R, HYPRE_BigInt *col_starts_R, hypre_ParCSRMatrix *W, hypre_ParCSRMatrix **R_ptr ); diff --git a/src/parcsr_mv/par_csr_matrix.c b/src/parcsr_mv/par_csr_matrix.c index fa50724036..ecfb036829 100644 --- a/src/parcsr_mv/par_csr_matrix.c +++ b/src/parcsr_mv/par_csr_matrix.c @@ -653,7 +653,7 @@ hypre_ParCSRMatrixCreateFromParVector(hypre_ParVector *b, if (hypre_VectorOwnsData(local_vector)) { hypre_CSRMatrixData(A_diag) = hypre_VectorData(local_vector); - hypre_VectorOwnsData(b) = 0; + hypre_VectorOwnsData(local_vector) = 0; } else { @@ -700,6 +700,9 @@ hypre_ParCSRMatrixCreateFromParVector(hypre_ParVector *b, hypre_TMemcpy(hypre_CSRMatrixJ(A_diag), A_diag_j, HYPRE_Int, num_nonzeros, memory_location, HYPRE_MEMORY_HOST); + + hypre_TFree(A_diag_i, HYPRE_MEMORY_HOST); + hypre_TFree(A_diag_j, HYPRE_MEMORY_HOST); } else { diff --git a/src/test/TEST_ij/fsai.saved.lassen b/src/test/TEST_ij/fsai.saved.lassen index 7b9f5002be..47b4ae6f59 100644 --- a/src/test/TEST_ij/fsai.saved.lassen +++ b/src/test/TEST_ij/fsai.saved.lassen @@ -149,4 +149,3 @@ Final Relative Residual Norm = 7.611745e-09 # Output file: fsai.out.118 Iterations = 38 Final Relative Residual Norm = 6.230831e-09 -