Skip to content

Commit 7b7b04f

Browse files
committedJul 24, 2024·
fix bug in env_vars parsing and forwarding; add new examples
1 parent 9b6639d commit 7b7b04f

9 files changed

+182
-11
lines changed
 

‎configs/hortense.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ ModelEvaluation:
77
cores_per_worker: 12
88
gpu: True
99
max_simulation_time: 20
10+
env_vars:
11+
KMP_BLOCKTIME: "1"
1012
slurm:
1113
partition: "gpu_rome_a100"
1214
account: "2023_070"
@@ -19,6 +21,8 @@ ModelTraining:
1921
cores_per_worker: 12
2022
gpu: true
2123
max_training_time: 40
24+
env_vars:
25+
OMP_PROC_BIND: "spread"
2226
slurm:
2327
partition: "gpu_rome_a100"
2428
account: "2023_070"
@@ -30,6 +34,7 @@ ModelTraining:
3034
CP2K:
3135
cores_per_worker: 64
3236
max_evaluation_time: 30
37+
memory_limit: 2GB
3338
launch_command: 'apptainer exec -e --no-init oras://ghcr.io/molmod/cp2k:2024.1 /opt/entry.sh mpirun -np 32 -bind-to core cp2k.psmp'
3439
slurm:
3540
partition: "cpu_rome"

‎configs/lumi.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ default_threads: 8
66
CP2K:
77
cores_per_worker: 32
88
max_evaluation_time: 20
9+
memory_limit: 2GB
910
launch_command: 'singularity exec -e --no-init oras://ghcr.io/molmod/cp2k:2024.1 /opt/entry.sh mpirun -np 32 cp2k.psmp'
1011
slurm:
1112
partition: "standard"

‎examples/data/acetaldehyde.xyz

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
7
2+
Properties=species:S:1:pos:R:3
3+
O 0.694151672 0.776743934 -0.455455855
4+
C 0.195993254 -0.270095005 -0.307053207
5+
C -0.846060202 -0.538006022 0.669585079
6+
H 0.515801613 -1.097661033 -0.987914453
7+
H -0.589257101 -0.505600908 1.733123281
8+
H -1.553309062 0.309375207 0.558315778
9+
H -1.411674563 -1.440354174 0.5617281699

‎examples/data/vinyl_alcohol.xyz

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
7
2+
Properties=species:S:1:pos:R:3
3+
O 1.041371715 -0.216863172 0.001603252
4+
C -0.098316254 0.512294574 -0.01021628
5+
C -1.225162144 -0.248210652 0.020868361
6+
H -0.087363805 1.596485281 -0.07557041
7+
H 0.61765221 -1.094559605 -0.02702971
8+
H -2.216985293 0.211688229 -0.00469380
9+
H -1.115257687 -1.357478425 -0.04507284

