diff --git a/.github/inactive_workflows/fesom2_icepack.yml b/.github/inactive_workflows/fesom2_icepack.yml index 9057057b1..9e295d101 100644 --- a/.github/inactive_workflows/fesom2_icepack.yml +++ b/.github/inactive_workflows/fesom2_icepack.yml @@ -21,14 +21,13 @@ jobs: - name: prepeare FESOM2_icepack run: | - sed -i 's/USE_ICEPACK OFF/USE_ICEPACK ON/g' CMakeLists.txt cd ./src/icepack_drivers/ ./download_icepack.sh cd ../../ - name: Compile model run: | - bash -l configure.sh ubuntu + bash -l configure.sh ubuntu -DUSE_ICEPACK=ON - name: Create global test run with ICEPACK run: | diff --git a/.github/workflows/fesom2.1.yml b/.github/workflows/fesom2.1.yml index 069a5a669..0b54ee9e8 100644 --- a/.github/workflows/fesom2.1.yml +++ b/.github/workflows/fesom2.1.yml @@ -18,18 +18,43 @@ jobs: steps: # NK: this changes working directory to fesom2 - uses: actions/checkout@v2 - + + - name: Git safe directory + run: | + git config --global --add safe.directory /__w/fesom2/fesom2 + - name: Compile model (binary) run: | - bash -l configure.sh ubuntu + ./configure.sh ubuntu + + - name: Compile model (ifs_interface) + run: | + export BUILD_DIR=$PWD/build.ifs_interface + ./configure.sh ubuntu -DENABLE_IFS_INTERFACE=ON -DCMAKE_INSTALL_PREFIX=$PWD/install.ifs_interface - - name: Compile model (library) + - name: Test downstream from /usr/local install-dir run: | - bash ./test/ifs_interface/configure_lib.sh -l + rm -rf test_downstream/build + cmake -S test_downstream -B test_downstream/build -DASSERT_HAVE_IFS_INTERFACE=OFF -DASSERT_FESOM_DIR=/usr/local + cmake --build test_downstream/build + test_downstream/build/main - - name: Library exists + - name: Test downstream from ifs_interface build-dir + run: | + cmake --version + export fesom_ROOT=$PWD/build.ifs_interface + rm -rf test_downstream/build + cmake -S test_downstream -B test_downstream/build -DASSERT_HAVE_IFS_INTERFACE=ON -DASSERT_FESOM_DIR=${fesom_ROOT} + cmake --build test_downstream/build + test_downstream/build/main + + - name: Test downstream from ifs_interface install-dir run: | - bash ./test/ifs_interface/check_exist.sh + export fesom_ROOT=$PWD/install.ifs_interface + rm -rf test_downstream/build + cmake -S test_downstream -B test_downstream/build -DASSERT_HAVE_IFS_INTERFACE=ON -DASSERT_FESOM_DIR=${fesom_ROOT} + cmake --build test_downstream/build + test_downstream/build/main - name: Create global test run run: | diff --git a/.github/workflows/fesom2_openmp.yml b/.github/workflows/fesom2_openmp.yml index fd1e8cafa..64c5a492b 100644 --- a/.github/workflows/fesom2_openmp.yml +++ b/.github/workflows/fesom2_openmp.yml @@ -19,15 +19,13 @@ jobs: # NK: this changes working directory to fesom2 - uses: actions/checkout@v2 - - name: switch OpenMP ON + - name: Git safe directory run: | - cd ./src/ - sed -i 's/with OpenMP\" OFF/with OpenMP\" ON/g' CMakeLists.txt - cd ../ + git config --global --add safe.directory /__w/fesom2/fesom2 - name: Compile model run: | - bash -l configure.sh ubuntu + bash -l configure.sh ubuntu -DENABLE_OPENMP=ON - name: Create global test run with 4 OpenMP threads run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index 60a65d66f..b256b38b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.16) # set default build type cache entry (do so before project(...) is called, which would create this cache entry on its own) if(NOT CMAKE_BUILD_TYPE) @@ -8,9 +8,7 @@ endif() project(FESOM2.0) -set(CMAKE_VERBOSE_MAKEFILE ON) - -option(BUILD_SHARED_LIBS "Build using shared libraries" OFF) # cmake-internal switch to toggle if library targets are being build as STATIC or SHARED, see https://cmake.org/cmake/help/latest/guide/tutorial/Selecting%20Static%20or%20Shared%20Libraries.html +set(BUILD_SHARED_LIBS ON CACHE BOOL "Default to using shared libs") set(TOPLEVEL_DIR ${CMAKE_CURRENT_LIST_DIR}) set(FESOM_COUPLED OFF CACHE BOOL "compile fesom standalone or with oasis support (i.e. coupled)") set(OIFS_COUPLED OFF CACHE BOOL "compile fesom coupled to OpenIFS. (Also needs FESOM_COUPLED to work)") @@ -21,3 +19,15 @@ set(OPENMP_REPRODUCIBLE OFF CACHE BOOL "serialize OpenMP loops that are critical #set(VERBOSE OFF CACHE BOOL "toggle debug output") #add_subdirectory(oasis3-mct/lib/psmile) add_subdirectory(src) + +foreach( _file fesom-config.cmake fesom-config-version.cmake fesom-targets.cmake ) + execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink ${PROJECT_BINARY_DIR}/src/${_file} ${PROJECT_BINARY_DIR}/${_file} ) +endforeach() + +# Define ${PROJECT_NAME}_DIR in PARENT_SCOPE so that a `find_package( )` in a bundle +# will easily find the project without requiring a `HINT _BINARY_DIR` argument +if( NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR ) + # Guard needed because PARENT_SCOPE cannot be used in top-level CMake project + + set( fesom_DIR ${fesom_DIR} PARENT_SCOPE ) +endif() diff --git a/cmake/FindBLAS.cmake b/cmake/FindBLAS.cmake deleted file mode 100644 index 27c4a76d5..000000000 --- a/cmake/FindBLAS.cmake +++ /dev/null @@ -1,61 +0,0 @@ - - - -# BLAS__FOUND -# BLAS__LIBRARIES -# BLAS__COMPILER_WRAPPER - - -if(CMAKE_C_COMPILER_LOADED) - #check_function_exists(cblas_sgemm SGEMM_C_FOUND) # this is also found if it is in the standard library paths, so we can not be sure we already have it in the wrapper - - include(CheckCSourceCompiles) - set(CMAKE_REQUIRED_FLAGS -c) - check_c_source_compiles([[ - #include - typedef void (*foo)(const enum CBLAS_ORDER, const enum CBLAS_TRANSPOSE, - const enum CBLAS_TRANSPOSE, const int, const int, - const int, const float, const float *, - const int, const float *, const int, - const float, float *, const int); - foo func = &cblas_sgemm; -]] BLAS_C_COMPILER_WRAPPER) - - if(NOT BLAS_C_COMPILER_WRAPPER) - # try to locate BLAS via the find module shipped with cmake - # the module does not search for C based blas if the Fortran language is enabled - include(${CMAKE_ROOT}/Modules/FindBLAS.cmake) - set(BLAS_C_LIBRARIES ${BLAS_LIBRARIES}) - # unset the results from the original FindBlas.cmake - unset(BLAS_FOUND) - unset(BLAS_LIBRARIES) - else() - set(BLAS_C_LIBRARIES "") # we do not want to explicitly add libraries as the wrapper will do it - set(BLAS_C_FOUND TRUE) - endif() - - if(BLAS_C_LIBRARIES) - set(BLAS_C_FOUND TRUE) - endif() -endif() - - -# include(${CMAKE_ROOT}/Modules/FindBLAS.cmake) -# This module sets the following variables: -# -# :: -# -# BLAS_FOUND - set to true if a library implementing the BLAS interface -# is found -# BLAS_LINKER_FLAGS - uncached list of required linker flags (excluding -l -# and -L). -# BLAS_LIBRARIES - uncached list of libraries (using full path name) to -# link against to use BLAS -# BLAS95_LIBRARIES - uncached list of libraries (using full path name) -# to link against to use BLAS95 interface -# BLAS95_FOUND - set to true if a library implementing the BLAS f95 interface -# is found -# BLA_STATIC if set on this determines what kind of linkage we do (static) -# BLA_VENDOR if set checks only the specified vendor, if not set checks -# all the possibilities -# BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK diff --git a/cmake/fesom_export.cmake b/cmake/fesom_export.cmake new file mode 100644 index 000000000..7a57f34b7 --- /dev/null +++ b/cmake/fesom_export.cmake @@ -0,0 +1,59 @@ + +macro( fesom_export ) + +set( options ) +set( single_value_args ) +set( multi_value_args TARGETS ) + +cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} ) + +set( PROJECT_TARGETS_FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-targets.cmake" ) +file( REMOVE ${PROJECT_TARGETS_FILE} ) + + +foreach( tgt ${_PAR_TARGETS} ) + install( TARGETS ${tgt} + EXPORT ${PROJECT_NAME}-targets + RUNTIME DESTINATION ${INSTALL_BIN_DIR} + LIBRARY DESTINATION ${INSTALL_LIB_DIR} + ARCHIVE DESTINATION ${INSTALL_LIB_DIR} ) + set_target_properties( ${tgt} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) + export( TARGETS ${tgt} APPEND FILE "${PROJECT_TARGETS_FILE}" ) +endforeach() + +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${PROJECT_NAME}-config-version.cmake" + VERSION ${${PROJECT_NAME}_VERSION} + COMPATIBILITY AnyNewerVersion) + +if( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}-config.cmake.in ) + configure_package_config_file(${PROJECT_NAME}-config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake + INSTALL_DESTINATION ${INSTALL_CMAKE_DIR}) +else() + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake.in "include(${CMAKE_CURRENT_LIST_DIR}/${PROJECT_NAME}-targets.cmake)") + configure_package_config_file(${PROJECT_NAME}-config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake + INSTALL_DESTINATION ${INSTALL_CMAKE_DIR}) +endif() + +install(EXPORT ${PROJECT_NAME}-targets DESTINATION "${INSTALL_CMAKE_DIR}") +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake + DESTINATION "${INSTALL_CMAKE_DIR}") + +install( DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/${CMAKE_CFG_INTDIR} + DESTINATION module/${PROJECT_NAME} + COMPONENT modules ) + +# Define ${PROJECT_NAME}_DIR in PARENT_SCOPE so that a `find_package( )` in a bundle +# will easily find the project without requiring a `HINT _BINARY_DIR` argument [ECBUILD-460] +if( NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR ) + # Guard needed because PARENT_SCOPE cannot be used in top-level CMake project + + set( ${PROJECT_NAME}_DIR ${PROJECT_BINARY_DIR} PARENT_SCOPE ) +endif() + +endmacro() diff --git a/cmake/fesom_setup.cmake b/cmake/fesom_setup.cmake new file mode 100644 index 000000000..e916074a5 --- /dev/null +++ b/cmake/fesom_setup.cmake @@ -0,0 +1,145 @@ +# To a large degree this follows the ecbuild setup +message("[${PROJECT_NAME}]") + +### Setup project + +if(CMAKE_VERSION VERSION_LESS 3.21) + get_property(not_top DIRECTORY PROPERTY PARENT_DIRECTORY) + if(NOT not_top) + set(PROJECT_IS_TOP_LEVEL true) + endif() +endif() + +set(BUILD_SHARED_LIBS ON CACHE BOOL "Default to using shared libs") +set(CMAKE_LINK_DEPENDS_NO_SHARED ON) # relink of downstream libraries not required when shared library is rebuilt + +# Default build type: Release +set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.") + +# Set location to look for find_package modules +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../cmake ${CMAKE_MODULE_PATH}) + +# Set Fortran module directory +set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/module/${PROJECT_NAME} ) + +# Build-dir destinations +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +# Set install directories +include(GNUInstallDirs) +if( NOT INSTALL_BIN_DIR ) + set( INSTALL_BIN_DIR ${CMAKE_INSTALL_BINDIR} ) +endif() +if( NOT INSTALL_LIB_DIR ) + set( INSTALL_LIB_DIR ${CMAKE_INSTALL_LIBDIR} ) +endif() +if( NOT INSTALL_INCLUDE_DIR ) + set( INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR} ) +endif() +set( INSTALL_CMAKE_DIR ${INSTALL_LIB_DIR}/cmake/${PROJECT_NAME} ) + +mark_as_advanced( INSTALL_BIN_DIR ) +mark_as_advanced( INSTALL_LIB_DIR ) +mark_as_advanced( INSTALL_INCLUDE_DIR ) +mark_as_advanced( INSTALL_CMAKE_DIR ) + +# make sure nothing breaks if INSTALL_LIB_DIR is not lib +if( NOT INSTALL_LIB_DIR STREQUAL "lib" AND NOT EXISTS ${CMAKE_BINARY_DIR}/${INSTALL_LIB_DIR} ) + execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink lib ${CMAKE_BINARY_DIR}/${INSTALL_LIB_DIR} ) +endif() + +# for macosx use @rpath in a target’s install name (CMP0042) +set( CMAKE_MACOSX_RPATH ON ) + +# add the automatic parts to RPATH which point to dirs outside build tree +set( CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE ) + +# use RPATHs for the build tree +set( CMAKE_SKIP_BUILD_RPATH FALSE ) + +# build with *relative* rpaths by default +option( ENABLE_RPATHS "when installing insert RPATHS into binaries" ON ) +option( ENABLE_RELATIVE_RPATHS "try to use relative RPATHS, including build dir" ON ) +if( ENABLE_RELATIVE_RPATHS ) + set( CMAKE_BUILD_WITH_INSTALL_RPATH TRUE ) +else() + # in case the RPATH is absolute, the install RPATH cannot be set + # at build-time since it breaks the build tree dynamic links + set( CMAKE_BUILD_WITH_INSTALL_RPATH FALSE ) +endif() + + +foreach( p LIB BIN INCLUDE DATA CMAKE ) + set( var INSTALL_${p}_DIR ) + set( ${PROJECT_NAME}_FULL_INSTALL_${p}_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_${p}_DIR}" + CACHE INTERNAL "${PROJECT_NAME} ${p} full install path" ) +endforeach() + + +function( _path_append var path ) + list( FIND ${var} ${path} _found ) + if( _found EQUAL "-1" ) + list( APPEND ${var} ${path}) + endif() + set( ${var} "${${var}}" PARENT_SCOPE ) # +endfunction() + +function( _make_relative_rpath_entry entry var ) + + if( CMAKE_SYSTEM_NAME MATCHES "Darwin" ) + set( ${var} "@loader_path/${entry}" PARENT_SCOPE ) + + elseif( CMAKE_SYSTEM_NAME MATCHES "FreeBSD|Linux|SunOS" ) + set( ${var} "$ORIGIN/${entry}" PARENT_SCOPE ) + + elseif( CMAKE_SYSTEM_NAME MATCHES "AIX" ) # always relative to executable path + set( ${var} "${entry}" PARENT_SCOPE ) + + else() + set( ${var} "${CMAKE_INSTALL_PREFIX}/${entry}" PARENT_SCOPE ) + + endif() +endfunction() + +macro( append_to_rpath RPATH_DIRS ) + + foreach( RPATH_DIR ${RPATH_DIRS} ) + + if( NOT ${RPATH_DIR} STREQUAL "" ) + + file( TO_CMAKE_PATH ${RPATH_DIR} RPATH_DIR ) # sanitize the path + + if( IS_ABSOLUTE ${RPATH_DIR} ) + _path_append( CMAKE_INSTALL_RPATH "${RPATH_DIR}" ) + else() + _make_relative_rpath_entry( "${RPATH_DIR}" rpath_dir_rel ) + _path_append( CMAKE_INSTALL_RPATH ${rpath_dir_rel} ) + endif() + + endif() + + endforeach() + +endmacro( append_to_rpath ) + + +if( ENABLE_RPATHS ) + if( ENABLE_RELATIVE_RPATHS ) + file( RELATIVE_PATH relative_rpath ${CMAKE_INSTALL_PREFIX}/${INSTALL_BIN_DIR} ${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR} ) + append_to_rpath( ${relative_rpath} ) + else() # make rpaths absolute + append_to_rpath( "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR}" ) + endif() +endif() + +# put the include dirs which are in the source or build tree +# before all other include dirs, so the headers in the sources +# are prefered over the already installed ones (since cmake 2.4.1) +set( CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON ) + +# Set -fPIC flag etc. +set( CMAKE_POSITION_INDEPENDENT_CODE ON ) + +include(fesom_export) diff --git a/configure.sh b/configure.sh index 86d7eb02a..78a064628 100755 --- a/configure.sh +++ b/configure.sh @@ -2,10 +2,15 @@ set -e +SOURCE_DIR="$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd -P )" +BUILD_DIR=${BUILD_DIR:-build} + source env.sh # source this from your run script too -mkdir build || true # make sure not to commit this to svn or git -cd build -cmake .. $@ -DCMAKE_BUILD_TYPE=Debug # not required when re-compiling - # additional cmake arguments can be passed to configure.sh - # this also includes fesom specific options in CMakeLists, can be used as -DFESOM_COUPLED=ON +mkdir -p ${BUILD_DIR} # make sure not to commit this to svn or git +cd ${BUILD_DIR} +cmake ${SOURCE_DIR} -DCMAKE_BUILD_TYPE=Debug ${CMAKE_ARGS} $@ + # not required when re-compiling + # additional cmake arguments can be passed to configure.sh + # this also includes fesom specific options in CMakeLists, can be used as -DFESOM_COUPLED=ON make install -j`nproc --all` + diff --git a/env.sh b/env.sh index a073ad208..3e12d53f7 100755 --- a/env.sh +++ b/env.sh @@ -37,7 +37,11 @@ else fi -if [[ $LOGINHOST =~ ^m[A-Za-z0-9]+\.hpc\.dkrz\.de$ ]]; then +if [[ "$LOGINHOST" == "local" ]]; then + echo "Using local environment $BEING_EXECUTED" + [ $BEING_EXECUTED = true ] && exit + return 0 # if we are being sourced, return from this script here +elif [[ $LOGINHOST =~ ^m[A-Za-z0-9]+\.hpc\.dkrz\.de$ ]]; then STRATEGY="mistral.dkrz.de" elif [[ $LOGINHOST =~ ^levante ]] || [[ $LOGINHOST =~ ^l[:alnum:]+\.lvt\.dkrz\.de$ ]]; then STRATEGY="levante.dkrz.de" diff --git a/env/ubuntu/shell b/env/ubuntu/shell index 29fc59dbc..c391d6e04 100644 --- a/env/ubuntu/shell +++ b/env/ubuntu/shell @@ -1,5 +1,6 @@ export FC=mpifort CC=mpicc CXX=mpicxx -export BLAS_LIBRARIES=/usr/lib/x86_64-linux-gnu/blas/ -export UBUNTU_BLAS_LIBRARY="libblas.a" - +if [[ -f "/usr/lib/x86_64-linux-gnu/liblapack.so.3" ]]; then + export LAPACK_LIBRARIES=/usr/lib/x86_64-linux-gnu/liblapack.so.3 + export CMAKE_ARGS=-DLAPACK_LIBRARIES=${LAPACK_LIBRARIES} +fi diff --git a/lib/parms/CMakeLists.txt b/lib/parms/CMakeLists.txt index 62ba062fa..f81cc26fb 100644 --- a/lib/parms/CMakeLists.txt +++ b/lib/parms/CMakeLists.txt @@ -1,32 +1,49 @@ -cmake_minimum_required(VERSION 3.4) +cmake_minimum_required(VERSION 3.16) project(parms C) +# Set location to look for find_package modules +set( CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../../cmake ) + +# Set -fPIC flag etc. +set( CMAKE_POSITION_INDEPENDENT_CODE ON ) + # get our source files set(src_home ${CMAKE_CURRENT_LIST_DIR}) # path to src directory starting from the dir containing our CMakeLists.txt file(GLOB all_sources ${src_home}/src/*.c ${src_home}/src/DDPQ/*.c) -include("${CMAKE_CURRENT_LIST_DIR}/../../cmake/FindBLAS.cmake") +if( NOT LAPACK_LIBRARIES ) + # First check if we have the Cray libraries + set( _cray_libsci_loaded $ENV{CRAY_LIBSCI_DIR} ) + if( _cray_libsci_loaded ) + # set( _CRAY_PRGENV $ENV{PE_ENV} ) + # string( TOLOWER "${_CRAY_PRGENV}" _cray_prgenv ) + # set( LAPACK_LIBRARIES sci_${_cray_prgenv} ) + else() + find_package(LAPACK REQUIRED) # cannot compile without! + endif() +endif() +if( NOT TARGET MPI::MPI_C ) + find_package(MPI REQUIRED COMPONENTS C) +endif() # create our library (set its name to name of this project) -add_library(${PROJECT_NAME} SHARED ${all_sources}) +add_library(${PROJECT_NAME} ${all_sources}) -target_compile_definitions(${PROJECT_NAME} - PRIVATE PARMS USE_MPI REAL=double DBL FORTRAN_UNDERSCORE VOID_POINTER_SIZE_8 HAS_BLAS) +target_compile_definitions(${PROJECT_NAME} PRIVATE PARMS USE_MPI REAL=double DBL FORTRAN_UNDERSCORE VOID_POINTER_SIZE_8) target_include_directories(${PROJECT_NAME} - PUBLIC $ - PRIVATE ${src_home}/src/include + PRIVATE ${src_home}/src/include + PUBLIC $ ) -target_link_libraries(${PROJECT_NAME} PRIVATE ${BLAS_C_LIBRARIES} $ENV{UBUNTU_BLAS_LIBRARY}) +target_link_libraries(${PROJECT_NAME} PRIVATE ${LAPACK_LIBRARIES}) +target_link_libraries(${PROJECT_NAME} PRIVATE MPI::MPI_C) if(${CMAKE_C_COMPILER_ID} STREQUAL "Intel") - target_compile_options(${PROJECT_NAME} PRIVATE -no-prec-div -no-prec-sqrt -fast-transcendentals -fp-model precise) - if(${FESOM_PLATFORM_STRATEGY} STREQUAL levante.dkrz.de ) - target_compile_options(${PROJECT_NAME} PRIVATE -march=core-avx2 -mtune=core-avx2) - endif() + target_compile_options(${PROJECT_NAME} PRIVATE -no-prec-div -no-prec-sqrt -fast-transcendentals -fp-model precise) + + if(${FESOM_PLATFORM_STRATEGY} STREQUAL levante.dkrz.de ) + target_compile_options(${PROJECT_NAME} PRIVATE -march=core-avx2 -mtune=core-avx2) + endif() endif() - -target_compile_options(${PROJECT_NAME} PRIVATE -fPIC) -install(TARGETS ${PROJECT_NAME} EXPORT ifs_sp-targets DESTINATION "${FESOM_INSTALL_PREFIX}/lib") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ffd62c5a3..78bcbfa02 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,10 @@ -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.16) -project(fesom C Fortran) +project(fesom LANGUAGES C CXX Fortran VERSION 2.0.0) + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../cmake ${CMAKE_MODULE_PATH}) + +include(fesom_setup) find_package(MPI REQUIRED COMPONENTS C CXX Fortran) @@ -48,53 +52,110 @@ else() endif() option(ENABLE_OPENACC "compile with OpenACC support" OFF) + +message(STATUS "ENABLE_OPENACC: ${ENABLE_OPENACC}") + set(NV_GPU_ARCH "cc80" CACHE STRING "GPU arch for nvfortran compiler (cc35,cc50,cc60,cc70,cc80,...)") option(ENABLE_OPENMP "build FESOM with OpenMP" OFF) -if(${ENABLE_OPENMP}) - find_package(OpenMP REQUIRED) +message(STATUS "ENABLE_OPENMP: ${ENABLE_OPENMP}") +if(ENABLE_OPENMP) + find_package(OpenMP REQUIRED COMPONENTS Fortran) endif() +option(USE_ICEPACK "Use ICEPACK" OFF) +message(STATUS "USE_ICEPACK: ${USE_ICEPACK}") + # option to trigger building a library version of FESOM # we do not always build the library along with the executable to avoid having two targets here in the CMakeLists.txt # two targets would allow e.g. setting different compiler options or preprocessor definition, which would be error prone. -option(BUILD_FESOM_AS_LIBRARY "Build a library instead of an executable" OFF) +set( ENABLE_IFS_INTERFACE_DEFAULT OFF ) +if(DEFINED BUILD_FESOM_AS_LIBRARY AND NOT DEFINED ENABLE_IFS_INTERFACE) + message(DEPRECATION "Use ENABLE_IFS_INTERFACE instead of BUILD_FESOM_AS_LIBRARY") + set(ENABLE_IFS_INTERFACE_DEFAULT ${BUILD_FESOM_AS_LIBRARY}) +endif() +option(ENABLE_IFS_INTERFACE "Enable IFS interface" ${ENABLE_IFS_INTERFACE_DEFAULT}) +if(DEFINED FESOM_ENABLE_IFS_INTERFACE) + set(ENABLE_IFS_INTERFACE ${FESOM_ENABLE_IFS_INTERFACE}) # To distinguish option in a nested cmake project (bundle) +endif() +message(STATUS "ENABLE_IFS_INTERFACE: ${ENABLE_IFS_INTERFACE}") + +set(ENABLE_MULTIO_DEFAULT OFF) +if(ENABLE_IFS_INTERFACE) + if(USE_ICEPACK) + message(FATAL_ERROR "Could not enable IFS interface as it is incompatible with USE_ICEPACK") + endif() + if( NOT DEFINED ENABLE_MULTIO ) + find_package(multio QUIET) + if( multio_FOUND ) + set(ENABLE_MULTIO_DEFAULT ON) + endif() + endif() +endif() + +option(ENABLE_MULTIO "Enable MultIO" ${ENABLE_MULTIO_DEFAULT}) +if(DEFINED FESOM_ENABLE_MULTIO) + set(ENABLE_MULTIO ${FESOM_ENABLE_MULTIO}) # To distinguish option in a nested cmake project (bundle) +endif() +message(STATUS "ENABLE_MULTIO: ${ENABLE_MULTIO}") +if(ENABLE_MULTIO) + find_package(multio) + if(multio_FOUND) + message(STATUS "Found multio: ${multio_DIR}") + else() + message(FATAL_ERROR "Could not enable multio as multio could not be found") + endif() + if(NOT TARGET multio-fapi) + message(FATAL_ERROR "Could not enable multio as multio was not compiled with 'multio-fapi' target") + endif() +endif() + + +set(FESOM_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/../.." CACHE FILEPATH "directory where FESOM will be installed to via 'make install'") set(FESOM_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/../.." CACHE FILEPATH "directory where FESOM will be installed to via 'make install'") # get our source files -set(src_home ${CMAKE_CURRENT_LIST_DIR}) # path to src directory starting from the dir containing our CMakeLists.txt -if(${USE_ICEPACK}) - file(GLOB sources_Fortran ${src_home}/*.F90 - ${src_home}/icepack_drivers/*.F90 - ${src_home}/icepack_drivers/Icepack/columnphysics/*.F90) -elseif(${BUILD_FESOM_AS_LIBRARY}) - file(GLOB sources_Fortran ${src_home}/*.F90 - ${src_home}/ifs_interface/*.F90) # ICEPACK + LIBRARY NOT SUPPORTED (YET) -else() - file(GLOB sources_Fortran ${src_home}/*.F90) +set(src_home ${CMAKE_CURRENT_SOURCE_DIR}) # path to src directory starting from the dir containing our CMakeLists.txt +file(GLOB sources_Fortran ${src_home}/*.F90) +if(USE_ICEPACK) + file(GLOB sources_ice_pack ${src_home}/icepack_drivers/*.F90 + ${src_home}/icepack_drivers/Icepack/columnphysics/*.F90) + list(APPEND sources_Fortran ${sources_ice_pack}) +elseif(ENABLE_IFS_INTERFACE) # ICEPACK + IFS_INTERFACE NOT SUPPORTED (YET) + list(APPEND sources_Fortran ${src_home}/ifs_interface/ifs_interface.F90 + ${src_home}/ifs_interface/ifs_modules.F90 + ${src_home}/ifs_interface/ifs_notused.F90 + ${src_home}/ifs_interface/mpp_io.F90) +endif() +if(ENABLE_MULTIO) + list(APPEND sources_Fortran ${src_home}/ifs_interface/iom.F90) endif() -#list(REMOVE_ITEM sources_Fortran ${src_home}/fesom_partition_init.F90) + file(GLOB sources_C ${src_home}/*.c) -list(REMOVE_ITEM sources_C ${src_home}/psolve_feom.c) # does the file still exist? # generate a custom file from fesom_version_info.F90 which includes the current git SHA set(FESOM_ORIGINAL_VERSION_FILE ${src_home}/fesom_version_info.F90) set(FESOM_GENERATED_VERSION_FILE ${CMAKE_CURRENT_BINARY_DIR}/fesom_version_info-generated.F90) list(REMOVE_ITEM sources_Fortran ${FESOM_ORIGINAL_VERSION_FILE}) # we want to compile the generated file instead list(APPEND sources_Fortran ${FESOM_GENERATED_VERSION_FILE}) -add_custom_command(OUTPUT 5303B6F4_E4F4_45B2_A6E5_8E2B9FB5CDC4 ${FESOM_GENERATED_VERSION_FILE} # the first arg to OUTPUT is a name for a file we never create to make sure this command will run on every re-build (let our file be the second arg, as the first file is inadvertently removed by make) - COMMAND ${CMAKE_COMMAND} -DFESOM_ORIGINAL_VERSION_FILE=${FESOM_ORIGINAL_VERSION_FILE} -DFESOM_GENERATED_VERSION_FILE=${FESOM_GENERATED_VERSION_FILE} -P GitRepositoryInfo.cmake - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - COMMENT "determining ${PROJECT_NAME} git SHA ...") +set_source_files_properties(${FESOM_GENERATED_VERSION_FILE} PROPERTIES GENERATED TRUE) + +add_custom_target(fesom_version_info-generated.F90 ALL + COMMENT "Determining ${PROJECT_NAME} git SHA ..." + COMMAND ${CMAKE_COMMAND} -DFESOM_ORIGINAL_VERSION_FILE=${FESOM_ORIGINAL_VERSION_FILE} -DFESOM_GENERATED_VERSION_FILE=${FESOM_GENERATED_VERSION_FILE} -P GitRepositoryInfo.cmake + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) -#if(${FESOM_STANDALONE}) +#if(FESOM_STANDALONE) # list(REMOVE_ITEM sources_Fortran ${src_home}/cpl_driver.F90) #endif() list(REMOVE_ITEM sources_Fortran ${src_home}/fvom_init.F90 ${src_home}/oce_local.F90 ${src_home}/gen_comm.F90) list(REMOVE_ITEM sources_C ${src_home}/fort_part.c) list(REMOVE_ITEM sources_Fortran ${src_home}/fesom_main.F90) +find_package( NETCDF REQUIRED COMPONENTS C Fortran ) +find_package( MPI REQUIRED COMPONENTS C Fortran ) + # depends on the metis library #add_subdirectory(../lib/metis-5.1.0 ${PROJECT_BINARY_DIR}/metis) #include_directories(../lib/metis-5.1.0/include) @@ -103,55 +164,70 @@ add_subdirectory(../lib/parms ${PROJECT_BINARY_DIR}/parms) add_subdirectory(async_threads_cpp) -include(${CMAKE_CURRENT_LIST_DIR}/../cmake/FindNETCDF.cmake) - -if(${BUILD_FESOM_AS_LIBRARY}) - add_library(${PROJECT_NAME}_C ${sources_C}) -else() add_library(${PROJECT_NAME}_C ${sources_C}) -endif() target_compile_definitions(${PROJECT_NAME}_C PRIVATE PARMS USE_MPI REAL=double DBL HAS_BLAS FORTRAN_UNDERSCORE VOID_POINTER_SIZE_8 SGI LINUX UNDER_ MPI2) -target_link_libraries(${PROJECT_NAME}_C PUBLIC parms) #metis +target_link_libraries(${PROJECT_NAME}_C PRIVATE parms) #metis +target_link_libraries(${PROJECT_NAME}_C PRIVATE MPI::MPI_C) -# create our binary or library (set its name to name of this project) -# we do not always build the library along with the executable to avoid having two targets here in the CMakeLists.txt -# two targets would allow e.g. setting different compiler options or preprocessor definition, which would be error prone. -if(${BUILD_FESOM_AS_LIBRARY}) - add_library(${PROJECT_NAME} ${sources_Fortran}) -else() - add_executable(${PROJECT_NAME} ${sources_Fortran} ${src_home}/fesom_main.F90) +# fesom library +add_library(${PROJECT_NAME} ${sources_Fortran}) +add_dependencies(${PROJECT_NAME} fesom_version_info-generated.F90) +target_compile_definitions(${PROJECT_NAME} PRIVATE PARMS -DMETIS_VERSION=5 -DPART_WEIGHTED -DMETISRANDOMSEED=35243) + +target_include_directories(${PROJECT_NAME} PUBLIC $) +target_include_directories(${PROJECT_NAME} PUBLIC $) +target_include_directories(${PROJECT_NAME} PRIVATE ${NETCDF_Fortran_INCLUDE_DIRECTORIES} ${OASIS_Fortran_INCLUDE_DIRECTORIES}) +target_include_directories(${PROJECT_NAME} PRIVATE ${MCT_Fortran_INCLUDE_DIRECTORIES} ${MPEU_Fortran_INCLUDE_DIRECTORIES}) +target_include_directories(${PROJECT_NAME} PRIVATE ${SCRIP_Fortran_INCLUDE_DIRECTORIES}) +target_link_libraries(${PROJECT_NAME} PRIVATE parms) #metis +target_link_libraries(${PROJECT_NAME} PRIVATE async_threads) +target_link_libraries(${PROJECT_NAME} PRIVATE MPI::MPI_Fortran) +target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_C ${NETCDF_Fortran_LIBRARIES} ${NETCDF_C_LIBRARIES} ${OASIS_Fortran_LIBRARIES}) +target_link_libraries(${PROJECT_NAME} PRIVATE ${MCT_Fortran_LIBRARIES} ${MPEU_Fortran_LIBRARIES} ${SCRIP_Fortran_LIBRARIES}) +set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE Fortran) +if(ENABLE_OPENMP AND NOT ${CMAKE_Fortran_COMPILER_ID} STREQUAL Cray) + target_link_libraries(${PROJECT_NAME} PRIVATE OpenMP::OpenMP_Fortran) +endif() + +if(ENABLE_MULTIO) + target_compile_definitions(${PROJECT_NAME} PRIVATE __MULTIO) + target_link_libraries(${PROJECT_NAME} PRIVATE multio-fapi) endif() -target_compile_definitions(${PROJECT_NAME} PRIVATE PARMS -DMETIS_VERSION=5 -DPART_WEIGHTED -DMETISRANDOMSEED=35243 __MULTIO) -if(${DISABLE_MULTITHREADING}) + +if(DISABLE_MULTITHREADING) target_compile_definitions(${PROJECT_NAME} PRIVATE DISABLE_MULTITHREADING) endif() -if(${FESOM_COUPLED}) - include(${CMAKE_CURRENT_LIST_DIR}/../cmake/FindOASIS.cmake) + +if(FESOM_COUPLED) + find_package(OASIS REQUIRED) target_compile_definitions(${PROJECT_NAME} PRIVATE __oasis) endif() -if(${OIFS_COUPLED}) + +if(OIFS_COUPLED) target_compile_definitions(${PROJECT_NAME} PRIVATE __oifs) endif() -if(${USE_ICEPACK}) + +if(USE_ICEPACK) target_compile_definitions(${PROJECT_NAME} PRIVATE __icepack) endif() -if(${BUILD_FESOM_AS_LIBRARY}) + +if(ENABLE_IFS_INTERFACE) target_compile_definitions(${PROJECT_NAME} PRIVATE __ifsinterface) endif() -if(${VERBOSE}) + +if(VERBOSE) target_compile_definitions(${PROJECT_NAME} PRIVATE VERBOSE) endif() -if(${OPENMP_REPRODUCIBLE}) + +if(OPENMP_REPRODUCIBLE) target_compile_definitions(${PROJECT_NAME} PRIVATE __openmp_reproducible) endif() + # CMAKE_Fortran_COMPILER_ID will also work if a wrapper is being used (e.g. mpif90 wraps ifort -> compiler id is Intel) if(${CMAKE_Fortran_COMPILER_ID} STREQUAL Intel ) - if(${BUILD_FESOM_AS_LIBRARY}) - target_compile_options(${PROJECT_NAME} PRIVATE -r8 -i4 -fp-model precise -no-prec-div -no-prec-sqrt -fimf-use-svml -ip -init=zero -no-wrap-margin -fpe0 -g -traceback) # add -fpe0 for RAPS environment - else() - target_compile_options(${PROJECT_NAME} PRIVATE -r8 -i4 -fp-model precise -no-prec-div -no-prec-sqrt -fimf-use-svml -ip -init=zero -no-wrap-margin -g -traceback) - endif() + target_compile_options(${PROJECT_NAME} PRIVATE -r8 -i4 -fp-model precise -no-prec-div -no-prec-sqrt -fimf-use-svml -xHost -ip -init=zero -no-wrap-margin -fpe0) # add -fpe0 for RAPS environment + if(${FESOM_PLATFORM_STRATEGY} STREQUAL levante.dkrz.de ) target_compile_options(${PROJECT_NAME} PRIVATE -march=core-avx2 -mtune=core-avx2) elseif(${FESOM_PLATFORM_STRATEGY} STREQUAL albedo) @@ -170,51 +246,31 @@ elseif(${CMAKE_Fortran_COMPILER_ID} STREQUAL GNU ) target_compile_options(${PROJECT_NAME} PRIVATE -fallow-argument-mismatch) # gfortran v10 is strict about erroneous API calls: "Rank mismatch between actual argument at (1) and actual argument at (2) (scalar and rank-1)" endif() elseif(${CMAKE_Fortran_COMPILER_ID} STREQUAL Cray ) - if(${ENABLE_OPENMP}) - target_compile_options(${PROJECT_NAME} PRIVATE -c -emf -hbyteswapio -hflex_mp=conservative -hfp1 -hadd_paren -Ounroll0 -hipa0 -r am -s real64 -N 1023 -homp) + target_compile_options(${PROJECT_NAME} PRIVATE -c -emf -hbyteswapio -hflex_mp=conservative -hfp1 -hadd_paren -Ounroll0 -hipa0 -r am -s real64 -N 1023) + if(ENABLE_OPENMP) + target_compile_options(${PROJECT_NAME} PRIVATE -homp) else() - target_compile_options(${PROJECT_NAME} PRIVATE -c -emf -hbyteswapio -hflex_mp=conservative -hfp1 -hadd_paren -Ounroll0 -hipa0 -r am -s real64 -N 1023 -hnoomp) + target_compile_options(${PROJECT_NAME} PRIVATE -hnoomp) endif() elseif(${CMAKE_Fortran_COMPILER_ID} STREQUAL NVHPC ) target_compile_definitions(${PROJECT_NAME} PRIVATE ENABLE_NVHPC_WORKAROUNDS) target_compile_options(${PROJECT_NAME} PRIVATE -fast -fastsse -O3 -Mallocatable=95 -Mr8 -pgf90libs) - if(${ENABLE_OPENACC}) + if(ENABLE_OPENACC) # additional compiler settings target_compile_options(${PROJECT_NAME} PRIVATE -acc -ta=tesla:${NV_GPU_ARCH} -Minfo=accel) set(CMAKE_EXE_LINKER_FLAGS "-acc -ta=tesla:${NV_GPU_ARCH}") endif() - if(${ENABLE_OPENMP}) + if(ENABLE_OPENMP) target_compile_options(${PROJECT_NAME} PRIVATE -Mipa=fast) else() target_compile_options(${PROJECT_NAME} PRIVATE -Mipa=fast,inline) endif() endif() -if(${BUILD_FESOM_AS_LIBRARY}) - target_compile_options(${PROJECT_NAME} PRIVATE -fPIC) - target_compile_options(${PROJECT_NAME}_C PRIVATE -fPIC) -endif() -target_include_directories(${PROJECT_NAME} PRIVATE ${NETCDF_Fortran_INCLUDE_DIRECTORIES} ${OASIS_Fortran_INCLUDE_DIRECTORIES}) -target_include_directories(${PROJECT_NAME} PRIVATE ${MCT_Fortran_INCLUDE_DIRECTORIES} ${MPEU_Fortran_INCLUDE_DIRECTORIES}) -target_include_directories(${PROJECT_NAME} PRIVATE ${SCRIP_Fortran_INCLUDE_DIRECTORIES}) -target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_C ${NETCDF_Fortran_LIBRARIES} ${NETCDF_C_LIBRARIES} ${OASIS_Fortran_LIBRARIES}) -target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_C ${MCT_Fortran_LIBRARIES} ${MPEU_Fortran_LIBRARIES} ${SCRIP_Fortran_LIBRARIES}) -target_link_libraries(${PROJECT_NAME} PRIVATE MPI::MPI_Fortran) -target_link_libraries(${PROJECT_NAME} PRIVATE async_threads_cpp multio-fapi) +# fesom.x executable +add_executable(${PROJECT_NAME}.x ${src_home}/fesom_main.F90) +target_link_libraries(${PROJECT_NAME}.x PUBLIC ${PROJECT_NAME}) -set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE Fortran) -if(${ENABLE_OPENMP} AND NOT ${CMAKE_Fortran_COMPILER_ID} STREQUAL Cray) - target_compile_options(${PROJECT_NAME} PRIVATE ${OpenMP_Fortran_FLAGS}) # currently we only have OpenMP in the Fortran part - target_link_libraries(${PROJECT_NAME} PRIVATE OpenMP::OpenMP_Fortran) -endif() +### Export and installation -#set(FESOM_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_DIR}/.." CACHE FILEPATH "directory where FESOM will be installed to via 'make install'") -if(${BUILD_FESOM_AS_LIBRARY}) - install(TARGETS ${PROJECT_NAME} EXPORT ifs_sp-targets DESTINATION "${FESOM_INSTALL_PREFIX}/lib") - install(TARGETS ${PROJECT_NAME}_C EXPORT ifs_sp-targets DESTINATION "${FESOM_INSTALL_PREFIX}/lib") -else() - set(FESOM_INSTALL_FILEPATH "${FESOM_INSTALL_PREFIX}/bin/fesom.x") - get_filename_component(FESOM_INSTALL_PATH ${FESOM_INSTALL_FILEPATH} DIRECTORY) - get_filename_component(FESOM_INSTALL_NAME ${FESOM_INSTALL_FILEPATH} NAME) - install(PROGRAMS ${PROJECT_BINARY_DIR}/${PROJECT_NAME} DESTINATION ${FESOM_INSTALL_PATH} RENAME ${FESOM_INSTALL_NAME}) -endif() +fesom_export(TARGETS ${PROJECT_NAME}_C ${PROJECT_NAME} parms async_threads fesom.x) diff --git a/src/GitRepositoryInfo.cmake b/src/GitRepositoryInfo.cmake index e5eb37c26..4f6a8172e 100644 --- a/src/GitRepositoryInfo.cmake +++ b/src/GitRepositoryInfo.cmake @@ -9,4 +9,6 @@ else() message("git not found, setting FESOM_GIT_SHA to: ${FESOM_GIT_SHA}") endif() -configure_file(${FESOM_ORIGINAL_VERSION_FILE} ${FESOM_GENERATED_VERSION_FILE} @ONLY) +configure_file(${FESOM_ORIGINAL_VERSION_FILE} ${FESOM_GENERATED_VERSION_FILE}.tmp @ONLY) +execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${FESOM_GENERATED_VERSION_FILE}.tmp ${FESOM_GENERATED_VERSION_FILE}) +execute_process(COMMAND ${CMAKE_COMMAND} -E remove ${FESOM_GENERATED_VERSION_FILE}.tmp) diff --git a/src/MOD_DYN.F90 b/src/MOD_DYN.F90 index ded902231..542992876 100644 --- a/src/MOD_DYN.F90 +++ b/src/MOD_DYN.F90 @@ -1,7 +1,7 @@ !========================================================== MODULE MOD_DYN USE O_PARAM -USE, intrinsic :: ISO_FORTRAN_ENV +USE, intrinsic :: ISO_FORTRAN_ENV, only : int32 USE MOD_WRITE_BINARY_ARRAYS USE MOD_READ_BINARY_ARRAYS IMPLICIT NONE diff --git a/src/MOD_ICE.F90 b/src/MOD_ICE.F90 index b2a91acd8..d2a29f7ef 100644 --- a/src/MOD_ICE.F90 +++ b/src/MOD_ICE.F90 @@ -1,6 +1,6 @@ MODULE MOD_ICE USE o_PARAM, only: WP -USE, intrinsic :: ISO_FORTRAN_ENV +USE, intrinsic :: ISO_FORTRAN_ENV, only : int32 USE MOD_WRITE_BINARY_ARRAYS USE MOD_READ_BINARY_ARRAYS IMPLICIT NONE diff --git a/src/MOD_MESH.F90 b/src/MOD_MESH.F90 index 30c2b928f..27b02fb3e 100644 --- a/src/MOD_MESH.F90 +++ b/src/MOD_MESH.F90 @@ -3,7 +3,7 @@ MODULE MOD_MESH USE O_PARAM USE MOD_WRITE_BINARY_ARRAYS USE MOD_READ_BINARY_ARRAYS -USE, intrinsic :: ISO_FORTRAN_ENV +USE, intrinsic :: ISO_FORTRAN_ENV, only : int32 IMPLICIT NONE SAVE integer, parameter :: MAX_ADJACENT=32 ! Max allowed number of adjacent nodes diff --git a/src/MOD_PARTIT.F90 b/src/MOD_PARTIT.F90 index fb4a88542..d64183086 100644 --- a/src/MOD_PARTIT.F90 +++ b/src/MOD_PARTIT.F90 @@ -2,7 +2,7 @@ ! Variables to organize parallel work module MOD_PARTIT USE O_PARAM -USE, intrinsic :: ISO_FORTRAN_ENV +USE, intrinsic :: ISO_FORTRAN_ENV, only : int32 USE MOD_WRITE_BINARY_ARRAYS USE MOD_READ_BINARY_ARRAYS #if defined(_OPENMP) diff --git a/src/MOD_TRACER.F90 b/src/MOD_TRACER.F90 index 0e66e96aa..8082a9b33 100644 --- a/src/MOD_TRACER.F90 +++ b/src/MOD_TRACER.F90 @@ -1,7 +1,7 @@ !========================================================== MODULE MOD_TRACER USE O_PARAM -USE, intrinsic :: ISO_FORTRAN_ENV +USE, intrinsic :: ISO_FORTRAN_ENV, only : int32 USE MOD_WRITE_BINARY_ARRAYS USE MOD_READ_BINARY_ARRAYS IMPLICIT NONE diff --git a/src/async_threads_cpp/CMakeLists.txt b/src/async_threads_cpp/CMakeLists.txt index f54186d8f..2b65b35cc 100644 --- a/src/async_threads_cpp/CMakeLists.txt +++ b/src/async_threads_cpp/CMakeLists.txt @@ -1,24 +1,18 @@ -cmake_minimum_required(VERSION 3.4) +cmake_minimum_required(VERSION 3.16) -project(async_threads_cpp CXX C Fortran) # the FortranCInterface requires the C language to be enabled +project(async_threads CXX C Fortran) # the FortranCInterface requires the C language to be enabled + +set (CMAKE_CXX_STANDARD 11) # get our source files -file(GLOB sources_CXX ${CMAKE_CURRENT_LIST_DIR}/*.cpp) +file(GLOB sources ${CMAKE_CURRENT_LIST_DIR}/*.cpp) include(FortranCInterface) FortranCInterface_HEADER(ThreadsManagerFCMacros.h MACRO_NAMESPACE "ThreadsManagerFCMacros_" SYMBOLS init_ccall begin_ccall end_ccall) -add_library(${PROJECT_NAME} SHARED ${sources_CXX}) - +add_library(${PROJECT_NAME} ${sources} async_threads_module.F90) target_include_directories(${PROJECT_NAME} - PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_BINARY_DIR} -) - -if(${CMAKE_CXX_COMPILER_ID} STREQUAL Cray ) - target_compile_options(${PROJECT_NAME} PRIVATE -hstd=c++11) -else() - target_compile_options(${PROJECT_NAME} PRIVATE -std=c++11) -endif() - -target_compile_options(${PROJECT_NAME} PRIVATE -fPIC) -install(TARGETS ${PROJECT_NAME} EXPORT ifs_sp-targets DESTINATION "${FESOM_INSTALL_PREFIX}/lib") + PRIVATE $ + PRIVATE $ + PUBLIC $ +) \ No newline at end of file diff --git a/src/async_threads_module.F90 b/src/async_threads_cpp/async_threads_module.F90 similarity index 96% rename from src/async_threads_module.F90 rename to src/async_threads_cpp/async_threads_module.F90 index 345f14eb5..198eb98dd 100644 --- a/src/async_threads_module.F90 +++ b/src/async_threads_cpp/async_threads_module.F90 @@ -1,3 +1,4 @@ +#define __FILENAME__ "async_threads_module.F90" module async_threads_module implicit none public thread_type @@ -110,7 +111,7 @@ subroutine assert(val, line) integer, intent(in) :: line ! EO args if(.NOT. val) then - print *, "error in line ",line, __FILE__ + print *, "error in line ",line, __FILENAME__ stop 1 end if end subroutine diff --git a/src/fesom-config.cmake.in b/src/fesom-config.cmake.in new file mode 100644 index 000000000..c0735281f --- /dev/null +++ b/src/fesom-config.cmake.in @@ -0,0 +1,36 @@ +# This file will get included upon `find_package(fesom ... )` + +@PACKAGE_INIT@ + +### insert definitions for IMPORTED targets +if(NOT @PROJECT_NAME@_BINARY_DIR) + find_file(@PROJECT_NAME@_TARGETS_FILE + NAMES @PROJECT_NAME@-targets.cmake + HINTS ${CMAKE_CURRENT_LIST_DIR} @PACKAGE_TARGETS_DIRS@ + NO_DEFAULT_PATH) + if(@PROJECT_NAME@_TARGETS_FILE) + include(${@PROJECT_NAME@_TARGETS_FILE}) + endif() +endif() + +include(CMakeFindDependencyMacro) +if( NOT (TARGET MPI::MPI_C AND TARGET MPI::MPI_Fortran) ) + enable_language(C) + enable_language(Fortran) + find_dependency(MPI COMPONENTS C Fortran) +endif() +if( @ENABLE_OPENMP@ ) + if( NOT TARGET OpenMP::OpenMP_Fortran ) + enable_language(Fortran) + find_dependency(OpenMP COMPONENTS Fortran) + endif() + set( fesom_HAVE_OPENMP 1 ) +else() + set( fesom_HAVE_OPENMP 0 ) +endif() + +if( @ENABLE_IFS_INTERFACE@ ) + set( fesom_HAVE_IFS_INTERFACE 1 ) +else() + set( fesom_HAVE_IFS_INTERFACE 0 ) +endif() diff --git a/src/fesom_module.F90 b/src/fesom_module.F90 index fea998944..7cab119cf 100755 --- a/src/fesom_module.F90 +++ b/src/fesom_module.F90 @@ -29,6 +29,8 @@ module fesom_main_storage_module use read_mesh_interface use fesom_version_info_module use command_line_options_module + use, intrinsic :: iso_fortran_env, only : real32 + ! Define icepack module #if defined (__icepack) use icedrv_main, only: set_icepack, init_icepack, alloc_icepack diff --git a/src/gen_halo_exchange.F90 b/src/gen_halo_exchange.F90 index ca6f87cb4..bdc94359c 100755 --- a/src/gen_halo_exchange.F90 +++ b/src/gen_halo_exchange.F90 @@ -16,7 +16,7 @@ module g_comm - use, intrinsic :: ISO_FORTRAN_ENV + use, intrinsic :: ISO_FORTRAN_ENV, only: int16, int32, real32, real64 implicit none diff --git a/src/gen_modules_read_NetCDF.F90 b/src/gen_modules_read_NetCDF.F90 index 8118fa78a..581e518d2 100755 --- a/src/gen_modules_read_NetCDF.F90 +++ b/src/gen_modules_read_NetCDF.F90 @@ -12,7 +12,7 @@ subroutine read_other_NetCDF(file, vari, itime, model_2Darray, check_dummy, do_o ! if check_dummy=.true., missing value is replaced with a meaningful value nearby ! if check_dummy=.false., missing value is replaced with 0.0 - use, intrinsic :: ISO_FORTRAN_ENV + use, intrinsic :: ISO_FORTRAN_ENV, only: real64 use g_config use o_param USE MOD_MESH @@ -198,6 +198,7 @@ subroutine read_surf_hydrography_NetCDF(file, vari, itime, model_2Darray, partit USE MOD_PARTIT USE MOD_PARSUP use g_rotate_grid + use, intrinsic :: ISO_FORTRAN_ENV, only: real64 implicit none #include "netcdf.inc" type(t_mesh), intent(in), target :: mesh @@ -312,7 +313,7 @@ end subroutine read_surf_hydrography_NetCDF ! subroutine read_2ddata_on_grid_NetCDF(file, vari, itime, model_2Darray, partit, mesh) - use, intrinsic :: ISO_FORTRAN_ENV + use, intrinsic :: ISO_FORTRAN_ENV, only: real64 use g_config use o_param diff --git a/src/ifs_interface/ifs_interface.F90 b/src/ifs_interface/ifs_interface.F90 index 847fa60ae..4f0f659a9 100644 --- a/src/ifs_interface/ifs_interface.F90 +++ b/src/ifs_interface/ifs_interface.F90 @@ -9,7 +9,6 @@ MODULE nemogcmcoup_steps INTEGER :: substeps !per IFS timestep END MODULE nemogcmcoup_steps -#if defined(__MULTIO) SUBROUTINE nemogcmcoup_init_ioserver( icomm, lnemoioserver, irequired, iprovided, lmpi1) ! Initialize the NEMO mppio server @@ -46,8 +45,7 @@ SUBROUTINE nemogcmcoup_end_ioserver IMPLICIT NONE CALL mpp_stop() - END SUBROUTINE nemogcmcoup_end_ioserver -#endif +END SUBROUTINE nemogcmcoup_end_ioserver SUBROUTINE nemogcmcoup_init( mype, icomm, inidate, initime, itini, itend, zstp, & & lwaveonly, iatmunit, lwrite ) diff --git a/src/ifs_interface/iom.F90 b/src/ifs_interface/iom.F90 index a7778834a..5ce9469ac 100644 --- a/src/ifs_interface/iom.F90 +++ b/src/ifs_interface/iom.F90 @@ -109,11 +109,10 @@ SUBROUTINE iom_initialize(client_id, local_comm, return_comm, global_comm ) CALL ctl_stop( 'setting multio failure handler failed: ', multio_error_string(err)) end if - err = conf_ctx%mpi_allow_world_default_comm(.FALSE._1) + err = conf_ctx%mpi_allow_world_default_comm(.FALSE.) IF (err /= MULTIO_SUCCESS) THEN - CALL ctl_stop('conf_ctx%mpi_allow_world_default_comm(.FALSE._1) failed: ', multio_error_string(err)) + CALL ctl_stop('conf_ctx%mpi_allow_world_default_comm(.FALSE.) failed: ', multio_error_string(err)) END IF - err = conf_ctx%mpi_return_client_comm(return_comm) IF (err /= MULTIO_SUCCESS) THEN WRITE (err_str, "(I10)") return_comm @@ -201,9 +200,9 @@ SUBROUTINE iom_init_server(server_comm) CALL ctl_stop('setting multio failure handler failed: ', multio_error_string(err)) END IF - err = conf_ctx%mpi_allow_world_default_comm(.FALSE._1) + err = conf_ctx%mpi_allow_world_default_comm(.FALSE.) IF (err /= MULTIO_SUCCESS) THEN - CALL ctl_stop('conf_ctx%mpi_allow_world_default_comm(.FALSE._1) failed: ', multio_error_string(err)) + CALL ctl_stop('conf_ctx%mpi_allow_world_default_comm(.FALSE.) failed: ', multio_error_string(err)) END IF err = conf_ctx%mpi_parent_comm(int(mio_parent_comm)) diff --git a/src/ifs_interface/mpp_io.F90 b/src/ifs_interface/mpp_io.F90 index eda8feae7..e285b111a 100644 --- a/src/ifs_interface/mpp_io.F90 +++ b/src/ifs_interface/mpp_io.F90 @@ -7,7 +7,8 @@ MODULE mpp_io #if defined(__MULTIO) - USE iom + USE iom, only : iom_initialize, iom_init_server, iom_finalize +#endif IMPLICIT NONE PRIVATE @@ -157,12 +158,14 @@ SUBROUTINE mpp_io_init_2( iicomm ) CALL mpi_comm_rank( iicommo, mppcomprank, ierr ) CALL mpi_comm_size( iicommo, mppcompsize, ierr ) +#if defined(__MULTIO) IF (.NOT.lioserver) THEN CALL iom_initialize( "for_xios_mpi_id", return_comm=iicommm, global_comm = pcommworldmultio ) ! nemo local communicator given by xios ELSE ! For io-server tasks start an run the right server CALL iom_init_server( server_comm = pcommworldmultio ) ENDIF +#endif ! Return to the model with iicomm being compute only tasks iicomm = iicommo @@ -172,11 +175,13 @@ END SUBROUTINE mpp_io_init_2 SUBROUTINE mpp_stop INTEGER :: ierr +#if defined(__MULTIO) IF (.NOT.lioserver) THEN call iom_finalize() ENDIF +#endif CALL mpi_finalize( ierr ) END SUBROUTINE mpp_stop -#endif + END MODULE mpp_io diff --git a/test_downstream/.gitignore b/test_downstream/.gitignore new file mode 100644 index 000000000..378eac25d --- /dev/null +++ b/test_downstream/.gitignore @@ -0,0 +1 @@ +build diff --git a/test_downstream/CMakeLists.txt b/test_downstream/CMakeLists.txt new file mode 100644 index 000000000..390aea563 --- /dev/null +++ b/test_downstream/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.16 FATAL_ERROR) + +project(test_downstream LANGUAGES Fortran) + +find_package(fesom REQUIRED) + +message("fesom found: ${fesom_DIR}") +message("fesom_VERSION: ${fesom_VERSION}") +message("fesom_HAVE_OPENMP: ${fesom_HAVE_OPENMP}") +message("fesom_HAVE_IFS_INTERFACE: ${fesom_HAVE_IFS_INTERFACE}") + +if(NOT TARGET fesom) + message(FATAL_ERROR "fesom was installed wrongly: fesom target not found") +endif() + +if (ASSERT_FESOM_DIR) + if (NOT fesom_DIR MATCHES "${ASSERT_FESOM_DIR}") + message(FATAL_ERROR "fesom was not found in expected location ${ASSERT_FESOM_DIR}") + endif() +endif() + +if (DEFINED ASSERT_HAVE_IFS_INTERFACE) + if (ASSERT_HAVE_IFS_INTERFACE AND NOT fesom_HAVE_IFS_INTERFACE) + message(FATAL_ERROR "fesom was installed wrongly: fesom_HAVE_IFS_INTERFACE=${fesom_HAVE_IFS_INTERFACE}") + elseif (NOT ASSERT_HAVE_IFS_INTERFACE AND fesom_HAVE_IFS_INTERFACE) + message(FATAL_ERROR "fesom was installed wrongly: fesom_HAVE_IFS_INTERFACE=${fesom_HAVE_IFS_INTERFACE}") + endif() +endif() + +get_target_property(target_type fesom TYPE) +if( NOT target_type MATCHES "STATIC_LIBRARY|SHARED_LIBRARY") + message(FATAL_ERROR "fesom target's TYPE is expected to be STATIC_LIBRARY or SHARED_LIBRARY. Actual TYPE: ${target_type}") +endif () + +add_executable( main main.F90 ) +target_link_libraries( main fesom ) + diff --git a/test_downstream/README b/test_downstream/README new file mode 100644 index 000000000..e46358cd9 --- /dev/null +++ b/test_downstream/README @@ -0,0 +1,9 @@ +This dummy project can be used to test if fesom was installed and can be found correctly in downstream CMake projects + +Example use: + + export fesom_ROOT= # can be install or build dir!!! + cmake -S . -B build + cmake --build build + build/main + diff --git a/test_downstream/main.F90 b/test_downstream/main.F90 new file mode 100644 index 000000000..3fe20d678 --- /dev/null +++ b/test_downstream/main.F90 @@ -0,0 +1,5 @@ +program main +use mod_mesh + + +end program