Source code for matador.cli.run3

# coding: utf-8
# Distributed under the terms of the MIT License.

""" Run calculations in a folder with BatchRun
such that there are no clashes.
"""
import os
import argparse
from matador import __version__, script_epilog
from matador.utils.print_utils import print_notify
from matador.utils.errors import InputError
from matador.compute import BatchRun


[docs]def main(): """Parse args and run any remaining jobs.""" parser = argparse.ArgumentParser( prog="run3", description='Run multiple calculations from a series of .res \ files and single cell and param files, typically CASTEP geometry \ optimisations. The geometry optimization will \ be split into "--rough" (default: 4) chunks of "--rough_iter" (default: 2) \ iterations, followed by chunks of "--fine_iter" (default: 20) \ iterations, until geom_max_iter is reached in the param file. \ Successful runs will be moved to "completed", crashes/failures will go to \ "bad_castep" and initial res files will go into "input". Running jobs will \ be listed in jobs.txt and those that completed cleanly will be listed \ in finished_cleanly.txt.', epilog=script_epilog, ) parser.add_argument( "--version", action="version", version="matador version " + __version__ + "." ) parser.add_argument( "seed", type=str, nargs="+", help="cell and param seed to use as template for CASTEP calculations OR list of files\ to apply run executable on", ) parser.add_argument( "-nc", "--ncores", type=int, help="number of cores per node per job [DEFAULT=cpu_count/nprocesses]", ) parser.add_argument( "-np", "--nprocesses", type=int, default=1, help="number of concurrent calculations, i.e. number \ of concurrent mpiruns [DEFAULT=1]", ) parser.add_argument( "-nn", "--nnodes", type=int, default=1, help="number of nodes per job, i.e. number of nodes \ using -nc cores [DEFAULT=1].", ) parser.add_argument( "-t", "--max_walltime", type=int, help="maximum walltime in seconds (job will quit early to clean up if specified)", ) parser.add_argument( "-exec", "--executable", type=str, help="specify path to or name of executable (DEFAULT: castep)", ) parser.add_argument( "--no_reopt", action="store_true", default=False, help="do not run geometry optimisation again after first success", ) parser.add_argument( "--redirect", type=str, help="filename to redirect output to, can use $seed macro", ) parser.add_argument( "--mode", type=str, default="castep", help="either castep or generic" ) parser.add_argument( "--noise", action="store_true", help=( "add 0.1 A of random noise to positions on every cell, " "useful for converging forces (DEFAULT: off)" ), ) parser.add_argument( "--squeeze", action="store_true", help="add external pressure to the rough steps of geom opts", ) parser.add_argument( "--ignore_jobs_file", action="store_true", help="whether to use the jobs.txt file to avoid clashes", ) parser.add_argument( "-d", "--debug", action="store_true", default=False, help="debug output" ) parser.add_argument( "-cust", "--custom_params", action="store_true", default=False, help="use custom param file per structure", ) parser.add_argument( "-v", "--verbosity", type=int, default=2, help="integer to set level of verbosity", ) parser.add_argument( "--archer", action="store_true", default=False, help="use aprun over mpirun" ) parser.add_argument( "--slurm", action="store_true", default=False, help="use srun over mpirun" ) parser.add_argument( "--intel", action="store_true", default=False, help="use Intel's mpirun" ) parser.add_argument( "--conv_cutoff", action="store_true", default=False, help="run all res files at cutoff defined in cutoff.conv file", ) parser.add_argument( "--conv_kpt", action="store_true", default=False, help="run all res files at kpoint spacings defined in kpt.conv file", ) parser.add_argument( "--memcheck", action="store_true", default=False, help="enable memcheck via castep dryrun", ) parser.add_argument( "--scratch_prefix", type=str, help="specify absolute path prefix for compute dir e.g. " "--scratch_prefix /scratch/user/ will set the compute directory to /scratch/user/$hostname. " "default value is taken from .matadorrc.", ) parser.add_argument("--maxmem", type=int, help="override max memory for memcheck") parser.add_argument( "--killcheck", action="store_true", default=True, help="check for $seed.kill file and quit job if present", ) parser.add_argument( "--kpts_1D", action="store_true", default=False, help="recalculate a 1D kpoint mesh of spacing specified in template cell", ) parser.add_argument( "--spin", type=int, nargs="?", const=5, default=None, help=( "if not specified in .cell file, break spin symmetry on first atom using the spin specified by " "the user [DEFAULT: 5]" ), ) parser.add_argument( "--rough", type=int, default=4, help="choose how many <rough_iter> geometry optimizations \ to perform, decrease if lattice is nearly correct. [DEFAULT: 4].", ) parser.add_argument( "--rough_iter", type=int, default=2, help="choose how many relaxation steps per rough geometry optimization\ to perform, [DEFAULT: 2].", ) parser.add_argument( "--fine_iter", type=int, default=20, help="choose how many relaxation steps per fine geometry optimization\ to perform, [DEFAULT: 20].", ) parser.add_argument( "-l", "--limit", type=int, default=None, help="limit to n structures per run" ) parser.add_argument( "--profile", action="store_true", help="profile code with cProfile" ) args = parser.parse_args() seed = vars(args)["seed"] kwargs = vars(args) del kwargs["seed"] from matador.config import load_custom_settings settings = load_custom_settings(debug=kwargs.get("debug")).get("run3") if settings is not None: if kwargs["scratch_prefix"] is None: kwargs["scratch_prefix"] = settings.get("scratch_prefix") if kwargs["scratch_prefix"] == ".": kwargs["scratch_prefix"] = None if kwargs["executable"] is None: kwargs["executable"] = settings.get("castep_executable", "castep") kwargs["run3_settings"] = settings if sum([vars(args)["slurm"], vars(args)["archer"], vars(args)["intel"]]) > 1: exit( "Incompatible MPI arguments specified, please use at most one of --archer/--intel/--slurm." ) if vars(args).get("profile"): import cProfile import pstats from sys import version_info hostname = os.uname()[1] pr = cProfile.Profile() pr.enable() try: runner = BatchRun(seed, **kwargs) runner.spawn() except InputError as exc: print_notify(exc) except RuntimeError: print_notify("Some jobs failed, exiting...") except Exception as exc: raise exc if vars(args).get("profile"): pr.disable() fname = "run3-{}-{}-{}.{}.{}".format( __version__, hostname, version_info.major, version_info.minor, version_info.micro, ) pr.dump_stats(fname + ".prof") with open(fname + ".pstats", "w") as s: sortby = "cumulative" ps = pstats.Stats(pr, stream=s).sort_stats(sortby) ps.print_stats()
if __name__ == "__main__": main()