Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows support #755

Merged
merged 18 commits into from
May 7, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 139 additions & 70 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,11 @@ if(DEFINED CMAKE_BUILD_TYPE AND "${CMAKE_BUILD_TYPE}" MATCHES "[Rr][Ee][Ll]")
if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fno-working-directory")
endif()
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fdebug-prefix-map=${CMAKE_SOURCE_DIR}=.")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fdebug-prefix-map=\"${CMAKE_SOURCE_DIR}\"=.")
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-working-directory")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdebug-prefix-map=${CMAKE_SOURCE_DIR}=.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdebug-prefix-map=\"${CMAKE_SOURCE_DIR}\"=.")
endif()

message( STATUS "Building OpenCoarrays version: ${full_git_describe}" )
Expand Down Expand Up @@ -204,6 +204,9 @@ endif()

if(CMAKE_BUILD_TYPE MATCHES "Debug|DEBUG|debug")
add_definitions(-DEXTRA_DEBUG_OUTPUT)
set(IMPI_BUILD debug)
else()
set(IMPI_BUILD release)
endif()

# We have populated CMAKE_Fortran_COMPILER_VERSION if it was missing
Expand Down Expand Up @@ -234,7 +237,7 @@ endif()

if(gfortran_compiler)
set(OLD_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS $<$<COMPILE_LANGUAGE:Fortran>:-fcoarray=single -ffree-form>)
set(CMAKE_REQUIRED_FLAGS -fcoarray=single)
endif()
include(CheckFortranSourceCompiles)
CHECK_Fortran_SOURCE_COMPILES("
Expand All @@ -243,7 +246,8 @@ CHECK_Fortran_SOURCE_COMPILES("
integer :: i
i = this_image()
end program
" Check_Simple_Coarray_Fortran_Source_Compiles)
" Check_Simple_Coarray_Fortran_Source_Compiles
SRC_EXT F90)
if(gfortran_compiler)
set (CMAKE_REQUIRED_FLAGS ${OLD_REQUIRED_FLAGS})
unset(OLD_REQUIRED_FLAGS)
Expand Down Expand Up @@ -273,102 +277,167 @@ if (C_COMPILER_NAME MATCHES "^[mM][pP][iI]")
set (MPI_C_COMPILER "${CMAKE_C_COMPILER}")
endif()

find_package( MPI )
if(WIN32) # Only support building with GCC & GFortran using Intel MPI (OneAPI)
# Here we assume Intel ONEAPI and the environment is loaded
cmake_path(SET MPI_ROOT NORMALIZE "$ENV{I_MPI_ROOT}")
set (IMPI_INCLUDES "${MPI_ROOT}/include")
set (IMPI_LIB_DIR "${MPI_ROOT}/lib/${IMPI_BUILD}")
set (IMPI_DLL_DIR "${MPI_ROOT}/bin/${IMPI_BUILD}")
set (IMPI_BIN_DIR "${MPI_ROOT}/bin")

find_library(IMPI_LIB
"impi.lib"
HINTS "${IMPI_LIB_DIR}"
DOC "Location of the Intel MPI impi.lib file"
REQUIRED
NO_DEFAULT_PATH)

set(MPI_impi_LIBRARY "${IMPI_LIB}")
set(MPI_impicxx_LIBRARY "${IMPI_LIB_DIR}/impicxx.lib")

find_file(IMPI_DLL
"impi.dll"
HINTS "${IMPI_DLL_DIR}"
DOC "Location of the Intel MPI impi.dll file"
REQUIRED
NO_DEFAULT_PATH)


add_library(IMPI::MPI SHARED IMPORTED)
set_target_properties(IMPI::MPI
PROPERTIES
IMPORTED_IMPLIB "${IMPI_LIB}"
IMPORTED_LOCATION "${IMPI_DLL}")
target_include_directories(IMPI::MPI
INTERFACE "${IMPI_INCLUDES}")

set(MPI_C_INCLUDE_DIRS "${IMPI_INCLUDES}")
set(MPI_C_INCLUDE_PATH "${IMPI_INCLUDES}")
set(MPI_C_HEADER_DIR "${IMPI_INCLUDES}")
set(MPI_Fortran_COMPILER_INCLUDE_DIRS "${IMPI_INCLUDES}")
set(MPI_Fortran_F77_HEADER_DIR "${IMPI_INCLUDES}")
set(MPI_Fortran_INCLUDE_PATH "${IMPI_INCLUDES}")

set(MPI_C_LIB_NAMES impi;impicxx)
set(MPI_C_LIBRARIES "${IMPI_LIB}")
set(MPI_Fortran_LIB_NAMES impi)
set(MPI_Fortran_LIBRARIES "${IMPI_LIB}")

set(MPI_Fortran_HAVE_F90_MODULE FALSE)
set(MPI_Fortran_HAVE_F08_MODULE FALSE)

find_program(MPIEXEC_EXECUTABLE
mpiexec
HINTS "${IMPI_BIN_DIR}"
DOC "Location of Intel MPI implementations mpiexec launcher program"
REQUIRED
NO_DEFAULT_PATH)
set(MPIEXEC "${MPIEXEC_EXECUTABLE}")
set(MPI_EXEC_NUMPROC_FLAG -n)
set(MPI_EXEC_PREFLAGS -print-all-exitcodes)

set(MPI_C_FOUND TRUE)
set(MPI_Fortran_FOUND TRUE)

else()
find_package( MPI )

if ( (NOT MPI_C_FOUND) OR (NOT MPI_Fortran_FOUND) OR (NOT MPIEXEC))
# Get default install location of MPICH from install.sh
message(WARNING "Could not find all MPI components!")
message(WARNING "
if ( (NOT MPI_C_FOUND) OR (NOT MPI_Fortran_FOUND) OR (NOT MPIEXEC_EXECUTABLE))
# Get default install location of MPICH from install.sh
message(WARNING "Could not find all MPI components!")
message(WARNING "
MPI_C_FOUND = ${MPI_C_FOUND}
MPI_Fortran_FOUND = ${MPI_Fortran_FOUND}
MPIEXEC = ${MPIEXEC}
MPIEXEC = ${MPIEXEC_EXECUTABLE}
")
execute_process( COMMAND "./install.sh" -P mpich
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE DEFAULT_MPICH_INSTALL_LOC
OUTPUT_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
find_program (MY_MPI_EXEC NAMES mpirun mpiexec lamexec srun
PATHS "${DEFAULT_MPICH_INSTALL_LOC}" ENV PATH
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 )
execute_process( COMMAND "./install.sh" -P mpich
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE DEFAULT_MPICH_INSTALL_LOC
OUTPUT_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
find_program (MY_MPI_EXEC NAMES mpirun mpiexec lamexec srun
PATHS "${DEFAULT_MPICH_INSTALL_LOC}" ENV PATH
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 )
endif()
endif()
list(REMOVE_DUPLICATES MPI_Fortran_INCLUDE_PATH)

# Test for consistent MPI environment
if (NOT MPIEXEC)
# Test for consistent MPI environment but not on windows
if (NOT MPIEXEC_EXECUTABLE)
message ( ERROR "CMake failed to find `mpiexec` or similar. If building with `./install.sh` please
report this bug to the OpenCoarrays developers at
https://github.com/sourceryinstitute/opencoarrays/issues, otherwise point CMake
to the desired MPI runtime.")
else()
add_definitions(-DHAVE_MPI)
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},\"
if(NOT WIN32)
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 a problem. If building with `./install.sh` please report
this to the OpenCoarrays developers by filing a new issue at:
https://github.com/sourceryinstitute/OpenCoarrays/issues/new")
endif()
endif()

#-----------------------------------------------
# Work around bug #317 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
#-----------------------------------------------
# Work around bug #317 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)
)
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()
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(CMAKE_REQUIRED_FLAGS ${MPI_C_COMPILE_OPTIONS} ${MPI_C_COMPILE_DEFINITIONS} ${MPI_C_LINK_FLAGS})
set(OLD_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
set(CMAKE_REQUIRED_INCLUDES ${MPI_C_INCLUDE_PATH})
set(CMAKE_REQUIRED_INCLUDES ${MPI_C_INCLUDE_DIRS})
set(OLD_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${MPI_C_LIBRARIES})
include (CheckCSourceCompiles)
Expand Down Expand Up @@ -409,7 +478,7 @@ endif()
# 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(CMAKE_REQUIRED_FLAGS "-ffree-form" ${MPI_Fortran_COMPILE_OPTIONS} ${MPI_Fortran_COMPILE_DEFINITIONS} ${MPI_Fortran_LINK_FLAGS})
set(OLD_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
set(CMAKE_REQUIRED_INCLUDES ${MPI_Fortran_INCLUDE_PATH})
set(OLD_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
Expand Down Expand Up @@ -441,7 +510,7 @@ 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(CMAKE_REQUIRED_FLAGS "-ffree-form" ${MPI_Fortran_COMPILE_OPTIONS} ${MPI_Fortra_COMPILE_DEFINITIONS} ${MPI_Fortran_LINK_FLAGS})
set(OLD_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
set(CMAKE_REQUIRED_INCLUDES ${MPI_Fortran_INCLUDE_PATH})
set(OLD_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
Expand Down
14 changes: 10 additions & 4 deletions src/extensions/caf.in
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ set -o pipefail
#
# CAF_VERSION, opencoarrays_aware_compiler, Fortran_COMPILER, CAF_MODDIR,
# CAF_MPI_Fortran_LINK_FLAGS, CAF_MPI_Fortran_COMPILE_FLAGS,
# CAF_LIBS, CAF_MPI_LIBS
# CAF_LIBS, THREADS_LIB, CAF_MPI_LIBS
#

caf_version='@CAF_VERSION@' # fetched from `git describe` and/or
Expand All @@ -61,7 +61,7 @@ oca_compiler="@opencoarrays_aware_compiler@" # True for GFortran > 5.0.0

# Compiler used to build OpenCoarrays; runtime must match compiler used during build
cafc="@Fortran_COMPILER@"
if [[ "${cafc}" == @*@ ]]; then
if [[ "${cafc}" == @*@ || -z "${cafc}" ]]; then
cafc=gfortran
fi
caf_mod_dir="@CAF_MODDIR@" # location of extensions module, needed for non-OCA compilers
Expand All @@ -87,6 +87,7 @@ mpi_link_flags=(@CAF_MPI_Fortran_LINK_FLAGS@) # e.g. `pkg-config
# --libs-only-L`
mpi_compile_flags=(@CAF_MPI_Fortran_COMPILE_FLAGS@)
caf_libs=(@CAF_LIBS@) # e.g. "libcaf_mpi" "libcaf_extensions",
threads_lib=@THREADS_LIB@ # pthreads or compatible, needed for windows
# preferably full paths, but could be
# combination of -L... and -lcaf_mpi...
mpi_libs=(@CAF_MPI_LIBS@) # e.g. `pkg-config --libs-only-l` or full paths
Expand Down Expand Up @@ -176,7 +177,7 @@ __only_compiling () {
substitute_lib () {
# Try to substitute a shared or static library if requested library is missing
# Some package managers only install dynamic or static libs
if ! [[ -f "${1}" ]] ; then
if ! [[ -f "${1}" && "${1}" = *.* ]] ; then
case "${1##*.}" in
a|lib)
for suff in so dylib dll ; do
Expand Down Expand Up @@ -235,6 +236,11 @@ if [[ -n "${caf_libs[*]:-}" ]]; then
caf_added_libs+=("$(substitute_lib "${prefix%/}/${lib}")")
done
fi

if [[ -n "${threads_lib}" ]]; then
caf_added_libs+=("${threads_lib}")
fi

if [[ -n "${mpi_libs[*]:-}" ]]; then
for lib in "${mpi_libs[@]:-}"; do
caf_added_libs+=("$(substitute_lib "${lib}")")
Expand Down Expand Up @@ -370,7 +376,7 @@ if "${cafc}" "${compiler_args[@]}" ; then
exit $?
else
return_code=$?
echo "Error: comand:" >&2
echo "Error: command:" >&2
echo " \`${cafc} ${compiler_args[*]}\`" >&2
echo "failed to compile." >&2
exit "${return_code}"
Expand Down
10 changes: 5 additions & 5 deletions src/extensions/cafrun.in
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,25 @@ set -o pipefail

caf_version='@CAF_VERSION@'
CAFRUN="@MPIEXEC@"
if [[ "${CAFRUN}" == @*@ ]]; then
if [[ "${CAFRUN}" == @*@ || -z "${CAFRUN}" ]]; then
CAFRUN=mpiexec
fi
have_failed_img=@HAVE_FAILED_IMG@
if [[ ${have_failed_img} == @*@ ]]; then
if [[ ${have_failed_img} == @*@ || -z "${have_failed_img}" ]]; then
have_failed_img=false
fi
numproc_flag='@MPIEXEC_NUMPROC_FLAG@'
if [[ ${numproc_flag} == @*@ ]]; then
if [[ ${numproc_flag} == @*@ || -z "${numproc_flag}" ]]; then
numproc_flag='-np'
fi
preflags="@MPIEXEC_PREFLAGS@"
preflags="${preflags//;/ }"
if [[ "${preflags}" == @*@ ]]; then
if [[ "${preflags}" == @*@ || -z "${preflags}" ]]; then
unset preflags
fi
postflags="@MPIEXEC_POSTFLAGS@"
postflags="${postflags//;/ }"
if [[ "${postflags}" == @*@ ]]; then
if [[ "${postflags}" == @*@ || -z "${postflags}" ]]; then
unset postflags
fi
#-------------------------
Expand Down
Loading