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
|
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import sys
from spack import *
class Roms(MakefilePackage):
"""ROMS is a free-surface, terrain-following,
primitive equations ocean model widely used by
the scientific community for a diverse range of applications"""
homepage = "https://www.myroms.org/"
url = "file://{0}/roms_3.8_source.tar.gz".format(os.getcwd())
manual_download = True
# TODO: ROMS v3.8 (svn version 986) require credentials to download and use
# Spack recipe expects ROMS source code in .tar.gz format
# checksum may differ from what is provided here.
# user can skip checksum verification by placing "--no-checksum"
# next to "spack install"
version('3.8', sha256='5da7a61b69bd3e1f84f33f894a9f418971f3ba61cf9f5ef0a806a722161e2c9a')
variant("openmp", default=False, description="Turn on shared-memory parallelization in ROMS")
variant("mpi", default=True, description="Turn on distributed-memory parallelization in ROMS")
variant(
'roms_application', default='benchmark',
description='Makefile to include its associated header file',
values=('upwelling', 'benchmark'), multi=False
)
variant("debug", default=False, description="Turn on symbolic debug information with no optimization")
depends_on("mpi", when="+mpi")
depends_on("netcdf-fortran")
depends_on("netcdf-c")
depends_on("hdf5+fortran")
depends_on("zlib")
depends_on("curl")
depends_on("amdlibm", when="%aocc")
# Note: you cannot set USE_OpenMP and USE_MPI at the same time
conflicts("+mpi+openmp")
def _copy_arch_file(self, lib):
"""AOCC compiler takes gfortran's makefile as reference"""
copy(
join_path('Compilers', 'Linux-gfortran.mk'),
join_path('Compilers', '{0}-{1}.mk'.format(self.arch, lib))
)
@property
def selected_roms_application(self):
"""
Application type that have been selected in this build
"""
return self.spec.variants['roms_application'].value
@property
def arch(self):
"""return target platform"""
plat = sys.platform
if plat.startswith("linux"):
plat = "Linux"
return plat
def _edit_arch(self, spec, prefix, lib):
"""
Edit Linux-flang.mk makefile to support AOCC compiler
"""
fflags = ['-fveclib=AMDLIBM', '-O3', '-ffast-math']
make_aocc = join_path('Compilers',
'{0}-{1}.mk'.format(self.arch, lib))
filter_file(r'\sFC := gfortran*$', 'FC := {0}'.format(lib), make_aocc)
filter_file(r'\sFFLAGS\s:=.*$',
'FFLAGS := {0}'.format(' '.join(fflags)),
make_aocc)
filter_file(r'\sLIBS\s:= [$]',
'LIBS := {0} $'.format(spec['amdlibm'].libs.ld_flags),
make_aocc)
filter_file(r'\sFREEFLAGS\s:=.*',
'FREEFLAGS := -ffree-form',
make_aocc)
def edit(self, spec, prefix):
# ROMS doesn't have support for AOCC out of the box
# Support extended to AOCC from below steps
if '%aocc' in self.spec:
lib_info = os.path.basename(spack_fc)
self._copy_arch_file(lib_info)
self._edit_arch(spec, prefix, lib_info)
makefile = FileFilter('makefile')
app_type = self.selected_roms_application
makefile.filter(r'ROMS_APPLICATION.*?=.*',
'ROMS_APPLICATION = {0}'.format(app_type.upper()))
makefile.filter(r'\sFORT\s[?]=.*',
'FORT = {0}'.format(os.path.basename(spack_fc)))
makefile.filter(r'\sUSE_NETCDF4\s[?]=.*', 'USE_NETCDF4 = on')
# Build MPI variant of ROMS
if "+mpi" in self.spec:
makefile.filter(r'\sUSE_MPI\s[?]=.*', 'USE_MPI = on')
makefile.filter(r'\sUSE_MPIF90\s[?]=.*', 'USE_MPIF90 = on')
makefile.filter(r'\sUSE_OpenMP\s[?]=.*', 'USE_OpenMP =')
# Build OpenMP variant of ROMS
if "+openmp" in self.spec:
makefile.filter(r'\sUSE_OpenMP\s[?]=.*', 'USE_OpenMP = on')
makefile.filter(r'\sUSE_MPI\s[?]=.*', 'USE_MPI =')
makefile.filter(r'\sUSE_MPIF90\s[?]=.*', 'USE_MPIF90 =')
# Build Debug variant of ROMS
if "+debug" in self.spec:
makefile.filter(r'\sUSE_DEBUG\s[?]=.*', 'USE_DEBUG = on')
def setup_build_environment(self, spack_env):
spec = self.spec
netcdf_include = spec['netcdf-fortran'].prefix.include
nf_config = join_path(spec['netcdf-fortran'].prefix.bin, 'nf-config')
spack_env.set('NF_CONFIG', nf_config)
spack_env.set('NETCDF_INCDIR', netcdf_include)
spack_env.set('HDF5_INCDIR', spec['hdf5'].prefix.include)
spack_env.set('HDF5_LIBDIR', spec['hdf5'].prefix.libs)
def build(self, spec, prefix):
make(parallel=False)
def install(self, spec, prefix):
mkdirp(prefix.bin)
install('roms*', prefix.bin)
|