Skip to content

Commit a39b417

Browse files
committed
Fix some bugs in tests.
1 parent e826a44 commit a39b417

8 files changed

Lines changed: 81 additions & 51 deletions

File tree

deepks/io/input/dispatcher.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,6 @@ def dispatch_command(config):
3131
scf_soft = config.get('scf_soft', 'pyscf')
3232
backend = get_scf_backend(scf_soft)
3333
backend.collect_stats(**config)
34-
elif task_type == 'scf_task':
35-
# Low-level per-task SCF runner (called by BatchTask in iterate workflow)
36-
from deepks.physics.backends.pyscf.run import main as scf_run_main
37-
# Strip orchestration-only keys that pyscf.run.main() doesn't understand
38-
scf_config = {k: v for k, v in config.items()
39-
if k not in ('type', 'scf_soft')}
40-
scf_run_main(**scf_config)
41-
elif task_type == 'train_task':
42-
# Low-level training runner (called by BatchTask in iterate workflow)
43-
from deepks.ml.train.train import main as train_main
44-
train_config = {k: v for k, v in config.items()
45-
if k not in ('type',)}
46-
train_main(**train_config)
4734
elif task_type == 'iterate':
4835
# Use new iterate workflow
4936
from deepks.workflows.iterate import run_iterate_workflow

