[BUG FIX] Use MPI ICB types (mpi_f08) instead of integer(kind=i_int).

This commit is contained in:
Franck HOUSSEN
2022-08-14 23:06:47 +02:00
parent e0d67054f5
commit 68b2840c63
9 changed files with 178 additions and 2 deletions
+1
View File
@@ -29,6 +29,7 @@ arpack-ng - 3.9.0
* arpackSolver: fix error messages.
* [BUG FIX] Make sure iseed is always initialized to values allowed by lapack ?larnv.
* [BUG FIX] According to lapack doc of ?larnv, iseed(4) must be odd.
* [BUG FIX] Use MPI ICB types (mpi_f08) instead of integer(kind=i_int).
[ Haoyang Liu ]
* CMake: minimum required version changed to 3.0
+39 -1
View File
@@ -207,6 +207,35 @@ if (MPI)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${MPI_Fortran_COMPILE_FLAG}")
# Check if we can use ISO_C_BINDING provided by MPI.
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/PROG_ICB.f90
"
PROGRAM PROG_ICB
USE :: mpi_f08
IMPLICIT NONE
type(MPI_Comm) comm
type(MPI_Status) status
END PROGRAM PROG_ICB
")
try_compile(COMPILE_ICB ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/PROG_ICB.f90 LINK_LIBRARIES MPI::MPI_Fortran)
if(NOT ${COMPILE_ICB})
message("-- MPI library does not support iso_c_binding.")
set(HAVE_MPI_ICB 0)
else()
message("-- MPI library does support iso_c_binding.")
set(HAVE_MPI_ICB 1)
add_compile_definitions(HAVE_MPI_ICB=1)
endif()
# As MPI can be used with or without ISO_C_BINDING (#ifdef), we need to preprocess code before compiling.
if ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -cpp")
elseif ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "Intel")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fpp")
else ()
message(WARNING "build script does not know how to preprocess Fortran code: set it manually via FFLAGS.")
endif ()
if(ICB)
if (NOT TARGET MPI::MPI_C) # Search only if not already found by upper CMakeLists.txt
include(FindMPI)
@@ -376,6 +405,15 @@ if (INTERFACE64)
else ()
message(WARNING "build script does not know how to make your Fortran compiler use 64-bit integers: set it manually via FFLAGS.")
endif ()
# Compiling with INTERFACE64 means you need to have control on integer type.
# If MPI is also required, then MPI types must be consistent with ILP64:
# to make sure of this, we must use the ISO_C_BINDING API provided by MPI.
if (MPI)
if (NOT HAVE_MPI_ICB)
message(FATAL_ERROR "ILP64 support require use of MPI library which provides ISO_C_BINDING support.")
endif()
endif()
else ()
set(INTERFACE64 0)
endif ()
@@ -848,7 +886,7 @@ endfunction(cprsummary)
message("-- Configuration summary for arpack-ng-${arpack_ng_VERSION}:")
message(" -- prefix: ${CMAKE_INSTALL_PREFIX}")
message(" -- MPI: ${MPI}")
message(" -- MPI: ${MPI} (ICB provided ${HAVE_MPI_ICB})")
message(" -- ICB: ${ICB}")
message(" -- INTERFACE64: ${INTERFACE64}")
cprsummary("FC" "${CMAKE_Fortran_COMPILER}"
+14
View File
@@ -4,9 +4,16 @@ subroutine pcnaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
iparam, ipntr, workd, workl, lworkl, rwork, info) &
bind(c, name="pcnaupd_c")
use :: iso_c_binding
#ifdef HAVE_MPI_ICB
use :: mpi_f08
#endif
implicit none
#include "arpackicb.h"
#ifdef HAVE_MPI_ICB
type(MPI_Comm), value, intent(in) :: comm
#else
integer(kind=i_int), value, intent(in) :: comm
#endif
integer(kind=i_int), intent(inout) :: ido
character(kind=c_char), intent(in) :: bmat
integer(kind=i_int), value, intent(in) :: n
@@ -41,9 +48,16 @@ subroutine pcneupd_c(comm, rvec, howmny, select, d, z, ldz, sigma, workev,&
iparam, ipntr, workd, workl, lworkl, rwork, info) &
bind(c, name="pcneupd_c")
use :: iso_c_binding
#ifdef HAVE_MPI_ICB
use :: mpi_f08
#endif
implicit none
#include "arpackicb.h"
#ifdef HAVE_MPI_ICB
type(MPI_Comm), value, intent(in) :: comm
#else
integer(kind=i_int), value, intent(in) :: comm
#endif
integer(kind=i_int), value, intent(in) :: rvec
character(kind=c_char), intent(in) :: howmny
integer(kind=i_int), dimension(ncv), intent(in) :: select
+14
View File
@@ -4,9 +4,16 @@ subroutine pdnaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
iparam, ipntr, workd, workl, lworkl, info) &
bind(c, name="pdnaupd_c")
use :: iso_c_binding
#ifdef HAVE_MPI_ICB
use :: mpi_f08
#endif
implicit none
#include "arpackicb.h"
#ifdef HAVE_MPI_ICB
type(MPI_Comm), value, intent(in) :: comm
#else
integer(kind=i_int), value, intent(in) :: comm
#endif
integer(kind=i_int), intent(inout) :: ido
character(kind=c_char), intent(in) :: bmat
integer(kind=i_int), value, intent(in) :: n
@@ -41,9 +48,16 @@ subroutine pdneupd_c(comm, rvec, howmny, select, &
iparam, ipntr, workd, workl, lworkl, info) &
bind(c, name="pdneupd_c")
use :: iso_c_binding
#ifdef HAVE_MPI_ICB
use :: mpi_f08
#endif
implicit none
#include "arpackicb.h"
#ifdef HAVE_MPI_ICB
type(MPI_Comm), value, intent(in) :: comm
#else
integer(kind=i_int), value, intent(in) :: comm
#endif
integer(kind=i_int), value, intent(in) :: rvec
character(kind=c_char), intent(in) :: howmny
integer(kind=i_int), dimension(ncv), intent(in) :: select
+14
View File
@@ -4,9 +4,16 @@ subroutine pdsaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
iparam, ipntr, workd, workl, lworkl, info) &
bind(c, name="pdsaupd_c")
use :: iso_c_binding
#ifdef HAVE_MPI_ICB
use :: mpi_f08
#endif
implicit none
#include "arpackicb.h"
#ifdef HAVE_MPI_ICB
type(MPI_Comm), value, intent(in) :: comm
#else
integer(kind=i_int), value, intent(in) :: comm
#endif
integer(kind=i_int), intent(inout) :: ido
character(kind=c_char), intent(in) :: bmat
integer(kind=i_int), value, intent(in) :: n
@@ -40,9 +47,16 @@ subroutine pdseupd_c(comm, rvec, howmny, select, d, z, ldz, sigma,&
iparam, ipntr, workd, workl, lworkl, info) &
bind(c, name="pdseupd_c")
use :: iso_c_binding
#ifdef HAVE_MPI_ICB
use :: mpi_f08
#endif
implicit none
#include "arpackicb.h"
#ifdef HAVE_MPI_ICB
type(MPI_Comm), value, intent(in) :: comm
#else
integer(kind=i_int), value, intent(in) :: comm
#endif
integer(kind=i_int), value, intent(in) :: rvec
character(kind=c_char), intent(in) :: howmny
integer(kind=i_int), dimension(ncv), intent(in) :: select
+14
View File
@@ -4,9 +4,16 @@ subroutine psnaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
iparam, ipntr, workd, workl, lworkl, info) &
bind(c, name="psnaupd_c")
use :: iso_c_binding
#ifdef HAVE_MPI_ICB
use :: mpi_f08
#endif
implicit none
#include "arpackicb.h"
#ifdef HAVE_MPI_ICB
type(MPI_Comm), value, intent(in) :: comm
#else
integer(kind=i_int), value, intent(in) :: comm
#endif
integer(kind=i_int), intent(inout) :: ido
character(kind=c_char), intent(in) :: bmat
integer(kind=i_int), value, intent(in) :: n
@@ -41,9 +48,16 @@ subroutine psneupd_c(comm, rvec, howmny, select, &
iparam, ipntr, workd, workl, lworkl, info) &
bind(c, name="psneupd_c")
use :: iso_c_binding
#ifdef HAVE_MPI_ICB
use :: mpi_f08
#endif
implicit none
#include "arpackicb.h"
#ifdef HAVE_MPI_ICB
type(MPI_Comm), value, intent(in) :: comm
#else
integer(kind=i_int), value, intent(in) :: comm
#endif
integer(kind=i_int), value, intent(in) :: rvec
character(kind=c_char), intent(in) :: howmny
integer(kind=i_int), dimension(ncv), intent(in) :: select
+14
View File
@@ -4,9 +4,16 @@ subroutine pssaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
iparam, ipntr, workd, workl, lworkl, info) &
bind(c, name="pssaupd_c")
use :: iso_c_binding
#ifdef HAVE_MPI_ICB
use :: mpi_f08
#endif
implicit none
#include "arpackicb.h"
#ifdef HAVE_MPI_ICB
type(MPI_Comm), value, intent(in) :: comm
#else
integer(kind=i_int), value, intent(in) :: comm
#endif
integer(kind=i_int), intent(inout) :: ido
character(kind=c_char), intent(in) :: bmat
integer(kind=i_int), value, intent(in) :: n
@@ -40,9 +47,16 @@ subroutine psseupd_c(comm, rvec, howmny, select, d, z, ldz, sigma,&
iparam, ipntr, workd, workl, lworkl, info) &
bind(c, name="psseupd_c")
use :: iso_c_binding
#ifdef HAVE_MPI_ICB
use :: mpi_f08
#endif
implicit none
#include "arpackicb.h"
#ifdef HAVE_MPI_ICB
type(MPI_Comm), value, intent(in) :: comm
#else
integer(kind=i_int), value, intent(in) :: comm
#endif
integer(kind=i_int), value, intent(in) :: rvec
character(kind=c_char), intent(in) :: howmny
integer(kind=i_int), dimension(ncv), intent(in) :: select
+14
View File
@@ -4,9 +4,16 @@ subroutine pznaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
iparam, ipntr, workd, workl, lworkl, rwork, info) &
bind(c, name="pznaupd_c")
use :: iso_c_binding
#ifdef HAVE_MPI_ICB
use :: mpi_f08
#endif
implicit none
#include "arpackicb.h"
#ifdef HAVE_MPI_ICB
type(MPI_Comm), value, intent(in) :: comm
#else
integer(kind=i_int), value, intent(in) :: comm
#endif
integer(kind=i_int), intent(inout) :: ido
character(kind=c_char), intent(in) :: bmat
integer(kind=i_int), value, intent(in) :: n
@@ -41,9 +48,16 @@ subroutine pzneupd_c(comm, rvec, howmny, select, d, z, ldz, sigma, workev,&
iparam, ipntr, workd, workl, lworkl, rwork, info) &
bind(c, name="pzneupd_c")
use :: iso_c_binding
#ifdef HAVE_MPI_ICB
use :: mpi_f08
#endif
implicit none
#include "arpackicb.h"
#ifdef HAVE_MPI_ICB
type(MPI_Comm), value, intent(in) :: comm
#else
integer(kind=i_int), value, intent(in) :: comm
#endif
integer(kind=i_int), value, intent(in) :: rvec
character(kind=c_char), intent(in) :: howmny
integer(kind=i_int), dimension(ncv), intent(in) :: select
+54 -1
View File
@@ -146,8 +146,61 @@ AS_IF([test x"$enable_mpi" != x"no"], [
FCFLAGS=$FCFLAGS_SAVE
FFLAGS=$FFLAGS_SAVE
dnl Check if we can use ISO_C_BINDING provided by MPI.
AC_LANG_PUSH([Fortran 77])
AC_MSG_CHECKING([for MPI support for iso_c_binding])
AC_LINK_IFELSE(
[
AC_LANG_PROGRAM(
[],
[
USE :: mpi_f08
IMPLICIT NONE
type(MPI_Comm) comm
type(MPI_Status) status
]
)
],
[
AC_MSG_RESULT([yes])
FCFLAGS=$FCFLAGS" -DHAVE_MPI_ICB"
FFLAGS=$FFLAGS" -DHAVE_MPI_ICB"
AS_VAR_SET([enable_mpi_icb], [yes])
],
[
AC_MSG_RESULT([no])
AC_MSG_WARN([MPI library does not support iso_c_binding])
AS_VAR_SET([enable_mpi_icb], [no])
]
)
AC_LANG_POP([Fortran 77])
dnl As MPI can be used with or without ISO_C_BINDING (#ifdef), we need to preprocess code before compiling.
AC_LANG_PUSH([Fortran 77])
AX_CHECK_COMPILE_FLAG(-cpp, FFLAGS="$FFLAGS -cpp",
AX_CHECK_COMPILE_FLAG(-fpp, FFLAGS="$FFLAGS -fpp",
AC_MSG_WARN([configure does not know how to preprocess Fortran code: set it manually via FFLAGS.])))
AC_LANG_POP([Fortran 77])
AC_LANG_PUSH([Fortran])
AX_CHECK_COMPILE_FLAG(-cpp, FCFLAGS="$FCFLAGS -cpp",
AX_CHECK_COMPILE_FLAG(-fpp, FCFLAGS="$FCFLAGS -fpp",
AC_MSG_WARN([configure does not know how to preprocess Fortran code: set it manually via FCFLAGS.])))
AC_LANG_POP([Fortran])
])
dnl Compiling with INTERFACE64 means you need to have control on integer type.
dnl If MPI is also required, then MPI types must be consistent with ILP64:
dnl to make sure of this, we must use the ISO_C_BINDING API provided by MPI.
if test x"$INTERFACE64" == x"1"; then
if test x"$enable_mpi" != x"no"; then
if test x"$enable_mpi_icb" == x"no"; then
AC_MSG_ERROR([ILP64 support require use of MPI library which provides ISO_C_BINDING support])
fi
fi
fi
if test x"$enable_icb" != x"no"; then
if test x"$enable_mpi" != x"no"; then
FCFLAGS_SAVE=$FCFLAGS
@@ -348,7 +401,7 @@ AC_MSG_RESULT([
Configuration summary for $PACKAGE_STRING
--------------------------------------------------
Installation prefix : $prefix
MPI enabled : $enable_mpi
MPI enabled : $enable_mpi (ICB provided $enable_mpi_icb)
ICB enabled : $enable_icb
INTERFACE64 : $INTERFACE64
F77 : $F77