|
|
|
|
@ -1,7 +1,13 @@
|
|
|
|
|
# FDEFINES : -DHAVE_LAPACK -DHAVE_FINAL -DHAVE_ISO_FORTRAN_ENV -DHAVE_FLUSH_STMT -DHAVE_VOLATILE -DSERIAL_MPI -DMPI_MOD
|
|
|
|
|
# CDEFINES : -DLowerUnderscore -DPtr64Bits
|
|
|
|
|
|
|
|
|
|
#-----------------------------------
|
|
|
|
|
# Set oldest allowable CMake version
|
|
|
|
|
#-----------------------------------
|
|
|
|
|
cmake_minimum_required(VERSION 3.4)
|
|
|
|
|
cmake_minimum_required(VERSION 3.10)
|
|
|
|
|
cmake_policy(VERSION 3.10.0...3.12.4)
|
|
|
|
|
|
|
|
|
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------
|
|
|
|
|
# Define canonical CMake build types and extras
|
|
|
|
|
@ -14,7 +20,7 @@ set_property ( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYP
|
|
|
|
|
#-----------------------------------------------------
|
|
|
|
|
# Determine version from .VERSION file or git describe
|
|
|
|
|
#-----------------------------------------------------
|
|
|
|
|
include("${CMAKE_SOURCE_DIR}/cmake/setVersion.cmake")
|
|
|
|
|
include(setVersion)
|
|
|
|
|
set_version(
|
|
|
|
|
VERSION_VARIABLE PSBLAS_Version
|
|
|
|
|
GIT_DESCRIBE_VAR full_git_describe
|
|
|
|
|
@ -24,7 +30,9 @@ message( STATUS "Building PSBLAS version: ${full_git_describe}" )
|
|
|
|
|
#------------------------------------------
|
|
|
|
|
# Name project and specify source languages
|
|
|
|
|
#------------------------------------------
|
|
|
|
|
project(psblas VERSION "${PSBLAS_Version}" LANGUAGES C Fortran)
|
|
|
|
|
project(psblas
|
|
|
|
|
VERSION "${PSBLAS_Version}"
|
|
|
|
|
LANGUAGES C Fortran)
|
|
|
|
|
|
|
|
|
|
#-----------------------------------------------------------------
|
|
|
|
|
# Define a target to create a checksummed & signed release archive
|
|
|
|
|
@ -40,24 +48,7 @@ endif()
|
|
|
|
|
#--------------------------
|
|
|
|
|
# Prohibit in-source builds
|
|
|
|
|
#--------------------------
|
|
|
|
|
if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
|
|
|
|
|
message(FATAL_ERROR "ERROR! "
|
|
|
|
|
"CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}"
|
|
|
|
|
" == CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}"
|
|
|
|
|
"\nThis archive does not support in-source builds:\n"
|
|
|
|
|
"You must now delete the CMakeCache.txt file and the CMakeFiles/ directory under "
|
|
|
|
|
"the 'src' source directory or you will not be able to configure correctly!"
|
|
|
|
|
"\nYou must now run something like:\n"
|
|
|
|
|
" $ rm -r CMakeCache.txt CMakeFiles/"
|
|
|
|
|
"\n"
|
|
|
|
|
"Please create a directory outside the ${CMAKE_PROJECT_NAME} source tree and build under that outside directory "
|
|
|
|
|
"in a manner such as\n"
|
|
|
|
|
" $ mkdir build\n"
|
|
|
|
|
" $ cd build\n"
|
|
|
|
|
" $ CC=gcc FC=gfortran cmake -DBUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/path/to/install/dir /path/to/psblas3/src/dir \n"
|
|
|
|
|
"\nsubstituting the appropriate syntax for your shell (the above line assumes the bash shell)."
|
|
|
|
|
)
|
|
|
|
|
endif()
|
|
|
|
|
include(CheckOutOfSourceBuild)
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------
|
|
|
|
|
# Define coverage flags and report untested compilers
|
|
|
|
|
@ -76,12 +67,11 @@ else()
|
|
|
|
|
)
|
|
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
#-------------------------------------
|
|
|
|
|
# Fortran name mangling intro-spection
|
|
|
|
|
#-------------------------------------
|
|
|
|
|
include("${CMAKE_SOURCE_DIR}/cmake/CapitalizeString.cmake")
|
|
|
|
|
#------------------------------------
|
|
|
|
|
# Fortran name mangling introspection
|
|
|
|
|
#------------------------------------
|
|
|
|
|
include(FortranCInterface)
|
|
|
|
|
CapitalizeString(${FortranCInterface_GLOBAL__CASE} fc_case)
|
|
|
|
|
string(TOUPPER ${FortranCInterface_GLOBAL__CASE} fc_case)
|
|
|
|
|
message(STATUS "Name mangling capitalization: ${fc_case}")
|
|
|
|
|
message(STATUS "Name mangling fortran global suffix underscore: ${FortranCInterface_GLOBAL__SUFFIX}")
|
|
|
|
|
if(FortranCInterface_GLOBAL__SUFFIX STREQUAL "")
|
|
|
|
|
@ -91,7 +81,7 @@ elseif(FortranCInterface_GLOBAL__SUFFIX STREQUAL "_")
|
|
|
|
|
elseif(FortranCInterface_GLOBAL__SUFFIX STREQUAL "__")
|
|
|
|
|
add_definitions("-D${fc_case}DoubleUnderscore")
|
|
|
|
|
else()
|
|
|
|
|
message( FATAL_ERROR "Fortran name mangling suffix, \'${FortranCInterface_GLOBAL__SUFFIX}\', unknown to morfeus/NEMO")
|
|
|
|
|
message( FATAL_ERROR "Fortran name mangling suffix, \'${FortranCInterface_GLOBAL__SUFFIX}\', unknown to PSBLAS")
|
|
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------
|
|
|
|
|
@ -154,228 +144,142 @@ CHECK_Fortran_SOURCE_COMPILES(
|
|
|
|
|
if(HAVE_FLUSH_STMT)
|
|
|
|
|
add_definitions(-DHAVE_FLUSH_STMT)
|
|
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------------
|
|
|
|
|
# Find MPI and set some flags so that FC and CC can point to gfortran and gcc
|
|
|
|
|
#----------------------------------------------------------------------------
|
|
|
|
|
# If the user passes FC=mpifort etc. check and prefer that location
|
|
|
|
|
get_filename_component( FTN_COMPILER_NAME "${CMAKE_Fortran_COMPILER}"
|
|
|
|
|
NAME )
|
|
|
|
|
get_filename_component( C_COMPILER_NAME "${CMAKE_C_COMPILER}"
|
|
|
|
|
NAME )
|
|
|
|
|
get_filename_component( FTN_COMPILER_DIR "${CMAKE_Fortran_COMPILER}"
|
|
|
|
|
REALPATH )
|
|
|
|
|
get_filename_component( C_COMPILER_DIR "${CMAKE_C_COMPILER}"
|
|
|
|
|
REALPATH )
|
|
|
|
|
|
|
|
|
|
if (FTN_COMPILER_NAME MATCHES "^[mM][pP][iI]")
|
|
|
|
|
set (MPI_Fortran_COMPILER "${CMAKE_Fortran_COMPILER}")
|
|
|
|
|
CHECK_Fortran_SOURCE_COMPILES(
|
|
|
|
|
"
|
|
|
|
|
module conftest_mod
|
|
|
|
|
type foo
|
|
|
|
|
integer :: i
|
|
|
|
|
contains
|
|
|
|
|
final :: destroy_foo
|
|
|
|
|
end type foo
|
|
|
|
|
private destroy_foo
|
|
|
|
|
contains
|
|
|
|
|
subroutine destroy_foo(a)
|
|
|
|
|
type(foo) :: a
|
|
|
|
|
! Just a test
|
|
|
|
|
end subroutine destroy_foo
|
|
|
|
|
end module conftest_mod
|
|
|
|
|
program conftest
|
|
|
|
|
use conftest_mod
|
|
|
|
|
type(foo) :: foovar
|
|
|
|
|
end program"
|
|
|
|
|
HAVE_FINAL
|
|
|
|
|
SRC_EXT f90
|
|
|
|
|
)
|
|
|
|
|
if(HAVE_FINAL)
|
|
|
|
|
add_definitions(-DHAVE_FINAL)
|
|
|
|
|
endif()
|
|
|
|
|
if (C_COMPILER_NAME MATCHES "^[mM][pP][iI]")
|
|
|
|
|
set (MPI_C_COMPILER "${CMAKE_C_COMPILER}")
|
|
|
|
|
CHECK_Fortran_SOURCE_COMPILES(
|
|
|
|
|
"
|
|
|
|
|
program xtt
|
|
|
|
|
type foo
|
|
|
|
|
integer :: i
|
|
|
|
|
end type foo
|
|
|
|
|
type, extends(foo) :: new_foo
|
|
|
|
|
integer :: j
|
|
|
|
|
end type new_foo
|
|
|
|
|
class(foo), allocatable :: fooab
|
|
|
|
|
type(new_foo) :: nfv
|
|
|
|
|
integer :: info
|
|
|
|
|
allocate(fooab, mold=nfv, stat=info)
|
|
|
|
|
end program"
|
|
|
|
|
HAVE_MOLD
|
|
|
|
|
SRC_EXT f90)
|
|
|
|
|
if(HAVE_MOLD)
|
|
|
|
|
add_definitions(-DHAVE_MOLD)
|
|
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
find_package( MPI )
|
|
|
|
|
|
|
|
|
|
if ( (NOT MPI_C_FOUND) OR (NOT MPI_Fortran_FOUND) OR (NOT MPIEXEC))
|
|
|
|
|
find_program (MY_MPI_EXEC NAMES mpirun mpiexec lamexec srun
|
|
|
|
|
HINTS "${FTN_COMPILER_DIR}" "${C_COMPILER_DIR}"
|
|
|
|
|
PATH_SUFFIXES bin)
|
|
|
|
|
set ( MPI_HOME "${MPI_HOME}" "${MY_MPI_EXEC}" "${MY_MPI_EXEC}/.." )
|
|
|
|
|
find_package( MPI REQUIRED )
|
|
|
|
|
CHECK_Fortran_SOURCE_COMPILES(
|
|
|
|
|
"
|
|
|
|
|
program conftest
|
|
|
|
|
type foo
|
|
|
|
|
integer :: i
|
|
|
|
|
end type foo
|
|
|
|
|
type, extends(foo) :: bar
|
|
|
|
|
integer j
|
|
|
|
|
end type bar
|
|
|
|
|
type(bar) :: barvar
|
|
|
|
|
end program "
|
|
|
|
|
HAVE_EXTENDS_TYPE_OF
|
|
|
|
|
SRC_EXT f90)
|
|
|
|
|
if(HAVE_EXTENDS_TYPE_OF)
|
|
|
|
|
add_definitions(-DHAVE_EXTENDS_TYPE_OF)
|
|
|
|
|
endif()
|
|
|
|
|
list(REMOVE_DUPLICATES MPI_Fortran_INCLUDE_PATH)
|
|
|
|
|
|
|
|
|
|
# Test for consistent MPI environment
|
|
|
|
|
if (NOT MPIEXEC)
|
|
|
|
|
message ( ERROR "CMake failed to find `mpiexec` or similar. If MPI is installed
|
|
|
|
|
on your system then please point CMake to the desired MPI runtime
|
|
|
|
|
using `cmake-gui` or `ccmake`. Otherwise, we will proceed with a
|
|
|
|
|
serial build. If you beleive you are getting this message in error,
|
|
|
|
|
please report this at https://github.com/sfilippone/psblas3/issues.")
|
|
|
|
|
CHECK_Fortran_SOURCE_COMPILES(
|
|
|
|
|
"
|
|
|
|
|
program stt
|
|
|
|
|
type foo
|
|
|
|
|
integer :: i
|
|
|
|
|
end type foo
|
|
|
|
|
type, extends(foo) :: new_foo
|
|
|
|
|
integer :: j
|
|
|
|
|
end type new_foo
|
|
|
|
|
type(foo) :: foov
|
|
|
|
|
type(new_foo) :: nfv1, nfv2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
write(*,*) 'foov == nfv1? ', same_type_as(foov,nfv1)
|
|
|
|
|
write(*,*) 'nfv2 == nfv1? ', same_type_as(nfv2,nfv1)
|
|
|
|
|
end program"
|
|
|
|
|
HAVE_SAME_TYPE_AS
|
|
|
|
|
SRC_EXT f90)
|
|
|
|
|
if(HAVE_SAME_TYPE_AS)
|
|
|
|
|
add_definitions(-DHAVE_SAME_TYPE_AS)
|
|
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
get_filename_component(MPIEXEC_RELATIVE_LOC "${MPIEXEC}"
|
|
|
|
|
PROGRAM)
|
|
|
|
|
get_filename_component(MPIEXEC_ABS_LOC "${MPIEXEC_RELATIVE_LOC}"
|
|
|
|
|
REALPATH)
|
|
|
|
|
get_filename_component(MPIEXEC_DIR "${MPIEXEC_ABS_LOC}"
|
|
|
|
|
DIRECTORY)
|
|
|
|
|
|
|
|
|
|
get_filename_component(MPICC_RELATIVE_LOC "${MPI_C_COMPILER}"
|
|
|
|
|
PROGRAM)
|
|
|
|
|
get_filename_component(MPICC_ABS_LOC "${MPICC_RELATIVE_LOC}"
|
|
|
|
|
REALPATH)
|
|
|
|
|
get_filename_component(MPICC_DIR "${MPICC_ABS_LOC}"
|
|
|
|
|
DIRECTORY)
|
|
|
|
|
|
|
|
|
|
get_filename_component(MPIFC_RELATIVE_LOC "${MPI_Fortran_COMPILER}"
|
|
|
|
|
PROGRAM)
|
|
|
|
|
get_filename_component(MPIFC_ABS_LOC "${MPIFC_RELATIVE_LOC}"
|
|
|
|
|
REALPATH)
|
|
|
|
|
get_filename_component(MPIFC_DIR "${MPIFC_ABS_LOC}"
|
|
|
|
|
DIRECTORY)
|
|
|
|
|
|
|
|
|
|
if ((MPIEXEC_DIR STREQUAL MPICC_DIR) AND (MPIEXEC_DIR STREQUAL MPIFC_DIR))
|
|
|
|
|
message ( STATUS "MPI runtime and compile time environments appear to be consistent")
|
|
|
|
|
else()
|
|
|
|
|
message ( WARNING "MPIEXEC is in \"${MPIEXEC_DIR},\"
|
|
|
|
|
which differs from the location of MPICC and/or MPIFC which are in
|
|
|
|
|
\"${MPICC_DIR}\" and \"${MPIFC_DIR},\" respectively.
|
|
|
|
|
This is likely indicative of an inconsistent MPI environment")
|
|
|
|
|
endif()
|
|
|
|
|
#----------------------------------------------------------------------------
|
|
|
|
|
# Find MPI and set some flags so that FC and CC can point to gfortran and gcc
|
|
|
|
|
#----------------------------------------------------------------------------
|
|
|
|
|
find_package( MPI )
|
|
|
|
|
|
|
|
|
|
#-----------------------------------------------
|
|
|
|
|
# Work around an issue present on fedora systems
|
|
|
|
|
#-----------------------------------------------
|
|
|
|
|
if( (MPI_C_LINK_FLAGS MATCHES "noexecstack") OR (MPI_Fortran_LINK_FLAGS MATCHES "noexecstack") )
|
|
|
|
|
message ( WARNING
|
|
|
|
|
"The `noexecstack` linker flag was found in the MPI_<lang>_LINK_FLAGS variable. This is
|
|
|
|
|
if(MPI_FOUND)
|
|
|
|
|
#-----------------------------------------------
|
|
|
|
|
# Work around an issue present on fedora systems
|
|
|
|
|
#-----------------------------------------------
|
|
|
|
|
if( (MPI_C_LINK_FLAGS MATCHES "noexecstack") OR (MPI_Fortran_LINK_FLAGS MATCHES "noexecstack") )
|
|
|
|
|
message ( WARNING
|
|
|
|
|
"The `noexecstack` linker flag was found in the MPI_<lang>_LINK_FLAGS variable. This is
|
|
|
|
|
known to cause segmentation faults for some Fortran codes. See, e.g.,
|
|
|
|
|
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71729 or
|
|
|
|
|
https://github.com/sourceryinstitute/OpenCoarrays/issues/317.
|
|
|
|
|
|
|
|
|
|
`noexecstack` is being replaced with `execstack`"
|
|
|
|
|
)
|
|
|
|
|
string(REPLACE "noexecstack"
|
|
|
|
|
"execstack" MPI_C_LINK_FLAGS_FIXED ${MPI_C_LINK_FLAGS})
|
|
|
|
|
string(REPLACE "noexecstack"
|
|
|
|
|
"execstack" MPI_Fortran_LINK_FLAGS_FIXED ${MPI_Fortran_LINK_FLAGS})
|
|
|
|
|
set(MPI_C_LINK_FLAGS "${MPI_C_LINK_FLAGS_FIXED}" CACHE STRING
|
|
|
|
|
"MPI C linking flags" FORCE)
|
|
|
|
|
set(MPI_Fortran_LINK_FLAGS "${MPI_Fortran_LINK_FLAGS_FIXED}" CACHE STRING
|
|
|
|
|
"MPI Fortran linking flags" FORCE)
|
|
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------
|
|
|
|
|
# Make sure a simple "hello world" C mpi program compiles
|
|
|
|
|
#--------------------------------------------------------
|
|
|
|
|
set(OLD_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
|
|
|
|
set(CMAKE_REQUIRED_FLAGS ${MPI_C_COMPILE_FLAGS} ${MPI_C_LINK_FLAGS})
|
|
|
|
|
set(OLD_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
|
|
|
|
|
set(CMAKE_REQUIRED_INCLUDES ${MPI_C_INCLUDE_PATH})
|
|
|
|
|
set(OLD_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
|
|
|
|
|
set(CMAKE_REQUIRED_LIBRARIES ${MPI_C_LIBRARIES})
|
|
|
|
|
include (CheckCSourceCompiles)
|
|
|
|
|
CHECK_C_SOURCE_COMPILES("
|
|
|
|
|
#include <mpi.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
int main(int argc, char** argv) {
|
|
|
|
|
MPI_Init(NULL, NULL);
|
|
|
|
|
int world_size;
|
|
|
|
|
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
|
|
|
|
|
int world_rank;
|
|
|
|
|
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
|
|
|
|
|
char processor_name[MPI_MAX_PROCESSOR_NAME];
|
|
|
|
|
int name_len;
|
|
|
|
|
MPI_Get_processor_name(processor_name, &name_len);
|
|
|
|
|
printf('Hello world from processor %s, rank %d out of %d processors',
|
|
|
|
|
processor_name, world_rank, world_size);
|
|
|
|
|
MPI_Finalize();
|
|
|
|
|
}"
|
|
|
|
|
MPI_C_COMPILES)
|
|
|
|
|
set(CMAKE_REQUIRED_FLAGS ${OLD_REQUIRED_FLAGS})
|
|
|
|
|
set(CMAKE_REQUIRED_INCLUDES ${OLD_INCLUDES})
|
|
|
|
|
set(CMAKE_REQUIRED_LIBRARIES ${OLD_LIBRARIES})
|
|
|
|
|
unset(OLD_REQUIRED_FLAGS)
|
|
|
|
|
unset(OLD_INCLUDES)
|
|
|
|
|
unset(OLD_LIBRARIES)
|
|
|
|
|
|
|
|
|
|
if (NOT MPI_C_COMPILES)
|
|
|
|
|
message(FATAL_ERROR "MPI_C is missing! "
|
|
|
|
|
"Try setting MPI_C_COMPILER to the appropriate C compiler wrapper script and reconfigure. "
|
|
|
|
|
"i.e., `cmake -DMPI_C_COMPILER=/path/to/mpicc ..` or set it by editing the cache using "
|
|
|
|
|
"cmake-gui or ccmake."
|
|
|
|
|
)
|
|
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------
|
|
|
|
|
# Make sure a simple "hello world" Fortran mpi program compiles
|
|
|
|
|
# Try using mpi.mod first then fall back on includ 'mpif.h'
|
|
|
|
|
#--------------------------------------------------------------
|
|
|
|
|
set(OLD_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
|
|
|
|
set(CMAKE_REQUIRED_FLAGS "-ffree-form" ${MPI_Fortran_COMPILE_FLAGS} ${MPI_Fortran_LINK_FLAGS})
|
|
|
|
|
set(OLD_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
|
|
|
|
|
set(CMAKE_REQUIRED_INCLUDES ${MPI_Fortran_INCLUDE_PATH})
|
|
|
|
|
set(OLD_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
|
|
|
|
|
set(CMAKE_REQUIRED_LIBRARIES ${MPI_Fortran_LIBRARIES})
|
|
|
|
|
include (CheckFortranSourceCompiles)
|
|
|
|
|
CHECK_Fortran_SOURCE_COMPILES("
|
|
|
|
|
program mpi_hello
|
|
|
|
|
use mpi
|
|
|
|
|
implicit none
|
|
|
|
|
integer :: ierr, mpi_world_size, mpi_world_rank, res_len
|
|
|
|
|
character*(MPI_MAX_PROCESSOR_NAME) :: proc
|
|
|
|
|
call mpi_init(ierr)
|
|
|
|
|
call mpi_comm_size(MPI_COMM_WORLD,mpi_world_size,ierr)
|
|
|
|
|
call mpi_comm_rank(MPI_COMM_WORLD,mpi_world_rank,ierr)
|
|
|
|
|
call mpi_get_processor_name(proc,res_len,ierr)
|
|
|
|
|
write(*,*) 'Hello from processor ', trim(proc), ' rank ', mpi_world_rank, ' out of ', mpi_world_size, '.'
|
|
|
|
|
call mpi_finalize(ierr)
|
|
|
|
|
end program
|
|
|
|
|
"
|
|
|
|
|
MPI_Fortran_MODULE_COMPILES)
|
|
|
|
|
set(CMAKE_REQUIRED_FLAGS ${OLD_REQUIRED_FLAGS})
|
|
|
|
|
set(CMAKE_REQUIRED_INCLUDES ${OLD_INCLUDES})
|
|
|
|
|
set(CMAKE_REQUIRED_LIBRARIES ${OLD_LIBRARIES})
|
|
|
|
|
unset(OLD_REQUIRED_FLAGS)
|
|
|
|
|
unset(OLD_INCLUDES)
|
|
|
|
|
unset(OLD_LIBRARIES)
|
|
|
|
|
|
|
|
|
|
#--------------------------------
|
|
|
|
|
# If that failed try using mpif.h
|
|
|
|
|
#--------------------------------
|
|
|
|
|
set(OLD_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
|
|
|
|
set(CMAKE_REQUIRED_FLAGS "-ffree-form" ${MPI_Fortran_COMPILE_FLAGS} ${MPI_Fortran_LINK_FLAGS})
|
|
|
|
|
set(OLD_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
|
|
|
|
|
set(CMAKE_REQUIRED_INCLUDES ${MPI_Fortran_INCLUDE_PATH})
|
|
|
|
|
set(OLD_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
|
|
|
|
|
set(CMAKE_REQUIRED_LIBRARIES ${MPI_Fortran_LIBRARIES})
|
|
|
|
|
include (CheckFortranSourceCompiles)
|
|
|
|
|
CHECK_Fortran_SOURCE_COMPILES("
|
|
|
|
|
program mpi_hello
|
|
|
|
|
implicit none
|
|
|
|
|
include 'mpif.h'
|
|
|
|
|
integer :: ierr, mpi_world_size, mpi_world_rank, res_len
|
|
|
|
|
character*(MPI_MAX_PROCESSOR_NAME) :: proc
|
|
|
|
|
call mpi_init(ierr)
|
|
|
|
|
call mpi_comm_size(MPI_COMM_WORLD,mpi_world_size,ierr)
|
|
|
|
|
call mpi_comm_rank(MPI_COMM_WORLD,mpi_world_rank,ierr)
|
|
|
|
|
call mpi_get_processor_name(proc,res_len,ierr)
|
|
|
|
|
write(*,*) 'Hello from processor ', trim(proc), ' rank ', mpi_world_rank, ' out of ', mpi_world_size, '.'
|
|
|
|
|
call mpi_finalize(ierr)
|
|
|
|
|
end program
|
|
|
|
|
"
|
|
|
|
|
MPI_Fortran_INCLUDE_COMPILES)
|
|
|
|
|
set(CMAKE_REQUIRED_FLAGS ${OLD_REQUIRED_FLAGS})
|
|
|
|
|
set(CMAKE_REQUIRED_INCLUDES ${OLD_INCLUDES})
|
|
|
|
|
set(CMAKE_REQUIRED_LIBRARIES ${OLD_LIBRARIES})
|
|
|
|
|
unset(OLD_REQUIRED_FLAGS)
|
|
|
|
|
unset(OLD_INCLUDES)
|
|
|
|
|
unset(OLD_LIBRARIES)
|
|
|
|
|
|
|
|
|
|
if ( (NOT MPI_Fortran_MODULE_COMPILES) AND (NOT MPI_Fortran_INCLUDE_COMPILES) )
|
|
|
|
|
message ( WARNING "It appears that the Fortran MPI compiler is not working. ")
|
|
|
|
|
endif()
|
|
|
|
|
)
|
|
|
|
|
string(REPLACE "noexecstack"
|
|
|
|
|
"execstack" MPI_C_LINK_FLAGS_FIXED ${MPI_C_LINK_FLAGS})
|
|
|
|
|
string(REPLACE "noexecstack"
|
|
|
|
|
"execstack" MPI_Fortran_LINK_FLAGS_FIXED ${MPI_Fortran_LINK_FLAGS})
|
|
|
|
|
set(MPI_C_LINK_FLAGS "${MPI_C_LINK_FLAGS_FIXED}" CACHE STRING
|
|
|
|
|
"MPI C linking flags" FORCE)
|
|
|
|
|
set(MPI_Fortran_LINK_FLAGS "${MPI_Fortran_LINK_FLAGS_FIXED}" CACHE STRING
|
|
|
|
|
"MPI Fortran linking flags" FORCE)
|
|
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
if ( MPI_Fortran_MODULE_COMPILES )
|
|
|
|
|
add_definitions(-DMPI_WORKING_MODULE)
|
|
|
|
|
#----------------
|
|
|
|
|
# Setup MPI flags
|
|
|
|
|
#----------------
|
|
|
|
|
list(REMOVE_DUPLICATES MPI_Fortran_INCLUDE_PATH)
|
|
|
|
|
set(CMAKE_C_COMPILE_FLAGS ${CMAKE_C_COMPILE_FLAGS} ${MPI_C_COMPILE_FLAGS})
|
|
|
|
|
set(CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} ${MPI_C_LINK_FLAGS})
|
|
|
|
|
set(CMAKE_Fortran_COMPILE_FLAGS ${CMAKE_Fortran_COMPILE_FLAGS} ${MPI_Fortran_COMPILE_FLAGS})
|
|
|
|
|
set(CMAKE_Fortran_LINK_FLAGS ${CMAKE_Fortran_LINK_FLAGS} ${MPI_Fortran_LINK_FLAGS})
|
|
|
|
|
include_directories(BEFORE ${MPI_C_INCLUDE_PATH} ${MPI_Fortran_INCLUDE_PATH})
|
|
|
|
|
|
|
|
|
|
if(MPI_Fortran_HAVE_F90_MODULE OR MPI_Fortran_HAVE_F08_MODULE)
|
|
|
|
|
add_definitions(-DMPI_MOD)
|
|
|
|
|
endif()
|
|
|
|
|
set(SERIAL_MPI OFF)
|
|
|
|
|
else()
|
|
|
|
|
message ( WARNING "It appears that MPI was built with a different Fortran compiler. "
|
|
|
|
|
"It is possible that this may cause unpredictable behavior. The build will continue "
|
|
|
|
|
"using `mpif.h` BUT please report any suspicious behavior to the ${CMAKE_PROJECT_NAME} "
|
|
|
|
|
"developers."
|
|
|
|
|
)
|
|
|
|
|
add_definitions(-DSERIAL_MPI)
|
|
|
|
|
add_definitions(-DMPI_MOD)
|
|
|
|
|
set(SERIAL_MPI ON)
|
|
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
#----------------
|
|
|
|
|
# Setup MPI flags
|
|
|
|
|
#----------------
|
|
|
|
|
set(CMAKE_C_COMPILE_FLAGS ${CMAKE_C_COMPILE_FLAGS} ${MPI_C_COMPILE_FLAGS})
|
|
|
|
|
set(CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} ${MPI_C_LINK_FLAGS})
|
|
|
|
|
set(CMAKE_Fortran_COMPILE_FLAGS ${CMAKE_Fortran_COMPILE_FLAGS} ${MPI_Fortran_COMPILE_FLAGS})
|
|
|
|
|
set(CMAKE_Fortran_LINK_FLAGS ${CMAKE_Fortran_LINK_FLAGS} ${MPI_Fortran_LINK_FLAGS})
|
|
|
|
|
include_directories(BEFORE ${MPI_C_INCLUDE_PATH} ${MPI_Fortran_INCLUDE_PATH})
|
|
|
|
|
#------------------------------
|
|
|
|
|
# Find Linear Algebra Libraries
|
|
|
|
|
#------------------------------
|
|
|
|
|
find_package(BLAS REQUIRED)
|
|
|
|
|
find_package(LAPACK REQUIRED)
|
|
|
|
|
add_definitions(-DHAVE_LAPACK)
|
|
|
|
|
|
|
|
|
|
#---------------------------------------------------
|
|
|
|
|
# Use standardized GNU install directory conventions
|
|
|
|
|
@ -386,9 +290,11 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/
|
|
|
|
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
|
|
|
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
|
|
|
|
|
|
|
|
|
#-----------------------------------
|
|
|
|
|
# Turn on testing/ctest capabilities
|
|
|
|
|
#-----------------------------------
|
|
|
|
|
enable_testing()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
# Add custom properties on targets for controling number of ranks during tests
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
@ -429,6 +335,7 @@ install(
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(MPI_FOUND)
|
|
|
|
|
#------------------------------------------
|
|
|
|
|
# Add portable unistall command to makefile
|
|
|
|
|
#------------------------------------------
|
|
|
|
|
@ -443,48 +350,99 @@ add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure)
|
|
|
|
|
# See JSON-Fortran's CMakeLists.txt file to find out how to get the check target to depend
|
|
|
|
|
# on the test executables
|
|
|
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------------
|
|
|
|
|
# Define macro for adding CAF tests, and ensuring proper flags are passed to MPI runtime
|
|
|
|
|
#---------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
#----------------------------------
|
|
|
|
|
# Determine if we're using Open MPI
|
|
|
|
|
#---------------------------------
|
|
|
|
|
execute_process(COMMAND ${MPIEXEC} --version
|
|
|
|
|
OUTPUT_VARIABLE mpi_version_out)
|
|
|
|
|
if (mpi_version_out MATCHES "[Oo]pen[ -][Mm][Pp][Ii]")
|
|
|
|
|
message( STATUS "OpenMPI detected")
|
|
|
|
|
set ( openmpi true )
|
|
|
|
|
endif ()
|
|
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
include( ProcessorCount )
|
|
|
|
|
ProcessorCount(N_CPU)
|
|
|
|
|
function(add_mpi_test name num_mpi_rank test_target)
|
|
|
|
|
# Function to add MPI tests.
|
|
|
|
|
if(TARGET ${test_target})
|
|
|
|
|
get_target_property(min_test_ranks ${test_target} MIN_RANKS)
|
|
|
|
|
elseif(TARGET build_${test_target})
|
|
|
|
|
get_target_property(min_test_ranks build_${test_target} MIN_RANKS)
|
|
|
|
|
endif()
|
|
|
|
|
if(min_test_ranks)
|
|
|
|
|
if(num_mpi_rank LESS min_test_ranks)
|
|
|
|
|
message( FATAL_ERROR "Test ${name} requires ${min_test_ranks} but was only given ${num_mpi_ranks}" )
|
|
|
|
|
endif()
|
|
|
|
|
endif()
|
|
|
|
|
if ( ((N_CPU LESS num_mpi_rank) OR (N_CPU EQUAL 0)) )
|
|
|
|
|
message(STATUS "Test ${name} is oversubscribed: ${num_mpi_rank} CAF ranks requested with ${N_CPU} system processor available.")
|
|
|
|
|
if ( openmpi )
|
|
|
|
|
if (min_test_ranks)
|
|
|
|
|
set( num_mpi_rank ${min_test_ranks} )
|
|
|
|
|
elseif ( N_CPU LESS 2 )
|
|
|
|
|
set( num_mpi_rank 2 )
|
|
|
|
|
endif()
|
|
|
|
|
set (test_parameters --oversubscribe)
|
|
|
|
|
message( STATUS "Open-MPI back end detected, passing --oversubscribe for oversubscribed test, ${name}, with ${num_mpi_rank} ranks." )
|
|
|
|
|
endif()
|
|
|
|
|
endif()
|
|
|
|
|
set(test_parameters -np ${num_mpi_rank} ${test_parameters})
|
|
|
|
|
add_test(NAME ${name} COMMAND "bash" "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/mpirun" ${test_parameters} "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test_target}")
|
|
|
|
|
set_property(TEST ${name} PROPERTY PASS_REGULAR_EXPRESSION "Test passed.")
|
|
|
|
|
endfunction(add_mpi_test)
|
|
|
|
|
#---------------------------------------
|
|
|
|
|
# Add the PSBLAS libraries and utilities
|
|
|
|
|
#---------------------------------------
|
|
|
|
|
|
|
|
|
|
# Link order, left to right:
|
|
|
|
|
# cbind.a, util.a krylov.a prec.a base.a
|
|
|
|
|
|
|
|
|
|
include(${CMAKE_CURRENT_LIST_DIR}/base/CMakeLists.txt)
|
|
|
|
|
add_library(base ${base_source_files})
|
|
|
|
|
set_target_properties(base
|
|
|
|
|
PROPERTIES
|
|
|
|
|
Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/${mod_dir_tail}"
|
|
|
|
|
POSITION_INDEPENDENT_CODE TRUE
|
|
|
|
|
OUTPUT_NAME psb_base
|
|
|
|
|
LINKER_LANGUAGE Fortran
|
|
|
|
|
)
|
|
|
|
|
target_include_directories(base PUBLIC
|
|
|
|
|
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/${mod_dir_tail}>
|
|
|
|
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
|
|
|
|
if(MPI_FOUND)
|
|
|
|
|
target_link_libraries(base PUBLIC ${MPI_C_LIBRARIES} ${MPI_Fortran_LIBRARIES})
|
|
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
include(${CMAKE_CURRENT_LIST_DIR}/prec/CMakeLists.txt)
|
|
|
|
|
add_library(prec ${prec_source_files})
|
|
|
|
|
set_target_properties(prec
|
|
|
|
|
PROPERTIES
|
|
|
|
|
Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/${mod_dir_tail}"
|
|
|
|
|
POSITION_INDEPENDENT_CODE TRUE
|
|
|
|
|
OUTPUT_NAME psb_prec
|
|
|
|
|
LINKER_LANGUAGE Fortran
|
|
|
|
|
)
|
|
|
|
|
target_include_directories(prec PUBLIC
|
|
|
|
|
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/${mod_dir_tail}>
|
|
|
|
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
|
|
|
|
target_link_libraries(prec PUBLIC base)
|
|
|
|
|
|
|
|
|
|
include(${CMAKE_CURRENT_LIST_DIR}/krylov/CMakeLists.txt)
|
|
|
|
|
add_library(krylov ${krylov_source_files})
|
|
|
|
|
set_target_properties(krylov
|
|
|
|
|
PROPERTIES
|
|
|
|
|
Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/${mod_dir_tail}"
|
|
|
|
|
POSITION_INDEPENDENT_CODE TRUE
|
|
|
|
|
OUTPUT_NAME psb_krylov
|
|
|
|
|
LINKER_LANGUAGE Fortran
|
|
|
|
|
)
|
|
|
|
|
target_include_directories(krylov PUBLIC
|
|
|
|
|
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/${mod_dir_tail}>
|
|
|
|
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
|
|
|
|
target_link_libraries(krylov PUBLIC base prec)
|
|
|
|
|
|
|
|
|
|
include(${CMAKE_CURRENT_LIST_DIR}/util/CMakeLists.txt)
|
|
|
|
|
add_library(util ${util_source_files})
|
|
|
|
|
set_target_properties(util
|
|
|
|
|
PROPERTIES
|
|
|
|
|
Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/${mod_dir_tail}"
|
|
|
|
|
POSITION_INDEPENDENT_CODE TRUE
|
|
|
|
|
OUTPUT_NAME psb_util
|
|
|
|
|
LINKER_LANGUAGE Fortran
|
|
|
|
|
)
|
|
|
|
|
target_include_directories(util PUBLIC
|
|
|
|
|
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/${mod_dir_tail}>
|
|
|
|
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
|
|
|
|
target_link_libraries(util PUBLIC base prec)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
install(DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
|
|
|
|
FILES_MATCHING PATTERN "*.mod")
|
|
|
|
|
install(TARGETS base prec krylov util
|
|
|
|
|
EXPORT ${CMAKE_PROJECT_NAME}-targets
|
|
|
|
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
|
|
|
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# set(directory_list base prec krylov util test) # TODO: add cbind
|
|
|
|
|
# foreach(directory ${directory_list})
|
|
|
|
|
# add_subdirectory("${directory}")
|
|
|
|
|
# endforeach()
|
|
|
|
|
#add_subdirectory(cbind)
|
|
|
|
|
|
|
|
|
|
#-----------------
|
|
|
|
|
# Add PSBLAS tests
|
|
|
|
|
@ -492,17 +450,3 @@ endfunction(add_mpi_test)
|
|
|
|
|
|
|
|
|
|
# Unit tests targeting each function, argument, and branch of code
|
|
|
|
|
# add_mpi_test(initialize_mpi 2 initialize_mpi)
|
|
|
|
|
|
|
|
|
|
add_definitions(
|
|
|
|
|
-DHAVE_METIS -DHAVE_LAPACK -DHAVE_MOLD -DHAVE_EXTENDS_TYPE_OF -DHAVE_SAME_TYPE_AS -DHAVE_FINAL -DMPI_MOD
|
|
|
|
|
)
|
|
|
|
|
# From ./configure CDEFINES section
|
|
|
|
|
add_definitions(
|
|
|
|
|
-DHAVE_METIS_
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
set(directory_list base prec krylov util test) # TODO: add cbind
|
|
|
|
|
foreach(directory ${directory_list})
|
|
|
|
|
add_subdirectory("${directory}")
|
|
|
|
|
endforeach()
|
|
|
|
|
#add_subdirectory(cbind)
|
|
|
|
|
|