experiments: bug fixes (#5407)

* exp run: display metrics on -m/--metrics

* exp show: fix sort handling
This commit is contained in:
Peter Rowlands (변기호)
2021-02-04 16:42:22 +09:00
committed by GitHub
parent b87e76aa84
commit 982802effc
3 changed files with 78 additions and 18 deletions
+47 -18
View File
@@ -130,14 +130,13 @@ def _collect_rows(
from dvc.scm.git import Git
if sort_by:
if sort_by in metric_names:
sort_type = "metrics"
elif sort_by in param_names:
sort_type = "params"
else:
raise InvalidArgumentError(f"Unknown sort column '{sort_by}'")
sort_path, sort_name, sort_type = _sort_column(
sort_by, metric_names, param_names
)
reverse = sort_order == "desc"
experiments = _sort_exp(experiments, sort_by, sort_type, reverse)
experiments = _sort_exp(
experiments, sort_path, sort_name, sort_type, reverse
)
new_checkpoint = True
for i, (rev, exp) in enumerate(experiments.items()):
@@ -193,22 +192,45 @@ def _collect_rows(
yield row, style
def _sort_exp(experiments, sort_by, typ, reverse):
def _sort_column(sort_by, metric_names, param_names):
path, _, sort_name = sort_by.rpartition(":")
matches = set()
if path:
if path in metric_names and sort_name in metric_names[path]:
matches.add((path, sort_name, "metrics"))
if path in param_names and sort_name in param_names[path]:
matches.add((path, sort_name, "params"))
else:
for path in metric_names:
if sort_name in metric_names[path]:
matches.add((path, sort_name, "metrics"))
for path in param_names:
if sort_name in param_names[path]:
matches.add((path, sort_name, "params"))
if len(matches) == 1:
return matches.pop()
if len(matches) > 1:
raise InvalidArgumentError(
"Ambiguous sort column '{}' matched '{}'".format(
sort_by,
", ".join([f"{path}:{name}" for path, name, _ in matches]),
)
)
raise InvalidArgumentError(f"Unknown sort column '{sort_by}'")
def _sort_exp(experiments, sort_path, sort_name, typ, reverse):
def _sort(item):
rev, exp = item
tip = exp.get("checkpoint_tip")
if tip and tip != rev:
# Sort checkpoint experiments by tip commit
return _sort((tip, experiments[tip]))
for fname, item in exp.get(typ, {}).items():
if isinstance(item, dict):
item = flatten(item)
else:
item = {fname: item}
if sort_by in item:
val = item[sort_by]
return (val is None, val)
return (True, None)
data = exp.get(typ, {}).get(sort_path, {})
val = flatten(data).get(sort_name)
return (val is None, val)
ret = OrderedDict()
if "baseline" in experiments:
@@ -472,10 +494,12 @@ class CmdExperimentsDiff(CmdBase):
class CmdExperimentsRun(CmdRepro):
def run(self):
from dvc.command.metrics import _show_metrics
if self.args.reset:
logger.info("Any existing checkpoints will be reset and re-run.")
self.repo.experiments.run(
results = self.repo.experiments.run(
name=self.args.name,
queue=self.args.queue,
run_all=self.args.run_all,
@@ -487,6 +511,11 @@ class CmdExperimentsRun(CmdRepro):
**self._repro_kwargs,
)
if self.args.metrics and results:
metrics = self.repo.metrics.show(revs=list(results))
metrics.pop("workspace", None)
logger.info(_show_metrics(metrics))
return 0
@@ -581,3 +581,15 @@ def test_queue(tmp_dir, scm, dvc, exp_stage, mocker):
with tree.open(tmp_dir / "metrics.yaml") as fobj:
metrics.add(fobj.read().strip())
assert expected == metrics
def test_run_metrics(tmp_dir, scm, dvc, exp_stage, mocker):
from dvc.main import main
mocker.patch.object(
dvc.experiments, "run", return_value={"abc123": "abc123"}
)
show_mock = mocker.patch.object(dvc.metrics, "show", return_value={})
main(["exp", "run", "-m"])
assert show_mock.called_once()
+19
View File
@@ -1,3 +1,4 @@
import logging
import os
from datetime import datetime
@@ -214,3 +215,21 @@ def test_show_multiple_commits(tmp_dir, scm, dvc, exp_stage):
results = dvc.experiments.show(num=100)
assert set(results.keys()) == expected
def test_show_sort(tmp_dir, scm, dvc, exp_stage, caplog):
with caplog.at_level(logging.ERROR):
assert main(["exp", "show", "--no-pager", "--sort-by=bar"]) != 0
assert "Unknown sort column" in caplog.text
with caplog.at_level(logging.ERROR):
assert main(["exp", "show", "--no-pager", "--sort-by=foo"]) != 0
assert "Ambiguous sort column" in caplog.text
assert (
main(["exp", "show", "--no-pager", "--sort-by=params.yaml:foo"]) == 0
)
assert (
main(["exp", "show", "--no-pager", "--sort-by=metrics.yaml:foo"]) == 0
)