Skip to content

Commit

Permalink
Add gcom4 package (#69)
Browse files Browse the repository at this point in the history
* Working draft version of gcom4 package

* Remove import of unused llnl.util.tty

* Use maintainers function

* Split install function into build and install

* Call self.build from install, since there is no build phase

* Change OpenMP flag for both MPI and serial variants

* Remove repetition
  • Loading branch information
penguian authored Mar 27, 2024
1 parent 06b7550 commit f9d2232
Showing 1 changed file with 104 additions and 0 deletions.
104 changes: 104 additions & 0 deletions packages/gcom4/package.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# 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 gcom/package.py by scottwales 2023
# and https://github.com/coecms/access-esm-build-gadi/blob/master/Makefile
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack.package import *

import llnl.util.filesystem as fs


class Gcom4(Package):
"""
GCOM is a wrapper around multiprocessing libraries such as MPI
Gcom4 is a package for older versions of GCOM as used by UM vn7.3 in ACCESS ESM 1.5
"""

homepage = "https://code.metoffice.gov.uk/trac/gcom"
git = "[email protected]:ACCESS-NRI/GCOM.git"

maintainers("penguian")

version("4.5", branch="dev")
build_directory = join_path("Share", "gcom4.5_access_config")

variant("mpi", default=True, description="Build with MPI")
depends_on("fcm", type="build")
depends_on("mpi", when="+mpi")


def gcom_machine(self, spec):
"""
Determine the machine configuration name
"""
if spec.satisfies("%intel"):
mach_c = "ifort"
elif spec.satisfies("%gcc"):
mach_c = "gfortran"
else:
raise NotImplementedError("Unknown compiler")
if "+mpi" in spec:
mach_m = "openmpi"
else:
mach_m = "serial"
return f"nci_{mach_c}_{mach_m}"


def patch(self):
"""
Perform the equivalent of the following sed commands:
sed -i '/build.target{ns}/d' $@/fcm-make/gcom.cfg
sed -i 's/-openmp/-qopenmp/g' $@/fcm-make/machines/nci_ifort_openmpi.cfg
sed -i 's/-openmp/-qopenmp/g' $@/fcm-make/machines/nci_ifort_serial.cfg
"""
with fs.working_dir(self.build_directory):
filter_file(
r"build\.target\{ns\}.*", "#",
join_path("fcm-make", "gcom.cfg"))
if self.spec.satisfies("%intel"):
machine = self.gcom_machine(self.spec)
filter_file(
r"-openmp", "-qopenmp",
join_path("fcm-make", "machines", f"{machine}.cfg"))


def build(self, spec, prefix):
"""
Build the library.
"""
fcm = which("fcm")
if fcm is None:
raise FileNotFoundError("fcm not found in $PATH")
with fs.working_dir(self.build_directory):

# Set up variables used by fcm-make/gcom.cfg
env["ACTION"] = "preprocess build"
env["DATE"] = ""
env["GCOM_SOURCE"] = "$HERE/.."
env["MIRROR"] = ""
env["REMOTE_ACTION"] = ""
env["ROSE_TASK_MIRROR_TARGET"] = "localhost"

# Decide on the build variant
env["GCOM_MACHINE"] = self.gcom_machine(spec)

# Do the build with fcm
fcm("make", "-f", join_path("fcm-make", "gcom.cfg"))


def install(self, spec, prefix):
"""
Build and install the library.
"""
self.build(spec, prefix)
with fs.working_dir(self.build_directory):
mkdirp(prefix.lib)
install(
join_path("build", "lib", "libgcom.a"),
join_path(prefix.lib, "libgcom.a"))
install_tree(join_path("build", "include"), prefix.include)

0 comments on commit f9d2232

Please sign in to comment.