Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/dvsim/cli/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ def report() -> None:
)
def gen(json_path: Path, output_dir: Path) -> None:
"""Generate a report from a existing results JSON."""
from dvsim.report.data import ResultsSummary
from dvsim.report.generate import gen_reports
from dvsim.sim.data import SimResultsSummary
from dvsim.sim.report import gen_reports

results: ResultsSummary = ResultsSummary.load(path=json_path)
results: SimResultsSummary = SimResultsSummary.load(path=json_path)

gen_reports(summary=results, path=output_dir)
67 changes: 1 addition & 66 deletions src/dvsim/flow/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import sys
from abc import ABC, abstractmethod
from collections.abc import Mapping, Sequence
from datetime import datetime, timezone
from pathlib import Path
from typing import TYPE_CHECKING, ClassVar

Expand All @@ -20,15 +19,12 @@
from dvsim.job.data import CompletedJobStatus
from dvsim.launcher.factory import get_launcher_cls
from dvsim.logging import log
from dvsim.report.data import FlowResults, IPMeta, ResultsSummary
from dvsim.report.generate import gen_block_report, gen_reports
from dvsim.scheduler import Scheduler
from dvsim.utils import (
find_and_substitute_wildcards,
rm_path,
subst_wildcards,
)
from dvsim.utils.git import git_commit_hash

if TYPE_CHECKING:
from dvsim.job.deploy import Deploy
Expand Down Expand Up @@ -447,75 +443,14 @@ def deploy_objects(self) -> Sequence[CompletedJobStatus]:
interactive=self.interactive,
).run()

@abstractmethod
def gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
"""Generate flow results.

Args:
results: completed job status objects.

"""
reports_dir = Path(self.scratch_base_path) / "reports"
commit = git_commit_hash(path=Path(self.proj_root))
url = f"https://github.com/lowrisc/opentitan/tree/{commit}"

all_flow_results: Mapping[str, FlowResults] = {}

for item in self.cfgs:
item_results = [
res
for res in results
if res.block.name == item.name and res.block.variant == item.variant
]

flow_results: FlowResults = item._gen_json_results(
run_results=item_results,
commit=commit,
url=url,
)

# Convert to lowercase to match filename
block_result_index = (
f"{item.name}_{item.variant}" if item.variant else item.name
).lower()

all_flow_results[block_result_index] = flow_results

# Generate the block's JSON/HTML reports to the report area.
gen_block_report(
results=flow_results,
path=reports_dir,
)

self.errors_seen |= item.errors_seen

if self.is_primary_cfg:
# The timestamp for this run has been taken with `utcnow()` and is
# stored in a custom format. Store it in standard ISO format with
# explicit timezone annotation.
timestamp = (
datetime.strptime(self.timestamp, "%Y%m%d_%H%M%S")
.replace(tzinfo=timezone.utc)
.isoformat()
)

results_summary = ResultsSummary(
top=IPMeta(
name=self.name,
variant=self.variant,
commit=commit,
branch=self.branch,
url=url,
),
timestamp=timestamp,
flow_results=all_flow_results,
report_path=reports_dir,
)

# Generate all the JSON/HTML reports to the report area.
gen_reports(
summary=results_summary,
path=reports_dir,
)

def has_errors(self) -> bool:
"""Return error state."""
Expand Down
2 changes: 1 addition & 1 deletion src/dvsim/flow/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
from dvsim.flow.hjson import load_hjson
from dvsim.flow.lint import LintCfg
from dvsim.flow.rdc import RdcCfg
from dvsim.flow.sim import SimCfg
from dvsim.flow.syn import SynCfg
from dvsim.logging import log
from dvsim.sim.flow import SimCfg

