-
Notifications
You must be signed in to change notification settings - Fork 36
fix: serialize LAMMPS HDF5 trajectories #381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -202,7 +202,7 @@ def execute( | |
|
|
||
| ret_dict = { | ||
| "log": work_dir / lmp_log_name, | ||
| "traj": work_dir / lmp_traj_name, | ||
| "traj": self.get_traj(work_dir / lmp_traj_name), | ||
| "model_devi": self.get_model_devi(work_dir / lmp_model_devi_name), | ||
| } | ||
| plm_output = ( | ||
|
|
@@ -223,6 +223,10 @@ def execute( | |
| def get_model_devi(self, model_devi_file): | ||
| return model_devi_file | ||
|
|
||
| def get_traj(self, traj_file): | ||
| """Return the filesystem trajectory used by the standard backend.""" | ||
| return traj_file | ||
|
|
||
| @staticmethod | ||
| def lmp_args(): | ||
| doc_lmp_cmd = "The command of LAMMPS" | ||
|
|
@@ -412,3 +416,7 @@ def get_output_sign(cls): | |
|
|
||
| def get_model_devi(self, model_devi_file): | ||
| return np.loadtxt(model_devi_file) | ||
|
|
||
| def get_traj(self, traj_file): | ||
| """Return trajectory text for serialization into an HDF5 dataset.""" | ||
| return traj_file.read_text() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the line to change. Suggest returning a list containing the Path, not the text: def get_traj(self, traj_file):
return [traj_file]The list is what if v.is_file():
try:
data = v.read_text(encoding="utf-8"); dtype = "utf-8"
except Exception:
data = np.void(v.read_bytes()); dtype = "binary"
d = f.create_dataset(s, data=data)
d.attrs["type"] = "file"; d.attrs["path"] = str(v); d.attrs["dtype"] = dtypeSo you get the The docstring on this method also needs updating: "Return trajectory text for serialization into an HDF5 dataset" asserts that returning the text is what causes serialization, and that is what is not true. Note too that |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,6 +35,7 @@ | |
| ) | ||
| from dpgen2.op.run_lmp import ( | ||
| RunLmp, | ||
| RunLmpHDF5, | ||
| get_ele_temp, | ||
| merge_pimd_files, | ||
| set_models, | ||
|
|
@@ -149,6 +150,31 @@ def test_extra_outputs(self): | |
| "Hello -i in.lammps -log log.lammps", | ||
| ) | ||
|
|
||
| @patch("dpgen2.op.run_lmp.run_command") | ||
| def test_hdf5_outputs_dataset_values(self, mocked_run): | ||
| """Return serializable data instead of filesystem paths for HDF5.""" | ||
|
|
||
| def write_outputs(*args, **kwargs): | ||
| Path(lmp_traj_name).write_text("trajectory data") | ||
| np.savetxt(lmp_model_devi_name, np.arange(7).reshape(1, 7)) | ||
| return 0, "foo\n", "" | ||
|
|
||
| mocked_run.side_effect = write_outputs | ||
|
|
||
| out = RunLmpHDF5().execute( | ||
| OPIO( | ||
| { | ||
| "config": {"command": "mylmp"}, | ||
| "task_name": self.task_name, | ||
| "task_path": self.task_path, | ||
| "models": self.models, | ||
| } | ||
| ) | ||
| ) | ||
|
|
||
| self.assertEqual(out["traj"], "trajectory data") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test is not vacuous — I checked, reverting
Issue #355 asked for "a test for from dflow.python.utils import handle_output_artifact
handle_output_artifact("traj", out["traj"], Artifact(HDF5Datasets), slices=0, data_root=tmp)
# then open the produced .h5 and assert its key set is non-emptyWorth doing for |
||
| np.testing.assert_array_equal(out["model_devi"], np.arange(7)) | ||
|
|
||
|
|
||
| class TestRunLmpDist(unittest.TestCase): | ||
| lmp_config = """variable NSTEPS equal 1000 | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has the identical defect and needs to move in the same change, not a follow-up.
np.loadtxtreturns anndarray, which is not alistordict, soflattendrops it too —keys = [].The reason it cannot wait: if only
trajbecomes a list, the two artifacts arrive downstream with different lengths, anddpgen2/exploration/selector/conf_selector_frame.py:88-89isI simulated all three states through the real
handle_output_artifact+handle_input_artifactround trip with two tasks:So fixing
trajalone is worse than fixing neither.return [np.loadtxt(model_devi_file)]alongside thetrajchange.