From 67cb77dceedea87e15ce9f62fb4a9d24e59d1436 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Fri, 10 Sep 2021 14:13:35 -0400 Subject: [PATCH 01/11] build the dycore with cmake --- .gitignore | 7 + CMakeLists.txt | 223 +++++++++++++++ README.md | 2 + cmake/FV3Config.cmake.in | 37 +++ cmake/FindESMF.cmake | 130 +++++++++ cmake/FindNetCDF.cmake | 347 +++++++++++++++++++++++ cmake/compiler_flags_GNU_Fortran.cmake | 16 ++ cmake/compiler_flags_Intel_Fortran.cmake | 17 ++ cmake/fv3_compiler_flags.cmake | 11 + 9 files changed, 790 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 cmake/FV3Config.cmake.in create mode 100644 cmake/FindESMF.cmake create mode 100644 cmake/FindNetCDF.cmake create mode 100644 cmake/compiler_flags_GNU_Fortran.cmake create mode 100644 cmake/compiler_flags_Intel_Fortran.cmake create mode 100644 cmake/fv3_compiler_flags.cmake diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..38093a286 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.aox +*.mod +*.sw[a-p] +*~ + +build*/ +install*/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..fc86c90c5 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,223 @@ +cmake_minimum_required(VERSION 3.18) + +project(FV3 + VERSION 1.0.0 + DESCRIPTION "GFDL Atmosphere Cubed Sphere Dynamical Core" + HOMEPAGE_URL "https://www.gfdl.noaa.gov/gfdl_atmos_cubed_sphere" + LANGUAGES Fortran) + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +include(GNUInstallDirs) + +if(NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release|Repro|MinSizeRel|RelWithDebInfo)$") + message(STATUS "No build type specified.") + set(CMAKE_BUILD_TYPE "Release" + CACHE STRING "Choose the type of build." FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Release" "Repro" "MinSizeRel" "RelWithDebInfo") +endif() +message(STATUS "Setting build type to '${CMAKE_BUILD_TYPE}'.") + +if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "^(Intel|GNU)$") + message(WARNING "Compiler not officially supported: ${CMAKE_Fortran_COMPILER_ID}") +endif() + +option(OPENMP "Enable OpenMP threading" OFF) +option(32BIT "Enable single precision (r4) arithmetic in FV3 dycore" ON) +option(DEBUG "Enable compiler definition -DDEBUG" OFF) +option(MULTI_GASES "Enable compiler definition -DMULTI_GASES" OFF) +option(USE_GFSL63 "Enable compiler definition -DUSE_GFSL63" OFF) +option(GFS_PHYS "Enable compiler definition -DGFS_PHYS" OFF) +option(GFS_TYPES "Enable compiler definition -DGFS_TYPES" OFF) +option(use_WRTCOMP "Enable compiler definition -Duse_WRTCOMP" OFF) + +find_package(MPI REQUIRED) +if(OPENMP) + find_package(OpenMP REQUIRED) +endif() +find_package(NetCDF REQUIRED C Fortran) +if(use_WRTCOMP) + if(NOT ESMF_FOUND) + find_package(ESMF REQUIRED) + endif() +endif() + +if(NOT FMS_FOUND) + if(32BIT) + set(FMS_COMPONENTS "R4") + set(fms_kind "r4") + else() + set(FMS_COMPONENTS "R8") + set(fms_kind "r8") + endif() + find_package(FMS REQUIRED COMPONENTS ${FMS_COMPONENTS}) + add_library(fms ALIAS FMS::fms_${fms_kind}) +endif() + +list(APPEND model_srcs + model/a2b_edge.F90 + model/multi_gases.F90 + model/boundary.F90 + model/dyn_core.F90 + model/fv_arrays.F90 + model/fv_control.F90 + model/fv_dynamics.F90 + model/fv_fill.F90 + model/fv_grid_utils.F90 + model/fv_mapz.F90 + model/fv_nesting.F90 + model/fv_regional_bc.F90 + model/fv_sg.F90 + model/fv_tracer2d.F90 + model/fv_update_phys.F90 + model/sw_core.F90 + model/tp_core.F90 + model/nh_core.F90 + model/nh_utils.F90) + +list(APPEND tools_srcs + tools/coarse_grained_diagnostics.F90 + tools/coarse_grained_restart_files.F90 + tools/coarse_graining.F90 + tools/external_ic.F90 + tools/external_sst.F90 + tools/fv_diag_column.F90 + tools/fv_diagnostics.F90 + tools/fv_eta.F90 + tools/fv_grid_tools.F90 + tools/fv_io.F90 + tools/fv_mp_mod.F90 + tools/fv_nudge.F90 + tools/fv_treat_da_inc.F90 + tools/fv_restart.F90 + tools/fv_surf_map.F90 + tools/fv_timing.F90 + tools/init_hydro.F90 + tools/sim_nc_mod.F90 + tools/sorted_index.F90 + tools/test_cases.F90) + +list(APPEND tools_srcs_extra + tools/fv_iau_mod.F90) + +list(APPEND driver_srcs + driver/fvGFS/DYCORE_typedefs.F90 + driver/fvGFS/fv_nggps_diag.F90 + driver/fvGFS/atmosphere.F90) + +list(APPEND fv3_srcs ${model_srcs} + ${tools_srcs}) + +list(APPEND fv3_defs SPMD + MOIST_CAPPA + USE_COND) + +# Additional (optional) compiler definitions +if(DEBUG) + list(APPEND fv3_defs DEBUG) +endif() + +if(USE_GFSL63) + list(APPEND fv3_defs USE_GFSL63) +endif() + +if(GFS_PHYS) + list(APPEND fv3_defs GFS_PHYS) +endif() + +if(GFS_TYPES) + list(APPEND fv3_defs GFS_TYPES) +endif() + +if(use_WRTCOMP) + list(APPEND fv3_defs use_WRTCOMP) + list(APPEND fv3_srcs ${tools_srcs_extra} + ${driver_srcs}) +endif() + +if(MULTI_GASES) + list(APPEND fv3_defs MULTI_GASES) +endif() + +if(32BIT) + list(APPEND fv3_defs OVERLOAD_R4 + OVERLOAD_R8) +endif() + +if(OPENMP) + list(APPEND fv3_defs OPENMP) +endif() + +# Obtain compiler-specific flags +include(fv3_compiler_flags) + +set(moduleDir "${CMAKE_CURRENT_BINARY_DIR}/${includeDir}") + +add_library(fv3 ${fv3_srcs}) +add_library(FV3::fv3 ALIAS fv3) + +set_property(SOURCE model/nh_utils.F90 APPEND_STRING PROPERTY COMPILE_FLAGS "${FAST}") +set_property(SOURCE model/fv_mapz.F90 APPEND_STRING PROPERTY COMPILE_FLAGS "${FAST}") + +set_target_properties(fv3 PROPERTIES COMPILE_FLAGS "${${kind}_flags}") + +set_target_properties(fv3 PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/fv3) +target_include_directories(fv3 INTERFACE $ + $) + +target_include_directories(fv3 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/tools) + +target_compile_definitions(fv3 PRIVATE "${fv3_defs}") + +target_link_libraries(fv3 PUBLIC fms) + +if(GFS_PHYS) + target_link_libraries(fv3 PUBLIC fv3ccpp) +endif() + +if(use_WRTCOMP) + target_link_libraries(fv3 PUBLIC esmf) +endif() + +if(OPENMP) + target_link_libraries(fv3 PUBLIC OpenMP::OpenMP_Fortran) +endif() + +# Install compiled Fortran module files +install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include DESTINATION ${CMAKE_INSTALL_PREFIX}) + +install( + TARGETS fv3 + EXPORT FV3Exports + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) + +### Package config +include(CMakePackageConfigHelpers) +set(CONFIG_INSTALL_DESTINATION lib/cmake/fv3) + +export(EXPORT FV3Exports + NAMESPACE FV3:: + FILE fv3-targets.cmake) + +configure_package_config_file( + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FV3Config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/fv3-config.cmake + INSTALL_DESTINATION ${CONFIG_INSTALL_DESTINATION}) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fv3-config.cmake + DESTINATION ${CONFIG_INSTALL_DESTINATION}) + +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/fv3-config-version.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fv3-config-version.cmake + DESTINATION ${CONFIG_INSTALL_DESTINATION}) + +install(EXPORT FV3Exports + NAMESPACE FV3:: + FILE fv3-targets.cmake + DESTINATION ${CONFIG_INSTALL_DESTINATION}) + diff --git a/README.md b/README.md index 400f2012a..7c9bf6f61 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ The top level directory structure groups source code and input files as follow: | ```driver/``` | contains drivers used by different models/modeling systems | | ```tools/``` | contains source code of tools used within the core | | ```docs/``` | contains documentation for the FV3 dynamical core, and Python notebooks demonstrating basic capabilities. | +| ```CMakeLists.txt``` | is the main project CMakeLists.txt file | +| ```cmake/``` | contains code to build FV3 dynamical core with CMake | # Disclaimer diff --git a/cmake/FV3Config.cmake.in b/cmake/FV3Config.cmake.in new file mode 100644 index 000000000..7fa15add5 --- /dev/null +++ b/cmake/FV3Config.cmake.in @@ -0,0 +1,37 @@ +@PACKAGE_INIT@ + +#fv3-config.cmake +# +# Output variables set: +# * @PROJECT_NAME@_FOUND +# +# Imported interface targets provided: +# * @PROJECT_NAME@::fv3 - FV3 dynamical core library target + +# Include targets file. This will create IMPORTED target fv3 +include("${CMAKE_CURRENT_LIST_DIR}/fv3-targets.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/fv3-config-version.cmake") +include(CMakeFindDependencyMacro) + +find_dependency(MPI COMPONENTS Fortran) + +# ON/OFF implies FV3 was compiled with/without OpenMP +if(@OPENMP@) + find_dependency(OpenMP COMPONENTS Fortran) +endif() + +find_dependency(MPI COMPONENTS Fortran) +find_dependency(NetCDF COMPONENTS C Fortran) +if(@use_WRTCOMP@) + find_dependency(ESMF) +endif() + +set(FV3Version "${PACKAGE_VERSION}") +set_and_check(FV3_INSTALL_PREFIX "${PACKAGE_PREFIX_DIR}") +get_property(FV3_LIBRARIES TARGET @PROJECT_NAME@::fv3 PROPERTY LOCATION) + +check_required_components("@PROJECT_NAME@") + +get_target_property(location @PROJECT_NAME@::fv3 LOCATION) +message(STATUS "Found @PROJECT_NAME@: \"${FV3_INSTALL_PREFIX}\" (Version: \"${FV3Version}\")") +message(STATUS "Found @PROJECT_NAME@::fv3 [Lib: ${FV3_LIBRARIES}]") diff --git a/cmake/FindESMF.cmake b/cmake/FindESMF.cmake new file mode 100644 index 000000000..5d0790fa2 --- /dev/null +++ b/cmake/FindESMF.cmake @@ -0,0 +1,130 @@ +# - Try to find ESMF +# +# Requires setting ESMFMKFILE to the filepath of esmf.mk. If this is NOT set, +# then ESMF_FOUND will always be FALSE. If ESMFMKFILE exists, then ESMF_FOUND=TRUE +# and all ESMF makefile variables will be set in the global scope. Optionally, +# set ESMF_MKGLOBALS to a string list to filter makefile variables. For example, +# to globally scope only ESMF_LIBSDIR and ESMF_APPSDIR variables, use this CMake +# command in CMakeLists.txt: +# +# set(ESMF_MKGLOBALS "LIBSDIR" "APPSDIR") + + +# Add the ESMFMKFILE path to the cache if defined as system env variable +if (DEFINED ENV{ESMFMKFILE} AND NOT DEFINED ESMFMKFILE) + set(ESMFMKFILE $ENV{ESMFMKFILE} CACHE FILEPATH "Path to ESMF mk file") +endif () + +# Found the mk file and ESMF exists on the system +if (EXISTS ${ESMFMKFILE}) + set(ESMF_FOUND TRUE CACHE BOOL "ESMF mk file found" FORCE) + # Did not find the ESMF mk file +else() + set(ESMF_FOUND FALSE CACHE BOOL "ESMF mk file NOT found" FORCE) + # Best to warn users that without the mk file there is no way to find ESMF + if (NOT DEFINED ESMFMKFILE) + message(FATAL_ERROR "ESMFMKFILE not defined. This is the path to esmf.mk file. \ +Without this filepath, ESMF_FOUND will always be FALSE.") + endif () +endif() + +# Only parse the mk file if it is found +if (ESMF_FOUND) + # Read the mk file + file(STRINGS "${ESMFMKFILE}" esmfmkfile_contents) + # Parse each line in the mk file + foreach(str ${esmfmkfile_contents}) + # Only consider uncommented lines + string(REGEX MATCH "^[^#]" def ${str}) + # Line is not commented + if (def) + # Extract the variable name + string(REGEX MATCH "^[^=]+" esmf_varname ${str}) + # Extract the variable's value + string(REGEX MATCH "=.+$" esmf_vardef ${str}) + # Only for variables with a defined value + if (esmf_vardef) + # Get rid of the assignment string + string(SUBSTRING ${esmf_vardef} 1 -1 esmf_vardef) + # Remove whitespace + string(STRIP ${esmf_vardef} esmf_vardef) + # A string or single-valued list + if(NOT DEFINED ESMF_MKGLOBALS) + # Set in global scope + set(${esmf_varname} ${esmf_vardef}) + # Don't display by default in GUI + mark_as_advanced(esmf_varname) + else() # Need to filter global promotion + foreach(m ${ESMF_MKGLOBALS}) + string(FIND ${esmf_varname} ${m} match) + # Found the string + if(NOT ${match} EQUAL -1) + # Promote to global scope + set(${esmf_varname} ${esmf_vardef}) + # Don't display by default in the GUI + mark_as_advanced (esmf_varname) + # No need to search for the current string filter + break() + endif() + endforeach() + endif() + endif() + endif() + endforeach() + + # Construct ESMF_VERSION from ESMF_VERSION_STRING_GIT + if(ESMF_FOUND) + # ESMF_VERSION_MAJOR and ESMF_VERSION_MINOR are defined in ESMFMKFILE + set(ESMF_VERSION 0) + set(ESMF_VERSION_PATCH ${ESMF_VERSION_REVISION}) + set(ESMF_BETA_RELEASE FALSE) + if(ESMF_VERSION_BETASNAPSHOT MATCHES "^('T')$") + set(ESMF_BETA_RELEASE TRUE) + string(REGEX REPLACE ".*beta_snapshot_*\([0-9]*\).*" "\\1" ESMF_BETA_SNAPSHOT "${ESMF_VERSION_STRING_GIT}") + endif() + set(ESMF_VERSION "${ESMF_VERSION_MAJOR}.${ESMF_VERSION_MINOR}.${ESMF_VERSION_PATCH}") + endif() + + separate_arguments(ESMF_F90COMPILEPATHS NATIVE_COMMAND ${ESMF_F90COMPILEPATHS}) + foreach (ITEM ${ESMF_F90COMPILEPATHS}) + string(REGEX REPLACE "^-I" "" ITEM "${ITEM}") + list(APPEND tmp ${ITEM}) + endforeach() + set(ESMF_F90COMPILEPATHS ${tmp}) + + add_library(esmf UNKNOWN IMPORTED) + # Look for static library, if not found try dynamic library + find_library(esmf_lib NAMES libesmf.a PATHS ${ESMF_LIBSDIR}) + if(esmf_lib MATCHES "esmf_lib-NOTFOUND") + message(STATUS "Static ESMF library not found, searching for dynamic library instead") + find_library(esmf_lib NAMES esmf_fullylinked PATHS ${ESMF_LIBSDIR}) + if(esmf_lib MATCHES "esmf_lib-NOTFOUND") + message(FATAL_ERROR "Neither the dynamic nor the static ESMF library was found") + endif() + set(ESMF_INTERFACE_LINK_LIBRARIES "") + else() + # When linking the static library, also need the ESMF linker flags; strip any leading/trailing whitespaces + string(STRIP "${ESMF_F90ESMFLINKRPATHS} ${ESMF_F90ESMFLINKPATHS} ${ESMF_F90LINKPATHS} ${ESMF_F90LINKLIBS} ${ESMF_F90LINKOPTS}" ESMF_INTERFACE_LINK_LIBRARIES) + endif() + + message(STATUS "Found ESMF library: ${esmf_lib}") + if(ESMF_BETA_RELEASE) + message(STATUS "Detected ESMF Beta snapshot ${ESMF_BETA_SNAPSHOT}") + endif() + + set_target_properties(esmf PROPERTIES + IMPORTED_LOCATION ${esmf_lib} + INTERFACE_INCLUDE_DIRECTORIES "${ESMF_F90COMPILEPATHS}" + INTERFACE_LINK_LIBRARIES "${ESMF_INTERFACE_LINK_LIBRARIES}") + +endif() + +## Finalize find_package +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args( ${CMAKE_FIND_PACKAGE_NAME} + REQUIRED_VARS ESMF_LIBSDIR + ESMF_INTERFACE_LINK_LIBRARIES + ESMF_F90COMPILEPATHS + VERSION_VAR ESMF_VERSION + HANDLE_COMPONENTS ) diff --git a/cmake/FindNetCDF.cmake b/cmake/FindNetCDF.cmake new file mode 100644 index 000000000..23f6a1e09 --- /dev/null +++ b/cmake/FindNetCDF.cmake @@ -0,0 +1,347 @@ +# (C) Copyright 2011- 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. + +# Try to find NetCDF includes and library. +# Supports static and shared libaries and allows each component to be found in sepearte prefixes. +# +# This module defines +# +# - NetCDF_FOUND - System has NetCDF +# - NetCDF_INCLUDE_DIRS - the NetCDF include directories +# - NetCDF_VERSION - the version of NetCDF +# - NetCDF_CONFIG_EXECUTABLE - the netcdf-config executable if found +# - NetCDF_PARALLEL - Boolean True if NetCDF4 has parallel IO support via hdf5 and/or pnetcdf +# - NetCDF_HAS_PNETCDF - Boolean True if NetCDF4 has pnetcdf support +# +# Deprecated Defines +# - NetCDF_LIBRARIES - [Deprecated] Use NetCDF::NetCDF_ targets instead. +# +# +# Following components are available: +# +# - C - C interface to NetCDF (netcdf) +# - CXX - CXX4 interface to NetCDF (netcdf_c++4) +# - Fortran - Fortran interface to NetCDF (netcdff) +# +# For each component the following are defined: +# +# - NetCDF__FOUND - whether the component is found +# - NetCDF__LIBRARIES - the libraries for the component +# - NetCDF__LIBRARY_SHARED - Boolean is true if libraries for component are shared +# - NetCDF__INCLUDE_DIRS - the include directories for specified component +# - NetCDF::NetCDF_ - target of component to be used with target_link_libraries() +# +# The following paths will be searched in order if set in CMake (first priority) or environment (second priority) +# +# - NetCDF_ROOT - root of NetCDF installation +# - NetCDF_PATH - root of NetCDF installation +# +# The search process begins with locating NetCDF Include headers. If these are in a non-standard location, +# set one of the following CMake or environment variables to point to the location: +# +# - NetCDF_INCLUDE_DIR or NetCDF_${comp}_INCLUDE_DIR +# - NetCDF_INCLUDE_DIRS or NetCDF_${comp}_INCLUDE_DIR +# +# Notes: +# +# - Use "NetCDF::NetCDF_" targets only. NetCDF_LIBRARIES exists for backwards compatibility and should not be used. +# - These targets have all the knowledge of include directories and library search directories, and a single +# call to target_link_libraries will provide all these transitive properties to your target. Normally all that is +# needed to build and link against NetCDF is, e.g.: +# target_link_libraries(my_c_tgt PUBLIC NetCDF::NetCDF_C) +# - "NetCDF" is always the preferred naming for this package, its targets, variables, and environment variables +# - For compatibility, some variables are also set/checked using alternate names NetCDF4, NETCDF, or NETCDF4 +# - Environments relying on these older environment variable names should move to using a "NetCDF_ROOT" environment variable +# - Preferred component capitalization follows the CMake LANGUAGES variables: i.e., C, Fortran, CXX +# - For compatibility, alternate capitalizations are supported but should not be used. +# - If no components are defined, all components will be searched +# + +list( APPEND _possible_components C CXX Fortran ) + +## Include names for each component +set( NetCDF_C_INCLUDE_NAME netcdf.h ) +set( NetCDF_CXX_INCLUDE_NAME netcdf ) +set( NetCDF_Fortran_INCLUDE_NAME netcdf.mod ) + +## Library names for each component +set( NetCDF_C_LIBRARY_NAME netcdf ) +set( NetCDF_CXX_LIBRARY_NAME netcdf_c++4 ) +set( NetCDF_Fortran_LIBRARY_NAME netcdff ) + +## Enumerate search components +foreach( _comp ${_possible_components} ) + string( TOUPPER "${_comp}" _COMP ) + set( _arg_${_COMP} ${_comp} ) + set( _name_${_COMP} ${_comp} ) +endforeach() + +set( _search_components C) +foreach( _comp ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS} ) + string( TOUPPER "${_comp}" _COMP ) + set( _arg_${_COMP} ${_comp} ) + list( APPEND _search_components ${_name_${_COMP}} ) + if( NOT _name_${_COMP} ) + message(SEND_ERROR "Find${CMAKE_FIND_PACKAGE_NAME}: COMPONENT ${_comp} is not a valid component. Valid components: ${_possible_components}" ) + endif() +endforeach() +list( REMOVE_DUPLICATES _search_components ) + +## Search hints for finding include directories and libraries +foreach( _comp IN ITEMS "_" "_C_" "_Fortran_" "_CXX_" ) + foreach( _name IN ITEMS NetCDF4 NetCDF NETCDF4 NETCDF ) + foreach( _var IN ITEMS ROOT PATH ) + list(APPEND _search_hints ${${_name}${_comp}${_var}} $ENV{${_name}${_comp}${_var}} ) + list(APPEND _include_search_hints + ${${_name}${_comp}INCLUDE_DIR} $ENV{${_name}${_comp}INCLUDE_DIR} + ${${_name}${_comp}INCLUDE_DIRS} $ENV{${_name}${_comp}INCLUDE_DIRS} ) + endforeach() + endforeach() +endforeach() +#Old-school HPC module env variable names +foreach( _name IN ITEMS NetCDF4 NetCDF NETCDF4 NETCDF ) + foreach( _comp IN ITEMS "_C" "_Fortran" "_CXX" ) + list(APPEND _search_hints ${${_name}} $ENV{${_name}}) + list(APPEND _search_hints ${${_name}${_comp}} $ENV{${_name}${_comp}}) + endforeach() +endforeach() + +## Find headers for each component +set(NetCDF_INCLUDE_DIRS) +set(_new_search_components) +foreach( _comp IN LISTS _search_components ) + if(NOT ${PROJECT_NAME}_NetCDF_${_comp}_FOUND) + list(APPEND _new_search_components ${_comp}) + endif() + find_file(NetCDF_${_comp}_INCLUDE_FILE + NAMES ${NetCDF_${_comp}_INCLUDE_NAME} + DOC "NetCDF ${_comp} include directory" + HINTS ${_include_search_hints} ${_search_hints} + PATH_SUFFIXES include include/netcdf + ) + mark_as_advanced(NetCDF_${_comp}_INCLUDE_FILE) + message(DEBUG "NetCDF_${_comp}_INCLUDE_FILE: ${NetCDF_${_comp}_INCLUDE_FILE}") + if( NetCDF_${_comp}_INCLUDE_FILE ) + get_filename_component(NetCDF_${_comp}_INCLUDE_FILE ${NetCDF_${_comp}_INCLUDE_FILE} ABSOLUTE) + get_filename_component(NetCDF_${_comp}_INCLUDE_DIR ${NetCDF_${_comp}_INCLUDE_FILE} DIRECTORY) + list(APPEND NetCDF_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIR}) + endif() +endforeach() +if(NetCDF_INCLUDE_DIRS) + list(REMOVE_DUPLICATES NetCDF_INCLUDE_DIRS) +endif() +set(NetCDF_INCLUDE_DIRS "${NetCDF_INCLUDE_DIRS}" CACHE STRING "NetCDF Include directory paths" FORCE) + +## Find n*-config executables for search components +foreach( _comp IN LISTS _search_components ) + if( _comp MATCHES "^(C)$" ) + set(_conf "c") + elseif( _comp MATCHES "^(Fortran)$" ) + set(_conf "f") + elseif( _comp MATCHES "^(CXX)$" ) + set(_conf "cxx4") + endif() + find_program( NetCDF_${_comp}_CONFIG_EXECUTABLE + NAMES n${_conf}-config + HINTS ${NetCDF_INCLUDE_DIRS} ${_include_search_hints} ${_search_hints} + PATH_SUFFIXES bin Bin ../bin ../../bin + DOC "NetCDF n${_conf}-config helper" ) + message(DEBUG "NetCDF_${_comp}_CONFIG_EXECUTABLE: ${NetCDF_${_comp}_CONFIG_EXECUTABLE}") +endforeach() + +set(_C_libs_flag --libs) +set(_Fortran_libs_flag --flibs) +set(_CXX_libs_flag --libs) +set(_C_includes_flag --includedir) +set(_Fortran_includes_flag --includedir) +set(_CXX_includes_flag --includedir) +function(netcdf_config exec flag output_var) + set(${output_var} False PARENT_SCOPE) + if( exec ) + execute_process( COMMAND ${exec} ${flag} RESULT_VARIABLE _ret OUTPUT_VARIABLE _val) + if( _ret EQUAL 0 ) + string( STRIP ${_val} _val ) + set( ${output_var} ${_val} PARENT_SCOPE ) + endif() + endif() +endfunction() + +## Detect additional package properties +netcdf_config(${NetCDF_C_CONFIG_EXECUTABLE} --has-parallel4 _val) +if( NOT _val MATCHES "^(yes|no)$" ) + netcdf_config(${NetCDF_C_CONFIG_EXECUTABLE} --has-parallel _val) +endif() +if( _val MATCHES "^(yes)$" ) + set(NetCDF_PARALLEL TRUE CACHE STRING "NetCDF has parallel IO capability via pnetcdf or hdf5." FORCE) +else() + set(NetCDF_PARALLEL FALSE CACHE STRING "NetCDF has no parallel IO capability." FORCE) +endif() + +if(NetCDF_PARALLEL) + find_package(MPI) +endif() + +## Find libraries for each component +set( NetCDF_LIBRARIES ) +foreach( _comp IN LISTS _search_components ) + string( TOUPPER "${_comp}" _COMP ) + + find_library( NetCDF_${_comp}_LIBRARY + NAMES ${NetCDF_${_comp}_LIBRARY_NAME} + DOC "NetCDF ${_comp} library" + HINTS ${NetCDF_${_comp}_INCLUDE_DIRS} ${_search_hints} + PATH_SUFFIXES lib64 lib ../lib64 ../lib ../../lib64 ../../lib ) + mark_as_advanced( NetCDF_${_comp}_LIBRARY ) + get_filename_component(NetCDF_${_comp}_LIBRARY ${NetCDF_${_comp}_LIBRARY} ABSOLUTE) + set(NetCDF_${_comp}_LIBRARY ${NetCDF_${_comp}_LIBRARY} CACHE STRING "NetCDF ${_comp} library" FORCE) + message(DEBUG "NetCDF_${_comp}_LIBRARY: ${NetCDF_${_comp}_LIBRARY}") + + if( NetCDF_${_comp}_LIBRARY ) + if( NetCDF_${_comp}_LIBRARY MATCHES ".a$" ) + set( NetCDF_${_comp}_LIBRARY_SHARED FALSE ) + set( _library_type STATIC) + else() + list( APPEND NetCDF_LIBRARIES ${NetCDF_${_comp}_LIBRARY} ) + set( NetCDF_${_comp}_LIBRARY_SHARED TRUE ) + set( _library_type SHARED) + endif() + endif() + + #Use nc-config to set per-component LIBRARIES variable if possible + netcdf_config( ${NetCDF_${_comp}_CONFIG_EXECUTABLE} ${_${_comp}_libs_flag} _val ) + if( _val ) + set( NetCDF_${_comp}_LIBRARIES ${_val} ) + if(NOT NetCDF_${_comp}_LIBRARY_SHARED AND NOT NetCDF_${_comp}_FOUND) #Static targets should use nc_config to get a proper link line with all necessary static targets. + list( APPEND NetCDF_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + endif() + else() + set( NetCDF_${_comp}_LIBRARIES ${NetCDF_${_comp}_LIBRARY} ) + if(NOT NetCDF_${_comp}_LIBRARY_SHARED) + message(SEND_ERROR "Unable to properly find NetCDF. Found static libraries at: ${NetCDF_${_comp}_LIBRARY} but could not run nc-config: ${NetCDF_CONFIG_EXECUTABLE}") + endif() + endif() + + #Use nc-config to set per-component INCLUDE_DIRS variable if possible + netcdf_config( ${NetCDF_${_comp}_CONFIG_EXECUTABLE} ${_${_comp}_includes_flag} _val ) + if( _val ) + string( REPLACE " " ";" _val ${_val} ) + set( NetCDF_${_comp}_INCLUDE_DIRS ${_val} ) + else() + set( NetCDF_${_comp}_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIR} ) + endif() + + if( NetCDF_${_comp}_LIBRARIES AND NetCDF_${_comp}_INCLUDE_DIRS ) + set( ${CMAKE_FIND_PACKAGE_NAME}_${_arg_${_COMP}}_FOUND TRUE ) + if (NOT TARGET NetCDF::NetCDF_${_comp}) + add_library(NetCDF::NetCDF_${_comp} ${_library_type} IMPORTED) + set_target_properties(NetCDF::NetCDF_${_comp} PROPERTIES + IMPORTED_LOCATION ${NetCDF_${_comp}_LIBRARY} + INTERFACE_INCLUDE_DIRECTORIES "${NetCDF_${_comp}_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + if( NOT _comp MATCHES "^(C)$" ) + target_link_libraries(NetCDF::NetCDF_${_comp} INTERFACE NetCDF::NetCDF_C) + endif() + if(MPI_${_comp}_FOUND) + target_link_libraries(NetCDF::NetCDF_${_comp} INTERFACE MPI::MPI_${_comp}) + endif() + endif() + endif() +endforeach() +if(NetCDF_LIBRARIES AND NetCDF_${_comp}_LIBRARY_SHARED) + list(REMOVE_DUPLICATES NetCDF_LIBRARIES) +endif() +set(NetCDF_LIBRARIES "${NetCDF_LIBRARIES}" CACHE STRING "NetCDF library targets" FORCE) + +## Find version via netcdf-config if possible +if (NetCDF_INCLUDE_DIRS) + if( NetCDF_C_CONFIG_EXECUTABLE ) + netcdf_config( ${NetCDF_C_CONFIG_EXECUTABLE} --version _vers ) + if( _vers ) + string(REGEX REPLACE ".* ((([0-9]+)\\.)+([0-9]+)).*" "\\1" NetCDF_VERSION "${_vers}" ) + endif() + else() + foreach( _dir IN LISTS NetCDF_INCLUDE_DIRS) + if( EXISTS "${_dir}/netcdf_meta.h" ) + file(STRINGS "${_dir}/netcdf_meta.h" _netcdf_version_lines + REGEX "#define[ \t]+NC_VERSION_(MAJOR|MINOR|PATCH|NOTE)") + string(REGEX REPLACE ".*NC_VERSION_MAJOR *\([0-9]*\).*" "\\1" _netcdf_version_major "${_netcdf_version_lines}") + string(REGEX REPLACE ".*NC_VERSION_MINOR *\([0-9]*\).*" "\\1" _netcdf_version_minor "${_netcdf_version_lines}") + string(REGEX REPLACE ".*NC_VERSION_PATCH *\([0-9]*\).*" "\\1" _netcdf_version_patch "${_netcdf_version_lines}") + string(REGEX REPLACE ".*NC_VERSION_NOTE *\"\([^\"]*\)\".*" "\\1" _netcdf_version_note "${_netcdf_version_lines}") + set(NetCDF_VERSION "${_netcdf_version_major}.${_netcdf_version_minor}.${_netcdf_version_patch}${_netcdf_version_note}") + unset(_netcdf_version_major) + unset(_netcdf_version_minor) + unset(_netcdf_version_patch) + unset(_netcdf_version_note) + unset(_netcdf_version_lines) + endif() + endforeach() + endif() +endif () + +## Finalize find_package +include(FindPackageHandleStandardArgs) + +if(NOT NetCDF_FOUND OR _new_search_components) + find_package_handle_standard_args( ${CMAKE_FIND_PACKAGE_NAME} + REQUIRED_VARS NetCDF_INCLUDE_DIRS NetCDF_LIBRARIES + VERSION_VAR NetCDF_VERSION + HANDLE_COMPONENTS ) +endif() + +foreach( _comp IN LISTS _search_components ) + if( NetCDF_${_comp}_FOUND ) + #Record found components to avoid duplication in NetCDF_LIBRARIES for static libraries + set(NetCDF_${_comp}_FOUND ${NetCDF_${_comp}_FOUND} CACHE BOOL "NetCDF ${_comp} Found" FORCE) + #Set a per-package, per-component found variable to communicate between multiple calls to find_package() + set(${PROJECT_NAME}_NetCDF_${_comp}_FOUND True) + endif() +endforeach() + +if( ${CMAKE_FIND_PACKAGE_NAME}_FOUND AND NOT ${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY AND _new_search_components) + message( STATUS "Find${CMAKE_FIND_PACKAGE_NAME} defines targets:" ) + message( STATUS " - NetCDF_VERSION [${NetCDF_VERSION}]") + message( STATUS " - NetCDF_PARALLEL [${NetCDF_PARALLEL}]") + foreach( _comp IN LISTS _new_search_components ) + string( TOUPPER "${_comp}" _COMP ) + message( STATUS " - NetCDF_${_comp}_CONFIG_EXECUTABLE [${NetCDF_${_comp}_CONFIG_EXECUTABLE}]") + if( ${CMAKE_FIND_PACKAGE_NAME}_${_arg_${_COMP}}_FOUND ) + get_filename_component(_root ${NetCDF_${_comp}_INCLUDE_DIR}/.. ABSOLUTE) + if( NetCDF_${_comp}_LIBRARY_SHARED ) + message( STATUS " - NetCDF::NetCDF_${_comp} [SHARED] [Root: ${_root}] Lib: ${NetCDF_${_comp}_LIBRARY} ") + else() + message( STATUS " - NetCDF::NetCDF_${_comp} [STATIC] [Root: ${_root}] Lib: ${NetCDF_${_comp}_LIBRARY} ") + endif() + endif() + endforeach() +endif() + +foreach( _prefix NetCDF NetCDF4 NETCDF NETCDF4 ${CMAKE_FIND_PACKAGE_NAME} ) + set( ${_prefix}_INCLUDE_DIRS ${NetCDF_INCLUDE_DIRS} ) + set( ${_prefix}_LIBRARIES ${NetCDF_LIBRARIES}) + set( ${_prefix}_VERSION ${NetCDF_VERSION} ) + set( ${_prefix}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_FOUND} ) + set( ${_prefix}_CONFIG_EXECUTABLE ${NetCDF_CONFIG_EXECUTABLE} ) + set( ${_prefix}_PARALLEL ${NetCDF_PARALLEL} ) + + foreach( _comp ${_search_components} ) + string( TOUPPER "${_comp}" _COMP ) + set( _arg_comp ${_arg_${_COMP}} ) + set( ${_prefix}_${_comp}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_${_arg_comp}_FOUND} ) + set( ${_prefix}_${_COMP}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_${_arg_comp}_FOUND} ) + set( ${_prefix}_${_arg_comp}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_${_arg_comp}_FOUND} ) + + set( ${_prefix}_${_comp}_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + set( ${_prefix}_${_COMP}_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + set( ${_prefix}_${_arg_comp}_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + + set( ${_prefix}_${_comp}_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIRS} ) + set( ${_prefix}_${_COMP}_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIRS} ) + set( ${_prefix}_${_arg_comp}_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIRS} ) + endforeach() +endforeach() diff --git a/cmake/compiler_flags_GNU_Fortran.cmake b/cmake/compiler_flags_GNU_Fortran.cmake new file mode 100644 index 000000000..9c6559f4f --- /dev/null +++ b/cmake/compiler_flags_GNU_Fortran.cmake @@ -0,0 +1,16 @@ +# Precision-based Fortran compiler flags +set(r8_flags "-fdefault-real-8 -fdefault-double-8") # Fortran flags for 64BIT precision + +# GNU Fortan +set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ggdb -fbacktrace -cpp -fcray-pointer -ffree-line-length-none -fno-range-check") +if(${CMAKE_Fortran_COMPILER_VERSION} VERSION_GREATER_EQUAL 10) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fallow-argument-mismatch -fallow-invalid-boz") +endif() + +set(CMAKE_Fortran_FLAGS_REPRO "-O2 -funroll-all-loops -finline-functions") + +set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -funroll-all-loops -finline-functions") + +set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans -ffpe-trap=invalid,zero,overflow -fbounds-check") + +set(CMAKE_Fortran_LINK_FLAGS "" ) diff --git a/cmake/compiler_flags_Intel_Fortran.cmake b/cmake/compiler_flags_Intel_Fortran.cmake new file mode 100644 index 000000000..5874cffcf --- /dev/null +++ b/cmake/compiler_flags_Intel_Fortran.cmake @@ -0,0 +1,17 @@ +# Precision-based Fortran compiler flags +set(r4_flags "-real-size 32") # Fortran flags for 32BIT precision +set(r8_flags "-real-size 64") # Fortran flags for 64BIT precision +set(r8_flags "${r8_flags} -no-prec-div -no-prec-sqrt") + +# Intel Fortran +set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -traceback -fpp -fno-alias -auto -safe-cray-ptr -ftz -assume byterecl -nowarn -sox -align array64byte -qno-opt-dynamic-align") + +set(CMAKE_Fortran_FLAGS_REPRO "-O2 -debug minimal -fp-model consistent -qoverride-limits") + +set(CMAKE_Fortran_FLAGS_RELEASE "-O2 -debug minimal -fp-model source -qoverride-limits -qopt-prefetch=3") + +set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -check -check noarg_temp_created -check nopointer -warn -warn noerrors -fp-stack-check -fstack-protector-all -fpe0 -debug -ftrapuv") + +set(CMAKE_Fortran_LINK_FLAGS "") + +set(FAST "-fast-transcendentals") diff --git a/cmake/fv3_compiler_flags.cmake b/cmake/fv3_compiler_flags.cmake new file mode 100644 index 000000000..889bd2301 --- /dev/null +++ b/cmake/fv3_compiler_flags.cmake @@ -0,0 +1,11 @@ +################################################################################ +# Fortran +################################################################################ + +if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU") + include(compiler_flags_GNU_Fortran) +elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel") + include(compiler_flags_Intel_Fortran) +else() + message(WARNING "Fortran compiler with ID ${CMAKE_Fortran_COMPILER_ID} will be used with CMake default options") +endif() From eb5bf02efd37830bc88cb8fa97b01ed3fd14edec Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Mon, 13 Sep 2021 09:00:46 -0400 Subject: [PATCH 02/11] add INTERNAL_FILE_NML and ENABLE_QUAD_PRECISION options --- CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc86c90c5..faa4d20f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,8 @@ option(USE_GFSL63 "Enable compiler definition -DUSE_GFSL63" OFF) option(GFS_PHYS "Enable compiler definition -DGFS_PHYS" OFF) option(GFS_TYPES "Enable compiler definition -DGFS_TYPES" OFF) option(use_WRTCOMP "Enable compiler definition -Duse_WRTCOMP" OFF) +option(INTERNAL_FILE_NML "Enable compiler definition -DINTERNAL_FILE_NML" ON) +option(ENABLE_QUAD_PRECISION "Enable compiler definition -DENABLE_QUAD_PRECISION" ON) find_package(MPI REQUIRED) if(OPENMP) @@ -145,6 +147,14 @@ if(32BIT) OVERLOAD_R8) endif() +if(INTERNAL_FILE_NML) + list(APPEND fv3_defs INTERNAL_FILE_NML) +endif() + +if(ENABLE_QUAD_PRECISION) + list(APPEND fv3_defs ENABLE_QUAD_PRECISION) +endif() + if(OPENMP) list(APPEND fv3_defs OPENMP) endif() From ec8a0f5711e2381e931d9d00594bca576d2c70ca Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Mon, 13 Sep 2021 09:15:33 -0400 Subject: [PATCH 03/11] remove FV3Exports --- CMakeLists.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index faa4d20f7..437c3d723 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -225,9 +225,3 @@ write_basic_package_version_file( COMPATIBILITY AnyNewerVersion) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fv3-config-version.cmake DESTINATION ${CONFIG_INSTALL_DESTINATION}) - -install(EXPORT FV3Exports - NAMESPACE FV3:: - FILE fv3-targets.cmake - DESTINATION ${CONFIG_INSTALL_DESTINATION}) - From 24f8fbf601be8fd9fe0350e39776708aa6d54e26 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Mon, 13 Sep 2021 10:27:39 -0400 Subject: [PATCH 04/11] accidentally removed the wrong line --- CMakeLists.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 437c3d723..ea4511678 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,10 +209,6 @@ install( include(CMakePackageConfigHelpers) set(CONFIG_INSTALL_DESTINATION lib/cmake/fv3) -export(EXPORT FV3Exports - NAMESPACE FV3:: - FILE fv3-targets.cmake) - configure_package_config_file( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FV3Config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/fv3-config.cmake INSTALL_DESTINATION ${CONFIG_INSTALL_DESTINATION}) @@ -225,3 +221,9 @@ write_basic_package_version_file( COMPATIBILITY AnyNewerVersion) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fv3-config-version.cmake DESTINATION ${CONFIG_INSTALL_DESTINATION}) + +install(EXPORT FV3Exports + NAMESPACE FV3:: + FILE fv3-targets.cmake + DESTINATION ${CONFIG_INSTALL_DESTINATION}) + From 34806e77e9d10964a5abd48c6c7e0a36e752ff6d Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Thu, 16 Sep 2021 14:05:56 -0400 Subject: [PATCH 05/11] update Intel flags to be consistent w/ UFS --- CMakeLists.txt | 4 +++- cmake/compiler_flags_Intel_Fortran.cmake | 12 ++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ea4511678..c56c225e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,7 +160,9 @@ if(OPENMP) endif() # Obtain compiler-specific flags -include(fv3_compiler_flags) +if(NOT UFS_FV3) + include(fv3_compiler_flags) +endif() set(moduleDir "${CMAKE_CURRENT_BINARY_DIR}/${includeDir}") diff --git a/cmake/compiler_flags_Intel_Fortran.cmake b/cmake/compiler_flags_Intel_Fortran.cmake index 5874cffcf..5f908852e 100644 --- a/cmake/compiler_flags_Intel_Fortran.cmake +++ b/cmake/compiler_flags_Intel_Fortran.cmake @@ -4,7 +4,7 @@ set(r8_flags "-real-size 64") # Fortran flags for 64BIT precision set(r8_flags "${r8_flags} -no-prec-div -no-prec-sqrt") # Intel Fortran -set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -traceback -fpp -fno-alias -auto -safe-cray-ptr -ftz -assume byterecl -nowarn -sox -align array64byte -qno-opt-dynamic-align") +set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -traceback -fpp -fno-alias -auto -safe-cray-ptr -ftz -assume byterecl -nowarn -sox -align array64byte -qno-opt-dynamic-align ${${fms_kind}_flags}") set(CMAKE_Fortran_FLAGS_REPRO "-O2 -debug minimal -fp-model consistent -qoverride-limits") @@ -14,4 +14,12 @@ set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -check -check noarg_temp_created -check nopoi set(CMAKE_Fortran_LINK_FLAGS "") -set(FAST "-fast-transcendentals") +if(NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Repro)$") + set(FAST "-fast-transcendentals") + if(AVX2) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -march=core-avx2") + elseif(SIMDMULTIARCH) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -axSSE4.2,CORE-AVX2") + endif() +endif() + From c819fe7f1f2db5fb6e77fb4560ffbba2bcf1a906 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Thu, 16 Sep 2021 15:09:16 -0400 Subject: [PATCH 06/11] remove obsolete makefile --- makefile | 115 ------------------------------------------------------- 1 file changed, 115 deletions(-) delete mode 100644 makefile diff --git a/makefile b/makefile deleted file mode 100644 index b27bf4367..000000000 --- a/makefile +++ /dev/null @@ -1,115 +0,0 @@ -SHELL = /bin/sh - -inside_nems := $(wildcard ../../../conf/configure.nems) -ifneq ($(strip $(inside_nems)),) - include ../../../conf/configure.nems -else - exist_configure_fv3 := $(wildcard ../conf/configure.fv3) - ifneq ($(strip $(exist_configure_fv3)),) - include ../conf/configure.fv3 - else - $(error "../conf/configure.fv3 file is missing. Run ./configure") - endif - $(info ) - $(info Build standalone FV3 fv3core ...) - $(info ) -endif - -LIBRARY = libfv3core.a - -FFLAGS += -I$(FMS_DIR) -I../gfsphysics -I../ipd -I../io -I. - -SRCS_f = - -SRCS_f90 = - -SRCS_F = - -SRCS_F90 = \ - ./model/a2b_edge.F90 \ - ./model/multi_gases.F90 \ - ./model/boundary.F90 \ - ./model/dyn_core.F90 \ - ./model/fv_arrays.F90 \ - ./model/fv_control.F90 \ - ./model/fv_dynamics.F90 \ - ./model/fv_fill.F90 \ - ./model/fv_grid_utils.F90 \ - ./model/fv_mapz.F90 \ - ./model/fv_nesting.F90 \ - ./model/fv_regional_bc.F90 \ - ./model/fv_sg.F90 \ - ./model/fv_tracer2d.F90 \ - ./model/fv_update_phys.F90 \ - ./model/sw_core.F90 \ - ./model/tp_core.F90 \ - ./model/nh_core.F90 \ - ./model/nh_utils.F90 \ - ./tools/external_ic.F90 \ - ./tools/external_sst.F90 \ - ./tools/fv_diagnostics.F90 \ - ./tools/fv_eta.F90 \ - ./tools/fv_grid_tools.F90 \ - ./tools/fv_io.F90 \ - ./tools/fv_mp_mod.F90 \ - ./tools/fv_nudge.F90 \ - ./tools/fv_treat_da_inc.F90 \ - ./tools/fv_iau_mod.F90 \ - ./tools/fv_restart.F90 \ - ./tools/fv_surf_map.F90 \ - ./tools/fv_timing.F90 \ - ./tools/init_hydro.F90 \ - ./tools/sim_nc_mod.F90 \ - ./tools/sorted_index.F90 \ - ./tools/test_cases.F90 \ - ./driver/fvGFS/DYCORE_typedefs.F90 \ - ./driver/fvGFS/fv_nggps_diag.F90 \ - ./driver/fvGFS/atmosphere.F90 - -SRCS_c = - -DEPEND_FILES = $(SRCS_f) $(SRCS_f90) $(SRCS_F) $(SRCS_F90) - -OBJS_f = $(SRCS_f:.f=.o) -OBJS_f90 = $(SRCS_f90:.f90=.o) -OBJS_F = $(SRCS_F:.F=.o) -OBJS_F90 = $(SRCS_F90:.F90=.o) -OBJS_c = $(SRCS_c:.c=.o) - -OBJS = $(OBJS_f) $(OBJS_f90) $(OBJS_F) $(OBJS_F90) $(OBJS_c) - -all default: depend $(LIBRARY) - -$(LIBRARY): $(OBJS) - $(AR) $(ARFLAGS) $@ $? - -# this is the place to override default (implicit) compilation rules -# and create specific (explicit) rules - -./model/nh_utils.o : ./model/nh_utils.F90 - $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) $(OTHER_FFLAGS) $(FAST) -c $< -o $@ - -./model/fv_mapz.o : ./model/fv_mapz.F90 - $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) $(OTHER_FFLAGS) $(FAST) -c $< -o $@ - -./driver/fvGFS/fv_nggps_diag.o : ./driver/fvGFS/fv_nggps_diag.F90 - $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) $(OTHER_FFLAGS) $(ESMF_INC) -c $< -o $@ - -# additional include files (ESMF_INC) needed for PGI -./driver/fvGFS/atmosphere.o : ./driver/fvGFS/atmosphere.F90 - $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) $(OTHER_FFLAGS) $(ESMF_INC) -c $< -o $@ - -.PHONY: clean -clean: - @echo "Cleaning fv3core ... " - @echo - $(RM) -f $(LIBRARY) *__genmod.f90 */*.o */*/*.o *.mod *.i90 *.lst *.i depend - -MKDEPENDS = ../mkDepends.pl -include ../conf/make.rules - -# do not include 'depend' file if the target contains string 'clean' -ifneq (clean,$(findstring clean,$(MAKECMDGOALS))) - -include depend -endif - From ba1ea863729796f651237db062d67f42156ec576 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Thu, 16 Sep 2021 15:25:21 -0400 Subject: [PATCH 07/11] update GNU flags --- cmake/compiler_flags_GNU_Fortran.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/compiler_flags_GNU_Fortran.cmake b/cmake/compiler_flags_GNU_Fortran.cmake index 9c6559f4f..68f1354db 100644 --- a/cmake/compiler_flags_GNU_Fortran.cmake +++ b/cmake/compiler_flags_GNU_Fortran.cmake @@ -2,14 +2,14 @@ set(r8_flags "-fdefault-real-8 -fdefault-double-8") # Fortran flags for 64BIT precision # GNU Fortan -set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ggdb -fbacktrace -cpp -fcray-pointer -ffree-line-length-none -fno-range-check") +set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ggdb -fbacktrace -cpp -fcray-pointer -ffree-line-length-none -fno-range-check ${${fms_kind}_flags}") if(${CMAKE_Fortran_COMPILER_VERSION} VERSION_GREATER_EQUAL 10) set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fallow-argument-mismatch -fallow-invalid-boz") endif() -set(CMAKE_Fortran_FLAGS_REPRO "-O2 -funroll-all-loops -finline-functions") +set(CMAKE_Fortran_FLAGS_REPRO "-O2") -set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -funroll-all-loops -finline-functions") +set(CMAKE_Fortran_FLAGS_RELEASE "-O2") set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans -ffpe-trap=invalid,zero,overflow -fbounds-check") From 5c0d250a46a919c1333bb897e404e93227a0f9a2 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Thu, 16 Sep 2021 17:00:43 -0400 Subject: [PATCH 08/11] move kind out of FMS found block --- CMakeLists.txt | 14 +++++++------- cmake/compiler_flags_GNU_Fortran.cmake | 2 +- cmake/compiler_flags_Intel_Fortran.cmake | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c56c225e6..e8aaca969 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,16 +45,20 @@ if(use_WRTCOMP) endif() endif() +if(32BIT) + set(kind "r4") +else() + set(kind "r8") +endif() + if(NOT FMS_FOUND) if(32BIT) set(FMS_COMPONENTS "R4") - set(fms_kind "r4") else() set(FMS_COMPONENTS "R8") - set(fms_kind "r8") endif() find_package(FMS REQUIRED COMPONENTS ${FMS_COMPONENTS}) - add_library(fms ALIAS FMS::fms_${fms_kind}) + add_library(fms ALIAS FMS::fms_${kind}) endif() list(APPEND model_srcs @@ -164,16 +168,12 @@ if(NOT UFS_FV3) include(fv3_compiler_flags) endif() -set(moduleDir "${CMAKE_CURRENT_BINARY_DIR}/${includeDir}") - add_library(fv3 ${fv3_srcs}) add_library(FV3::fv3 ALIAS fv3) set_property(SOURCE model/nh_utils.F90 APPEND_STRING PROPERTY COMPILE_FLAGS "${FAST}") set_property(SOURCE model/fv_mapz.F90 APPEND_STRING PROPERTY COMPILE_FLAGS "${FAST}") -set_target_properties(fv3 PROPERTIES COMPILE_FLAGS "${${kind}_flags}") - set_target_properties(fv3 PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/fv3) target_include_directories(fv3 INTERFACE $ $) diff --git a/cmake/compiler_flags_GNU_Fortran.cmake b/cmake/compiler_flags_GNU_Fortran.cmake index 68f1354db..87caa409f 100644 --- a/cmake/compiler_flags_GNU_Fortran.cmake +++ b/cmake/compiler_flags_GNU_Fortran.cmake @@ -2,7 +2,7 @@ set(r8_flags "-fdefault-real-8 -fdefault-double-8") # Fortran flags for 64BIT precision # GNU Fortan -set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ggdb -fbacktrace -cpp -fcray-pointer -ffree-line-length-none -fno-range-check ${${fms_kind}_flags}") +set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ggdb -fbacktrace -cpp -fcray-pointer -ffree-line-length-none -fno-range-check ${${kind}_flags}") if(${CMAKE_Fortran_COMPILER_VERSION} VERSION_GREATER_EQUAL 10) set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fallow-argument-mismatch -fallow-invalid-boz") endif() diff --git a/cmake/compiler_flags_Intel_Fortran.cmake b/cmake/compiler_flags_Intel_Fortran.cmake index 5f908852e..00d99acf8 100644 --- a/cmake/compiler_flags_Intel_Fortran.cmake +++ b/cmake/compiler_flags_Intel_Fortran.cmake @@ -4,7 +4,7 @@ set(r8_flags "-real-size 64") # Fortran flags for 64BIT precision set(r8_flags "${r8_flags} -no-prec-div -no-prec-sqrt") # Intel Fortran -set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -traceback -fpp -fno-alias -auto -safe-cray-ptr -ftz -assume byterecl -nowarn -sox -align array64byte -qno-opt-dynamic-align ${${fms_kind}_flags}") +set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -traceback -fpp -fno-alias -auto -safe-cray-ptr -ftz -assume byterecl -nowarn -sox -align array64byte -qno-opt-dynamic-align ${${kind}_flags}") set(CMAKE_Fortran_FLAGS_REPRO "-O2 -debug minimal -fp-model consistent -qoverride-limits") From 7b15fce87f0f07fa85e1535d441ac074167c6189 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Thu, 16 Sep 2021 17:17:07 -0400 Subject: [PATCH 09/11] simplify 32bit/64bit logic --- CMakeLists.txt | 11 +++-------- cmake/compiler_flags_GNU_Fortran.cmake | 2 +- cmake/compiler_flags_Intel_Fortran.cmake | 6 +++--- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e8aaca969..f296fb342 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,18 +46,13 @@ if(use_WRTCOMP) endif() if(32BIT) - set(kind "r4") + set(kind "R4") else() - set(kind "r8") + set(kind "R8") endif() if(NOT FMS_FOUND) - if(32BIT) - set(FMS_COMPONENTS "R4") - else() - set(FMS_COMPONENTS "R8") - endif() - find_package(FMS REQUIRED COMPONENTS ${FMS_COMPONENTS}) + find_package(FMS REQUIRED COMPONENTS ${kind}) add_library(fms ALIAS FMS::fms_${kind}) endif() diff --git a/cmake/compiler_flags_GNU_Fortran.cmake b/cmake/compiler_flags_GNU_Fortran.cmake index 87caa409f..a8dee674d 100644 --- a/cmake/compiler_flags_GNU_Fortran.cmake +++ b/cmake/compiler_flags_GNU_Fortran.cmake @@ -1,5 +1,5 @@ # Precision-based Fortran compiler flags -set(r8_flags "-fdefault-real-8 -fdefault-double-8") # Fortran flags for 64BIT precision +set(R8_flags "-fdefault-real-8 -fdefault-double-8") # Fortran flags for 64BIT precision # GNU Fortan set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ggdb -fbacktrace -cpp -fcray-pointer -ffree-line-length-none -fno-range-check ${${kind}_flags}") diff --git a/cmake/compiler_flags_Intel_Fortran.cmake b/cmake/compiler_flags_Intel_Fortran.cmake index 00d99acf8..743afce35 100644 --- a/cmake/compiler_flags_Intel_Fortran.cmake +++ b/cmake/compiler_flags_Intel_Fortran.cmake @@ -1,7 +1,7 @@ # Precision-based Fortran compiler flags -set(r4_flags "-real-size 32") # Fortran flags for 32BIT precision -set(r8_flags "-real-size 64") # Fortran flags for 64BIT precision -set(r8_flags "${r8_flags} -no-prec-div -no-prec-sqrt") +set(R4_flags "-real-size 32") # Fortran flags for 32BIT precision +set(R8_flags "-real-size 64") # Fortran flags for 64BIT precision +set(R8_flags "${R8_flags} -no-prec-div -no-prec-sqrt") # Intel Fortran set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -traceback -fpp -fno-alias -auto -safe-cray-ptr -ftz -assume byterecl -nowarn -sox -align array64byte -qno-opt-dynamic-align ${${kind}_flags}") From c11ae4df3e32d1f3764602d01f0a6897e5fb2106 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Fri, 17 Sep 2021 11:15:07 -0400 Subject: [PATCH 10/11] add -fPIC to dycore --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f296fb342..a4558aaa4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,6 +163,9 @@ if(NOT UFS_FV3) include(fv3_compiler_flags) endif() +# Enable -fPIC compiler flag for all targets +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + add_library(fv3 ${fv3_srcs}) add_library(FV3::fv3 ALIAS fv3) From 312fc63581693d3a97d8dcf0f201ee15846be197 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Fri, 17 Sep 2021 13:35:36 -0400 Subject: [PATCH 11/11] use the compiler flags from the dycore for UFS instead of inheriting from UFS --- CMakeLists.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a4558aaa4..d7d4eb52d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,9 +159,7 @@ if(OPENMP) endif() # Obtain compiler-specific flags -if(NOT UFS_FV3) - include(fv3_compiler_flags) -endif() +include(fv3_compiler_flags) # Enable -fPIC compiler flag for all targets set(CMAKE_POSITION_INDEPENDENT_CODE ON)