Skip to content

Commit d3ef90e

Browse files
test(skills): harden dpgen-run validation
1 parent b7c2a8f commit d3ef90e

3 files changed

Lines changed: 78 additions & 2 deletions

File tree

skills/dpgen-run/references/machine-json.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ Keep separate `train`, `model_devi`, and `fp` blocks. For each stage, collect or
2727
- `resources.source_list` for scheduler runtime activation
2828
- queue, partition, account, and custom scheduler flags when applicable
2929

30-
Typical commands are `dp` for training, `lmp` for LAMMPS exploration, and a backend executable such as `vasp_std`, `cp2k.popt`, `abacus`, `pw.x`, or `g16` for labeling. Preserve known working commands.
30+
`train_backend` does not rewrite the machine command. `dp` selects the DeePMD installation's default backend; a DeePMD-kit 3.x PyTorch installation may require `dp --pt`. Verify the installed entry point with `dp train -h` or `dp --pt train -h`, then make the `train` command agree with `train_backend`.
31+
32+
Typical later-stage commands are `lmp` for LAMMPS exploration and a backend executable such as `vasp_std`, `cp2k.popt`, `abacus`, `pw.x`, or `g16` for labeling. Preserve known working commands.
3133

3234
## Context and batch compatibility
3335

@@ -51,6 +53,6 @@ Patch the closest existing working configuration. Do not transplant site-specifi
5153
- Keep CPU, GPU, node, and grouping requests explicit.
5254
- Require explicit `source_list` activation for scheduler stages.
5355
- Preserve working local omissions and installed-version aliases.
54-
- Ensure commands match the scientific stack selected in `param.json`.
56+
- Ensure the training command selects the same backend as `train_backend` and all commands match the scientific stack selected in `param.json`.
5557

5658
External machine reference: https://docs.deepmodeling.com/projects/dpgen/en/latest/run/mdata.html

skills/dpgen-run/references/validation-and-run.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Compare every `type_map.raw` line-for-line with `param.json.type_map`. Verify ev
5252
Confirm:
5353

5454
- DeePMD-kit version, backend, descriptor, and training-input layout agree
55+
- `train_backend` and the machine `train.command` select the same backend; for DeePMD-kit 3.x PyTorch, verify `dp --pt train -h` and use `dp --pt` when required
5556
- each exploration job references valid systems and MD settings
5657
- force trust thresholds are ordered and scientifically intentional
5758
- FP inputs and support files match `fp_style`

tests/test_dpgen_run_skill.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1+
import copy
12
import json
23
import re
34
import unittest
45
from pathlib import Path
56

7+
from dargs.dargs import (
8+
ArgumentKeyError,
9+
ArgumentTypeError,
10+
ArgumentValueError,
11+
)
12+
613
from dpgen.generator.arginfo import run_jdata_arginfo
714
from dpgen.remote.decide_machine import convert_mdata
815
from dpgen.util import normalize
@@ -88,6 +95,72 @@ def test_linked_parameter_examples_use_current_schema(self):
8895
self.assertIsInstance(normalized, dict)
8996
self.assertTrue(normalized)
9097

98+
def test_documented_parameter_schema_invariants(self):
99+
repository_root = Path(__file__).resolve().parents[1]
100+
example = (
101+
repository_root
102+
/ "examples"
103+
/ "run"
104+
/ "dp2.x-lammps-cp2k"
105+
/ "param_CH4_deepmd-kit-2.0.1.json"
106+
)
107+
parameter_data = json.loads(example.read_text())
108+
normalized = normalize(
109+
run_jdata_arginfo(),
110+
copy.deepcopy(parameter_data),
111+
strict_check=False,
112+
)
113+
114+
self.assertEqual(normalized["model_devi_engine"], "lammps")
115+
self.assertEqual(normalized["train_backend"], "tensorflow")
116+
117+
without_mass_map = copy.deepcopy(parameter_data)
118+
without_mass_map.pop("mass_map", None)
119+
normalized_without_mass_map = normalize(
120+
run_jdata_arginfo(),
121+
without_mass_map,
122+
strict_check=False,
123+
)
124+
self.assertEqual(normalized_without_mass_map["mass_map"], "auto")
125+
126+
invalid_fp_style = copy.deepcopy(parameter_data)
127+
invalid_fp_style["fp_style"] = "none"
128+
with self.assertRaises(ArgumentValueError):
129+
normalize(
130+
run_jdata_arginfo(),
131+
invalid_fp_style,
132+
strict_check=False,
133+
)
134+
135+
missing_model_devi_skip = copy.deepcopy(parameter_data)
136+
missing_model_devi_skip.pop("model_devi_skip")
137+
with self.assertRaises(ArgumentKeyError):
138+
normalize(
139+
run_jdata_arginfo(),
140+
missing_model_devi_skip,
141+
strict_check=False,
142+
)
143+
144+
flat_sys_configs = copy.deepcopy(parameter_data)
145+
flat_sys_configs["sys_configs"] = ["POSCAR"]
146+
with self.assertRaises(ArgumentTypeError):
147+
normalize(
148+
run_jdata_arginfo(),
149+
flat_sys_configs,
150+
strict_check=False,
151+
)
152+
153+
for backend in ("tensorflow", "pytorch"):
154+
with self.subTest(backend=backend):
155+
backend_data = copy.deepcopy(parameter_data)
156+
backend_data["train_backend"] = backend
157+
normalized_backend = normalize(
158+
run_jdata_arginfo(),
159+
backend_data,
160+
strict_check=False,
161+
)
162+
self.assertEqual(normalized_backend["train_backend"], backend)
163+
91164
def test_linked_machine_examples_use_current_schema(self):
92165
repository_root = Path(__file__).resolve().parents[1]
93166
examples_root = repository_root / "examples" / "machine"

0 commit comments

Comments
 (0)