Skip to content

Commit 8aaa7ca

Browse files
Run lammps extra outputs (#299)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for collecting and returning additional output files ("extra_outputs") in relevant operations. * Users can now specify extra output file patterns (including wildcards) to be captured after LAMMPS runs. * **Tests** * Introduced a new test to verify correct handling and content of extra output files. * Extended existing tests to validate downloading of "extra_outputs" artifacts. * **Chores** * Updated artifact download settings to include "extra_outputs" in the list of downloadable items. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: zjgemi <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 9062e8a commit 8aaa7ca

File tree

6 files changed

+59
-1
lines changed

6 files changed

+59
-1
lines changed

dpgen2/op/run_lmp.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def get_output_sign(cls):
8383
"model_devi": Artifact(Path),
8484
"plm_output": Artifact(Path, optional=True),
8585
"optional_output": Artifact(Path, optional=True),
86+
"extra_outputs": Artifact(List[Path]),
8687
}
8788
)
8889

@@ -213,6 +214,10 @@ def execute(
213214
if ele_temp is not None:
214215
ret_dict["optional_output"] = work_dir / "job.json"
215216

217+
extra_outputs = []
218+
for fname in config["extra_output_files"]:
219+
extra_outputs += list(work_dir.glob(fname))
220+
ret_dict["extra_outputs"] = extra_outputs # type: ignore
216221
return OPIO(ret_dict)
217222

218223
def get_model_devi(self, model_devi_file):
@@ -226,6 +231,7 @@ def lmp_args():
226231
doc_head = "Select a head from multitask"
227232
doc_use_ele_temp = "Whether to use electronic temperature, 0 for no, 1 for frame temperature, and 2 for atomic temperature"
228233
doc_use_hdf5 = "Use HDF5 to store trajs and model_devis"
234+
doc_extra_output_files = "Extra output file names, support wildcards"
229235
return [
230236
Argument("command", str, optional=True, default="lmp", doc=doc_lmp_cmd),
231237
Argument(
@@ -256,6 +262,13 @@ def lmp_args():
256262
default=False,
257263
doc=doc_use_hdf5,
258264
),
265+
Argument(
266+
"extra_output_files",
267+
list,
268+
optional=True,
269+
default=[],
270+
doc=doc_extra_output_files,
271+
),
259272
]
260273

261274
@staticmethod

dpgen2/superop/prep_run_lmp.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ def __init__(
7676
"model_devis": OutputArtifact(),
7777
"plm_output": OutputArtifact(),
7878
"optional_outputs": OutputArtifact(),
79+
"extra_outputs": OutputArtifact(),
7980
}
8081

8182
super().__init__(
@@ -179,6 +180,7 @@ def _prep_run_lmp(
179180
"model_devi",
180181
"plm_output",
181182
"optional_output",
183+
"extra_outputs",
182184
],
183185
**template_slice_config,
184186
),
@@ -217,5 +219,8 @@ def _prep_run_lmp(
217219
prep_run_steps.outputs.artifacts[
218220
"optional_outputs"
219221
]._from = run_lmp.outputs.artifacts["optional_output"]
222+
prep_run_steps.outputs.artifacts["extra_outputs"]._from = run_lmp.outputs.artifacts[
223+
"extra_outputs"
224+
]
220225

221226
return prep_run_steps

dpgen2/utils/download_dpgen2_artifacts.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ def add_output(
6363
"prep-run-explore": DownloadDefinition()
6464
.add_output("logs")
6565
.add_output("trajs")
66-
.add_output("model_devis"),
66+
.add_output("model_devis")
67+
.add_output("extra_outputs"),
6768
"prep-run-fp": DownloadDefinition()
6869
.add_input("confs")
6970
.add_output("logs")

tests/mocked_ops.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ def execute(
424424
"log": work_dir / log,
425425
"traj": work_dir / traj,
426426
"model_devi": work_dir / model_devi,
427+
"extra_outputs": [],
427428
}
428429
)
429430

tests/op/test_run_lmp.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,29 @@ def test_error(self, mocked_run):
126126
]
127127
mocked_run.assert_has_calls(calls)
128128

129+
def test_extra_outputs(self):
130+
op = RunLmp()
131+
out = op.execute(
132+
OPIO(
133+
{
134+
"config": {
135+
"command": "echo Hello > foo.txt",
136+
"extra_output_files": ["foo.txt"],
137+
},
138+
"task_name": self.task_name,
139+
"task_path": self.task_path,
140+
"models": self.models,
141+
}
142+
)
143+
)
144+
work_dir = Path(self.task_name)
145+
# check output
146+
self.assertEqual(out["extra_outputs"], [work_dir / "foo.txt"])
147+
self.assertEqual(
148+
(work_dir / "foo.txt").read_text().strip(),
149+
"Hello -i in.lammps -log log.lammps",
150+
)
151+
129152

130153
class TestRunLmpDist(unittest.TestCase):
131154
lmp_config = """variable NSTEPS equal 1000

tests/utils/test_dl_dpgen2_arti.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ def test_lmp_download(self, mocked_dl):
123123
path=Path("iter-000001/prep-run-explore/outputs"),
124124
skip_exists=True,
125125
),
126+
mock.call(
127+
"arti-extra_outputs",
128+
path=Path("iter-000001/prep-run-explore/outputs"),
129+
skip_exists=True,
130+
),
126131
]
127132
self.assertEqual(len(mocked_dl.call_args_list), len(expected))
128133
for ii, jj in zip(mocked_dl.call_args_list, expected):
@@ -253,6 +258,11 @@ def test_update_finished_steps_exist_steps(self, mocked_dl):
253258
path=Path("iter-000001/prep-run-explore/outputs"),
254259
skip_exists=True,
255260
),
261+
mock.call(
262+
"arti-extra_outputs",
263+
path=Path("iter-000001/prep-run-explore/outputs"),
264+
skip_exists=True,
265+
),
256266
]
257267
self.assertEqual(len(mocked_dl.call_args_list), len(expected))
258268
for ii, jj in zip(mocked_dl.call_args_list, expected):
@@ -315,6 +325,11 @@ def test_update_finished_steps_none_steps(self, mocked_dl):
315325
path=Path("iter-000001/prep-run-explore/outputs"),
316326
skip_exists=True,
317327
),
328+
mock.call(
329+
"arti-extra_outputs",
330+
path=Path("iter-000001/prep-run-explore/outputs"),
331+
skip_exists=True,
332+
),
318333
]
319334
for ii, jj in zip(mocked_dl.call_args_list, expected):
320335
self.assertEqual(ii, jj)

0 commit comments

Comments
 (0)