vyas-group-scripts 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vyas_group_scripts/__init__.py +4 -0
- vyas_group_scripts/gen_batch.py +161 -0
- vyas_group_scripts/run_batch.py +35 -0
- vyas_group_scripts/templates/g16_batch_inputs.py +180 -0
- vyas_group_scripts/templates/orca_batch_inputs.py +315 -0
- vyas_group_scripts-0.3.0.dist-info/METADATA +11 -0
- vyas_group_scripts-0.3.0.dist-info/RECORD +9 -0
- vyas_group_scripts-0.3.0.dist-info/WHEEL +4 -0
- vyas_group_scripts-0.3.0.dist-info/entry_points.txt +4 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
from glob import glob
|
|
2
|
+
from .templates.g16_batch_inputs import simple_g16_template, complex_g16_template
|
|
3
|
+
from .templates.orca_batch_inputs import orca_template, orca_restart_template
|
|
4
|
+
import os
|
|
5
|
+
import argparse
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def process_g16_files(file_pattern="*.gjf",complex = False ,time=os.environ.get("DEFAULT_DFT_TIME") ,num_nodes=os.environ.get("NUM_NODES") ,benchmarking=False):
|
|
10
|
+
|
|
11
|
+
benchmarking_line = ""
|
|
12
|
+
batch_file = simple_g16_template
|
|
13
|
+
if complex:
|
|
14
|
+
batch_file = complex_g16_template
|
|
15
|
+
if benchmarking:
|
|
16
|
+
benchmarking_line = "\n#SBATCH --exclusive"
|
|
17
|
+
|
|
18
|
+
for gjf_file in glob(file_pattern):
|
|
19
|
+
if ".gjf" != gjf_file[-4:]:
|
|
20
|
+
continue
|
|
21
|
+
|
|
22
|
+
bash_file_name = gjf_file[:-4]+".s"
|
|
23
|
+
print(bash_file_name)
|
|
24
|
+
if os.path.exists(bash_file_name):
|
|
25
|
+
print(f"{bash_file_name} already exists, skipping.")
|
|
26
|
+
continue
|
|
27
|
+
|
|
28
|
+
this_file_string = batch_file.format(TIME=time,
|
|
29
|
+
ACTNUM=os.environ.get("ACTNUM"),
|
|
30
|
+
JOB_NAME=gjf_file[:-4],
|
|
31
|
+
TASKS_PER_NODE=1,
|
|
32
|
+
N_TASKS=num_nodes,
|
|
33
|
+
INPUT_FILE_NAME=gjf_file.split("/")[-1][:-4],
|
|
34
|
+
NUM_NODES=num_nodes,
|
|
35
|
+
BENCHMARKING_LINE = benchmarking_line)
|
|
36
|
+
with open(bash_file_name,"w") as bash_file:
|
|
37
|
+
bash_file.write(this_file_string)
|
|
38
|
+
|
|
39
|
+
apply_parallelization(gjf_file,num_nodes)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def process_inp_files(file_pattern="*.inp",complex = False ,time=os.environ.get("DEFAULT_DFT_TIME") ,num_nodes=os.environ.get("NUM_NODES") ,benchmarking=False,restart=False):
|
|
44
|
+
|
|
45
|
+
# Select the bash template
|
|
46
|
+
batch_file = orca_template
|
|
47
|
+
|
|
48
|
+
# Set Benchmarking line
|
|
49
|
+
benchmarking_line = ""
|
|
50
|
+
if benchmarking:
|
|
51
|
+
benchmarking_line = "\n#SBATCH --exclusive"
|
|
52
|
+
|
|
53
|
+
# loop through input files
|
|
54
|
+
for inp_file in glob(file_pattern):
|
|
55
|
+
if ".inp" != inp_file[-4:]:
|
|
56
|
+
continue
|
|
57
|
+
bash_file_name = inp_file[:-4]+".s"
|
|
58
|
+
|
|
59
|
+
if os.path.exists(bash_file_name):
|
|
60
|
+
print(f"{bash_file_name} already exists, skipping.")
|
|
61
|
+
continue
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# Modify bash script
|
|
65
|
+
this_file_string = batch_file.format(TIME=time,
|
|
66
|
+
ACTNUM=os.environ.get("ACTNUM"),
|
|
67
|
+
JOB_NAME=inp_file[:-4],
|
|
68
|
+
TASKS_PER_NODE=1,
|
|
69
|
+
N_TASKS=num_nodes,
|
|
70
|
+
INPUT_FILE_NAME=inp_file.split("/")[-1][:-4],
|
|
71
|
+
NUM_NODES=num_nodes,
|
|
72
|
+
BENCHMARKING_LINE = benchmarking_line)
|
|
73
|
+
with open(bash_file_name,"w") as bash_file:
|
|
74
|
+
bash_file.write(this_file_string)
|
|
75
|
+
|
|
76
|
+
# Add parallelization to input file
|
|
77
|
+
apply_parallelization(inp_file,num_nodes)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def apply_parallelization(input_file,nprocs = 36):
|
|
81
|
+
|
|
82
|
+
if ".gjf" == input_file[-4:]:
|
|
83
|
+
if nprocs != 0:
|
|
84
|
+
print(f"Adding parallelization to {input_file}.")
|
|
85
|
+
with open(input_file,"r") as file:
|
|
86
|
+
file_string = file.read()
|
|
87
|
+
file_string = f"%mem=5GB\n%nprocshared={nprocs}\n"+file_string
|
|
88
|
+
|
|
89
|
+
with open(input_file,"w") as file:
|
|
90
|
+
file.write(file_string)
|
|
91
|
+
|
|
92
|
+
if ".inp" == input_file[-4:]:
|
|
93
|
+
if nprocs != 0:
|
|
94
|
+
if not nprocs in [6,10,30,36]:
|
|
95
|
+
print("invalid nprocs selected.")
|
|
96
|
+
return None
|
|
97
|
+
memory = int(144000/nprocs)
|
|
98
|
+
file_string = f"%maxcore {memory}\n%pal nprocs {nprocs} end\n"
|
|
99
|
+
with open(input_file,"r") as file:
|
|
100
|
+
file_list = file.readlines()
|
|
101
|
+
lastinput_line = 1
|
|
102
|
+
for index,line in enumerate(file_list):
|
|
103
|
+
if len(line.strip())>0 and line.strip()[0] == "!":
|
|
104
|
+
lastinput_line = index
|
|
105
|
+
file_list.insert(lastinput_line+1,file_string)
|
|
106
|
+
with open(input_file,"w") as file:
|
|
107
|
+
file.writelines(file_list)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def gen_all_batch():
|
|
120
|
+
|
|
121
|
+
parser = argparse.ArgumentParser(prog="gab")
|
|
122
|
+
parser.add_argument("-t",default=os.environ.get("DEFAULT_DFT_TIME"),help="Set the time limit for the batch script (format: HH:MM:SS)." \
|
|
123
|
+
" If not specified, the default from the DFT_DEFAULT_TIME environment variable is used.")
|
|
124
|
+
parser.add_argument("-b",action="store_true",help="Enable benchmarking mode. This sets the node allocation" \
|
|
125
|
+
" to exclusive to ensure consistent performance for benchmarking runs.")
|
|
126
|
+
parser.add_argument("-k",default="*",help="Provide a comma seperated regex pattern to match input files. " \
|
|
127
|
+
"Only batch files for matching input files will be generated.\nExample: -k 'xyz,*mol' (quotes reccomended)")
|
|
128
|
+
parser.add_argument("-p",default=-1,type=int,choices=[0,6,10,30,36],help="Specify the number of processors to use"\
|
|
129
|
+
" Acceptable values 36, 30, 10, 6, or 0." \
|
|
130
|
+
" Memory sttings will be adjusted based on this value. Use 0 to skip adding parallelization directives entirely." \
|
|
131
|
+
" When the -p flag is not called the default options in DFT_DEFAULT_MEM and DFT_DEFAULT_PROCESSORS environment variables" \
|
|
132
|
+
" are used for all calculations.\n\tOrca jobs:\n\t\tInsert content after first '!' in input file.\n\tGaussian Jobs:\n\t\tAppends" \
|
|
133
|
+
" parralleliszation options to the top of input file\n\t\tOnly '36' and '0' options are available for gaussian jobs.")
|
|
134
|
+
parser.add_argument("-r",default="*",help="Restart ORCA jobs from one or more specified folders. Provide a comma-seperated list of" \
|
|
135
|
+
" folder names.\n\tExample: -r 'job1_TIMEOUT,job2_TIMEOUT")
|
|
136
|
+
parser.add_argument("-v",default=None,help="Specify the quantum chemistry software version to use." \
|
|
137
|
+
" Currently only downgrading to ORCA 5 is supported.")
|
|
138
|
+
parser.add_argument("-c",action="store_false",help="Uses a more simple .s file for gaussian jobs that does not create a bunch of subdirectories.")
|
|
139
|
+
args = parser.parse_args()
|
|
140
|
+
|
|
141
|
+
patterns_to_search = args.k.split(",")
|
|
142
|
+
complex_choice = args.c
|
|
143
|
+
time_choice = args.t
|
|
144
|
+
processors_choice = args.p
|
|
145
|
+
benchmarking_choice = args.b
|
|
146
|
+
orca_version = args.v
|
|
147
|
+
restarts = args.r
|
|
148
|
+
if processors_choice == -1:
|
|
149
|
+
processors_choice = os.environ.get("DEFAULT_DFT_NUM_NODES")
|
|
150
|
+
|
|
151
|
+
for file_pattern in patterns_to_search:
|
|
152
|
+
|
|
153
|
+
for file in glob(file_pattern):
|
|
154
|
+
|
|
155
|
+
process_g16_files(file,complex_choice,time_choice,processors_choice,benchmarking_choice)
|
|
156
|
+
process_inp_files(file,complex_choice,time_choice,processors_choice,benchmarking_choice)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
if __name__ == "__main__":
|
|
161
|
+
gen_all_batch()
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from glob import glob
|
|
3
|
+
from rich import print
|
|
4
|
+
import argparse
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def check_file_has_pair(s_file:str):
|
|
8
|
+
print(f"Checking {s_file}")
|
|
9
|
+
if os.path.exists(s_file[:-1]+"inp"):
|
|
10
|
+
return True
|
|
11
|
+
if os.path.exists(s_file[:-1]+"gjf"):
|
|
12
|
+
return True
|
|
13
|
+
print(f"[red]Matching file not found for {s_file}")
|
|
14
|
+
return False
|
|
15
|
+
|
|
16
|
+
def submit_job_pattern(sfile_pattern:str="*.s"):
|
|
17
|
+
for s_file in glob(sfile_pattern):
|
|
18
|
+
if check_file_has_pair(s_file):
|
|
19
|
+
os.system(f"sbatch {s_file}")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def run_all_batch():
|
|
23
|
+
|
|
24
|
+
parser = argparse.ArgumentParser(prog="rab")
|
|
25
|
+
parser.add_argument("-k",default="*.s",help="provide a regesx pattern for .s files to submit")
|
|
26
|
+
|
|
27
|
+
args = parser.parse_args()
|
|
28
|
+
|
|
29
|
+
patterns_to_submit = args.k
|
|
30
|
+
|
|
31
|
+
submit_job_pattern(patterns_to_submit)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
if __name__ == "__main__":
|
|
35
|
+
run_all_batch()
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
|
|
2
|
+
##################################################
|
|
3
|
+
# This a simple g16 batch file template python
|
|
4
|
+
# Is responsible for feeding in the following
|
|
5
|
+
# information:
|
|
6
|
+
# JOB_NAME
|
|
7
|
+
# ACTNUM
|
|
8
|
+
# NUM_NODES
|
|
9
|
+
# TASKS_PER_NODE
|
|
10
|
+
# N_TASKS
|
|
11
|
+
# INPUT_FILE_NAME
|
|
12
|
+
# TIME
|
|
13
|
+
##################################################
|
|
14
|
+
simple_g16_template = """#!/bin/bash -x
|
|
15
|
+
|
|
16
|
+
#SBATCH --job-name={JOB_NAME}
|
|
17
|
+
#SBATCH --account={ACTNUM} # you can find the account number by running $ sacctmgr show Account
|
|
18
|
+
#SBATCH --nodes={NUM_NODES}
|
|
19
|
+
#SBATCH --ntasks-per-node={TASKS_PER_NODE}
|
|
20
|
+
#SBATCH --ntasks={N_TASKS}
|
|
21
|
+
#SBATCH --export=ALL
|
|
22
|
+
#SBATCH --time={TIME} # time when job will automatically terminate- want the smallest possible overestimate{BENCHMARKING_LINE}
|
|
23
|
+
|
|
24
|
+
export KMP_AFFINITY=respect,verbose
|
|
25
|
+
|
|
26
|
+
module load apps/gaussian16/c01
|
|
27
|
+
|
|
28
|
+
cd $SLURM_SUBMIT_DIR
|
|
29
|
+
|
|
30
|
+
eval "$VGS_LOAD_G16"
|
|
31
|
+
INPUT_FILE="{INPUT_FILE_NAME}"
|
|
32
|
+
|
|
33
|
+
OUTPUT_FILE="${{INPUT_FILE: 0:-4}}.log"
|
|
34
|
+
|
|
35
|
+
JOBID=`echo $SLURM_JOBID`
|
|
36
|
+
|
|
37
|
+
#export OMP_NUM_THREADS=1
|
|
38
|
+
#export GAUSS_EXEDIR=/opt/g09/g09
|
|
39
|
+
|
|
40
|
+
echo "Running Job"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
g16 <"${{INPUT_FILE}}">"${{OUTPUT_FILE}}"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
echo "job has finished" """
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
##################################################
|
|
51
|
+
# This a more complex g16 batch file template python
|
|
52
|
+
# Is responsible for feeding in the following
|
|
53
|
+
# information:
|
|
54
|
+
# JOB_NAME
|
|
55
|
+
# ACTNUM
|
|
56
|
+
# NUM_NODES
|
|
57
|
+
# TASKS_PER_NODE
|
|
58
|
+
# N_TASKS
|
|
59
|
+
# INPUT_FILE_NAME
|
|
60
|
+
# TIME
|
|
61
|
+
##################################################
|
|
62
|
+
|
|
63
|
+
complex_g16_template = """#!/bin/bash -x
|
|
64
|
+
|
|
65
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
66
|
+
#
|
|
67
|
+
# This script will submit the input file specified to Gaussian 16 via the slurm scheduler. The script will
|
|
68
|
+
# automatically create a new output directory with the same title as the input file and send all files there.
|
|
69
|
+
# Script timing will be recorded in the slurm.out file which will be copied to the output directory only when
|
|
70
|
+
# the job has completed. Email status updates will be sent if configured in the config.toml.
|
|
71
|
+
#
|
|
72
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
# must set the account number as an env variable manually - gab will automatically use this
|
|
75
|
+
#SBATCH --account={ACTNUM} # you can find the account number by running $ sacctmgr show Account
|
|
76
|
+
#SBATCH --nodes={NUM_NODES}
|
|
77
|
+
#SBATCH --ntasks-per-node={TASKS_PER_NODE}
|
|
78
|
+
#SBATCH --ntasks={N_TASKS}
|
|
79
|
+
#SBATCH --export=ALL
|
|
80
|
+
#SBATCH --time={TIME} # time when job will automatically terminate- want the smallest possible overestimate{BENCHMARKING_LINE}
|
|
81
|
+
maxtime=3590 # buffer time to allow cleanup, should be ~10 seconds less than auto termination time
|
|
82
|
+
|
|
83
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
84
|
+
|
|
85
|
+
INPUT_FILE="{INPUT_FILE_NAME}"
|
|
86
|
+
|
|
87
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
88
|
+
|
|
89
|
+
# record submission time
|
|
90
|
+
mystart=$(date +%Y-%m-%d %H:%M:%S)
|
|
91
|
+
|
|
92
|
+
# make a new output folder with the job name as the title and direct the output there
|
|
93
|
+
OUTPUT_DIR="${{SLURM_SUBMIT_DIR}}/${{SLURM_JOB_NAME: 0:-2}}"
|
|
94
|
+
mkdir -p "${{OUTPUT_DIR}}_IN-PROGRESS"
|
|
95
|
+
|
|
96
|
+
# copy the input file to the output folder and delete the copy in the submit directory
|
|
97
|
+
cp "${{SLURM_SUBMIT_DIR}}/${{INPUT_FILE}}" "${{OUTPUT_DIR}}_IN-PROGRESS/${{INPUT_FILE}}"
|
|
98
|
+
rm "${{SLURM_SUBMIT_DIR}}/${{INPUT_FILE}}"
|
|
99
|
+
|
|
100
|
+
# copy the input script to the output folder and delete the copy in the submit directory
|
|
101
|
+
cp "${{SLURM_SUBMIT_DIR}}/${{SLURM_JOB_NAME}}" "${{OUTPUT_DIR}}_IN-PROGRESS/${{SLURM_JOB_NAME}}"
|
|
102
|
+
rm "${{SLURM_SUBMIT_DIR}}/${{SLURM_JOB_NAME}}"
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# configure KMP_AFFINITY to communicate hardware threads to OMP parallelizer
|
|
106
|
+
export KMP_AFFINITY=respect,verbose
|
|
107
|
+
|
|
108
|
+
# load the gaussian module and print JOBID to slurm out for debugging
|
|
109
|
+
eval "$VGS_LOAD_G16"
|
|
110
|
+
JOBID=`echo $SLURM_JOBID`
|
|
111
|
+
|
|
112
|
+
# configure and pass OMP parameters
|
|
113
|
+
#export OMP_NUM_THREADS=1
|
|
114
|
+
#export GAUSS_EXEDIR=/opt/g09/g09
|
|
115
|
+
|
|
116
|
+
# go the output folder
|
|
117
|
+
cd "${{OUTPUT_DIR}}_IN-PROGRESS"
|
|
118
|
+
|
|
119
|
+
# run the input file and generate an output file of the same name
|
|
120
|
+
# if the timeout is reached it will return exit 124, otherwise it returns the calc exit status
|
|
121
|
+
start=`date +%s.%N`
|
|
122
|
+
OUTPUT_FILE="${{INPUT_FILE: 0:-4}}.log"
|
|
123
|
+
timeout -s SIGTERM $maxtime g16 <"${{OUTPUT_DIR}}_IN-PROGRESS/${{INPUT_FILE}}">"${{OUTPUT_FILE}}"
|
|
124
|
+
CALC_STATUS=$?
|
|
125
|
+
end=`date +%s.%N`
|
|
126
|
+
|
|
127
|
+
# get the job status
|
|
128
|
+
if [[ $CALC_STATUS == 124 ]]; then
|
|
129
|
+
status="TIMEOUT"
|
|
130
|
+
elif [[ $CALC_STATUS != 0 ]]; then
|
|
131
|
+
status="ERROR"
|
|
132
|
+
elif [[ $CALC_STATUS == 0 ]]; then
|
|
133
|
+
status="NORMAL"
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
# log the time for benchmarking in the outputfile
|
|
137
|
+
runtime=$( echo "$end - $start" | bc -l )
|
|
138
|
+
echo $runtime
|
|
139
|
+
exec 3>>"${{OUTPUT_FILE}}"
|
|
140
|
+
echo "">&3
|
|
141
|
+
echo "slurmID: ${{SLURM_JOBID}}">&3
|
|
142
|
+
echo "totalRuntime[s]: ${{runtime}}">&3
|
|
143
|
+
exec 3>&-
|
|
144
|
+
|
|
145
|
+
# get the number of basis functions used in the first calculation
|
|
146
|
+
myBasis=$(grep -o -m 1 '[0-9]\+ basis functions' myFile | cut -d ' ' -f 1)
|
|
147
|
+
myBasis=($myBasis)
|
|
148
|
+
|
|
149
|
+
# record the completion time
|
|
150
|
+
myend=$(date +%Y-%m-%d %H:%M:%S)
|
|
151
|
+
|
|
152
|
+
# write the total job timing to the job_timings file in the submit directory as a CSV
|
|
153
|
+
cd "${{SLURM_SUBMIT_DIR}}"
|
|
154
|
+
if [ ! -f job_timings.csv ]; then
|
|
155
|
+
echo "filename,slurmID,nbasisfuncs,start,end,runtime[s],jobstatus" > job_timings.csv
|
|
156
|
+
fi
|
|
157
|
+
exec 3>>job_timings.csv
|
|
158
|
+
echo "${{INPUT_FILE}},${{SLURM_JOBID}},${{myBasis}},${{mystart}},${{myend}},${{runtime}},${{status}}">&3
|
|
159
|
+
exec 3>&-
|
|
160
|
+
|
|
161
|
+
# copy the slurm output to the output folder and delete from the submit directory
|
|
162
|
+
cp "${{SLURM_SUBMIT_DIR}}/slurm-${{SLURM_JOBID}}.out" "${{OUTPUT_DIR}}_IN-PROGRESS/slurm-${{SLURM_JOBID}}-${{INPUT_FILE: 0:-4}}.out"
|
|
163
|
+
rm "${{SLURM_SUBMIT_DIR}}/slurm-${{SLURM_JOBID}}.out"
|
|
164
|
+
|
|
165
|
+
# rename the output directory appropriately
|
|
166
|
+
if [[ $CALC_STATUS == 124 ]]; then
|
|
167
|
+
|
|
168
|
+
mv "${{OUTPUT_DIR}}_IN-PROGRESS" "${{OUTPUT_DIR}}_TIMEOUT"
|
|
169
|
+
exit 124
|
|
170
|
+
|
|
171
|
+
elif [[ $CALC_STATUS != 0 ]]; then
|
|
172
|
+
|
|
173
|
+
mv "${{OUTPUT_DIR}}_IN-PROGRESS" "${{OUTPUT_DIR}}_ERROR"
|
|
174
|
+
exit 2
|
|
175
|
+
|
|
176
|
+
elif [[ $CALC_STATUS == 0 ]]; then
|
|
177
|
+
|
|
178
|
+
mv "${{OUTPUT_DIR}}_IN-PROGRESS" "${{OUTPUT_DIR}}"
|
|
179
|
+
exit 0
|
|
180
|
+
fi"""
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
orca_template = """#!/bin/bash -x
|
|
2
|
+
|
|
3
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
4
|
+
#
|
|
5
|
+
# This script will submit the input file specified to ORCA via the slurm scheduler. The script will automatically
|
|
6
|
+
# create a new output directory with the same title as the input file and send all files there. Script timing
|
|
7
|
+
# will be recorded in the slurm.out file which will be copied to the output directory only when the job has
|
|
8
|
+
# completed. Email status updates will be sent if configured in the config.toml.
|
|
9
|
+
#
|
|
10
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
# must set the account number as an env variable manually - gab will automatically use this
|
|
13
|
+
#SBATCH --account={ACTNUM} # you can find the account number by running $ sacctmgr show Account
|
|
14
|
+
#SBATCH --nodes={NUM_NODES}
|
|
15
|
+
#SBATCH --ntasks-per-node={TASKS_PER_NODE}
|
|
16
|
+
#SBATCH --ntasks={N_TASKS}
|
|
17
|
+
#SBATCH --export=ALL
|
|
18
|
+
#SBATCH --time={TIME} # time when job will automatically terminate- want the smallest possible overestimate{BENCHMARKING_LINE}
|
|
19
|
+
maxtime=3590 # buffer time to allow cleanup, should be ~10 seconds less than auto termination time
|
|
20
|
+
|
|
21
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
INPUT_FILE="{INPUT_FILE_NAME}"
|
|
24
|
+
|
|
25
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
ml purge
|
|
28
|
+
|
|
29
|
+
# record submission time
|
|
30
|
+
mystart=$(date +%Y-%m-%d %H:%M:%S)
|
|
31
|
+
|
|
32
|
+
# make a new output folder with the job name as the title and direct the output there
|
|
33
|
+
OUTPUT_DIR="${{SLURM_SUBMIT_DIR}}/${{SLURM_JOB_NAME: 0:-2}}"
|
|
34
|
+
mkdir -p "${{OUTPUT_DIR}}_IN-PROGRESS"
|
|
35
|
+
|
|
36
|
+
# copy the input orca file to the output folder and delete the copy in the submit directory
|
|
37
|
+
cp "${{SLURM_SUBMIT_DIR}}/${{INPUT_FILE}}" "${{OUTPUT_DIR}}_IN-PROGRESS/${{INPUT_FILE}}"
|
|
38
|
+
rm "${{SLURM_SUBMIT_DIR}}/${{INPUT_FILE}}"
|
|
39
|
+
|
|
40
|
+
# copy the input xyz file to the output folder and delete the copy in the submit directory
|
|
41
|
+
cp "${{SLURM_SUBMIT_DIR}}/${{SLURM_JOB_NAME: 0:-2}}.xyz" "${{OUTPUT_DIR}}_IN-PROGRESS/${{SLURM_JOB_NAME: 0:-2}}.xyz" || echo "NO XYZ INPUT FOR THIS JOB"
|
|
42
|
+
rm "${{SLURM_SUBMIT_DIR}}/${{SLURM_JOB_NAME: 0:-2}}.xyz" || echo "NO XYZ FILE TO REMOVE"
|
|
43
|
+
|
|
44
|
+
# copy the input script to the output folder and delete the copy in the submit directory
|
|
45
|
+
cp "${{SLURM_SUBMIT_DIR}}/${{SLURM_JOB_NAME}}" "${{OUTPUT_DIR}}_IN-PROGRESS/${{SLURM_JOB_NAME}}"
|
|
46
|
+
rm "${{SLURM_SUBMIT_DIR}}/${{SLURM_JOB_NAME}}"
|
|
47
|
+
|
|
48
|
+
# load and export NBO path
|
|
49
|
+
eval "$VGS_LOAD_NBO"
|
|
50
|
+
|
|
51
|
+
# load ORCA path
|
|
52
|
+
eval "$VGS_LOAD_ORCA"
|
|
53
|
+
|
|
54
|
+
# load the mpi module and print JOBID to slurm out for debugging
|
|
55
|
+
eval "$VGS_LOAD_MPI"
|
|
56
|
+
JOBID=`echo $SLURM_JOBID`
|
|
57
|
+
|
|
58
|
+
# configure and pass OMP parameters
|
|
59
|
+
#export OMP_NUM_THREADS=1
|
|
60
|
+
|
|
61
|
+
# go the output folder
|
|
62
|
+
cd "${{OUTPUT_DIR}}_IN-PROGRESS"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
#################################################################################################
|
|
66
|
+
# run the input file and generate an output file of the same name
|
|
67
|
+
# if the timeout is reached it will return exit 124, otherwise it returns the calc exit status
|
|
68
|
+
start=`date +%s.%N`
|
|
69
|
+
OUTPUT_FILE="${{INPUT_FILE: 0:-4}}.out"
|
|
70
|
+
timeout -s SIGTERM $maxtime $VGS_ORCA_PATH "${{OUTPUT_DIR}}_IN-PROGRESS/${{INPUT_FILE}}">"${{OUTPUT_FILE}}"
|
|
71
|
+
CALC_STATUS=$?
|
|
72
|
+
end=`date +%s.%N`
|
|
73
|
+
#################################################################################################
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# try to generate the orbital *.cube files and *.html files if the ORCA job was successful
|
|
77
|
+
# also try to extract the NBO output (not always called, will pass if no NBO)
|
|
78
|
+
if [[ $CALC_STATUS == 0 ]]; then
|
|
79
|
+
cubegen="${{VGSPATH}}/orca_orbital_cubegen.s"
|
|
80
|
+
chmod +x "${{cubegen}}"
|
|
81
|
+
"${{cubegen}}" -f "${{INPUT_FILE: 0:-4}}.gbw" || echo "MO VISUALIZATION FAILED"
|
|
82
|
+
|
|
83
|
+
sed -n '/Now starting NBO\.\.\./,/returned from NBO program/p' "${{OUTPUT_FILE}}" | tail -n +2 | head -n -1 > "${{INPUT_FILE: 0:-4}}.nbout" || echo "NBO SCRAPING FAILED"
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# get the job status
|
|
88
|
+
# get the job status
|
|
89
|
+
if [[ $CALC_STATUS == 124 ]]; then
|
|
90
|
+
status="TIMEOUT"
|
|
91
|
+
elif [[ $CALC_STATUS != 0 ]]; then
|
|
92
|
+
status="ERROR"
|
|
93
|
+
elif [[ $CALC_STATUS == 0 ]]; then
|
|
94
|
+
# check if the words "ORCA TERMINATED NORMALLY" appear in the last 10 lines of the output file
|
|
95
|
+
if tail -n 10 "$OUTPUT_FILE" | grep -q "****ORCA TERMINATED NORMALLY****"; then
|
|
96
|
+
status="NORMAL"
|
|
97
|
+
else
|
|
98
|
+
CALC_STATUS=2
|
|
99
|
+
status="INCOMPLETE"
|
|
100
|
+
fi
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# log the time for benchmarking in the outputfile
|
|
105
|
+
runtime=$( echo "$end - $start" | bc -l )
|
|
106
|
+
echo $runtime
|
|
107
|
+
exec 3>>"${{OUTPUT_FILE}}"
|
|
108
|
+
echo "">&3
|
|
109
|
+
echo "slurmID: ${{SLURM_JOBID}}">&3
|
|
110
|
+
echo "totalRuntime[s]: ${{runtime}}">&3
|
|
111
|
+
exec 3>&-
|
|
112
|
+
|
|
113
|
+
# get the number of basis functions used in the first calculation by the SHARK package
|
|
114
|
+
myBasis=$(grep -m 1 "Number of basis functions" "${{OUTPUT_FILE}}" | awk '{{print $NF}}' | tr -d '[:space:]')
|
|
115
|
+
myBasis=($myBasis)
|
|
116
|
+
|
|
117
|
+
# record the completion time
|
|
118
|
+
myend=$(date +%Y-%m-%d %H:%M:%S)
|
|
119
|
+
|
|
120
|
+
# write the total job timing to the job_timings file in the submit directory as a CSV
|
|
121
|
+
cd "${{SLURM_SUBMIT_DIR}}"
|
|
122
|
+
if [ ! -f job_timings.csv ]; then
|
|
123
|
+
echo "filename,slurmID,nbasisfuncs,start,end,runtime[s],jobstatus" > job_timings.csv
|
|
124
|
+
fi
|
|
125
|
+
exec 3>>job_timings.csv
|
|
126
|
+
echo "${{INPUT_FILE}},${{SLURM_JOBID}},${{myBasis}},${{mystart}},${{myend}},${{runtime}},${{status}}">&3
|
|
127
|
+
exec 3>&-
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# copy the slurm output to the output folder and delete from the submit directory
|
|
132
|
+
cp "${{SLURM_SUBMIT_DIR}}/slurm-${{SLURM_JOBID}}.out" "${{OUTPUT_DIR}}_IN-PROGRESS/slurm-${{SLURM_JOBID}}-${{INPUT_FILE: 0:-4}}.out"
|
|
133
|
+
rm "${{SLURM_SUBMIT_DIR}}/slurm-${{SLURM_JOBID}}.out"
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
# rename the output directory appropriately
|
|
137
|
+
if [[ $status == "TIMEOUT" ]]; then
|
|
138
|
+
|
|
139
|
+
mv "${{OUTPUT_DIR}}_IN-PROGRESS" "${{OUTPUT_DIR}}_TIMEOUT"
|
|
140
|
+
exit 124
|
|
141
|
+
|
|
142
|
+
elif [[ $status == "ERROR" ]]; then
|
|
143
|
+
|
|
144
|
+
mv "${{OUTPUT_DIR}}_IN-PROGRESS" "${{OUTPUT_DIR}}_ERROR"
|
|
145
|
+
exit 2
|
|
146
|
+
|
|
147
|
+
elif [[ $status == "INCOMPLETE" ]]; then
|
|
148
|
+
|
|
149
|
+
mv "${{OUTPUT_DIR}}_IN-PROGRESS" "${{OUTPUT_DIR}}_INCOMPLETE"
|
|
150
|
+
exit 2
|
|
151
|
+
|
|
152
|
+
elif [[ $status == "NORMAL" ]]; then
|
|
153
|
+
|
|
154
|
+
mv "${{OUTPUT_DIR}}_IN-PROGRESS" "${{OUTPUT_DIR}}"
|
|
155
|
+
cd "${{OUTPUT_DIR}}"
|
|
156
|
+
# cleanup empty files
|
|
157
|
+
if [[ -e "2" && ! -s "2" ]]; then
|
|
158
|
+
rm "2"
|
|
159
|
+
fi
|
|
160
|
+
for nbout_file in *.nbout; do
|
|
161
|
+
if [[ -e "$nbout_file" && ! -s "$nbout_file" ]]; then
|
|
162
|
+
rm "${{nbout_file}}"
|
|
163
|
+
fi
|
|
164
|
+
done
|
|
165
|
+
cd ..
|
|
166
|
+
|
|
167
|
+
exit 0
|
|
168
|
+
fi"""
|
|
169
|
+
|
|
170
|
+
orca_restart_template = """#!/bin/bash -x
|
|
171
|
+
|
|
172
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
173
|
+
#
|
|
174
|
+
# This script will re-submit the input file specified to ORCA via the slurm scheduler. This script automatically
|
|
175
|
+
# edits the last input file to ensure that the previous geometry and wavefunction is read. All output will be
|
|
176
|
+
# generated in the same directory as the original calculation that timed out. Script timing will be recorded in
|
|
177
|
+
# the slurm.out file which will be copied to the original output directory only when the job has completed. Email
|
|
178
|
+
# status updates will be sent if configured in the config.toml.
|
|
179
|
+
#
|
|
180
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
181
|
+
|
|
182
|
+
# must set the account number as an env variable manually - gab will automatically use this
|
|
183
|
+
#SBATCH --account={ACTNUM} # you can find the account number by running $ sacctmgr show Account
|
|
184
|
+
#SBATCH --nodes={NUM_NODES}
|
|
185
|
+
#SBATCH --ntasks-per-node={TASKS_PER_NODE}
|
|
186
|
+
#SBATCH --ntasks={N_TASKS}
|
|
187
|
+
#SBATCH --export=ALL
|
|
188
|
+
#SBATCH --time={TIME} # time when job will automatically terminate- want the smallest possible overestimate{BENCHMARKING_LINE}
|
|
189
|
+
maxtime=3590 # buffer time to allow cleanup, should be ~10 seconds less than auto termination time
|
|
190
|
+
|
|
191
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
192
|
+
|
|
193
|
+
INPUT_FILE="{INPUT_FILE_NAME}"
|
|
194
|
+
OLD_JOB_DIR="my_old_job"
|
|
195
|
+
|
|
196
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
197
|
+
|
|
198
|
+
# record submission time
|
|
199
|
+
mystart=$(date +%Y-%m-%d %H:%M:%S)
|
|
200
|
+
|
|
201
|
+
# make a new output folder with the job name as the title and direct the output there
|
|
202
|
+
OUTPUT_DIR="${{SLURM_SUBMIT_DIR}}/${{OLD_JOB_DIR}}"
|
|
203
|
+
mv "${{OUTPUT_DIR}}" "${{OUTPUT_DIR}}_RESTARTED"
|
|
204
|
+
|
|
205
|
+
# copy the input script to the output folder and delete the copy in the submit directory
|
|
206
|
+
cp "${{SLURM_SUBMIT_DIR}}/${{SLURM_JOB_NAME}}" "${{OUTPUT_DIR}}_RESTARTED/${{SLURM_JOB_NAME}}"
|
|
207
|
+
rm "${{SLURM_SUBMIT_DIR}}/${{SLURM_JOB_NAME}}"
|
|
208
|
+
cp "${{SLURM_SUBMIT_DIR}}/${{INPUT_FILE}}" "${{OUTPUT_DIR}}_RESTARTED/${{INPUT_FILE}}"
|
|
209
|
+
rm "${{SLURM_SUBMIT_DIR}}/${{INPUT_FILE}}"
|
|
210
|
+
|
|
211
|
+
# load and export NBO path
|
|
212
|
+
eval "$VGS_LOAD_NBO"
|
|
213
|
+
|
|
214
|
+
# load the mpi module and print JOBID to slurm out for debugging
|
|
215
|
+
eval "$VGS_LOAD_MPI"
|
|
216
|
+
JOBID=`echo $SLURM_JOBID`
|
|
217
|
+
|
|
218
|
+
# go the output folder
|
|
219
|
+
cd "${{OUTPUT_DIR}}_RESTARTED"
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
#################################################################################################
|
|
223
|
+
# run the input file and generate an output file of the same name
|
|
224
|
+
# if the timeout is reached it will return exit 124, otherwise it returns the calc exit status
|
|
225
|
+
start=`date +%s.%N`
|
|
226
|
+
OUTPUT_FILE="${{INPUT_FILE: 0:-4}}.out"
|
|
227
|
+
timeout -s SIGTERM $maxtime $SS_ORCA_PATH "${{OUTPUT_DIR}}_RESTARTED/${{INPUT_FILE}}">"${{OUTPUT_FILE}}"
|
|
228
|
+
CALC_STATUS=$?
|
|
229
|
+
end=`date +%s.%N`
|
|
230
|
+
#################################################################################################
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
# try to generate the orbital *.cube files and *.html files if the ORCA job was successful
|
|
234
|
+
# also try to extract the NBO output (not always called, will pass if no NBO)
|
|
235
|
+
if [[ $CALC_STATUS == 0 ]]; then
|
|
236
|
+
cubegen="${{VGSPATH}}/orca_orbital_cubegen.s"
|
|
237
|
+
chmod +x "${{cubegen}}"
|
|
238
|
+
"${{cubegen}}" -f "${{INPUT_FILE: 0:-4}}.gbw" || echo "MO VISUALIZATION FAILED"
|
|
239
|
+
|
|
240
|
+
sed -n '/Now starting NBO\.\.\./,/returned from NBO program/p' "${{OUTPUT_FILE}}" | tail -n +2 | head -n -1 > "${{INPUT_FILE: 0:-4}}.nbout" || echo "NBO SCRAPING FAILED"
|
|
241
|
+
fi
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
# get the job status
|
|
245
|
+
if [[ $CALC_STATUS == 124 ]]; then
|
|
246
|
+
status="TIMEOUT"
|
|
247
|
+
elif [[ $CALC_STATUS != 0 ]]; then
|
|
248
|
+
status="ERROR"
|
|
249
|
+
elif [[ $CALC_STATUS == 0 ]]; then
|
|
250
|
+
status="NORMAL"
|
|
251
|
+
fi
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
# log the time for benchmarking in the outputfile
|
|
255
|
+
runtime=$( echo "$end - $start" | bc -l )
|
|
256
|
+
echo $runtime
|
|
257
|
+
exec 3>>"${{OUTPUT_FILE}}"
|
|
258
|
+
echo "">&3
|
|
259
|
+
echo "slurmID: ${{SLURM_JOBID}}">&3
|
|
260
|
+
echo "totalRuntime[s]: ${{runtime}}">&3
|
|
261
|
+
exec 3>&-
|
|
262
|
+
|
|
263
|
+
# get the number of basis functions used in the first calculation by the SHARK package
|
|
264
|
+
myBasis=$(grep -m 1 "Number of basis functions" "${{OUTPUT_FILE}}" | awk '{{print $NF}}' | tr -d '[:space:]')
|
|
265
|
+
myBasis=($myBasis)
|
|
266
|
+
|
|
267
|
+
# record the completion time
|
|
268
|
+
myend=$(date +%Y-%m-%d %H:%M:%S)
|
|
269
|
+
|
|
270
|
+
# write the total job timing to the job_timings file in the submit directory as a CSV
|
|
271
|
+
cd "${{SLURM_SUBMIT_DIR}}"
|
|
272
|
+
if [ ! -f job_timings.csv ]; then
|
|
273
|
+
echo "filename,slurmID,nbasisfuncs,start,end,runtime[s],jobstatus" > job_timings.csv
|
|
274
|
+
fi
|
|
275
|
+
exec 3>>job_timings.csv
|
|
276
|
+
echo "${{INPUT_FILE}},${{SLURM_JOBID}},${{myBasis}},${{mystart}},${{myend}},${{runtime}},${{status}}">&3
|
|
277
|
+
exec 3>&-
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
# copy the slurm output to the output folder and delete from the submit directory
|
|
282
|
+
cp "${{SLURM_SUBMIT_DIR}}/slurm-${{SLURM_JOBID}}.out" "${{OUTPUT_DIR}}_RESTARTED/slurm-${{SLURM_JOBID}}-${{INPUT_FILE: 0:-4}}.out"
|
|
283
|
+
rm "${{SLURM_SUBMIT_DIR}}/slurm-${{SLURM_JOBID}}.out"
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
# rename the output directory appropriately
|
|
287
|
+
if [[ $CALC_STATUS == 124 ]]; then
|
|
288
|
+
|
|
289
|
+
mv "${{OUTPUT_DIR}}_RESTARTED" "${{OUTPUT_DIR}}_TIMEOUT"
|
|
290
|
+
exit 124
|
|
291
|
+
|
|
292
|
+
elif [[ $CALC_STATUS != 0 ]]; then
|
|
293
|
+
|
|
294
|
+
mv "${{OUTPUT_DIR}}_RESTARTED" "${{OUTPUT_DIR}}_ERROR"
|
|
295
|
+
exit 2
|
|
296
|
+
|
|
297
|
+
elif [[ $CALC_STATUS == 0 ]]; then
|
|
298
|
+
|
|
299
|
+
FINAL_OUTPUT="${{OUTPUT_DIR%_TIMEOUT}}"
|
|
300
|
+
mv "${{OUTPUT_DIR}}_RESTARTED" "${{FINAL_OUTPUT}}"
|
|
301
|
+
cd "${{OUTPUT_DIR}}"
|
|
302
|
+
# cleanup empty files
|
|
303
|
+
if [[ -e "2" && ! -s "2" ]]; then
|
|
304
|
+
rm "2"
|
|
305
|
+
fi
|
|
306
|
+
for nbout_file in *.nbout; do
|
|
307
|
+
if [[ -e "$nbout_file" && ! -s "$nbout_file" ]]; then
|
|
308
|
+
rm "${{nbout_file}}"
|
|
309
|
+
fi
|
|
310
|
+
done
|
|
311
|
+
cd ..
|
|
312
|
+
|
|
313
|
+
exit 0
|
|
314
|
+
fi"""
|
|
315
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: vyas-group-scripts
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Add your description here
|
|
5
|
+
Author: Ben Payton
|
|
6
|
+
Author-email: Ben Payton <bennyp2494@gmail.com>
|
|
7
|
+
Requires-Dist: argparse>=1.4.0
|
|
8
|
+
Requires-Dist: rich>=14.2.0
|
|
9
|
+
Requires-Python: >=3.9
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
vyas_group_scripts/__init__.py,sha256=PZJwQzDvN8PbfBDMCXOb0ciJKMir9J35nU1EXRqgARg,131
|
|
2
|
+
vyas_group_scripts/gen_batch.py,sha256=WHaw2DsC0gq9FSrkOpnCvwX8LqC-3bHJ-9x1OaGGhOc,7025
|
|
3
|
+
vyas_group_scripts/run_batch.py,sha256=RUqEM2UATNq1KOorfszeCfNcdABhwiSlQf6MHnXdENU,881
|
|
4
|
+
vyas_group_scripts/templates/g16_batch_inputs.py,sha256=3BbLCZaPOeiivJJlLNc5lL-8bRDcOkAyGIuChqsdUEY,6138
|
|
5
|
+
vyas_group_scripts/templates/orca_batch_inputs.py,sha256=moYHIJmhX8NRH5J6NK_TcGLSh_nzWoQVQ1HiDA25yfg,12087
|
|
6
|
+
vyas_group_scripts-0.3.0.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
7
|
+
vyas_group_scripts-0.3.0.dist-info/entry_points.txt,sha256=7cL-_aZU96ATik2TKSKoUHO0Ar4b7Rhoa3NqoTG8Ki0,121
|
|
8
|
+
vyas_group_scripts-0.3.0.dist-info/METADATA,sha256=1qBK7c-hiHuDf2yQdH6-dzDP_Ts_1kIj6niDoX8TTcY,287
|
|
9
|
+
vyas_group_scripts-0.3.0.dist-info/RECORD,,
|