#!/usr/bin/env python3
import os
import sys
from datetime import datetime
from collections import OrderedDict
from pygromos.utils import bash
from pygromos.utils.utils import spacer, spacer2
"""
These functioons build a Gromos++ and GromosXX binary with conda.
If you want to use these features please uncomment all lines in .gitmodules
and provide the correct credetials for the gitlab repository.
"""
[docs]def default_install(nCores: int = 1, _timing_dict: dict = {}, verbose: bool = False):
root_dir = os.path.dirname(__file__)
install_gromos(
root_dir=root_dir,
do_clean=True,
gromosXX_with_mpi=False,
gromosPP_with_omp=False,
recompile_from_scratch=True,
nCore=nCores,
_timing_dict=_timing_dict,
)
[docs]def install_gromos(
root_dir: str = None,
nCore: int = 3,
gromosXX_with_mpi: bool = False,
gromosXX_with_omp: bool = False,
gromosXX_with_cuda: str = None,
gromosPP_with_omp=False,
gromosPP_with_debug: bool = False,
gromosXX_with_debug: bool = False,
do_compile: bool = True,
do_clean: bool = True,
recompile: bool = False,
recompile_from_scratch: bool = False,
_do_gromosPP: bool = True,
_do_gromosXX: bool = True,
_timing_dict: dict = {},
verbose: bool = True,
):
"""
Install the gromos simulation packages. As a helper: to get the dependencies right, install and activate the provided pygromos environments!
Parameters
----------
root_dir : str
this dir contains the gromosXX and the gromosPP git repositories
nCore : int, optional
how many cores should be used to compile?, by default 1
gromosXX_with_cuda_dir : str, optional
use the following cuda path and activate cuda support, by default None
gromosXX_with_omp : bool, optional
should gromosXX be compiled with omp - Warning dont combine wiht mpi!, by default False
gromosXX_with_mpi : bool, optional
should gromosXX be compiled wiht mpi - Warning dont combine with omp!, by default False
gromosPP_with_omp : bool, optional
should gromosPP be compiled with omp, by default False
gromosPP_with_debug : bool, optional
set gromosPP debug flag, by default False
gromosXX_with_debug : bool, optional
set gromosXX debug flag, by default False
do_compile : bool, optional
compile the programms, by default True
do_clean : bool, optional
clean up and remove the programs (can be used together with do_compile to get a clean start), by default False
recompile : bool, optional
recompile the programs with make, by default False
recompile_from_scratch : bool, optional
recompile with configure and make, by default False
_do_gromosPP : bool, optional
install the gromosPP program, by default True
_do_gromosXX : bool, optional
install the gromosXX program, by default True
_timing_dict : dict, optional
structure for storing timings of process, by default {}
verbose : bool, optional
compiling is fun, I can tell you more!, by default True
"""
if root_dir is None:
root_dir = os.path.dirname(__file__)
if do_clean:
if _do_gromosPP:
if verbose:
print(spacer + "\n CLEAN GROMOSPP \n" + spacer)
gromosPP_path = root_dir + "/gromosPlsPls/gromos++"
gromosPP_build_path = gromosPP_path + "/build"
if os.path.exists(gromosPP_build_path):
_timing_dict["gromosPP_clean_start"] = datetime.now()
_make_clean(gromosPP_build_path, verbose=verbose)
_timing_dict["gromosPP_clean_end"] = datetime.now()
if _do_gromosXX:
if verbose:
print(spacer + "\n CLEAN GROMOSXX \n" + spacer)
gromosXX_path = root_dir + "/gromosXX/gromosXX"
gromosXX_build_path = gromosXX_path + "/build"
if os.path.exists(gromosXX_build_path):
_timing_dict["gromosXX_clean_start"] = datetime.now()
_make_clean(gromosXX_build_path, verbose=verbose)
_timing_dict["gromosXX_clean_end"] = datetime.now()
if do_compile:
binary_dir = root_dir + "/bin"
if _do_gromosXX:
if verbose:
print(spacer + "\n BUILD GROMOSXX \n" + spacer)
gromosXX_path = root_dir + "/gromosXX/gromosXX"
gromosXX_build_path = gromosXX_path + "/build"
if not os.path.exists(gromosXX_build_path) or recompile_from_scratch:
_configure_gromosXX_autotools(
build_dir=gromosXX_build_path,
binary_dir=binary_dir,
with_mpi=gromosXX_with_mpi,
with_omp=gromosXX_with_omp,
with_cuda_dir=gromosXX_with_cuda,
with_debug=gromosXX_with_debug,
verbose=verbose,
)
if not os.path.exists(gromosXX_build_path + "/bin") or recompile or recompile_from_scratch:
_make_compile(
build_dir=gromosXX_build_path,
nCore=nCore,
verbose=verbose,
_timing_dict=_timing_dict,
_timing_prefix="gromosXX_",
)
if _do_gromosPP:
if verbose:
print(spacer + "\n BUILD GROMOSPP \n" + spacer)
gromosPP_path = root_dir + "/gromosPlsPls/gromos++"
gromosPP_build_path = gromosPP_path + "/build"
if not os.path.exists(gromosPP_build_path) or recompile_from_scratch:
_configure_gromosPP_autotools(
build_dir=gromosPP_build_path,
binary_dir=binary_dir,
with_omp=gromosPP_with_omp,
with_debug=gromosPP_with_debug,
verbose=verbose,
)
if not os.path.exists(gromosPP_build_path + "/bin") or recompile or recompile_from_scratch:
_make_compile(
build_dir=gromosPP_build_path,
nCore=nCore,
verbose=verbose,
_timing_dict=_timing_dict,
_timing_prefix="gromosPP_",
)
if verbose:
# TIMINGS Printout
print("\n" + ">" * 10 + " TIMINGS:")
for key, val in _timing_dict.items():
print(key, val)
# get duration
print("\n\n" + ">" * 10 + " duration:")
durations = OrderedDict({})
keys = list(_timing_dict.keys())
for key in keys:
prefix = "_".join(key.split("_")[:-1])
if "start" in key:
print(key)
print(keys)
end_key = list(filter(lambda x: x == (prefix + "_end"), keys))[0]
else:
pass
durations[prefix] = _timing_dict[end_key] - _timing_dict[key]
print(prefix, str(durations[prefix]))
[docs]def _make_compile(
build_dir: str, nCore: int = 1, verbose: bool = True, _timing_dict: dict = {}, _timing_prefix: str = ""
):
"""
This function triggers make and make install in the build_dir.
Parameters
----------
build_dir : str
directory prepared for make.
nCore : int, optional
how many cores for each make command?, by default 1
verbose : bool, optional
make, make things and talk loudly about it! , by default True
_timing_dict : dict, optional
structure for storing timings of process, by default {}
_timing_prefix : str, optional
prefix for timing keys, by default ""
"""
os.chdir(build_dir)
_timing_dict[_timing_prefix + "make_start"] = datetime.now()
log_file = build_dir + "/make.log"
cmd = "make -j" + str(nCore)
# Compile
if verbose:
print(spacer2 + "\t\t> MAKE \n" + spacer2)
print("start time: ", _timing_dict[_timing_prefix + "make_start"])
print("log_file: ", log_file)
print("command: ", cmd, "\n")
bash.execute(cmd, catch_STD=log_file)
_timing_dict[_timing_prefix + "make_end"] = datetime.now()
if verbose:
print(
"duration: ",
str(_timing_dict[_timing_prefix + "make_end"] - _timing_dict[_timing_prefix + "make_start"]),
"\n",
)
# Create Binaries
log_file = build_dir + "/makeInstall.log"
_timing_dict[_timing_prefix + "make_install_start"] = datetime.now()
log_file = build_dir + "/make_install.log"
cmd = "make -j" + str(nCore) + " install"
if verbose:
print(spacer2 + "\t\t> INSTALL \n" + spacer2)
print("start time: ", _timing_dict[_timing_prefix + "make_start"])
print("log_file: ", log_file)
print("command: ", cmd)
bash.execute(cmd, catch_STD=log_file)
_timing_dict[_timing_prefix + "make_install_end"] = datetime.now()
if verbose:
print(
"duration: ",
str(
_timing_dict[_timing_prefix + "make_install_end"] - _timing_dict[_timing_prefix + "make_install_start"]
),
"\n",
)
[docs]def _make_clean(
build_dir: str, nCore: int = 1, verbose: bool = True, _timing_dict: dict = {}, _timing_prefix: str = ""
):
"""
This function triggers make clean and removes the build_dir.
Parameters
----------
build_dir : str
directory prepared for make.
nCore : int, optional
how many cores for each make command?, by default 1
verbose: bool, optional
cleaning, cleaning, every thing gets so shiny and I can sing!, by default True
_timing_dict : dict, optional
structure for storing timings of process, by default {}
_timing_prefix : str, optional
prefix for timing keys, by default ""
"""
os.chdir(build_dir)
cmd = "make -j" + str(nCore) + " clean"
_timing_dict[_timing_prefix + "make_clean_start"] = datetime.now()
if verbose:
print("command: ", cmd)
print("start time: ", _timing_dict[_timing_prefix + "make_clean_start"])
try:
bash.execute(cmd)
except Exception:
pass
if verbose:
print("remove dir: ", build_dir)
bash.remove_file(build_dir, recursive=True)
_timing_dict[_timing_prefix + "make_clean_end"] = datetime.now()
if verbose:
print(
"duration: ",
str(_timing_dict[_timing_prefix + "make_clean_end"] - _timing_dict[_timing_prefix + "make_clean_start"]),
"\n",
)
if __name__ == "__main__": # Main function
# try modifying path if necessary
root_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
sys.path.append(root_dir)
from pygromos.utils.utils import dynamic_parser
args = dynamic_parser(install_gromos, title="Run MD-Worker")
install_gromos(**vars(args))
# default_install(nCores=nCores, verbose=True)