Skip to content

Commit 6af59ba

Browse files
authored
Merge pull request #493 from Ericwang6/devel
Update gromacs model devi engine
2 parents f7e49f3 + f2397f3 commit 6af59ba

File tree

6 files changed

+342
-60
lines changed

6 files changed

+342
-60
lines changed

dpgen/generator/lib/gaussian.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,13 @@ def make_gaussian_input(sys_data, fp_params):
114114
keywords = [keywords]
115115
else:
116116
keywords = keywords.copy()
117+
117118
# assume default charge is zero and default spin multiplicity is 1
118-
charge = fp_params.get('charge', 0)
119+
if 'charge' in sys_data.keys():
120+
charge = sys_data['charge']
121+
else:
122+
charge = fp_params.get('charge', 0)
123+
119124
use_fragment_guesses = False
120125
multiplicity = fp_params.get('multiplicity', 'auto')
121126
if type(multiplicity) == int:

dpgen/generator/run.py

Lines changed: 105 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,12 @@ def dump_to_poscar(dump, poscar, type_map, fmt = "lammps/dump") :
184184
sys = dpdata.System(dump, fmt = fmt, type_map = type_map)
185185
sys.to_vasp_poscar(poscar)
186186

187-
def dump_to_deepmd_raw(dump, deepmd_raw, type_map, fmt='gromacs/gro'):
187+
def dump_to_deepmd_raw(dump, deepmd_raw, type_map, fmt='gromacs/gro', charge=None):
188188
system = dpdata.System(dump, fmt = fmt, type_map = type_map)
189189
system.to_deepmd_raw(deepmd_raw)
190+
if charge is not None:
191+
with open(os.path.join(deepmd_raw, "charge"), 'w') as f:
192+
f.write(str(charge))
190193

191194

