ESCOMP / CMEPS

NUOPC Community Mediator for Earth Prediction Systems
https://escomp.github.io/CMEPS/
21 stars 77 forks source link

how to build stand alone library of cmeps? #465

Open StevePny opened 3 months ago

StevePny commented 3 months ago

Short version:

How do I build CMEPS as a library that can be used as the mediator for an ESMF/NUOPC coupled model? I've tried a few obvious approaches but none have worked and I have not been able to find instructions in the repo.

Long version:

I'm attempting to use CMEPS as a replacement mediator for our own ESM comprising a set of NUOPC-compliant coupled models.

I'd like to build cmeps as a library, similar to what is specified in the Makefile as: https://github.com/ESCOMP/CMEPS/blob/6384ff4e4a6bc82a678f9419a43ffbd5d53ac209/mediator/Makefile#L18 so that we can create an ESMF makefile fragment for CMEPS and then use it to replace our own med.F90 mediator.

I have installed the ParallelIO package (which was not mentioned in the documentation, but seemed to be needed by the CMakeLists.txt and Makefile as required dependencies). After setting export PIO=/opt/PIO, where I installed it, the Makefile runs but is looking for additional routines that are in files in application-specific directories. While some are in the ../ufs directory in this repository, others are completely outside of this repository (as far as I can tell), for example I found some in the UFS repo and CDEPS repo.

As an alternative, I've tried building with cmake. The Readme does not have any instructions for building. So assuming it is something like:

cmake .
make

I get this error:

[ 16%] Building Fortran object mediator/CMakeFiles/cmeps.dir/med_methods_mod.F90.o
/tmp/CMEPS/mediator/med_methods_mod.F90(2642): error #7002: Error in opening the compiled module file.  Check INCLUDE paths.   [SHR_INFNAN_MOD]
    use shr_infnan_mod, only: shr_infnan_isnan
--------^
/tmp/CMEPS/mediator/med_methods_mod.F90(2658): error #7002: Error in opening the compiled module file.  Check INCLUDE paths.   [SHR_INFNAN_MOD]
    use shr_infnan_mod, only: shr_infnan_isnan
--------^
/tmp/CMEPS/mediator/med_methods_mod.F90(2651): error #6404: This name does not have a type, and must have an explicit type.   [SHR_INFNAN_ISNAN]
       if (shr_infnan_isnan(dataptr(n))) then
-----------^
/tmp/CMEPS/mediator/med_methods_mod.F90(2651): error #6341: A logical data type is required in this context.   [SHR_INFNAN_ISNAN]
       if (shr_infnan_isnan(dataptr(n))) then
-----------^
/tmp/CMEPS/mediator/med_methods_mod.F90(2642): error #6580: Name in only-list does not exist or is not accessible.   [SHR_INFNAN_ISNAN]
    use shr_infnan_mod, only: shr_infnan_isnan
------------------------------^
/tmp/CMEPS/mediator/med_methods_mod.F90(2668): error #6406: Conflicting attributes or multiple declaration of name.   [SHR_INFNAN_ISNAN]
          if (shr_infnan_isnan(dataptr(k,n))) then
--------------^
/tmp/CMEPS/mediator/med_methods_mod.F90(2668): error #6341: A logical data type is required in this context.   [SHR_INFNAN_ISNAN]
          if (shr_infnan_isnan(dataptr(k,n))) then
--------------^
/tmp/CMEPS/mediator/med_methods_mod.F90(2658): error #6580: Name in only-list does not exist or is not accessible.   [SHR_INFNAN_ISNAN]
    use shr_infnan_mod, only: shr_infnan_isnan
