Source code for pycif.plugins.models.chimere_acc.compile

import os
import subprocess
from shutil import copytree, ignore_patterns, rmtree, copy
from logging import info, debug


[docs] def compile(self): comp_dir = "{}/model".format(self.workdir) # Copying the executables try: # If force-recompile = True, return IOError to avoid copying if getattr(self, "force-recompile"): raise IOError # Otherwise, try copying executables source = "{}/src/fwdchimere.e".format(self.direxec) copy(source, comp_dir) source = "{}/src_tl/tlchimere.e".format(self.direxec) copy(source, comp_dir) source = "{}/src_ad/achimere.e".format(self.direxec) copy(source, comp_dir) return except IOError as e: if not getattr(self, "auto-recompile"): raise Exception( "CHIMERE could not find executables ({}) and was not asked to " "compile them; specify auto-recompile = True in Yaml to do so" .format(self.direxec) ) # Otherwise, re-compile # Copying sources locally; overwrite folder if exists if os.path.isdir("{}/sources".format(comp_dir)): rmtree("{}/sources".format(comp_dir)) dir_sources = self.dir_sources if self.dir_sources != "" else self.direxec copytree( dir_sources, "{}/sources".format(comp_dir), ignore=ignore_patterns("*.a"), ) # Modifying LDFLAGS if needed if hasattr(self, "LDFLAGS") or hasattr(self, "NETCDFLIB") or hasattr(self, "NETCDFINC"): old_lines = open( "{}/sources/Makefile".format(comp_dir), "r" ).readlines() old_lines = [ln.rstrip() for ln in old_lines] for k, ln in enumerate(old_lines): if ln[:9] == "LIBRARIES" and hasattr(self, "LDFLAGS"): info('change LIBRARIES') old_lines[k] = "LIBRARIES =\t{}".format(self.LDFLAGS) if ln[:10] == "NETCDF_LIB" and hasattr(self, "NETCDFLIB"): info('change NETCDF_LIB') old_lines[k] = "NETCDF_LIB =\t{}".format(self.NETCDFLIB) if ln[:10] == "NETCDF_INC" and hasattr(self, "NETCDFINC"): info('change NETCDF_INC') old_lines[k] = "NETCDF_INC =\t{}".format(self.NETCDFINC) with open("{}/sources/Makefile".format(comp_dir), "w") as f: f.write("\n".join(old_lines)) # Now compiling comp_mode = "" if getattr(self, "compile-mode") == "PROD" else "--debug" comp_clean = "--clean" if getattr(self, "compile-clean") else "" compiler = "--{}".format(getattr(self, "compiler", "gpu")) for mode, pref, suff in zip( ["A", "L", "D"], ["a", "tl", "fwd"], ["_ad", "_tl", ""] ): if not mode in getattr(self, "compile-only"): continue info("Compiling CHIMERE {}".format(mode)) info(f"./compile-chimere {compiler} -m {mode} {comp_mode} {comp_clean}") with open("{}/CHIMERE_compiling_{}.log" .format(comp_dir, mode), "w") as log: process = subprocess.Popen( f"./compile-chimere {compiler} -m " f"{mode} {comp_mode} {comp_clean}", shell=True, stdout=log, cwd="{}/sources/".format(comp_dir), stderr=subprocess.PIPE, ) _, stderr = process.communicate() # Print errors if no executable created (or if forced to) exe_file = "{}/sources/src{}/{}chimere.e".format(comp_dir, suff, pref) if not os.path.isfile(exe_file) or getattr(self, "force-compile-stderr"): debug("CHIMERE returned errors during compiling.") debug("There might be some bugs in the Fortran or in the " "libraries loaded in the system:") debug("### START OF CHIMERE ERROR MESSAGE ###") for ln in stderr.decode().split("\n"): debug(ln) debug("### END OF CHIMERE ERROR MESSAGE ###") # Copy executable at model root directory copy(exe_file, comp_dir)