HPCW 3.0
Loading...
Searching...
No Matches
ecrad.cmake
Go to the documentation of this file.
1# Copyright (c) 2020 - 2025 David Guibert
2# Copyright (c) 2024 - 2025 Niclas Schroeter
3# Copyright (c) 2024 Antoine Morvan
4# All rights reserved.
5#
6# SPDX-License-Identifier: Apache-2.0
7
8include(ExternalData)
9
10set_property(GLOBAL PROPERTY ecrad_can_use_system TRUE)
11set_property(GLOBAL PROPERTY ecrad_depends netcdf cdo)
12
13set(ecrad_build_args "" CACHE STRING "Custom Make arguments for ecRad")
14
15option(ecrad_custom_profile "Use a custom Make profile" OFF)
16set(ecrad_opt_flags "" CACHE STRING "Optimization flags for custom profile")
17set(ecrad_ld_flags "" CACHE STRING "Linker flags for custom profile")
18set(ecrad_basic_flags "" CACHE STRING "Basic flags for custom profile")
19
20set(test_cases small medium big)
21list(TRANSFORM test_cases PREPEND "<BINARY_DIR>/" OUTPUT_VARIABLE required_dirs)
22
23if(ecrad_enabled)
24 if(USE_SYSTEM_ecrad)
25 message(STATUS "ecrad: enabled (system installed)")
26 find_program(ECRAD_EXE ecrad REQUIRED)
27
28 get_filename_component(ECRAD_EXE_DIR "${ECRAD_EXE}" DIRECTORY)
29 set_if_not_present(ENV{PATH} "$ENV{PATH}" "${ECRAD_EXE_DIR}")
30
31 # dummy ecrad external project to get tests
32 ExternalProject_Data_Add(
33 ecrad
34 ${ecrad_revision}
35 CONFIGURE_COMMAND ""
36 BUILD_COMMAND ""
37 INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${required_dirs})
38
39 ExternalProject_Get_Property(ecrad BINARY_DIR)
40 set(ecrad_BIN_DIR ${BINARY_DIR})
41
42 else()
43 message(STATUS "ecrad: enabled (internally built)")
44
45 # Check compiler to set the PROFILE argument of make command
46 set(copy_cmd "true")
47 if(ecrad_custom_profile)
48 set(ECRAD_COMPILER_PROFILE "custom")
49 message(STATUS "Building a custom Make profile...")
50 find_package(OpenMP REQUIRED)
51 set(custom_profile_path "${CMAKE_CURRENT_BINARY_DIR}/Makefile_include.custom")
52 set(copy_cmd "cp ${custom_profile_path} <SOURCE_DIR>")
53
54 file(GENERATE OUTPUT ${custom_profile_path} CONTENT "
55FC = ${CMAKE_Fortran_COMPILER}
56CC = ${CMAKE_C_COMPILER}
57OPTFLAGS = ${ecrad_opt_flags}
58LDFLAGS = ${ecrad_ld_flags}
59BASICFLAGS = ${CMAKE_Fortran_MODDIR_FLAG}../mod ${ecrad_basic_flags}
60OMPFLAG = ${OpenMP_Fortran_FLAGS}"
61 )
62 elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
63 set(ECRAD_COMPILER_PROFILE "gfortran")
64 elseif(CMAKE_Fortran_COMPILER_ID MATCHES "^Intel(LLVM)?$")
65 set(ECRAD_COMPILER_PROFILE "intel")
66 else()
67 message(
68 FATAL_ERROR
69 "ecrad: compiler profile not supported (${CMAKE_Fortran_COMPILER_ID}). Provide a custom profile instead!"
70 )
71 endif()
72
73 ExternalProject_Data_Add(
74 ecrad
75 DEPENDS netcdf::Fortran ${ecrad_revision}
76 CONFIGURE_COMMAND bash -c ${copy_cmd}
77 BUILD_COMMAND env
78 PATH=$ENV{PATH} CPATH=$ENV{CPATH}
79 C_INCLUDE_PATH=$ENV{C_INCLUDE_PATH}
80 LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} LIBRARY_PATH=$ENV{LIBRARY_PATH}
81 ${CMAKE_MAKE_PROGRAM} -j 1 PROFILE=${ECRAD_COMPILER_PROFILE} FC=${CMAKE_Fortran_COMPILER} ${default_build_args} ${ecrad_build_args}
82 INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${required_dirs}
83 COMMAND ${CMAKE_COMMAND} -E make_directory <INSTALL_DIR>
84 COMMAND ${CMAKE_COMMAND} -E copy_directory <BINARY_DIR>/bin
85 <INSTALL_DIR>/bin
86 COMMAND ${CMAKE_COMMAND} -E copy_directory <BINARY_DIR>/lib
87 <INSTALL_DIR>/lib
88 )
89
90 ExternalProject_Get_Property(ecrad INSTALL_DIR)
91 set(ecrad_DIR ${INSTALL_DIR})
92
93 set_if_not_present(ENV{PATH} "$ENV{PATH}" "${ecrad_DIR}/bin")
94 set_if_not_present(ENV{LD_LIBRARY_PATH} "$ENV{LD_LIBRARY_PATH}"
95 "${ecrad_DIR}/lib")
96
97 ExternalProject_Get_Property(ecrad BINARY_DIR)
98 set(ecrad_BIN_DIR ${BINARY_DIR})
99 set_if_not_present(ENV{PATH} "$ENV{PATH}" "${ecrad_BIN_DIR}/bin")
100 endif()
101
102 #The large tests require inputs that are NC4 files. ecRad requires setting a parameter in the radiation_driver namelist to
103 #enable reading and writing of this file format. Additionally, the tests are repeated 5 times by adding the other parameter.
104 #For comparability's sake, the small test is also executed with this adjusted namelist.
105 set(awk_add_params "awk '/do_write_double_precision/ { print; print \"do_write_hdf5 = true,\\nnrepeat = 5,\"; next }1'")
106 set(namelist_large_files configLargeFiles.nam)
107 set(namelist_creation "${awk_add_params} config.nam > ${namelist_large_files}")
108 set(append_new_namelist "&& ${namelist_creation}")
109
110 #Setting up the directories' contents
111 foreach(case IN LISTS test_cases)
112 add_test(
113 NAME ecrad-${case}-stage-in
114 COMMAND
115 env LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} LIBRARY_PATH=$ENV{LIBRARY_PATH}
116 PATH=$ENV{PATH} $<TARGET_FILE:job_launcher> --name=ecrad-${case}-stage-in
117 --log-dir=${LOG_DIR}
118 --
119 bash -c "${ecrad_BIN_DIR}/bin/create_practical.sh ${append_new_namelist}"
120 WORKING_DIRECTORY ${ecrad_BIN_DIR}/${case}
121 )
122 endforeach()
123
124 add_test(
125 NAME ecrad-small
126 COMMAND
127 env LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} LIBRARY_PATH=$ENV{LIBRARY_PATH}
128 PATH=$ENV{PATH} $<TARGET_FILE:job_launcher> --name=ecrad-small
129 --log-dir=${LOG_DIR}
130 -- ecrad
131 ${namelist_large_files} era5slice.nc control.nc
132 WORKING_DIRECTORY ${ecrad_BIN_DIR}/small
133 )
134
135 #The large two tests require input data from outside of ecRad.
136 ExternalData_Add_Test(offline_ecrad_medium
137 NAME ecrad-medium
138 COMMAND
139 env LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} LIBRARY_PATH=$ENV{LIBRARY_PATH}
140 PATH=$ENV{PATH} $<TARGET_FILE:job_launcher> --name=ecrad-medium
141 --log-dir=${LOG_DIR}
142 -- ecrad
143 ${namelist_large_files} DATA{inputs/ecrad/era5sliceConcat1000.nc} control.nc
144 WORKING_DIRECTORY ${ecrad_BIN_DIR}/medium
145 )
146
147 ExternalData_Add_Test(offline_ecrad_big
148 NAME ecrad-big
149 COMMAND
150 env LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} LIBRARY_PATH=$ENV{LIBRARY_PATH}
151 PATH=$ENV{PATH} $<TARGET_FILE:job_launcher> --name=ecrad-big
152 --log-dir=${LOG_DIR}
153 -- ecrad
154 ${namelist_large_files} DATA{inputs/ecrad/era5sliceConcat2000.nc} control.nc
155 WORKING_DIRECTORY ${ecrad_BIN_DIR}/big
156 )
157
158 ExternalData_Add_Target(offline_ecrad_medium)
159 ExternalData_Add_Target(offline_ecrad_big)
160 add_dependencies(offline offline_ecrad_medium offline_ecrad_big)
161
162 foreach(case IN LISTS test_cases)
163 ExternalData_Add_Test(offline_ecrad_${case}_validation
164 NAME ecrad-${case}-validation
165 COMMAND
166 env LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} LIBRARY_PATH=$ENV{LIBRARY_PATH}
167 PATH=$ENV{PATH} $<TARGET_FILE:job_launcher> --name=ecrad-${case}-validation
168 --log-dir=${LOG_DIR}
169 --
170 cdo diff,abslim=0.001 DATA{inputs/ecrad/ref-${case}.nc} control.nc
171 WORKING_DIRECTORY ${ecrad_BIN_DIR}/${case}
172 )
173 ExternalData_Add_Target(offline_ecrad_${case}_validation)
174 add_dependencies(offline offline_ecrad_${case}_validation)
175
176 set_tests_properties(ecrad-${case}-stage-in PROPERTIES FIXTURES_SETUP _setup-ecrad-${case})
177 set_tests_properties(ecrad-${case} PROPERTIES FIXTURES_SETUP _run-ecrad-${case})
178
179 set_tests_properties(ecrad-${case} PROPERTIES FIXTURES_REQUIRED _setup-ecrad-${case})
180 set_tests_properties(ecrad-${case}-validation PROPERTIES FIXTURES_REQUIRED _run-ecrad-${case})
181 endforeach()
182
183endif(ecrad_enabled)