Skip to content

Commit 81eb36f

Browse files
committed
Fix "mg" preconditioner with petsc 3.14
This is dealing with bug https://gitlab.com/petsc/petsc/-/issues/868 Which is fixed for 3.15. Unfortunately no workaround exists in fortran, because even if we do provide the optional argument it still gets recognized for NULL and hits the bug. So instead write our own wrapper in C. This also drop support for petsc version <3.8 Note that Bionic official packages are 3.7 - but we have always supplied our own 3.8 package for it. Groovy and Hirsute are now on 3.14 Dropping support for <3.8 simplifies/removes a lot of the legacy workarounds. We no longer support linking with petsc without fortran modules (we never did for versions >=3.8).
1 parent 68ec400 commit 81eb36f

22 files changed

+62
-303
lines changed

aclocal.m4

+17-25
Original file line numberDiff line numberDiff line change
@@ -439,9 +439,9 @@ AC_COMPUTE_INT(PETSC_VERSION_MAJOR, "PETSC_VERSION_MAJOR", [#include "petscversi
439439
AC_COMPUTE_INT(PETSC_VERSION_MINOR, "PETSC_VERSION_MINOR", [#include "petscversion.h"],
440440
[AC_MSG_ERROR([Unknown petsc minor version])])
441441
AC_MSG_NOTICE([Detected PETSc version "$PETSC_VERSION_MAJOR"."$PETSC_VERSION_MINOR"])
442-
# if major<3 or minor<4
443-
if test "0$PETSC_VERSION_MAJOR" -lt 3 -o "0$PETSC_VERSION_MINOR" -lt 4; then
444-
AC_MSG_ERROR([Fluidity needs PETSc version >=3.4])
442+
# if major<3 or minor<8
443+
if test "0$PETSC_VERSION_MAJOR" -lt 3 -o "0$PETSC_VERSION_MINOR" -lt 8; then
444+
AC_MSG_ERROR([Fluidity needs PETSc version >=3.8])
445445
fi
446446
447447
AC_LANG(Fortran)
@@ -451,35 +451,27 @@ ac_ext=F90
451451
# may need some extra flags for testing that we don't want to use in the end
452452
SAVE_FCFLAGS="$FCFLAGS"
453453
454-
if test "$enable_petsc_fortran_modules" != "no" ; then
455-
# now try if the petsc fortran modules work:
456-
AC_LINK_IFELSE(
457-
[AC_LANG_PROGRAM([],[[
458-
use petsc
459-
integer :: ierr
460-
print*, "hello petsc"
461-
call PetscInitialize(PETSC_NULL_CHARACTER, ierr)
462-
]])],
463-
[
464-
AC_MSG_NOTICE([PETSc modules are working.])
465-
AC_DEFINE(HAVE_PETSC_MODULES,1,[Define if you have petsc fortran modules.] )
466-
FCFLAGS="$FCFLAGS -DHAVE_PETSC_MODULES"
467-
],
468-
[
469-
AC_MSG_NOTICE([PETSc modules don't work, using headers instead.])
470-
])
471-
elif test "0$PETSC_VERSION_MINOR" -ge 8; then
472-
AC_MSG_ERROR([PETSc v3.8 and newer requires petsc fortran modules. Do not use the --disable-petsc-fortran-modules option])
473-
fi
454+
# now try if the petsc fortran modules work:
455+
AC_LINK_IFELSE(
456+
[AC_LANG_PROGRAM([],[[
457+
use petsc
458+
integer :: ierr
459+
print*, "hello petsc"
460+
call PetscInitialize(PETSC_NULL_CHARACTER, ierr)
461+
]])],
462+
[
463+
AC_MSG_NOTICE([PETSc modules are working.])
464+
],
465+
[
466+
AC_MSG_ERROR([PETSc fortran modules cannot be used. Either it the petsc*.mod files cannot be found, or petsc has been built using a different fortran compiler.])
467+
])
474468
475469
# now try a more realistic program, it's a stripped down
476470
# petsc tutorial - using the headers in the same way as we do in the code
477471
AC_LINK_IFELSE(
478472
[AC_LANG_SOURCE([
479473
program test_petsc
480-
#ifdef HAVE_PETSC_MODULES
481474
use petsc
482-
#endif
483475
implicit none
484476
#include "petsc_legacy.h"
485477
double precision norm

assemble/Full_Projection.F90

-6
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ module Full_Projection
3131
use global_parameters
3232
use elements
3333
use spud
34-
#ifdef HAVE_PETSC_MODULES
3534
use petsc
36-
#endif
3735
use parallel_tools
3836
use data_structures
3937
use sparse_tools
@@ -359,11 +357,7 @@ subroutine petsc_solve_setup_full_projection(y,A,b,ksp,petsc_numbering_p,name,so
359357
else
360358
! workaround bug in petsc 3.8: missing CHKFORTRANNULLOBJECT, so PETSC_NULL_MAT isn't translated to C null
361359
! this however seems to do the trick:
362-
#if PETSC_VERSION_MINOR>=8
363360
S%v = 0
364-
#else
365-
S = PETSC_NULL_OBJECT
366-
#endif
367361
call MatCreateSchurComplement(inner_M%M,inner_M%M,G,G_t_comp,S,A,ierr)
368362
end if
369363

assemble/tests/test_matrix_free.F90

-2
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,7 @@ subroutine petsc_solve_matrix_free(x, matrix, rhs)
236236
use petsc_tools
237237
use matrix_free_solvers
238238

239-
#ifdef HAVE_PETSC_MODULES
240239
use petsc
241-
#endif
242240
implicit none
243241
#include "petsc_legacy.h"
244242
type(scalar_field), intent(inout) :: x

assemble/tests/test_pressure_solve.F90

+1-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ subroutine test_pressure_solve
1515
use boundary_conditions
1616
use global_parameters, only: OPTION_PATH_LEN
1717
use free_surface_module
18-
#ifdef HAVE_PETSC_MODULES
19-
use petsc
20-
#endif
18+
use petsc
2119
implicit none
2220
#include "petsc_legacy.h"
2321

configure

+12-35
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,6 @@ with_femdem
785785
with_psmile
786786
with_netcdf
787787
with_exodusii
788-
enable_petsc_fortran_modules
789788
with_x
790789
enable_sam
791790
enable_dp
@@ -1463,12 +1462,6 @@ Optional Features:
14631462
--enable-shared Compile objects with -fPIC to enable the 'make
14641463
shared' target.
14651464
--enable-verbose turns on super verbosity
1466-
--disable-petsc-fortran-modules
1467-
By default fluidity tries to use fortran modules
1468-
provided with petsc. Use
1469-
--disable-petsc-fortran-modules if these are known
1470-
to be not functional (e.g. compiled with different
1471-
compiler version)
14721465
--enable-sam use sam rather than zoltan for adaptive load
14731466
rebalancing
14741467
--enable-dp=flag compile with 64 bit floating point numbers (default)
@@ -6001,7 +5994,7 @@ then
60015994
if test -z "$PYTHON_VERSION"; then
60025995
# if PYTHON_VERSION is set we use python$PYTHON_VERSION as the python interpreter
60035996
# if not, if there is no `python` in the path, or there is a `python` but its version is <3
6004-
# then use `python3` (by setting PETSC_VERSION=3).
5997+
# then use `python3` (by setting PYTHON_VERSION=3).
60055998
# If there *is* a `python` of version 3, we use that
60065999
# Extract the first word of "python", so it can be a program name with args.
60076000
set dummy python; ac_word=$2
@@ -11791,11 +11784,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
1179111784
1179211785
1179311786
11794-
fi
11795-
11796-
# Check whether --enable-petsc-fortran-modules was given.
11797-
if test "${enable_petsc_fortran_modules+set}" = set; then :
11798-
enableval=$enable_petsc_fortran_modules;
1179911787
fi
1180011788
1180111789
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5
@@ -12724,9 +12712,9 @@ fi
1272412712
1272512713
{ $as_echo "$as_me:${as_lineno-$LINENO}: Detected PETSc version \"$PETSC_VERSION_MAJOR\".\"$PETSC_VERSION_MINOR\"" >&5
1272612714
$as_echo "$as_me: Detected PETSc version \"$PETSC_VERSION_MAJOR\".\"$PETSC_VERSION_MINOR\"" >&6;}
12727-
# if major<3 or minor<4
12728-
if test "0$PETSC_VERSION_MAJOR" -lt 3 -o "0$PETSC_VERSION_MINOR" -lt 4; then
12729-
as_fn_error $? "Fluidity needs PETSc version >=3.4" "$LINENO" 5
12715+
# if major<3 or minor<8
12716+
if test "0$PETSC_VERSION_MAJOR" -lt 3 -o "0$PETSC_VERSION_MINOR" -lt 8; then
12717+
as_fn_error $? "Fluidity needs PETSc version >=3.8" "$LINENO" 5
1273012718
fi
1273112719
1273212720
ac_ext=${ac_fc_srcext-f}
@@ -12740,47 +12728,36 @@ ac_ext=F90
1274012728
# may need some extra flags for testing that we don't want to use in the end
1274112729
SAVE_FCFLAGS="$FCFLAGS"
1274212730
12743-
if test "$enable_petsc_fortran_modules" != "no" ; then
12744-
# now try if the petsc fortran modules work:
12745-
cat > conftest.$ac_ext <<_ACEOF
12731+
# now try if the petsc fortran modules work:
12732+
cat > conftest.$ac_ext <<_ACEOF
1274612733
program main
1274712734
12748-
use petsc
12749-
integer :: ierr
12750-
print*, "hello petsc"
12751-
call PetscInitialize(PETSC_NULL_CHARACTER, ierr)
12735+
use petsc
12736+
integer :: ierr
12737+
print*, "hello petsc"
12738+
call PetscInitialize(PETSC_NULL_CHARACTER, ierr)
1275212739
1275312740
end
1275412741
_ACEOF
1275512742
if ac_fn_fc_try_link "$LINENO"; then :
1275612743
12757-
{ $as_echo "$as_me:${as_lineno-$LINENO}: PETSc modules are working." >&5
12744+
{ $as_echo "$as_me:${as_lineno-$LINENO}: PETSc modules are working." >&5
1275812745
$as_echo "$as_me: PETSc modules are working." >&6;}
1275912746
12760-
$as_echo "#define HAVE_PETSC_MODULES 1" >>confdefs.h
12761-
12762-
FCFLAGS="$FCFLAGS -DHAVE_PETSC_MODULES"
12763-
1276412747
else
1276512748
12766-
{ $as_echo "$as_me:${as_lineno-$LINENO}: PETSc modules don't work, using headers instead." >&5
12767-
$as_echo "$as_me: PETSc modules don't work, using headers instead." >&6;}
12749+
as_fn_error $? "PETSc fortran modules cannot be used. Either it the petsc*.mod files cannot be found, or petsc has been built using a different fortran compiler." "$LINENO" 5
1276812750
1276912751
fi
1277012752
rm -f core conftest.err conftest.$ac_objext \
1277112753
conftest$ac_exeext conftest.$ac_ext
12772-
elif test "0$PETSC_VERSION_MINOR" -ge 8; then
12773-
as_fn_error $? "PETSc v3.8 and newer requires petsc fortran modules. Do not use the --disable-petsc-fortran-modules option" "$LINENO" 5
12774-
fi
1277512754
1277612755
# now try a more realistic program, it's a stripped down
1277712756
# petsc tutorial - using the headers in the same way as we do in the code
1277812757
cat > conftest.$ac_ext <<_ACEOF
1277912758
1278012759
program test_petsc
12781-
#ifdef HAVE_PETSC_MODULES
1278212760
use petsc
12783-
#endif
1278412761
implicit none
1278512762
#include "petsc_legacy.h"
1278612763
double precision norm

configure.in

+1-4
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ then
193193
if test -z "$PYTHON_VERSION"; then
194194
# if PYTHON_VERSION is set we use python$PYTHON_VERSION as the python interpreter
195195
# if not, if there is no `python` in the path, or there is a `python` but its version is <3
196-
# then use `python3` (by setting PETSC_VERSION=3).
196+
# then use `python3` (by setting PYTHON_VERSION=3).
197197
# If there *is* a `python` of version 3, we use that
198198
AC_CHECK_PROG(have_bare_python, python, "yes")
199199
if test "x$have_bare_python" = "xyes"; then
@@ -828,9 +828,6 @@ if test "$with_exodusii" = "yes" ; then
828828
])
829829
fi
830830
AC_SUBST(HAVE_EXODUSII)
831-
AC_ARG_ENABLE(petsc-fortran-modules,
832-
[AC_HELP_STRING([--disable-petsc-fortran-modules],
833-
[By default fluidity tries to use fortran modules provided with petsc. Use --disable-petsc-fortran-modules if these are known to be not functional (e.g. compiled with different compiler version)])])
834831
ACX_PETSc([AC_MSG_NOTICE(["PETSc found, enabling scalable solver"])], [AC_MSG_ERROR(["PETSc not found"])])
835832
ACX_hypre([AC_MSG_NOTICE(["hypre found, enabling hypre preconditioners"])], [AC_MSG_WARN(["hypre not found"])])
836833
CPPFLAGS="$CPPFLAGS -DHAVE_PETSC"

femtools/ISCopyIndices.cpp

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,18 @@
11
#include "confdefs.h"
22
#include "petsc.h"
3-
#if PETSC_VERSION_MINOR==0
4-
#include "petscfix.h"
5-
#include "petscis.h"
6-
#endif
73

84
#include <string.h>
95

106
extern "C" {
117
void iscopyindices_(IS *is, PetscInt *iarray,PetscErrorCode *ierr);
128
void petscobjectreference_(PetscObject obj, int *__ierr );
9+
void pcmgsetlevels_nocomms_(PC *pc, PetscInt *levels, int *ierr);
1310
}
1411

1512
// our own version of IsGetIndices, that just does a copy
1613
// to avoid silly fortran interface issues
1714
void iscopyindices_(IS *is, PetscInt *iarray,PetscErrorCode *ierr){
18-
#if PETSC_VERSION_MAJOR==3
1915
const PetscInt *iptr;
20-
#else
21-
PetscInt *iptr;
22-
#endif
2316
PetscInt n;
2417

2518
*ierr = ISGetIndices(*is, &iptr); if (*ierr) return;
@@ -58,3 +51,14 @@ void petscobjectreference_(PetscObject obj, int *__ierr ){
5851
}
5952

6053

54+
// This is a woraround bug in https://gitlab.com/petsc/petsc/-/issues/868
55+
// In 3.14 not only is it impossible to "fake" a NULL argument using PETSC_NULL_KSP
56+
// as we'd done previously, even if you do provide a comms filled with MPI_COMM_WORLD
57+
// that because MPI_COMM_WORLD==0 it is still mistaken for a NULL argument and hits the
58+
// bug in the petsc fortran wrapper for this routine
59+
// So instead we just write our own wrapper without the comms argument:
60+
void pcmgsetlevels_nocomms_(PC *pc, PetscInt *levels, int *ierr){
61+
*ierr = PCMGSetLevels(*pc, *levels, NULL);
62+
}
63+
64+

femtools/Multigrid.F90

+4-8
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ module multigrid
66
use spud
77
use futils
88
use parallel_tools
9-
#ifdef HAVE_PETSC_MODULES
109
use petsc
11-
#endif
1210
use Sparse_tools
1311
use Petsc_Tools
1412
use sparse_tools_petsc
@@ -412,8 +410,7 @@ subroutine SetupSmoothedAggregation(prec, matrix, ierror, &
412410
end do
413411
deallocate(matrices, prolongators, contexts)
414412
! Need to set n/o levels (to 1) otherwise PCDestroy will fail:
415-
! See note below about PETSC_NULL_KSP argument
416-
call PCMGSetLevels(prec, 1, PETSC_NULL_KSP, ierr)
413+
call PCMGSetLevels_nocomms(prec, 1, ierr)
417414
ierror=1
418415
return
419416
end if
@@ -435,10 +432,9 @@ subroutine SetupSmoothedAggregation(prec, matrix, ierror, &
435432
nolevels=i
436433
end if
437434

438-
! NOTE: in petsc v3.8 it's unclear what the legal null argument should be for MPI_Comm *comms
439-
! it does not accept any scalar null object (e.g. PETSC_NULL_INTEGER) - luckily there's no
440-
! explicit interface so we can pass this instead which does get correctly translated to a null argument
441-
call PCMGSetLevels(prec, nolevels, PETSC_NULL_KSP, ierr)
435+
! NOTE: we use a wrapper around PCMGLEVELS defined in femtools/ISCopyIndices.cpp
436+
! to deal with bug in https://gitlab.com/petsc/petsc/-/issues/868
437+
call PCMGSetLevels_nocomms(prec, nolevels, ierr)
442438

443439
if (lno_top_smoothing) then
444440
top_level=nolevels-2

0 commit comments

Comments
 (0)