From 7cd9882c82c91dde046aa790fab1ba6a1535d134 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Mon, 20 Jul 2026 11:15:15 +0000 Subject: [PATCH 01/21] feat: validate LAMMPS template revision variables before task execution Add pre-check logic in LmpTemplateTaskGroup.make_task() that scans substituted templates for unreplaced V_* revision placeholders. This catches undefined revision variables at submit time (fail fast) instead of waiting until LAMMPS execution on remote cluster fails, which can waste hours of GPU training + queue time. Changes: - Add find_unreplaced_variables() to detect residual V_* patterns - Add check_revisions_completeness() with two checks: 1. Post-substitution residual check (raises ValueError) 2. Unused revision key detection (emits warning for typos) - Update test_lmp_empty to expect ValueError (previously would silently pass templates with unreplaced variables to LAMMPS) - Add TestRevisionVariablePrecheck test class with 5 test cases Closes: template variable typo wastes 75min train + queue time issue --- .../task/lmp_template_task_group.py | 99 ++++++++++ .../exploration/test_lmp_templ_task_group.py | 177 ++++++++++++++++-- 2 files changed, 258 insertions(+), 18 deletions(-) diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index d1f8e9fc..aab78af2 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -1,11 +1,14 @@ import itertools import random +import re +import warnings from pathlib import ( Path, ) from typing import ( List, Optional, + Set, ) from dpgen2.constants import ( @@ -101,6 +104,28 @@ def make_task( if self.plm_set: templates.append(self.plm_template) conts = self.make_cont(templates, self.revisions) + # Validate: check for unreplaced V_* variables in substituted templates + if self.revisions: + template_raw = "\n".join(self.lmp_template) + if self.plm_set: + template_raw += "\n" + "\n".join(self.plm_template) + check_revisions_completeness( + conts[0], + list(self.revisions.keys()), + template_raw=template_raw, + ) + else: + # Even without revisions, check if template has V_* that need substitution + combined = "\n".join(self.lmp_template) + if self.plm_set: + combined += "\n" + "\n".join(self.plm_template) + unreplaced = find_unreplaced_variables(combined) + if unreplaced: + raise ValueError( + f"LAMMPS template contains revision variable(s) {sorted(unreplaced)} " + f"but no 'revisions' dict was provided. " + f"Please define them in 'revisions' in your exploration config." + ) nconts = len(conts[0]) for cc, ii in itertools.product(confs, range(nconts)): # type: ignore if not self.plm_set: @@ -218,3 +243,77 @@ def revise_by_keys(lmp_lines, keys, values): for ii in range(len(lmp_lines)): lmp_lines[ii] = lmp_lines[ii].replace(kk, str(vv)) return lmp_lines + + +# Regex pattern for dpgen-style revision placeholders: V_ followed by uppercase letters/digits/underscores. +# This matches the universal convention in dpgen v1/v2 (all tests, docs, and examples use V_XXX). +_REVISION_VARIABLE_PATTERN = re.compile(r"(? Set[str]: + """Scan text for remaining V_* revision placeholders that were not substituted. + + Parameters + ---------- + content : str + The LAMMPS input content after revision substitution. + + Returns + ------- + Set[str] + Set of variable names (e.g. {"V_PRESS", "V_UNDEFINED"}) still present. + """ + return set(_REVISION_VARIABLE_PATTERN.findall(content)) + + +def check_revisions_completeness( + templates_content: List[str], + revision_keys: List[str], + template_raw: str = "", +) -> None: + """Validate that all V_* placeholders in the template have been substituted. + + This function performs two checks: + 1. **Post-substitution residual check**: After applying revisions, scan the output + for any remaining V_* variables that were not replaced. This catches typos in + template variables or missing keys in revisions. + 2. **Unused key warning**: If a revision key is defined but never appears in the + raw template, emit a warning (possible typo in the key name). + + Parameters + ---------- + templates_content : List[str] + List of template strings after revision substitution (one per revision combo). + revision_keys : List[str] + The keys defined in the revisions dict. + template_raw : str + The raw template content before substitution (for unused key detection). + + Raises + ------ + ValueError + If unreplaced V_* variables are found in substituted templates. + """ + # Check 1: Residual unreplaced variables + all_unreplaced: Set[str] = set() + for content in templates_content: + all_unreplaced.update(find_unreplaced_variables(content)) + + if all_unreplaced: + raise ValueError( + f"LAMMPS template contains undefined revision variable(s): " + f"{sorted(all_unreplaced)}. " + f"Defined revisions: {sorted(revision_keys)}. " + f"Please add missing variables to 'revisions' in your exploration config, " + f"or remove them from the template." + ) + + # Check 2: Unused revision keys (warning only) + if template_raw and revision_keys: + for key in revision_keys: + if key not in template_raw: + warnings.warn( + f"Revision key '{key}' is defined but does not appear in the " + f"LAMMPS/PLUMED template. Possible typo?", + stacklevel=3, + ) diff --git a/tests/exploration/test_lmp_templ_task_group.py b/tests/exploration/test_lmp_templ_task_group.py index 6211137d..17bb95c7 100644 --- a/tests/exploration/test_lmp_templ_task_group.py +++ b/tests/exploration/test_lmp_templ_task_group.py @@ -388,6 +388,7 @@ def test_lmp_plm(self): idx += 1 def test_lmp_empty(self): + """Empty revisions with template containing V_* should now raise ValueError.""" task_group = LmpTemplateTaskGroup() task_group.set_conf(self.confs) task_group.set_lmp( @@ -396,24 +397,10 @@ def test_lmp_empty(self): revisions=self.rev_empty, traj_freq=self.traj_freq, ) - task_group.make_task() - ngroup = len(task_group) - self.assertEqual( - ngroup, - len(self.confs), - ) - idx = 0 - for cc in range(len(self.confs)): - ee = expected_lmp_template.split("\n") - self.assertEqual( - task_group[idx].files()[lmp_conf_name], - self.confs[cc], - ) - self.assertEqual( - task_group[idx].files()[lmp_input_name].split("\n"), - ee, - ) - idx += 1 + with self.assertRaises(ValueError) as ctx: + task_group.make_task() + self.assertIn("V_NSTEPS", str(ctx.exception)) + self.assertIn("V_TEMP", str(ctx.exception)) def test_lmp_pimd(self): task_group = LmpTemplateTaskGroup() @@ -436,3 +423,157 @@ def test_lmp_pimd(self): task_group[0].files()[lmp_input_name].split("\n"), ee, ) + + +class TestRevisionVariablePrecheck(unittest.TestCase): + """Test PR6: validation of revision variables in LAMMPS templates.""" + + def setUp(self): + self.lmp_template_fname = Path("lmp_precheck.template") + self.numb_models = 4 + self.confs = ["foo"] + self.traj_freq = 10 + + def tearDown(self): + if self.lmp_template_fname.exists(): + os.remove(self.lmp_template_fname) + + def _write_template(self, content): + self.lmp_template_fname.write_text(content) + + def test_undefined_variable_raises(self): + """Template has V_PRESS but revisions only define V_NSTEPS and V_TEMP.""" + template = textwrap.dedent( + """\ + variable NSTEPS equal V_NSTEPS + variable TEMP equal V_TEMP + variable PRESS equal V_PRESS + + pair_style deepmd + pair_coeff * * + dump dpgen_dump + run ${NSTEPS} + """ + ) + self._write_template(template) + task_group = LmpTemplateTaskGroup() + task_group.set_conf(self.confs) + task_group.set_lmp( + self.numb_models, + self.lmp_template_fname, + revisions={"V_NSTEPS": [1000], "V_TEMP": [300]}, + traj_freq=self.traj_freq, + ) + with self.assertRaises(ValueError) as ctx: + task_group.make_task() + self.assertIn("V_PRESS", str(ctx.exception)) + self.assertIn("undefined revision variable", str(ctx.exception).lower()) + + def test_no_revisions_but_template_has_variables(self): + """Template has V_* variables but no revisions provided at all.""" + template = textwrap.dedent( + """\ + variable NSTEPS equal V_NSTEPS + variable TEMP equal V_TEMP + + pair_style deepmd + pair_coeff * * + dump dpgen_dump + run ${NSTEPS} + """ + ) + self._write_template(template) + task_group = LmpTemplateTaskGroup() + task_group.set_conf(self.confs) + task_group.set_lmp( + self.numb_models, + self.lmp_template_fname, + revisions={}, + traj_freq=self.traj_freq, + ) + with self.assertRaises(ValueError) as ctx: + task_group.make_task() + self.assertIn("V_NSTEPS", str(ctx.exception)) + self.assertIn("V_TEMP", str(ctx.exception)) + + def test_all_variables_defined_no_error(self): + """All V_* variables are covered by revisions — should succeed.""" + template = textwrap.dedent( + """\ + variable NSTEPS equal V_NSTEPS + variable TEMP equal V_TEMP + + pair_style deepmd + pair_coeff * * + dump dpgen_dump + run ${NSTEPS} + """ + ) + self._write_template(template) + task_group = LmpTemplateTaskGroup() + task_group.set_conf(self.confs) + task_group.set_lmp( + self.numb_models, + self.lmp_template_fname, + revisions={"V_NSTEPS": [1000], "V_TEMP": [300, 600]}, + traj_freq=self.traj_freq, + ) + # Should not raise + task_group.make_task() + self.assertEqual(len(task_group), 2) # 1 conf * 2 V_TEMP values + + def test_unused_revision_key_warns(self): + """Revision defines V_TYPO that doesn't appear in template — should warn.""" + template = textwrap.dedent( + """\ + variable NSTEPS equal V_NSTEPS + + pair_style deepmd + pair_coeff * * + dump dpgen_dump + run ${NSTEPS} + """ + ) + self._write_template(template) + task_group = LmpTemplateTaskGroup() + task_group.set_conf(self.confs) + task_group.set_lmp( + self.numb_models, + self.lmp_template_fname, + revisions={"V_NSTEPS": [1000], "V_TYPO": [42]}, + traj_freq=self.traj_freq, + ) + import warnings as _warnings + + with _warnings.catch_warnings(record=True) as w: + _warnings.simplefilter("always") + task_group.make_task() + # Should have at least one warning about V_TYPO + typo_warnings = [x for x in w if "V_TYPO" in str(x.message)] + self.assertGreater(len(typo_warnings), 0) + + def test_lammps_internal_variables_not_flagged(self): + """${NSTEPS} and similar LAMMPS internal refs should NOT be flagged.""" + template = textwrap.dedent( + """\ + variable NSTEPS equal V_NSTEPS + + pair_style deepmd + pair_coeff * * + dump dpgen_dump + velocity all create ${TEMP} 12345 + run ${NSTEPS} + """ + ) + self._write_template(template) + task_group = LmpTemplateTaskGroup() + task_group.set_conf(self.confs) + task_group.set_lmp( + self.numb_models, + self.lmp_template_fname, + revisions={"V_NSTEPS": [1000]}, + traj_freq=self.traj_freq, + ) + # ${TEMP} is LAMMPS syntax, not a dpgen revision variable — should not raise + task_group.make_task() + self.assertEqual(len(task_group), 1) From 87c626aa5c64491d607503314b8e55a8a684970d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 20 Jul 2026 11:41:51 +0000 Subject: [PATCH 02/21] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- dpgen2/exploration/task/lmp_template_task_group.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index aab78af2..2064b204 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -247,7 +247,9 @@ def revise_by_keys(lmp_lines, keys, values): # Regex pattern for dpgen-style revision placeholders: V_ followed by uppercase letters/digits/underscores. # This matches the universal convention in dpgen v1/v2 (all tests, docs, and examples use V_XXX). -_REVISION_VARIABLE_PATTERN = re.compile(r"(? Set[str]: From c2145a27f65e36bddc50686e3f1ba5be374b7b79 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Mon, 20 Jul 2026 12:09:35 +0000 Subject: [PATCH 03/21] fix: include PLUMED templates in revision variable validation Address CodeRabbit review: check_revisions_completeness was only called with conts[0] (LAMMPS templates), missing conts[1] (PLUMED templates). Now flatten all template variants before validation so V_* placeholders in PLUMED templates are also caught. Add test_plumed_template_undefined_variable_raises test case. --- .../task/lmp_template_task_group.py | 4 +- .../exploration/test_lmp_templ_task_group.py | 40 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index 2064b204..72cf55e9 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -109,8 +109,10 @@ def make_task( template_raw = "\n".join(self.lmp_template) if self.plm_set: template_raw += "\n" + "\n".join(self.plm_template) + # Flatten all template variants (LAMMPS + PLUMED) for validation + all_conts = [c for c_list in conts for c in c_list] check_revisions_completeness( - conts[0], + all_conts, list(self.revisions.keys()), template_raw=template_raw, ) diff --git a/tests/exploration/test_lmp_templ_task_group.py b/tests/exploration/test_lmp_templ_task_group.py index 17bb95c7..72dfd39c 100644 --- a/tests/exploration/test_lmp_templ_task_group.py +++ b/tests/exploration/test_lmp_templ_task_group.py @@ -577,3 +577,43 @@ def test_lammps_internal_variables_not_flagged(self): # ${TEMP} is LAMMPS syntax, not a dpgen revision variable — should not raise task_group.make_task() self.assertEqual(len(task_group), 1) + + def test_plumed_template_undefined_variable_raises(self): + """V_* in PLUMED template but not in revisions should also be caught.""" + lmp_template = textwrap.dedent( + """\ + variable NSTEPS equal V_NSTEPS + variable TEMP equal V_TEMP + + pair_style deepmd + pair_coeff * * + dump dpgen_dump + fix dpgen_plm + run ${NSTEPS} + """ + ) + plm_template = textwrap.dedent( + """\ + DISTANCE ATOMS=3,5 LABEL=d1 + RESTRAINT ARG=d1 AT=V_DIST0 KAPPA=150.0 LABEL=restraint + """ + ) + self._write_template(lmp_template) + plm_fname = Path("plm_precheck.template") + plm_fname.write_text(plm_template) + try: + task_group = LmpTemplateTaskGroup() + task_group.set_conf(self.confs) + task_group.set_lmp( + self.numb_models, + self.lmp_template_fname, + plm_template_fname=str(plm_fname), + # V_DIST0 is used in PLUMED template but NOT defined here + revisions={"V_NSTEPS": [1000], "V_TEMP": [300]}, + traj_freq=self.traj_freq, + ) + with self.assertRaises(ValueError) as ctx: + task_group.make_task() + self.assertIn("V_DIST0", str(ctx.exception)) + finally: + plm_fname.unlink(missing_ok=True) From 60497af989b7cba36d541537340b560691423cbc Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 22 Jul 2026 01:57:19 +0000 Subject: [PATCH 04/21] fix: downgrade empty-revisions check from error to warning The ValueError for 'no revisions but template has V_*' broke existing tests (test_submit.TestSubmitCmdStd) that legitimately use templates with V_* placeholders without providing revisions (e.g., customized- lmp-template workflows where substitution is handled externally). Change to warnings.warn() instead of raise ValueError for the empty-revisions case. The hard ValueError is still raised when revisions ARE provided but incomplete (the important fail-fast case). Update tests to expect UserWarning instead of ValueError. --- .../task/lmp_template_task_group.py | 10 ++++--- .../exploration/test_lmp_templ_task_group.py | 27 +++++++++++++------ .../94d39895-028f-456c-9aa5-f4ef568c8bdd | 1 + .../dcc8fdef-431f-4319-baed-7af17279fc76 | 1 + .../624cf245-9304-4f86-87d1-0e02ab7b1818 | 1 + .../tmp5vwchqhk/bar | 1 + .../tmp5vwchqhk/tar | 1 + .../dd47dec4-413c-4a0d-bf09-06ef71eed82d | 1 + .../53c59fa1-24c1-4294-842a-a30bd879463f | 1 + .../0b194043-4a01-44da-9b41-82ece9593c13 | 1 + .../tmp7w6dps2y/bar | 1 + .../tmp7w6dps2y/tar | 1 + .../e4755d22-db3b-4c5c-95f5-fe878598107f | 1 + .../66ffad38-5bd9-4393-becf-c5b9e877b511 | 1 + .../lib/python3.12/site-packages/dflow | 1 + .../lib/python3.12/site-packages/jsonpickle | 1 + .../tmp4ad_vu54/tests/mocked_ops.py | 1 + .../89374e85-79d6-4678-8102-69e3e18ac409 | 1 + .../4a5ca489-eb72-450c-b224-2b82ff7e7c57 | 1 + 19 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd create mode 100644 upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 create mode 100644 upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 create mode 120000 upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar create mode 120000 upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar create mode 100644 upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d create mode 100644 upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f create mode 100644 upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 create mode 120000 upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar create mode 120000 upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar create mode 100644 upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f create mode 100644 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 create mode 120000 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow create mode 120000 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle create mode 120000 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py create mode 100644 upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 create mode 100644 upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index 72cf55e9..a9650d7f 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -117,16 +117,20 @@ def make_task( template_raw=template_raw, ) else: - # Even without revisions, check if template has V_* that need substitution + # Warn (but don't error) if template has V_* but no revisions provided. + # This can be legitimate for customized-lmp-template workflows or tests. combined = "\n".join(self.lmp_template) if self.plm_set: combined += "\n" + "\n".join(self.plm_template) unreplaced = find_unreplaced_variables(combined) if unreplaced: - raise ValueError( + warnings.warn( f"LAMMPS template contains revision variable(s) {sorted(unreplaced)} " f"but no 'revisions' dict was provided. " - f"Please define them in 'revisions' in your exploration config." + f"These variables will NOT be substituted. " + f"If this is unintentional, add them to 'revisions' in your " + f"exploration config.", + stacklevel=2, ) nconts = len(conts[0]) for cc, ii in itertools.product(confs, range(nconts)): # type: ignore diff --git a/tests/exploration/test_lmp_templ_task_group.py b/tests/exploration/test_lmp_templ_task_group.py index 72dfd39c..d8ff77c4 100644 --- a/tests/exploration/test_lmp_templ_task_group.py +++ b/tests/exploration/test_lmp_templ_task_group.py @@ -388,7 +388,7 @@ def test_lmp_plm(self): idx += 1 def test_lmp_empty(self): - """Empty revisions with template containing V_* should now raise ValueError.""" + """Empty revisions with template containing V_* should warn but succeed.""" task_group = LmpTemplateTaskGroup() task_group.set_conf(self.confs) task_group.set_lmp( @@ -397,10 +397,16 @@ def test_lmp_empty(self): revisions=self.rev_empty, traj_freq=self.traj_freq, ) - with self.assertRaises(ValueError) as ctx: + import warnings as _warnings + + with _warnings.catch_warnings(record=True) as w: + _warnings.simplefilter("always") task_group.make_task() - self.assertIn("V_NSTEPS", str(ctx.exception)) - self.assertIn("V_TEMP", str(ctx.exception)) + var_warnings = [x for x in w if "V_NSTEPS" in str(x.message)] + self.assertGreater(len(var_warnings), 0) + # Should still produce tasks + ngroup = len(task_group) + self.assertEqual(ngroup, len(self.confs)) def test_lmp_pimd(self): task_group = LmpTemplateTaskGroup() @@ -470,7 +476,7 @@ def test_undefined_variable_raises(self): self.assertIn("undefined revision variable", str(ctx.exception).lower()) def test_no_revisions_but_template_has_variables(self): - """Template has V_* variables but no revisions provided at all.""" + """Template has V_* variables but no revisions — should warn, not error.""" template = textwrap.dedent( """\ variable NSTEPS equal V_NSTEPS @@ -491,10 +497,15 @@ def test_no_revisions_but_template_has_variables(self): revisions={}, traj_freq=self.traj_freq, ) - with self.assertRaises(ValueError) as ctx: + import warnings as _warnings + + with _warnings.catch_warnings(record=True) as w: + _warnings.simplefilter("always") task_group.make_task() - self.assertIn("V_NSTEPS", str(ctx.exception)) - self.assertIn("V_TEMP", str(ctx.exception)) + var_warnings = [x for x in w if "V_NSTEPS" in str(x.message)] + self.assertGreater(len(var_warnings), 0) + # Should still succeed + self.assertEqual(len(task_group), 1) def test_all_variables_defined_no_error(self): """All V_* variables are covered by revisions — should succeed.""" diff --git a/upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd b/upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd new file mode 100644 index 00000000..7519394f --- /dev/null +++ b/upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd @@ -0,0 +1 @@ +{"path_list": []} \ No newline at end of file diff --git a/upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 b/upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 new file mode 100644 index 00000000..7519394f --- /dev/null +++ b/upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 @@ -0,0 +1 @@ +{"path_list": []} \ No newline at end of file diff --git a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 new file mode 100644 index 00000000..647741c3 --- /dev/null +++ b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 @@ -0,0 +1 @@ +{"path_list": [{"dflow_list_item": "bar", "order": 0}, {"dflow_list_item": "tar", "order": 1}]} \ No newline at end of file diff --git a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar new file mode 120000 index 00000000..a3f038af --- /dev/null +++ b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar @@ -0,0 +1 @@ +/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/bar \ No newline at end of file diff --git a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar new file mode 120000 index 00000000..5ceb6c49 --- /dev/null +++ b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar @@ -0,0 +1 @@ +/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/tar \ No newline at end of file diff --git a/upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d b/upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d new file mode 100644 index 00000000..7519394f --- /dev/null +++ b/upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d @@ -0,0 +1 @@ +{"path_list": []} \ No newline at end of file diff --git a/upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f b/upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f new file mode 100644 index 00000000..6be45e2f --- /dev/null +++ b/upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f @@ -0,0 +1 @@ +{"path_list": [{"dflow_list_item": "student_model.pb", "order": 0}]} \ No newline at end of file diff --git a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 new file mode 100644 index 00000000..647741c3 --- /dev/null +++ b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 @@ -0,0 +1 @@ +{"path_list": [{"dflow_list_item": "bar", "order": 0}, {"dflow_list_item": "tar", "order": 1}]} \ No newline at end of file diff --git a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar new file mode 120000 index 00000000..a3f038af --- /dev/null +++ b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar @@ -0,0 +1 @@ +/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/bar \ No newline at end of file diff --git a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar new file mode 120000 index 00000000..5ceb6c49 --- /dev/null +++ b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar @@ -0,0 +1 @@ +/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/tar \ No newline at end of file diff --git a/upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f b/upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f new file mode 100644 index 00000000..7519394f --- /dev/null +++ b/upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f @@ -0,0 +1 @@ +{"path_list": []} \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 new file mode 100644 index 00000000..a3c6fad4 --- /dev/null +++ b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 @@ -0,0 +1 @@ +{"path_list": [{"dflow_list_item": "tests/mocked_ops.py", "order": 0}, {"dflow_list_item": "root/miniconda3/lib/python3.12/site-packages/dflow", "order": 1}, {"dflow_list_item": "root/miniconda3/lib/python3.12/site-packages/jsonpickle", "order": 2}]} \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow new file mode 120000 index 00000000..64eea929 --- /dev/null +++ b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow @@ -0,0 +1 @@ +/root/miniconda3/lib/python3.12/site-packages/dflow \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle new file mode 120000 index 00000000..e1c5737a --- /dev/null +++ b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle @@ -0,0 +1 @@ +/root/miniconda3/lib/python3.12/site-packages/jsonpickle \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py new file mode 120000 index 00000000..12e876ff --- /dev/null +++ b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py @@ -0,0 +1 @@ +/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/tests/mocked_ops.py \ No newline at end of file diff --git a/upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 b/upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 new file mode 100644 index 00000000..7519394f --- /dev/null +++ b/upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 @@ -0,0 +1 @@ +{"path_list": []} \ No newline at end of file diff --git a/upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 b/upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 new file mode 100644 index 00000000..7519394f --- /dev/null +++ b/upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 @@ -0,0 +1 @@ +{"path_list": []} \ No newline at end of file From edd20b13d3f685daef8a912e24c9512241af3042 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 22 Jul 2026 01:58:36 +0000 Subject: [PATCH 05/21] chore: remove test upload artifacts and add to .gitignore --- .gitignore | 1 + .../tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd | 1 - .../tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 | 1 - .../tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 | 1 - upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar | 1 - upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar | 1 - .../tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d | 1 - .../tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f | 1 - .../tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 | 1 - upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar | 1 - upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar | 1 - .../tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f | 1 - .../tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 | 1 - .../root/miniconda3/lib/python3.12/site-packages/dflow | 1 - .../root/miniconda3/lib/python3.12/site-packages/jsonpickle | 1 - .../tmp4ad_vu54/tests/mocked_ops.py | 1 - .../tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 | 1 - .../tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 | 1 - 18 files changed, 1 insertion(+), 17 deletions(-) delete mode 100644 upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd delete mode 100644 upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 delete mode 100644 upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 delete mode 120000 upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar delete mode 120000 upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar delete mode 100644 upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d delete mode 100644 upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f delete mode 100644 upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 delete mode 120000 upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar delete mode 120000 upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar delete mode 100644 upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f delete mode 100644 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 delete mode 120000 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow delete mode 120000 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle delete mode 120000 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py delete mode 100644 upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 delete mode 100644 upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 diff --git a/.gitignore b/.gitignore index f471ce9e..6bb3b858 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,4 @@ tests/init_data/ tests/incar tests/potcar tests/tmp* +upload/ diff --git a/upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd b/upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd deleted file mode 100644 index 7519394f..00000000 --- a/upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd +++ /dev/null @@ -1 +0,0 @@ -{"path_list": []} \ No newline at end of file diff --git a/upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 b/upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 deleted file mode 100644 index 7519394f..00000000 --- a/upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 +++ /dev/null @@ -1 +0,0 @@ -{"path_list": []} \ No newline at end of file diff --git a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 deleted file mode 100644 index 647741c3..00000000 --- a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 +++ /dev/null @@ -1 +0,0 @@ -{"path_list": [{"dflow_list_item": "bar", "order": 0}, {"dflow_list_item": "tar", "order": 1}]} \ No newline at end of file diff --git a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar deleted file mode 120000 index a3f038af..00000000 --- a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar +++ /dev/null @@ -1 +0,0 @@ -/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/bar \ No newline at end of file diff --git a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar deleted file mode 120000 index 5ceb6c49..00000000 --- a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar +++ /dev/null @@ -1 +0,0 @@ -/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/tar \ No newline at end of file diff --git a/upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d b/upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d deleted file mode 100644 index 7519394f..00000000 --- a/upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d +++ /dev/null @@ -1 +0,0 @@ -{"path_list": []} \ No newline at end of file diff --git a/upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f b/upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f deleted file mode 100644 index 6be45e2f..00000000 --- a/upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f +++ /dev/null @@ -1 +0,0 @@ -{"path_list": [{"dflow_list_item": "student_model.pb", "order": 0}]} \ No newline at end of file diff --git a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 deleted file mode 100644 index 647741c3..00000000 --- a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 +++ /dev/null @@ -1 +0,0 @@ -{"path_list": [{"dflow_list_item": "bar", "order": 0}, {"dflow_list_item": "tar", "order": 1}]} \ No newline at end of file diff --git a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar deleted file mode 120000 index a3f038af..00000000 --- a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar +++ /dev/null @@ -1 +0,0 @@ -/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/bar \ No newline at end of file diff --git a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar deleted file mode 120000 index 5ceb6c49..00000000 --- a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar +++ /dev/null @@ -1 +0,0 @@ -/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/tar \ No newline at end of file diff --git a/upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f b/upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f deleted file mode 100644 index 7519394f..00000000 --- a/upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f +++ /dev/null @@ -1 +0,0 @@ -{"path_list": []} \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 deleted file mode 100644 index a3c6fad4..00000000 --- a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 +++ /dev/null @@ -1 +0,0 @@ -{"path_list": [{"dflow_list_item": "tests/mocked_ops.py", "order": 0}, {"dflow_list_item": "root/miniconda3/lib/python3.12/site-packages/dflow", "order": 1}, {"dflow_list_item": "root/miniconda3/lib/python3.12/site-packages/jsonpickle", "order": 2}]} \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow deleted file mode 120000 index 64eea929..00000000 --- a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow +++ /dev/null @@ -1 +0,0 @@ -/root/miniconda3/lib/python3.12/site-packages/dflow \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle deleted file mode 120000 index e1c5737a..00000000 --- a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle +++ /dev/null @@ -1 +0,0 @@ -/root/miniconda3/lib/python3.12/site-packages/jsonpickle \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py deleted file mode 120000 index 12e876ff..00000000 --- a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py +++ /dev/null @@ -1 +0,0 @@ -/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/tests/mocked_ops.py \ No newline at end of file diff --git a/upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 b/upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 deleted file mode 100644 index 7519394f..00000000 --- a/upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 +++ /dev/null @@ -1 +0,0 @@ -{"path_list": []} \ No newline at end of file diff --git a/upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 b/upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 deleted file mode 100644 index 7519394f..00000000 --- a/upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 +++ /dev/null @@ -1 +0,0 @@ -{"path_list": []} \ No newline at end of file From 01ee42d90bcaa29a3e58ee4ed99eace55a9625d3 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 22 Jul 2026 02:00:50 +0000 Subject: [PATCH 06/21] Revert "chore: remove test upload artifacts and add to .gitignore" This reverts commit edd20b13d3f685daef8a912e24c9512241af3042. --- .gitignore | 1 - .../tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd | 1 + .../tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 | 1 + .../tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 | 1 + upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar | 1 + upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar | 1 + .../tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d | 1 + .../tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f | 1 + .../tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 | 1 + upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar | 1 + upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar | 1 + .../tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f | 1 + .../tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 | 1 + .../root/miniconda3/lib/python3.12/site-packages/dflow | 1 + .../root/miniconda3/lib/python3.12/site-packages/jsonpickle | 1 + .../tmp4ad_vu54/tests/mocked_ops.py | 1 + .../tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 | 1 + .../tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 | 1 + 18 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd create mode 100644 upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 create mode 100644 upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 create mode 120000 upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar create mode 120000 upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar create mode 100644 upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d create mode 100644 upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f create mode 100644 upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 create mode 120000 upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar create mode 120000 upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar create mode 100644 upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f create mode 100644 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 create mode 120000 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow create mode 120000 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle create mode 120000 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py create mode 100644 upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 create mode 100644 upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 diff --git a/.gitignore b/.gitignore index 6bb3b858..f471ce9e 100644 --- a/.gitignore +++ b/.gitignore @@ -53,4 +53,3 @@ tests/init_data/ tests/incar tests/potcar tests/tmp* -upload/ diff --git a/upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd b/upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd new file mode 100644 index 00000000..7519394f --- /dev/null +++ b/upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd @@ -0,0 +1 @@ +{"path_list": []} \ No newline at end of file diff --git a/upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 b/upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 new file mode 100644 index 00000000..7519394f --- /dev/null +++ b/upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 @@ -0,0 +1 @@ +{"path_list": []} \ No newline at end of file diff --git a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 new file mode 100644 index 00000000..647741c3 --- /dev/null +++ b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 @@ -0,0 +1 @@ +{"path_list": [{"dflow_list_item": "bar", "order": 0}, {"dflow_list_item": "tar", "order": 1}]} \ No newline at end of file diff --git a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar new file mode 120000 index 00000000..a3f038af --- /dev/null +++ b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar @@ -0,0 +1 @@ +/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/bar \ No newline at end of file diff --git a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar new file mode 120000 index 00000000..5ceb6c49 --- /dev/null +++ b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar @@ -0,0 +1 @@ +/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/tar \ No newline at end of file diff --git a/upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d b/upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d new file mode 100644 index 00000000..7519394f --- /dev/null +++ b/upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d @@ -0,0 +1 @@ +{"path_list": []} \ No newline at end of file diff --git a/upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f b/upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f new file mode 100644 index 00000000..6be45e2f --- /dev/null +++ b/upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f @@ -0,0 +1 @@ +{"path_list": [{"dflow_list_item": "student_model.pb", "order": 0}]} \ No newline at end of file diff --git a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 new file mode 100644 index 00000000..647741c3 --- /dev/null +++ b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 @@ -0,0 +1 @@ +{"path_list": [{"dflow_list_item": "bar", "order": 0}, {"dflow_list_item": "tar", "order": 1}]} \ No newline at end of file diff --git a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar new file mode 120000 index 00000000..a3f038af --- /dev/null +++ b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar @@ -0,0 +1 @@ +/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/bar \ No newline at end of file diff --git a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar new file mode 120000 index 00000000..5ceb6c49 --- /dev/null +++ b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar @@ -0,0 +1 @@ +/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/tar \ No newline at end of file diff --git a/upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f b/upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f new file mode 100644 index 00000000..7519394f --- /dev/null +++ b/upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f @@ -0,0 +1 @@ +{"path_list": []} \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 new file mode 100644 index 00000000..a3c6fad4 --- /dev/null +++ b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 @@ -0,0 +1 @@ +{"path_list": [{"dflow_list_item": "tests/mocked_ops.py", "order": 0}, {"dflow_list_item": "root/miniconda3/lib/python3.12/site-packages/dflow", "order": 1}, {"dflow_list_item": "root/miniconda3/lib/python3.12/site-packages/jsonpickle", "order": 2}]} \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow new file mode 120000 index 00000000..64eea929 --- /dev/null +++ b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow @@ -0,0 +1 @@ +/root/miniconda3/lib/python3.12/site-packages/dflow \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle new file mode 120000 index 00000000..e1c5737a --- /dev/null +++ b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle @@ -0,0 +1 @@ +/root/miniconda3/lib/python3.12/site-packages/jsonpickle \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py new file mode 120000 index 00000000..12e876ff --- /dev/null +++ b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py @@ -0,0 +1 @@ +/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/tests/mocked_ops.py \ No newline at end of file diff --git a/upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 b/upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 new file mode 100644 index 00000000..7519394f --- /dev/null +++ b/upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 @@ -0,0 +1 @@ +{"path_list": []} \ No newline at end of file diff --git a/upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 b/upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 new file mode 100644 index 00000000..7519394f --- /dev/null +++ b/upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 @@ -0,0 +1 @@ +{"path_list": []} \ No newline at end of file From 620b5cbbfe2167f441429afb020d59d070625be9 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 22 Jul 2026 02:01:20 +0000 Subject: [PATCH 07/21] chore: remove accidentally committed test artifacts --- .../tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd | 1 - .../tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 | 1 - .../tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 | 1 - upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar | 1 - upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar | 1 - .../tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d | 1 - .../tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f | 1 - .../tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 | 1 - upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar | 1 - upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar | 1 - .../tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f | 1 - .../tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 | 1 - .../root/miniconda3/lib/python3.12/site-packages/dflow | 1 - .../root/miniconda3/lib/python3.12/site-packages/jsonpickle | 1 - .../tmp4ad_vu54/tests/mocked_ops.py | 1 - .../tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 | 1 - .../tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 | 1 - 17 files changed, 17 deletions(-) delete mode 100644 upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd delete mode 100644 upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 delete mode 100644 upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 delete mode 120000 upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar delete mode 120000 upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar delete mode 100644 upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d delete mode 100644 upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f delete mode 100644 upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 delete mode 120000 upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar delete mode 120000 upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar delete mode 100644 upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f delete mode 100644 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 delete mode 120000 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow delete mode 120000 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle delete mode 120000 upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py delete mode 100644 upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 delete mode 100644 upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 diff --git a/upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd b/upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd deleted file mode 100644 index 7519394f..00000000 --- a/upload/11fb7126-7b2d-4b61-a7c9-5a2cd22c74c2/tmp95a6gmsp/.dflow/94d39895-028f-456c-9aa5-f4ef568c8bdd +++ /dev/null @@ -1 +0,0 @@ -{"path_list": []} \ No newline at end of file diff --git a/upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 b/upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 deleted file mode 100644 index 7519394f..00000000 --- a/upload/13ae4c9d-5b59-4ca0-b651-264d4469cad5/tmps33e6rm3/.dflow/dcc8fdef-431f-4319-baed-7af17279fc76 +++ /dev/null @@ -1 +0,0 @@ -{"path_list": []} \ No newline at end of file diff --git a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 deleted file mode 100644 index 647741c3..00000000 --- a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/.dflow/624cf245-9304-4f86-87d1-0e02ab7b1818 +++ /dev/null @@ -1 +0,0 @@ -{"path_list": [{"dflow_list_item": "bar", "order": 0}, {"dflow_list_item": "tar", "order": 1}]} \ No newline at end of file diff --git a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar deleted file mode 120000 index a3f038af..00000000 --- a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/bar +++ /dev/null @@ -1 +0,0 @@ -/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/bar \ No newline at end of file diff --git a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar b/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar deleted file mode 120000 index 5ceb6c49..00000000 --- a/upload/303d02e7-3632-47bf-9039-0b6ad036e715/tmp5vwchqhk/tar +++ /dev/null @@ -1 +0,0 @@ -/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/tar \ No newline at end of file diff --git a/upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d b/upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d deleted file mode 100644 index 7519394f..00000000 --- a/upload/36f2b24f-05e7-474b-9274-74e58e01f7a5/tmp8k1r53e3/.dflow/dd47dec4-413c-4a0d-bf09-06ef71eed82d +++ /dev/null @@ -1 +0,0 @@ -{"path_list": []} \ No newline at end of file diff --git a/upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f b/upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f deleted file mode 100644 index 6be45e2f..00000000 --- a/upload/6a1eed3c-49b5-4aea-b1b8-c8e074a65357/tmpph01l6v8/.dflow/53c59fa1-24c1-4294-842a-a30bd879463f +++ /dev/null @@ -1 +0,0 @@ -{"path_list": [{"dflow_list_item": "student_model.pb", "order": 0}]} \ No newline at end of file diff --git a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 deleted file mode 100644 index 647741c3..00000000 --- a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/.dflow/0b194043-4a01-44da-9b41-82ece9593c13 +++ /dev/null @@ -1 +0,0 @@ -{"path_list": [{"dflow_list_item": "bar", "order": 0}, {"dflow_list_item": "tar", "order": 1}]} \ No newline at end of file diff --git a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar deleted file mode 120000 index a3f038af..00000000 --- a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/bar +++ /dev/null @@ -1 +0,0 @@ -/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/bar \ No newline at end of file diff --git a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar b/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar deleted file mode 120000 index 5ceb6c49..00000000 --- a/upload/890e3650-96dd-48c2-b40b-b9d11a476ddc/tmp7w6dps2y/tar +++ /dev/null @@ -1 +0,0 @@ -/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/tar \ No newline at end of file diff --git a/upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f b/upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f deleted file mode 100644 index 7519394f..00000000 --- a/upload/aed09d00-fe77-4f28-8f6f-97d40a0b6648/tmpz65hbgx5/.dflow/e4755d22-db3b-4c5c-95f5-fe878598107f +++ /dev/null @@ -1 +0,0 @@ -{"path_list": []} \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 deleted file mode 100644 index a3c6fad4..00000000 --- a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/.dflow/66ffad38-5bd9-4393-becf-c5b9e877b511 +++ /dev/null @@ -1 +0,0 @@ -{"path_list": [{"dflow_list_item": "tests/mocked_ops.py", "order": 0}, {"dflow_list_item": "root/miniconda3/lib/python3.12/site-packages/dflow", "order": 1}, {"dflow_list_item": "root/miniconda3/lib/python3.12/site-packages/jsonpickle", "order": 2}]} \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow deleted file mode 120000 index 64eea929..00000000 --- a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/dflow +++ /dev/null @@ -1 +0,0 @@ -/root/miniconda3/lib/python3.12/site-packages/dflow \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle deleted file mode 120000 index e1c5737a..00000000 --- a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/root/miniconda3/lib/python3.12/site-packages/jsonpickle +++ /dev/null @@ -1 +0,0 @@ -/root/miniconda3/lib/python3.12/site-packages/jsonpickle \ No newline at end of file diff --git a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py b/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py deleted file mode 120000 index 12e876ff..00000000 --- a/upload/d86e2d0e-47fc-4ea3-85e7-71274e1b777a/tmp4ad_vu54/tests/mocked_ops.py +++ /dev/null @@ -1 +0,0 @@ -/aisi-nas/guomingyu/personal/aluminium_ems/algorithms/dpgen2/tests/mocked_ops.py \ No newline at end of file diff --git a/upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 b/upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 deleted file mode 100644 index 7519394f..00000000 --- a/upload/d97ec93d-f54e-4c43-9a00-1a22cb197a33/tmplsb5l24q/.dflow/89374e85-79d6-4678-8102-69e3e18ac409 +++ /dev/null @@ -1 +0,0 @@ -{"path_list": []} \ No newline at end of file diff --git a/upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 b/upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 deleted file mode 100644 index 7519394f..00000000 --- a/upload/deb95540-6f78-49d0-bcbb-4ba0b1a36c05/tmp9lg5w8l0/.dflow/4a5ca489-eb72-450c-b224-2b82ff7e7c57 +++ /dev/null @@ -1 +0,0 @@ -{"path_list": []} \ No newline at end of file From 44ddb10fae76b9fead161e4718e0228627a8055a Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 22 Jul 2026 02:16:35 +0000 Subject: [PATCH 08/21] fix: strip LAMMPS comments before scanning for unreplaced V_* variables Avoid false positives when V_* appears in comments (e.g., '# TODO: add V_PRESS support later'). The regex now only scans non-comment portions of each line. Add _strip_lammps_comments() helper and test_commented_variables_not_flagged. --- .../task/lmp_template_task_group.py | 24 ++++++++++++++++- .../exploration/test_lmp_templ_task_group.py | 27 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index a9650d7f..73e081c9 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -258,9 +258,30 @@ def revise_by_keys(lmp_lines, keys, values): ) +def _strip_lammps_comments(content: str) -> str: + """Remove LAMMPS-style comments (# to end of line) to avoid false positives. + + This prevents V_* patterns in comments (e.g., "# set V_PRESS later") + from being flagged as unreplaced variables. + """ + lines = content.split("\n") + stripped = [] + for line in lines: + # LAMMPS comments start with # (not inside quotes for our purposes) + idx = line.find("#") + if idx >= 0: + stripped.append(line[:idx]) + else: + stripped.append(line) + return "\n".join(stripped) + + def find_unreplaced_variables(content: str) -> Set[str]: """Scan text for remaining V_* revision placeholders that were not substituted. + Strips LAMMPS comments before scanning to avoid false positives from + commented-out variable references. + Parameters ---------- content : str @@ -271,7 +292,8 @@ def find_unreplaced_variables(content: str) -> Set[str]: Set[str] Set of variable names (e.g. {"V_PRESS", "V_UNDEFINED"}) still present. """ - return set(_REVISION_VARIABLE_PATTERN.findall(content)) + stripped = _strip_lammps_comments(content) + return set(_REVISION_VARIABLE_PATTERN.findall(stripped)) def check_revisions_completeness( diff --git a/tests/exploration/test_lmp_templ_task_group.py b/tests/exploration/test_lmp_templ_task_group.py index d8ff77c4..d899caf9 100644 --- a/tests/exploration/test_lmp_templ_task_group.py +++ b/tests/exploration/test_lmp_templ_task_group.py @@ -628,3 +628,30 @@ def test_plumed_template_undefined_variable_raises(self): self.assertIn("V_DIST0", str(ctx.exception)) finally: plm_fname.unlink(missing_ok=True) + + def test_commented_variables_not_flagged(self): + """V_* in LAMMPS comments should NOT trigger errors.""" + template = textwrap.dedent( + """\ + variable NSTEPS equal V_NSTEPS + # TODO: add V_PRESS support later + # variable PRESS equal V_PRESS + + pair_style deepmd + pair_coeff * * + dump dpgen_dump + run ${NSTEPS} + """ + ) + self._write_template(template) + task_group = LmpTemplateTaskGroup() + task_group.set_conf(self.confs) + task_group.set_lmp( + self.numb_models, + self.lmp_template_fname, + revisions={"V_NSTEPS": [1000]}, + traj_freq=self.traj_freq, + ) + # V_PRESS is only in comments — should NOT raise + task_group.make_task() + self.assertEqual(len(task_group), 1) From 67e57bc718a40aa780ebc8523e024f31e1e8d938 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 12 Aug 2026 04:43:50 +0000 Subject: [PATCH 09/21] fix: validate complete LAMMPS revision tokens --- .../task/lmp_template_task_group.py | 74 ++++++++++++++----- .../exploration/test_lmp_templ_task_group.py | 47 ++++++++++++ 2 files changed, 101 insertions(+), 20 deletions(-) diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index 73e081c9..2181051a 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -229,9 +229,9 @@ def revise_lmp_input_dump(lmp_lines, trj_freq, pimd_bead=None): lmp_traj_file_name = ( lmp_pimd_traj_name % pimd_bead if pimd_bead is not None else lmp_traj_name ) - lmp_lines[ - idx - ] = f"dump dpgen_dump all custom {trj_freq} {lmp_traj_file_name} id type x y z" + lmp_lines[idx] = ( + f"dump dpgen_dump all custom {trj_freq} {lmp_traj_file_name} id type x y z" + ) return lmp_lines @@ -245,9 +245,12 @@ def revise_lmp_input_plm(lmp_lines, in_plm, out_plm="output.plumed"): def revise_by_keys(lmp_lines, keys, values): + """Replace complete revision tokens without matching identifier prefixes.""" for kk, vv in zip(keys, values): # type: ignore + replacement = str(vv) + pattern = re.compile(rf"(? str: - """Remove LAMMPS-style comments (# to end of line) to avoid false positives. + """Remove unquoted LAMMPS comments while preserving quoted hash characters. This prevents V_* patterns in comments (e.g., "# set V_PRESS later") - from being flagged as unreplaced variables. + from being flagged as unreplaced variables without hiding executable + placeholders inside single- or double-quoted strings. """ - lines = content.split("\n") - stripped = [] - for line in lines: - # LAMMPS comments start with # (not inside quotes for our purposes) - idx = line.find("#") - if idx >= 0: - stripped.append(line[:idx]) - else: - stripped.append(line) + stripped: List[str] = [] + for line in content.split("\n"): + quote: Optional[str] = None + escaped = False + kept: List[str] = [] + for char in line: + if escaped: + kept.append(char) + escaped = False + elif char == "\\" and quote is not None: + kept.append(char) + escaped = True + elif char in ("'", '"'): + if quote == char: + quote = None + elif quote is None: + quote = char + kept.append(char) + elif char == "#" and quote is None: + break + else: + kept.append(char) + stripped.append("".join(kept)) return "\n".join(stripped) @@ -303,11 +321,13 @@ def check_revisions_completeness( ) -> None: """Validate that all V_* placeholders in the template have been substituted. - This function performs two checks: - 1. **Post-substitution residual check**: After applying revisions, scan the output + This function performs three checks: + 1. **Raw-template definition check**: Compare complete placeholder tokens with + the revision keys before applying substitutions. + 2. **Post-substitution residual check**: After applying revisions, scan the output for any remaining V_* variables that were not replaced. This catches typos in template variables or missing keys in revisions. - 2. **Unused key warning**: If a revision key is defined but never appears in the + 3. **Unused key warning**: If a revision key is defined but never appears in the raw template, emit a warning (possible typo in the key name). Parameters @@ -324,7 +344,21 @@ def check_revisions_completeness( ValueError If unreplaced V_* variables are found in substituted templates. """ - # Check 1: Residual unreplaced variables + revision_key_set = set(revision_keys) + + # Check 1: Compare raw tokens before substitution so a shorter defined key + # cannot erase the prefix of a longer undefined placeholder. + raw_variables = find_unreplaced_variables(template_raw) if template_raw else set() + undefined_raw = raw_variables - revision_key_set + if undefined_raw: + raise ValueError( + f"LAMMPS template contains undefined revision variable(s): " + f"{sorted(undefined_raw)}. Defined revisions: {sorted(revision_keys)}. " + f"Please add missing variables to 'revisions' in your exploration config, " + f"or remove them from the template." + ) + + # Check 2: Residual unreplaced variables all_unreplaced: Set[str] = set() for content in templates_content: all_unreplaced.update(find_unreplaced_variables(content)) @@ -338,7 +372,7 @@ def check_revisions_completeness( f"or remove them from the template." ) - # Check 2: Unused revision keys (warning only) + # Check 3: Unused revision keys (warning only) if template_raw and revision_keys: for key in revision_keys: if key not in template_raw: diff --git a/tests/exploration/test_lmp_templ_task_group.py b/tests/exploration/test_lmp_templ_task_group.py index d899caf9..80486a5a 100644 --- a/tests/exploration/test_lmp_templ_task_group.py +++ b/tests/exploration/test_lmp_templ_task_group.py @@ -33,6 +33,10 @@ ExplorationStage, LmpTemplateTaskGroup, ) +from dpgen2.exploration.task.lmp_template_task_group import ( + find_unreplaced_variables, + revise_by_keys, +) in_lmp_template = textwrap.dedent( """variable NSTEPS equal V_NSTEPS @@ -655,3 +659,46 @@ def test_commented_variables_not_flagged(self): # V_PRESS is only in comments — should NOT raise task_group.make_task() self.assertEqual(len(task_group), 1) + + def test_undefined_longer_placeholder_raises_before_substitution(self): + """A defined prefix must not erase a longer undefined placeholder.""" + template = textwrap.dedent( + """\ + variable TEMP equal V_TEMPERATURE + + pair_style deepmd + pair_coeff * * + dump dpgen_dump + run 1 + """ + ) + self._write_template(template) + task_group = LmpTemplateTaskGroup() + task_group.set_conf(self.confs) + task_group.set_lmp( + self.numb_models, + self.lmp_template_fname, + revisions={"V_TEMP": [300]}, + traj_freq=self.traj_freq, + ) + with self.assertRaisesRegex(ValueError, "V_TEMPERATURE"): + task_group.make_task() + + def test_overlapping_defined_placeholders_are_replaced_as_tokens(self): + lines = ["print V_TEMP V_TEMPERATURE"] + revised = revise_by_keys(lines, ["V_TEMP", "V_TEMPERATURE"], [300, 450]) + self.assertEqual(revised, ["print 300 450"]) + + def test_quoted_hashes_preserve_revision_placeholders(self): + content = textwrap.dedent( + r"""\ + print "# target V_MISSING" + print 'hash # target V_OTHER' + print "escaped \"# target V_ESCAPED" + # V_COMMENT_ONLY + """ + ) + self.assertEqual( + find_unreplaced_variables(content), + {"V_MISSING", "V_OTHER", "V_ESCAPED"}, + ) From bb912dff970c1780e42a371c60f90e7e27a24891 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 04:45:59 +0000 Subject: [PATCH 10/21] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- dpgen2/exploration/task/lmp_template_task_group.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index 2181051a..d93609d9 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -229,9 +229,9 @@ def revise_lmp_input_dump(lmp_lines, trj_freq, pimd_bead=None): lmp_traj_file_name = ( lmp_pimd_traj_name % pimd_bead if pimd_bead is not None else lmp_traj_name ) - lmp_lines[idx] = ( - f"dump dpgen_dump all custom {trj_freq} {lmp_traj_file_name} id type x y z" - ) + lmp_lines[ + idx + ] = f"dump dpgen_dump all custom {trj_freq} {lmp_traj_file_name} id type x y z" return lmp_lines From 0f17a01a9344b344840ece6574ca2d3af7d2aa98 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 12 Aug 2026 05:24:35 +0000 Subject: [PATCH 11/21] fix: match unused revision keys as tokens --- dpgen2/exploration/task/lmp_template_task_group.py | 2 +- tests/exploration/test_lmp_templ_task_group.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index d93609d9..21ef2d50 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -375,7 +375,7 @@ def check_revisions_completeness( # Check 3: Unused revision keys (warning only) if template_raw and revision_keys: for key in revision_keys: - if key not in template_raw: + if key not in raw_variables: warnings.warn( f"Revision key '{key}' is defined but does not appear in the " f"LAMMPS/PLUMED template. Possible typo?", diff --git a/tests/exploration/test_lmp_templ_task_group.py b/tests/exploration/test_lmp_templ_task_group.py index 80486a5a..c1ec6591 100644 --- a/tests/exploration/test_lmp_templ_task_group.py +++ b/tests/exploration/test_lmp_templ_task_group.py @@ -34,6 +34,7 @@ LmpTemplateTaskGroup, ) from dpgen2.exploration.task.lmp_template_task_group import ( + check_revisions_completeness, find_unreplaced_variables, revise_by_keys, ) @@ -702,3 +703,12 @@ def test_quoted_hashes_preserve_revision_placeholders(self): find_unreplaced_variables(content), {"V_MISSING", "V_OTHER", "V_ESCAPED"}, ) + + def test_unused_revision_key_uses_complete_comment_aware_tokens(self): + template = "print V_TEMPERATURE # V_TEMP" + with self.assertWarnsRegex(UserWarning, "Revision key 'V_TEMP'"): + check_revisions_completeness( + templates_content=["print 450"], + revision_keys=["V_TEMP", "V_TEMPERATURE"], + template_raw=template, + ) From 7cdec448ee92d92a3446ecbd066eb83268451277 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 12 Aug 2026 10:50:29 +0000 Subject: [PATCH 12/21] fix: mark revision validation errors as fatal --- .../exploration/task/lmp_template_task_group.py | 17 ++++++++++++----- tests/exploration/test_lmp_templ_task_group.py | 10 +++++++--- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index 21ef2d50..6f8b0008 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -11,6 +11,10 @@ Set, ) +from dflow.python import ( + FatalError, +) + from dpgen2.constants import ( lmp_conf_name, lmp_input_name, @@ -111,11 +115,14 @@ def make_task( template_raw += "\n" + "\n".join(self.plm_template) # Flatten all template variants (LAMMPS + PLUMED) for validation all_conts = [c for c_list in conts for c in c_list] - check_revisions_completeness( - all_conts, - list(self.revisions.keys()), - template_raw=template_raw, - ) + try: + check_revisions_completeness( + all_conts, + list(self.revisions.keys()), + template_raw=template_raw, + ) + except ValueError as exc: + raise FatalError(str(exc)) from exc else: # Warn (but don't error) if template has V_* but no revisions provided. # This can be legitimate for customized-lmp-template workflows or tests. diff --git a/tests/exploration/test_lmp_templ_task_group.py b/tests/exploration/test_lmp_templ_task_group.py index c1ec6591..464e1457 100644 --- a/tests/exploration/test_lmp_templ_task_group.py +++ b/tests/exploration/test_lmp_templ_task_group.py @@ -24,6 +24,10 @@ patch, ) +from dflow.python import ( + FatalError, +) + from dpgen2.constants import ( lmp_conf_name, lmp_input_name, @@ -475,7 +479,7 @@ def test_undefined_variable_raises(self): revisions={"V_NSTEPS": [1000], "V_TEMP": [300]}, traj_freq=self.traj_freq, ) - with self.assertRaises(ValueError) as ctx: + with self.assertRaises(FatalError) as ctx: task_group.make_task() self.assertIn("V_PRESS", str(ctx.exception)) self.assertIn("undefined revision variable", str(ctx.exception).lower()) @@ -628,7 +632,7 @@ def test_plumed_template_undefined_variable_raises(self): revisions={"V_NSTEPS": [1000], "V_TEMP": [300]}, traj_freq=self.traj_freq, ) - with self.assertRaises(ValueError) as ctx: + with self.assertRaises(FatalError) as ctx: task_group.make_task() self.assertIn("V_DIST0", str(ctx.exception)) finally: @@ -682,7 +686,7 @@ def test_undefined_longer_placeholder_raises_before_substitution(self): revisions={"V_TEMP": [300]}, traj_freq=self.traj_freq, ) - with self.assertRaisesRegex(ValueError, "V_TEMPERATURE"): + with self.assertRaisesRegex(FatalError, "V_TEMPERATURE"): task_group.make_task() def test_overlapping_defined_placeholders_are_replaced_as_tokens(self): From a061a86096fd6ac1eb40a62d8fc6496dbcdb65f6 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 12 Aug 2026 10:54:08 +0000 Subject: [PATCH 13/21] test: cover V-prefixed LAMMPS identifiers --- .../exploration/test_lmp_templ_task_group.py | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/tests/exploration/test_lmp_templ_task_group.py b/tests/exploration/test_lmp_templ_task_group.py index 464e1457..d6160271 100644 --- a/tests/exploration/test_lmp_templ_task_group.py +++ b/tests/exploration/test_lmp_templ_task_group.py @@ -572,8 +572,8 @@ def test_unused_revision_key_warns(self): typo_warnings = [x for x in w if "V_TYPO" in str(x.message)] self.assertGreater(len(typo_warnings), 0) - def test_lammps_internal_variables_not_flagged(self): - """${NSTEPS} and similar LAMMPS internal refs should NOT be flagged.""" + def test_lammps_variables_without_revision_prefix_are_not_flagged(self): + """LAMMPS references without the reserved V_* prefix remain untouched.""" template = textwrap.dedent( """\ variable NSTEPS equal V_NSTEPS @@ -598,6 +598,32 @@ def test_lammps_internal_variables_not_flagged(self): task_group.make_task() self.assertEqual(len(task_group), 1) + def test_v_prefixed_lammps_identifier_is_reserved_in_strict_mode(self): + """Strict validation treats standalone V_* tokens as DPGEN revisions.""" + template = textwrap.dedent( + f""" + variable NSTEPS equal V_NSTEPS + variable V_MAX equal 3.0 + + pair_style deepmd + pair_coeff * * + dump dpgen_dump + velocity all create {chr(36)}{{V_MAX}} 12345 + run {chr(36)}{{NSTEPS}} + """ + ).lstrip() + self._write_template(template) + task_group = LmpTemplateTaskGroup() + task_group.set_conf(self.confs) + task_group.set_lmp( + self.numb_models, + self.lmp_template_fname, + revisions={"V_NSTEPS": [1000]}, + traj_freq=self.traj_freq, + ) + with self.assertRaisesRegex(FatalError, "V_MAX"): + task_group.make_task() + def test_plumed_template_undefined_variable_raises(self): """V_* in PLUMED template but not in revisions should also be caught.""" lmp_template = textwrap.dedent( From 6857e8b2a69e1668cf3c004444c375b11ee3fef4 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 12 Aug 2026 10:56:49 +0000 Subject: [PATCH 14/21] feat: allow non-strict revision validation --- .../task/lmp_template_task_group.py | 50 +++++++++++++------ .../task/make_task_group_from_config.py | 8 +++ .../exploration/test_lmp_templ_task_group.py | 11 ++++ 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index 6f8b0008..26323dc3 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -52,6 +52,7 @@ def set_lmp( lmp_template_fname: str, plm_template_fname: Optional[str] = None, revisions: dict = {}, + strict_revisions: bool = True, traj_freq: int = 10, extra_pair_style_args: str = "", pimd_bead: Optional[str] = None, @@ -59,6 +60,7 @@ def set_lmp( ) -> None: self.lmp_template = Path(lmp_template_fname).read_text().split("\n") self.revisions = revisions + self.strict_revisions = strict_revisions self.traj_freq = traj_freq self.extra_pair_style_args = extra_pair_style_args self.pimd_bead = pimd_bead @@ -120,6 +122,7 @@ def make_task( all_conts, list(self.revisions.keys()), template_raw=template_raw, + strict=self.strict_revisions, ) except ValueError as exc: raise FatalError(str(exc)) from exc @@ -321,10 +324,32 @@ def find_unreplaced_variables(content: str) -> Set[str]: return set(_REVISION_VARIABLE_PATTERN.findall(stripped)) +def report_undefined_revision_variables( + variables: Set[str], + revision_keys: List[str], + strict: bool, +) -> None: + if not variables: + return + message = ( + f"LAMMPS template contains undefined revision variable(s): " + f"{sorted(variables)}. Defined revisions: {sorted(revision_keys)}. " + f"Please add missing variables to 'revisions' in your exploration config, " + f"or remove them from the template." + ) + if strict: + raise ValueError(message) + warnings.warn( + message + " Continuing because strict revision validation is disabled.", + stacklevel=3, + ) + + def check_revisions_completeness( templates_content: List[str], revision_keys: List[str], template_raw: str = "", + strict: bool = True, ) -> None: """Validate that all V_* placeholders in the template have been substituted. @@ -357,27 +382,22 @@ def check_revisions_completeness( # cannot erase the prefix of a longer undefined placeholder. raw_variables = find_unreplaced_variables(template_raw) if template_raw else set() undefined_raw = raw_variables - revision_key_set - if undefined_raw: - raise ValueError( - f"LAMMPS template contains undefined revision variable(s): " - f"{sorted(undefined_raw)}. Defined revisions: {sorted(revision_keys)}. " - f"Please add missing variables to 'revisions' in your exploration config, " - f"or remove them from the template." - ) + report_undefined_revision_variables( + undefined_raw, + revision_keys, + strict=strict, + ) # Check 2: Residual unreplaced variables all_unreplaced: Set[str] = set() for content in templates_content: all_unreplaced.update(find_unreplaced_variables(content)) - if all_unreplaced: - raise ValueError( - f"LAMMPS template contains undefined revision variable(s): " - f"{sorted(all_unreplaced)}. " - f"Defined revisions: {sorted(revision_keys)}. " - f"Please add missing variables to 'revisions' in your exploration config, " - f"or remove them from the template." - ) + report_undefined_revision_variables( + all_unreplaced - undefined_raw, + revision_keys, + strict=strict, + ) # Check 3: Unused revision keys (warning only) if template_raw and revision_keys: diff --git a/dpgen2/exploration/task/make_task_group_from_config.py b/dpgen2/exploration/task/make_task_group_from_config.py index 2859ac8f..4df2cb5c 100644 --- a/dpgen2/exploration/task/make_task_group_from_config.py +++ b/dpgen2/exploration/task/make_task_group_from_config.py @@ -133,6 +133,7 @@ def lmp_template_task_group_args(): doc_lmp_template_fname = "The file name of lammps input template" doc_plm_template_fname = "The file name of plumed input template" doc_revisions = "The revisions. Should be a dict providing the key - list of desired values pair. Key is the word to be replaced in the templates, and it may appear in both the lammps and plumed input templates. All values in the value list will be enmerated." + doc_strict_revisions = "Whether undefined V_* revision tokens fail task generation. Disable to warn and preserve templates that use V_* as native LAMMPS or PLUMED identifiers." doc_traj_freq = "The frequency of dumping configurations and thermodynamic states" doc_extra_pair_style_args = "The extra arguments for pair_style" doc_pimd_bead = "Bead index for PIMD, None for non-PIMD" @@ -165,6 +166,13 @@ def lmp_template_task_group_args(): alias=["plm_template", "plm"], ), Argument("revisions", dict, optional=True, default={}, doc=doc_revisions), + Argument( + "strict_revisions", + bool, + optional=True, + default=True, + doc=doc_strict_revisions, + ), Argument( "traj_freq", int, diff --git a/tests/exploration/test_lmp_templ_task_group.py b/tests/exploration/test_lmp_templ_task_group.py index d6160271..1b96dd75 100644 --- a/tests/exploration/test_lmp_templ_task_group.py +++ b/tests/exploration/test_lmp_templ_task_group.py @@ -624,6 +624,17 @@ def test_v_prefixed_lammps_identifier_is_reserved_in_strict_mode(self): with self.assertRaisesRegex(FatalError, "V_MAX"): task_group.make_task() + task_group.set_lmp( + self.numb_models, + self.lmp_template_fname, + revisions={"V_NSTEPS": [1000]}, + strict_revisions=False, + traj_freq=self.traj_freq, + ) + with self.assertWarnsRegex(UserWarning, "V_MAX"): + task_group.make_task() + self.assertEqual(len(task_group), 1) + def test_plumed_template_undefined_variable_raises(self): """V_* in PLUMED template but not in revisions should also be caught.""" lmp_template = textwrap.dedent( From ca2907108422af1f1e41dd77b36b9c5a45558f53 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 12 Aug 2026 11:00:56 +0000 Subject: [PATCH 15/21] docs: clarify strict revision validation --- docs/input.md | 9 +++++++++ .../task/lmp_template_task_group.py | 19 +++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/docs/input.md b/docs/input.md index 6fc03bd1..4ae893d3 100644 --- a/docs/input.md +++ b/docs/input.md @@ -106,6 +106,7 @@ This section defines how the configuration space is explored. "type" : "lmp-template", "lmp" : "template.lammps", "plm" : "template.plumed", "trj_freq" : 10, "revisions" : {"V_NSTEPS" : [40], "V_TEMP" : [150, 200]}, + "strict_revisions": true, "conf_idx": [0], "n_sample" : 3 } ], @@ -120,6 +121,14 @@ This section defines how the configuration space is explored. ] } ``` + +For an `"lmp-template"` task group, `revisions` keys are replaced as complete +tokens in both LAMMPS and PLUMED templates. By default, `strict_revisions` is +`true`: any standalone `V_*` token not listed in `revisions` stops task +generation before submission. Set `strict_revisions` to `false` only when a +template intentionally uses `V_*` as a native LAMMPS or PLUMED identifier; the +unknown tokens are then preserved and reported as warnings. + The {dargs:argument}`"type" : "lmp"` means that configurations are explored by LAMMPS DPMD runs. The {dargs:argument}`"config"` key defines the lmp configs. The {dargs:argument}`"configurations"` provides the initial configurations (coordinates of atoms and the simulation cell) of the DPMD simulations. It is a list. The elements of the list are `dict`s that defines how the configurations are generated diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index 26323dc3..ad2da579 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -264,8 +264,9 @@ def revise_by_keys(lmp_lines, keys, values): return lmp_lines -# Regex pattern for dpgen-style revision placeholders: V_ followed by uppercase letters/digits/underscores. -# This matches the universal convention in dpgen v1/v2 (all tests, docs, and examples use V_XXX). +# DPGEN and DPGEN2 templates conventionally use standalone V_* tokens for +# revisions. Native LAMMPS or PLUMED identifiers may use the same spelling; +# strict_revisions controls whether unexpected tokens are errors or warnings. _REVISION_VARIABLE_PATTERN = re.compile( r"(? str: def find_unreplaced_variables(content: str) -> Set[str]: - """Scan text for remaining V_* revision placeholders that were not substituted. + """Scan text for standalone V_* tokens that may be unreplaced revisions. Strips LAMMPS comments before scanning to avoid false positives from commented-out variable references. @@ -329,6 +330,7 @@ def report_undefined_revision_variables( revision_keys: List[str], strict: bool, ) -> None: + """Raise for undefined tokens in strict mode, otherwise emit a warning.""" if not variables: return message = ( @@ -370,11 +372,20 @@ def check_revisions_completeness( The keys defined in the revisions dict. template_raw : str The raw template content before substitution (for unused key detection). + strict : bool + If true, undefined V_* tokens are errors. If false, warn and continue + so templates may use V_* as native LAMMPS or PLUMED identifiers. Raises ------ ValueError - If unreplaced V_* variables are found in substituted templates. + If undefined V_* tokens are found and strict is true. + + Warns + ----- + UserWarning + If undefined V_* tokens are found and strict is false, or if a + revision key is unused. """ revision_key_set = set(revision_keys) From 1ee1e613253b4f6fd09f057c5fc33966216a8501 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 12 Aug 2026 11:56:56 +0000 Subject: [PATCH 16/21] fix: preserve positional set_lmp arguments --- dpgen2/exploration/task/lmp_template_task_group.py | 2 +- tests/exploration/test_lmp_templ_task_group.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index ad2da579..e2ac206f 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -52,11 +52,11 @@ def set_lmp( lmp_template_fname: str, plm_template_fname: Optional[str] = None, revisions: dict = {}, - strict_revisions: bool = True, traj_freq: int = 10, extra_pair_style_args: str = "", pimd_bead: Optional[str] = None, input_extra_files: Optional[List[str]] = None, + strict_revisions: bool = True, ) -> None: self.lmp_template = Path(lmp_template_fname).read_text().split("\n") self.revisions = revisions diff --git a/tests/exploration/test_lmp_templ_task_group.py b/tests/exploration/test_lmp_templ_task_group.py index 1b96dd75..69a3658e 100644 --- a/tests/exploration/test_lmp_templ_task_group.py +++ b/tests/exploration/test_lmp_templ_task_group.py @@ -348,6 +348,19 @@ def test_lmp(self): ) idx += 1 + def test_set_lmp_preserves_positional_traj_freq(self): + task_group = LmpTemplateTaskGroup() + task_group.set_lmp( + self.numb_models, + self.lmp_template_fname, + None, + self.lmp_rev_mat, + self.traj_freq, + ) + + self.assertEqual(task_group.traj_freq, self.traj_freq) + self.assertTrue(task_group.strict_revisions) + def test_lmp_plm(self): task_group = LmpTemplateTaskGroup() task_group.set_conf(self.confs) From 7d458f0c4a192d14d6bf94f96ac0cae4002ee77b Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 12 Aug 2026 11:58:01 +0000 Subject: [PATCH 17/21] fix: validate empty revision mappings in strict mode --- .../task/lmp_template_task_group.py | 45 ++++++------------- .../exploration/test_lmp_templ_task_group.py | 15 +++---- 2 files changed, 19 insertions(+), 41 deletions(-) diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index e2ac206f..b7f2cba4 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -111,37 +111,20 @@ def make_task( templates.append(self.plm_template) conts = self.make_cont(templates, self.revisions) # Validate: check for unreplaced V_* variables in substituted templates - if self.revisions: - template_raw = "\n".join(self.lmp_template) - if self.plm_set: - template_raw += "\n" + "\n".join(self.plm_template) - # Flatten all template variants (LAMMPS + PLUMED) for validation - all_conts = [c for c_list in conts for c in c_list] - try: - check_revisions_completeness( - all_conts, - list(self.revisions.keys()), - template_raw=template_raw, - strict=self.strict_revisions, - ) - except ValueError as exc: - raise FatalError(str(exc)) from exc - else: - # Warn (but don't error) if template has V_* but no revisions provided. - # This can be legitimate for customized-lmp-template workflows or tests. - combined = "\n".join(self.lmp_template) - if self.plm_set: - combined += "\n" + "\n".join(self.plm_template) - unreplaced = find_unreplaced_variables(combined) - if unreplaced: - warnings.warn( - f"LAMMPS template contains revision variable(s) {sorted(unreplaced)} " - f"but no 'revisions' dict was provided. " - f"These variables will NOT be substituted. " - f"If this is unintentional, add them to 'revisions' in your " - f"exploration config.", - stacklevel=2, - ) + template_raw = "\n".join(self.lmp_template) + if self.plm_set: + template_raw += "\n" + "\n".join(self.plm_template) + # Flatten all template variants (LAMMPS + PLUMED) for validation + all_conts = [c for c_list in conts for c in c_list] + try: + check_revisions_completeness( + all_conts, + list(self.revisions.keys()), + template_raw=template_raw, + strict=self.strict_revisions, + ) + except ValueError as exc: + raise FatalError(str(exc)) from exc nconts = len(conts[0]) for cc, ii in itertools.product(confs, range(nconts)): # type: ignore if not self.plm_set: diff --git a/tests/exploration/test_lmp_templ_task_group.py b/tests/exploration/test_lmp_templ_task_group.py index 69a3658e..09d8fa8c 100644 --- a/tests/exploration/test_lmp_templ_task_group.py +++ b/tests/exploration/test_lmp_templ_task_group.py @@ -410,7 +410,7 @@ def test_lmp_plm(self): idx += 1 def test_lmp_empty(self): - """Empty revisions with template containing V_* should warn but succeed.""" + """Non-strict empty revisions should warn but succeed.""" task_group = LmpTemplateTaskGroup() task_group.set_conf(self.confs) task_group.set_lmp( @@ -418,6 +418,7 @@ def test_lmp_empty(self): self.lmp_template_fname, revisions=self.rev_empty, traj_freq=self.traj_freq, + strict_revisions=False, ) import warnings as _warnings @@ -497,8 +498,8 @@ def test_undefined_variable_raises(self): self.assertIn("V_PRESS", str(ctx.exception)) self.assertIn("undefined revision variable", str(ctx.exception).lower()) - def test_no_revisions_but_template_has_variables(self): - """Template has V_* variables but no revisions — should warn, not error.""" + def test_no_revisions_strict_mode_raises(self): + """Strict mode rejects V_* variables when no revisions are provided.""" template = textwrap.dedent( """\ variable NSTEPS equal V_NSTEPS @@ -519,15 +520,9 @@ def test_no_revisions_but_template_has_variables(self): revisions={}, traj_freq=self.traj_freq, ) - import warnings as _warnings - with _warnings.catch_warnings(record=True) as w: - _warnings.simplefilter("always") + with self.assertRaisesRegex(FatalError, "V_NSTEPS"): task_group.make_task() - var_warnings = [x for x in w if "V_NSTEPS" in str(x.message)] - self.assertGreater(len(var_warnings), 0) - # Should still succeed - self.assertEqual(len(task_group), 1) def test_all_variables_defined_no_error(self): """All V_* variables are covered by revisions — should succeed.""" From 25febe0ccdcdf13aa3dd0b65fd81675e509bb42b Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 26 Aug 2026 02:35:59 +0000 Subject: [PATCH 18/21] fix: preserve customized template compatibility --- docs/input.md | 5 ++ .../customized_lmp_template_task_group.py | 5 ++ .../task/make_task_group_from_config.py | 12 +++++ .../test_customized_lmp_templ_task_group.py | 47 +++++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/docs/input.md b/docs/input.md index 4ae893d3..a7421f3b 100644 --- a/docs/input.md +++ b/docs/input.md @@ -129,6 +129,11 @@ generation before submission. Set `strict_revisions` to `false` only when a template intentionally uses `V_*` as a native LAMMPS or PLUMED identifier; the unknown tokens are then preserved and reported as warnings. +For a `"customized-lmp-template"` task group, `strict_revisions` defaults to +`false` for backward compatibility because its shell commands may intentionally +generate templates containing `V_*` tokens. Set it to `true` to apply the same +strict validation to the generated templates. + The {dargs:argument}`"type" : "lmp"` means that configurations are explored by LAMMPS DPMD runs. The {dargs:argument}`"config"` key defines the lmp configs. The {dargs:argument}`"configurations"` provides the initial configurations (coordinates of atoms and the simulation cell) of the DPMD simulations. It is a list. The elements of the list are `dict`s that defines how the configurations are generated diff --git a/dpgen2/exploration/task/customized_lmp_template_task_group.py b/dpgen2/exploration/task/customized_lmp_template_task_group.py index d7022516..f25a50c5 100644 --- a/dpgen2/exploration/task/customized_lmp_template_task_group.py +++ b/dpgen2/exploration/task/customized_lmp_template_task_group.py @@ -62,6 +62,7 @@ def set_lmp( output_lmp_conf_name: str = lmp_conf_name, output_lmp_tmpl_name: str = lmp_input_name, output_plm_tmpl_name: Optional[str] = None, + strict_revisions: bool = False, ) -> None: r"""Set lammps task. @@ -99,11 +100,14 @@ def set_lmp( Generated lmp input file name. output_plm_tmpl_name : str Generated plm input file name. + strict_revisions : bool + Whether undefined V_* revision tokens fail task generation. """ self.numb_models = numb_models self.lmp_template = Path(input_lmp_tmpl_name).read_text().split("\n") self.revisions = revisions + self.strict_revisions = strict_revisions self.traj_freq = traj_freq self.has_plm = input_plm_tmpl_name is not None self.do_custom = ( @@ -218,6 +222,7 @@ def _make_customized_task_group( self.output_plm_tmpl_name if self.has_plm else None, revisions=self.revisions, traj_freq=self.traj_freq, + strict_revisions=self.strict_revisions, ) conf_fc = Path(self.output_lmp_conf_name).read_text() lmp_tgroup.set_conf( diff --git a/dpgen2/exploration/task/make_task_group_from_config.py b/dpgen2/exploration/task/make_task_group_from_config.py index 4df2cb5c..0872d73b 100644 --- a/dpgen2/exploration/task/make_task_group_from_config.py +++ b/dpgen2/exploration/task/make_task_group_from_config.py @@ -209,6 +209,11 @@ def customized_lmp_template_task_group_args(): doc_input_lmp_tmpl_name = "The file name of lammps input template" doc_input_plm_tmpl_name = "The file name of plumed input template" doc_revisions = "The revisions. Should be a dict providing the key - list of desired values pair. Key is the word to be replaced in the templates, and it may appear in both the lammps and plumed input templates. All values in the value list will be enmerated." + doc_strict_revisions = ( + "Whether undefined V_* revision tokens fail task generation. " + "Defaults to false for customized templates so generated V_* tokens " + "are warned about and preserved." + ) doc_traj_freq = "The frequency of dumping configurations and thermodynamic states" doc_custom_shell_commands = ( "Customized shell commands to be run for each configuration. " @@ -245,6 +250,13 @@ def customized_lmp_template_task_group_args(): "custom_shell_commands", list, optional=False, doc=doc_custom_shell_commands ), Argument("revisions", dict, optional=True, default={}, doc=doc_revisions), + Argument( + "strict_revisions", + bool, + optional=True, + default=False, + doc=doc_strict_revisions, + ), Argument( "traj_freq", int, diff --git a/tests/exploration/test_customized_lmp_templ_task_group.py b/tests/exploration/test_customized_lmp_templ_task_group.py index 57462759..262a68a1 100644 --- a/tests/exploration/test_customized_lmp_templ_task_group.py +++ b/tests/exploration/test_customized_lmp_templ_task_group.py @@ -12,6 +12,9 @@ ) import numpy as np +from dflow.python import ( + FatalError, +) try: from exploration.context import ( @@ -259,3 +262,47 @@ def test_lmp(self): * len(self.lmp_rev_mat["V_TEMP"]) * 2, ) + + def test_empty_revisions_default_to_non_strict(self): + task_group = CustomizedLmpTemplateTaskGroup() + task_group.set_conf(self.confs) + task_group.set_lmp( + self.numb_models, + custom_shell_commands=self.shell_cmd, + revisions=self.rev_empty, + traj_freq=self.traj_freq, + input_lmp_conf_name="foo.lmp", + input_lmp_tmpl_name=self.lmp_template_fname, + input_plm_tmpl_name=None, + input_extra_files=[self.py_script], + output_dir_pattern="task_*", + output_lmp_conf_name="bar.lmp", + output_lmp_tmpl_name="lmp.template", + ) + + with self.assertWarnsRegex(UserWarning, "V_NSTEPS"): + task_group.make_task() + + self.assertFalse(task_group.strict_revisions) + self.assertEqual(len(task_group), len(self.confs) * 2) + + def test_empty_revisions_can_opt_into_strict_mode(self): + task_group = CustomizedLmpTemplateTaskGroup() + task_group.set_conf(self.confs) + task_group.set_lmp( + self.numb_models, + custom_shell_commands=self.shell_cmd, + revisions=self.rev_empty, + traj_freq=self.traj_freq, + input_lmp_conf_name="foo.lmp", + input_lmp_tmpl_name=self.lmp_template_fname, + input_plm_tmpl_name=None, + input_extra_files=[self.py_script], + output_dir_pattern="task_*", + output_lmp_conf_name="bar.lmp", + output_lmp_tmpl_name="lmp.template", + strict_revisions=True, + ) + + with self.assertRaisesRegex(FatalError, "V_NSTEPS"): + task_group.make_task() From 2f731e3d64243ed01abdbae7fc3ee5ffffe5dcd2 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Wed, 26 Aug 2026 02:37:18 +0000 Subject: [PATCH 19/21] refactor: validate the effective LAMMPS template --- dpgen2/exploration/task/lmp_template_task_group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index b7f2cba4..ccf300e5 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -111,7 +111,7 @@ def make_task( templates.append(self.plm_template) conts = self.make_cont(templates, self.revisions) # Validate: check for unreplaced V_* variables in substituted templates - template_raw = "\n".join(self.lmp_template) + template_raw = "\n".join(lmp_template) if self.plm_set: template_raw += "\n" + "\n".join(self.plm_template) # Flatten all template variants (LAMMPS + PLUMED) for validation From 92776fbd49087aba203fa805f1d6e79ffe359800 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Tue, 1 Sep 2026 00:11:02 +0000 Subject: [PATCH 20/21] fix: preserve lmp template compatibility --- docs/input.md | 14 +++++++------- dpgen2/exploration/task/lmp_template_task_group.py | 2 +- .../task/make_task_group_from_config.py | 8 ++++++-- tests/exploration/test_lmp_templ_task_group.py | 11 ++++++++--- .../test_make_task_group_from_config.py | 1 + 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/docs/input.md b/docs/input.md index a7421f3b..a0bf2c29 100644 --- a/docs/input.md +++ b/docs/input.md @@ -124,15 +124,15 @@ This section defines how the configuration space is explored. For an `"lmp-template"` task group, `revisions` keys are replaced as complete tokens in both LAMMPS and PLUMED templates. By default, `strict_revisions` is -`true`: any standalone `V_*` token not listed in `revisions` stops task -generation before submission. Set `strict_revisions` to `false` only when a -template intentionally uses `V_*` as a native LAMMPS or PLUMED identifier; the -unknown tokens are then preserved and reported as warnings. +`false`: standalone `V_*` tokens not listed in `revisions` are preserved and +reported as warnings because they may be native LAMMPS or PLUMED identifiers. +Set `strict_revisions` to `true` to stop task generation when such tokens are +found. For a `"customized-lmp-template"` task group, `strict_revisions` defaults to -`false` for backward compatibility because its shell commands may intentionally -generate templates containing `V_*` tokens. Set it to `true` to apply the same -strict validation to the generated templates. +`false` for the same compatibility reason: its shell commands may intentionally +generate templates containing `V_*` tokens. Set it to `true` to apply strict +validation to the generated templates. The {dargs:argument}`"type" : "lmp"` means that configurations are explored by LAMMPS DPMD runs. The {dargs:argument}`"config"` key defines the lmp configs. diff --git a/dpgen2/exploration/task/lmp_template_task_group.py b/dpgen2/exploration/task/lmp_template_task_group.py index ccf300e5..0d33a7b7 100644 --- a/dpgen2/exploration/task/lmp_template_task_group.py +++ b/dpgen2/exploration/task/lmp_template_task_group.py @@ -56,7 +56,7 @@ def set_lmp( extra_pair_style_args: str = "", pimd_bead: Optional[str] = None, input_extra_files: Optional[List[str]] = None, - strict_revisions: bool = True, + strict_revisions: bool = False, ) -> None: self.lmp_template = Path(lmp_template_fname).read_text().split("\n") self.revisions = revisions diff --git a/dpgen2/exploration/task/make_task_group_from_config.py b/dpgen2/exploration/task/make_task_group_from_config.py index 0872d73b..d3b4ce52 100644 --- a/dpgen2/exploration/task/make_task_group_from_config.py +++ b/dpgen2/exploration/task/make_task_group_from_config.py @@ -133,7 +133,11 @@ def lmp_template_task_group_args(): doc_lmp_template_fname = "The file name of lammps input template" doc_plm_template_fname = "The file name of plumed input template" doc_revisions = "The revisions. Should be a dict providing the key - list of desired values pair. Key is the word to be replaced in the templates, and it may appear in both the lammps and plumed input templates. All values in the value list will be enmerated." - doc_strict_revisions = "Whether undefined V_* revision tokens fail task generation. Disable to warn and preserve templates that use V_* as native LAMMPS or PLUMED identifiers." + doc_strict_revisions = ( + "Whether undefined V_* revision tokens fail task generation. " + "Defaults to false so templates using V_* as native LAMMPS or PLUMED " + "identifiers are warned about and preserved." + ) doc_traj_freq = "The frequency of dumping configurations and thermodynamic states" doc_extra_pair_style_args = "The extra arguments for pair_style" doc_pimd_bead = "Bead index for PIMD, None for non-PIMD" @@ -170,7 +174,7 @@ def lmp_template_task_group_args(): "strict_revisions", bool, optional=True, - default=True, + default=False, doc=doc_strict_revisions, ), Argument( diff --git a/tests/exploration/test_lmp_templ_task_group.py b/tests/exploration/test_lmp_templ_task_group.py index 09d8fa8c..ec6c9f22 100644 --- a/tests/exploration/test_lmp_templ_task_group.py +++ b/tests/exploration/test_lmp_templ_task_group.py @@ -359,7 +359,7 @@ def test_set_lmp_preserves_positional_traj_freq(self): ) self.assertEqual(task_group.traj_freq, self.traj_freq) - self.assertTrue(task_group.strict_revisions) + self.assertFalse(task_group.strict_revisions) def test_lmp_plm(self): task_group = LmpTemplateTaskGroup() @@ -492,6 +492,7 @@ def test_undefined_variable_raises(self): self.lmp_template_fname, revisions={"V_NSTEPS": [1000], "V_TEMP": [300]}, traj_freq=self.traj_freq, + strict_revisions=True, ) with self.assertRaises(FatalError) as ctx: task_group.make_task() @@ -519,6 +520,7 @@ def test_no_revisions_strict_mode_raises(self): self.lmp_template_fname, revisions={}, traj_freq=self.traj_freq, + strict_revisions=True, ) with self.assertRaisesRegex(FatalError, "V_NSTEPS"): @@ -607,7 +609,7 @@ def test_lammps_variables_without_revision_prefix_are_not_flagged(self): self.assertEqual(len(task_group), 1) def test_v_prefixed_lammps_identifier_is_reserved_in_strict_mode(self): - """Strict validation treats standalone V_* tokens as DPGEN revisions.""" + """Native V_* identifiers warn by default and fail in strict mode.""" template = textwrap.dedent( f""" variable NSTEPS equal V_NSTEPS @@ -628,6 +630,7 @@ def test_v_prefixed_lammps_identifier_is_reserved_in_strict_mode(self): self.lmp_template_fname, revisions={"V_NSTEPS": [1000]}, traj_freq=self.traj_freq, + strict_revisions=True, ) with self.assertRaisesRegex(FatalError, "V_MAX"): task_group.make_task() @@ -636,11 +639,11 @@ def test_v_prefixed_lammps_identifier_is_reserved_in_strict_mode(self): self.numb_models, self.lmp_template_fname, revisions={"V_NSTEPS": [1000]}, - strict_revisions=False, traj_freq=self.traj_freq, ) with self.assertWarnsRegex(UserWarning, "V_MAX"): task_group.make_task() + self.assertFalse(task_group.strict_revisions) self.assertEqual(len(task_group), 1) def test_plumed_template_undefined_variable_raises(self): @@ -676,6 +679,7 @@ def test_plumed_template_undefined_variable_raises(self): # V_DIST0 is used in PLUMED template but NOT defined here revisions={"V_NSTEPS": [1000], "V_TEMP": [300]}, traj_freq=self.traj_freq, + strict_revisions=True, ) with self.assertRaises(FatalError) as ctx: task_group.make_task() @@ -730,6 +734,7 @@ def test_undefined_longer_placeholder_raises_before_substitution(self): self.lmp_template_fname, revisions={"V_TEMP": [300]}, traj_freq=self.traj_freq, + strict_revisions=True, ) with self.assertRaisesRegex(FatalError, "V_TEMPERATURE"): task_group.make_task() diff --git a/tests/exploration/test_make_task_group_from_config.py b/tests/exploration/test_make_task_group_from_config.py index f9fe93be..0dc6d79d 100644 --- a/tests/exploration/test_make_task_group_from_config.py +++ b/tests/exploration/test_make_task_group_from_config.py @@ -63,6 +63,7 @@ def test_template(self): self.numb_models, self.mass_map, self.config_template ) self.assertTrue(isinstance(tgroup, LmpTemplateTaskGroup)) + self.assertFalse(tgroup.strict_revisions) class TestMakeCalyTaskGroupFromConfig(unittest.TestCase): From 76f9707df4b361b85f98fd9dfa5852ad6444cc43 Mon Sep 17 00:00:00 2001 From: SchrodingersCattt Date: Tue, 1 Sep 2026 01:03:15 +0000 Subject: [PATCH 21/21] test: cover strict template config opt-in --- tests/exploration/test_make_task_group_from_config.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/exploration/test_make_task_group_from_config.py b/tests/exploration/test_make_task_group_from_config.py index 0dc6d79d..254605ae 100644 --- a/tests/exploration/test_make_task_group_from_config.py +++ b/tests/exploration/test_make_task_group_from_config.py @@ -65,6 +65,16 @@ def test_template(self): self.assertTrue(isinstance(tgroup, LmpTemplateTaskGroup)) self.assertFalse(tgroup.strict_revisions) + def test_template_strict_revisions(self): + strict_config = { + **self.config_template, + "strict_revisions": True, + } + tgroup = make_lmp_task_group_from_config( + self.numb_models, self.mass_map, strict_config + ) + self.assertTrue(tgroup.strict_revisions) + class TestMakeCalyTaskGroupFromConfig(unittest.TestCase): def setUp(self):