deepks/workflows/iterate/template.py

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def make_scf_task(*, workdir=".",
8787

8888
# --- build per-task override dict ---
8989
TASK_YAML = "_scf_task.yaml"
90-
overrides = {"type": "scf_task"}
90+
overrides = {"type": "scf", "scf_soft": "pyscf"}
9191
if sys_str is not None:
9292
overrides["systems"] = sys_str
9393
if model_file:
@@ -275,21 +275,19 @@ def make_train_task(*, workdir=".",
275275
python="python", **task_args):
276276
"""Create a training task as a BatchTask running via the unified 'deepks' CLI.
277277
278-
All training parameters are folded into a per-task YAML (_train_task.yaml)
279-
with type: train_task. The YAML is written to disk during preprocess()
280-
(not via a shell one-liner), so the command is simply:
281-
deepks _train_task.yaml
278+
The base train_input.yaml (from share) is read at construction time, merged
279+
with runtime overrides (train_paths, test_paths, type, restart, etc.), and
280+
written back to train_input.yaml in the workdir during preprocess(). No
281+
separate _train_task.yaml is created.
282282
"""
283-
link_share = task_args.pop("link_share_files", [])
283+
from deepks.io.utils import load_yaml, deep_update
284+
284285
link_prev = task_args.pop("link_prev_files", [])
286+
link_share = task_args.pop("link_share_files", [])
285287
forward_files = task_args.pop("forward_files", [])
286288
backward_files = task_args.pop("backward_files", [])
287289

288-
# --- file links ---
289-
if arg_file and source_arg is not None:
290-
link_share.append((source_arg, arg_file))
291-
if arg_file:
292-
forward_files.append(arg_file)
290+
# --- file links (everything except train_input.yaml, which we write ourselves) ---
293291
if restart_model and source_model is not None:
294292
link_prev.append((source_model, restart_model))
295293
forward_files.append(restart_model)
@@ -305,24 +303,27 @@ def make_train_task(*, workdir=".",
305303
if save_model:
306304
backward_files.append(save_model)
307305

308-
# --- build per-task YAML overrides ---
309-
TASK_YAML = "_train_task.yaml"
310-
overrides = {"type": "train_task"}
306+
# --- read base train_input.yaml from source_arg (share folder) if available ---
307+
base_config = {}
308+
if source_arg is not None and os.path.exists(source_arg):
309+
base_config = load_yaml(source_arg) or {}
310+
311+
# --- build runtime overrides and merge into base ---
312+
overrides = {"type": "train"}
311313
if data_train:
312-
overrides["train_paths"] = os.path.join(data_train, "*")
314+
overrides["systems_train"] = os.path.join(data_train, "*")
313315
if data_test:
314-
overrides["test_paths"] = os.path.join(data_test, "*")
316+
overrides["systems_test"] = os.path.join(data_test, "*")
315317
if restart_model:
316318
overrides["restart"] = restart_model
317319
if proj_basis:
318320
overrides["proj_basis"] = proj_basis
319321
if save_model:
320-
overrides.setdefault("train_args", {})["ckpt_file"] = save_model
322+
overrides["ckpt_file"] = save_model
321323

322-
# Write the YAML at construction time; BatchTask.preprocess() writes it to
323-
# disk before the shell command runs — no fragile python -c one-liner needed.
324-
task_yaml_content = dump_yaml_str(overrides)
325-
command = f"{SCF_CMD} {TASK_YAML}"
324+
merged = deep_update(dict(base_config), overrides)
325+
task_yaml_content = dump_yaml_str(merged)
326+
command = f"{SCF_CMD} {arg_file}"
326327

327328
return BatchTask(
328329
command,
@@ -336,7 +337,7 @@ def make_train_task(*, workdir=".",
336337
link_prev_files=link_prev,
337338
forward_files=forward_files,
338339
backward_files=backward_files,
339-
write_files={TASK_YAML: task_yaml_content},
340+
write_files={arg_file: task_yaml_content},
340341
**task_args
341342
)
342343

deepks/workflows/scf/execute.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,24 @@ def build_batch_task(sys_paths, sys_names, abacus_path, run_cmd,
262262
forward_files=forward_files,
263263
backward_files=backward_files
264264
)
265+
266+
267+
def execute_scf_tasks_pyscf(prepare_task, config):
268+
"""Execute SCF via PySCF by calling pyscf.run.main() directly."""
269+
from deepks.physics.backends.pyscf.run import main as pyscf_main
270+
from deepks.orchestration.workflow.task import PythonTask
271+
from deepks.orchestration.workflow.workflow import Sequence
272+
273+
call_kwargs = {
274+
k: v for k, v in config.items()
275+
if k not in ('type', 'scf_soft')
276+
}
277+
run_task = PythonTask(
278+
pyscf_main,
279+
call_kwargs=call_kwargs,
280+
outlog=config.get('outlog', 'log.scf'),
281+
errlog='err',
282+
workdir='.'
283+
)
284+
workflow = Sequence([prepare_task, run_task], workdir='.')
285+
workflow.run()

deepks/workflows/scf/prepare.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,7 @@ def prepare_scf_tasks(config):
159159
if scf_soft.lower() == 'abacus':
160160
return prepare_scf_tasks_abacus(config)
161161
elif scf_soft.lower() == 'pyscf':
162-
# PySCF preparation (to be implemented or kept as is)
163-
raise NotImplementedError(
164-
"PySCF workflow not yet implemented in new architecture"
165-
)
162+
return prepare_scf_tasks_pyscf(config)
166163
else:
167164
raise ValueError(f"Unknown SCF backend: {scf_soft}")
168165

@@ -218,3 +215,9 @@ def prepare_scf_tasks_abacus(config):
218215
)
219216

220217
return task
218+
219+
220+
def prepare_scf_tasks_pyscf(config):
221+
"""PySCF SCF - no separate preparation needed; return a BlankTask."""
222+
from deepks.orchestration.workflow.task import BlankTask
223+
return BlankTask(workdir='.')

deepks/workflows/train/train.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,10 @@ def train_model(train_reader: GroupReader,
6969

7070
# Train model
7171
print('# starting training')
72-
train_function(model, train_reader, test_reader=test_reader, **train_args)
72+
import inspect
73+
valid_train_keys = set(inspect.signature(train_function).parameters.keys())
74+
filtered_train_args = {k: v for k, v in train_args.items() if k in valid_train_keys}
75+
train_function(model, train_reader, test_reader=test_reader, **filtered_train_args)
7376

7477
# Collect training statistics
7578
train_stats = {

deepks/workflows/train/workflow.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from .evaluate import evaluate_model
1010
from .types import TrainResult
1111
from dataclasses import asdict
12+
import sys
13+
from contextlib import redirect_stdout
1214

1315

1416
def run_train_workflow(config):
@@ -47,9 +49,22 @@ def run_train_workflow(config):
4749
# Stage 2: Train - Train the model
4850
model, train_stats = train_model(train_data, test_data, model_config)
4951

50-
# Stage 3: Evaluate - Evaluate model performance
52+
# Stage 3: Evaluate - Evaluate model performance and write log.test
5153
metrics = evaluate_model(model, test_data, config)
5254

55+
# Reproduce legacy log.test: run test() with stdout redirected
56+
ckpt_file = config.get('ckpt_file', 'model.pth')
57+
test_log = config.get('test_log', 'log.test')
58+
if test_data is not None:
59+
from deepks.ml.eval.test import test as run_test
60+
# Reconstruct the header line that GroupReader prints at construction time
61+
data_keys = list(dict.fromkeys(test_data.readers[0].sample_all().keys()))
62+
header_line = f'# load {test_data.nsystems} systems with fields {data_keys}'
63+
with open(test_log, 'w', 1) as f_test, redirect_stdout(f_test):
64+
print(header_line)
65+
print(ckpt_file)
66+
run_test(model, test_data, dump_prefix=None)
67+
5368
result = TrainResult(
5469
model_path=config.get('ckpt_file', 'model.pth'),
5570
metrics=metrics,

tests/fixtures/legacy_integral_full/05_iter/01_abacus_local/iter_input.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ scf_soft: abacus
9090
scf_abacus:
9191
#INPUT args
9292
ntype: 2
93-
ecutwfc: 50
94-
scf_thr: 1e-5
93+
ecutwfc: 100
94+
scf_thr: 1e-7
9595
scf_nmax: 50
96-
dft_functional: "lda"
96+
dft_functional: "pbe"
9797
gamma_only: 1
9898
#STRU args
9999
orb_files:
@@ -115,10 +115,10 @@ init_scf_abacus:
115115
proj_file:
116116
- "../../data/jle.orb"
117117
ntype: 2
118-
ecutwfc: 50
119-
scf_thr: 1e-5
118+
ecutwfc: 100
119+
scf_thr: 1e-7
120120
scf_nmax: 50
121-
dft_functional: "lda"
121+
dft_functional: "pbe"
122122
gamma_only: 1
123123
lattice_constant: 1.8897261255
124124
coord_type: "Cartesian"

tests/fixtures/legacy_integral_full/05_iter/01_abacus_local/test_iterate.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def _remove_generated() -> None:
4444

4545

4646
def _fake_make_scf_abacus(*args, **kwargs):
47-
from deepks.orchestration.scheduler.task import PythonTask
47+
from deepks.orchestration.workflow.task import PythonTask
4848
workdir = kwargs.get("workdir", "00.scf")
4949

5050
def _run_mock_scf():
@@ -55,7 +55,7 @@ def _run_mock_scf():
5555

5656

5757
def _fake_make_train(*args, **kwargs):
58-
from deepks.orchestration.scheduler.task import PythonTask
58+
from deepks.orchestration.workflow.task import PythonTask
5959
workdir = kwargs.get("workdir", "01.train")
6060

6161
def _run_mock_train():
@@ -66,13 +66,13 @@ def _run_mock_train():
6666

6767
@pytest.fixture(autouse=True)
6868
def _prepare_runtime_tree(monkeypatch):
69-
_remove_generated()
69+
# _remove_generated()
7070
if not ABACUS_AVAILABLE:
7171
from deepks.workflows.iterate import scf_step, train_step
7272
monkeypatch.setattr(scf_step, "make_scf_abacus", _fake_make_scf_abacus)
7373
monkeypatch.setattr(train_step, "make_train", _fake_make_train)
7474
yield
75-
_remove_generated()
75+
# _remove_generated()
7676

7777

7878
def run_iter():

0 commit comments

Comments
 (0)