-
Notifications
You must be signed in to change notification settings - Fork 50
/
Copy pathCMakeLists.txt
318 lines (268 loc) · 12.8 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
cmake_minimum_required(VERSION 3.14)
project(scm
VERSION 5.0.0
LANGUAGES C Fortran)
set(PROJECT "CCPP-SCM")
####################################################################
# Begin CCPP prebuild step #
####################################################################
if(DEFINED CCPP_SUITES)
if (${CCPP_SUITES} MATCHES "ALL")
message("Calling CCPP code generator (ccpp_prebuild.py) for all available suites ...")
else()
set(_ccpp_suites_arg "--suites=${CCPP_SUITES}")
message("Calling CCPP code generator (ccpp_prebuild.py) for suites ${_ccpp_suites_arg} ...")
endif()
unset(CCPP_SUITES CACHE)
else()
execute_process(
COMMAND scm/src/suite_info.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../..
OUTPUT_VARIABLE suite_string
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(_ccpp_suites_arg "--suites=${suite_string}")
message("Calling CCPP code generator (ccpp_prebuild.py) for suites listed in scm/src/suite_info.py: ${_ccpp_suites_arg}.")
endif()
# Run CCPP prebuild.py
message (STATUS "Running ccpp_prebuild.py for CCPP")
# Make the directories where the ccpp_prebuild.py script wants to write caps and make snippets
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ccpp/physics/physics)
if (NOT EXISTS "${CMAKE_SOURCE_DIR}/../../ccpp/framework/scripts/ccpp_prebuild.py")
message( FATAL_ERROR "ccpp_prebuild.py script does not exist, did you check out the code recursively?" )
endif()
if (${CMAKE_BUILD_TYPE} MATCHES "Debug")
execute_process(
COMMAND ccpp/framework/scripts/ccpp_prebuild.py --config=ccpp/config/ccpp_prebuild_config.py ${_ccpp_suites_arg} --builddir=${CMAKE_CURRENT_BINARY_DIR} --debug --verbose
OUTPUT_FILE ${PROJECT_BINARY_DIR}/ccpp_prebuild.out
ERROR_FILE ${PROJECT_BINARY_DIR}/ccpp_prebuild.err
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../..
RESULT_VARIABLE return_code
)
else()
execute_process(
COMMAND ccpp/framework/scripts/ccpp_prebuild.py --config=ccpp/config/ccpp_prebuild_config.py ${_ccpp_suites_arg} --builddir=${CMAKE_CURRENT_BINARY_DIR}
OUTPUT_FILE ${PROJECT_BINARY_DIR}/ccpp_prebuild.out
ERROR_FILE ${PROJECT_BINARY_DIR}/ccpp_prebuild.err
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../..
RESULT_VARIABLE return_code
)
endif()
# Check return code from CCPP prebuild.py
if(return_code EQUAL 0)
message (STATUS "CCPP prebuild step completed successfully")
else(return_code EQUAL 0)
message (FATAL_ERROR "CCPP prebuild step failed, check ccpp_prebuild.out/ccpp_prebuild.err")
endif(return_code EQUAL 0)
####################################################################
# End CCPP prebuild step #
####################################################################
ENABLE_LANGUAGE(Fortran)
include(CMakeForceCompiler)
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/../../CMakeModules/Modules)
find_package(NetCDF REQUIRED COMPONENTS C Fortran)
find_package(bacio REQUIRED)
find_package(sp REQUIRED)
find_package(w3emc REQUIRED)
find_package(MPI REQUIRED)
if(NOT MPI_Fortran_HAVE_F08_MODULE)
message(FATAL_ERROR "MPI_F08 Required")
endif()
find_package(MPI REQUIRED Fortran)
if(NOT MPI_Fortran_HAVE_F08_MODULE)
message(FATAL_ERROR "MPI implementation does not support the Fortran 2008 mpi_f08 interface")
endif()
message(STATUS "MPI Include Path: ${MPI_INCLUDE_PATH}")
message(STATUS "MPI Libraries: ${MPI_LIBRARIES}")
SET(CCPP_FRAMEWORK_SRC ${CMAKE_SOURCE_DIR}/../../ccpp/framework)
SET(CCPP_PHYSICS_SRC ${CMAKE_SOURCE_DIR}/../../ccpp/physics)
# Use rpaths on MacOSX
set(CMAKE_MACOSX_RPATH 1)
#------------------------------------------------------------------------------
# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
endif()
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/ccpp/framework/src)
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/ccpp/physics)
include_directories(${MPI_Fortran_INCLUDE_PATH})
#------------------------------------------------------------------------------
# Add required preprocessor flags for build type
if (${CMAKE_BUILD_TYPE} MATCHES "Debug")
ADD_DEFINITIONS(-DDEBUG)
endif ()
#------------------------------------------------------------------------------
# Add -DCCPP preprocessor flag (needed to preprocess GFS_typedefs.F90 from FV3)
ADD_DEFINITIONS(-DCCPP)
#------------------------------------------------------------------------------
# Add host-model specific preprocessor flag (needed for some physics schemes)
ADD_DEFINITIONS(-DSCM)
ADD_DEFINITIONS(-DMPI)
#------------------------------------------------------------------------------
# Add model-specific flags for C/C++/Fortran preprocessor
ADD_DEFINITIONS(-DMOIST_CAPPA -DUSE_COND -DNEMS_GSM)
#ADD_DEFINITIONS(-DINTERNAL_FILE_NML)
#------------------------------------------------------------------------------
# Detect OS and set preprocessor flags
if(APPLE)
ADD_DEFINITIONS(-DMACOSX)
elseif(UNIX)
ADD_DEFINITIONS(-DLINUX)
else ()
message (FATAL_ERROR "Unsupported platform, only Linux and MacOSX are supported at this time.")
endif()
# Build Options
set(32BIT OFF CACHE BOOL "Enable 32BIT (single precision arithmetic in SCM)")
set(AVX2 ON CACHE BOOL "Enable AVX2 instruction set")
set(AVX OFF CACHE BOOL "Enable AVX-I instruction set")
set(SIMDMULTIARCH OFF CACHE BOOL "Enable multi-target SIMD instruction sets")
#------------------------------------------------------------------------------
# Set compile options
if (32BIT)
add_definitions(-DSINGLE_PREC)
add_definitions(-DRTE_USE_SP)
endif()
if (${CMAKE_Fortran_COMPILER_ID} MATCHES "GNU")
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()
if(NOT 32BIT)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fdefault-real-8 -fdefault-double-8")
endif()
if (${CMAKE_BUILD_TYPE} MATCHES "Debug")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -O0 -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans -ffpe-trap=invalid,zero,overflow -fbounds-check")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
else()
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -O2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
endif()
set(CMAKE_C_FLAGS_RELEASE "-O2 -fPIC" CACHE STRING "" FORCE)
set(CMAKE_Fortran_FLAGS_RELEASE "-O2 -fPIC" CACHE STRING "" FORCE)
set(CMAKE_C_FLAGS_BITFORBIT "-O2 -fPIC" CACHE STRING "" FORCE)
set(CMAKE_Fortran_FLAGS_BITFORBIT "-O2 -fPIC" CACHE STRING "" FORCE)
elseif (${CMAKE_Fortran_COMPILER_ID} MATCHES "Intel")
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_C_FLAGS "${CMAKE_C_FLAGS} -qno-opt-dynamic-align -sox -fp-model source")
if(NOT 32BIT)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -real-size 64")
endif()
if (${CMAKE_BUILD_TYPE} MATCHES "Debug")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -O0 -check -check noarg_temp_created -check nopointer -warn -warn noerrors -fp-stack-check -fstack-protector-all -fpe0 -debug -ftrapuv -init=snan,arrays")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -ftrapuv")
else()
if(32BIT)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -O2 -debug minimal -fp-model source -qoverride-limits -qopt-prefetch=3")
else()
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -O2 -debug minimal -fp-model source -qoverride-limits -qopt-prefetch=3 -no-prec-div -no-prec-sqrt")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -debug minimal")
set(FAST "-fast-transcendentals")
if(AVX2)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -march=core-avx2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=core-avx2")
elseif(SIMDMULTIARCH)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -axSSE4.2,CORE-AVX2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -axSSE4.2,CORE-AVX2")
elseif(AVX)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -march=core-avx-i")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=core-avx-i")
endif()
endif()
set(CMAKE_C_FLAGS_RELEASE "-O2 -fPIC" CACHE STRING "" FORCE)
set(CMAKE_Fortran_FLAGS_RELEASE "-O2 -fPIC" CACHE STRING "" FORCE)
set(CMAKE_C_FLAGS_BITFORBIT "-O2 -fPIC" CACHE STRING "" FORCE)
set(CMAKE_Fortran_FLAGS_BITFORBIT "-O2 -fPIC" CACHE STRING "" FORCE)
elseif (${CMAKE_Fortran_COMPILER_ID} MATCHES "NVHPC")
if(ENABLE_NVIDIA_OPENACC MATCHES "true")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -acc -Minfo=accel")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -acc -Minfo=accel")
else()
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
endif()
if(NOT 32BIT)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -r8")
endif()
if (${CMAKE_BUILD_TYPE} MATCHES "Debug")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -O0 -g")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g")
else()
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -O2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
endif()
set(MPI_C_COMPILER mpicc)
set(MPI_CXX_COMPILER mpicxx)
set(MPI_Fortran_COMPILER mpif90)
set(CMAKE_C_FLAGS_RELEASE "-O2 -fPIC" CACHE STRING "" FORCE)
set(CMAKE_Fortran_FLAGS_RELEASE "-O2 -fPIC" CACHE STRING "" FORCE)
set(CMAKE_C_FLAGS_BITFORBIT "-O2 -fPIC" CACHE STRING "" FORCE)
set(CMAKE_Fortran_FLAGS_BITFORBIT "-O2 -fPIC" CACHE STRING "" FORCE)
else (${CMAKE_Fortran_COMPILER_ID} MATCHES "GNU")
message (FATAL_ERROR "This program has only been compiled with gfortran and ifort. If another compiler is needed, the appropriate flags must be added in ${CMAKE_SOURCE_DIR}/CMakeLists.txt")
endif (${CMAKE_Fortran_COMPILER_ID} MATCHES "GNU")
#------------------------------------------------------------------------------
# Set flag for 32bit dynamics build
if(32BIT)
message(STATUS "Compile CCPP slow physics with 64-bit precision, fast physics with 32-bit precision")
add_definitions(-DOVERLOAD_R4)
if(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
# set(CMAKE_Fortran_FLAGS_PHYSICS "-real-size 64 -no-prec-div -no-prec-sqrt")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
# set(CMAKE_Fortran_FLAGS_PHYSICS "-fdefault-real-8 -fdefault-double-8")
endif()
set(CMAKE_Fortran_FLAGS_DYNAMICS "")
else()
message(STATUS "Compile CCPP physics with 64-bit precision")
remove_definitions(-DOVERLOAD_R8)
remove_definitions(-DOVERLOAD_R4)
set(CMAKE_Fortran_FLAGS_PHYSICS "")
set(CMAKE_Fortran_FLAGS_DYNAMICS "")
endif()
#------------------------------------------------------------------------------
# Set netCDF flags for preprocessor
ADD_DEFINITIONS(-DNETCDF)
# Set OpenMP flags for C/C++/Fortran
if (OPENMP)
# Clang compiler does not support OpenMP out of the box
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang*")
message(FATAL_ERROR "OpenMP not supported for Apple/LLVM Clang compilers")
endif()
find_package(OpenMP REQUIRED)
endif()
# How about using proper compile targets etc?
#------------------------------------------------------------------------------
# Configure sources
ADD_SUBDIRECTORY(${CCPP_FRAMEWORK_SRC} ${CMAKE_BINARY_DIR}/ccpp/framework)
ADD_SUBDIRECTORY(${CCPP_PHYSICS_SRC} ${CMAKE_BINARY_DIR}/ccpp/physics)
ADD_DEPENDENCIES(ccpp_physics ccpp_framework)
SET(scm_source_files scm.F90
scm_input.F90
scm_utils.F90
scm_vgrid.F90
scm_setup.F90
scm_forcing.F90
scm_time_integration.F90
scm_output.F90
)
ADD_EXECUTABLE(scm ${scm_source_files} ccpp_static_api.F90)
if(OPENMP)
TARGET_LINK_LIBRARIES(scm PUBLIC OpenMP::OpenMP_Fortran)
endif()
TARGET_LINK_LIBRARIES(scm NetCDF::NetCDF_Fortran)
TARGET_LINK_LIBRARIES(scm bacio::bacio_4)
TARGET_LINK_LIBRARIES(scm sp::sp_d)
TARGET_LINK_LIBRARIES(scm w3emc::w3emc_d)
TARGET_LINK_LIBRARIES(scm ccpp_framework)
TARGET_LINK_LIBRARIES(scm ccpp_physics)
SET_TARGET_PROPERTIES(scm PROPERTIES
COMPILE_FLAGS "${CMAKE_Fortran_FLAGS}"
LINK_FLAGS "${CMAKE_Fortran_FLAGS}")
ADD_CUSTOM_COMMAND(
TARGET scm POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink
${CMAKE_SOURCE_DIR}/run_scm.py
${CMAKE_CURRENT_BINARY_DIR}/run_scm.py)