‎examples/online_learning_pimd.py

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
from pathlib import Path
2+
3+
import psiflow
4+
from psiflow.reference import CP2K
5+
from psiflow.data import Dataset
6+
from psiflow.sampling import Walker
7+
from psiflow.models import MACE
8+
from psiflow.hamiltonians import MACEHamiltonian
9+
from psiflow.learning import Learning
10+
11+
12+
def main():
13+
path_output = Path.cwd() / 'output'
14+
15+
with open('data/cp2k_input.txt', 'r') as f: cp2k_input = f.read()
16+
cp2k = CP2K(cp2k_input)
17+
18+
model = MACE(
19+
batch_size=4,
20+
lr=0.02,
21+
max_ell=3,
22+
r_max=6.5,
23+
energy_weight=100,
24+
correlation=3,
25+
max_L=1,
26+
num_channels=24,
27+
patience=8,
28+
scheduler_patience=4,
29+
max_num_epochs=200,
30+
)
31+
model.add_atomic_energy('H', cp2k.compute_atomic_energy('H', box_size=9))
32+
model.add_atomic_energy('O', cp2k.compute_atomic_energy('O', box_size=9))
33+
34+
state = Dataset.load('data/water_train.xyz')[0]
35+
walkers = (
36+
Walker(state, temperature=300, pressure=0.1).multiply(40) +
37+
Walker(state, temperature=450, pressure=0.1).multiply(40) +
38+
Walker(state, temperature=600, pressure=0.1).multiply(40)
39+
)
40+
learning = Learning(
41+
cp2k,
42+
path_output,
43+
wandb_project='psiflow_examples',
44+
wandb_group='water_learning_pimd',
45+
)
46+
47+
model, walkers = learning.passive_learning(
48+
model,
49+
walkers,
50+
hamiltonian=MACEHamiltonian.mace_mp0(),
51+
steps=10000,
52+
step=2000,
53+
)
54+
55+
for i in range(3):
56+
model, walkers = learning.active_learning(
57+
model,
58+
walkers,
59+
steps=2000,
60+
)
61+
62+
# PIMD phase for low-temperature walkers
63+
for j, walker in enumerate(walkers[:40]):
64+
walker.nbeads = 32
65+
model, walkers = learning.active_learning(
66+
model,
67+
walkers,
68+
steps=500,
69+
)
70+
71+
72+
if __name__ == '__main__':
73+
with psiflow.load():
74+
main()

‎examples/proton_jump_plumed.py

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from ase.units import kJ, mol
2+
import numpy as np
3+
4+
import psiflow
5+
from psiflow.data import Dataset
6+
from psiflow.geometry import Geometry
7+
from psiflow.hamiltonians import PlumedHamiltonian, MACEHamiltonian
8+
from psiflow.sampling import Walker, sample, quench, Metadynamics, replica_exchange
9+
10+
11+
PLUMED_INPUT = """UNITS LENGTH=A ENERGY=kj/mol
12+
d_C: DISTANCE ATOMS=3,5
13+
d_O: DISTANCE ATOMS=1,5
14+
CV: COMBINE ARG=d_C,d_O COEFFICIENTS=1,-1 PERIODIC=NO
15+
16+
"""
17+
18+
19+
def get_bias(kappa: float, center: float):
20+
plumed_str = PLUMED_INPUT
21+
plumed_str += '\n'
22+
plumed_str += 'RESTRAINT ARG=CV KAPPA={} AT={}\n'.format(kappa, center)
23+
return PlumedHamiltonian(plumed_str)
24+
25+
26+
def main():
27+
aldehyd = Geometry.load('data/acetaldehyde.xyz')
28+
alcohol = Geometry.load('data/vinyl_alcohol.xyz')
29+
30+
mace = MACEHamiltonian.mace_cc()
31+
energy = mace.compute([aldehyd, alcohol], 'energy').result()
32+
energy = (energy - np.min(energy)) / (kJ / mol)
33+
print('E_vinyl - E_aldehyde = {:7.3f} kJ/mol'.format(energy[1] - energy[0]))
34+
35+
# generate initial structures using metadynamics
36+
plumed_str = PLUMED_INPUT
37+
plumed_str += 'METAD ARG=CV PACE=5 SIGMA=0.25 HEIGHT=5\n'
38+
metadynamics = Metadynamics(plumed_str)
39+
40+
# create 40 identical walkers
41+
walkers = Walker(
42+
aldehyd,
43+
hamiltonian=mace,
44+
temperature=300,
45+
metadynamics=metadynamics,
46+
).multiply(4)
47+
48+
# do MTD and create large dataset from all trajectories
49+
outputs = sample(walkers, steps=2000, step=20, start=1000)
50+
data_mtd = sum([o.trajectory for o in outputs], start=Dataset([]))
51+
52+
# initialize walkers for umbrella sampling
53+
walkers = []
54+
for i, center in enumerate(np.linspace(1, 3, num=16)):
55+
bias = get_bias(kappa=1500, center=center)
56+
hamiltonian = mace + bias
57+
walker = Walker(alcohol, hamiltonian=hamiltonian, temperature=300)
58+
walkers.append(walker)
59+
quench(walkers, data_mtd) # make sure initial structure is reasonable
60+
replica_exchange(walkers, trial_frequency=100) # use REX for improved sampling
61+
62+
outputs = sample(walkers, steps=1000, step=10)
63+
64+
65+
if __name__ == '__main__':
66+
with psiflow.load() as f:
67+
main()

