Source code for scine_puffin.programs.program

# -*- coding: utf-8 -*-
__copyright__ = """ This code is licensed under the 3-clause BSD license.
Copyright ETH Zurich, Laboratory of Physical Chemistry, Reiher Group.
See LICENSE.txt for details.
"""

from typing import List
import git
import os
import subprocess
import sys

from scine_puffin.config import Configuration


[docs]class Program: """ A common interface for all programs and their setups Parameters ---------- settings :: dict The settings for the particular program. This dictionary should be the given program's block in the ``Configuration``. """ def __init__(self, settings: dict): self.version = settings["version"] self.root = settings["root"] self.source = settings["source"] self.settings = settings
[docs] def install(self, repo_dir: str, install_dir: str, ncores: int): """ Installs or loads the given program. After the install, the ``check_install`` function should run through with out exceptions. The choice of installation/compilation or loading of the program is based on the settings given in the constructor. Parameters ---------- repo_dir :: str The folder for all repositories, if a clone or download is required for the installation, this folder will be used. install_dir :: str If the program is actually installed and not just loaded, this folder will be used as target directory for the install process. ncores :: int The number of cores/threads to be used when compiling/installing the program. """ raise NotImplementedError
[docs] def check_install(self): """ A small function checking if the program was installed/located correctly and does provide the expected features. """ raise NotImplementedError
[docs] def setup_environment(self, config: Configuration, env_paths: dict, env_vars: dict): """ Appends the program specific environment variables to the given dictionaries. Parameters ---------- config :: scine_puffin.config.Configuration The current global configuration. env_paths :: dict A dictionary for all the environment paths, such as ``PATH`` and ``LD_LIBRARY_PATH``. The added settings will be appended to the existing paths, using ``export PATH=$PATH:...``. env_vars :: dict A dictionary for all fixed environment variables. All settings will replace existing variables such as ``export OMP_NUM_THREADS=1`` """ raise NotImplementedError
[docs] def available_models(self) -> List[str]: """ A small function returning the single point models available now with the given program loaded/installed. Returns ------- models :: List[str] A list of names of models that are available if the program is avialable. """ raise NotImplementedError
def scine_module_install(self, repo_dir: str, install_dir: str, ncores: int, add_lib: bool = False, add_bin: bool = False): initial_dir = os.getcwd() # Handle repository if os.path.exists(repo_dir): repository = git.Repo(repo_dir) try: repository.remotes.origin.pull() repository.git.submodule("update", "--init") except BaseException: try: repository.git.checkout("master") except git.exc.GitCommandError: repository.git.checkout("main") repository.git.submodule("update", "--init") repository.remotes.origin.pull() repository.git.submodule("update", "--init") finally: repository.git.checkout(self.version) repository.remotes.origin.pull() repository.git.submodule("update", "--init") else: repository = git.Repo.clone_from(self.source, repo_dir) repository.git.checkout(self.version) repository.git.submodule("update", "--init") # Build from sources into <repo>/build and install build_dir = os.path.join(repo_dir, "build") if build_dir and not os.path.exists(build_dir): os.makedirs(build_dir) os.chdir(build_dir) env = os.environ.copy() if add_bin: env["PATH"] = env["PATH"] + ":" + os.path.join(install_dir, "bin") if add_lib: if "LD_LIBRARY_PATH" in env.keys(): env["LD_LIBRARY_PATH"] = ( env["LD_LIBRARY_PATH"] + ":" + os.path.join(install_dir, "lib") ) else: env["LD_LIBRARY_PATH"] = os.path.join(install_dir, "lib") env["LD_LIBRARY_PATH"] = ( env["LD_LIBRARY_PATH"] + ":" + os.path.join(install_dir, "lib64") ) args = ["cmake"] args.append("-DCMAKE_BUILD_TYPE=Release") args.append("-DSCINE_BUILD_TESTS=OFF") args.append("-DSCINE_BUILD_PYTHON_BINDINGS=ON") args.append("-DSCINE_MARCH=" + self.settings["march"]) if self.settings["cxx_compiler_flags"]: args.append("-DCMAKE_CXX_FLAGS=" + self.settings["cxx_compiler_flags"]) args.append("-DCMAKE_INSTALL_PREFIX=" + install_dir) args.append("-DPYTHON_EXECUTABLE=" + sys.executable) if self.settings["cmake_flags"]: args += self.settings["cmake_flags"].split(" ") args.append("..") subprocess.run(args, env=env, check=True) subprocess.run(["make", "-j" + str(ncores), "install"], env=env, check=True) os.chdir(initial_dir)