-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathpackage.py
213 lines (178 loc) · 9.01 KB
/
package.py
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
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# Copyright 2024 ACCESS-NRI
# Based on https://github.com/nci/spack-repo/blob/main/packages/um/package.py
# and https://github.com/coecms/access-esm-build-gadi
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack.package import *
class Um7(Package):
"""
UM is a numerical weather prediction and climate modelling software package.
Um7 is a package for UM vn7.3 for ACCESS ESM 1.5
"""
homepage = "https://code.metoffice.gov.uk/trac/um"
git = "[email protected]:ACCESS-NRI/UM7.git"
# https://code.metoffice.gov.uk/trac/um/wiki/PastReleases
version("access-esm1.6", branch="dev-access-esm1.6", preferred=True)
version("access-esm1.5", branch="access-esm1.5")
maintainers("penguian")
depends_on("fcm", type="build")
depends_on("dummygrib", type=("build", "link"))
depends_on("gcom4+mpi", type=("build", "link"))
depends_on("openmpi", type=("build", "run"))
depends_on("[email protected]:", type=("build", "link"))
depends_on("oasis3-mct", type=("build", "link"))
variant("optim", default="high", description="Optimization level",
values=("high", "debug"), multi=False)
phases = ["edit", "build", "install"]
def setup_build_environment(self, env):
"""
Set environment variables to their required values.
"""
env.prepend_path("PATH", self.spec["fcm"].prefix.bin)
oasis3_incs = [
join_path(self.spec["oasis3-mct"].prefix.include, subdir)
for subdir in ["psmile.MPI1", "mct"]]
ideps = ["gcom4", "netcdf-fortran"]
incs = [self.spec[d].prefix.include for d in ideps] + oasis3_incs
for ipath in incs:
env.prepend_path("CPATH", ipath)
# The gcom4 library does not contain shared objects and
# therefore must be statically linked.
env.prepend_path("LIBRARY_PATH", self.spec["gcom4"].prefix.lib)
# The path to the build directory.
_bld_path = "ummodel_hg3"
# The path to the build configuration.
_bld_cfg_path = join_path(_bld_path, "cfg", "bld-hadgem3-spack.cfg")
def _exe_name(self, optim_value):
"""
Return the executable name, depending on optim_value.
"""
if optim_value == "debug":
return "um_hg3_dbg.exe"
else:
return "um_hg3.exe"
def _get_linker_args(self, spec, name):
"""
The reason for the explicit -rpath is:
https://github.com/ACCESS-NRI/spack-packages/issues/14#issuecomment-1653651447
"""
return " ".join(
[(spec[name].libs).ld_flags,
"-Wl,-rpath=" + join_path(spec[name].prefix, "lib")]
)
def edit(self, spec, prefix):
"""
Create an FCM configuration file based on
ummodel_hg3/cfg/bld-dbg-hadgem3-C2.cfg and
ummodel_hg3/cfg/bld-hadgem3-mct.cfg
"""
ldeps = ["oasis3-mct", "netcdf-fortran", "dummygrib"]
libs = " ".join([self._get_linker_args(spec, d) for d in ldeps] + ["-lgcom"])
opt_value = spec.variants["optim"].value
EXE_NAME = self._exe_name(opt_value)
CPPKEYS = (
"C_LONG_LONG_INT=c_long_long_int MPP=mpp C_LOW_U=c_low_u "
"FRL8=frl8 LINUX=linux BUFRD_IO=bufrd_io LITTLE_END=little_end "
"LINUX_INTEL_COMPILER=linux_intel_compiler "
"ACCESS=access OASIS3=oasis3 CONTROL=control REPROD=reprod "
"MPP=mpp ATMOS=atmos GLOBAL=global A04_ALL=a04_all "
"A01_3A=a01_3a A02_3A=a02_3a A03_8C=a03_8c A04_3D=a04_3d "
"A05_4A=a05_4a A06_4A=a06_4a A08_7A=a08_7a A09_2A=a09_2a "
"A10_2A=a10_2a A11_2A=a11_2a A12_2A=a12_2a A13_2A=a13_2a "
"A14_1B=a14_1b A15_1A=a15_1a A16_1A=a16_1a A17_2B=a17_2b "
"A18_0A=a18_0a A19_1A=a19_1a A25_0A=a25_0a A26_1A=a26_1a "
"A30_1A=a30_1a A31_0A=a31_0a A32_1A=a32_1a A33_0A=a33_0a "
"A34_0A=a34_0a A35_0A=a35_0a A38_0A=a38_0a A70_1B=a70_1b "
"A71_1A=a71_1a C70_1A=c70_1a C72_0A=c72_0a C80_1A=c80_1a "
"C82_1A=c82_1a C84_1A=c84_1a C92_2A=c92_2a C94_1A=c94_1a "
"C95_2A=c95_2a C96_1C=c96_1c C97_3A=c97_3a "
"CABLE_17TILES=cable_17tiles "
"CABLE_SOIL_LAYERS=cable_soil_layers "
"TIMER=timer")
FFLAGS = "-ftz -what -fno-alias -stack-temps -safe-cray-ptr"
if opt_value == "debug":
FO = "-O0"
FTRACEBACK = "-traceback"
FDEBUG = "-debug all"
FG = "-g"
FARCH = ""
FOBLANK = "-O0"
else:
FO = "-O2"
FTRACEBACK = ""
FDEBUG = ""
FG = ""
FARCH = "-xCORE-AVX512"
FOBLANK = ""
config = f"""
# ------------------------------------------------------------------------------
# File header
# ------------------------------------------------------------------------------
CFG::TYPE bld
CFG::REVISION 1.0
USE $HERE/../../umbase_hg3
# ------------------------------------------------------------------------------
# Destination
# ------------------------------------------------------------------------------
DEST $HERE/..
# ------------------------------------------------------------------------------
# Build declarations
# ------------------------------------------------------------------------------
blockdata blkdata.o
excl_dep USE::NetCDF
excl_dep INC::netcdf.inc
excl_dep INC::mpif.h
excl_dep USE::mpl
excl_dep USE::mod_prism
excl_dep USE::mod_prism_proto
excl_dep USE::mod_prism_grids_writing
excl_dep USE::mod_prism_def_partition_proto
excl_dep USE::mod_prism_put_proto
excl_dep USE::mod_prism_get_proto
excl_dep::script EXE
exe_dep portio2a.o pio_data_conv.o pio_io_timer.o
exe_name::flumeMain {EXE_NAME}
pp 1
target {EXE_NAME}
tool::ar ar
tool::cc mpicc
tool::cflags {FO} -g {FTRACEBACK} {FDEBUG} {FARCH} -fp-model precise
tool::cpp cpp
tool::cppflags
tool::cppkeys {CPPKEYS}
tool::fc mpif90
tool::fflags {FO} -g -traceback {FDEBUG} -V -i8 -r8 -fp-model precise {FFLAGS}
tool::fflags::control::coupling::dump_received {FO} {FG} {FTRACEBACK} {FDEBUG} -mp1 -fp-model strict {FFLAGS}
tool::fflags::control::coupling::dump_sent {FO} {FG} {FTRACEBACK} {FDEBUG} -mp1 -fp-model strict {FFLAGS}
tool::fflags::control::coupling::oasis3_atmos_init {FO} {FG} {FTRACEBACK} {FDEBUG} -i4 -r8 -mp1 -fp-model strict {FFLAGS}
tool::fflags::control::top_level::atm_step -O0 -g {FTRACEBACK} {FDEBUG} -V -i8 -r8 -mp1 -fp-model strict {FFLAGS}
tool::fflags::control::top_level::set_atm_pointers -O0 -g -traceback {FDEBUG} -i8 -r8 -fp-model strict -ftz -std95
tool::fflags::control::top_level::u_model -O0 -g {FTRACEBACK} {FDEBUG} -V -i8 -r8 -mp1 -fp-model strict {FFLAGS}
tool::fpp cpp
tool::fppflags -P -traditional
tool::fppkeys {CPPKEYS}
tool::geninterface none
tool::ld mpif90
tool::ldflags {FOBLANK} -g -traceback {FDEBUG} -static-intel {libs}
"""
with open(self._bld_cfg_path, "w") as bld_cfg_file:
bld_cfg_file.write(config)
def build(self, spec, prefix):
"""
Use FCM to build the executable.
"""
fcm = which("fcm")
fcm("build", "-f", "-j", "4", self._bld_cfg_path)
def install(self, spec, prefix):
"""
Install the executable into the prefix.bin directory.
The executable name depends on the "optim" value.
"""
um_exe = self._exe_name(spec.variants["optim"].value)
mkdirp(prefix.bin)
install(
join_path(self._bld_path, "bin", um_exe),
join_path(prefix.bin, um_exe))