------------------------------^
compilation aborted for /tmp/CMEPS/mediator/med_methods_mod.F90 (code 1)
make[2]: *** [mediator/CMakeFiles/cmeps.dir/build.make:89: mediator/CMakeFiles/cmeps.dir/med_methods_mod.F90.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:142: mediator/CMakeFiles/cmeps.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

which is clearly looking for the missing files that are found in either the CDEPS or UFS repositories.

I tried just copying them into the local shared directory and adding them to the CMakeLists.txt files, but that did not seem to be sufficient. In that case I get this error:

[ 13%] Built target cmeps_share
Scanning dependencies of target shared
[ 15%] Building Fortran object shared/CMakeFiles/shared.dir/shr_kind_mod.F90.o
[ 17%] Building Fortran object shared/CMakeFiles/shared.dir/shr_infnan_mod.F90.o
/tmp/CMEPS/shared/shr_infnan_mod.F90(76): error #7950: Procedure name in MODULE PROCEDURE statement must be the name of accessible module procedure.   [SHR_INFNAN_ISNAN_DOUBLE]
   module procedure shr_infnan_isnan_double
--------------------^
/tmp/CMEPS/shared/shr_infnan_mod.F90(78): error #7950: Procedure name in MODULE PROCEDURE statement must be the name of accessible module procedure.   [SHR_INFNAN_ISNAN_REAL]
   module procedure shr_infnan_isnan_real
--------------------^
/tmp/CMEPS/shared/shr_infnan_mod.F90(76): error #7407: Unresolved MODULE PROCEDURE specification name.   [SHR_INFNAN_ISNAN_DOUBLE]
   module procedure shr_infnan_isnan_double
--------------------^
/tmp/CMEPS/shared/shr_infnan_mod.F90(78): error #7407: Unresolved MODULE PROCEDURE specification name.   [SHR_INFNAN_ISNAN_REAL]
   module procedure shr_infnan_isnan_real
--------------------^

Could you provide some guidance as to how to build this package? (it would be great if these notes could be added to the README.md or an INSTALL file)

StevePny commented 3 months ago

It appears that a similar question was asked by @uturuncoglu in issue #402 almost a year ago but has not received a response. @uturuncoglu did you ever find a solution?

I would second that the the organization of the shared codes is confusing. Best practice would be to put these shared codes in their own dedicated repository and then link them here and anywhere else they are used.

A generic build not dependent on the CESM or UFS applications, as suggested by @uturuncoglu, would be great too.

StevePny commented 3 months ago

I think I have a solution, which required copying over many of the shared files from CDEPS and UFS to a new local directory shared/ and then editing the CMakeList.txt files at the top level:

add_subdirectory(shared)

in the new shared/ directory:

project(shared Fortran)
include(ExternalProject)

add_library(shared shr_infnan_mod.F90 shr_kind_mod.F90 shr_orb_mod.F90 shr_sys_mod.F90 shr_sys_mod.F90 shr_sys_mod.F90 shr_sys_mod.F90 shr_log_mod.F90 shr_strconvert_mod.F90 shr_abort_mod.F90 shr_const_mod.F90)

target_include_directories (shared PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${ESMF_F90COMPILEPATHS} ${PIO_Fortran_INCLUDE_DIRS})

target_compile_definitions(shared PUBLIC HAVE_IEEE_ARITHMETIC)

(note: I had to add the HAVE_IEEE_ARITHMETIC definition, which I assume is valid with the intel compiler, but I'm not sure how to deal with the error above when using gfortran instead.)

and in the mediator/ directory:

target_include_directories (cmeps PUBLIC "${CMAKE_BINARY_DIR}/shared")

@jedwards4b are you the owner of this repository? Can we add this in for now, and then change to a more generic solution with an external repo for the shared files later?

jedwards4b commented 3 months ago

@StevePny I am the maintainer of this repository. I apparently haven't followed it very well as I wasn't aware of issue #402 until now. I am planning to address the issue of the organization of shared files in the coming months and I will include this as one of the objectives of that reorg. For now I would suggest that you create a fork of cmeps with the mods that you need to build standalone - so you want a mediator library without a driver and without cdeps.