192195
def make_train (iter_index,
@@ -206,7 +209,14 @@ def make_train (iter_index,
206209
training_init_model = jdata.get('training_init_model', False)
207210
training_reuse_iter = jdata.get('training_reuse_iter')
208211
training_reuse_old_ratio = jdata.get('training_reuse_old_ratio', None)
209-
training_reuse_stop_batch = jdata.get('training_reuse_stop_batch', 400000)
212+
213+
if 'training_reuse_stop_batch' in jdata.keys():
214+
training_reuse_stop_batch = jdata['training_reuse_stop_batch']
215+
elif 'training_reuse_numb_steps' in jdata.keys():
216+
training_reuse_stop_batch = jdata['training_reuse_numb_steps']
217+
else:
218+
training_reuse_stop_batch = 400000
219+
210220
training_reuse_start_lr = jdata.get('training_reuse_start_lr', 1e-4)
211221
training_reuse_start_pref_e = jdata.get('training_reuse_start_pref_e', 0.1)
212222
training_reuse_start_pref_f = jdata.get('training_reuse_start_pref_f', 100)
@@ -347,10 +357,12 @@ def make_train (iter_index,
347357
# set training reuse model
348358
if training_reuse_iter is not None and iter_index >= training_reuse_iter:
349359
if LooseVersion('1') <= LooseVersion(mdata["deepmd_version"]) < LooseVersion('2'):
360+
jinput['training']['stop_batch'] = training_reuse_stop_batch
350361
jinput['training']['auto_prob_style'] \
351362
="prob_sys_size; 0:%d:%f; %d:%d:%f" \
352363
%(old_range, training_reuse_old_ratio, old_range, len(init_data_sys), 1.-training_reuse_old_ratio)
353364
elif LooseVersion('2') <= LooseVersion(mdata["deepmd_version"]) < LooseVersion('3'):
365+
jinput['training']['numb_steps'] = training_reuse_stop_batch
354366
jinput['training']['training_data']['auto_prob'] \
355367
="prob_sys_size; 0:%d:%f; %d:%d:%f" \
356368
%(old_range, training_reuse_old_ratio, old_range, len(init_data_sys), 1.-training_reuse_old_ratio)
@@ -361,7 +373,7 @@ def make_train (iter_index,
361373
if jinput['loss'].get('start_pref_f') is not None:
362374
jinput['loss']['start_pref_f'] = training_reuse_start_pref_f
363375
jinput['learning_rate']['start_lr'] = training_reuse_start_lr
364-
jinput['training']['stop_batch'] = training_reuse_stop_batch
376+
365377

366378
for ii in range(numb_models) :
367379
task_path = os.path.join(work_path, train_task_fmt % ii)
@@ -1077,6 +1089,9 @@ def _make_model_devi_native(iter_index, jdata, mdata, conf_systems):
10771089
sys_counter += 1
10781090

10791091
def _make_model_devi_native_gromacs(iter_index, jdata, mdata, conf_systems):
1092+
# only support for deepmd v2.0
1093+
if LooseVersion(mdata['deepmd_version']) < LooseVersion('2.0'):
1094+
raise RuntimeError("Only support deepmd-kit 2.x for model_devi_engine='gromacs'")
10801095
model_devi_jobs = jdata['model_devi_jobs']
10811096
if (iter_index >= len(model_devi_jobs)) :
10821097
return False
@@ -1087,6 +1102,12 @@ def _make_model_devi_native_gromacs(iter_index, jdata, mdata, conf_systems):
10871102
else:
10881103
model_devi_dt = jdata['model_devi_dt']
10891104
nsteps = cur_job.get("nsteps", None)
1105+
lambdas = cur_job.get("lambdas", [1.0])
1106+
temps = cur_job.get("temps", [298.0])
1107+
1108+
for ll in lambdas:
1109+
assert (ll >= 0.0 and ll <= 1.0), "Lambda should be in [0,1]"
1110+
10901111
if nsteps is None:
10911112
raise RuntimeError("nsteps is None, you should set nsteps in model_devi_jobs!")
10921113
# Currently Gromacs engine is not supported for different temperatures!
@@ -1112,48 +1133,50 @@ def _make_model_devi_native_gromacs(iter_index, jdata, mdata, conf_systems):
11121133
conf_counter = 0
11131134
task_counter = 0
11141135
for cc in ss :
1115-
task_name = make_model_devi_task_name(sys_idx[sys_counter], task_counter)
1116-
#conf_name = make_model_devi_conf_name(sys_idx[sys_counter], conf_counter) + '.lmp'
1117-
task_path = os.path.join(work_path, task_name)
1118-
# dlog.info(task_path)
1119-
create_path(task_path)
1120-
#create_path(os.path.join(task_path, 'traj'))
1121-
#loc_conf_name = 'conf.lmp'
1122-
gromacs_settings = jdata.get("gromacs_settings" , "")
1123-
for key,file in gromacs_settings.items():
1124-
if key != "traj_filename" and key != "mdp_filename":
1125-
os.symlink(os.path.join(cc,file), os.path.join(task_path, file))
1126-
1127-
# input.json for DP-Gromacs
1128-
with open(os.path.join(cc, "input.json")) as f:
1129-
input_json = json.load(f)
1130-
input_json["graph_file"] = models[0]
1131-
with open(os.path.join(task_path,'input.json'), 'w') as _outfile:
1132-
json.dump(input_json, _outfile, indent = 4)
1133-
1134-
# trj_freq
1135-
trj_freq = cur_job.get("trj_freq", 10)
1136-
mdp = MDP()
1137-
mdp.read(os.path.join(cc, gromacs_settings['mdp_filename']))
1138-
mdp['nstcomm'] = trj_freq
1139-
mdp['nstxout'] = trj_freq
1140-
mdp['nstlog'] = trj_freq
1141-
mdp['nstenergy'] = trj_freq
1142-
# dt
1143-
mdp['dt'] = dt
1144-
mdp.write(os.path.join(task_path, gromacs_settings['mdp_filename']))
1145-
1146-
cwd_ = os.getcwd()
1147-
os.chdir(task_path)
1148-
job = {}
1149-
1150-
job["model_devi_dt"] = model_devi_dt
1151-
job["nsteps"] = nsteps
1152-
with open('job.json', 'w') as _outfile:
1153-
json.dump(job, _outfile, indent = 4)
1154-
os.chdir(cwd_)
1155-
1156-
task_counter += 1
1136+
for ll in lambdas:
1137+
for tt in temps:
1138+
task_name = make_model_devi_task_name(sys_idx[sys_counter], task_counter)
1139+
task_path = os.path.join(work_path, task_name)
1140+
create_path(task_path)
1141+
gromacs_settings = jdata.get("gromacs_settings" , "")
1142+
for key,file in gromacs_settings.items():
1143+
if key != "traj_filename" and key != "mdp_filename" and key != "group_name":
1144+
os.symlink(os.path.join(cc,file), os.path.join(task_path, file))
1145+
# input.json for DP-Gromacs
1146+
with open(os.path.join(cc, "input.json")) as f:
1147+
input_json = json.load(f)
1148+
input_json["graph_file"] = models[0]
1149+
input_json["lambda"] = ll
1150+
with open(os.path.join(task_path,'input.json'), 'w') as _outfile:
1151+
json.dump(input_json, _outfile, indent = 4)
1152+
1153+
# trj_freq
1154+
trj_freq = cur_job.get("trj_freq", 10)
1155+
mdp = MDP()
1156+
mdp.read(os.path.join(cc, gromacs_settings['mdp_filename']))
1157+
mdp['nstcomm'] = trj_freq
1158+
mdp['nstxout'] = trj_freq
1159+
mdp['nstlog'] = trj_freq
1160+
mdp['nstenergy'] = trj_freq
1161+
# dt
1162+
mdp['dt'] = model_devi_dt
1163+
# temps
1164+
if "ref_t" in list(mdp.keys()):
1165+
mdp["ref_t"] = tt
1166+
else:
1167+
mdp["ref-t"] = tt
1168+
mdp.write(os.path.join(task_path, gromacs_settings['mdp_filename']))
1169+
1170+
cwd_ = os.getcwd()
1171+
os.chdir(task_path)
1172+
job = {}
1173+
job["trj_freq"] = cur_job["trj_freq"]
1174+
job["model_devi_dt"] = model_devi_dt
1175+
job["nsteps"] = nsteps
1176+
with open('job.json', 'w') as _outfile:
1177+
json.dump(job, _outfile, indent = 4)
1178+
os.chdir(cwd_)
1179+
task_counter += 1
11571180
conf_counter += 1
11581181
sys_counter += 1
11591182

@@ -1209,21 +1232,32 @@ def run_model_devi (iter_index,
12091232
if use_plm_path:
12101233
forward_files += ['plmpath.pdb']
12111234
elif model_devi_engine == "gromacs":
1235+
12121236
gromacs_settings = jdata.get("gromacs_settings", {})
12131237
mdp_filename = gromacs_settings.get("mdp_filename", "md.mdp")
12141238
topol_filename = gromacs_settings.get("topol_filename", "processed.top")
12151239
conf_filename = gromacs_settings.get("conf_filename", "conf.gro")
12161240
index_filename = gromacs_settings.get("index_filename", "index.raw")
1241+
# Initial reference to process pbc condition.
1242+
# Default is em.tpr
1243+
ref_filename = gromacs_settings.get("ref_filename", "em.tpr")
12171244
deffnm = gromacs_settings.get("deffnm", "deepmd")
12181245
maxwarn = gromacs_settings.get("maxwarn", 1)
1246+
traj_filename = gromacs_settings.get("traj_filename", "deepmd_traj.gro")
1247+
grp_name = gromacs_settings.get("group_name", "Other")
12191248
nsteps = cur_job["nsteps"]
1249+
trj_freq = cur_job.get("trj_freq", 10)
12201250

12211251
command = "%s grompp -f %s -p %s -c %s -o %s -maxwarn %d" % (model_devi_exec, mdp_filename, topol_filename, conf_filename, deffnm, maxwarn)
1222-
command += "&& %s mdrun -deffnm %s -nsteps %d" %(model_devi_exec, deffnm, nsteps)
1252+
command += "&& %s mdrun -deffnm %s -nsteps %d" %(model_devi_exec, deffnm, nsteps)
1253+
command += "&& echo -e \"%s\n%s\n\" | %s trjconv -s %s -f %s.trr -o %s -pbc mol -ur compact -center" % (grp_name, grp_name, model_devi_exec, ref_filename, deffnm, traj_filename)
1254+
command += "&& if [ ! -d traj ]; then \n mkdir traj; fi\n"
1255+
command += f"python -c \"import dpdata;system = dpdata.System('{traj_filename}', fmt='gromacs/gro'); [system.to_gromacs_gro('traj/%d.gromacstrj' % (i * {trj_freq}), frame_idx=i) for i in range(system.get_nframes())]; system.to_deepmd_npy('traj_deepmd')\""
1256+
command += f"&& dp model-devi -m ../graph.000.pb ../graph.001.pb ../graph.002.pb ../graph.003.pb -s traj_deepmd -o model_devi.out -f {trj_freq}"
12231257
commands = [command]
1224-
1225-
forward_files = [mdp_filename, topol_filename, conf_filename, index_filename, "input.json" ]
1226-
backward_files = ["%s.tpr" % deffnm, "%s.log" %deffnm , 'model_devi.out', 'model_devi.log']
1258+
1259+
forward_files = [mdp_filename, topol_filename, conf_filename, index_filename, ref_filename, "input.json", "job.json" ]
1260+
backward_files = ["%s.tpr" % deffnm, "%s.log" %deffnm , traj_filename, 'model_devi.out', "traj", "traj_deepmd" ]
12271261

12281262

12291263
cwd = os.getcwd()
@@ -1531,6 +1565,10 @@ def _make_fp_vasp_inner (modd_path,
15311565
system_index.sort()
15321566

15331567
fp_tasks = []
1568+
1569+
charges_recorder = [] # record charges for each fp_task
1570+
charges_map = jdata.get("sys_charges", [])
1571+
15341572
cluster_cutoff = jdata['cluster_cutoff'] if jdata.get('use_clusters', False) else None
15351573
model_devi_adapt_trust_lo = jdata.get('model_devi_adapt_trust_lo', False)
15361574
model_devi_f_avg_relative = jdata.get('model_devi_f_avg_relative', False)
@@ -1627,11 +1665,11 @@ def _make_fp_vasp_inner (modd_path,
16271665
continue
16281666

16291667
if fp_cluster_vacuum is not None:
1630-
assert fp_cluster_vacuum >0
1631-
skip_cluster = check_cluster(conf_name, fp_cluster_vacuum)
1632-
if skip_cluster:
1633-
count_bad_cluster +=1
1634-
continue
1668+
assert fp_cluster_vacuum >0
1669+
skip_cluster = check_cluster(conf_name, fp_cluster_vacuum)
1670+
if skip_cluster:
1671+
count_bad_cluster +=1
1672+
continue
16351673

16361674
# link job.json
16371675
job_name = os.path.join(tt, "job.json")
@@ -1647,6 +1685,8 @@ def _make_fp_vasp_inner (modd_path,
16471685
fp_task_path = os.path.join(work_path, fp_task_name)
16481686
create_path(fp_task_path)
16491687
fp_tasks.append(fp_task_path)
1688+
if charges_map:
1689+
charges_recorder.append(charges_map[int(ss)])
16501690
cwd = os.getcwd()
16511691
os.chdir(fp_task_path)
16521692
if cluster_cutoff is None:
@@ -1664,13 +1704,18 @@ def _make_fp_vasp_inner (modd_path,
16641704
dlog.info("system {0:s} skipped {1:6d} confs with bad cluster, {2:6d} remains".format(ss, count_bad_cluster, numb_task - count_bad_cluster))
16651705
if cluster_cutoff is None:
16661706
cwd = os.getcwd()
1667-
for ii in fp_tasks:
1668-
os.chdir(ii)
1707+
for idx, task in enumerate(fp_tasks):
1708+
os.chdir(task)
16691709
if model_devi_engine == "lammps":
16701710
dump_to_poscar('conf.dump', 'POSCAR', type_map, fmt = "lammps/dump")
1711+
if charges_map:
1712+
warnings.warn('"sys_charges" keyword only support for gromacs engine now.')
16711713
elif model_devi_engine == "gromacs":
16721714
# dump_to_poscar('conf.dump', 'POSCAR', type_map, fmt = "gromacs/gro")
1673-
dump_to_deepmd_raw('conf.dump', 'deepmd.raw', type_map, fmt = 'gromacs/gro')
1715+
if charges_map:
1716+
dump_to_deepmd_raw('conf.dump', 'deepmd.raw', type_map, fmt='gromacs/gro', charge=charges_recorder[idx])
1717+
else:
1718+
dump_to_deepmd_raw('conf.dump', 'deepmd.raw', type_map, fmt='gromacs/gro', charge=None)
16741719
else:
16751720
raise RuntimeError("unknown model_devi engine", model_devi_engine)
16761721
os.chdir(cwd)
@@ -2096,6 +2141,8 @@ def make_fp_gaussian(iter_index,
20962141
sys_data = dpdata.System('POSCAR').data
20972142
elif model_devi_engine == "gromacs":
20982143
sys_data = dpdata.System("deepmd.raw", fmt='deepmd/raw').data
2144+
if os.path.isfile('deepmd.raw/charge'):
2145+
sys_data['charge'] = int(np.loadtxt('deepmd.raw/charge', dtype=int))
20992146
ret = make_gaussian_input(sys_data, fp_params)
21002147
with open('input', 'w') as fp:
21012148
fp.write(ret)
@@ -2646,6 +2693,7 @@ def post_fp_gaussian (iter_index,
26462693
sys_output = glob.glob(os.path.join(work_path, "task.%s.*/output"%ss))
26472694
sys_output.sort()
26482695
for idx,oo in enumerate(sys_output) :
2696+
# TODO : UnboundLocalError sometimes occurs when parsing gaussian log
26492697
sys = dpdata.LabeledSystem(oo, fmt = 'gaussian/log')
26502698
if len(sys) > 0:
26512699
sys.check_type_map(type_map = jdata['type_map'])
File renamed without changes.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"deepmd_version" : "2.0",
3+
"train": [
4+
{
5+
"machine": {
6+
"batch": "slurm",
7+
"work_path": "/work/path"
8+
},
9+
"resources": {
10+
"numb_node": 1,
11+
"numb_gpu": 1,
12+
"partition": "all",
13+
"time_limit": "120:0:0",
14+
"task_per_node": 8,
15+
"exclude_list": [],
16+
"module_list": [],
17+
"source_list": ["/path/to/dp-2.0.env"]
18+
},
19+
"command": "dp"
20+
}
21+
],
22+
"model_devi": [
23+
{
24+
"machine": {
25+
"batch": "slurm",
26+
"work_path": "/work/path"
27+
},
28+
"resources": {
29+
"numb_node": 1,
30+
"numb_gpu": 1,
31+
"partition": "all",
32+
"time_limit": "120:0:0",
33+
"task_per_node": 8,
34+
"source_list": [
35+
"/path/to/gromacs-dp/env"
36+
],
37+
"module_list": [],
38+
"exclude_list": [],
39+
"envs": {
40+
"GMX_DEEPMD_INPUT_JSON": "input.json"
41+
}
42+
},
43+
"command": "gmx_mpi",
44+
"group_size": 1
45+
}
46+
],
47+
"fp": [
48+
{
49+
"machine": {
50+
"batch": "slurm",
51+
"work_path": "/work/path"
52+
},
53+
"resources": {
54+
"numb_node": 1,
55+
"numb_gpu": 0,
56+
"time_limit": "120:0:0",
57+
"task_per_node": 28,
58+
"partition": "cpu",
59+
"exclude_list": [],
60+
"source_list": [
61+
"/path/to/gaussian/bashrc"
62+
],
63+
"module_list": []
64+
},
65+
"command": "g16 < input",
66+
"group_size": 20
67+
}
68+
]
69+
}

0 commit comments

Comments
 (0)