FLOW_HANDLERS = {
"cdc": CdcCfg,
Expand Down
5 changes: 4 additions & 1 deletion src/dvsim/flow/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ def gen_results_summary(self):

keys = self.totals.get_keys(self.report_severities)
for cfg in self.cfgs:
name_with_link = cfg._get_results_page_link(self.results_dir)
link_text = self.name.upper()
relative_link = Path(self.results_dir) / self.results_page

name_with_link = f"[{link_text}]({relative_link})"

row = [name_with_link]
row += cfg.result_summary.get_counts_md(keys)
Expand Down
61 changes: 55 additions & 6 deletions src/dvsim/flow/one_shot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@

"""Class describing a one-shot build configuration object."""

import pathlib
from abc import abstractmethod
from collections import OrderedDict
from collections.abc import Sequence
from pathlib import Path

from dvsim.flow.base import FlowCfg
from dvsim.job.data import CompletedJobStatus
from dvsim.job.deploy import CompileOneShot
from dvsim.logging import log
from dvsim.modes import BuildMode, Mode
from dvsim.utils import rm_path


class OneShotCfg(FlowCfg):
"""Simple one-shot build flow for non-simulation targets like
linting, synthesis and FPV.
"""
"""Simple one-shot build flow for non-simulation targets like linting, synthesis and FPV."""

ignored_wildcards = [*FlowCfg.ignored_wildcards, "build_mode", "index", "test"]

Expand Down Expand Up @@ -134,8 +135,10 @@ def _print_list(self) -> None:
def _create_dirs(self) -> None:
"""Create initial set of directories."""
for link in self.links:
rm_path(self.links[link])
pathlib.Path(self.links[link]).mkdir(parents=True)
link_path = Path(self.links[link])

rm_path(link_path)
link_path.mkdir(parents=True)

def _create_deploy_objects(self) -> None:
"""Create deploy objects from build modes."""
Expand All @@ -149,3 +152,49 @@ def _create_deploy_objects(self) -> None:

# Create initial set of directories before kicking off the regression.
self._create_dirs()

@abstractmethod
def _gen_results(self):
"""Generate results for this config."""

@abstractmethod
def gen_results_summary(self):
"""Gathers the aggregated results from all sub configs."""

def gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
"""Generate flow results.

Args:
results: completed job status objects.

"""
for item in self.cfgs:
project = item.name

item_results = [
res
for res in results
if res.block.name == item.name and res.block.variant == item.variant
]

result = item._gen_results(item_results)

log.info("[results]: [%s]:\n%s\n", project, result)
log.info("[scratch_path]: [%s] [%s]", project, item.scratch_path)

# TODO: Implement HTML report using templates

results_dir = Path(self.results_dir)
results_dir.mkdir(exist_ok=True, parents=True)

# (results_dir / self.results_html_name).write_text(
# md_results_to_html(self.results_title, self.css_file, item.results_md)
# )

log.verbose("[report]: [%s] [%s/report.html]", project, item.results_dir)

self.errors_seen |= item.errors_seen

if self.is_primary_cfg:
self.gen_results_summary()
# self.write_results(self.results_html_name, self.results_summary_md)
4 changes: 4 additions & 0 deletions src/dvsim/job/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ def __init__(self, sim_cfg: "SimCfg") -> None:
# Cross ref the whole cfg object for ease.
self.sim_cfg = sim_cfg
self.flow = sim_cfg.name

if not hasattr(self.sim_cfg, "variant"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is variant used anywhere outside of deploy.py? If not, maybe a nicer hack would be to use things like this?

self._variant_suffix = f"_{self.sim_cfg.variant}" if self.sim_cfg.getattr("variant") else ""

That way, we don't touch the contents of the sim_cfg object.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I had initially, but unfortunately it is used elsewhere. So I chose this approach for time sake and also to reduce the risk of the change.

Longer term I think we need to factor out the Deploy objects altogether and get the FlowCfg to generate the JobSpec objects directly. But that is a bigger change than we can do right now.

self.sim_cfg.variant = ""

self._variant_suffix = f"_{self.sim_cfg.variant}" if self.sim_cfg.variant else ""

# A list of jobs on which this job depends.
Expand Down
33 changes: 18 additions & 15 deletions src/dvsim/launcher/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,25 +339,28 @@ def _find_patterns(patterns: Sequence[str], line: str) -> Sequence[str] | None:
# since it is devoid of the delays incurred due to infrastructure and
# setup overhead.

plugin = get_sim_tool_plugin(tool=self.job_spec.tool.name)
time = self.job_runtime_secs
unit = "s"

if self.job_spec.job_type in [
"CompileSim",
"RunTest",
"CovUnr",
"CovMerge",
"CovReport",
"CovAnalyze",
]:
plugin = get_sim_tool_plugin(tool=self.job_spec.tool.name)

try:
time, unit = plugin.get_job_runtime(log_text=lines)
self.job_runtime.set(time, unit)

except RuntimeError as e:
log.warning(
f"{self.job_spec.full_name}: {e} Using dvsim-maintained job_runtime instead."
)
self.job_runtime.set(self.job_runtime_secs, "s")

if self.job_spec.job_type == "RunTest":
try:
time, unit = plugin.get_simulated_time(log_text=lines)
self.simulated_time.set(time, unit)
time, unit = plugin.get_job_runtime(log_text=lines)

except RuntimeError as e:
log.debug(f"{self.job_spec.full_name}: {e}")
log.warning(
f"{self.job_spec.full_name}: {e} Using dvsim-maintained job_runtime instead."
)

self.job_runtime.set(time, unit)

if chk_failed or chk_passed:
for cnt, line in enumerate(lines):
Expand Down
Loading
Loading