‎psiflow/execution.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def __init__(
170170
self,
171171
max_simulation_time: Optional[float] = None,
172172
timeout: float = (10 / 60), # 5 seconds
173-
env_vars: Optional[dict] = None,
173+
env_vars: Optional[dict[str, str]] = None,
174174
**kwargs,
175175
) -> None:
176176
super().__init__(**kwargs)
@@ -186,9 +186,10 @@ def __init__(
186186
'PYTHONUNBUFFERED': 'TRUE',
187187
}
188188
if env_vars is None:
189-
env_vars = dict(default_env_vars)
189+
env_vars = default_env_vars
190190
else:
191-
env_vars.update(default_env_vars)
191+
default_env_vars.update(env_vars)
192+
env_vars = default_env_vars
192193
self.env_vars = env_vars
193194

194195
def server_command(self):
@@ -245,7 +246,7 @@ def __init__(
245246
self,
246247
gpu=True,
247248
max_training_time: Optional[float] = None,
248-
env_vars: Optional[dict] = None,
249+
env_vars: Optional[dict[str, str]] = None,
249250
**kwargs,
250251
) -> None:
251252
super().__init__(gpu=gpu, **kwargs)
@@ -266,9 +267,10 @@ def __init__(
266267
'PYTHONUNBUFFERED': 'TRUE',
267268
}
268269
if env_vars is None:
269-
env_vars = dict(default_env_vars)
270+
env_vars = default_env_vars
270271
else:
271-
env_vars.update(default_env_vars)
272+
default_env_vars.update(env_vars)
273+
env_vars = default_env_vars
272274
self.env_vars = env_vars
273275

274276
def train_command(self, initialize: bool = False):

‎psiflow/sampling/client.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ def main():
77
import time
88
from pathlib import Path
99

10-
import torch
1110
from ase.io import read
1211
from ipi._driver.driver import run_driver
1312

@@ -54,6 +53,10 @@ def main():
5453
assert args.address is not None
5554
assert args.start is not None
5655

56+
print("pid: {}".format(os.getpid()))
57+
affinity = os.sched_getaffinity(os.getpid())
58+
print("CPU affinity before function init: {}".format(affinity))
59+
5760
template = Geometry.from_atoms(read(args.start))
5861
function = function_from_json(
5962
args.path_hamiltonian,
@@ -68,9 +71,8 @@ def main():
6871
verbose=True,
6972
)
7073

71-
print("pid: {}".format(os.getpid()))
72-
print("CPU affinity: {}".format(os.sched_getaffinity(os.getpid())))
73-
print("torch num threads: ", torch.get_num_threads())
74+
affinity = os.sched_getaffinity(os.getpid())
75+
print("CPU affinity after function init: {}".format(affinity))
7476

7577
try:
7678
t0 = time.time()

‎psiflow/sampling/sampling.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,8 @@ def _sample(
533533
command_server = definition.server_command()
534534
command_client = definition.client_command()
535535
resources = definition.wq_resources(max_nclients)
536+
print('ENV VARS')
537+
print(definition.env_vars)
536538
result = execute_ipi(
537539
len(walkers),
538540
hamiltonian_names,
@@ -543,7 +545,7 @@ def _sample(
543545
command_server,
544546
command_client,
545547
*plumed_list,
546-
env_vars=definition.env_vars,
548+
env_vars=dict(definition.env_vars),
547549
stdout=parsl.AUTO_LOGNAME,
548550
stderr=parsl.AUTO_LOGNAME,
549551
inputs=inputs,

0 commit comments

Comments
 (0)
Please sign in to comment.