diff --git a/CMakeLists.txt b/CMakeLists.txt index adc0b29b9..30e0559d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,16 +9,33 @@ cmake_minimum_required( VERSION 3.24 FATAL_ERROR ) find_package( ecbuild 3.4 REQUIRED HINTS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../ecbuild ) -set(PARENT_PROJECT_NAME "${PROJECT_NAME}") +# If the directory name matches ecwam_dp or ecwam_sp, that will be chosen as PROJECT_NAME instead +get_filename_component( ecwam-source_dir ${CMAKE_CURRENT_SOURCE_DIR} NAME ) +if( ecwam-source_dir MATCHES "ecwam_(dp|sp)" ) + set( ECWAM_PROJECT_NAME ${ecwam-source_dir} ) +endif() + if( NOT ECWAM_PROJECT_NAME ) set( ECWAM_PROJECT_NAME ecwam ) endif() +string( TOUPPER ${ECWAM_PROJECT_NAME} PNAME ) +set( ${PNAME}_ECBUILD_COMPILE_FLAGS ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ecwam_init_flags.cmake CACHE FILEPATH "") project( ${ECWAM_PROJECT_NAME} LANGUAGES Fortran C CXX ) include( ecwam_macros ) ecbuild_enable_fortran( REQUIRED NO_MODULE_DIRECTORY ) +### Determine ocean model precision +if( NOT DEFINED OCEAN_PREC ) + if( HAVE_SINGLE_PRECISION ) + set(OCEAN_PREC SP) + else() + set(OCEAN_PREC DP) + endif() +endif() +string( TOLOWER "${OCEAN_PREC}" ocean_prec ) + ### Dependencies ecbuild_find_package( fiat REQUIRED ) @@ -50,7 +67,7 @@ ecbuild_add_option( FEATURE UNWAM ecbuild_add_option( FEATURE OCEAN_COUPLING DEFAULT ON DESCRIPTION "Support ocean coupling" - CONDITION ${PNAME}_OCEANMODEL_LIBRARIES ) + REQUIRED_PACKAGES "nemo_${ocean_prec}" ) ecbuild_add_option( FEATURE ECWAM_LAUNCH DEFAULT ON diff --git a/cmake/ecwam_compile_flags.cmake b/cmake/ecwam_compile_flags.cmake index bc81e5a5d..d5a37b2e6 100644 --- a/cmake/ecwam_compile_flags.cmake +++ b/cmake/ecwam_compile_flags.cmake @@ -6,6 +6,11 @@ # granted to it by virtue of its status as an intergovernmental organisation # nor does it submit to any jurisdiction. +# Capture ecbuild defaults and/or flags set by a toolchain +set( ${PNAME}_Fortran_FLAGS "${${PNAME}_Fortran_FLAGS} ${ECBUILD_Fortran_FLAGS}" ) +set( ${PNAME}_Fortran_FLAGS_BIT "${${PNAME}_Fortran_FLAGS_BIT} ${ECBUILD_Fortran_FLAGS_BIT}" ) +set( ${PNAME}_Fortran_FLAGS_DEBUG "${${PNAME}_Fortran_FLAGS_DEBUG} ${ECBUILD_Fortran_FLAGS_DEBUG}" ) + if(CMAKE_Fortran_COMPILER_ID MATCHES "Cray") set(autopromote_flags "-sreal64") set(checkbounds_flags "-Rb") @@ -23,11 +28,17 @@ elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel") set(checkbounds_flags "-check bounds") set(initsnan_flags "-init=snan") set(fpe_flags "-fpe0") + set(vectorization_flags "-march=core-avx2 -no-fma") + set(fpmodel_flags "-fp-model precise -fp-speculation=safe") + set(transcendentals_flags "-fast-transcendentals") + set(heap_arrays_flags "-heap-arrays 32") elseif(CMAKE_Fortran_COMPILER_ID MATCHES "PGI|NVHPC") set(autopromote_flags "-r8") set(fpe_flags "-Ktrap=fp") -# set(checkbounds_flags "-Mbounds") # Added by default by CMake in NVHPC debug builds + set(vectorization_flags "-O3 -fast") + string(REPLACE "-O2" "" ${PNAME}_Fortran_FLAGS_BIT ${${PNAME}_Fortran_FLAGS_BIT}) + set(checkbounds_flags "-Mbounds") elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Flang") set(autopromote_flags "-fdefault-real-8") @@ -38,17 +49,29 @@ endif() if( NOT HAVE_SINGLE_PRECISION ) ecbuild_add_fortran_flags( "${autopromote_flags}" NAME autopromote ) endif() +if( DEFINED vectorization_flags ) + # vectorization flags must be per-sourcefile overrideable, so are set via ${PNAME}_Fortran_FLAGS + set( ${PNAME}_Fortran_FLAGS_BIT "${${PNAME}_Fortran_FLAGS_BIT} ${vectorization_flags}" ) +endif() +if( DEFINED fpmodel_flags ) + ecbuild_add_fortran_flags( "${fpmodel_flags}" NAME fpmodel ) +endif() +if( DEFINED transcendentals_flags ) + ecbuild_add_fortran_flags( "${transcendentals_flags}" NAME transcendentals ) +endif() +if( DEFINED heap_arrays_flags ) + ecbuild_add_fortran_flags( "${heap_arrays_flags}" NAME heap_arrays ) +endif() -## Debug flags for NVHPC are applied selectively to sourcefiles in src/ecwam/CMakeLists.txt -if( CMAKE_BUILD_TYPE MATCHES "Debug" AND NOT CMAKE_Fortran_COMPILER_ID MATCHES PGI|NVHPC ) +if( CMAKE_BUILD_TYPE MATCHES "Debug" ) foreach( debug_flag fpe initsnan checkbounds ) if( ${debug_flag}_flags ) - ecbuild_add_fortran_flags( "${${debug_flag}_flags}" NAME ${debug_flag} ) + set( ${PNAME}_Fortran_FLAGS_DEBUG "${${PNAME}_Fortran_FLAGS_DEBUG} ${${debug_flag}_flags}" ) endif() endforeach() if(CMAKE_Fortran_COMPILER_ID MATCHES "Intel") # In case '-check all' has been added, we need to remove the '-check arg_temp_created' warnings - ecbuild_add_fortran_flags( "-check noarg_temp_created" NAME check_noarg_temp_created BUILD DEBUG ) # the BUILD DEBUG argument makes sure it is appended after '-check all' + set( ${PNAME}_Fortran_FLAGS_DEBUG "${${PNAME}_Fortran_FLAGS_DEBUG} -check noarg_temp_created" ) endif() endif() @@ -56,6 +79,9 @@ if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU") if( NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 10 ) ecbuild_add_fortran_flags( "-fallow-argument-mismatch" NAME argument_mismatch ) endif() + if( NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "aarch64" ) + ecbuild_add_fortran_flags( "-m64" NAME gnu_arch ) + endif() endif() if(CMAKE_Fortran_COMPILER_ID MATCHES "Flang") diff --git a/cmake/ecwam_init_flags.cmake b/cmake/ecwam_init_flags.cmake new file mode 100644 index 000000000..12d93af36 --- /dev/null +++ b/cmake/ecwam_init_flags.cmake @@ -0,0 +1,9 @@ +# (C) Copyright 2022- ECMWF. +# +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# In applying this licence, ECMWF does not waive the privileges and immunities +# granted to it by virtue of its status as an intergovernmental organisation +# nor does it submit to any jurisdiction. + +# Empty file to trigger ecbuild to use ${PNAME}__FLAGS \ No newline at end of file diff --git a/src/ecwam/CMakeLists.txt b/src/ecwam/CMakeLists.txt index 9f2ce99e3..6c015e83a 100644 --- a/src/ecwam/CMakeLists.txt +++ b/src/ecwam/CMakeLists.txt @@ -404,14 +404,13 @@ if( HAVE_MULTIO ) list(APPEND ECWAM_DEFINITIONS WAM_HAVE_MULTIO) endif() +set( ${PNAME}_OCEANMODEL_LIBRARIES "" ) if( HAVE_OCEAN_COUPLING ) list(APPEND ECWAM_DEFINITIONS WITH_NEMO ) if( ${PNAME}_OCEANMODEL_HAVE_SINGLE_PRECISION ) list(APPEND ECWAM_DEFINITIONS PARKIND1_SINGLE_NEMO ) endif() -else() - unset( ${PNAME}_OCEANMODEL_LIBRARIES ) - unset( ${PNAME}_OCEANMODEL_INCLUDE_DIRS ) + set( ${PNAME}_OCEANMODEL_LIBRARIES nemogcmcoup.${OCEAN_PREC} ) endif() if( HAVE_ECFLOW ) @@ -430,7 +429,6 @@ ecbuild_add_library( field_api_${prec} $<${HAVE_ECFLOW}:ecflow_lightf> PUBLIC_INCLUDES $ - PRIVATE_INCLUDES ${${PNAME}_OCEANMODEL_INCLUDE_DIRS} PRIVATE_DEFINITIONS ${ECWAM_PRIVATE_DEFINITIONS} PUBLIC_DEFINITIONS ${ECWAM_DEFINITIONS} ) @@ -453,10 +451,14 @@ if( CMAKE_Fortran_COMPILER_ID MATCHES Intel ) set_source_files_properties( propconnect.F90 PROPERTIES COMPILE_OPTIONS "-fp-model;strict" ) elseif( CMAKE_Fortran_COMPILER_ID MATCHES GNU ) set_source_files_properties( mubuf.F90 PROPERTIES COMPILE_OPTIONS "-ffp-contract=off" ) -elseif(CMAKE_Fortran_COMPILER_ID MATCHES "PGI|NVHPC") +elseif(CMAKE_Fortran_COMPILER_ID MATCHES "PGI|NVHPC" AND CMAKE_BUILD_TYPE MATCHES "Bit") set_source_files_properties( - sbottom.F90 PROPERTIES COMPILE_FLAGS " -g -O1 -Mflushz -Mno-signed-zeros -Mstack_arrays " + sbottom.F90 PROPERTIES COMPILE_FLAGS " -g -O1 -Mflushz -Mno-signed-zeros " ) +elseif(CMAKE_Fortran_COMPILER_ID MATCHES "PGI|NVHPC" AND CMAKE_BUILD_TYPE MATCHES "Debug") + string(REPLACE "-Ktrap=fp" "" ${PNAME}_Fortran_FLAGS_DEBUG ${${PNAME}_Fortran_FLAGS_DEBUG}) + set_source_files_properties( outbeta.F90 PROPERTIES COMPILE_OPTIONS "${${PNAME}_Fortran_FLAGS_DEBUG} -Ktrap=divz") + set_source_files_properties( secondhh.F90 PROPERTIES COMPILE_OPTIONS "${${PNAME}_Fortran_FLAGS_DEBUG} -Ktrap=inv,ovf") endif() ### The file grib2wgrid.F90 is sensitive to optimizations in single precision builds. @@ -466,20 +468,3 @@ endif() if( CMAKE_Fortran_COMPILER_ID MATCHES Intel AND HAVE_SINGLE_PRECISION ) set_source_files_properties( grib2wgrid.F90 PROPERTIES COMPILE_OPTIONS "-fp-model;strict" ) endif() - -### NVHPC debug flags applied selectively to sourcefiles to avoid single-precision overflow -if( CMAKE_Fortran_COMPILER_ID MATCHES PGI|NVHPC AND CMAKE_BUILD_TYPE MATCHES "Debug" ) - foreach( debug_flag initsnan checkbounds ) - if( ${debug_flag}_flags ) - ecbuild_add_fortran_flags( "${${debug_flag}_flags}" NAME ${debug_flag} ) - endif() - endforeach() - - list(REMOVE_ITEM ecwam_srcs outbeta.F90 secondhh.F90) - if( fpe_flags ) - set_source_files_properties( ${ecwam_srcs} PROPERTIES COMPILE_OPTIONS ${fpe_flags} ) - set_source_files_properties( outbeta.F90 PROPERTIES COMPILE_OPTIONS "-Ktrap=divz" ) - set_source_files_properties( secondhh.F90 PROPERTIES COMPILE_OPTIONS "-Ktrap=inv,ovf" ) - endif() - list(APPEND ecwam_srcs outbeta.F90 secondhh.F90) -endif() diff --git a/src/ecwam/getcurr.F90 b/src/ecwam/getcurr.F90 index 9bedcd3b7..2e1b5d38f 100644 --- a/src/ecwam/getcurr.F90 +++ b/src/ecwam/getcurr.F90 @@ -158,8 +158,10 @@ SUBROUTINE GETCURR(LWCUR, IREAD, BLK2LOC, & JY = BLK2LOC%JFROMIJ(IJ,ICHNK) IF (FIELDG%LKFR(IX,JY) <= 0.0_JWRB ) THEN ! if lake cover = 0, we assume open ocean point, then get currents directly from NEMO - WVENVI%UCUR(IJ,ICHNK) = SIGN(MIN(ABS(NEMO2WAM%NEMOUCUR(IJ,ICHNK)),CURRENT_MAX),NEMO2WAM%NEMOUCUR(IJ,ICHNK)) - WVENVI%VCUR(IJ,ICHNK) = SIGN(MIN(ABS(NEMO2WAM%NEMOVCUR(IJ,ICHNK)),CURRENT_MAX),NEMO2WAM%NEMOVCUR(IJ,ICHNK)) + WVENVI%UCUR(IJ,ICHNK) = SIGN(MIN(ABS(NEMO2WAM%NEMOUCUR(IJ,ICHNK)),REAL(CURRENT_MAX,JWRO)), & + & NEMO2WAM%NEMOUCUR(IJ,ICHNK)) + WVENVI%VCUR(IJ,ICHNK) = SIGN(MIN(ABS(NEMO2WAM%NEMOVCUR(IJ,ICHNK)),REAL(CURRENT_MAX,JWRO)), & + & NEMO2WAM%NEMOVCUR(IJ,ICHNK)) ELSE ! no currents over lakes and land WVENVI%UCUR(IJ,ICHNK) = 0.0_JWRB diff --git a/src/ecwam/recvnemofields.F90 b/src/ecwam/recvnemofields.F90 index 7eaa4b0a2..9931650dc 100644 --- a/src/ecwam/recvnemofields.F90 +++ b/src/ecwam/recvnemofields.F90 @@ -198,8 +198,10 @@ SUBROUTINE RECVNEMOFIELDS(BLK2LOC, WVENVI, NEMO2WAM, & JY = BLK2LOC%JFROMIJ(IJ,ICHNK) ! if lake cover = 0, we assume open ocean point, then get currents directly from NEMO IF (FIELDG%LKFR(IX,JY) <= 0.0_JWRB ) THEN - WVENVI%UCUR(IJ,ICHNK) = SIGN(MIN(ABS(NEMO2WAM%NEMOUCUR(IJ,ICHNK)),CURRENT_MAX),NEMO2WAM%NEMOUCUR(IJ,ICHNK)) - WVENVI%VCUR(IJ,ICHNK) = SIGN(MIN(ABS(NEMO2WAM%NEMOVCUR(IJ,ICHNK)),CURRENT_MAX),NEMO2WAM%NEMOVCUR(IJ,ICHNK)) + WVENVI%UCUR(IJ,ICHNK) = SIGN(MIN(ABS(NEMO2WAM%NEMOUCUR(IJ,ICHNK)),REAL(CURRENT_MAX,JWRO)), & + & NEMO2WAM%NEMOUCUR(IJ,ICHNK)) + WVENVI%VCUR(IJ,ICHNK) = SIGN(MIN(ABS(NEMO2WAM%NEMOVCUR(IJ,ICHNK)),REAL(CURRENT_MAX,JWRO)), & + & NEMO2WAM%NEMOVCUR(IJ,ICHNK)) ELSE WVENVI%UCUR(IJ,ICHNK)=0.0_JWRB WVENVI%VCUR(IJ,ICHNK)=0.0_JWRB diff --git a/src/ecwam/userin.F90 b/src/ecwam/userin.F90 index 3a87679bb..a7cc81956 100644 --- a/src/ecwam/userin.F90 +++ b/src/ecwam/userin.F90 @@ -1016,7 +1016,6 @@ SUBROUTINE USERIN (IFORCA, LWCUR) & TRIM(CSATNAME(ISAT)),' (',IBUFRSAT(ISAT),')' IF (LALTPAS(ISAT)) THEN WRITE(IU06,*) ' THE DATA WILL ONLY BE USED PASSIVELY !!! ' - WRITE(IU06,*) ' ' ENDIF IF (LALTLRGR(ISAT)) THEN WRITE(IU06,*) ' THE DATA WILL BE CORRECTED ' @@ -1038,8 +1037,7 @@ SUBROUTINE USERIN (IFORCA, LWCUR) & ' THE OBSERVATION ERROR.' ENDIF IF (LALTGRDOUT(ISAT)) THEN - WRITE(IU06,*) ' GRIDDED ALTIMETER FIELDS WILL BE' - WRITE(IU06,*) ' PRODUCED FOR THIS ALTIMETER.' + WRITE(IU06,*) ' GRIDDED ALTIMETER FIELDS WILL BE PRODUCED FOR THIS ALTIMETER.' LLNALTGO = .FALSE. ENDIF WRITE(IU06,*) ' ' diff --git a/src/ecwam/yowaltas.F90 b/src/ecwam/yowaltas.F90 index 556dc7787..1d4263ee2 100644 --- a/src/ecwam/yowaltas.F90 +++ b/src/ecwam/yowaltas.F90 @@ -13,7 +13,7 @@ MODULE YOWALTAS IMPLICIT NONE - INTEGER(KIND=JWIM), PARAMETER :: NUMALT=10 + INTEGER(KIND=JWIM), PARAMETER :: NUMALT=11 INTEGER(KIND=JWIM), PARAMETER :: NIJALT=4 INTEGER(KIND=JWIM), PARAMETER :: NALTDT=3 INTEGER(KIND=JWIM), PARAMETER :: NALTEDT=3 diff --git a/src/ecwam/yowgribhd.F90 b/src/ecwam/yowgribhd.F90 index b3694c7c2..ee213829a 100644 --- a/src/ecwam/yowgribhd.F90 +++ b/src/ecwam/yowgribhd.F90 @@ -15,8 +15,8 @@ MODULE YOWGRIBHD !* ** *GRIB HEADERS: COMMON (DEFAULT) GRIB HEADERS. - INTEGER(KIND=JWIM), PARAMETER :: IMDLGRBID_G=119 !! see below the rule on how to select IMDLGRBID_G - INTEGER(KIND=JWIM), PARAMETER :: IMDLGRBID_M=219 + INTEGER(KIND=JWIM), PARAMETER :: IMDLGRBID_G=106 !! see below the rule on how to select IMDLGRBID_G + INTEGER(KIND=JWIM), PARAMETER :: IMDLGRBID_M=206 INTEGER(KIND=JWIM) :: NDATE_TIME_WINDOW_END INTEGER(KIND=JWIM) :: NWINOFF INTEGER(KIND=JWIM) :: NGRIB_VERSION ! grib version for output